Initial WebM release v0.9.0
authorJohn Koleszar <jkoleszar@google.com>
Tue, 18 May 2010 15:58:33 +0000 (11:58 -0400)
committerJohn Koleszar <jkoleszar@google.com>
Tue, 18 May 2010 15:58:33 +0000 (11:58 -0400)
724 files changed:
.gitattributes [new file with mode: 0644]
AUTHORS [new file with mode: 0644]
CHANGELOG [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
args.c [new file with mode: 0644]
args.h [new file with mode: 0644]
build/.gitignore [new file with mode: 0644]
build/arm-wince-vs8/.gitattributes [new file with mode: 0644]
build/arm-wince-vs8/armasmv5.rules [new file with mode: 0644]
build/arm-wince-vs8/armasmv6.rules [new file with mode: 0644]
build/arm-wince-vs8/armasmxscale.rules [new file with mode: 0644]
build/arm-wince-vs8/obj_int_extract.bat [new file with mode: 0644]
build/arm-wince-vs8/vpx_decoder.sln [new file with mode: 0644]
build/make/Makefile [new file with mode: 0755]
build/make/ads2gas.pl [new file with mode: 0755]
build/make/ads2gas_apple.pl [new file with mode: 0755]
build/make/armlink_adapter.sh [new file with mode: 0755]
build/make/configure.sh [new file with mode: 0755]
build/make/gen_asm_deps.sh [new file with mode: 0755]
build/make/gen_msvs_def.sh [new file with mode: 0755]
build/make/gen_msvs_proj.sh [new file with mode: 0755]
build/make/gen_msvs_sln.sh [new file with mode: 0755]
build/make/obj_int_extract.c [new file with mode: 0644]
build/make/version.sh [new file with mode: 0755]
configure [new file with mode: 0755]
docs.mk [new file with mode: 0644]
example_xma.c [new file with mode: 0644]
examples.mk [new file with mode: 0644]
examples/decode_to_md5.txt [new file with mode: 0644]
examples/decode_with_drops.txt [new file with mode: 0644]
examples/decoder_tmpl.c [new file with mode: 0644]
examples/decoder_tmpl.txt [new file with mode: 0644]
examples/encoder_tmpl.c [new file with mode: 0644]
examples/encoder_tmpl.txt [new file with mode: 0644]
examples/error_resilient.txt [new file with mode: 0644]
examples/force_keyframe.txt [new file with mode: 0644]
examples/gen_example_code.sh [new file with mode: 0755]
examples/gen_example_doxy.php [new file with mode: 0755]
examples/gen_example_text.sh [new file with mode: 0755]
examples/includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.cfg.php [new file with mode: 0644]
examples/includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.class.php [new file with mode: 0644]
examples/includes/ASCIIMathPHP-2.0/htmlMathML.js [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/.gitattributes [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/Changes [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/MANIFEST [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/Makefile.PL [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/Toc.pm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/Toc.pod [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/TocGenerator.pm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/TocInsertor.pm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/TocUpdator.pm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/ManualTest/manualTest1.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir1/SubSubDir1/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir1/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/SubSubDir1/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/SubSubDir2/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir3/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/SiteMap/index.htm [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/extend.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/format.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/generate.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/insert.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/manualTest.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/options.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/podExamples.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/propagate.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/siteMap.t [new file with mode: 0644]
examples/includes/HTML-Toc-0.91/t/update.t [new file with mode: 0644]
examples/includes/PHP-Markdown-Extra-1.2.3/License.text [new file with mode: 0644]
examples/includes/PHP-Markdown-Extra-1.2.3/PHP Markdown Extra Readme.text [new file with mode: 0644]
examples/includes/PHP-Markdown-Extra-1.2.3/markdown.php [new file with mode: 0644]
examples/includes/PHP-Markdown-Extra-1.2.3/markdown.php.orig [new file with mode: 0644]
examples/includes/PHP-SmartyPants-1.5.1e/PHP SmartyPants Readme.txt [new file with mode: 0644]
examples/includes/PHP-SmartyPants-1.5.1e/smartypants.php [new file with mode: 0644]
examples/includes/geshi/contrib/aliased.php [new file with mode: 0644]
examples/includes/geshi/contrib/cssgen.php [new file with mode: 0644]
examples/includes/geshi/contrib/cssgen2.php [new file with mode: 0644]
examples/includes/geshi/contrib/example.php [new file with mode: 0644]
examples/includes/geshi/contrib/langcheck.php [new file with mode: 0644]
examples/includes/geshi/docs/BUGS [new file with mode: 0644]
examples/includes/geshi/docs/CHANGES [new file with mode: 0644]
examples/includes/geshi/docs/COPYING [new file with mode: 0644]
examples/includes/geshi/docs/README [new file with mode: 0644]
examples/includes/geshi/docs/THANKS [new file with mode: 0644]
examples/includes/geshi/docs/TODO [new file with mode: 0644]
examples/includes/geshi/docs/api/__filesource/fsource_geshi_core_geshi.php.html [new file with mode: 0644]
examples/includes/geshi/docs/api/blank.html [new file with mode: 0644]
examples/includes/geshi/docs/api/classtrees_geshi.html [new file with mode: 0644]
examples/includes/geshi/docs/api/elementindex.html [new file with mode: 0644]
examples/includes/geshi/docs/api/elementindex_geshi.html [new file with mode: 0644]
examples/includes/geshi/docs/api/errors.html [new file with mode: 0644]
examples/includes/geshi/docs/api/geshi/core/GeSHi.html [new file with mode: 0644]
examples/includes/geshi/docs/api/geshi/core/_geshi.php.html [new file with mode: 0644]
examples/includes/geshi/docs/api/index.html [new file with mode: 0644]
examples/includes/geshi/docs/api/li_geshi.html [new file with mode: 0644]
examples/includes/geshi/docs/api/media/banner.css [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/AbstractClass.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/AbstractClass_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/AbstractMethod.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/AbstractPrivateClass.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/AbstractPrivateClass_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/AbstractPrivateMethod.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Class.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Class_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Constant.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Constructor.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Destructor.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Function.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Global.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/I.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Index.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Interface.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Interface_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/L.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Lminus.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Lplus.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Method.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Page.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Page_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/PrivateClass.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/PrivateClass_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/PrivateMethod.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/PrivateVariable.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/StaticMethod.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/StaticVariable.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/T.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Tminus.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Tplus.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/Variable.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/blank.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/class_folder.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/empty.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/file.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/folder.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/function_folder.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/next_button.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/next_button_disabled.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/package.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/package_folder.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/previous_button.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/previous_button_disabled.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/private_class_logo.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/tutorial.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/tutorial_folder.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/images/up_button.png [new file with mode: 0644]
examples/includes/geshi/docs/api/media/stylesheet.css [new file with mode: 0644]
examples/includes/geshi/docs/api/packages.html [new file with mode: 0644]
examples/includes/geshi/docs/api/todolist.html [new file with mode: 0644]
examples/includes/geshi/docs/geshi-doc.html [new file with mode: 0644]
examples/includes/geshi/docs/geshi-doc.txt [new file with mode: 0644]
examples/includes/geshi/docs/phpdoc.ini [new file with mode: 0644]
examples/includes/geshi/geshi.php [new file with mode: 0644]
examples/includes/geshi/geshi/abap.php [new file with mode: 0644]
examples/includes/geshi/geshi/actionscript.php [new file with mode: 0644]
examples/includes/geshi/geshi/actionscript3.php [new file with mode: 0644]
examples/includes/geshi/geshi/ada.php [new file with mode: 0644]
examples/includes/geshi/geshi/apache.php [new file with mode: 0644]
examples/includes/geshi/geshi/applescript.php [new file with mode: 0644]
examples/includes/geshi/geshi/apt_sources.php [new file with mode: 0644]
examples/includes/geshi/geshi/asm.php [new file with mode: 0644]
examples/includes/geshi/geshi/asp.php [new file with mode: 0644]
examples/includes/geshi/geshi/autoit.php [new file with mode: 0644]
examples/includes/geshi/geshi/avisynth.php [new file with mode: 0644]
examples/includes/geshi/geshi/bash.php [new file with mode: 0644]
examples/includes/geshi/geshi/basic4gl.php [new file with mode: 0644]
examples/includes/geshi/geshi/bf.php [new file with mode: 0644]
examples/includes/geshi/geshi/blitzbasic.php [new file with mode: 0644]
examples/includes/geshi/geshi/bnf.php [new file with mode: 0644]
examples/includes/geshi/geshi/boo.php [new file with mode: 0644]
examples/includes/geshi/geshi/c.php [new file with mode: 0644]
examples/includes/geshi/geshi/c_mac.php [new file with mode: 0644]
examples/includes/geshi/geshi/caddcl.php [new file with mode: 0644]
examples/includes/geshi/geshi/cadlisp.php [new file with mode: 0644]
examples/includes/geshi/geshi/cfdg.php [new file with mode: 0644]
examples/includes/geshi/geshi/cfm.php [new file with mode: 0644]
examples/includes/geshi/geshi/cil.php [new file with mode: 0644]
examples/includes/geshi/geshi/cobol.php [new file with mode: 0644]
examples/includes/geshi/geshi/cpp-qt.php [new file with mode: 0644]
examples/includes/geshi/geshi/cpp.php [new file with mode: 0644]
examples/includes/geshi/geshi/csharp.php [new file with mode: 0644]
examples/includes/geshi/geshi/css.php [new file with mode: 0644]
examples/includes/geshi/geshi/d.php [new file with mode: 0644]
examples/includes/geshi/geshi/dcs.php [new file with mode: 0644]
examples/includes/geshi/geshi/delphi.php [new file with mode: 0644]
examples/includes/geshi/geshi/diff.php [new file with mode: 0644]
examples/includes/geshi/geshi/div.php [new file with mode: 0644]
examples/includes/geshi/geshi/dos.php [new file with mode: 0644]
examples/includes/geshi/geshi/dot.php [new file with mode: 0644]
examples/includes/geshi/geshi/eiffel.php [new file with mode: 0644]
examples/includes/geshi/geshi/email.php [new file with mode: 0644]
examples/includes/geshi/geshi/fortran.php [new file with mode: 0644]
examples/includes/geshi/geshi/freebasic.php [new file with mode: 0644]
examples/includes/geshi/geshi/genero.php [new file with mode: 0644]
examples/includes/geshi/geshi/gettext.php [new file with mode: 0644]
examples/includes/geshi/geshi/glsl.php [new file with mode: 0644]
examples/includes/geshi/geshi/gml.php [new file with mode: 0644]
examples/includes/geshi/geshi/gnuplot.php [new file with mode: 0644]
examples/includes/geshi/geshi/groovy.php [new file with mode: 0644]
examples/includes/geshi/geshi/haskell.php [new file with mode: 0644]
examples/includes/geshi/geshi/hq9plus.php [new file with mode: 0644]
examples/includes/geshi/geshi/html4strict.php [new file with mode: 0644]
examples/includes/geshi/geshi/idl.php [new file with mode: 0644]
examples/includes/geshi/geshi/ini.php [new file with mode: 0644]
examples/includes/geshi/geshi/inno.php [new file with mode: 0644]
examples/includes/geshi/geshi/intercal.php [new file with mode: 0644]
examples/includes/geshi/geshi/io.php [new file with mode: 0644]
examples/includes/geshi/geshi/java.php [new file with mode: 0644]
examples/includes/geshi/geshi/java5.php [new file with mode: 0644]
examples/includes/geshi/geshi/javascript.php [new file with mode: 0644]
examples/includes/geshi/geshi/kixtart.php [new file with mode: 0644]
examples/includes/geshi/geshi/klonec.php [new file with mode: 0644]
examples/includes/geshi/geshi/klonecpp.php [new file with mode: 0644]
examples/includes/geshi/geshi/latex.php [new file with mode: 0644]
examples/includes/geshi/geshi/lisp.php [new file with mode: 0644]
examples/includes/geshi/geshi/locobasic.php [new file with mode: 0644]
examples/includes/geshi/geshi/lolcode.php [new file with mode: 0644]
examples/includes/geshi/geshi/lotusformulas.php [new file with mode: 0644]
examples/includes/geshi/geshi/lotusscript.php [new file with mode: 0644]
examples/includes/geshi/geshi/lscript.php [new file with mode: 0644]
examples/includes/geshi/geshi/lsl2.php [new file with mode: 0644]
examples/includes/geshi/geshi/lua.php [new file with mode: 0644]
examples/includes/geshi/geshi/m68k.php [new file with mode: 0644]
examples/includes/geshi/geshi/make.php [new file with mode: 0644]
examples/includes/geshi/geshi/matlab.php [new file with mode: 0644]
examples/includes/geshi/geshi/mirc.php [new file with mode: 0644]
examples/includes/geshi/geshi/modula3.php [new file with mode: 0644]
examples/includes/geshi/geshi/mpasm.php [new file with mode: 0644]
examples/includes/geshi/geshi/mxml.php [new file with mode: 0644]
examples/includes/geshi/geshi/mysql.php [new file with mode: 0644]
examples/includes/geshi/geshi/nsis.php [new file with mode: 0644]
examples/includes/geshi/geshi/objc.php [new file with mode: 0644]
examples/includes/geshi/geshi/ocaml-brief.php [new file with mode: 0644]
examples/includes/geshi/geshi/ocaml.php [new file with mode: 0644]
examples/includes/geshi/geshi/oobas.php [new file with mode: 0644]
examples/includes/geshi/geshi/oracle11.php [new file with mode: 0644]
examples/includes/geshi/geshi/oracle8.php [new file with mode: 0644]
examples/includes/geshi/geshi/pascal.php [new file with mode: 0644]
examples/includes/geshi/geshi/per.php [new file with mode: 0644]
examples/includes/geshi/geshi/perl.php [new file with mode: 0644]
examples/includes/geshi/geshi/php-brief.php [new file with mode: 0644]
examples/includes/geshi/geshi/php.php [new file with mode: 0644]
examples/includes/geshi/geshi/pic16.php [new file with mode: 0644]
examples/includes/geshi/geshi/pixelbender.php [new file with mode: 0644]
examples/includes/geshi/geshi/plsql.php [new file with mode: 0644]
examples/includes/geshi/geshi/povray.php [new file with mode: 0644]
examples/includes/geshi/geshi/powershell.php [new file with mode: 0644]
examples/includes/geshi/geshi/progress.php [new file with mode: 0644]
examples/includes/geshi/geshi/prolog.php [new file with mode: 0644]
examples/includes/geshi/geshi/providex.php [new file with mode: 0644]
examples/includes/geshi/geshi/python.php [new file with mode: 0644]
examples/includes/geshi/geshi/qbasic.php [new file with mode: 0644]
examples/includes/geshi/geshi/rails.php [new file with mode: 0644]
examples/includes/geshi/geshi/rebol.php [new file with mode: 0644]
examples/includes/geshi/geshi/reg.php [new file with mode: 0644]
examples/includes/geshi/geshi/robots.php [new file with mode: 0644]
examples/includes/geshi/geshi/ruby.php [new file with mode: 0644]
examples/includes/geshi/geshi/sas.php [new file with mode: 0644]
examples/includes/geshi/geshi/scala.php [new file with mode: 0644]
examples/includes/geshi/geshi/scheme.php [new file with mode: 0644]
examples/includes/geshi/geshi/scilab.php [new file with mode: 0644]
examples/includes/geshi/geshi/sdlbasic.php [new file with mode: 0644]
examples/includes/geshi/geshi/smalltalk.php [new file with mode: 0644]
examples/includes/geshi/geshi/smarty.php [new file with mode: 0644]
examples/includes/geshi/geshi/sql.php [new file with mode: 0644]
examples/includes/geshi/geshi/tcl.php [new file with mode: 0644]
examples/includes/geshi/geshi/teraterm.php [new file with mode: 0644]
examples/includes/geshi/geshi/text.php [new file with mode: 0644]
examples/includes/geshi/geshi/thinbasic.php [new file with mode: 0644]
examples/includes/geshi/geshi/tsql.php [new file with mode: 0644]
examples/includes/geshi/geshi/typoscript.php [new file with mode: 0644]
examples/includes/geshi/geshi/vb.php [new file with mode: 0644]
examples/includes/geshi/geshi/vbnet.php [new file with mode: 0644]
examples/includes/geshi/geshi/verilog.php [new file with mode: 0644]
examples/includes/geshi/geshi/vhdl.php [new file with mode: 0644]
examples/includes/geshi/geshi/vim.php [new file with mode: 0644]
examples/includes/geshi/geshi/visualfoxpro.php [new file with mode: 0644]
examples/includes/geshi/geshi/visualprolog.php [new file with mode: 0644]
examples/includes/geshi/geshi/whitespace.php [new file with mode: 0644]
examples/includes/geshi/geshi/winbatch.php [new file with mode: 0644]
examples/includes/geshi/geshi/xml.php [new file with mode: 0644]
examples/includes/geshi/geshi/xorg_conf.php [new file with mode: 0644]
examples/includes/geshi/geshi/xpp.php [new file with mode: 0644]
examples/includes/geshi/geshi/z80.php [new file with mode: 0644]
examples/includes/vp8_doc_tools.php [new file with mode: 0644]
examples/postproc.txt [new file with mode: 0644]
examples/simple_decoder.txt [new file with mode: 0644]
examples/simple_encoder.txt [new file with mode: 0644]
examples/twopass_encoder.txt [new file with mode: 0644]
examples/vp8_scalable_patterns.txt [new file with mode: 0644]
examples/vp8_set_maps.txt [new file with mode: 0644]
examples/vp8cx_set_ref.txt [new file with mode: 0644]
ivfdec.c [new file with mode: 0644]
ivfenc.c [new file with mode: 0644]
keywords.dox [new file with mode: 0644]
libs.doxy_template [new file with mode: 0644]
libs.mk [new file with mode: 0644]
mainpage.dox [new file with mode: 0644]
md5_utils.c [new file with mode: 0644]
md5_utils.h [new file with mode: 0644]
release.sh [new file with mode: 0755]
solution.mk [new file with mode: 0644]
usage.dox [new file with mode: 0644]
usage_cx.dox [new file with mode: 0644]
usage_dx.dox [new file with mode: 0644]
vp8/common/alloccommon.c [new file with mode: 0644]
vp8/common/alloccommon.h [new file with mode: 0644]
vp8/common/arm/armv6/bilinearfilter_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/copymem16x16_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/copymem8x4_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/copymem8x8_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/filter_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/idct_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/iwalsh_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/loopfilter_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/recon_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/simpleloopfilter_v6.asm [new file with mode: 0644]
vp8/common/arm/armv6/sixtappredict8x4_v6.asm [new file with mode: 0644]
vp8/common/arm/bilinearfilter_arm.c [new file with mode: 0644]
vp8/common/arm/filter_arm.c [new file with mode: 0644]
vp8/common/arm/idct_arm.h [new file with mode: 0644]
vp8/common/arm/loopfilter_arm.c [new file with mode: 0644]
vp8/common/arm/loopfilter_arm.h [new file with mode: 0644]
vp8/common/arm/neon/bilinearpredict16x16_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/bilinearpredict4x4_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/bilinearpredict8x4_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/bilinearpredict8x8_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/buildintrapredictorsmby_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/copymem16x16_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/copymem8x4_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/copymem8x8_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/iwalsh_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/loopfilterhorizontaledge_uv_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/loopfilterhorizontaledge_y_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/loopfilterverticaledge_uv_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/loopfilterverticaledge_y_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/mbloopfilterhorizontaledge_uv_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/mbloopfilterhorizontaledge_y_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/mbloopfilterverticaledge_uv_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/mbloopfilterverticaledge_y_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/recon16x16mb_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/recon2b_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/recon4b_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/reconb_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/save_neon_reg.asm [new file with mode: 0644]
vp8/common/arm/neon/shortidct4x4llm_1_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/shortidct4x4llm_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/sixtappredict16x16_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/sixtappredict4x4_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/sixtappredict8x4_neon.asm [new file with mode: 0644]
vp8/common/arm/neon/sixtappredict8x8_neon.asm [new file with mode: 0644]
vp8/common/arm/recon_arm.c [new file with mode: 0644]
vp8/common/arm/recon_arm.h [new file with mode: 0644]
vp8/common/arm/reconintra4x4_arm.c [new file with mode: 0644]
vp8/common/arm/reconintra_arm.c [new file with mode: 0644]
vp8/common/arm/subpixel_arm.h [new file with mode: 0644]
vp8/common/arm/systemdependent.c [new file with mode: 0644]
vp8/common/arm/vpx_asm_offsets.c [new file with mode: 0644]
vp8/common/bigend.h [new file with mode: 0644]
vp8/common/blockd.c [new file with mode: 0644]
vp8/common/blockd.h [new file with mode: 0644]
vp8/common/boolcoder.h [new file with mode: 0644]
vp8/common/codec_common_interface.h [new file with mode: 0644]
vp8/common/coefupdateprobs.h [new file with mode: 0644]
vp8/common/common.h [new file with mode: 0644]
vp8/common/common_types.h [new file with mode: 0644]
vp8/common/context.c [new file with mode: 0644]
vp8/common/debugmodes.c [new file with mode: 0644]
vp8/common/defaultcoefcounts.h [new file with mode: 0644]
vp8/common/dma_desc.h [new file with mode: 0644]
vp8/common/duck_io.h [new file with mode: 0644]
vp8/common/entropy.c [new file with mode: 0644]
vp8/common/entropy.h [new file with mode: 0644]
vp8/common/entropymode.c [new file with mode: 0644]
vp8/common/entropymode.h [new file with mode: 0644]
vp8/common/entropymv.c [new file with mode: 0644]
vp8/common/entropymv.h [new file with mode: 0644]
vp8/common/extend.c [new file with mode: 0644]
vp8/common/extend.h [new file with mode: 0644]
vp8/common/filter_c.c [new file with mode: 0644]
vp8/common/findnearmv.c [new file with mode: 0644]
vp8/common/findnearmv.h [new file with mode: 0644]
vp8/common/fourcc.hpp [new file with mode: 0644]
vp8/common/g_common.h [new file with mode: 0644]
vp8/common/generic/systemdependent.c [new file with mode: 0644]
vp8/common/header.h [new file with mode: 0644]
vp8/common/idct.h [new file with mode: 0644]
vp8/common/idctllm.c [new file with mode: 0644]
vp8/common/invtrans.c [new file with mode: 0644]
vp8/common/invtrans.h [new file with mode: 0644]
vp8/common/littlend.h [new file with mode: 0644]
vp8/common/loopfilter.c [new file with mode: 0644]
vp8/common/loopfilter.h [new file with mode: 0644]
vp8/common/loopfilter_filters.c [new file with mode: 0644]
vp8/common/mac_specs.h [new file with mode: 0644]
vp8/common/mbpitch.c [new file with mode: 0644]
vp8/common/modecont.c [new file with mode: 0644]
vp8/common/modecont.h [new file with mode: 0644]
vp8/common/modecontext.c [new file with mode: 0644]
vp8/common/mv.h [new file with mode: 0644]
vp8/common/onyx.h [new file with mode: 0644]
vp8/common/onyxc_int.h [new file with mode: 0644]
vp8/common/onyxd.h [new file with mode: 0644]
vp8/common/partialgfupdate.h [new file with mode: 0644]
vp8/common/postproc.c [new file with mode: 0644]
vp8/common/postproc.h [new file with mode: 0644]
vp8/common/ppc/copy_altivec.asm [new file with mode: 0644]
vp8/common/ppc/filter_altivec.asm [new file with mode: 0644]
vp8/common/ppc/filter_bilinear_altivec.asm [new file with mode: 0644]
vp8/common/ppc/idctllm_altivec.asm [new file with mode: 0644]
vp8/common/ppc/loopfilter_altivec.c [new file with mode: 0644]
vp8/common/ppc/loopfilter_filters_altivec.asm [new file with mode: 0644]
vp8/common/ppc/platform_altivec.asm [new file with mode: 0644]
vp8/common/ppc/recon_altivec.asm [new file with mode: 0644]
vp8/common/ppc/systemdependent.c [new file with mode: 0644]
vp8/common/ppflags.h [new file with mode: 0644]
vp8/common/pragmas.h [new file with mode: 0644]
vp8/common/predictdc.c [new file with mode: 0644]
vp8/common/predictdc.h [new file with mode: 0644]
vp8/common/preproc.h [new file with mode: 0644]
vp8/common/preprocif.h [new file with mode: 0644]
vp8/common/proposed.h [new file with mode: 0644]
vp8/common/quant_common.c [new file with mode: 0644]
vp8/common/quant_common.h [new file with mode: 0644]
vp8/common/recon.c [new file with mode: 0644]
vp8/common/recon.h [new file with mode: 0644]
vp8/common/reconinter.c [new file with mode: 0644]
vp8/common/reconinter.h [new file with mode: 0644]
vp8/common/reconintra.c [new file with mode: 0644]
vp8/common/reconintra.h [new file with mode: 0644]
vp8/common/reconintra4x4.c [new file with mode: 0644]
vp8/common/reconintra4x4.h [new file with mode: 0644]
vp8/common/segmentation_common.c [new file with mode: 0644]
vp8/common/segmentation_common.h [new file with mode: 0644]
vp8/common/setupintrarecon.c [new file with mode: 0644]
vp8/common/setupintrarecon.h [new file with mode: 0644]
vp8/common/subpixel.h [new file with mode: 0644]
vp8/common/swapyv12buffer.c [new file with mode: 0644]
vp8/common/swapyv12buffer.h [new file with mode: 0644]
vp8/common/systemdependent.h [new file with mode: 0644]
vp8/common/textblit.c [new file with mode: 0644]
vp8/common/threading.h [new file with mode: 0644]
vp8/common/treecoder.c [new file with mode: 0644]
vp8/common/treecoder.h [new file with mode: 0644]
vp8/common/type_aliases.h [new file with mode: 0644]
vp8/common/vfwsetting.hpp [new file with mode: 0644]
vp8/common/vpx_ref_build_prefix.h [new file with mode: 0644]
vp8/common/vpxblit.h [new file with mode: 0644]
vp8/common/vpxblit_c64.h [new file with mode: 0644]
vp8/common/vpxerrors.h [new file with mode: 0644]
vp8/common/x86/boolcoder.cxx [new file with mode: 0644]
vp8/common/x86/idct_x86.h [new file with mode: 0644]
vp8/common/x86/idctllm_mmx.asm [new file with mode: 0644]
vp8/common/x86/iwalsh_mmx.asm [new file with mode: 0644]
vp8/common/x86/iwalsh_sse2.asm [new file with mode: 0644]
vp8/common/x86/loopfilter_mmx.asm [new file with mode: 0644]
vp8/common/x86/loopfilter_sse2.asm [new file with mode: 0644]
vp8/common/x86/loopfilter_x86.c [new file with mode: 0644]
vp8/common/x86/loopfilter_x86.h [new file with mode: 0644]
vp8/common/x86/postproc_mmx.asm [new file with mode: 0644]
vp8/common/x86/postproc_mmx.c [new file with mode: 0644]
vp8/common/x86/postproc_sse2.asm [new file with mode: 0644]
vp8/common/x86/postproc_x86.h [new file with mode: 0644]
vp8/common/x86/recon_mmx.asm [new file with mode: 0644]
vp8/common/x86/recon_sse2.asm [new file with mode: 0644]
vp8/common/x86/recon_x86.h [new file with mode: 0644]
vp8/common/x86/subpixel_mmx.asm [new file with mode: 0644]
vp8/common/x86/subpixel_sse2.asm [new file with mode: 0644]
vp8/common/x86/subpixel_x86.h [new file with mode: 0644]
vp8/common/x86/vp8_asm_stubs.c [new file with mode: 0644]
vp8/common/x86/x86_systemdependent.c [new file with mode: 0644]
vp8/decoder/arm/armv5/dequantize_v5.asm [new file with mode: 0644]
vp8/decoder/arm/armv6/dboolhuff_v6.asm [new file with mode: 0644]
vp8/decoder/arm/armv6/dequantdcidct_v6.asm [new file with mode: 0644]
vp8/decoder/arm/armv6/dequantidct_v6.asm [new file with mode: 0644]
vp8/decoder/arm/armv6/dequantize_v6.asm [new file with mode: 0644]
vp8/decoder/arm/dboolhuff_arm.h [new file with mode: 0644]
vp8/decoder/arm/dequantize_arm.c [new file with mode: 0644]
vp8/decoder/arm/dequantize_arm.h [new file with mode: 0644]
vp8/decoder/arm/detokenizearm_sjl.c [new file with mode: 0644]
vp8/decoder/arm/detokenizearm_v6.asm [new file with mode: 0644]
vp8/decoder/arm/dsystemdependent.c [new file with mode: 0644]
vp8/decoder/arm/neon/dboolhuff_neon.asm [new file with mode: 0644]
vp8/decoder/arm/neon/dequantdcidct_neon.asm [new file with mode: 0644]
vp8/decoder/arm/neon/dequantidct_neon.asm [new file with mode: 0644]
vp8/decoder/arm/neon/dequantizeb_neon.asm [new file with mode: 0644]
vp8/decoder/dboolhuff.c [new file with mode: 0644]
vp8/decoder/dboolhuff.h [new file with mode: 0644]
vp8/decoder/decodemv.c [new file with mode: 0644]
vp8/decoder/decodemv.h [new file with mode: 0644]
vp8/decoder/decoderthreading.h [new file with mode: 0644]
vp8/decoder/decodframe.c [new file with mode: 0644]
vp8/decoder/demode.c [new file with mode: 0644]
vp8/decoder/demode.h [new file with mode: 0644]
vp8/decoder/dequantize.c [new file with mode: 0644]
vp8/decoder/dequantize.h [new file with mode: 0644]
vp8/decoder/detokenize.c [new file with mode: 0644]
vp8/decoder/detokenize.h [new file with mode: 0644]
vp8/decoder/generic/dsystemdependent.c [new file with mode: 0644]
vp8/decoder/onyxd_if.c [new file with mode: 0644]
vp8/decoder/onyxd_if_sjl.c [new file with mode: 0644]
vp8/decoder/onyxd_int.h [new file with mode: 0644]
vp8/decoder/threading.c [new file with mode: 0644]
vp8/decoder/treereader.h [new file with mode: 0644]
vp8/decoder/x86/dequantize_mmx.asm [new file with mode: 0644]
vp8/decoder/x86/dequantize_x86.h [new file with mode: 0644]
vp8/decoder/x86/onyxdxv.c [new file with mode: 0644]
vp8/decoder/x86/x86_dsystemdependent.c [new file with mode: 0644]
vp8/decoder/xprintf.c [new file with mode: 0644]
vp8/decoder/xprintf.h [new file with mode: 0644]
vp8/encoder/arm/armv6/walsh_v6.asm [new file with mode: 0644]
vp8/encoder/arm/boolhuff_arm.c [new file with mode: 0644]
vp8/encoder/arm/csystemdependent.c [new file with mode: 0644]
vp8/encoder/arm/dct_arm.h [new file with mode: 0644]
vp8/encoder/arm/encodemb_arm.c [new file with mode: 0644]
vp8/encoder/arm/encodemb_arm.h [new file with mode: 0644]
vp8/encoder/arm/mcomp_arm.c [new file with mode: 0644]
vp8/encoder/arm/neon/boolhuff_armv7.asm [new file with mode: 0644]
vp8/encoder/arm/neon/fastfdct4x4_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/fastfdct8x4_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/fastquantizeb_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/sad16_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/sad8_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/shortfdct_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/subtract_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/variance_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_memcpy_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_mse16x16_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_packtokens_armv7.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_packtokens_mbrow_armv7.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_packtokens_partitions_armv7.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_subpixelvariance16x16_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_subpixelvariance16x16s_neon.asm [new file with mode: 0644]
vp8/encoder/arm/neon/vp8_subpixelvariance8x8_neon.asm [new file with mode: 0644]
vp8/encoder/arm/picklpf_arm.c [new file with mode: 0644]
vp8/encoder/arm/quantize_arm.c [new file with mode: 0644]
vp8/encoder/arm/quantize_arm.h [new file with mode: 0644]
vp8/encoder/arm/variance_arm.h [new file with mode: 0644]
vp8/encoder/arm/vpx_vp8_enc_asm_offsets.c [new file with mode: 0644]
vp8/encoder/bitstream.c [new file with mode: 0644]
vp8/encoder/bitstream.h [new file with mode: 0644]
vp8/encoder/block.h [new file with mode: 0644]
vp8/encoder/boolhuff.c [new file with mode: 0644]
vp8/encoder/boolhuff.h [new file with mode: 0644]
vp8/encoder/dct.c [new file with mode: 0644]
vp8/encoder/dct.h [new file with mode: 0644]
vp8/encoder/encodeframe.c [new file with mode: 0644]
vp8/encoder/encodeintra.c [new file with mode: 0644]
vp8/encoder/encodeintra.h [new file with mode: 0644]
vp8/encoder/encodemb.c [new file with mode: 0644]
vp8/encoder/encodemb.h [new file with mode: 0644]
vp8/encoder/encodemv.c [new file with mode: 0644]
vp8/encoder/encodemv.h [new file with mode: 0644]
vp8/encoder/ethreading.c [new file with mode: 0644]
vp8/encoder/firstpass.c [new file with mode: 0644]
vp8/encoder/firstpass.h [new file with mode: 0644]
vp8/encoder/generic/csystemdependent.c [new file with mode: 0644]
vp8/encoder/mcomp.c [new file with mode: 0644]
vp8/encoder/mcomp.h [new file with mode: 0644]
vp8/encoder/modecosts.c [new file with mode: 0644]
vp8/encoder/modecosts.h [new file with mode: 0644]
vp8/encoder/onyx_if.c [new file with mode: 0644]
vp8/encoder/onyx_int.h [new file with mode: 0644]
vp8/encoder/parms.cpp [new file with mode: 0644]
vp8/encoder/pickinter.c [new file with mode: 0644]
vp8/encoder/pickinter.h [new file with mode: 0644]
vp8/encoder/picklpf.c [new file with mode: 0644]
vp8/encoder/ppc/csystemdependent.c [new file with mode: 0644]
vp8/encoder/ppc/encodemb_altivec.asm [new file with mode: 0644]
vp8/encoder/ppc/fdct_altivec.asm [new file with mode: 0644]
vp8/encoder/ppc/rdopt_altivec.asm [new file with mode: 0644]
vp8/encoder/ppc/sad_altivec.asm [new file with mode: 0644]
vp8/encoder/ppc/variance_altivec.asm [new file with mode: 0644]
vp8/encoder/ppc/variance_subpixel_altivec.asm [new file with mode: 0644]
vp8/encoder/preproc.c [new file with mode: 0644]
vp8/encoder/psnr.c [new file with mode: 0644]
vp8/encoder/psnr.h [new file with mode: 0644]
vp8/encoder/quantize.c [new file with mode: 0644]
vp8/encoder/quantize.h [new file with mode: 0644]
vp8/encoder/ratectrl.c [new file with mode: 0644]
vp8/encoder/ratectrl.h [new file with mode: 0644]
vp8/encoder/rdopt.c [new file with mode: 0644]
vp8/encoder/rdopt.h [new file with mode: 0644]
vp8/encoder/sad_c.c [new file with mode: 0644]
vp8/encoder/ssim.c [new file with mode: 0644]
vp8/encoder/tokenize.c [new file with mode: 0644]
vp8/encoder/tokenize.h [new file with mode: 0644]
vp8/encoder/treewriter.c [new file with mode: 0644]
vp8/encoder/treewriter.h [new file with mode: 0644]
vp8/encoder/variance.h [new file with mode: 0644]
vp8/encoder/variance_c.c [new file with mode: 0644]
vp8/encoder/x86/csystemdependent.c [new file with mode: 0644]
vp8/encoder/x86/dct_mmx.asm [new file with mode: 0644]
vp8/encoder/x86/dct_sse2.asm [new file with mode: 0644]
vp8/encoder/x86/dct_x86.h [new file with mode: 0644]
vp8/encoder/x86/encodemb_x86.h [new file with mode: 0644]
vp8/encoder/x86/encodeopt.asm [new file with mode: 0644]
vp8/encoder/x86/fwalsh_sse2.asm [new file with mode: 0644]
vp8/encoder/x86/mcomp_x86.h [new file with mode: 0644]
vp8/encoder/x86/preproc_mmx.c [new file with mode: 0644]
vp8/encoder/x86/quantize_mmx.asm [new file with mode: 0644]
vp8/encoder/x86/sad_mmx.asm [new file with mode: 0644]
vp8/encoder/x86/sad_sse2.asm [new file with mode: 0644]
vp8/encoder/x86/sad_sse3.asm [new file with mode: 0644]
vp8/encoder/x86/sad_ssse3.asm [new file with mode: 0644]
vp8/encoder/x86/subtract_mmx.asm [new file with mode: 0644]
vp8/encoder/x86/variance_impl_mmx.asm [new file with mode: 0644]
vp8/encoder/x86/variance_impl_sse2.asm [new file with mode: 0644]
vp8/encoder/x86/variance_mmx.c [new file with mode: 0644]
vp8/encoder/x86/variance_sse2.c [new file with mode: 0644]
vp8/encoder/x86/variance_x86.h [new file with mode: 0644]
vp8/encoder/x86/x86_csystemdependent.c [new file with mode: 0644]
vp8/vp8.h [new file with mode: 0644]
vp8/vp8_common.mk [new file with mode: 0644]
vp8/vp8_cx_iface.c [new file with mode: 0644]
vp8/vp8_dx_iface.c [new file with mode: 0644]
vp8/vp8cx.h [new file with mode: 0644]
vp8/vp8cx.mk [new file with mode: 0644]
vp8/vp8cx_arm.mk [new file with mode: 0644]
vp8/vp8dx.h [new file with mode: 0644]
vp8/vp8dx.mk [new file with mode: 0644]
vp8/vp8dx_arm.mk [new file with mode: 0644]
vp8/vp8e.h [new file with mode: 0644]
vp8_api1_migration.txt [new file with mode: 0644]
vpx_codec/exports [new file with mode: 0644]
vpx_codec/internal/vpx_codec_internal.h [new file with mode: 0644]
vpx_codec/src/vpx_codec.c [new file with mode: 0644]
vpx_codec/src/vpx_decoder.c [new file with mode: 0644]
vpx_codec/src/vpx_decoder_compat.c [new file with mode: 0644]
vpx_codec/src/vpx_encoder.c [new file with mode: 0644]
vpx_codec/src/vpx_image.c [new file with mode: 0644]
vpx_codec/vpx_codec.h [new file with mode: 0644]
vpx_codec/vpx_codec.mk [new file with mode: 0644]
vpx_codec/vpx_codec_impl_bottom.h [new file with mode: 0644]
vpx_codec/vpx_codec_impl_top.h [new file with mode: 0644]
vpx_codec/vpx_decoder.h [new file with mode: 0644]
vpx_codec/vpx_decoder_compat.h [new file with mode: 0644]
vpx_codec/vpx_encoder.h [new file with mode: 0644]
vpx_codec/vpx_image.h [new file with mode: 0644]
vpx_mem/include/nds/vpx_mem_nds.h [new file with mode: 0644]
vpx_mem/include/vpx_mem_intrnl.h [new file with mode: 0644]
vpx_mem/include/vpx_mem_tracker.h [new file with mode: 0644]
vpx_mem/intel_linux/vpx_mem.c [new file with mode: 0644]
vpx_mem/intel_linux/vpx_mem_tracker.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_alloc.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_base.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_dflt_abort.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_grow.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_largest.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_resize.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_shrink.c [new file with mode: 0644]
vpx_mem/memory_manager/hmm_true.c [new file with mode: 0644]
vpx_mem/memory_manager/include/cavl_if.h [new file with mode: 0644]
vpx_mem/memory_manager/include/cavl_impl.h [new file with mode: 0644]
vpx_mem/memory_manager/include/heapmm.h [new file with mode: 0644]
vpx_mem/memory_manager/include/hmm_cnfg.h [new file with mode: 0644]
vpx_mem/memory_manager/include/hmm_intrnl.h [new file with mode: 0644]
vpx_mem/nds/vpx_mem_nds.c [new file with mode: 0644]
vpx_mem/ti_c6x/vpx_mem_ti_6cx.c [new file with mode: 0644]
vpx_mem/vpx_mem.c [new file with mode: 0644]
vpx_mem/vpx_mem.h [new file with mode: 0644]
vpx_mem/vpx_mem.mk [new file with mode: 0644]
vpx_mem/vpx_mem_tracker.c [new file with mode: 0644]
vpx_ports/config.h [new file with mode: 0644]
vpx_ports/emms.asm [new file with mode: 0644]
vpx_ports/mem.h [new file with mode: 0644]
vpx_ports/mem_ops.h [new file with mode: 0644]
vpx_ports/mem_ops_aligned.h [new file with mode: 0644]
vpx_ports/vpx_integer.h [new file with mode: 0644]
vpx_ports/vpx_timer.h [new file with mode: 0644]
vpx_ports/vpxtypes.h [new file with mode: 0644]
vpx_ports/x86.h [new file with mode: 0644]
vpx_ports/x86_abi_support.asm [new file with mode: 0644]
vpx_scale/arm/armv4/gen_scalers_armv4.asm [new file with mode: 0644]
vpx_scale/arm/nds/yv12extend.c [new file with mode: 0644]
vpx_scale/arm/neon/vp8_vpxyv12_copyframe_func_neon.asm [new file with mode: 0644]
vpx_scale/arm/neon/vp8_vpxyv12_copyframeyonly_neon.asm [new file with mode: 0644]
vpx_scale/arm/neon/vp8_vpxyv12_copysrcframe_func_neon.asm [new file with mode: 0644]
vpx_scale/arm/neon/vp8_vpxyv12_extendframeborders_neon.asm [new file with mode: 0644]
vpx_scale/arm/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/arm/yv12extend_arm.c [new file with mode: 0644]
vpx_scale/blackfin/yv12config.c [new file with mode: 0644]
vpx_scale/blackfin/yv12extend.c [new file with mode: 0644]
vpx_scale/dm642/bicubic_scaler_c64.c [new file with mode: 0644]
vpx_scale/dm642/gen_scalers_c64.c [new file with mode: 0644]
vpx_scale/dm642/yv12extend.c [new file with mode: 0644]
vpx_scale/generic/bicubic_scaler.c [new file with mode: 0644]
vpx_scale/generic/gen_scalers.c [new file with mode: 0644]
vpx_scale/generic/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/generic/vpxscale.c [new file with mode: 0644]
vpx_scale/generic/yv12config.c [new file with mode: 0644]
vpx_scale/generic/yv12extend.c [new file with mode: 0644]
vpx_scale/include/arm/vpxscale_nofp.h [new file with mode: 0644]
vpx_scale/include/generic/vpxscale_arbitrary.h [new file with mode: 0644]
vpx_scale/include/generic/vpxscale_depricated.h [new file with mode: 0644]
vpx_scale/include/generic/vpxscale_nofp.h [new file with mode: 0644]
vpx_scale/include/leapster/vpxscale.h [new file with mode: 0644]
vpx_scale/include/symbian/vpxscale_nofp.h [new file with mode: 0644]
vpx_scale/include/vpxscale_nofp.h [new file with mode: 0644]
vpx_scale/intel_linux/scaleopt.c [new file with mode: 0644]
vpx_scale/intel_linux/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/leapster/doptsystemdependant_lf.c [new file with mode: 0644]
vpx_scale/leapster/gen_scalers_lf.c [new file with mode: 0644]
vpx_scale/leapster/vpxscale_lf.c [new file with mode: 0644]
vpx_scale/leapster/yv12extend.c [new file with mode: 0644]
vpx_scale/scale_mode.h [new file with mode: 0644]
vpx_scale/symbian/gen_scalers_armv4.asm [new file with mode: 0644]
vpx_scale/symbian/gen_scalers_armv4.s [new file with mode: 0644]
vpx_scale/symbian/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/vpx_scale.mk [new file with mode: 0644]
vpx_scale/vpxscale.h [new file with mode: 0644]
vpx_scale/wce/gen_scalers_armv4.asm [new file with mode: 0644]
vpx_scale/wce/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/win32/scaleopt.c [new file with mode: 0644]
vpx_scale/win32/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/x86_64/scaleopt.c [new file with mode: 0644]
vpx_scale/x86_64/scalesystemdependant.c [new file with mode: 0644]
vpx_scale/yv12config.h [new file with mode: 0644]
vpx_scale/yv12extend.h [new file with mode: 0644]
wince_wmain_adapter.cpp [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..ffc6912
--- /dev/null
@@ -0,0 +1,18 @@
+*.[chs]      filter=fixtabswsp
+*.[ch]pp     filter=fixtabswsp
+*.[ch]xx     filter=fixtabswsp
+*.asm        filter=fixtabswsp
+*.php        filter=fixtabswsp
+*.pl         filter=fixtabswsp
+*.sh         filter=fixtabswsp
+*.txt       filter=fixwsp
+[Mm]akefile  filter=fixwsp
+*.mk         filter=fixwsp
+*.rc         -crlf
+*.ds[pw]     -crlf
+*.bat        -crlf
+*.mmp        -crlf
+*.dpj        -crlf
+*.pjt        -crlf
+*.vcp        -crlf
+*.inf        -crlf
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..9686ac1
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,4 @@
+# Names should be added to this file like so:
+# Name or Organization <email address>
+
+Google Inc.
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644 (file)
index 0000000..d6c8ce8
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,3 @@
+2010-05-18 v0.9.0
+  - Initial open source release. Welcome to WebM and VP8!
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..6b0e867
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,48 @@
+Copyright (c) 2010, Google, Inc.
+
+All rights reserved.
+
+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 Google 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 COPYRIGHT
+HOLDER 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.
+
+Subject to the terms and conditions of the above License, Google
+hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this
+section) patent license to make, have made, use, offer to sell, sell,
+import, and otherwise transfer this implementation of VP8, where such
+license applies only to those patent claims, both currently owned by
+Google and acquired in the future, licensable by Google that are
+necessarily infringed by this implementation of VP8. If You or your
+agent or exclusive licensee institute or order or agree to the
+institution of patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that this
+implementation of VP8 or any code incorporated within this
+implementation of VP8 constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any rights
+granted to You under this License for this implementation of VP8
+shall terminate as of the date such litigation is filed.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..cfaf4cc
--- /dev/null
+++ b/README
@@ -0,0 +1,106 @@
+vpx Multi-Format Codec SDK
+README - 19 May 2010
+
+Welcome to the WebM VP8 Codec SDK!
+
+COMPILING THE APPLICATIONS/LIBRARIES:
+  The build system used is similar to autotools. Building generally consists of
+  "configuring" with your desired build options, then using GNU make to build
+  the application.
+
+  1. Prerequisites
+  
+    * All x86 targets require the Yasm[1] assembler be installed.
+    * All Windows builds require that Cygwin[2] be installed.
+    * Building the documentation requires PHP[3] and Doxygen[4]. If you do not
+      have these packages, you must pass --disable-install-docs to the
+      configure script.
+    
+    [1]: http://www.tortall.net/projects/yasm
+    [2]: http://www.cygwin.com
+    [3]: http://php.net
+    [4]: http://www.doxygen.org
+    
+  2. Out-of-tree builds
+  Out of tree builds are a supported method of building the application. For
+  an out of tree build, the source tree is kept separate from the object
+  files produced during compilation. For instance:
+
+    $ mkdir build
+    $ cd build
+    $ ../libvpx/configure <options>
+    $ make
+
+  3. Configuration options
+  The 'configure' script supports a number of options. The --help option can be
+  used to get a list of supported options:
+    $ ../libvpx/configure --help
+
+  4. Cross development
+  For cross development, the most notable option is the --target option. The
+  most up-to-date list of supported targets can be found at the bottom of the
+  --help output of the configure script. As of this writing, the list of
+  available targets is:
+
+    armv5te-linux-rvct
+    armv5te-linux-gcc
+    armv5te-symbian-gcc
+    armv5te-wince-vs8
+    armv6-darwin-gcc
+    armv6-linux-rvct
+    armv6-linux-gcc
+    armv6-symbian-gcc
+    armv6-wince-vs8
+    iwmmxt-linux-rvct
+    iwmmxt-linux-gcc
+    iwmmxt-wince-vs8
+    iwmmxt2-linux-rvct
+    iwmmxt2-linux-gcc
+    iwmmxt2-wince-vs8
+    armv7-linux-rvct
+    armv7-linux-gcc
+    mips32-linux-gcc
+    ppc32-darwin8-gcc
+    ppc32-darwin9-gcc
+    ppc64-darwin8-gcc
+    ppc64-darwin9-gcc
+    ppc64-linux-gcc
+    x86-darwin8-gcc
+    x86-darwin8-icc
+    x86-darwin9-gcc
+    x86-darwin9-icc
+    x86-linux-gcc
+    x86-linux-icc
+    x86-solaris-gcc
+    x86-win32-vs7
+    x86-win32-vs8
+    x86_64-darwin9-gcc
+    x86_64-linux-gcc
+    x86_64-solaris-gcc
+    x86_64-win64-vs8
+    universal-darwin8-gcc
+    universal-darwin9-gcc
+    generic-gnu
+
+  The generic-gnu target, in conjunction with the CROSS environment variable,
+  can be used to cross compile architectures that aren't explicitly listed, if
+  the toolchain is a cross GNU (gcc/binutils) toolchain. Other POSIX toolchains
+  will likely work as well. For instance, to build using the mipsel-linux-uclibc
+  toolchain, the following command could be used (note, POSIX SH syntax, adapt
+  to your shell as necessary):
+
+    $ CROSS=mipsel-linux-uclibc- ../libvpx/src/configure
+
+  In addition, the executables to be invoked can be overridden by specifying the
+  environment variables: CC, AR, LD, AS, STRIP, NM. Additional flags can be
+  passed to these executables with CFLAGS, LDFLAGS, and ASFLAGS.
+
+  5. Configuration errors
+  If the configuration step fails, the first step is to look in the error log.
+  This defaults to config.err. This should give a good indication of what went
+  wrong. If not, contact us for support.
+
+SUPPORT
+  This library is an open source project supported by its community. Please
+  please email webm-users@webmproject.org for help.
+
diff --git a/args.c b/args.c
new file mode 100644 (file)
index 0000000..f2ad697
--- /dev/null
+++ b/args.c
@@ -0,0 +1,215 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "args.h"
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
+#if defined(__GNUC__) && __GNUC__
+extern void die(const char *fmt, ...) __attribute__((noreturn));
+#else
+extern void die(const char *fmt, ...);
+#endif
+
+
+struct arg arg_init(char **argv)
+{
+    struct arg a;
+
+    a.argv      = argv;
+    a.argv_step = 1;
+    a.name      = NULL;
+    a.val       = NULL;
+    a.def       = NULL;
+    return a;
+}
+
+int arg_match(struct arg *arg_, const struct arg_def *def, char **argv)
+{
+    struct arg arg;
+
+    if (!argv[0] || argv[0][0] != '-')
+        return 0;
+
+    arg = arg_init(argv);
+
+    if (def->short_name
+        && strlen(arg.argv[0]) == strlen(def->short_name) + 1
+        && !strcmp(arg.argv[0] + 1, def->short_name))
+    {
+
+        arg.name = arg.argv[0] + 1;
+        arg.val = def->has_val ? arg.argv[1] : NULL;
+        arg.argv_step = def->has_val ? 2 : 1;
+    }
+    else if (def->long_name)
+    {
+        int name_len = strlen(def->long_name);
+
+        if (strlen(arg.argv[0]) >= name_len + 2
+            && arg.argv[0][1] == '-'
+            && !strncmp(arg.argv[0] + 2, def->long_name, name_len)
+            && (arg.argv[0][name_len+2] == '='
+                || arg.argv[0][name_len+2] == '\0'))
+        {
+
+            arg.name = arg.argv[0] + 2;
+            arg.val = arg.name[name_len] == '=' ? arg.name + name_len + 1 : NULL;
+            arg.argv_step = 1;
+        }
+    }
+
+    if (arg.name && !arg.val && def->has_val)
+        die("Error: option %s requires argument.\n", arg.name);
+
+    if (arg.name && arg.val && !def->has_val)
+        die("Error: option %s requires no argument.\n", arg.name);
+
+    if (arg.name
+        && (arg.val || !def->has_val))
+    {
+        arg.def = def;
+        *arg_ = arg;
+        return 1;
+    }
+
+    return 0;
+}
+
+
+const char *arg_next(struct arg *arg)
+{
+    if (arg->argv[0])
+        arg->argv += arg->argv_step;
+
+    return *arg->argv;
+}
+
+
+char **argv_dup(int argc, const char **argv)
+{
+    char **new_argv = malloc((argc + 1) * sizeof(*argv));
+
+    memcpy(new_argv, argv, argc * sizeof(*argv));
+    new_argv[argc] = NULL;
+    return new_argv;
+}
+
+
+void arg_show_usage(FILE *fp, const struct arg_def *const *defs)
+{
+    char option_text[40] = {0};
+
+    for (; *defs; defs++)
+    {
+        const struct arg_def *def = *defs;
+        char *short_val = def->has_val ? " <arg>" : "";
+        char *long_val = def->has_val ? "=<arg>" : "";
+
+        if (def->short_name && def->long_name)
+            snprintf(option_text, 37, "-%s%s, --%s%s",
+                     def->short_name, short_val,
+                     def->long_name, long_val);
+        else if (def->short_name)
+            snprintf(option_text, 37, "-%s%s",
+                     def->short_name, short_val);
+        else if (def->long_name)
+            snprintf(option_text, 37, "          --%s%s",
+                     def->long_name, long_val);
+
+        fprintf(fp, "  %-37s\t%s\n", option_text, def->desc);
+    }
+}
+
+
+unsigned int arg_parse_uint(const struct arg *arg)
+{
+    long int   rawval;
+    char      *endptr;
+
+    rawval = strtol(arg->val, &endptr, 10);
+
+    if (arg->val[0] != '\0' && endptr[0] == '\0')
+    {
+        if (rawval >= 0 && rawval <= UINT_MAX)
+            return rawval;
+
+        die("Option %s: Value %ld out of range for unsigned int\n",
+            arg->name, rawval);
+    }
+
+    die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
+    return 0;
+}
+
+
+int arg_parse_int(const struct arg *arg)
+{
+    long int   rawval;
+    char      *endptr;
+
+    rawval = strtol(arg->val, &endptr, 10);
+
+    if (arg->val[0] != '\0' && endptr[0] == '\0')
+    {
+        if (rawval >= INT_MIN && rawval <= INT_MAX)
+            return rawval;
+
+        die("Option %s: Value %ld out of range for signed int\n",
+            arg->name, rawval);
+    }
+
+    die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
+    return 0;
+}
+
+
+struct vpx_rational
+{
+    int num; /**< fraction numerator */
+    int den; /**< fraction denominator */
+};
+struct vpx_rational arg_parse_rational(const struct arg *arg)
+{
+    long int             rawval;
+    char                *endptr;
+    struct vpx_rational  rat;
+
+    /* parse numerator */
+    rawval = strtol(arg->val, &endptr, 10);
+
+    if (arg->val[0] != '\0' && endptr[0] == '/')
+    {
+        if (rawval >= INT_MIN && rawval <= INT_MAX)
+            rat.num = rawval;
+        else die("Option %s: Value %ld out of range for signed int\n",
+                     arg->name, rawval);
+    }
+    else die("Option %s: Expected / at '%c'\n", arg->name, *endptr);
+
+    /* parse denominator */
+    rawval = strtol(endptr + 1, &endptr, 10);
+
+    if (arg->val[0] != '\0' && endptr[0] == '\0')
+    {
+        if (rawval >= INT_MIN && rawval <= INT_MAX)
+            rat.den = rawval;
+        else die("Option %s: Value %ld out of range for signed int\n",
+                     arg->name, rawval);
+    }
+    else die("Option %s: Invalid character '%c'\n", arg->name, *endptr);
+
+    return rat;
+}
diff --git a/args.h b/args.h
new file mode 100644 (file)
index 0000000..c063f53
--- /dev/null
+++ b/args.h
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef ARGS_H
+#define ARGS_H
+#include <stdio.h>
+
+struct arg
+{
+    char                 **argv;
+    const char            *name;
+    const char            *val;
+    unsigned int           argv_step;
+    const struct arg_def  *def;
+};
+
+typedef struct arg_def
+{
+    const char *short_name;
+    const char *long_name;
+    int         has_val;
+    const char *desc;
+} arg_def_t;
+#define ARG_DEF(s,l,v,d) {s,l,v,d}
+#define ARG_DEF_LIST_END {0}
+
+struct arg arg_init(char **argv);
+int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);
+const char *arg_next(struct arg *arg);
+void arg_show_usage(FILE *fp, const struct arg_def *const *defs);
+char **argv_dup(int argc, const char **argv);
+
+unsigned int arg_parse_uint(const struct arg *arg);
+int arg_parse_int(const struct arg *arg);
+struct vpx_rational arg_parse_rational(const struct arg *arg);
+#endif
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644 (file)
index 0000000..1350fcb
--- /dev/null
@@ -0,0 +1 @@
+x86*-win32-vs*
diff --git a/build/arm-wince-vs8/.gitattributes b/build/arm-wince-vs8/.gitattributes
new file mode 100644 (file)
index 0000000..be1eeb9
--- /dev/null
@@ -0,0 +1 @@
+*.rules -crlf
diff --git a/build/arm-wince-vs8/armasmv5.rules b/build/arm-wince-vs8/armasmv5.rules
new file mode 100644 (file)
index 0000000..efb80bc
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<VisualStudioToolFile\r
+       Name="armasm"\r
+       Version="8.00"\r
+       >\r
+       <Rules>\r
+               <CustomBuildRule\r
+                       Name="ARMASM"\r
+                       DisplayName="Armasm Assembler"\r
+                       CommandLine="armasm -o &quot;$(IntDir)\$(InputName).obj&quot; $(InputPath) -32 -ARCH 5&#x0D;&#x0A;"\r
+                       Outputs="$(IntDir)\$(InputName).obj"\r
+                       FileExtensions="*.asm"\r
+                       ExecutionDescription="Assembling $(InputName).asm"\r
+                       ShowOnlyRuleProperties="false"\r
+                       >\r
+                       <Properties>\r
+                       </Properties>\r
+               </CustomBuildRule>\r
+       </Rules>\r
+</VisualStudioToolFile>\r
diff --git a/build/arm-wince-vs8/armasmv6.rules b/build/arm-wince-vs8/armasmv6.rules
new file mode 100644 (file)
index 0000000..67c6bc9
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<VisualStudioToolFile\r
+       Name="armasm"\r
+       Version="8.00"\r
+       >\r
+       <Rules>\r
+               <CustomBuildRule\r
+                       Name="ARMASM"\r
+                       DisplayName="Armasm Assembler"\r
+                       CommandLine="armasm -o &quot;$(IntDir)\$(InputName).obj&quot; $(InputPath) -32 -ARCH 6&#x0D;&#x0A;"\r
+                       Outputs="$(IntDir)\$(InputName).obj"\r
+                       FileExtensions="*.asm"\r
+                       ExecutionDescription="Assembling $(InputName).asm"\r
+                       ShowOnlyRuleProperties="false"\r
+                       >\r
+                       <Properties>\r
+                       </Properties>\r
+               </CustomBuildRule>\r
+       </Rules>\r
+</VisualStudioToolFile>\r
diff --git a/build/arm-wince-vs8/armasmxscale.rules b/build/arm-wince-vs8/armasmxscale.rules
new file mode 100644 (file)
index 0000000..4da9d1e
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<VisualStudioToolFile\r
+       Name="armasm"\r
+       Version="8.00"\r
+       >\r
+       <Rules>\r
+               <CustomBuildRule\r
+                       Name="ARMASM"\r
+                       DisplayName="Armasm Assembler"\r
+                       CommandLine="armasm -o &quot;$(IntDir)\$(InputName).obj&quot; $(InputPath) -32 -cpu XSCALE&#x0D;&#x0A;"\r
+                       Outputs="$(IntDir)\$(InputName).obj"\r
+                       FileExtensions="*.asm"\r
+                       ExecutionDescription="Assembling $(InputName).asm"\r
+                       ShowOnlyRuleProperties="false"\r
+                       >\r
+                       <Properties>\r
+                       </Properties>\r
+               </CustomBuildRule>\r
+       </Rules>\r
+</VisualStudioToolFile>\r
diff --git a/build/arm-wince-vs8/obj_int_extract.bat b/build/arm-wince-vs8/obj_int_extract.bat
new file mode 100644 (file)
index 0000000..e58bdd6
--- /dev/null
@@ -0,0 +1,12 @@
+@echo off
+REM   Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+REM 
+REM   Use of this source code is governed by a BSD-style license and patent
+REM   grant that can be found in the LICENSE file in the root of the source
+REM   tree. All contributing project authors may be found in the AUTHORS
+REM   file in the root of the source tree.
+echo on
+
+
+cl /I ".\\" /I "..\vp6_decoder_sdk" /I "..\vp6_decoder_sdk\vpx_ports" /D "NDEBUG" /D "_WIN32_WCE=0x420" /D "UNDER_CE" /D "WIN32_PLATFORM_PSPC" /D "WINCE" /D "_LIB" /D "ARM" /D "_ARM_" /D "_UNICODE" /D "UNICODE" /D "HAVE_CONFIG_H" /FD /EHsc /MT /GS- /fp:fast /GR- /Fo"Pocket_PC_2003__ARMV4_\%1/" /Fd"Pocket_PC_2003__ARMV4_\%1/vc80.pdb" /W3 /nologo /c /TC ..\vp6_decoder_sdk\vp6_decoder\algo\common\arm\dec_asm_offsets_arm.c\r
+obj_int_extract.exe rvds "Pocket_PC_2003__ARMV4_\%1/dec_asm_offsets_arm.obj"\r
diff --git a/build/arm-wince-vs8/vpx_decoder.sln b/build/arm-wince-vs8/vpx_decoder.sln
new file mode 100644 (file)
index 0000000..2262057
--- /dev/null
@@ -0,0 +1,88 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcproj", "{BA5FE66F-38DD-E034-F542-B1578C5FB950}"
+       ProjectSection(ProjectDependencies) = postProject
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74} = {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2} = {E1360C65-D375-4335-8057-7ED99CC3F9B2}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "obj_int_extract", "obj_int_extract.vcproj", "{E1360C65-D375-4335-8057-7ED99CC3F9B2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vpx_decoder", "vpx_decoder.vcproj", "{DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}"
+       ProjectSection(ProjectDependencies) = postProject
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2} = {E1360C65-D375-4335-8057-7ED99CC3F9B2}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xma", "xma.vcproj", "{A955FC4A-73F1-44F7-135E-30D84D32F022}"
+       ProjectSection(ProjectDependencies) = postProject
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2} = {E1360C65-D375-4335-8057-7ED99CC3F9B2}
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74} = {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}
+       EndProjectSection
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Mixed Platforms = Debug|Mixed Platforms
+               Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
+               Debug|Win32 = Debug|Win32
+               Release|Mixed Platforms = Release|Mixed Platforms
+               Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4)
+               Release|Win32 = Release|Win32
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+               {BA5FE66F-38DD-E034-F542-B1578C5FB950}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Debug|Mixed Platforms.ActiveCfg = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Debug|Mixed Platforms.Build.0 = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Debug|Win32.ActiveCfg = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Debug|Win32.Build.0 = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Release|Mixed Platforms.Build.0 = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Release|Win32.ActiveCfg = Release|Win32
+               {E1360C65-D375-4335-8057-7ED99CC3F9B2}.Release|Win32.Build.0 = Release|Win32
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+               {DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Mixed Platforms.Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Pocket PC 2003 (ARMV4).Build.0 = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Pocket PC 2003 (ARMV4).Deploy.0 = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Mixed Platforms.Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Pocket PC 2003 (ARMV4).Build.0 = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Pocket PC 2003 (ARMV4).Deploy.0 = Release|Pocket PC 2003 (ARMV4)
+               {A955FC4A-73F1-44F7-135E-30D84D32F022}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4)
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/build/make/Makefile b/build/make/Makefile
new file mode 100755 (executable)
index 0000000..412629e
--- /dev/null
@@ -0,0 +1,341 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+include config.mk
+quiet?=true
+ifeq ($(target),)
+# If a target wasn't specified, invoke for all enabled targets.
+.DEFAULT:
+       @for t in $(ALL_TARGETS); do \
+            $(MAKE) --no-print-directory target=$$t $(MAKECMDGOALS) || exit $$?;\
+        done
+all: .DEFAULT
+clean:: .DEFAULT
+
+
+# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
+# installed on cygwin, so we need to autodetect here.
+md5sum := $(firstword $(wildcard \
+          $(foreach e,md5sum openssl,\
+          $(foreach p,$(subst :, ,$(PATH)),$(p)/$(e)*))\
+          ))
+md5sum := $(if $(filter %openssl,$(md5sum)),$(md5sum) dgst -md5,$(md5sum))
+
+TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN)))
+install:
+       @for t in $(ALL_TARGETS); do \
+            $(MAKE) --no-print-directory target=$$t $(MAKECMDGOALS) || exit $$?;\
+        done
+        # Run configure for the user with the current toolchain.
+       @if [ -d "$(DIST_DIR)/src" ]; then \
+            mkdir -p "$(DIST_DIR)/build"; \
+            cd "$(DIST_DIR)/build"; \
+            if [ $(TGT_CC) = "rvct" ] ; then \
+                               echo "../src/configure --target=$(TOOLCHAIN) --libc=$(ALT_LIBC)"; \
+                               ../src/configure --target=$(TOOLCHAIN) --libc=$(ALT_LIBC); \
+                       else \
+                               echo "../src/configure --target=$(TOOLCHAIN)"; \
+                               ../src/configure --target=$(TOOLCHAIN); \
+                       fi; \
+            $(if $(filter vs%,$(TGT_CC)),make NO_LAUNCH_DEVENV=1;) \
+        fi
+       @if [ -d "$(DIST_DIR)" ]; then \
+            echo "    [MD5SUM] $(DIST_DIR)"; \
+           cd $(DIST_DIR) && \
+           $(md5sum) `find . -name md5sums.txt -prune -o -type f -print` \
+                | sed -e 's/MD5(\(.*\))= \([0-9a-f]\{32\}\)/\2  \1/' \
+                > md5sums.txt;\
+        fi
+
+
+svnstat: ALL_TARGETS:=$(firstword $(ALL_TARGETS))
+endif
+
+ifneq ($(target),)
+# Normally, we want to build the filename from the target and the toolchain.
+# This disambiguates from the $(target).mk file that exists in the source tree.
+# However, the toolchain is part of the target in universal builds, so we
+# don't want to include TOOLCHAIN in that case. FAT_ARCHS is used to test
+# if we're in the universal case.
+include $(target)$(if $(FAT_ARCHS),,-$(TOOLCHAIN)).mk
+endif
+BUILD_ROOT?=.
+VPATH=$(SRC_PATH_BARE)
+CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)
+ASFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)
+DIST_DIR?=dist
+HOSTCC?=gcc
+TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
+TGT_OS:=$(word 2, $(subst -, ,$(TOOLCHAIN)))
+TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN)))
+quiet:=$(if $(verbose),,yes)
+qexec=$(if $(quiet),@)
+
+# Cancel built-in implicit rules
+%: %.o
+%.asm:
+%.a:
+
+#
+# Common rules"
+#
+.PHONY: all-$(target)
+all-$(target):
+
+.PHONY: clean
+clean::
+       rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.s.o=.asm.s)
+       rm -f $(CLEAN-OBJS)
+
+.PHONY: install
+install:
+.PHONY: install-helper
+install-helper:
+
+$(BUILD_PFX)%.c.d: %.c
+       $(if $(quiet),@echo "    [DEP] $@")
+       $(qexec)mkdir -p $(dir $@)
+       $(qexec)$(CC) $(CFLAGS) -M $< | $(fmt_deps) > $@
+
+$(BUILD_PFX)%.c.o: %.c
+       $(if $(quiet),@echo "    [CC] $@")
+       $(qexec)$(CC) $(CFLAGS) -c -o $@ $<
+
+$(BUILD_PFX)%.asm.d: %.asm
+       $(if $(quiet),@echo "    [DEP] $@")
+       $(qexec)mkdir -p $(dir $@)
+       $(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
+            --build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
+
+$(BUILD_PFX)%.asm.o: %.asm
+       $(if $(quiet),@echo "    [AS] $@")
+       $(qexec)$(AS) $(ASFLAGS) -o $@ $<
+
+$(BUILD_PFX)%.s.d: %.s
+       $(if $(quiet),@echo "    [DEP] $@")
+       $(qexec)mkdir -p $(dir $@)
+       $(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
+            --build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
+
+$(BUILD_PFX)%.s.o: %.s
+       $(if $(quiet),@echo "    [AS] $@")
+       $(qexec)$(AS) $(ASFLAGS) -o $@ $<
+
+.PRECIOUS: %.asm.s
+$(BUILD_PFX)%.asm.s: %.asm
+       $(if $(quiet),@echo "    [ASM CONVERSION] $@")
+       $(qexec)mkdir -p $(dir $@)
+       $(qexec)$(ASM_CONVERSION) <$< >$@
+
+# If we're in debug mode, pretend we don't have GNU strip, to fall back to
+# the copy implementation
+HAVE_GNU_STRIP := $(if $(CONFIG_DEBUG),,$(HAVE_GNU_STRIP))
+ifeq ($(HAVE_GNU_STRIP),yes)
+# Older binutils strip global sybols not needed for relocation processing
+# when given --strip-unneeded. Use nm and awk to identify globals and
+# keep them.
+%.a: %_g.a
+       $(if $(quiet),@echo "    [STRIP] $@ < $<")
+       $(qexec)$(STRIP) --strip-unneeded \
+         `$(NM) $< | grep ' [A-TV-Z] ' | awk '{print "-K"$$3'}`\
+          -o $@ $<
+else
+%.a: %_g.a
+       $(if $(quiet),@echo "    [CP] $@ < $<")
+       $(qexec)cp $< $@
+endif
+
+#
+# Rule to extract assembly constants from C sources
+#
+obj_int_extract: build/make/obj_int_extract.c
+       $(if $(quiet),echo "    [HOSTCC] $@")
+       $(qexec)$(HOSTCC) -I. -o $@ $<
+CLEAN-OBJS += obj_int_extract
+
+#
+# Utility functions
+#
+pairmap=$(if $(strip $(2)),\
+    $(call $(1),$(word 1,$(2)),$(word 2,$(2)))\
+    $(call pairmap,$(1),$(wordlist 3,$(words $(2)),$(2)))\
+)
+
+enabled=$(filter-out $($(1)-no),$($(1)-yes))
+cond_enabled=$(if $(filter yes,$($(1))), $(call enabled,$(2)))
+
+find_file1=$(word 1,$(wildcard $(subst //,/,$(addsuffix /$(1),$(2)))))
+find_file=$(foreach f,$(1),$(call find_file1,$(strip $(f)),$(strip $(2))) )
+obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o
+objs=$(addprefix $(BUILD_PFX),$(foreach p,$(obj_pats),$(filter %.o,$(1:$(p))) ))
+
+install_map_templates=$(eval $(call install_map_template,$(1),$(2)))
+
+not=$(subst yes,no,$(1))
+
+ifeq ($(CONFIG_MSVS),yes)
+lib_file_name=$(1).lib
+else
+lib_file_name=lib$(1).a
+endif
+#
+# Rule Templates
+#
+define linker_template
+$(1): $(filter-out -%,$(2))
+$(1):
+       $(if $(quiet),@echo    "    [LD] $$@")
+       $(qexec)$$(LD) $$(strip $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs))
+endef
+# make-3.80 has a bug with expanding large input strings to the eval function,
+# which was triggered in some cases by the following component of
+# linker_template:
+#   $(1): $$(call find_file, $(patsubst -l%,lib%.a,$(filter -l%,$(2))),\
+#                           $$(patsubst -L%,%,$$(filter -L%,$$(LDFLAGS) $(2))))
+# This may be useful to revisit in the future (it tries to locate libraries
+# in a search path and add them as prerequisites
+
+define install_map_template
+$(DIST_DIR)/$(1): $(2)
+       $(if $(quiet),@echo "    [INSTALL] $$@")
+       $(qexec)mkdir -p $$(dir $$@)
+       $(qexec)cp -p $$< $$@
+endef
+
+define archive_template
+# Not using a pattern rule here because we don't want to generate empty
+# archives when they are listed as a dependency in files not responsible
+# for creating them.
+$(1):
+       $(if $(quiet),@echo "    [AR] $$@")
+       $(qexec)$$(AR) $$(ARFLAGS) $$@ $$?
+endef
+
+define lipo_lib_template
+$(1): $(addsuffix /$(1),$(FAT_ARCHS))
+       $(if $(quiet),@echo "    [LIPO] $$@")
+       $(qexec)libtool -static -o $$@ $$?
+endef
+
+define lipo_bin_template
+$(1): $(addsuffix /$(1),$(FAT_ARCHS))
+       $(if $(quiet),@echo "    [LIPO] $$@")
+       $(qexec)lipo -output $$@ -create $$?
+endef
+
+
+#
+# Get current configuration
+#
+ifneq ($(target),)
+include $(SRC_PATH_BARE)/$(target:-$(TOOLCHAIN)=).mk
+endif
+ifeq ($(filter clean,$(MAKECMDGOALS)),)
+  # Older versions of make don't like -include directives with no arguments
+  ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),)
+    -include $(filter %.d,$(OBJS-yes:.o=.d))
+  endif
+endif
+
+#
+# Configuration dependant rules
+#
+$(call pairmap,install_map_templates,$(INSTALL_MAPS))
+
+DOCS=$(call cond_enabled,CONFIG_INSTALL_DOCS,DOCS)
+.docs: $(DOCS)
+       @touch $@
+
+INSTALL-DOCS=$(call cond_enabled,CONFIG_INSTALL_DOCS,INSTALL-DOCS)
+.install-docs: .docs $(addprefix $(DIST_DIR)/,$(INSTALL-DOCS))
+       @touch $@
+
+clean::
+       rm -f .docs .install-docs $(DOCS)
+
+BINS=$(call enabled,BINS)
+.bins: $(BINS)
+       @touch $@
+
+INSTALL-BINS=$(call cond_enabled,CONFIG_INSTALL_BINS,INSTALL-BINS)
+.install-bins: .bins $(addprefix $(DIST_DIR)/,$(INSTALL-BINS))
+       @touch $@
+
+clean::
+       rm -f .bins .install-bins $(BINS)
+
+LIBS=$(call enabled,LIBS)
+.libs: $(LIBS)
+       @touch $@
+$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib))))
+
+INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS)
+.install-libs: .libs $(addprefix $(DIST_DIR)/,$(INSTALL-LIBS))
+       @touch $@
+
+clean::
+       rm -f .libs .install-libs $(LIBS)
+
+ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
+PROJECTS=$(call enabled,PROJECTS)
+.projects: $(PROJECTS)
+       @touch $@
+
+INSTALL-PROJECTS=$(call cond_enabled,CONFIG_INSTALL_PROJECTS,INSTALL-PROJECTS)
+.install-projects: .projects $(addprefix $(DIST_DIR)/,$(INSTALL-PROJECTS))
+       @touch $@
+
+clean::
+       rm -f .projects .install-projects $(PROJECTS)
+endif
+
+# If there are any source files to be installed, then include the build
+# system too.
+ifneq ($(call enabled,INSTALL-SRCS),)
+    INSTALL-SRCS-yes            += configure
+    INSTALL-SRCS-yes            += build/make/configure.sh
+    INSTALL-SRCS-yes            += build/make/gen_asm_deps.sh
+    INSTALL-SRCS-yes            += build/make/Makefile
+    INSTALL-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_def.sh
+    INSTALL-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_proj.sh
+    INSTALL-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_sln.sh
+    INSTALL-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh
+    #
+    # This isn't really ARCH_ARM dependent, it's dependant on whether we're
+    # using assembly code or not (CONFIG_OPTIMIZATIONS maybe). Just use
+    # this for now.
+    INSTALL-SRCS-$(ARCH_ARM)    += build/make/obj_int_extract.c
+    INSTALL-SRCS-$(ARCH_ARM)    += build/make/ads2gas.pl
+    INSTALL-SRCS-yes            += $(target:-$(TOOLCHAIN)=).mk
+endif
+INSTALL-SRCS := $(call cond_enabled,CONFIG_INSTALL_SRCS,INSTALL-SRCS)
+.install-srcs: $(addprefix $(DIST_DIR)/src/,$(INSTALL-SRCS))
+       @touch $@
+
+clean::
+       rm -f .install-srcs
+
+ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
+    BUILD_TARGETS += .projects
+    INSTALL_TARGETS += .install-projects
+endif
+BUILD_TARGETS += .docs .libs .bins
+INSTALL_TARGETS += .install-docs .install-srcs .install-libs .install-bins
+all-$(target): $(BUILD_TARGETS)
+install: $(INSTALL_TARGETS)
+
+#
+# Development helper targets
+#
+ifneq ($(SRC_PATH_BARE),)
+.PHONY: svnstat
+svnstat:
+       svn stat $(SRC_PATH_BARE)
+endif
diff --git a/build/make/ads2gas.pl b/build/make/ads2gas.pl
new file mode 100755 (executable)
index 0000000..6fcba84
--- /dev/null
@@ -0,0 +1,149 @@
+#!/usr/bin/perl
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+# ads2gas.pl
+# Author: Eric Fung (efung (at) acm.org)
+#
+# Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format
+#
+# Usage: cat inputfile | perl ads2gas.pl > outputfile
+#
+print "@ This file was created from a .asm file\n";
+print "@  using the ads2gas.pl script.\n";
+print "\t.equ DO1STROUNDING, 0\n";
+
+while (<STDIN>)
+{
+    # Comment character
+    s/;/@/g;
+
+    # Hexadecimal constants prefaced by 0x
+    s/#&/#0x/g;
+
+    # Convert :OR: to |
+    s/:OR:/ | /g;
+
+    # Convert :AND: to &
+    s/:AND:/ & /g;
+
+    # Convert :NOT: to ~
+    s/:NOT:/ ~ /g;
+
+    # Convert :SHL: to <<
+    s/:SHL:/ << /g;
+
+    # Convert :SHR: to >>
+    s/:SHR:/ >> /g;
+
+    # Convert ELSE to .else
+    s/ELSE/.else/g;
+
+    # Convert ENDIF to .endif
+    s/ENDIF/.endif/g;
+
+    # Convert ELSEIF to .elseif
+    s/ELSEIF/.elseif/g;
+
+    # Convert LTORG to .ltorg
+    s/LTORG/.ltorg/g;
+
+    # Convert IF :DEF:to .if
+    # gcc doesn't have the ability to do a conditional
+    # if defined variable that is set by IF :DEF: on
+    # armasm, so convert it to a normal .if and then
+    # make sure to define a value elesewhere
+    if (s/\bIF :DEF:\b/.if /g)
+    {
+        s/=/==/g;
+    }
+
+    # Convert IF to .if
+    if (s/\bIF\b/.if/g)
+    {
+        s/=+/==/g;
+    }
+
+    # Convert INCLUDE to .INCLUDE "file"
+    s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/;
+
+    # Code directive (ARM vs Thumb)
+    s/CODE([0-9][0-9])/.code $1/;
+
+    # No AREA required
+    s/^\s*AREA.*$/.text/;
+
+    # DCD to .word
+    # This one is for incoming symbols
+    s/DCD\s+\|(\w*)\|/.long $1/;
+
+    # DCW to .short
+    s/DCW\s+\|(\w*)\|/.short $1/;
+    s/DCW(.*)/.short $1/;
+
+    # Constants defined in scope
+    s/DCD(.*)/.long $1/;
+    s/DCB(.*)/.byte $1/;
+
+    # RN to .req
+    if (s/RN\s+([Rr]\d+|lr)/.req $1/)
+    {
+        print;
+        next;
+    }
+
+    # Make function visible to linker, and make additional symbol with
+    # prepended underscore
+    s/EXPORT\s+\|([\$\w]*)\|/.global $1 \n\t.type $1, function/;
+    s/IMPORT\s+\|([\$\w]*)\|/.global $1/;
+
+    # No vertical bars required; make additional symbol with prepended
+    # underscore
+    s/^\|(\$?\w+)\|/_$1\n\t$1:/g;
+
+    # Labels need trailing colon
+#   s/^(\w+)/$1:/ if !/EQU/;
+    # put the colon at the end of the line in the macro
+    s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
+
+    # Strip ALIGN
+    s/\sALIGN/@ ALIGN/g;
+
+    # Strip ARM
+    s/\sARM/@ ARM/g;
+
+    # Strip REQUIRE8
+    #s/\sREQUIRE8/@ REQUIRE8/g;
+    s/\sREQUIRE8/@ /g;      #EQU cause problem
+
+    # Strip PRESERVE8
+    s/\sPRESERVE8/@ PRESERVE8/g;
+
+    # Strip PROC and ENDPROC
+    s/\sPROC/@/g;
+    s/\sENDP/@/g;
+
+    # EQU directive
+    s/(.*)EQU(.*)/.equ $1, $2/;
+
+    # Begin macro definition
+    if (/MACRO/) {
+        $_ = <STDIN>;
+        s/^/.macro/;
+        s/\$//g;                # remove formal param reference
+        s/;/@/g;                # change comment characters
+    }
+
+    # For macros, use \ to reference formal params
+    s/\$/\\/g;                  # End macro definition
+    s/MEND/.endm/;              # No need to tell it where to stop assembling
+    next if /^\s*END\s*$/;
+    print;
+}
diff --git a/build/make/ads2gas_apple.pl b/build/make/ads2gas_apple.pl
new file mode 100755 (executable)
index 0000000..569c3e7
--- /dev/null
@@ -0,0 +1,194 @@
+#!/usr/bin/env perl
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+# ads2gas.pl
+# Author: Eric Fung (efung (at) acm.org)
+#
+# Convert ARM Developer Suite 1.0.1 syntax assembly source to GNU as format
+#
+# Usage: cat inputfile | perl ads2gas.pl > outputfile
+#
+print "@ This file was created from a .asm file\n";
+print "@  using the ads2gas_apple.pl script.\n\n";
+print "\t.set WIDE_REFERENCE, 0\n";
+print "\t.set ARCHITECTURE, 5\n";
+print "\t.set DO1STROUNDING, 0\n";
+
+my %register_aliases;
+my %macro_aliases;
+
+my @mapping_list = ("\$0", "\$1", "\$2", "\$3", "\$4", "\$5", "\$6", "\$7", "\$8", "\$9");
+
+my @incoming_array;
+
+# Perl trim function to remove whitespace from the start and end of the string
+sub trim($)
+{
+    my $string = shift;
+    $string =~ s/^\s+//;
+    $string =~ s/\s+$//;
+    return $string;
+}
+
+while (<STDIN>)
+{
+    # Comment character
+    s/;/@/g;
+
+    # Hexadecimal constants prefaced by 0x
+    s/#&/#0x/g;
+
+    # Convert :OR: to |
+    s/:OR:/ | /g;
+
+    # Convert :AND: to &
+    s/:AND:/ & /g;
+
+    # Convert :NOT: to ~
+    s/:NOT:/ ~ /g;
+
+    # Convert :SHL: to <<
+    s/:SHL:/ << /g;
+
+    # Convert :SHR: to >>
+    s/:SHR:/ >> /g;
+
+    # Convert ELSE to .else
+    s/ELSE/.else/g;
+
+    # Convert ENDIF to .endif
+    s/ENDIF/.endif/g;
+
+    # Convert ELSEIF to .elseif
+    s/ELSEIF/.elseif/g;
+
+    # Convert LTORG to .ltorg
+    s/LTORG/.ltorg/g;
+
+    # Convert IF :DEF:to .if
+    # gcc doesn't have the ability to do a conditional
+    # if defined variable that is set by IF :DEF: on
+    # armasm, so convert it to a normal .if and then
+    # make sure to define a value elesewhere
+    if (s/\bIF :DEF:\b/.if /g)
+    {
+        s/=/==/g;
+    }
+
+    # Convert IF to .if
+    if (s/\bIF\b/.if/g)
+    {
+        s/=/==/g;
+    }
+
+    # Convert INCLUDE to .INCLUDE "file"
+    s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/;
+
+    # Code directive (ARM vs Thumb)
+    s/CODE([0-9][0-9])/.code $1/;
+
+    # No AREA required
+    s/^\s*AREA.*$/.text/;
+
+    # DCD to .word
+    # This one is for incoming symbols
+    s/DCD\s+\|(\w*)\|/.long $1/;
+
+    # DCW to .short
+    s/DCW\s+\|(\w*)\|/.short $1/;
+    s/DCW(.*)/.short $1/;
+
+    # Constants defined in scope
+    s/DCD(.*)/.long $1/;
+    s/DCB(.*)/.byte $1/;
+
+    # Build a hash of all the register - alias pairs.
+    if (s/(.*)RN(.*)/$1 .req $2/g)
+    {
+        $register_aliases{trim($1)} = trim($2);
+        next;
+    }
+
+    while (($key, $value) = each(%register_aliases))
+    {
+        s/\b$key\b/$value/g;
+    }
+
+    # Make function visible to linker, and make additional symbol with
+    # prepended underscore
+    s/EXPORT\s+\|([\$\w]*)\|/.globl _$1\n\t.globl $1/;
+    s/IMPORT\s+\|([\$\w]*)\|/.globl $1/;
+
+    # No vertical bars required; make additional symbol with prepended
+    # underscore
+    s/^\|(\$?\w+)\|/_$1\n\t$1:/g;
+
+    # Labels need trailing colon
+#   s/^(\w+)/$1:/ if !/EQU/;
+    # put the colon at the end of the line in the macro
+    s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
+
+    # Strip ALIGN
+    s/\sALIGN/@ ALIGN/g;
+
+    # Strip ARM
+    s/\sARM/@ ARM/g;
+
+    # Strip REQUIRE8
+    #s/\sREQUIRE8/@ REQUIRE8/g;
+    s/\sREQUIRE8/@ /g;
+
+    # Strip PRESERVE8
+    s/\sPRESERVE8/@ PRESERVE8/g;
+
+    # Strip PROC and ENDPROC
+    s/PROC/@/g;
+    s/ENDP/@/g;
+
+    # EQU directive
+    s/(.*)EQU(.*)/.set $1, $2/;
+
+    # Begin macro definition
+    if (/MACRO/)
+    {
+        # Process next line down, which will be the macro definition
+        $_ = <STDIN>;
+
+        $trimmed = trim($_);
+
+        # remove commas that are separating list
+        $trimmed =~ s/,//g;
+
+        # string to array
+        @incoming_array = split(/ /, $trimmed);
+
+        print ".macro @incoming_array[0]\n";
+
+        # remove the first element, as that is the name of the macro
+        shift (@incoming_array);
+
+        @macro_aliases{@incoming_array} = @mapping_list;
+
+        next;
+    }
+
+    while (($key, $value) = each(%macro_aliases))
+    {
+        $key =~ s/\$/\\\$/;
+        s/$key\b/$value/g;
+    }
+
+    # For macros, use \ to reference formal params
+#   s/\$/\\/g;                  # End macro definition
+    s/MEND/.endm/;              # No need to tell it where to stop assembling
+    next if /^\s*END\s*$/;
+    print;
+}
diff --git a/build/make/armlink_adapter.sh b/build/make/armlink_adapter.sh
new file mode 100755 (executable)
index 0000000..dcaa82c
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+verbose=0
+set -- $*
+for i; do
+    if [ "$i" == "-o" ]; then
+        on_of=1
+    elif [ "$i" == "-v" ]; then
+        verbose=1
+    elif [ "$on_of" == "1" ]; then
+        outfile=$i
+    on_of=0
+    elif [ -f "$i" ]; then
+        infiles="$infiles $i"
+    elif [ "${i:0:2}" == "-l" ]; then
+        libs="$libs ${i#-l}"
+    elif [ "${i:0:2}" == "-L" ]; then
+    libpaths="${libpaths} ${i#-L}"
+    else
+        args="${args} ${i}"
+    fi
+    shift
+done
+
+# Absolutize library file names
+for f in $libs; do
+    found=0
+    for d in $libpaths; do
+        [ -f "$d/$f" ] && infiles="$infiles $d/$f" && found=1 && break
+        [ -f "$d/lib${f}.so" ] && infiles="$infiles $d/lib${f}.so" && found=1 && break
+        [ -f "$d/lib${f}.a" ] && infiles="$infiles $d/lib${f}.a" && found=1 && break
+    done
+    [ $found -eq 0 ] && infiles="$infiles $f"
+done
+for d in $libpaths; do
+    [ -n "$libsearchpath" ] && libsearchpath="${libsearchpath},"
+    libsearchpath="${libsearchpath}$d"
+done
+
+cmd="armlink $args --userlibpath=$libsearchpath --output=$outfile $infiles"
+[ $verbose -eq 1 ] && echo $cmd
+$cmd
diff --git a/build/make/configure.sh b/build/make/configure.sh
new file mode 100755 (executable)
index 0000000..ed3a34f
--- /dev/null
@@ -0,0 +1,907 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+
+#
+# Logging / Output Functions
+#
+die_unknown(){
+    echo "Unknown option \"$1\"."
+    echo "See $0 --help for available options."
+    clean_temp_files
+    exit 1
+}
+
+
+die() {
+    echo "$@"
+    echo
+    echo "Configuration failed. This could reflect a misconfiguration of your"
+    echo "toolchains, improper options selected, or another problem. If you"
+    echo "don't see any useful error messages above, the next step is to look"
+    echo "at the configure error log file ($logfile) to determine what"
+    echo "configure was trying to do when it died."
+    clean_temp_files
+    exit 1
+}
+
+
+log(){
+    echo "$@" >>$logfile
+}
+
+
+log_file(){
+    log BEGIN $1
+    pr -n -t $1 >>$logfile
+    log END $1
+}
+
+
+log_echo() {
+    echo "$@"
+    log "$@"
+}
+
+
+fwrite () {
+    outfile=$1
+    shift
+    echo "$@" >> ${outfile}
+}
+
+
+show_help_pre(){
+    for opt in ${CMDLINE_SELECT}; do
+        opt2=`echo $opt | sed -e 's;_;-;g'`
+        if enabled $opt; then
+            eval "toggle_${opt}=\"--disable-${opt2}\""
+        else
+            eval "toggle_${opt}=\"--enable-${opt2} \""
+        fi
+    done
+
+    cat <<EOF
+Usage: configure [options]
+Options:
+
+Build options:
+  --help                      print this message
+  --log=yes|no|FILE           file configure log is written to [config.err]
+  --target=TARGET             target platform tuple [generic-gnu]
+  --cpu=CPU                   optimize for a specific cpu rather than a family
+  ${toggle_extra_warnings}    emit harmless warnings (always non-fatal)
+  ${toggle_werror}            treat warnings as errors, if possible
+                              (not available with all compilers)
+  ${toggle_optimizations}     turn on/off compiler optimization flags
+  ${toggle_pic}               turn on/off Position Independant Code
+  ${toggle_ccache}            turn on/off compiler cache
+  ${toggle_debug}             enable/disable debug mode
+  ${toggle_gprof}             enable/disable gprof profiling instrumentation
+  ${toggle_gcov}              enable/disable gcov coverage instrumentation
+
+Install options:
+  ${toggle_install_docs}      control whether docs are installed
+  ${toggle_install_bins}      control whether binaries are installed
+  ${toggle_install_libs}      control whether libraries are installed
+  ${toggle_install_srcs}      control whether sources are installed
+
+
+EOF
+}
+
+
+show_help_post(){
+    cat <<EOF
+
+
+NOTES:
+    Object files are built at the place where configure is launched.
+
+    All boolean options can be negated. The default value is the opposite
+    of that shown above. If the option --disable-foo is listed, then
+    the default value for foo is enabled.
+
+Supported targets:
+EOF
+  show_targets ${all_platforms}
+  echo
+  exit 1
+}
+
+
+show_targets() {
+    while [ -n "$*" ]; do
+        if [ "${1%%-*}" == "${2%%-*}" ]; then
+            if [ "${2%%-*}" == "${3%%-*}" ]; then
+                printf "    %-24s %-24s %-24s\n" "$1" "$2" "$3"
+                shift; shift; shift
+            else
+                printf "    %-24s %-24s\n" "$1" "$2"
+                shift; shift
+            fi
+        else
+            printf "    %-24s\n" "$1"
+            shift
+        fi
+    done
+}
+
+
+show_help() {
+    show_help_pre
+    show_help_post
+}
+
+#
+# List Processing Functions
+#
+set_all(){
+    value=$1
+    shift
+    for var in $*; do
+        eval $var=$value
+    done
+}
+
+
+is_in(){
+    value=$1
+    shift
+    for var in $*; do
+        [ $var = $value ] && return 0
+    done
+    return 1
+}
+
+
+add_cflags() {
+    CFLAGS="${CFLAGS} $@"
+}
+
+
+add_ldflags() {
+    LDFLAGS="${LDFLAGS} $@"
+}
+
+
+add_asflags() {
+    ASFLAGS="${ASFLAGS} $@"
+}
+
+
+add_extralibs() {
+    extralibs="${extralibs} $@"
+}
+
+#
+# Boolean Manipulation Functions
+#
+enable(){
+    set_all yes $*
+}
+
+disable(){
+    set_all no $*
+}
+
+enabled(){
+    eval test "x\$$1" = "xyes"
+}
+
+disabled(){
+    eval test "x\$$1" = "xno"
+}
+
+
+soft_enable() {
+    for var in $*; do
+        if ! disabled $var; then
+            log_echo "  enabling $var"
+            enable $var
+        fi
+    done
+}
+
+soft_disable() {
+    for var in $*; do
+        if ! enabled $var; then
+            log_echo "  disabling $var"
+            disable $var
+        fi
+    done
+}
+
+
+#
+# Text Processing Functions
+#
+toupper(){
+    echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+}
+
+
+tolower(){
+    echo "$@" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
+}
+
+
+#
+# Temporary File Functions
+#
+source_path=${0%/*}
+enable source_path_used
+if test -z "$source_path" -o "$source_path" = "." ; then
+    source_path="`pwd`"
+    disable source_path_used
+fi
+
+if test ! -z "$TMPDIR" ; then
+    TMPDIRx="${TMPDIR}"
+elif test ! -z "$TEMPDIR" ; then
+    TMPDIRx="${TEMPDIR}"
+else
+    TMPDIRx="/tmp"
+fi
+TMP_H="${TMPDIRx}/vpx-conf-$$-${RANDOM}.h"
+TMP_C="${TMPDIRx}/vpx-conf-$$-${RANDOM}.c"
+TMP_O="${TMPDIRx}/vpx-conf-$$-${RANDOM}.o"
+TMP_X="${TMPDIRx}/vpx-conf-$$-${RANDOM}.x"
+
+clean_temp_files() {
+    rm -f ${TMP_C} ${TMP_H} ${TMP_O} ${TMP_X}
+}
+
+#
+# Toolchain Check Functions
+#
+check_cmd() {
+    log "$@"
+    "$@" >>${logfile} 2>&1
+}
+
+check_cc() {
+    log check_cc "$@"
+    cat >${TMP_C}
+    log_file ${TMP_C}
+    check_cmd ${CC} ${CFLAGS} "$@" -c -o ${TMP_O} ${TMP_C}
+}
+
+check_cpp() {
+    log check_cpp "$@"
+    cat > ${TMP_C}
+    log_file ${TMP_C}
+    check_cmd ${CC} ${CFLAGS} "$@" -E -o ${TMP_O} ${TMP_C}
+}
+
+check_ld() {
+    log check_ld "$@"
+    check_cc $@ \
+        && check_cmd ${LD} ${LDFLAGS} "$@" -o ${TMP_X} ${TMP_O} ${extralibs}
+}
+
+check_header(){
+    log check_header "$@"
+    header=$1
+    shift
+    var=`echo $header | sed 's/[^A-Za-z0-9_]/_/g'`
+    disable $var
+    check_cpp "$@" <<EOF && enable $var
+#include "$header"
+int x;
+EOF
+}
+
+
+check_cflags() {
+    log check_cflags "$@"
+    check_cc "$@" <<EOF
+int x;
+EOF
+}
+
+check_add_cflags() {
+    check_cflags "$@" && add_cflags "$@"
+}
+
+check_add_asflags() {
+    log add_asflags "$@"
+    add_asflags "$@"
+}
+
+check_add_ldflags() {
+    log add_ldflags "$@"
+    add_ldflags "$@"
+}
+
+write_common_config_banner() {
+    echo '# This file automatically generated by configure. Do not edit!' > config.mk
+    echo "TOOLCHAIN := ${toolchain}" >> config.mk
+
+    case ${toolchain} in
+        *-linux-rvct)
+            echo "ALT_LIBC := ${alt_libc}" >> config.mk
+            ;;
+    esac
+}
+
+write_common_config_targets() {
+    for t in ${all_targets}; do
+        if enabled ${t}; then
+            if enabled universal || enabled child; then
+                fwrite config.mk "ALL_TARGETS += ${t}-${toolchain}"
+            else
+                fwrite config.mk "ALL_TARGETS += ${t}"
+            fi
+        fi
+    true;
+    done
+true
+}
+
+write_common_target_config_mk() {
+    [ -n "$2" ] && local have_config_h="-DHAVE_CONFIG_H=\"${2##*/}\""
+    local CC=${CC}
+    enabled ccache && CC="ccache ${CC}"
+
+    cat > $1 << EOF
+# This file automatically generated by configure. Do not edit!
+SRC_PATH="$source_path"
+SRC_PATH_BARE=$source_path
+BUILD_PFX=${BUILD_PFX}
+TOOLCHAIN=${toolchain}
+ASM_CONVERSION=${asm_conversion_cmd:-${source_path}/build/make/ads2gas.pl}
+
+CC=${CC}
+AR=${AR}
+LD=${LD}
+AS=${AS}
+STRIP=${STRIP}
+NM=${NM}
+
+CFLAGS  = ${CFLAGS} ${have_config_h}
+ARFLAGS = -rus\$(if \$(quiet),c,v)
+LDFLAGS = ${LDFLAGS}
+ASFLAGS = ${ASFLAGS}
+extralibs = ${extralibs}
+AS_SFX    = ${AS_SFX:-.asm}
+EOF
+
+    if enabled rvct; then cat >> $1 << EOF
+fmt_deps = sed -e 's;^__image.axf;\$(dir \$@)\$(notdir \$<).o \$@;' #hide
+EOF
+    else cat >> $1 << EOF
+fmt_deps = sed -e 's;^\(.*\)\.o;\$(dir \$@)\1\$(suffix \$<).o \$@;' #hide
+EOF
+    fi
+
+    print_config_mk ARCH   "${1}" ${ARCH_LIST}
+    print_config_mk HAVE   "${1}" ${HAVE_LIST}
+    print_config_mk CONFIG "${1}" ${CONFIG_LIST}
+    print_config_mk HAVE   "${1}" gnu_strip
+
+    enabled msvs && echo "CONFIG_VS_VERSION=${vs_version}" >> "${1}"
+
+}
+
+
+write_common_target_config_h() {
+    cat > ${TMP_H} << EOF
+/* This file automatically generated by configure. Do not edit! */
+#define INLINE      ${INLINE}
+#define FORCEINLINE ${FORCEINLINE:-${INLINE}}
+#define RESTRICT    ${RESTRICT}
+EOF
+    print_config_h ARCH   "${TMP_H}" ${ARCH_LIST}
+    print_config_h HAVE   "${TMP_H}" ${HAVE_LIST}
+    print_config_h CONFIG "${TMP_H}" ${CONFIG_LIST}
+    mkdir -p `dirname "$1"`
+    cmp "$1" ${TMP_H} >/dev/null 2>&1 || mv ${TMP_H} "$1"
+}
+
+process_common_cmdline() {
+    for opt in "$@"; do
+        optval="${opt#*=}"
+        case "$opt" in
+        --child) enable child
+        ;;
+        --log*)
+        logging="$optval"
+        if ! disabled logging ; then
+            enabled logging || logfile="$logging"
+        else
+            logfile=/dev/null
+        fi
+        ;;
+        --target=*) toolchain="${toolchain:-${optval}}"
+        ;;
+        --force-target=*) toolchain="${toolchain:-${optval}}"; enable force_toolchain
+        ;;
+        --cpu)
+        ;;
+        --cpu=*) tune_cpu="$optval"
+        ;;
+        --enable-?*|--disable-?*)
+        eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
+        echo "${CMDLINE_SELECT} ${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null || die_unknown $opt
+        $action $option
+        ;;
+        --force-enable-?*|--force-disable-?*)
+        eval `echo "$opt" | sed 's/--force-/action=/;s/-/ option=/;s/-/_/g'`
+        $action $option
+        ;;
+        --libc=*)
+        [ -d "${optval}" ] || die "Not a directory: ${optval}"
+        disable builtin_libc
+        alt_libc="${optval}"
+        ;;
+        --libc)
+        die "Option ${opt} requires argument"
+        ;;
+        --help|-h) show_help
+        ;;
+        *) die_unknown $opt
+        ;;
+        esac
+    done
+}
+
+process_cmdline() {
+    for opt do
+        optval="${opt#*=}"
+        case "$opt" in
+        *) process_common_cmdline $opt
+        ;;
+        esac
+    done
+}
+
+post_process_cmdline() {
+    true;
+}
+
+setup_gnu_toolchain() {
+        CC=${CC:-${CROSS}gcc}
+        AR=${AR:-${CROSS}ar}
+        LD=${LD:-${CROSS}${link_with_cc:-ld}}
+        AS=${AS:-${CROSS}as}
+    STRIP=${STRIP:-${CROSS}strip}
+    NM=${NM:-${CROSS}nm}
+        AS_SFX=.s
+}
+
+process_common_toolchain() {
+    toolchain=${toolchain:-generic-gnu}
+
+    is_in ${toolchain} ${all_platforms} || enabled force_toolchain \
+        || die "Unrecognized toolchain '${toolchain}'"
+
+    enabled child || log_echo "Configuring for target '${toolchain}'"
+
+    #
+    # Set up toolchain variables
+    #
+    tgt_isa=$(echo ${toolchain} | awk 'BEGIN{FS="-"}{print $1}')
+    tgt_os=$(echo ${toolchain} | awk 'BEGIN{FS="-"}{print $2}')
+    tgt_cc=$(echo ${toolchain} | awk 'BEGIN{FS="-"}{print $3}')
+
+    # Mark the specific ISA requested as enabled
+    soft_enable ${tgt_isa}
+    enable ${tgt_os}
+    enable ${tgt_cc}
+
+    # Enable the architecture family
+    case ${tgt_isa} in
+        arm*|iwmmxt*) enable arm;;
+    mips*)        enable mips;;
+    esac
+
+    # Handle darwin variants
+    case ${toolchain} in
+        *-darwin8-gcc)
+            add_cflags  "-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
+            add_cflags  "-mmacosx-version-min=10.4"
+            add_ldflags "-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
+            add_ldflags "-mmacosx-version-min=10.4"
+            ;;
+        *-darwin9-gcc)
+            add_cflags  "-isysroot /Developer/SDKs/MacOSX10.5.sdk"
+            add_cflags  "-mmacosx-version-min=10.5"
+            add_ldflags "-isysroot /Developer/SDKs/MacOSX10.5.sdk"
+            add_ldflags "-mmacosx-version-min=10.5"
+            ;;
+    esac
+
+    # Process ARM architecture variants
+    case ${toolchain} in
+    arm*|iwmmxt*)
+    # on arm, isa versions are supersets
+    enabled armv7a && soft_enable armv7 ### DEBUG
+    enabled armv7 && soft_enable armv6
+    enabled armv6 && soft_enable armv5te
+    enabled armv6 && soft_enable fast_unaligned
+    enabled iwmmxt2 && soft_enable iwmmxt
+    enabled iwmmxt && soft_enable armv5te
+
+    asm_conversion_cmd="cat"
+
+        case ${tgt_cc} in
+        gcc)
+        if enabled iwmmxt || enabled iwmmxt2
+            then
+                CROSS=${CROSS:-arm-iwmmxt-linux-gnueabi-}
+            elif enabled symbian; then
+                CROSS=${CROSS:-arm-none-symbianelf-}
+            else
+                CROSS=${CROSS:-arm-none-linux-gnueabi-}
+            fi
+            link_with_cc=gcc
+            setup_gnu_toolchain
+            arch_int=${tgt_isa##armv}
+            arch_int=${arch_int%%te}
+            check_add_asflags --defsym ARCHITECTURE=${arch_int}
+            tune_cflags="-mtune="
+        if enabled iwmmxt || enabled iwmmxt2
+            then
+                check_add_asflags -mcpu=${tgt_isa}
+            elif enabled armv7
+            then
+                check_add_cflags -march=armv7-a -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp  #-ftree-vectorize
+        check_add_asflags -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp  #-march=armv7-a
+            else
+                check_add_cflags -march=${tgt_isa}
+                check_add_asflags -march=${tgt_isa}
+            fi
+
+            asm_conversion_cmd="${source_path}/build/make/ads2gas.pl"
+            ;;
+        rvct)
+            CC=armcc
+            AR=armar
+            AS=armasm
+            LD=${source_path}/build/make/armlink_adapter.sh
+            STRIP=arm-none-linux-gnueabi-strip
+            NM=arm-none-linux-gnueabi-nm
+            tune_cflags="--cpu="
+            tune_asflags="--cpu="
+            if [ -z "${tune_cpu}" ]; then
+            if enabled armv7
+                then
+                    check_add_cflags --cpu=Cortex-A8 --fpu=softvfp+vfpv3
+                    check_add_asflags --cpu=Cortex-A8 --fpu=none
+                else
+                    check_add_cflags --cpu=${tgt_isa##armv}
+                    check_add_asflags --cpu=${tgt_isa##armv}
+                fi
+            fi
+            arch_int=${tgt_isa##armv}
+            arch_int=${arch_int%%te}
+            check_add_asflags --pd "\"ARCHITECTURE SETA ${arch_int}\""
+        ;;
+        esac
+
+        case ${tgt_os} in
+        darwin*)
+            SDK_PATH=/Developer/Platforms/iPhoneOS.platform/Developer
+            TOOLCHAIN_PATH=${SDK_PATH}/usr/bin
+            CC=${TOOLCHAIN_PATH}/gcc
+            AR=${TOOLCHAIN_PATH}/ar
+            LD=${TOOLCHAIN_PATH}/arm-apple-darwin9-gcc-4.2.1
+            AS=${TOOLCHAIN_PATH}/as
+            STRIP=${TOOLCHAIN_PATH}/strip
+            NM=${TOOLCHAIN_PATH}/nm
+            AS_SFX=.s
+
+            # ASFLAGS is written here instead of using check_add_asflags
+            # because we need to overwrite all of ASFLAGS and purge the
+            # options that were put in above
+            ASFLAGS="-version -arch ${tgt_isa} -g"
+
+            add_cflags -arch ${tgt_isa}
+            add_ldflags -arch_only ${tgt_isa}
+
+            add_cflags  "-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk"
+
+            # This should be overridable
+            alt_libc=${SDK_PATH}/SDKs/iPhoneOS3.1.sdk
+
+            # Add the paths for the alternate libc
+#            for d in usr/include usr/include/gcc/darwin/4.0/; do
+            for d in usr/include usr/include/gcc/darwin/4.0/ usr/lib/gcc/arm-apple-darwin9/4.0.1/include/; do
+                try_dir="${alt_libc}/${d}"
+                [ -d "${try_dir}" ] && add_cflags -I"${try_dir}"
+            done
+
+            for d in lib usr/lib; do
+                try_dir="${alt_libc}/${d}"
+                [ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
+            done
+
+            asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl"
+         ;;
+
+        linux*)
+            enable linux
+            if enabled rvct; then
+                # Compiling with RVCT requires an alternate libc (glibc) when
+                # targetting linux.
+                disabled builtin_libc \
+                    || die "Must supply --libc when targetting *-linux-rvct"
+
+                # Set up compiler
+                add_cflags --gnu
+                add_cflags --enum_is_int
+                add_cflags --library_interface=aeabi_glibc
+                add_cflags --no_hide_all
+                add_cflags --wchar32
+                add_cflags --dwarf2
+                add_cflags --gnu
+
+                # Set up linker
+                add_ldflags --sysv --no_startup --no_ref_cpp_init
+                add_ldflags --entry=_start
+                add_ldflags --keep '"*(.init)"' --keep '"*(.fini)"'
+                add_ldflags --keep '"*(.init_array)"' --keep '"*(.fini_array)"'
+                add_ldflags --dynamiclinker=/lib/ld-linux.so.3
+                add_extralibs libc.so.6 -lc_nonshared crt1.o crti.o crtn.o
+
+                # Add the paths for the alternate libc
+                for d in usr/include; do
+                    try_dir="${alt_libc}/${d}"
+                    [ -d "${try_dir}" ] && add_cflags -J"${try_dir}"
+                done
+                add_cflags -J"${RVCT31INC}"
+                for d in lib usr/lib; do
+                    try_dir="${alt_libc}/${d}"
+                    [ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
+                done
+
+
+                # glibc has some struct members named __align, which is a
+                # storage modifier in RVCT. If we need to use this modifier,
+                # we'll have to #undef it in our code. Note that this must
+                # happen AFTER all libc inclues.
+                add_cflags -D__align=x_align_x
+            fi
+        ;;
+
+        symbian*)
+            enable symbian
+            # Add the paths for the alternate libc
+            for d in include/libc; do
+                try_dir="${alt_libc}/${d}"
+                [ -d "${try_dir}" ] && add_cflags -I"${try_dir}"
+            done
+            for d in release/armv5/urel; do
+                try_dir="${alt_libc}/${d}"
+                [ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
+            done
+            add_cflags -DIMPORT_C=
+
+        esac
+    ;;
+    mips*)
+        CROSS=${CROSS:-mipsel-linux-uclibc-}
+        link_with_cc=gcc
+        setup_gnu_toolchain
+        tune_cflags="-mtune="
+        check_add_cflags -march=${tgt_isa}
+    check_add_asflags -march=${tgt_isa}
+    check_add_asflags -KPIC
+    ;;
+    ppc*)
+        enable ppc
+        bits=${tgt_isa##ppc}
+        link_with_cc=gcc
+        setup_gnu_toolchain
+        add_asflags -force_cpusubtype_ALL -I"\$(dir \$<)darwin"
+        add_cflags -maltivec -faltivec
+        soft_enable altivec
+
+        case "$tgt_os" in
+        linux*)
+            add_asflags -maltivec -mregnames -I"\$(dir \$<)linux"
+        ;;
+        darwin*)
+            darwin_arch="-arch ppc"
+            enabled ppc64 && darwin_arch="${darwin_arch}64"
+            add_cflags  ${darwin_arch} -m${bits} -fasm-blocks
+            add_asflags ${darwin_arch} -force_cpusubtype_ALL -I"\$(dir \$<)darwin"
+            add_ldflags ${darwin_arch} -m${bits}
+        ;;
+        esac
+    ;;
+    x86*)
+        bits=32
+        enabled x86_64 && bits=64
+        soft_enable runtime_cpu_detect
+        soft_enable mmx
+        soft_enable sse
+        soft_enable sse2
+        soft_enable sse3
+        soft_enable ssse3
+
+        case  ${tgt_os} in
+            solaris*)
+                CC=${CC:-${CROSS}gcc}
+                LD=${LD:-${CROSS}gcc}
+                CROSS=${CROSS:-g}
+                ;;
+        esac
+
+        case  ${tgt_cc} in
+            icc*)
+                CC=${CC:-icc}
+                LD=${LD:-icc}
+                setup_gnu_toolchain
+                add_cflags -use-msasm -use-asm
+                add_ldflags -i-static
+                ;;
+            gcc*)
+                add_cflags  -m${bits}
+                add_ldflags -m${bits}
+                link_with_cc=gcc
+            setup_gnu_toolchain
+                ;;
+        esac
+
+        AS=yasm
+        AS_SFX=.asm
+        case  ${tgt_os} in
+            win*)
+                add_asflags -f win${bits}
+                enabled debug && add_asflags -g dwarf2
+            ;;
+            linux*|solaris*)
+                add_asflags -f elf${bits}
+                enabled debug && add_asflags -g dwarf2
+            ;;
+            darwin*)
+                add_asflags -f macho${bits}
+                enabled x86 && darwin_arch="-arch i386" || darwin_arch="-arch x86_64"
+                add_cflags  ${darwin_arch}
+                add_ldflags ${darwin_arch}
+                # -mdynamic-no-pic is still a bit of voodoo -- it was required at
+                # one time, but does not seem to be now, and it breaks some of the
+                # code that still relies on inline assembly.
+                # enabled icc && ! enabled pic && add_cflags -fno-pic -mdynamic-no-pic
+                enabled icc && ! enabled pic && add_cflags -fno-pic
+            ;;
+            *) log "Warning: Unknown os $tgt_os while setting up yasm flags"
+            ;;
+        esac
+    ;;
+    universal*|*-gcc|generic-gnu)
+        link_with_cc=gcc
+    setup_gnu_toolchain
+    ;;
+    esac
+
+    # Try to enable CPU specific tuning
+    if [ -n "${tune_cpu}" ]; then
+        if [ -n "${tune_cflags}" ]; then
+            check_add_cflags ${tune_cflags}${tune_cpu} || \
+                die "Requested CPU '${tune_cpu}' not supported by compiler"
+        fi
+    if [ -n "${tune_asflags}" ]; then
+            check_add_asflags ${tune_asflags}${tune_cpu} || \
+                die "Requested CPU '${tune_cpu}' not supported by assembler"
+        fi
+    if [ -z "${tune_cflags}${tune_asflags}" ]; then
+            log_echo "Warning: CPU tuning not supported by this toolchain"
+        fi
+    fi
+
+    enabled debug && check_add_cflags -g && check_add_ldflags -g
+    enabled gprof && check_add_cflags -pg && check_add_ldflags -pg
+    enabled gcov &&
+        check_add_cflags -fprofile-arcs -ftest-coverage &&
+        check_add_ldflags -fprofile-arcs -ftest-coverage
+    enabled optimizations && check_add_cflags -O3
+    if enabled rvct; then
+        enabled optimizations && check_add_cflags -Otime
+    fi
+
+    # Position Independant Code (PIC) support, for building relocatable
+    # shared objects
+    enabled gcc && enabled pic && check_add_cflags -fPIC
+
+    # Check for strip utility variant
+    ${STRIP} -V 2>/dev/null | grep GNU >/dev/null && enable gnu_strip
+
+    # Try to determine target endianness
+    check_cc <<EOF
+    unsigned int e = 'O'<<24 | '2'<<16 | 'B'<<8 | 'E';
+EOF
+    [ -f "${TMP_O}" ] && od -A n -t x1 "${TMP_O}" | tr -d '\n' |
+        grep '4f *32 *42 *45' >/dev/null 2>&1 && enable big_endian
+
+    # Almost every platform uses pthreads.
+    if enabled multithread; then
+        case ${toolchain} in
+            *-win*);;
+            *) check_header pthread.h && add_extralibs -lpthread
+        esac
+    fi
+
+    # glibc needs these
+    if enabled linux; then
+       add_cflags -D_LARGEFILE_SOURCE
+       add_cflags -D_FILE_OFFSET_BITS=64
+    fi
+}
+
+process_toolchain() {
+    process_common_toolchain
+}
+
+print_config_mk() {
+    prefix=$1
+    makefile=$2
+    shift 2
+    for cfg; do
+        upname="`toupper $cfg`"
+        if enabled $cfg; then
+            echo "${prefix}_${upname}=yes" >> $makefile
+        fi
+    done
+}
+
+print_config_h() {
+    prefix=$1
+    header=$2
+    shift 2
+    for cfg; do
+        upname="`toupper $cfg`"
+        if enabled $cfg; then
+            echo "#define ${prefix}_${upname} 1" >> $header
+        else
+            echo "#define ${prefix}_${upname} 0" >> $header
+        fi
+    done
+}
+
+process_targets() {
+    true;
+}
+
+process_detect() {
+    true;
+}
+
+enable logging
+logfile="config.err"
+self=$0
+process() {
+    cmdline_args="$@"
+    process_cmdline "$@"
+    if enabled child; then
+        echo "# ${self} $@" >> ${logfile}
+    else
+        echo "# ${self} $@" > ${logfile}
+    fi
+    post_process_cmdline
+    process_toolchain
+    process_detect
+    process_targets
+
+    OOT_INSTALLS="${OOT_INSTALLS}"
+    if enabled source_path_used; then
+    # Prepare the PWD for building.
+    for f in ${OOT_INSTALLS}; do
+            install -D ${source_path}/$f $f
+    done
+    fi
+    cp ${source_path}/build/make/Makefile .
+
+    clean_temp_files
+    true
+}
diff --git a/build/make/gen_asm_deps.sh b/build/make/gen_asm_deps.sh
new file mode 100755 (executable)
index 0000000..c1118e1
--- /dev/null
@@ -0,0 +1,63 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+self=$0
+show_help() {
+    echo "usage: $self [options] <srcfile>"
+    echo
+    echo "Generate Makefile dependency information from assembly code source"
+    echo
+    exit 1
+}
+die_unknown(){
+    echo "Unknown option \"$1\"."
+    echo "See $0 --help for available options."
+    exit 1
+}
+for opt do
+    optval="${opt#*=}"
+    case "$opt" in
+    --build-pfx=*) pfx="${optval}"
+    ;;
+    --depfile=*) out="${optval}"
+    ;;
+    -I*) raw_inc_paths="${raw_inc_paths} ${opt}"
+         inc_path="${inc_path} ${opt#-I}"
+    ;;
+    -h|--help) show_help
+    ;;
+    *) [ -f "$opt" ] && srcfile="$opt"
+    ;;
+    esac
+done
+
+[ -n "$srcfile" ] || show_help
+sfx=${sfx:-asm}
+includes=$(egrep -i "include +\"?+[a-z0-9_/]+\.${sfx}" $srcfile |
+           perl -p -e "s;.*?([a-z0-9_/]+.${sfx}).*;\1;")
+#" restore editor state
+for inc in ${includes}; do
+    found_inc_path=
+    for idir in ${inc_path}; do
+        [ -f "${idir}/${inc}" ] && found_inc_path="${idir}" && break
+    done
+    if [ -f `dirname $srcfile`/$inc ]; then
+        # Handle include files in the same directory as the source
+        $self --build-pfx=$pfx --depfile=$out ${raw_inc_paths} `dirname $srcfile`/$inc
+    elif [ -n "${found_inc_path}" ]; then
+        # Handle include files on the include path
+        $self --build-pfx=$pfx --depfile=$out ${raw_inc_paths} "${found_inc_path}/$inc"
+    else
+        # Handle generated includes in the build root (which may not exist yet)
+        echo ${out} ${out%d}o: "${pfx}${inc}"
+    fi
+done
+echo ${out} ${out%d}o: $srcfile
diff --git a/build/make/gen_msvs_def.sh b/build/make/gen_msvs_def.sh
new file mode 100755 (executable)
index 0000000..68b2406
--- /dev/null
@@ -0,0 +1,82 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+self=$0
+self_basename=${self##*/}
+EOL=$'\n'
+
+show_help() {
+    cat <<EOF
+Usage: ${self_basename} [options] file1 [file2 ...]
+
+This script generates a MSVC module definition file containing a list of symbols
+to export from a DLL. Source files are technically bash scripts (and thus may
+use #comment syntax) but in general, take the form of a list of symbols:
+
+  <kind> symbol1 [symbol2, symbol3, ...]
+
+where <kind> is either 'text' or 'data'
+
+
+Options:
+    --help                      Print this message
+    --out=filename              Write output to a file [stdout]
+    --name=project_name         Name of the library (required)
+EOF
+    exit 1
+}
+
+die() {
+    echo "${self_basename}: $@"
+    exit 1
+}
+
+die_unknown(){
+    echo "Unknown option \"$1\"."
+    echo "See ${self_basename} --help for available options."
+    exit 1
+}
+
+text() {
+    for sym in "$@"; do
+        echo "  $sym" >> ${outfile}
+    done
+}
+
+data() {
+    for sym in "$@"; do
+        printf "  %-40s DATA\n" "$sym" >> ${outfile}
+    done
+}
+
+# Process command line
+for opt in "$@"; do
+    optval="${opt#*=}"
+    case "$opt" in
+    --help|-h) show_help
+    ;;
+    --out=*) outfile="$optval"
+    ;;
+    --name=*) name="${optval}"
+    ;;
+     -*) die_unknown $opt
+    ;;
+    *) file_list[${#file_list[@]}]="$opt"
+    esac
+done
+outfile=${outfile:-/dev/stdout}
+[ -n "$name" ] || die "Library name (--name) must be specified!"
+
+echo "LIBRARY ${name}" > ${outfile}
+echo "EXPORTS" >> ${outfile}
+for f in "${file_list[@]}"; do
+    . $f
+done
diff --git a/build/make/gen_msvs_proj.sh b/build/make/gen_msvs_proj.sh
new file mode 100755 (executable)
index 0000000..eb482a4
--- /dev/null
@@ -0,0 +1,717 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+self=$0
+self_basename=${self##*/}
+EOL=$'\n'
+
+show_help() {
+    cat <<EOF
+Usage: ${self_basename} --name=projname [options] file1 [file2 ...]
+
+This script generates a Visual Studio project file from a list of source
+code files.
+
+Options:
+    --help                      Print this message
+    --exe                       Generate a project for building an Application
+    --lib                       Generate a project for creating a static library
+    --static-crt                Use the static C runtime (/MT)
+    --target=isa-os-cc          Target specifier (required)
+    --out=filename              Write output to a file [stdout]
+    --name=project_name         Name of the project (required)
+    --proj-guid=GUID            GUID to use for the project
+    --module-def=filename       File containing export definitions (for DLLs)
+    --ver=version               Version (7,8) of visual studio to generate for
+    -Ipath/to/include           Additional include directories
+    -DFLAG[=value]              Preprocessor macros to define
+    -Lpath/to/lib               Additional library search paths
+    -llibname                   Library to link against
+EOF
+    exit 1
+}
+
+die() {
+    echo "${self_basename}: $@" >&2
+    exit 1
+}
+
+die_unknown(){
+    echo "Unknown option \"$1\"." >&2
+    echo "See ${self_basename} --help for available options." >&2
+    exit 1
+}
+
+generate_uuid() {
+    local hex="0123456789ABCDEF"
+    local i
+    local uuid=""
+    local j
+    #93995380-89BD-4b04-88EB-625FBE52EBFB
+    for ((i=0; i<32; i++)); do
+        (( j = $RANDOM % 16 ))
+        uuid="${uuid}${hex:$j:1}"
+    done
+    echo "${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}"
+}
+
+indent1="    "
+indent=""
+indent_push() {
+    indent="${indent}${indent1}"
+}
+indent_pop() {
+    indent="${indent%${indent1}}"
+}
+
+tag_attributes() {
+    for opt in "$@"; do
+        optval="${opt#*=}"
+        [ -n "${optval}" ] ||
+            die "Missing attribute value in '$opt' while generating $tag tag"
+        echo "${indent}${opt%%=*}=\"${optval}\""
+    done
+}
+
+open_tag() {
+    local tag=$1
+    shift
+    if [ $# -ne 0 ]; then
+        echo "${indent}<${tag}"
+        indent_push
+        tag_attributes "$@"
+        echo "${indent}>"
+    else
+        echo "${indent}<${tag}>"
+        indent_push
+    fi
+}
+
+close_tag() {
+    local tag=$1
+    indent_pop
+    echo "${indent}</${tag}>"
+}
+
+tag() {
+    local tag=$1
+    shift
+    if [ $# -ne 0 ]; then
+        echo "${indent}<${tag}"
+        indent_push
+        tag_attributes "$@"
+        indent_pop
+        echo "${indent}/>"
+    else
+        echo "${indent}<${tag}/>"
+    fi
+}
+
+generate_filter() {
+    local var=$1
+    local name=$2
+    local pats=$3
+    local file_list_sz
+    local i
+    local f
+    local saveIFS="$IFS"
+    local pack
+    echo "generating filter '$name' from ${#file_list[@]} files" >&2
+    IFS=*
+
+    open_tag Filter \
+        Name=$name \
+        Filter=$pats \
+        UniqueIdentifier=`generate_uuid`
+
+    file_list_sz=${#file_list[@]}
+    for i in ${!file_list[@]}; do
+        f=${file_list[i]}
+        for pat in ${pats//;/$IFS}; do
+            if [ "${f##*.}" == "$pat" ]; then
+                unset file_list[i]
+
+                open_tag File RelativePath="./$f"
+                if [ "$pat" == "asm" ] && $asm_use_custom_step; then
+                    for plat in "${platforms[@]}"; do
+                        for cfg in Debug Release; do
+                            open_tag  FileConfiguration \
+                            Name="${cfg}|${plat}"
+                            tag Tool \
+                                Name="VCCustomBuildTool" \
+                                Description="Assembling \$(InputFileName)" \
+                                CommandLine="$(eval echo \$asm_${cfg}_cmdline)"\
+                                Outputs="\$(InputName).obj"
+                            close_tag FileConfiguration
+                        done
+                    done
+                fi
+
+                if [ "${f##*.}" == "cpp" ]; then
+                    for plat in "${platforms[@]}"; do
+                        for cfg in Debug Release; do
+                        open_tag FileConfiguration \
+                            Name="${cfg}|${plat}"
+                        tag Tool \
+                            Name="VCCLCompilerTool" \
+                            CompileAs="2"
+                        close_tag FileConfiguration
+                        done
+                    done
+                fi
+                close_tag  File
+
+                break
+            fi
+        done
+    done
+
+    close_tag Filter
+    IFS="$saveIFS"
+}
+
+# Process command line
+unset target
+for opt in "$@"; do
+    optval="${opt#*=}"
+    case "$opt" in
+    --help|-h) show_help
+    ;;
+    --target=*) target="${optval}"
+    ;;
+    --out=*) outfile="$optval"
+    ;;
+    --name=*) name="${optval}"
+    ;;
+    --proj-guid=*) guid="${optval}"
+    ;;
+    --module-def=*)
+        link_opts="${link_opts} ModuleDefinitionFile=${optval}"
+    ;;
+    --exe) proj_kind="exe"
+    ;;
+    --lib) proj_kind="lib"
+    ;;
+    --static-crt) use_static_runtime=true
+    ;;
+    --ver=*) vs_ver="$optval"
+             case $optval in
+             [78])
+             ;;
+             *) die Unrecognized Visual Studio Version in $opt
+             ;;
+             esac
+    ;;
+    -I*) opt="${opt%/}"
+         incs="${incs}${incs:+;}&quot;${opt##-I}&quot;"
+         yasmincs="${yasmincs} ${opt}"
+    ;;
+    -D*) defines="${defines}${defines:+;}${opt##-D}"
+    ;;
+    -L*) # fudge . to $(OutDir)
+         if [ "${opt##-L}" == "." ]; then
+             libdirs="${libdirs}${libdirs:+;}&quot;\$(OutDir)&quot;"
+         else
+             # Also try directories for this platform/configuration
+             libdirs="${libdirs}${libdirs:+;}&quot;${opt##-L}&quot;"
+             libdirs="${libdirs}${libdirs:+;}&quot;${opt##-L}/\$(PlatformName)/\$(ConfigurationName)&quot;"
+             libdirs="${libdirs}${libdirs:+;}&quot;${opt##-L}/\$(PlatformName)&quot;"
+         fi
+    ;;
+    -l*) libs="${libs}${libs:+ }${opt##-l}.lib"
+    ;;
+    -*) die_unknown $opt
+    ;;
+    *) file_list[${#file_list[@]}]="$opt"
+       case "$opt" in
+       *.asm) uses_asm=true;;
+       esac
+    esac
+done
+outfile=${outfile:-/dev/stdout}
+guid=${guid:-`generate_uuid`}
+asm_use_custom_step=false
+uses_asm=${uses_asm:-false}
+case "${vs_ver:-8}" in
+    7) vs_ver_id="7.10"
+       asm_use_custom_step=$uses_asm
+    ;;
+    8) vs_ver_id="8.00"
+    ;;
+esac
+
+[ -n "$name" ] || die "Project name (--name) must be specified!"
+[ -n "$target" ] || die "Target (--target) must be specified!"
+
+if ${use_static_runtime:-false}; then
+    release_runtime=0
+    debug_runtime=1
+    lib_sfx=mt
+else
+    release_runtime=2
+    debug_runtime=3
+    lib_sfx=md
+fi
+
+# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
+# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
+# debug exe, so this may need to be refactored later.
+for lib in ${libs}; do
+    if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
+        lib=${lib%.lib}d.lib
+    fi
+    debug_libs="${debug_libs}${debug_libs:+ }${lib}"
+done
+
+
+# List Keyword for this target
+case "$target" in
+    x86*)
+        keyword="ManagedCProj"
+    ;;
+    arm*|iwmmx*)
+        keyword="Win32Proj"
+    ;;
+    *) die "Unsupported target $target!"
+esac
+
+# List of all platforms supported for this target
+case "$target" in
+    x86_64*)
+        platforms[0]="x64"
+    ;;
+    x86*)
+        platforms[0]="Win32"
+        # these are only used by vs7
+        asm_Debug_cmdline="yasm -Xvc -g cv8 -f \$(PlatformName) ${yasmincs} \$(InputPath)"
+        asm_Release_cmdline="yasm -Xvc -f \$(PlatformName) ${yasmincs} \$(InputPath)"
+    ;;
+    arm*|iwmmx*)
+        case "${name}" in
+        obj_int_extract) platforms[0]="Win32"
+        ;;
+        *) platforms[0]="Pocket PC 2003 (ARMV4)"
+        ;;
+        esac
+    ;;
+    *) die "Unsupported target $target!"
+esac
+
+# List Command-line Arguments for this target
+case "$target" in
+    arm*|iwmmx*)
+        if [ "$name" == "example" ];then
+            ARGU="--codec vp6 --flipuv --progress _bnd.vp6"
+        fi
+        if [ "$name" == "xma" ];then
+            ARGU="--codec vp6 -h 240 -w 320 -v"
+        fi
+    ;;
+esac
+
+generate_vcproj() {
+    case "$proj_kind" in
+    exe) vs_ConfigurationType=1
+    ;;
+    *)   vs_ConfigurationType=4
+    ;;
+    esac
+
+    echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
+    open_tag  VisualStudioProject \
+                  ProjectType="Visual C++" \
+                  Version="${vs_ver_id}" \
+                  Name="${name}" \
+                  ProjectGUID="{${guid}}" \
+                  RootNamespace="${name}" \
+                  Keyword="${keyword}"
+
+    open_tag  Platforms
+    for plat in "${platforms[@]}"; do
+        tag   Platform Name="$plat"
+    done
+    close_tag Platforms
+
+    open_tag  ToolFiles
+    case "$target" in
+        x86*) $uses_asm && tag DefaultToolFile FileName="yasm.rules"
+        ;;
+        arm*|iwmmx*)
+            if [ "$name" == "vpx_decoder" ];then
+            case "$target" in
+                armv5*)
+                    tag DefaultToolFile FileName="armasmv5.rules"
+                ;;
+                armv6*)
+                    tag DefaultToolFile FileName="armasmv6.rules"
+                ;;
+                iwmmxt*)
+                    tag DefaultToolFile FileName="armasmxscale.rules"
+                ;;
+            esac
+            fi
+        ;;
+    esac
+    close_tag ToolFiles
+
+    open_tag  Configurations
+    for plat in "${platforms[@]}"; do
+        plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
+        open_tag  Configuration \
+                      Name="Debug|$plat" \
+                      OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
+                      IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
+                      ConfigurationType="$vs_ConfigurationType" \
+                      CharacterSet="1"
+
+        if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then
+            case "$name" in
+                vpx_decoder) tag Tool \
+                             Name="VCPreBuildEventTool" \
+                             CommandLine="call obj_int_extract.bat \$(ConfigurationName)"
+                             tag Tool \
+                             Name="VCMIDLTool" \
+                             TargetEnvironment="1"
+                             tag Tool \
+                             Name="VCCLCompilerTool" \
+                             ExecutionBucket="7" \
+                             Optimization="0" \
+                             AdditionalIncludeDirectories="$incs" \
+                             PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;DEBUG;_LIB;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;HAVE_CONFIG_H" \
+                             MinimalRebuild="true" \
+                             RuntimeLibrary="1" \
+                             BufferSecurityCheck="false" \
+                             UsePrecompiledHeader="0" \
+                             WarningLevel="3" \
+                             DebugInformationFormat="1" \
+                             CompileAs="1"
+                             tag Tool \
+                             Name="VCResourceCompilerTool" \
+                             PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \
+                             Culture="1033" \
+                             AdditionalIncludeDirectories="\$(IntDir)" \
+                ;;
+                example|xma) tag Tool \
+                             Name="VCCLCompilerTool" \
+                             ExecutionBucket="7" \
+                             Optimization="0" \
+                             AdditionalIncludeDirectories="$incs" \
+                             PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;DEBUG;_CONSOLE;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;HAVE_CONFIG_H" \
+                             MinimalRebuild="true" \
+                             RuntimeLibrary="1" \
+                             BufferSecurityCheck="false" \
+                             UsePrecompiledHeader="0" \
+                             WarningLevel="3" \
+                             DebugInformationFormat="1" \
+                             CompileAs="1"
+                             tag Tool \
+                             Name="VCResourceCompilerTool" \
+                             PreprocessorDefinitions="_DEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \
+                             Culture="1033" \
+                             AdditionalIncludeDirectories="\$(IntDir)" \
+                ;;
+                obj_int_extract) tag Tool \
+                             Name="VCCLCompilerTool" \
+                             Optimization="0" \
+                             AdditionalIncludeDirectories="$incs" \
+                             PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE" \
+                             RuntimeLibrary="1" \
+                             WarningLevel="3" \
+                             DebugInformationFormat="1" \
+                ;;
+            esac
+        fi
+
+        case "$target" in
+            x86*) tag Tool \
+                Name="VCCLCompilerTool" \
+                Optimization="0" \
+                AdditionalIncludeDirectories="$incs" \
+                PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;$defines" \
+                RuntimeLibrary="$debug_runtime" \
+                UsePrecompiledHeader="0" \
+                WarningLevel="3" \
+                DebugInformationFormat="1" \
+                Detect64BitPortabilityProblems="true" \
+
+                $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs" Debug="1"
+            ;;
+        esac
+
+        case "$proj_kind" in
+            exe)
+                case "$target" in
+                    x86*) tag Tool \
+                          Name="VCLinkerTool" \
+                          AdditionalDependencies="$debug_libs \$(NoInherit)" \
+                          AdditionalLibraryDirectories="$libdirs" \
+                          GenerateDebugInformation="true" \
+                          ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
+
+                    ;;
+                    arm*|iwmmx*)
+                        case "$name" in
+                            obj_int_extract) tag Tool \
+                                Name="VCLinkerTool" \
+                                OutputFile="${name}.exe" \
+                                GenerateDebugInformation="true"
+                            ;;
+                            *) tag Tool \
+                                Name="VCLinkerTool" \
+                                AdditionalDependencies="$debug_libs" \
+                                OutputFile="\$(OutDir)/${name}.exe" \
+                                LinkIncremental="2" \
+                                AdditionalLibraryDirectories="${libdirs};&quot;..\lib/$plat_no_ws&quot;" \
+                                DelayLoadDLLs="\$(NOINHERIT)" \
+                                GenerateDebugInformation="true" \
+                                ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
+                                SubSystem="9" \
+                                StackReserveSize="65536" \
+                                StackCommitSize="4096" \
+                                EntryPointSymbol="mainWCRTStartup" \
+                                TargetMachine="3"
+                            ;;
+                        esac
+                     ;;
+                 esac
+            ;;
+            lib)
+                case "$target" in
+                      arm*|iwmmx*) tag Tool \
+                                    Name="VCLibrarianTool" \
+                                    AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM" \
+                                    OutputFile="\$(OutDir)/${name}.lib" \
+                                ;;
+                                *) tag Tool \
+                                    Name="VCLibrarianTool" \
+                                    OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \
+                                ;;
+                esac
+            ;;
+            dll) tag Tool \
+                 Name="VCLinkerTool" \
+                AdditionalDependencies="\$(NoInherit)" \
+                LinkIncremental="2" \
+                GenerateDebugInformation="true" \
+                AssemblyDebug="1" \
+                TargetMachine="1" \
+                      $link_opts
+        esac
+
+        if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then
+            case "$name" in
+                vpx_decoder) tag DeploymentTool \
+                             ForceDirty="-1" \
+                             RegisterOutput="0"
+                                ;;
+                example|xma) tag DeploymentTool \
+                             ForceDirty="-1" \
+                             RegisterOutput="0"
+                             tag DebuggerTool \
+                             Arguments="${ARGU}"
+                                ;;
+            esac
+        fi
+        close_tag Configuration
+
+        open_tag  Configuration \
+                      Name="Release|$plat" \
+                      OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
+                      IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
+                      ConfigurationType="$vs_ConfigurationType" \
+                      CharacterSet="1" \
+                      WholeProgramOptimization="0"
+
+        if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then
+            case "$name" in
+                vpx_decoder) tag Tool \
+                                     Name="VCPreBuildEventTool" \
+                                     CommandLine="call obj_int_extract.bat \$(ConfigurationName)"
+                             tag Tool \
+                                     Name="VCMIDLTool" \
+                                     TargetEnvironment="1"
+                             tag Tool \
+                                             Name="VCCLCompilerTool" \
+                                             ExecutionBucket="7" \
+                                             Optimization="2" \
+                                             FavorSizeOrSpeed="1" \
+                                             AdditionalIncludeDirectories="$incs" \
+                                             PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;_LIB;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;HAVE_CONFIG_H" \
+                                             RuntimeLibrary="0" \
+                                             BufferSecurityCheck="false" \
+                                             UsePrecompiledHeader="0" \
+                                             WarningLevel="3" \
+                                             DebugInformationFormat="0" \
+                                             CompileAs="1"
+                             tag Tool \
+                                             Name="VCResourceCompilerTool" \
+                                             PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \
+                                             Culture="1033" \
+                                             AdditionalIncludeDirectories="\$(IntDir)" \
+                ;;
+                example|xma) tag Tool \
+                             Name="VCCLCompilerTool" \
+                             ExecutionBucket="7" \
+                             Optimization="2" \
+                             FavorSizeOrSpeed="1" \
+                             AdditionalIncludeDirectories="$incs" \
+                             PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES);WINCE;_CONSOLE;\$(ARCHFAM);\$(_ARCHFAM_);_UNICODE;UNICODE;HAVE_CONFIG_H" \
+                             RuntimeLibrary="0" \
+                             BufferSecurityCheck="false" \
+                             UsePrecompiledHeader="0" \
+                             WarningLevel="3" \
+                             DebugInformationFormat="0" \
+                             CompileAs="1"
+                             tag Tool \
+                             Name="VCResourceCompilerTool" \
+                             PreprocessorDefinitions="NDEBUG;_WIN32_WCE=\$(CEVER);UNDER_CE;\$(PLATFORMDEFINES)" \
+                             Culture="1033" \
+                             AdditionalIncludeDirectories="\$(IntDir)" \
+                ;;
+                obj_int_extract) tag Tool \
+                             Name="VCCLCompilerTool" \
+                             AdditionalIncludeDirectories="$incs" \
+                             PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" \
+                             RuntimeLibrary="0" \
+                             UsePrecompiledHeader="0" \
+                             WarningLevel="3" \
+                             Detect64BitPortabilityProblems="true" \
+                             DebugInformationFormat="0" \
+                ;;
+            esac
+        fi
+
+    case "$target" in
+        x86*) tag       Tool \
+                      Name="VCCLCompilerTool" \
+                      AdditionalIncludeDirectories="$incs" \
+                      PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;$defines" \
+                      RuntimeLibrary="$release_runtime" \
+                      UsePrecompiledHeader="0" \
+                      WarningLevel="3" \
+                      DebugInformationFormat="0" \
+                      Detect64BitPortabilityProblems="true"
+
+                $uses_asm && tag Tool Name="YASM"  IncludePaths="$incs"
+                ;;
+                esac
+
+        case "$proj_kind" in
+            exe)
+                case "$target" in
+                    x86*) tag Tool \
+                                  Name="VCLinkerTool" \
+                                  AdditionalDependencies="$libs \$(NoInherit)" \
+                                  AdditionalLibraryDirectories="$libdirs" \
+                    ;;
+                    arm*|iwmmx*)
+                        case "$name" in
+                            obj_int_extract) tag Tool \
+                                Name="VCLinkerTool" \
+                                OutputFile="${name}.exe" \
+                                LinkIncremental="1" \
+                                GenerateDebugInformation="false" \
+                                SubSystem="0" \
+                                OptimizeReferences="0" \
+                                EnableCOMDATFolding="0" \
+                                TargetMachine="0"
+                            ;;
+                            *) tag Tool \
+                                Name="VCLinkerTool" \
+                                AdditionalDependencies="$libs" \
+                                OutputFile="\$(OutDir)/${name}.exe" \
+                                LinkIncremental="1" \
+                                AdditionalLibraryDirectories="${libdirs};&quot;..\lib/$plat_no_ws&quot;" \
+                                DelayLoadDLLs="\$(NOINHERIT)" \
+                                GenerateDebugInformation="true" \
+                                ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
+                                SubSystem="9" \
+                                StackReserveSize="65536" \
+                                StackCommitSize="4096" \
+                                OptimizeReferences="2" \
+                                EnableCOMDATFolding="2" \
+                                EntryPointSymbol="mainWCRTStartup" \
+                                TargetMachine="3"
+                            ;;
+                        esac
+                     ;;
+                 esac
+            ;;
+        lib)
+                case "$target" in
+                      arm*|iwmmx*) tag Tool \
+                                    Name="VCLibrarianTool" \
+                                    AdditionalOptions=" /subsystem:windowsce,4.20 /machine:ARM" \
+                                    OutputFile="\$(OutDir)/${name}.lib" \
+                                ;;
+                                *) tag Tool \
+                                    Name="VCLibrarianTool" \
+                                    OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \
+                                ;;
+                esac
+        ;;
+        dll) # note differences to debug version: LinkIncremental, AssemblyDebug
+             tag Tool \
+                      Name="VCLinkerTool" \
+                      AdditionalDependencies="\$(NoInherit)" \
+                      LinkIncremental="1" \
+                      GenerateDebugInformation="true" \
+                      TargetMachine="1" \
+                      $link_opts
+        esac
+
+        if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then
+            case "$name" in
+                vpx_decoder) tag DeploymentTool \
+                             ForceDirty="-1" \
+                             RegisterOutput="0"
+                ;;
+                example|xma) tag DeploymentTool \
+                             ForceDirty="-1" \
+                             RegisterOutput="0"
+                             tag DebuggerTool \
+                             Arguments="${ARGU}"
+                                ;;
+            esac
+        fi
+
+        close_tag Configuration
+    done
+    close_tag Configurations
+
+    open_tag  Files
+    generate_filter srcs   "Source Files"   "cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+    generate_filter hdrs   "Header Files"   "h;hpp;hxx;hm;inl;inc;xsd"
+    generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+    generate_filter resrcs "Build Files"    "mk"
+    close_tag Files
+
+    tag       Globals
+    close_tag VisualStudioProject
+
+    # This must be done from within the {} subshell
+    echo "Ignored files list (${#file_list[@]} items) is:" >&2
+    for f in "${file_list[@]}"; do
+        echo "    $f" >&2
+    done
+}
+
+generate_vcproj |
+    sed  -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}
+
+exit
+<!--
+TODO: Add any files not captured by filters.
+                <File
+                        RelativePath=".\ReadMe.txt"
+                        >
+                </File>
+-->
diff --git a/build/make/gen_msvs_sln.sh b/build/make/gen_msvs_sln.sh
new file mode 100755 (executable)
index 0000000..b670ec5
--- /dev/null
@@ -0,0 +1,272 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+self=$0
+self_basename=${self##*/}
+EOL=$'\n'
+EOLDOS=$'\r'
+
+show_help() {
+    cat <<EOF
+Usage: ${self_basename} [options] file1 [file2 ...]
+
+This script generates a Visual Studio 2005 solution file from a list of project
+files.
+
+Options:
+    --help                      Print this message
+    --out=outfile               Redirect output to a file
+    --ver=version               Version (7,8) of visual studio to generate for
+    --target=isa-os-cc          Target specifier
+EOF
+    exit 1
+}
+
+die() {
+    echo "${self_basename}: $@" >&2
+    [ -f "${outfile}" ] && rm -f ${outfile}{,.mk}
+    exit 1
+}
+
+die_unknown(){
+    echo "Unknown option \"$1\"." >&2
+    echo "See ${self_basename} --help for available options." >&2
+    [ -f "${outfile}" ] && rm -f ${outfile}{,.mk}
+    exit 1
+}
+
+indent1=$'\t'
+indent=""
+indent_push() {
+    indent="${indent}${indent1}"
+}
+indent_pop() {
+    indent="${indent%${indent1}}"
+}
+
+parse_project() {
+    local file=$1
+    local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
+    local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
+
+    # save the project GUID to a varaible, normalizing to the basename of the
+    # vcproj file without the extension
+    local var
+    var=${file##*/}
+    var=${var%%.vcproj}
+    eval "${var}_file=\"$1\""
+    eval "${var}_name=$name"
+    eval "${var}_guid=$guid"
+
+    # assume that all projects have the same list of possible configurations,
+    # so overwriting old config_lists is not a problem
+    config_list=`grep -A1 '<Configuration' $file |
+        grep Name | cut -d\" -f2`
+    proj_list="${proj_list} ${var}"
+}
+
+process_project() {
+    eval "local file=\${$1_file}"
+    eval "local name=\${$1_name}"
+    eval "local guid=\${$1_guid}"
+
+    # save the project GUID to a varaible, normalizing to the basename of the
+    # vcproj file without the extension
+    local var
+    var=${file##*/}
+    var=${var%%.vcproj}
+    eval "${var}_guid=$guid"
+
+    echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
+    indent_push
+
+    eval "local deps=\"\${${var}_deps}\""
+    if [ -n "$deps" ]; then
+        echo "${indent}ProjectSection(ProjectDependencies) = postProject"
+        indent_push
+
+        for dep in $deps; do
+            eval "local dep_guid=\${${dep}_guid}"
+            [ -z "${dep_guid}" ] && die "Unknown GUID for $dep (dependency of $var)"
+            echo "${indent}$dep_guid = $dep_guid"
+        done
+
+        indent_pop
+        echo "${indent}EndProjectSection"
+
+    fi
+
+    indent_pop
+    echo "EndProject"
+}
+
+process_global() {
+    echo "Global"
+    indent_push
+
+    #
+    # Solution Configuration Platforms
+    #
+    echo "${indent}GlobalSection(SolutionConfigurationPlatforms) = preSolution"
+    indent_push
+    IFS_bak=${IFS}
+    IFS=$'\r'$'\n'
+    for config in ${config_list}; do
+        echo "${indent}$config = $config"
+    done
+    IFS=${IFS_bak}
+    indent_pop
+    echo "${indent}EndGlobalSection"
+
+    #
+    # Project Configuration Platforms
+    #
+    echo "${indent}GlobalSection(ProjectConfigurationPlatforms) = postSolution"
+    indent_push
+    for proj in ${proj_list}; do
+        eval "local proj_guid=\${${proj}_guid}"
+        IFS=$'\r'$'\n'
+        for config in ${config_list}; do
+            echo "${indent}${proj_guid}.${config}.ActiveCfg = ${config}"
+            echo "${indent}${proj_guid}.${config}.Build.0 = ${config}"
+
+            if [ "$target" == "armv6-wince-vs8" ] || [ "$target" == "armv5te-wince-vs8" ] || [ "$target" == "iwmmxt-wince-vs8" ] || [ "$target" == "iwmmxt2-wince-vs8" ];then
+                echo "${indent}${proj_guid}.${config}.Deploy.0 = ${config}"
+            fi
+        done
+        IFS=${IFS_bak}
+    done
+    indent_pop
+    echo "${indent}EndGlobalSection"
+
+    #
+    # Solution Properties
+    #
+    echo "${indent}GlobalSection(SolutionProperties) = preSolution"
+    indent_push
+    echo "${indent}HideSolutionNode = FALSE"
+    indent_pop
+    echo "${indent}EndGlobalSection"
+
+    indent_pop
+    echo "EndGlobal"
+}
+
+process_makefile() {
+    IFS_bak=${IFS}
+    IFS=$'\r'$'\n'
+    local TAB=$'\t'
+    cat <<EOF
+found_devenv := \$(shell which devenv.com >/dev/null 2>&1 && echo yes)
+.nodevenv.once:
+${TAB}@echo "  * devenv.com not found in path."
+${TAB}@echo "  * "
+${TAB}@echo "  * You will have to build all configurations manually using the"
+${TAB}@echo "  * Visual Studio IDE. To allow make to build them automatically,"
+${TAB}@echo "  * add the Common7/IDE directory of your Visual Studio"
+${TAB}@echo "  * installation to your path, eg:"
+${TAB}@echo "  *   C:\Program Files\Microsoft Visual Studio 8\Common7\IDE"
+${TAB}@echo "  * "
+${TAB}@touch \$@
+CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once)
+
+EOF
+
+    for sln_config in ${config_list}; do
+        local config=${sln_config%%|*}
+        local platform=${sln_config##*|}
+        local nows_sln_config=`echo $sln_config | sed -e 's/[^a-zA-Z0-9]/_/g'`
+        cat <<EOF
+BUILD_TARGETS += \$(if \$(NO_LAUNCH_DEVENV),,$nows_sln_config)
+clean::
+${TAB}rm -rf "$platform"/"$config"
+.PHONY: $nows_sln_config
+ifneq (\$(found_devenv),)
+  ifeq (\$(CONFIG_VS_VERSION),7)
+$nows_sln_config: $outfile
+${TAB}devenv.com $outfile /build "$config"
+
+  else
+$nows_sln_config: $outfile
+${TAB}devenv.com $outfile /build "$sln_config"
+
+  endif
+else
+$nows_sln_config: $outfile .nodevenv.once
+${TAB}@echo "  * Skipping build of $sln_config (devenv.com not in path)."
+${TAB}@echo "  * "
+endif
+
+EOF
+    done
+    IFS=${IFS_bak}
+}
+
+# Process command line
+outfile=/dev/stdout
+for opt in "$@"; do
+    optval="${opt#*=}"
+    case "$opt" in
+    --help|-h) show_help
+    ;;
+    --out=*) outfile="${optval}"; mkoutfile="${optval}".mk
+    ;;
+    --dep=*) eval "${optval%%:*}_deps=\"\${${optval%%:*}_deps} ${optval##*:}\""
+    ;;
+    --ver=*) vs_ver="$optval"
+             case $optval in
+             [78])
+             ;;
+             *) die Unrecognized Visual Studio Version in $opt
+             ;;
+             esac
+    ;;
+    --ver=*) vs_ver="$optval"
+             case $optval in
+             7) sln_vers="8.00"
+                sln_vers_str="Visual Studio .NET 2003"
+             ;;
+             8)
+             ;;
+             *) die "Unrecognized Visual Studio Version '$optval' in $opt"
+             ;;
+             esac
+    ;;
+    --target=*) target="${optval}"
+    ;;
+    -*) die_unknown $opt
+    ;;
+    *) file_list[${#file_list[@]}]="$opt"
+    esac
+done
+outfile=${outfile:-/dev/stdout}
+mkoutfile=${mkoutfile:-/dev/stdout}
+case "${vs_ver:-8}" in
+    7) sln_vers="8.00"
+       sln_vers_str="Visual Studio .NET 2003"
+    ;;
+    8) sln_vers="9.00"
+       sln_vers_str="Visual Studio 2005"
+    ;;
+esac
+
+for f in "${file_list[@]}"; do
+    parse_project $f
+done
+cat  >${outfile} <<EOF
+Microsoft Visual Studio Solution File, Format Version $sln_vers${EOLDOS}
+# $sln_vers_str${EOLDOS}
+EOF
+for proj in ${proj_list}; do
+    process_project $proj >>${outfile}
+done
+process_global >>${outfile}
+process_makefile >${mkoutfile}
diff --git a/build/make/obj_int_extract.c b/build/make/obj_int_extract.c
new file mode 100644 (file)
index 0000000..cef14e7
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "vpx_config.h"
+
+#if defined(_MSC_VER)
+#include <io.h>
+#include <share.h>
+#include "vpx_ports/vpx_integer.h"
+#else
+#include <stdint.h>
+#include <unistd.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+typedef enum
+{
+    OUTPUT_FMT_PLAIN,
+    OUTPUT_FMT_RVDS,
+    OUTPUT_FMT_GAS,
+} output_fmt_t;
+
+int log_msg(const char *fmt, ...)
+{
+    int res;
+    va_list ap;
+    va_start(ap, fmt);
+    res = vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    return res;
+}
+
+#if defined(__GNUC__) && __GNUC__
+
+#if defined(__MACH__)
+
+#include <mach-o/loader.h>
+#include <mach-o/nlist.h>
+
+int parse_macho(uint8_t *base_buf, size_t sz)
+{
+    int i, j;
+    struct mach_header header;
+    uint8_t *buf = base_buf;
+    int base_data_section = 0;
+
+    memcpy(&header, buf, sizeof(struct mach_header));
+    buf += sizeof(struct mach_header);
+
+    if (header.magic != MH_MAGIC)
+    {
+        log_msg("Bad magic number for object file. 0x%x expected, 0x%x found.\n",
+                header.magic, MH_MAGIC);
+        goto bail;
+    }
+
+    if (header.cputype != CPU_TYPE_ARM)
+    {
+        log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_ARM.\n");
+        goto bail;
+    }
+
+    if (header.filetype != MH_OBJECT)
+    {
+        log_msg("Bad filetype for object file. Currently only tested for MH_OBJECT.\n");
+        goto bail;
+    }
+
+    for (i = 0; i < header.ncmds; i++)
+    {
+        struct load_command lc;
+        struct symtab_command sc;
+        struct segment_command seg_c;
+
+        memcpy(&lc, buf, sizeof(struct load_command));
+
+        if (lc.cmd == LC_SEGMENT)
+        {
+            uint8_t *seg_buf = buf;
+            struct section s;
+
+            memcpy(&seg_c, buf, sizeof(struct segment_command));
+
+            seg_buf += sizeof(struct segment_command);
+
+            for (j = 0; j < seg_c.nsects; j++)
+            {
+                memcpy(&s, seg_buf + (j * sizeof(struct section)), sizeof(struct section));
+
+                // Need to get this offset which is the start of the symbol table
+                // before matching the strings up with symbols.
+                base_data_section = s.offset;
+            }
+        }
+        else if (lc.cmd == LC_SYMTAB)
+        {
+            uint8_t *sym_buf = base_buf;
+            uint8_t *str_buf = base_buf;
+
+            if (base_data_section != 0)
+            {
+                memcpy(&sc, buf, sizeof(struct symtab_command));
+
+                if (sc.cmdsize != sizeof(struct symtab_command))
+                    log_msg("Can't find symbol table!\n");
+
+                sym_buf += sc.symoff;
+                str_buf += sc.stroff;
+
+                for (j = 0; j < sc.nsyms; j++)
+                {
+                    struct nlist nl;
+                    int val;
+
+                    memcpy(&nl, sym_buf + (j * sizeof(struct nlist)), sizeof(struct nlist));
+
+                    val = *((int *)(base_buf + base_data_section + nl.n_value));
+
+                    // Location of string is cacluated each time from the
+                    // start of the string buffer.  On darwin the symbols
+                    // are prefixed by "_".  On other platforms it is not
+                    // so it needs to be removed.  That is the reason for
+                    // the +1.
+                    printf("%-40s EQU %5d\n", str_buf + nl.n_un.n_strx + 1, val);
+                }
+            }
+        }
+
+        buf += lc.cmdsize;
+    }
+
+    return 0;
+bail:
+    return 1;
+
+}
+
+int main(int argc, char **argv)
+{
+    int fd;
+    char *f;
+    struct stat stat_buf;
+    uint8_t *file_buf;
+    int res;
+
+    if (argc < 2 || argc > 3)
+    {
+        fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
+        fprintf(stderr, "  <obj file>\tMachO format object file to parse\n");
+        fprintf(stderr, "Output Formats:\n");
+        fprintf(stderr, "  gas  - compatible with GNU assembler\n");
+        fprintf(stderr, "  rvds - compatible with armasm\n");
+        goto bail;
+    }
+
+    f = argv[2];
+
+    if (!((!strcmp(argv[1], "rvds")) || (!strcmp(argv[1], "gas"))))
+        f = argv[1];
+
+    fd = open(f, O_RDONLY);
+
+    if (fd < 0)
+    {
+        perror("Unable to open file");
+        goto bail;
+    }
+
+    if (fstat(fd, &stat_buf))
+    {
+        perror("stat");
+        goto bail;
+    }
+
+    file_buf = malloc(stat_buf.st_size);
+
+    if (!file_buf)
+    {
+        perror("malloc");
+        goto bail;
+    }
+
+    if (read(fd, file_buf, stat_buf.st_size) != stat_buf.st_size)
+    {
+        perror("read");
+        goto bail;
+    }
+
+    if (close(fd))
+    {
+        perror("close");
+        goto bail;
+    }
+
+    res = parse_macho(file_buf, stat_buf.st_size);
+    free(file_buf);
+
+    if (!res)
+        return EXIT_SUCCESS;
+
+bail:
+    return EXIT_FAILURE;
+}
+
+#else
+#include "elf.h"
+
+#define COPY_STRUCT(dst, buf, ofst, sz) do {\
+        if(ofst + sizeof((*(dst))) > sz) goto bail;\
+        memcpy(dst, buf+ofst, sizeof((*(dst))));\
+    } while(0)
+
+#define ENDIAN_ASSIGN(val, memb) do {\
+        if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail;}\
+        (val) = (memb);\
+    } while(0)
+
+#define ENDIAN_ASSIGN_IN_PLACE(memb) do {\
+        ENDIAN_ASSIGN(memb, memb);\
+    } while(0)
+
+typedef struct
+{
+    uint8_t     *buf; /* Buffer containing ELF data */
+    size_t       sz;  /* Buffer size */
+    int          le_data;   /* Data is little-endian */
+    Elf32_Ehdr   hdr;
+} elf_obj_t;
+
+int parse_elf32_header(elf_obj_t *elf)
+{
+    int res;
+    /* Verify ELF32 header */
+    COPY_STRUCT(&elf->hdr, elf->buf, 0, elf->sz);
+    res = elf->hdr.e_ident[EI_MAG0] == ELFMAG0;
+    res &= elf->hdr.e_ident[EI_MAG1] == ELFMAG1;
+    res &= elf->hdr.e_ident[EI_MAG2] == ELFMAG2;
+    res &= elf->hdr.e_ident[EI_MAG3] == ELFMAG3;
+    res &= elf->hdr.e_ident[EI_CLASS] == ELFCLASS32;
+    res &= elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB
+           || elf->hdr.e_ident[EI_DATA] == ELFDATA2MSB;
+
+    if (!res) goto bail;
+
+    elf->le_data = elf->hdr.e_ident[EI_DATA] == ELFDATA2LSB;
+
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_type);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_machine);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_version);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_entry);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phoff);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shoff);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_flags);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_ehsize);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phentsize);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_phnum);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shentsize);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shnum);
+    ENDIAN_ASSIGN_IN_PLACE(elf->hdr.e_shstrndx);
+    return 0;
+bail:
+    return 1;
+}
+
+int parse_elf32_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr)
+{
+    if (idx >= elf->hdr.e_shnum)
+        goto bail;
+
+    COPY_STRUCT(hdr, elf->buf, elf->hdr.e_shoff + idx * elf->hdr.e_shentsize,
+                elf->sz);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_name);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_type);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_flags);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addr);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_offset);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_size);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_link);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_info);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_addralign);
+    ENDIAN_ASSIGN_IN_PLACE(hdr->sh_entsize);
+    return 0;
+bail:
+    return 1;
+}
+
+char *parse_elf32_string_table(elf_obj_t *elf, int s_idx, int idx)
+{
+    Elf32_Shdr shdr;
+
+    if (parse_elf32_section(elf, s_idx, &shdr))
+    {
+        log_msg("Failed to parse ELF string table: section %d, index %d\n",
+                s_idx, idx);
+        return "";
+    }
+
+    return (char *)(elf->buf + shdr.sh_offset + idx);
+}
+
+int parse_elf32_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym)
+{
+    COPY_STRUCT(sym, elf->buf, ofst, elf->sz);
+    ENDIAN_ASSIGN_IN_PLACE(sym->st_name);
+    ENDIAN_ASSIGN_IN_PLACE(sym->st_value);
+    ENDIAN_ASSIGN_IN_PLACE(sym->st_size);
+    ENDIAN_ASSIGN_IN_PLACE(sym->st_info);
+    ENDIAN_ASSIGN_IN_PLACE(sym->st_other);
+    ENDIAN_ASSIGN_IN_PLACE(sym->st_shndx);
+    return 0;
+bail:
+    return 1;
+}
+
+int parse_elf32(uint8_t *buf, size_t sz, output_fmt_t mode)
+{
+    elf_obj_t  elf;
+    Elf32_Shdr shdr;
+    unsigned int ofst;
+    int         i;
+    Elf32_Off strtab_off;   /* save String Table offset for later use */
+
+    memset(&elf, 0, sizeof(elf));
+    elf.buf = buf;
+    elf.sz = sz;
+
+    /* Parse Header */
+    if (parse_elf32_header(&elf))
+    {
+        log_msg("Parse error: File does not appear to be valid ELF32\n");
+        return 1;
+    }
+
+    for (i = 0; i < elf.hdr.e_shnum; i++)
+    {
+        parse_elf32_section(&elf, i, &shdr);
+
+        if (shdr.sh_type == SHT_STRTAB)
+        {
+            char strtsb_name[128];
+
+            strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
+
+            if (!(strcmp(strtsb_name, ".shstrtab")))
+            {
+                log_msg("found section: %s\n", strtsb_name);
+                strtab_off = shdr.sh_offset;
+                break;
+            }
+        }
+    }
+
+    /* Parse all Symbol Tables */
+    for (i = 0; i < elf.hdr.e_shnum; i++)
+    {
+
+        parse_elf32_section(&elf, i, &shdr);
+
+        if (shdr.sh_type == SHT_SYMTAB)
+        {
+            for (ofst = shdr.sh_offset;
+                 ofst < shdr.sh_offset + shdr.sh_size;
+                 ofst += shdr.sh_entsize)
+            {
+                Elf32_Sym sym;
+
+                parse_elf32_symbol(&elf, ofst, &sym);
+
+                /* For all OBJECTS (data objects), extract the value from the
+                 * proper data segment.
+                 */
+                if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
+                    log_msg("found data object %s\n",
+                            parse_elf32_string_table(&elf,
+                                                     shdr.sh_link,
+                                                     sym.st_name));
+
+                if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
+                    && sym.st_size == 4)
+                {
+                    Elf32_Shdr dhdr;
+                    int32_t      val;
+                    char section_name[128];
+
+                    parse_elf32_section(&elf, sym.st_shndx, &dhdr);
+
+                    /* For explanition - refer to _MSC_VER version of code */
+                    strcpy(section_name, (char *)(elf.buf + strtab_off + dhdr.sh_name));
+                    log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type);
+
+                    if (!(strcmp(section_name, ".bss")))
+                    {
+                        val = 0;
+                    }
+                    else
+                    {
+                        memcpy(&val,
+                               elf.buf + dhdr.sh_offset + sym.st_value,
+                               sizeof(val));
+                    }
+
+                    if (!elf.le_data)
+                    {
+                        log_msg("Big Endian data not supported yet!\n");
+                        goto bail;
+                    }\
+
+                    switch (mode)
+                    {
+                    case OUTPUT_FMT_RVDS:
+                        printf("%-40s EQU %5d\n",
+                               parse_elf32_string_table(&elf,
+                                                        shdr.sh_link,
+                                                        sym.st_name),
+                               val);
+                        break;
+                    case OUTPUT_FMT_GAS:
+                        printf(".equ %-40s, %5d\n",
+                               parse_elf32_string_table(&elf,
+                                                        shdr.sh_link,
+                                                        sym.st_name),
+                               val);
+                        break;
+                    default:
+                        printf("%s = %d\n",
+                               parse_elf32_string_table(&elf,
+                                                        shdr.sh_link,
+                                                        sym.st_name),
+                               val);
+                    }
+                }
+            }
+        }
+    }
+
+    if (mode == OUTPUT_FMT_RVDS)
+        printf("    END\n");
+
+    return 0;
+bail:
+    log_msg("Parse error: File does not appear to be valid ELF32\n");
+    return 1;
+}
+
+int main(int argc, char **argv)
+{
+    int fd;
+    output_fmt_t mode;
+    char *f;
+    struct stat stat_buf;
+    uint8_t *file_buf;
+    int res;
+
+    if (argc < 2 || argc > 3)
+    {
+        fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
+        fprintf(stderr, "  <obj file>\tELF format object file to parse\n");
+        fprintf(stderr, "Output Formats:\n");
+        fprintf(stderr, "  gas  - compatible with GNU assembler\n");
+        fprintf(stderr, "  rvds - compatible with armasm\n");
+        goto bail;
+    }
+
+    f = argv[2];
+
+    if (!strcmp(argv[1], "rvds"))
+        mode = OUTPUT_FMT_RVDS;
+    else if (!strcmp(argv[1], "gas"))
+        mode = OUTPUT_FMT_GAS;
+    else
+        f = argv[1];
+
+
+    fd = open(f, O_RDONLY);
+
+    if (fd < 0)
+    {
+        perror("Unable to open file");
+        goto bail;
+    }
+
+    if (fstat(fd, &stat_buf))
+    {
+        perror("stat");
+        goto bail;
+    }
+
+    file_buf = malloc(stat_buf.st_size);
+
+    if (!file_buf)
+    {
+        perror("malloc");
+        goto bail;
+    }
+
+    if (read(fd, file_buf, stat_buf.st_size) != stat_buf.st_size)
+    {
+        perror("read");
+        goto bail;
+    }
+
+    if (close(fd))
+    {
+        perror("close");
+        goto bail;
+    }
+
+    res = parse_elf32(file_buf, stat_buf.st_size, mode);
+    //res = parse_coff(file_buf, stat_buf.st_size);
+    free(file_buf);
+
+    if (!res)
+        return EXIT_SUCCESS;
+
+bail:
+    return EXIT_FAILURE;
+}
+#endif
+#endif
+
+
+#if defined(_MSC_VER)
+/*  See "Microsoft Portable Executable and Common Object File Format Specification"
+    for reference.
+*/
+#define get_le32(x) ((*(x)) | (*(x+1)) << 8 |(*(x+2)) << 16 | (*(x+3)) << 24 )
+#define get_le16(x) ((*(x)) | (*(x+1)) << 8)
+
+int parse_coff(unsigned __int8 *buf, size_t sz)
+{
+    unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr;
+    unsigned int sectionrawdata_ptr;
+    unsigned int i;
+    unsigned __int8 *ptr;
+    unsigned __int32 symoffset;
+    FILE *fp;
+
+    char **sectionlist;  //this array holds all section names in their correct order.
+    //it is used to check if the symbol is in .bss or .data section.
+
+    nsections = get_le16(buf + 2);
+    symtab_ptr = get_le32(buf + 8);
+    symtab_sz = get_le32(buf + 12);
+    strtab_ptr = symtab_ptr + symtab_sz * 18;
+
+    if (nsections > 96)
+        goto bail;
+
+    sectionlist = malloc(nsections * sizeof * sectionlist);
+
+    //log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections);
+
+    /*
+    The size of optional header is always zero for an obj file. So, the section header
+    follows the file header immediately.
+    */
+
+    ptr = buf + 20;     //section header
+
+    for (i = 0; i < nsections; i++)
+    {
+        char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+        strncpy(sectionname, ptr, 8);
+        //log_msg("COFF: Parsing section %s\n",sectionname);
+
+        sectionlist[i] = malloc(strlen(sectionname) + 1);
+        strcpy(sectionlist[i], sectionname);
+
+        if (!strcmp(sectionname, ".data")) sectionrawdata_ptr = get_le32(ptr + 20);
+
+        ptr += 40;
+    }
+
+    //log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
+    //log_msg("COFF: raw data pointer ofset for section .data is %u\n", sectionrawdata_ptr);
+
+    fp = fopen("vpx_asm_offsets.asm", "w");
+
+    if (fp == NULL)
+    {
+        perror("open file");
+        goto bail;
+    }
+
+    /*  The compiler puts the data with non-zero offset in .data section, but puts the data with
+        zero offset in .bss section. So, if the data in in .bss section, set offset=0.
+        Note from Wiki: In an object module compiled from C, the bss section contains
+        the local variables (but not functions) that were declared with the static keyword,
+        except for those with non-zero initial values. (In C, static variables are initialized
+        to zero by default.) It also contains the non-local (both extern and static) variables
+        that are also initialized to zero (either explicitly or by default).
+        */
+    //move to symbol table
+    /* COFF symbol table:
+        offset      field
+        0           Name(*)
+        8           Value
+        12          SectionNumber
+        14          Type
+        16          StorageClass
+        17          NumberOfAuxSymbols
+        */
+    ptr = buf + symtab_ptr;
+
+    for (i = 0; i < symtab_sz; i++)
+    {
+        __int16 section = get_le16(ptr + 12); //section number
+
+        if (section > 0 && ptr[16] == 2)
+        {
+            //if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) {
+
+            if (get_le32(ptr))
+            {
+                char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+                strncpy(name, ptr, 8);
+                //log_msg("COFF: Parsing symbol %s\n",name);
+                fprintf(fp, "%-40s EQU ", name);
+            }
+            else
+            {
+                //log_msg("COFF: Parsing symbol %s\n",
+                //        buf + strtab_ptr + get_le32(ptr+4));
+                fprintf(fp, "%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4));
+            }
+
+            if (!(strcmp(sectionlist[section-1], ".bss")))
+            {
+                symoffset = 0;
+            }
+            else
+            {
+                symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8));
+            }
+
+            //log_msg("      Section: %d\n",section);
+            //log_msg("      Class:   %d\n",ptr[16]);
+            //log_msg("      Address: %u\n",get_le32(ptr+8));
+            //log_msg("      Offset: %u\n", symoffset);
+
+            fprintf(fp, "%5d\n", symoffset);
+        }
+
+        ptr += 18;
+    }
+
+    fprintf(fp, "    END\n");
+    fclose(fp);
+
+    for (i = 0; i < nsections; i++)
+    {
+        free(sectionlist[i]);
+    }
+
+    free(sectionlist);
+
+    return 0;
+bail:
+
+    for (i = 0; i < nsections; i++)
+    {
+        free(sectionlist[i]);
+    }
+
+    free(sectionlist);
+
+    return 1;
+}
+
+int main(int argc, char **argv)
+{
+    int fd;
+    output_fmt_t mode;
+    const char *f;
+    struct _stat stat_buf;
+    unsigned __int8 *file_buf;
+    int res;
+
+    if (argc < 2 || argc > 3)
+    {
+        fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
+        fprintf(stderr, "  <obj file>\tELF format object file to parse\n");
+        fprintf(stderr, "Output Formats:\n");
+        fprintf(stderr, "  gas  - compatible with GNU assembler\n");
+        fprintf(stderr, "  rvds - compatible with armasm\n");
+        goto bail;
+    }
+
+    f = argv[2];
+
+    if (!strcmp(argv[1], "rvds"))
+        mode = OUTPUT_FMT_RVDS;
+    else if (!strcmp(argv[1], "gas"))
+        mode = OUTPUT_FMT_GAS;
+    else
+        f = argv[1];
+
+    if (_sopen_s(&fd, f, _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE))
+    {
+        perror("Unable to open file");
+        goto bail;
+    }
+
+    if (_fstat(fd, &stat_buf))
+    {
+        perror("stat");
+        goto bail;
+    }
+
+    file_buf = malloc(stat_buf.st_size);
+
+    if (!file_buf)
+    {
+        perror("malloc");
+        goto bail;
+    }
+
+    if (_read(fd, file_buf, stat_buf.st_size) != stat_buf.st_size)
+    {
+        perror("read");
+        goto bail;
+    }
+
+    if (_close(fd))
+    {
+        perror("close");
+        goto bail;
+    }
+
+    res = parse_coff(file_buf, stat_buf.st_size);
+
+    free(file_buf);
+
+    if (!res)
+        return EXIT_SUCCESS;
+
+bail:
+    return EXIT_FAILURE;
+}
+#endif
diff --git a/build/make/version.sh b/build/make/version.sh
new file mode 100755 (executable)
index 0000000..2bda701
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+
+for opt in "$@"; do
+    optval="${opt#*=}"
+    case "$opt" in
+    --bare) bare=true ;;
+    *) break ;;
+    esac
+    shift
+done
+source_path=${1:-.}
+out_file=${2}
+id=${3:-VERSION_STRING}
+
+git_version_id=""
+if [ -d ${source_path}/.git ]; then
+    # Source Path is a git working copy. Check for local modifications.
+    export GIT_DIR=${source_path}/.git
+    git_version_id=`git describe --match=v[0-9]* 2>/dev/null`
+fi
+
+changelog_version=""
+for p in "${source_path}" "${source_path}/.."; do
+    if [ -z "$git_version_id" -a -f "${p}/CHANGELOG" ]; then
+        changelog_version=`head -n1 "${p}/CHANGELOG" | awk '{print $2}'`
+        changelog_version="${changelog_version}"
+        break
+    fi
+done
+version_str="${changelog_version}${git_version_id}"
+bare_version=${version_str#v}
+major_version=${bare_version%%.*}
+bare_version=${bare_version#*.}
+minor_version=${bare_version%%.*}
+bare_version=${bare_version#*.}
+patch_version=${bare_version%%-*}
+bare_version=${bare_version#${patch_version}}
+extra_version=${bare_version##-}
+
+#since they'll be used as integers below make sure they are or force to 0
+for v in major_version minor_version patch_version; do
+    if eval echo \$$v |grep -E -q '[^[:digit:]]'; then
+        eval $v=0
+    fi
+done
+
+if [ ${bare} ]; then
+    echo "${changelog_version}${git_version_id}" > $$.tmp
+else
+    cat<<EOF>$$.tmp
+#define VERSION_MAJOR  $major_version
+#define VERSION_MINOR  $minor_version
+#define VERSION_PATCH  $patch_version
+#define VERSION_EXTRA  "$extra_version"
+#define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH))
+#define ${id}_NOSP "${version_str}"
+#define ${id}      " ${version_str}"
+EOF
+fi
+if [ -n "$out_file" ]; then
+diff $$.tmp ${out_file} >/dev/null 2>&1 || cat $$.tmp > ${out_file}
+else
+cat $$.tmp
+fi
+rm $$.tmp
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..3083343
--- /dev/null
+++ b/configure
@@ -0,0 +1,515 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+#source_path="`dirname \"$0\"`"
+source_path=${0%/*}
+. "${source_path}/build/make/configure.sh"
+
+show_help(){
+    show_help_pre
+    cat << EOF
+Advanced options:
+  ${toggle_libs}                  don't build libraries
+  ${toggle_examples}              don't build examples
+  --libc=PATH                     path to alternate libc
+  ${toggle_fast_unaligned}        don't use unaligned accesses, even when
+                                  supported by hardware [auto]
+  ${toggle_codec_srcs}            in/exclude codec library source code
+  ${toggle_debug_libs}            in/exclude debug version of libraries
+  ${toggle_eval_limit}            enable limited evaluation build
+  ${toggle_md5}                   support for output of checksum data
+  ${toggle_static_msvcrt}         use static MSVCRT (VS builds only)
+  ${toggle_vp8}                   VP8 codec support
+  ${toggle_psnr}                  output of PSNR data, if supported (encoders)
+  ${toggle_mem_tracker}           track memory usage
+  ${toggle_eval_limit}            decoder limitted to 500 frames
+  ${toggle_postproc}              postprocessing
+  ${toggle_multithread}           multithreaded encoding and decoding.
+  ${toggle_spatial_resampling}    spatial sampling (scaling) support
+  ${toggle_realtime_only}         enable this option while building for real-time encoding
+  ${toggle_runtime_cpu_detect}    runtime cpu detection
+
+Codecs:
+  Codecs can be selectively enabled or disabled individually, or by family:
+      --disable-<codec>
+  is equivalent to:
+      --disable-<codec>-encoder
+      --disable-<codec>-decoder
+
+  Codecs available in this distribution:
+EOF
+#restore editor state '
+
+    local family;
+    local last_family;
+    local c;
+    local str;
+    for c in ${CODECS}; do
+        family=${c%_*}
+        if [ "${family}" != "${last_family}" ]; then
+            [ -z "${str}" ] || echo "${str}"
+            str="$(printf '    %10s:' ${family})"
+        fi
+        str="${str} $(printf '%10s' ${c#*_})"
+        last_family=${family}
+    done
+    echo "${str}"
+    show_help_post
+}
+
+##
+## BEGIN APPLICATION SPECIFIC CONFIGURATION
+##
+
+# all_platforms is a list of all supported target platforms. Maintain
+# alphabetically by architecture, generic-gnu last.
+all_platforms="${all_platforms} armv5te-linux-rvct"
+all_platforms="${all_platforms} armv5te-linux-gcc"
+all_platforms="${all_platforms} armv5te-symbian-gcc"
+all_platforms="${all_platforms} armv5te-wince-vs8"
+all_platforms="${all_platforms} armv6-darwin-gcc"
+all_platforms="${all_platforms} armv6-linux-rvct"
+all_platforms="${all_platforms} armv6-linux-gcc"
+all_platforms="${all_platforms} armv6-symbian-gcc"
+all_platforms="${all_platforms} armv6-wince-vs8"
+all_platforms="${all_platforms} iwmmxt-linux-rvct"
+all_platforms="${all_platforms} iwmmxt-linux-gcc"
+all_platforms="${all_platforms} iwmmxt-wince-vs8"
+all_platforms="${all_platforms} iwmmxt2-linux-rvct"
+all_platforms="${all_platforms} iwmmxt2-linux-gcc"
+all_platforms="${all_platforms} iwmmxt2-wince-vs8"
+all_platforms="${all_platforms} armv7-darwin-gcc"    #neon Cortex-A8
+all_platforms="${all_platforms} armv7-linux-rvct"    #neon Cortex-A8
+all_platforms="${all_platforms} armv7-linux-gcc"     #neon Cortex-A8
+all_platforms="${all_platforms} mips32-linux-gcc"
+all_platforms="${all_platforms} ppc32-darwin8-gcc"
+all_platforms="${all_platforms} ppc32-darwin9-gcc"
+all_platforms="${all_platforms} ppc64-darwin8-gcc"
+all_platforms="${all_platforms} ppc64-darwin9-gcc"
+all_platforms="${all_platforms} ppc64-linux-gcc"
+all_platforms="${all_platforms} x86-darwin8-gcc"
+all_platforms="${all_platforms} x86-darwin8-icc"
+all_platforms="${all_platforms} x86-darwin9-gcc"
+all_platforms="${all_platforms} x86-darwin9-icc"
+all_platforms="${all_platforms} x86-linux-gcc"
+all_platforms="${all_platforms} x86-linux-icc"
+all_platforms="${all_platforms} x86-solaris-gcc"
+all_platforms="${all_platforms} x86-win32-gcc"
+all_platforms="${all_platforms} x86-win32-vs7"
+all_platforms="${all_platforms} x86-win32-vs8"
+all_platforms="${all_platforms} x86_64-darwin9-gcc"
+all_platforms="${all_platforms} x86_64-linux-gcc"
+all_platforms="${all_platforms} x86_64-solaris-gcc"
+all_platforms="${all_platforms} x86_64-win64-vs8"
+all_platforms="${all_platforms} universal-darwin8-gcc"
+all_platforms="${all_platforms} universal-darwin9-gcc"
+all_platforms="${all_platforms} generic-gnu"
+
+# all_targets is a list of all targets that can be configured
+# note that these should be in dependency order for now.
+all_targets="libs examples docs"
+
+# all targets available are enabled, by default.
+for t in ${all_targets}; do
+    [ -f ${source_path}/${t}.mk ] && enable ${t}
+done
+
+# check installed doxygen version
+doxy_version=$(doxygen --version 2>/dev/null)
+doxy_major=${doxy_version%%.*}
+if [ ${doxy_major:-0} -ge 1 ]; then
+    doxy_version=${doxy_version#*.}
+    doxy_minor=${doxy_version%%.*}
+    doxy_patch=${doxy_version##*.}
+
+    [ $doxy_major -gt 1 ] && enable doxygen
+    [ $doxy_minor -gt 5 ] && enable doxygen
+    [ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable doxygen
+fi
+
+# install everything, by default
+enabled doxygen && php -v >/dev/null 2>&1 && enable install_docs
+enable install_bins
+enable install_libs
+enable install_srcs
+
+enable optimizations
+enable fast_unaligned #allow unaligned accesses, if supported by hw
+enable md5
+enable spatial_resampling
+enable multithread
+
+[ -d ${source_path}/../include ] && enable alt_tree_layout
+for d in vp8; do
+    [ -d ${source_path}/${d} ] && disable alt_tree_layout;
+done
+
+if ! enabled alt_tree_layout; then
+# development environment
+[ -d ${source_path}/vp8 ] && CODECS="${CODECS} vp8_encoder vp8_decoder"
+else
+# customer environment
+[ -f ${source_path}/../include/vp8cx.h ] && CODECS="${CODECS} vp8_encoder"
+[ -f ${source_path}/../include/vp8dx.h ] && CODECS="${CODECS} vp8_decoder"
+
+[ -f ${source_path}/../lib/*/*mt.lib ] && soft_enable static_msvcrt
+fi
+
+CODECS="$(echo ${CODECS} | tr ' ' '\n')"
+CODEC_FAMILIES="$(for c in ${CODECS}; do echo ${c%_*}; done | sort | uniq)"
+
+ARCH_LIST="
+    arm
+    mips
+    x86
+    x86_64
+    ppc32
+    ppc64
+"
+ARCH_EXT_LIST="
+    armv5te
+    armv6
+    armv7
+    iwmmxt
+    iwmmxt2
+
+    mips32
+
+    mmx
+    sse
+    sse2
+    sse3
+    ssse3
+
+    altivec
+"
+HAVE_LIST="
+    ${ARCH_EXT_LIST}
+    vpx_ports
+    stdint_h
+    alt_tree_layout
+    pthread_h
+    sys_mman_h
+"
+CONFIG_LIST="
+    external_build
+    install_docs
+    install_bins
+    install_libs
+    install_srcs
+    debug
+    gprof
+    gcov
+    rvct
+    gcc
+    msvs
+    pic
+    big_endian
+
+    codec_srcs
+    debug_libs
+    fast_unaligned
+    mem_manager
+    mem_tracker
+    mem_checks
+    md5
+
+    dequant_tokens
+    dc_recon
+    new_tokens
+    eval_limit
+    runtime_cpu_detect
+    postproc
+    postproc_generic
+    multithread
+    psnr
+    ${CODECS}
+    ${CODEC_FAMILIES}
+    encoders
+    decoders
+    static_msvcrt
+    spatial_resampling
+    realtime_only
+"
+CMDLINE_SELECT="
+    extra_warnings
+    werror
+    install_docs
+    install_bins
+    install_libs
+    install_srcs
+    debug
+    gprof
+    gcov
+    pic
+    optimizations
+    ccache
+    runtime_cpu_detect
+
+    libs
+    examples
+    libc
+    fast_unaligned
+    codec_srcs
+    debug_libs
+    md5
+
+    dequant_tokens
+    dc_recon
+    new_tokens
+    eval_limit
+    postproc
+    postproc_generic
+    multithread
+    psnr
+    ${CODECS}
+    ${CODEC_FAMILIES}
+    static_msvcrt
+    mem_tracker
+    spatial_resampling
+    realtime_only
+"
+
+process_cmdline() {
+    for opt do
+        optval="${opt#*=}"
+        case "$opt" in
+        --disable-codecs) for c in ${CODECS}; do disable $c; done ;;
+        *) process_common_cmdline $opt
+        ;;
+        esac
+    done
+}
+
+post_process_cmdline() {
+    local c
+
+    # If the codec family is disabled, disable all components of that family.
+    # If the codec family is enabled, enable all components of that family.
+    log_echo "Configuring selected codecs"
+    for c in ${CODECS}; do
+        disabled ${c%%_*} && disable ${c}
+        enabled ${c%%_*} && enable ${c}
+    done
+
+    # Enable all detected codecs, if they haven't been disabled
+    for c in ${CODECS}; do soft_enable $c; done
+
+    # Enable the codec family if any component of that family is enabled
+    for c in ${CODECS}; do
+        enabled $c && enable ${c%_*}
+    done
+
+    # Set the {en,de}coders variable if any algorithm in that class is enabled
+    for c in ${CODECS}; do
+        enabled ${c} && enable ${c##*_}s
+    done
+
+
+}
+
+
+process_targets() {
+    enabled child || write_common_config_banner
+    enabled universal || write_common_target_config_h  ${BUILD_PFX}vpx_config.h
+
+    # TODO: add host tools target (obj_int_extract, etc)
+
+    # For fat binaries, call configure recursively to configure for each
+    # binary architecture to be included.
+    if enabled universal; then
+        # Call configure (ourselves) for each subarchitecture
+        for arch in $fat_bin_archs; do
+            BUILD_PFX=${arch}/ toolchain=${arch} $self --child $cmdline_args || exit $?
+        done
+    fi
+
+    # The write_common_config (config.mk) logic is deferred until after the
+    # recursive calls to configure complete, becuase we want our universal
+    # targets to be executed last.
+    write_common_config_targets
+    enabled universal && echo "FAT_ARCHS=${fat_bin_archs}" >> config.mk
+
+    # Calculate the default distribution name, based on the enabled features
+    local cf
+    local DIST_DIR=vpx
+    for cf in $CODEC_FAMILIES; do
+        if enabled ${cf}_encoder && enabled ${cf}_decoder; then
+            DIST_DIR="${DIST_DIR}-${cf}"
+        elif enabled ${cf}_encoder; then
+            DIST_DIR="${DIST_DIR}-${cf}cx"
+        elif enabled ${cf}_decoder; then
+            DIST_DIR="${DIST_DIR}-${cf}dx"
+        fi
+    done
+    enabled debug_libs && DIST_DIR="${DIST_DIR}-debug"
+    enabled codec_srcs && DIST_DIR="${DIST_DIR}-src"
+    ! enabled postproc && DIST_DIR="${DIST_DIR}-nopost"
+    ! enabled multithread && DIST_DIR="${DIST_DIR}-nomt"
+    enabled eval_limit && DIST_DIR="${DIST_DIR}-eval"
+    ! enabled install_docs && DIST_DIR="${DIST_DIR}-nodocs"
+    DIST_DIR="${DIST_DIR}-${tgt_isa}-${tgt_os}"
+    case "${tgt_os}" in
+    win*) enabled static_msvcrt && DIST_DIR="${DIST_DIR}mt" || DIST_DIR="${DIST_DIR}md"
+          DIST_DIR="${DIST_DIR}-${tgt_cc}"
+          ;;
+    esac
+    if [ -f "${source_path}/build/make/version.sh" ]; then
+        local ver=`"$source_path/build/make/version.sh" --bare $source_path`
+        DIST_DIR="${DIST_DIR}-${ver}"
+    fi
+    enabled child || echo "DIST_DIR?=${DIST_DIR}" >> config.mk
+    enabled child || echo "CONFIGURE_ARGS?=${CONFIGURE_ARGS}" >> config.mk
+
+    #
+    # Write makefiles for all enabled targets
+    #
+    for tgt in libs examples docs solution; do
+        local tgt_fn="$tgt-$toolchain.mk"
+
+        if enabled $tgt; then
+            echo "Creating makefiles for ${toolchain} ${tgt}"
+            write_common_target_config_mk $tgt_fn ${BUILD_PFX}vpx_config.h
+            #write_${tgt}_config
+        fi
+    done
+
+}
+
+process_detect() {
+    if [ -z "$CC" ]; then
+        echo "Bypassing toolchain for environment detection."
+        enable external_build
+        check_header() {
+            log fake_check_header "$@"
+            header=$1
+            shift
+            var=`echo $header | sed 's/[^A-Za-z0-9_]/_/g'`
+            disable $var
+            case $header in
+                stdio.h)
+                    true;
+                ;;
+                *)
+                    local result=false
+                    for d in "$@"; do
+                        [ -f "${d##-I}/$header" ] && result=true && break
+                    done
+                    ${result:-true}
+            esac && enable $var
+        }
+        check_ld() {
+            true
+        }
+    fi
+    check_header stdio.h || die "Unable to invoke compiler: ${CC} ${CFLAGS}"
+    check_ld <<EOF || die "Toolchain is unable to link executables"
+int main(void) {return 0;}
+EOF
+    # check system headers
+    check_header stdint.h
+    check_header pthread.h
+    check_header sys/mman.h
+
+    check_header vpx_ports/vpx_integer.h -I${source_path} && enable vpx_ports
+}
+
+process_toolchain() {
+    process_common_toolchain
+
+    # Handle universal binaries for this architecture
+    case $toolchain in
+        universal-darwin*)
+            local darwin_ver=${tgt_os##darwin}
+            fat_bin_archs="$fat_bin_archs ppc32-${tgt_os}-gcc"
+
+            # Intel
+            fat_bin_archs="$fat_bin_archs x86-${tgt_os}-${tgt_cc}"
+            if [ $darwin_ver -gt 8 ]; then
+                fat_bin_archs="$fat_bin_archs x86_64-${tgt_os}-${tgt_cc}"
+            fi
+            ;;
+    esac
+
+
+    # Enable some useful compiler flags
+    if enabled gcc; then
+        enabled werror && check_add_cflags -Werror
+        check_add_cflags -Wall
+        check_add_cflags -Wdeclaration-after-statement
+        check_add_cflags -Wdisabled-optimization
+        check_add_cflags -Wpointer-arith
+        check_add_cflags -Wtype-limits
+        check_add_cflags -Wcast-qual
+        enabled extra_warnings || check_add_cflags -Wno-unused
+    fi
+
+    if enabled icc; then
+        enabled werror && check_add_cflags -Werror
+        check_add_cflags -Wall
+        check_add_cflags -Wpointer-arith
+
+        # ICC has a number of floating point optimizations that we disable
+        # in favor of deterministic output WRT to other compilers
+        add_cflags -fp-model precise
+    fi
+
+    # Enable extra, harmless warnings. These might provide additional insight
+    # to what the compiler is doing and why, but in general, but they shouldn't
+    # be treated as fatal, even if we're treating warnings as errors.
+    GCC_EXTRA_WARNINGS="
+        -Wdisabled-optimization
+        -Winline
+    "
+    enabled gcc && EXTRA_WARNINGS="${GCC_EXTRA_WARNINGS}"
+    RVCT_EXTRA_WARNINGS="
+        --remarks
+    "
+    enabled rvct && EXTRA_WARNINGS="${RVCT_EXTRA_WARNINGS}"
+    if enabled extra_warnings; then
+        for w in ${EXTRA_WARNINGS}; do
+            check_add_cflags ${w}
+            enabled gcc && enabled werror && check_add_cflags -Wno-error=${w}
+        done
+    fi
+
+    # ccache only really works on gcc toolchains
+    enabled gcc || soft_disable ccache
+    if enabled mips; then
+        enable dequant_tokens
+       enable dc_recon
+    fi
+
+    # Enable the postbuild target if building for visual studio.
+    case "$tgt_cc" in
+        vs*) enable msvs
+             enable solution
+             vs_version=${tgt_cc##vs}
+             all_targets="${all_targets} solution"
+             INLINE=__inline
+             FORCEINLINE=__forceinline
+        ;;
+    esac
+
+    # Other toolchain specific defaults
+    case $toolchain in x86*|ppc*|universal*) soft_enable postproc;; esac
+}
+
+
+##
+## END APPLICATION SPECIFIC CONFIGURATION
+##
+CONFIGURE_ARGS="$@"
+process "$@"
+cat <<EOF > ${BUILD_PFX}vpx_config.c
+static const char* const cfg = "$CONFIGURE_ARGS";
+const char *vpx_codec_build_config(void) {return cfg;}
+EOF
diff --git a/docs.mk b/docs.mk
new file mode 100644 (file)
index 0000000..3e7b5cd
--- /dev/null
+++ b/docs.mk
@@ -0,0 +1,54 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+INSTALL_MAPS += docs/%    docs/%
+INSTALL_MAPS += src/%     %
+INSTALL_MAPS += %         %
+
+# Static documentation authored in doxygen
+CODEC_DOX :=    mainpage.dox \
+               keywords.dox \
+               usage.dox \
+               usage_cx.dox \
+               usage_dx.dox \
+
+# Other doxy files sourced in Markdown
+TXT_DOX-$(CONFIG_VP8)          += vp8_api1_migration.dox
+vp8_api1_migration.dox.DESC     = VP8 API 1.x Migration
+
+TXT_DOX = $(call enabled,TXT_DOX)
+
+%.dox: %.txt
+       @echo "    [DOXY] $@"
+       @$(SRC_PATH_BARE)/examples/gen_example_doxy.php \
+             $(@:.dox=)  "$($@.DESC)" > $@ < $<
+
+
+EXAMPLE_PATH += $(SRC_PATH_BARE) #for CHANGELOG, README, etc
+
+doxyfile: libs.doxy_template libs.doxy examples.doxy
+       @echo "    [CREATE] $@"
+       @cat $^ > $@
+       @echo "STRIP_FROM_PATH += $(SRC_PATH_BARE) $(BUILD_ROOT)" >> $@
+       @echo "INPUT += $(addprefix $(SRC_PATH_BARE)/,$(CODEC_DOX))" >> $@;
+       @echo "INPUT += $(TXT_DOX)" >> $@;
+       @echo "EXAMPLE_PATH += $(EXAMPLE_PATH)" >> $@
+
+CLEAN-OBJS += doxyfile $(wildcard docs/html/*)
+docs/html/index.html: doxyfile $(CODEC_DOX) $(TXT_DOX)
+       @echo "    [DOXYGEN] $<"
+       @doxygen $<
+DOCS-yes += docs/html/index.html
+
+INSTALL-DOCS-yes = $(wildcard docs/html/*)
+INSTALL-DOCS-$(CONFIG_CODEC_SRCS) += $(addprefix src/,$(CODEC_DOX))
+INSTALL-DOCS-$(CONFIG_CODEC_SRCS) += src/libs.doxy_template
+INSTALL-DOCS-yes                  += CHANGELOG
+INSTALL-DOCS-yes                  += README
diff --git a/example_xma.c b/example_xma.c
new file mode 100644 (file)
index 0000000..cc4e591
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This is a simple program showing how to initialize the decoder in XMA mode */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx_config.h"
+#include "vpx_decoder.h"
+#include "vpx_integer.h"
+#if CONFIG_VP8_DECODER
+#include "vp8dx.h"
+#endif
+
+static char *exec_name;
+static int   verbose = 0;
+
+static const struct
+{
+    const char *name;
+    const vpx_codec_iface_t *iface;
+} ifaces[] =
+{
+#if CONFIG_VP8_DECODER
+    {"vp8",  &vpx_codec_vp8_dx_algo},
+#endif
+};
+
+static void usage_exit(void)
+{
+    int i;
+
+    printf("Usage: %s <options>\n\n"
+           "Options:\n"
+           "\t--codec <name>\tCodec to use (default=%s)\n"
+           "\t-h <height>\tHeight of the simulated video frame, in pixels\n"
+           "\t-w <width> \tWidth of the simulated video frame, in pixels\n"
+           "\t-v         \tVerbose mode (show individual segment sizes)\n"
+           "\t--help     \tShow this message\n"
+           "\n"
+           "Included decoders:\n"
+           "\n",
+           exec_name,
+           ifaces[0].name);
+
+    for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
+        printf("    %-6s - %s\n",
+               ifaces[i].name,
+               vpx_codec_iface_name(ifaces[i].iface));
+
+    exit(EXIT_FAILURE);
+}
+
+static void usage_error(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    printf("\n");
+    usage_exit();
+}
+
+void my_mem_dtor(vpx_codec_mmap_t *mmap)
+{
+    if (verbose)
+        printf("freeing segment %d\n", mmap->id);
+
+    free(mmap->priv);
+}
+
+int main(int argc, char **argv)
+{
+    vpx_codec_ctx_t           decoder;
+    vpx_codec_iface_t        *iface = ifaces[0].iface;
+    vpx_codec_iter_t          iter;
+    vpx_codec_dec_cfg_t       cfg;
+    vpx_codec_err_t           res = VPX_CODEC_OK;
+    unsigned int            alloc_sz = 0;
+    unsigned int            w = 352;
+    unsigned int            h = 288;
+    int                     i;
+
+    exec_name = argv[0];
+
+    for (i = 1; i < argc; i++)
+    {
+        if (!strcmp(argv[i], "--codec"))
+        {
+            if (i + 1 < argc)
+            {
+                int j, k = -1;
+
+                i++;
+
+                for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++)
+                    if (!strcmp(ifaces[j].name, argv[i]))
+                        k = j;
+
+                if (k >= 0)
+                    iface = ifaces[k].iface;
+                else
+                    usage_error("Error: Unrecognized argument (%s) to --codec\n",
+                                argv[i]);
+            }
+            else
+                usage_error("Error: Option --codec requires argument.\n");
+        }
+        else if (!strcmp(argv[i], "-v"))
+            verbose = 1;
+        else if (!strcmp(argv[i], "-h"))
+            if (i + 1 < argc)
+            {
+                h = atoi(argv[++i]);
+            }
+            else
+                usage_error("Error: Option -h requires argument.\n");
+        else if (!strcmp(argv[i], "-w"))
+            if (i + 1 < argc)
+            {
+                w = atoi(argv[++i]);
+            }
+            else
+                usage_error("Error: Option -w requires argument.\n");
+        else if (!strcmp(argv[i], "--help"))
+            usage_exit();
+        else
+            usage_error("Error: Unrecognized option %s\n\n", argv[i]);
+    }
+
+    if (argc == 1)
+        printf("Using built-in defaults. For options, rerun with --help\n\n");
+
+    /* XMA mode is not supported on all decoders! */
+    if (!(vpx_codec_get_caps(iface) & VPX_CODEC_CAP_XMA))
+    {
+        printf("%s does not support XMA mode!\n", vpx_codec_iface_name(iface));
+        return EXIT_FAILURE;
+    }
+
+    /* The codec knows how much memory to allocate based on the size of the
+     * encoded frames. This data can be parsed from the bitstream with
+     * vpx_codec_peek_stream_info() if a bitstream is available. Otherwise,
+     * a fixed size can be used that will be the upper limit on the frame
+     * size the decoder can decode.
+     */
+    cfg.w = w;
+    cfg.h = h;
+
+    /* Initialize the decoder in XMA mode. */
+    if (vpx_codec_dec_init(&decoder, iface, &cfg, VPX_CODEC_USE_XMA))
+    {
+        printf("Failed to initialize decoder in XMA mode: %s\n", vpx_codec_error(&decoder));
+        return EXIT_FAILURE;
+    }
+
+    /* Iterate through the list of memory maps, allocating them with the
+     * requested alignment.
+     */
+    iter = NULL;
+
+    do
+    {
+        vpx_codec_mmap_t  mmap;
+        unsigned int    align;
+
+        res = vpx_codec_get_mem_map(&decoder, &mmap, &iter);
+        align = mmap.align ? mmap.align - 1 : 0;
+
+        if (!res)
+        {
+            if (verbose)
+                printf("Allocating segment %u, size %lu, align %u %s\n",
+                       mmap.id, mmap.sz, mmap.align,
+                       mmap.flags & VPX_CODEC_MEM_ZERO ? "(ZEROED)" : "");
+
+            if (mmap.flags & VPX_CODEC_MEM_ZERO)
+                mmap.priv = calloc(1, mmap.sz + align);
+            else
+                mmap.priv = malloc(mmap.sz + align);
+
+            mmap.base = (void *)((((uintptr_t)mmap.priv) + align) & ~(uintptr_t)align);
+            mmap.dtor = my_mem_dtor;
+            alloc_sz += mmap.sz + align;
+
+            if (vpx_codec_set_mem_map(&decoder, &mmap, 1))
+            {
+                printf("Failed to set mmap: %s\n", vpx_codec_error(&decoder));
+                return EXIT_FAILURE;
+            }
+        }
+        else if (res != VPX_CODEC_LIST_END)
+        {
+            printf("Failed to get mmap: %s\n", vpx_codec_error(&decoder));
+            return EXIT_FAILURE;
+        }
+    }
+    while (res != VPX_CODEC_LIST_END);
+
+    printf("%s\n    %d bytes external memory required for %dx%d.\n",
+           decoder.name, alloc_sz, cfg.w, cfg.h);
+    vpx_codec_destroy(&decoder);
+    return EXIT_SUCCESS;
+
+}
diff --git a/examples.mk b/examples.mk
new file mode 100644 (file)
index 0000000..036a423
--- /dev/null
@@ -0,0 +1,231 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+# List of examples to build. UTILS are files that are taken from the source
+# tree directly, and GEN_EXAMPLES are files that are created from the
+# examples folder.
+UTILS-$(CONFIG_DECODERS)    += ivfdec.c
+ivfdec.SRCS                 += md5_utils.c md5_utils.h
+ivfdec.SRCS                 += vpx_ports/vpx_timer.h
+ivfdec.SRCS                 += vpx_ports/vpx_integer.h
+ivfdec.SRCS                 += args.c args.h vpx_ports/config.h
+ivfdec.GUID                  = BA5FE66F-38DD-E034-F542-B1578C5FB950
+ivfdec.DESCRIPTION           = Full featured decoder
+UTILS-$(CONFIG_ENCODERS)    += ivfenc.c
+ivfenc.SRCS                 += args.c args.h vpx_ports/config.h
+ivfenc.SRCS                 += vpx_ports/mem_ops.h vpx_ports/mem_ops_aligned.h
+ivfenc.GUID                  = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
+ivfenc.DESCRIPTION           = Full featured encoder
+UTILS-$(CONFIG_DECODERS)    += example_xma.c
+example_xma.GUID             = A955FC4A-73F1-44F7-135E-30D84D32F022
+example_xma.DESCRIPTION      = External Memory Allocation mode usage
+
+GEN_EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
+simple_decoder.GUID              = D3BBF1E9-2427-450D-BBFF-B2843C1D44CC
+simple_decoder.DESCRIPTION       = Simplified decoder loop
+GEN_EXAMPLES-$(CONFIG_DECODERS) += postproc.c
+postproc.GUID                    = 65E33355-F35E-4088-884D-3FD4905881D7
+postproc.DESCRIPTION             = Decoder postprocessor control
+GEN_EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
+decode_to_md5.SRCS              += md5_utils.h md5_utils.c
+decode_to_md5.GUID               = 59120B9B-2735-4BFE-B022-146CA340FE42
+decode_to_md5.DESCRIPTION        = Frame by frame MD5 checksum
+
+GEN_EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
+simple_encoder.GUID              = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
+simple_encoder.DESCRIPTION       = Simplified encoder loop
+GEN_EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
+twopass_encoder.GUID             = 73494FA6-4AF9-4763-8FBB-265C92402FD8
+twopass_encoder.DESCRIPTION      = Two-pass encoder loop
+GEN_EXAMPLES-$(CONFIG_ENCODERS) += force_keyframe.c
+force_keyframe.GUID              = 3C67CADF-029F-4C86-81F5-D6D4F51177F0
+force_keyframe.DESCRIPTION       = Force generation of keyframes
+ifeq ($(CONFIG_DECODERS),yes)
+GEN_EXAMPLES-$(CONFIG_ENCODERS) += decode_with_drops.c
+endif
+decode_with_drops.GUID           = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
+decode_with_drops.DESCRIPTION    = Drops frames while decoding
+GEN_EXAMPLES-$(CONFIG_ENCODERS) += error_resilient.c
+error_resilient.GUID             = DF5837B9-4145-4F92-A031-44E4F832E00C
+error_resilient.DESCRIPTION      = Error Resiliency Feature
+
+GEN_EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_scalable_patterns.c
+vp8_scalable_patterns.GUID          = 0D6A210B-F482-4D6F-8570-4A9C01ACC88C
+vp8_scalable_patterns.DESCRIPTION   = VP8 Scalable Bitstream Patterns
+GEN_EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_set_maps.c
+vp8_set_maps.GUID                   = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
+vp8_set_maps.DESCRIPTION            = VP8 set active and ROI maps
+GEN_EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
+vp8cx_set_ref.GUID                  = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
+vp8cx_set_ref.DESCRIPTION           = VP8 set encoder reference frame
+
+
+# Handle extra library flags depending on codec configuration
+CODEC_EXTRA_LIBS-$(CONFIG_VP8)         += m
+
+#
+# End of specified files. The rest of the build rules should happen
+# automagically from here.
+#
+
+
+# Examples need different flags based on whether we're building
+# from an installed tree or a version controlled tree. Determine
+# the proper paths.
+ifeq ($(HAVE_ALT_TREE_LAYOUT),yes)
+    LIB_PATH := $(SRC_PATH_BARE)/../lib
+    INC_PATH := $(SRC_PATH_BARE)/../include
+else
+    LIB_PATH-yes                     += $(if $(BUILD_PFX),$(BUILD_PFX),.)
+    INC_PATH-yes                     += $(SRC_PATH_BARE)/vpx_codec
+    INC_PATH-yes                     += $(SRC_PATH_BARE)/vpx_ports
+    INC_PATH-$(CONFIG_VP8_DECODER)   += $(SRC_PATH_BARE)/vp8
+    INC_PATH-$(CONFIG_VP8_ENCODER)   += $(SRC_PATH_BARE)/vp8
+    LIB_PATH := $(call enabled,LIB_PATH)
+    INC_PATH := $(call enabled,INC_PATH)
+endif
+CFLAGS += $(addprefix -I,$(INC_PATH))
+LDFLAGS += $(addprefix -L,$(LIB_PATH))
+
+
+# Expand list of selected examples to build (as specified above)
+UTILS           = $(call enabled,UTILS)
+GEN_EXAMPLES    = $(call enabled,GEN_EXAMPLES)
+ALL_EXAMPLES    = $(UTILS) $(GEN_EXAMPLES)
+ALL_SRCS        = $(foreach ex,$(ALL_EXAMPLES),$($(ex:.c=).SRCS))
+CODEC_EXTRA_LIBS=$(sort $(call enabled,CODEC_EXTRA_LIBS))
+
+
+# Expand all example sources into a variable containing all sources
+# for that example (not just them main one specified in UTILS/GEN_EXAMPLES)
+# and add this file to the list (for MSVS workspace generation)
+$(foreach ex,$(ALL_EXAMPLES),$(eval $(ex:.c=).SRCS += $(ex) examples.mk))
+
+
+# If this is a universal (fat) binary, then all the subarchitectures have
+# already been built and our job is to stitch them together. The
+# BUILD_OBJS variable indicates whether we should be building
+# (compiling, linking) the library. The LIPO_OBJS variable indicates
+# that we're stitching.
+$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_OBJS,BUILD_OBJS):=yes)
+
+
+# Create build/install dependencies for all examples. The common case
+# is handled here. The MSVS case is handled below.
+NOT_MSVS = $(if $(CONFIG_MSVS),,yes)
+INSTALL-BINS-$(NOT_MSVS)   += $(addprefix bin/,$(ALL_EXAMPLES:.c=))
+INSTALL-SRCS-yes           += $(ALL_SRCS)
+OBJS-$(NOT_MSVS)           += $(if $(BUILD_OBJS),$(call objs,$(ALL_SRCS)))
+BINS-$(NOT_MSVS)           += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=))
+
+
+# Instantiate linker template for all examples.
+CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
+$(foreach bin,$(BINS-yes),\
+    $(if $(BUILD_OBJS),$(eval $(bin): $(LIB_PATH)/lib$(CODEC_LIB).a))\
+    $(if $(BUILD_OBJS),$(eval $(call linker_template,$(bin),\
+        $(call objs,$($(notdir $(bin)).SRCS)) \
+        -l$(CODEC_LIB) $(addprefix -l,$(CODEC_EXTRA_LIBS))\
+        )))\
+    $(if $(LIPO_OBJS),$(eval $(call lipo_bin_template,$(bin))))\
+    )
+
+
+# Rules to generate the GEN_EXAMPLES sources
+.PRECIOUS: %.c
+CLEAN-OBJS += $(GEN_EXAMPLES)
+%.c: examples/%.txt
+       @echo "    [EXAMPLE] $@"
+       @$(SRC_PATH_BARE)/examples/gen_example_code.sh $< > $@
+
+
+# The following pairs define a mapping of locations in the distribution
+# tree to locations in the source/build trees.
+INSTALL_MAPS += src/%.c   %.c
+INSTALL_MAPS += src/%     $(SRC_PATH_BARE)/%
+INSTALL_MAPS += bin/%     %
+INSTALL_MAPS += %         %
+
+
+# Set up additional MSVS environment
+ifeq ($(CONFIG_MSVS),yes)
+CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
+# This variable uses deferred expansion intentionally, since the results of
+# $(wildcard) may change during the course of the Make.
+VS_PLATFORMS = $(foreach d,$(wildcard */Release/$(CODEC_LIB).lib),$(word 1,$(subst /, ,$(d))))
+INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),bin/$(p)/%  $(p)/Release/%)
+endif
+
+# Build Visual Studio Projects. We use a template here to instantiate
+# explicit rules rather than using an implicit rule because we want to
+# leverage make's VPATH searching rather than specifying the paths on
+# each file in ALL_EXAMPLES. This has the unfortunate side effect that
+# touching the source files trigger a rebuild of the project files
+# even though there is no real dependency there (the dependency is on
+# the makefiles). We may want to revisit this.
+define vcproj_template
+$(1): $($(1:.vcproj=).SRCS)
+       @echo "    [vcproj] $$@"
+       $$(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh\
+            --exe\
+            --target=$$(TOOLCHAIN)\
+            --name=$$(@:.vcproj=)\
+            --ver=$$(CONFIG_VS_VERSION)\
+            --proj-guid=$$($$(@:.vcproj=).GUID)\
+            $$(if $$(CONFIG_STATIC_MSVCRT),--static-crt) \
+            --out=$$@ $$(CFLAGS) $$(LDFLAGS) -l$$(CODEC_LIB) -lwinmm $$^
+endef
+PROJECTS-$(CONFIG_MSVS) += $(ALL_EXAMPLES:.c=.vcproj)
+INSTALL-BINS-$(CONFIG_MSVS) += $(foreach p,$(VS_PLATFORMS),\
+                               $(addprefix bin/$(p)/,$(ALL_EXAMPLES:.c=.exe)))
+$(foreach proj,$(call enabled,PROJECTS),\
+    $(eval $(call vcproj_template,$(proj))))
+
+
+
+#
+# Documentation Rules
+#
+%.dox: examples/%.txt
+       @echo "    [DOXY] $@"
+       @$(SRC_PATH_BARE)/examples/gen_example_text.sh $< | \
+         $(SRC_PATH_BARE)/examples/gen_example_doxy.php \
+             example_$(@:.dox=)  $(@:.dox=.c) > $@
+
+%.dox: %.c
+       @echo "    [DOXY] $@"
+       @echo "/*!\page example_$(@:.dox=) $(@:.dox=)" > $@
+       @echo "   \includelineno $(notdir $<)" >> $@
+       @echo "*/" >> $@
+
+samples.dox: examples.mk
+       @echo "    [DOXY] $@"
+       @echo "/*!\page samples Sample Code" > $@
+       @echo "    This SDK includes a number of sample applications."\
+             "each sample documents a feature of the SDK in both prose"\
+             "and the associated C code. In general, later samples"\
+             "build upon prior samples, so it is best to work through the"\
+             "list in order. The following samples are included: ">>$@
+       @$(foreach ex,$(GEN_EXAMPLES:.c=),\
+          echo "     - \subpage example_$(ex) $($(ex).DESCRIPTION)" >> $@;)
+       @echo >> $@
+       @echo "    In addition, the SDK contains a number of utilities."\
+              "Since these utilities are built upon the concepts described"\
+              "in the sample code listed above, they are not documented in"\
+              "pieces like the samples are. Thir sourcre is included here"\
+              "for reference. The following utilities are included:" >> $@
+       @$(foreach ex,$(UTILS:.c=),\
+          echo "     - \subpage example_$(ex) $($(ex).DESCRIPTION)" >> $@;)
+       @echo "*/" >> $@
+
+CLEAN-OBJS += examples.doxy samples.dox $(ALL_EXAMPLES:.c=.dox)
+DOCS-yes += examples.doxy samples.dox $(ALL_EXAMPLES:.c=.dox)
+examples.doxy: samples.dox $(ALL_EXAMPLES:.c=.dox)
+       @echo "INPUT += $^" > $@
diff --git a/examples/decode_to_md5.txt b/examples/decode_to_md5.txt
new file mode 100644 (file)
index 0000000..0599b13
--- /dev/null
@@ -0,0 +1,48 @@
+@TEMPLATE decoder_tmpl.c
+Frame-by-frame MD5 Checksum
+===========================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This example builds upon the simple decoder loop to show how checksums
+of the decoded output can be generated. These are used for validating
+decoder implementations against the reference implementation, for example.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+MD5 algorithm
+-------------
+The Message-Digest 5 (MD5) is a well known hash function. We have provided
+an implementation derived from the RSA Data Security, Inc. MD5 Message-Digest
+Algorithm for your use. Our implmentation only changes the interface of this
+reference code. You must include the `md5_utils.h` header for access to these
+functions.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_INCLUDES
+#include "md5_utils.h"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_INCLUDES
+
+
+Processing The Decoded Data
+---------------------------
+Each row of the image is passed to the MD5 accumulator. First the Y plane
+is processed, then U, then V. It is important to honor the image's `stride`
+values.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_DX
+unsigned char  md5_sum[16];
+md5_ctx_t      md5;
+int            i;
+
+md5_init(&md5);
+
+for(plane=0; plane < 3; plane++) {
+    unsigned char *buf =img->planes[plane];
+
+    for(y=0; y<img->d_h >> (plane?1:0); y++) {
+        md5_update(&md5, buf, img->d_w >> (plane?1:0));
+        buf += img->stride[plane];
+    }
+}
+
+md5_finalize(&md5, md5_sum);
+for(i=0; i<16; i++)
+    fprintf(outfile, "%02x",md5_sum[i]);
+fprintf(outfile, "  img-%dx%d-%04d.i420\n", img->d_w, img->d_h,
+        frame_cnt);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_DX
diff --git a/examples/decode_with_drops.txt b/examples/decode_with_drops.txt
new file mode 100644 (file)
index 0000000..fb77a7e
--- /dev/null
@@ -0,0 +1,73 @@
+@TEMPLATE decoder_tmpl.c
+Decode With Drops Example
+=========================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example utility which drops a series of frames, as specified
+on the command line. This is useful for observing the error recovery
+features of the codec.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+Usage
+-----
+This example adds a single argument to the `simple_decoder` example,
+which specifies the range or pattern of frames to drop. The parameter is
+parsed as follows:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+if(argc!=4)
+    die("Usage: %s <infile> <outfile> <N-M|N/M>\n", argv[0]);
+{
+    char *nptr;
+    n = strtol(argv[3], &nptr, 0);
+    m = strtol(nptr+1, NULL, 0);
+    is_range = *nptr == '-';
+    if(!n || !m || (*nptr != '-' && *nptr != '/'))
+        die("Couldn't parse pattern %s\n", argv[3]);
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+
+
+Dropping A Range Of Frames
+--------------------------
+To drop a range of frames, specify the starting frame and the ending
+frame to drop, separated by a dash. The following command will drop
+frames 5 through 10 (base 1).
+
+  $ ./decode_with_drops in.ivf out.i420 5-10
+
+
+Dropping A Pattern Of Frames
+----------------------------
+To drop a pattern of frames, specify the number of frames to drop and
+the number of frames after which to repeat the pattern, separated by
+a forward-slash. The following command will drop 3 of 7 frames.
+Specifically, it will decode 4 frames, then drop 3 frames, and then
+repeat.
+
+  $ ./decode_with_drops in.ivf out.i420 3/7
+
+
+Extra Variables
+---------------
+This example maintains the pattern passed on the command line in the
+`n`, `m`, and `is_range` variables:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_VARS
+int              n, m, is_range;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_VARS
+
+
+Making The Drop Decision
+------------------------
+The example decides whether to drop the frame based on the current
+frame number, immediately before decoding the frame.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PRE_DECODE
+if((is_range && frame_cnt >= n && frame_cnt <= m)
+   ||(!is_range && m - (frame_cnt-1)%m <= n)) {
+   putc('X', stdout);
+   continue;
+}
+putc('.', stdout);
+fflush(stdout);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PRE_DECODE
diff --git a/examples/decoder_tmpl.c b/examples/decoder_tmpl.c
new file mode 100644 (file)
index 0000000..deea449
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+@*INTRODUCTION
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx_decoder.h"
+#if CONFIG_VP8_DECODER && !defined(interface)
+#include "vp8dx.h"
+#define interface (&vpx_codec_vp8_dx_algo)
+#endif
+@EXTRA_INCLUDES
+
+
+#define IVF_FILE_HDR_SZ  (32)
+#define IVF_FRAME_HDR_SZ (12)
+
+static unsigned int mem_get_le32(const unsigned char *mem) {
+    return (mem[3] << 24)|(mem[2] << 16)|(mem[1] << 8)|(mem[0]);
+}
+
+static void die(const char *fmt, ...) {
+    va_list ap;
+
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    if(fmt[strlen(fmt)-1] != '\n')
+        printf("\n");
+    exit(EXIT_FAILURE);
+}
+
+@DIE_CODEC
+
+int main(int argc, char **argv) {
+    FILE            *infile, *outfile;
+    vpx_codec_ctx_t  codec;
+    int              flags = 0, frame_cnt = 0;
+    unsigned char    file_hdr[IVF_FILE_HDR_SZ];
+    unsigned char    frame_hdr[IVF_FRAME_HDR_SZ];
+    unsigned char    frame[256*1024];
+    vpx_codec_err_t  res;
+@@@@EXTRA_VARS
+
+    (void)res;
+    /* Open files */
+@@@@USAGE
+    if(!(infile = fopen(argv[1], "rb")))
+        die("Failed to open %s for reading", argv[1]);
+    if(!(outfile = fopen(argv[2], "wb")))
+        die("Failed to open %s for writing", argv[2]);
+
+    /* Read file header */
+    fread(file_hdr, 1, IVF_FILE_HDR_SZ, infile);
+    if(!(file_hdr[0]=='D' && file_hdr[1]=='K' && file_hdr[2]=='I'
+         && file_hdr[3]=='F'))
+        die("%s is not an IVF file.", argv[1]);
+
+    printf("Using %s\n",vpx_codec_iface_name(interface));
+@@@@DEC_INIT
+
+    /* Read each frame */
+    while(fread(frame_hdr, 1, IVF_FRAME_HDR_SZ, infile) == IVF_FRAME_HDR_SZ) {
+        int               frame_sz = mem_get_le32(frame_hdr);
+        vpx_codec_iter_t  iter = NULL;
+        vpx_image_t      *img;
+
+
+        frame_cnt++;
+        if(frame_sz > sizeof(frame))
+            die("Frame %d data too big for example code buffer", frame_sz);
+        if(fread(frame, 1, frame_sz, infile) != frame_sz)
+            die("Frame %d failed to read complete frame", frame_cnt);
+
+@@@@@@@@PRE_DECODE
+@@@@@@@@DECODE
+
+        /* Write decoded data to disk */
+@@@@@@@@GET_FRAME
+            unsigned int plane, y;
+
+@@@@@@@@@@@@PROCESS_DX
+        }
+    }
+    printf("Processed %d frames.\n",frame_cnt);
+@@@@DESTROY
+
+    fclose(outfile);
+    fclose(infile);
+    return EXIT_SUCCESS;
+}
diff --git a/examples/decoder_tmpl.txt b/examples/decoder_tmpl.txt
new file mode 100644 (file)
index 0000000..3287d50
--- /dev/null
@@ -0,0 +1,61 @@
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INCLUDES
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx_decoder.h"
+#include "vp8dx.h"
+#define interface (&vpx_codec_vp8_dx_algo)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INCLUDES
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
+static void die_codec(vpx_codec_ctx_t *ctx, const char *s) {
+    const char *detail = vpx_codec_error_detail(ctx);
+
+    printf("%s: %s\n", s, vpx_codec_error(ctx));
+    if(detail)
+        printf("    %s\n",detail);
+    exit(EXIT_FAILURE);
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+if(argc!=3)
+    die("Usage: %s <infile> <outfile>\n", argv[0]);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
+/* Initialize codec */
+if(vpx_codec_dec_init(&codec, interface, NULL, flags))
+    die_codec(&codec, "Failed to initialize decoder");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE
+/* Decode the frame */
+if(vpx_codec_decode(&codec, frame, frame_sz, NULL, 0))
+    die_codec(&codec, "Failed to decode frame");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GET_FRAME
+while((img = vpx_codec_get_frame(&codec, &iter))) {
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GET_FRAME
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_DX
+for(plane=0; plane < 3; plane++) {
+    unsigned char *buf =img->planes[plane];
+
+    for(y=0; y<img->d_h >> (plane?1:0); y++) {
+        fwrite(buf, 1, img->d_w >> (plane?1:0), outfile);
+        buf += img->stride[plane];
+    }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_DX
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
+if(vpx_codec_destroy(&codec))
+    die_codec(&codec, "Failed to destroy codec");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
diff --git a/examples/encoder_tmpl.c b/examples/encoder_tmpl.c
new file mode 100644 (file)
index 0000000..2df893a
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+@*INTRODUCTION
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx_encoder.h"
+#if CONFIG_VP8_ENCODER && !defined(interface)
+#include "vp8cx.h"
+#define interface (&vpx_codec_vp8_cx_algo)
+#define fourcc    0x30385056
+#endif
+@EXTRA_INCLUDES
+
+#define IVF_FILE_HDR_SZ  (32)
+#define IVF_FRAME_HDR_SZ (12)
+
+static void mem_put_le16(char *mem, unsigned int val) {
+    mem[0] = val;
+    mem[1] = val>>8;
+}
+
+static void mem_put_le32(char *mem, unsigned int val) {
+    mem[0] = val;
+    mem[1] = val>>8;
+    mem[2] = val>>16;
+    mem[3] = val>>24;
+}
+
+static void die(const char *fmt, ...) {
+    va_list ap;
+
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    if(fmt[strlen(fmt)-1] != '\n')
+        printf("\n");
+    exit(EXIT_FAILURE);
+}
+
+@DIE_CODEC
+
+static int read_frame(FILE *f, vpx_image_t *img) {
+    size_t nbytes, to_read;
+    int    res = 1;
+
+    to_read = img->w*img->h*3/2;
+    nbytes = fread(img->planes[0], 1, to_read, f);
+    if(nbytes != to_read) {
+        res = 0;
+        if(nbytes > 0)
+            printf("Warning: Read partial frame. Check your width & height!\n");
+    }
+    return res;
+}
+
+static void write_ivf_file_header(FILE *outfile,
+                                  const vpx_codec_enc_cfg_t *cfg,
+                                  int frame_cnt) {
+    char header[32];
+
+    if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
+        return;
+    header[0] = 'D';
+    header[1] = 'K';
+    header[2] = 'I';
+    header[3] = 'F';
+    mem_put_le16(header+4,  0);                   /* version */
+    mem_put_le16(header+6,  32);                  /* headersize */
+    mem_put_le32(header+8,  fourcc);              /* headersize */
+    mem_put_le16(header+12, cfg->g_w);            /* width */
+    mem_put_le16(header+14, cfg->g_h);            /* height */
+    mem_put_le32(header+16, cfg->g_timebase.den); /* rate */
+    mem_put_le32(header+20, cfg->g_timebase.num); /* scale */
+    mem_put_le32(header+24, frame_cnt);           /* length */
+    mem_put_le32(header+28, 0);                   /* unused */
+
+    fwrite(header, 1, 32, outfile);
+}
+
+
+static void write_ivf_frame_header(FILE *outfile,
+                                   const vpx_codec_cx_pkt_t *pkt)
+{
+    char             header[12];
+    vpx_codec_pts_t  pts;
+
+    if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
+        return;
+
+    pts = pkt->data.frame.pts;
+    mem_put_le32(header, pkt->data.frame.sz);
+    mem_put_le32(header+4, pts&0xFFFFFFFF);
+    mem_put_le32(header+8, pts >> 32);
+
+    fwrite(header, 1, 12, outfile);
+}
+
+int main(int argc, char **argv) {
+    FILE                *infile, *outfile;
+    vpx_codec_ctx_t      codec;
+    vpx_codec_enc_cfg_t  cfg;
+    int                  frame_cnt = 0;
+    unsigned char        file_hdr[IVF_FILE_HDR_SZ];
+    unsigned char        frame_hdr[IVF_FRAME_HDR_SZ];
+    vpx_image_t          raw;
+    vpx_codec_err_t      res;
+    long                 width;
+    long                 height;
+    int                  frame_avail;
+    int                  got_data;
+    int                  flags = 0;
+@@@@TWOPASS_VARS
+
+    /* Open files */
+@@@@USAGE
+    width = strtol(argv[1], NULL, 0);
+    height = strtol(argv[2], NULL, 0);
+    if(width < 16 || width%2 || height <16 || height%2)
+        die("Invalid resolution: %ldx%ld", width, height);
+    if(!vpx_img_alloc(&raw, IMG_FMT_YV12, width, height, 1))
+        die("Faile to allocate image", width, height);
+    if(!(outfile = fopen(argv[4], "wb")))
+        die("Failed to open %s for writing", argv[4]);
+
+    printf("Using %s\n",vpx_codec_iface_name(interface));
+
+@@@@ENC_DEF_CFG
+
+@@@@ENC_SET_CFG
+@@@@ENC_SET_CFG2
+
+    write_ivf_file_header(outfile, &cfg, 0);
+
+@@@@TWOPASS_LOOP_BEGIN
+
+        /* Open input file for this encoding pass */
+        if(!(infile = fopen(argv[3], "rb")))
+            die("Failed to open %s for reading", argv[3]);
+
+@@@@@@@@ENC_INIT
+
+        frame_avail = 1;
+        got_data = 0;
+        while(frame_avail || got_data) {
+            vpx_codec_iter_t iter = NULL;
+            const vpx_codec_cx_pkt_t *pkt;
+
+@@@@@@@@@@@@PER_FRAME_CFG
+@@@@@@@@@@@@ENCODE_FRAME
+            got_data = 0;
+            while( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
+                got_data = 1;
+                switch(pkt->kind) {
+@@@@@@@@@@@@@@@@PROCESS_FRAME
+@@@@@@@@@@@@@@@@PROCESS_STATS
+                default:
+                    break;
+                }
+                printf(pkt->kind == VPX_CODEC_CX_FRAME_PKT
+                       && (pkt->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
+                fflush(stdout);
+            }
+            frame_cnt++;
+        }
+        printf("\n");
+        fclose(infile);
+@@@@TWOPASS_LOOP_END
+
+    printf("Processed %d frames.\n",frame_cnt-1);
+@@@@DESTROY
+
+    /* Try to rewrite the file header with the actual frame count */
+    if(!fseek(outfile, 0, SEEK_SET))
+        write_ivf_file_header(outfile, &cfg, frame_cnt-1);
+    fclose(outfile);
+    return EXIT_SUCCESS;
+}
diff --git a/examples/encoder_tmpl.txt b/examples/encoder_tmpl.txt
new file mode 100644 (file)
index 0000000..db1ea77
--- /dev/null
@@ -0,0 +1,73 @@
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INCLUDES
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx_encoder.h"
+#include "vp8cx.h"
+#define interface (&vpx_codec_vp8_cx_algo)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INCLUDES
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
+static void die_codec(vpx_codec_ctx_t *ctx, const char *s) {
+    const char *detail = vpx_codec_error_detail(ctx);
+
+    printf("%s: %s\n", s, vpx_codec_error(ctx));
+    if(detail)
+        printf("    %s\n",detail);
+    exit(EXIT_FAILURE);
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+if(argc!=5)
+    die("Usage: %s <width> <height> <infile> <outfile>\n", argv[0]);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_DEF_CFG
+/* Populate encoder configuration */
+res = vpx_codec_enc_config_default(interface, &cfg, 0);
+if(res) {
+    printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
+    return EXIT_FAILURE;
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_DEF_CFG
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG
+/* Update the default configuration with our settings */
+cfg.rc_target_bitrate = width * height * cfg.rc_target_bitrate
+                        / cfg.g_w / cfg.g_h;
+cfg.g_w = width;
+cfg.g_h = height;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INIT
+/* Initialize codec */
+if(vpx_codec_enc_init(&codec, interface, &cfg, 0))
+    die_codec(&codec, "Failed to initialize encoder");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INIT
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+frame_avail = read_frame(infile, &raw);
+if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt,
+                    1, flags, VPX_DL_REALTIME))
+    die_codec(&codec, "Failed to encode frame");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_FRAME
+case VPX_CODEC_CX_FRAME_PKT:
+    write_ivf_frame_header(outfile, pkt);
+    fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
+           outfile);
+    break;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_FRAME
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
+if(vpx_codec_destroy(&codec))
+    die_codec(&codec, "Failed to destroy codec");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
diff --git a/examples/error_resilient.txt b/examples/error_resilient.txt
new file mode 100644 (file)
index 0000000..e9d0949
--- /dev/null
@@ -0,0 +1,25 @@
+@TEMPLATE encoder_tmpl.c
+Error Resiliency Features
+=========================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example demonstrating how to enable the error resiliency
+features of the codec.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Configuration
+-------------
+Error resiliency is controlled by the g_error_resilient member of the
+configuration structure.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ENC_SET_CFG2
+
+/* Enable error resilient mode */
+cfg.g_error_resilient = 1;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG2
+
+
+Observing The Effects
+---------------------
+Use the `decode_with_drops` example to decode with frames 5-10 dropped.
+Compare the output for a file encoded with this example versus one
+encoded with the `simple_encoder` example.
diff --git a/examples/force_keyframe.txt b/examples/force_keyframe.txt
new file mode 100644 (file)
index 0000000..a9c16be
--- /dev/null
@@ -0,0 +1,28 @@
+@TEMPLATE encoder_tmpl.c
+Forcing A Keyframe
+==================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example demonstrating how to control placement of keyframes
+on a frame-by-frame basis.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Configuration
+-------------
+Keyframes can be forced by setting the VPX_EFLAG_FORCE_KF bit of the
+flags passed to `vpx_codec_control()`. In this example, we force a
+keyframe every 8 frames.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  PER_FRAME_CFG
+if(!(frame_cnt & 7))
+    flags |= VPX_EFLAG_FORCE_KF;
+else
+    flags &= ~VPX_EFLAG_FORCE_KF;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG
+
+
+Observing The Effects
+---------------------
+The output of the encoder examples shows a 'K' rather than a dot '.'
+when the encoder generates a keyframe. Note that every 8 frames a 'K'
+is output.
diff --git a/examples/gen_example_code.sh b/examples/gen_example_code.sh
new file mode 100755 (executable)
index 0000000..f2e45c5
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+# gen_example_code.sh
+
+self=$0
+
+die_usage() {
+    echo "Usage: $self <example.txt>"
+    exit 1
+}
+
+die() {
+    echo "$@"
+    exit 1
+}
+
+include_block() {
+    show_bar=$1
+    block_name=${line##*@}
+    indent=${line%%${block_name}}
+    indent=${#indent}
+    [ $indent -eq 1 ] && indent=0
+    local on_block
+    while IFS=$'\n' read -r t_line; do
+        case "$t_line" in
+            \~*\ ${block_name})
+                if [ "x$on_block" == "xyes" ]; then
+                    return 0;
+                else
+                    on_block=yes
+                fi
+                ;;
+            @DEFAULT)
+                if [ "x$on_block" == "xyes" ]; then
+                    include_block $show_bar < "${template%.c}.txt"
+                    return 0
+                fi
+                ;;
+            *)
+                if [ "x$on_block" == "xyes" ]; then
+                    local rem
+                    (( rem = 78 - indent ))
+                    case "$block_name" in
+                      \**) printf "%${indent}s * %s\n" "" "$t_line" ;;
+                        *)
+                            if [ "$show_bar" == "yes" ]; then
+                                printf "%${indent}s%-${rem}s//\n" "" "$t_line"
+                            else
+                                printf "%${indent}s%s\n" "" "$t_line"
+                            fi
+                            ;;
+                    esac
+                fi
+        esac
+    done
+    return 1
+}
+
+txt=$1
+[ -f "$txt" ] || die_usage
+read -r template < "$txt"
+case "$template" in
+    @TEMPLATE*) template=${txt%/*}/${template##@TEMPLATE } ;;
+    *) die "Failed to parse template name from '$template'" ;;
+esac
+
+while IFS=$'\n' read -r line; do
+    case "$line" in
+        @*) include_block yes < "$txt" \
+            || include_block < "${template%.c}.txt" \
+            #|| echo "WARNING: failed to find text for block $block_name" >&2
+            ;;
+        *)  echo "$line" ;;
+    esac
+done < "$template"
diff --git a/examples/gen_example_doxy.php b/examples/gen_example_doxy.php
new file mode 100755 (executable)
index 0000000..08beade
--- /dev/null
@@ -0,0 +1,223 @@
+#!/usr/bin/env php
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+<?php
+
+/* This script converts markdown to doxygen htmlonly syntax, nesting the
+ * content inside a \page. It expects input on stdin and outputs on stdout.
+ *
+ * Usage: gen_example_doxy.php <page_identifier> "<page description>"
+ */
+
+
+$geshi_path = dirname($argv[0])."/includes/geshi/geshi/"; // Language files
+$tmp_token  = '<!-- I wanna rock you, Chaka Khan -->';
+
+// Include prerequisites or exit
+if(!include_once('includes/PHP-Markdown-Extra-1.2.3/markdown.php'))
+  die("Cannot load Markdown transformer.\n");
+if(!include_once('includes/PHP-SmartyPants-1.5.1e/smartypants.php'))
+  die("Cannot load SmartyPants transformer.\n");
+if(!include_once('includes/geshi/geshi.php'))
+  die("Cannot load GeSHi transformer.\n");
+// ASCIIMathPHP?
+// HTML::Toc?
+// Tidy?
+// Prince?
+
+/**
+ *  Generate XHTML body
+ *
+ */
+
+$page_body = file_get_contents('php://stdin');
+
+// Transform any MathML expressions in the body text
+$regexp = '/\[\[(.*?)\]\]/'; // Double square bracket delimiters
+$page_body = preg_replace_callback($regexp, 'ASCIIMathPHPCallback', $page_body);
+
+// Fix ASCIIMathPHP's output
+$page_body = fix_asciiMath($page_body);
+
+// Wrap block-style <math> elements in <p>, since Markdown doesn't.
+$page_body = preg_replace('/\n(<math.*<\/math>)\n/', '<p class="eq_para">$1</p>', $page_body);
+
+// Transform the body text to HTML
+$page_body = Markdown($page_body);
+
+// Preprocess code blocks
+// Decode XML entities. GeSHi doesn't anticipate that
+// Markdown has already done this.
+$regexp = '|<pre><code>(.*?)<\/code><\/pre>|si';
+while (preg_match($regexp, $page_body, $matches) > 0)
+{
+  // Replace 1st match with token
+  $page_body = preg_replace($regexp, $tmp_token, $page_body, 1);
+  $block_new = $matches[1];
+  // Un-encode ampersand entities
+  $block_new = decode_markdown($block_new);
+  // Replace token with revised string
+  $page_body = preg_replace("|$tmp_token|", '<div class="codeblock">'.$block_new.'</div>', $page_body);
+}
+
+// Run GeSHi over code blocks
+$regexp   = '|<div class="codeblock">(.*?)<\/div>|si';
+$language = 'c';
+
+while (preg_match($regexp, $page_body, $matches))
+{
+  $geshi = new GeSHi($matches[1], $language);
+  $geshi->set_language_path($geshi_path);
+  $block_new = $geshi->parse_code();
+  // Strip annoying final newline
+  $block_new = preg_replace('|\n&nbsp;<\/pre>|', '</pre>' , $block_new);
+  // Remove style attribute (TODO: Research this in GeSHi)
+  $block_new = preg_replace('| style="font-family:monospace;"|', '' , $block_new);
+  $page_body = preg_replace($regexp, $block_new, $page_body, 1);
+  unset($geshi);    // Clean up
+}
+unset($block_new);  // Clean up
+
+// Apply typographic flourishes
+$page_body = SmartyPants($page_body);
+
+
+/**
+ *  Generate Doxygen Body
+ *
+ */
+$page_id=(isset($argv[1]))?$argv[1]:"";
+$page_desc=(isset($argv[2]))?$argv[2]:"";
+print "/*!\\page ".$page_id." ".$page_desc."\n\\htmlonly\n";
+print $page_body;
+print "\\endhtmlonly\n*/\n";
+
+// ---------------------------------------------------------
+
+/**
+ * decode_markdown()
+ *
+ * Markdown encodes '&', '<' and '>' in detected code
+ * blocks, as a convenience. This will restore the
+ * encoded entities to ordinary characters, since a
+ * downstream transformer (like GeSHi) may not
+ * anticipate this.
+ *
+ **********************************************************/
+
+function decode_markdown($input)
+{
+  $out = FALSE;
+
+  $entities   = array ('|&amp;|'
+                      ,'|&lt;|'
+                      ,'|&gt;|'
+                      );
+  $characters = array ('&'
+                      ,'<'
+                      ,'>'
+                      );
+  $input = preg_replace($entities, $characters, $input);
+  $out = $input;
+
+  return $out;
+}
+
+
+/**
+ * ASCIIMathML parser
+ * http://tinyurl.com/ASCIIMathPHP
+ *
+ * @PARAM mtch_arr array - Array of ASCIIMath expressions
+ *   as returned by preg_replace_callback([pattern]). First
+ *   dimension is the full matched string (with delimiter);
+ *   2nd dimension is the undelimited contents (typically
+ *   a capture group).
+ *
+ **********************************************************/
+
+function ASCIIMathPHPCallback($mtch_arr)
+{
+  $txt = trim($mtch_arr[1]);
+
+  include('includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.cfg.php');
+  require_once('includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.class.php');
+
+  static $asciimath;
+
+  if (!isset($asciimath)) $asciimath = new ASCIIMathPHP($symbol_arr);
+
+  $math_attr_arr = array('displaystyle' => 'true');
+
+  $asciimath->setExpr($txt);
+  $asciimath->genMathML($math_attr_arr);
+
+  return($asciimath->getMathML());
+}
+
+/**
+ * fix_asciiMath()
+ *
+ * ASCIIMath pretty-prints its output, with linefeeds
+ * and tabs. Causes unexpected behavior in some renderers.
+ * This flattens <math> blocks.
+ *
+ * @PARAM page_body str - The <body> element of an
+ * XHTML page to transform.
+ *
+ **********************************************************/
+
+function fix_asciiMath($page_body)
+{
+  $out = FALSE;
+
+  // Remove linefeeds and whitespace in <math> elements
+  $tags_bad  = array('/(<math.*?>)\n*\s*/'
+                    , '/(<mstyle.*?>)\n*\s*/'
+                    , '/(<\/mstyle>)\n*\s*/'
+                    , '/(<mrow.*?>)\n*\s*/'
+                    , '/(<\/mrow>)\n*\s*/'
+                    , '/(<mo.*?>)\n*\s*/'
+                    , '/(<\/mo>)\n*\s*/'
+                    , '/(<mi.*?>)\n*\s*/'
+                    , '/(<\/mi>)\n*\s*/'
+                    , '/(<mn.*?>)\n*\s*/'
+                    , '/(<\/mn>)\n*\s*/'
+                    , '/(<mtext.*?>)\n*\s*/'
+                    , '/(<\/mtext>)\n*\s*/'
+                    , '/(<msqrt.*?>)\n*\s*/'
+                    , '/(<\/msqrt>)\n*\s*/'
+                    , '/(<mfrac.*?>)\n*\s*/'
+                    , '/(<\/mfrac>)\n*\s*/'
+                    );
+  $tags_good = array( '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    );
+  $out = preg_replace($tags_bad, $tags_good, $page_body);
+
+  return $out;
+
+}
diff --git a/examples/gen_example_text.sh b/examples/gen_example_text.sh
new file mode 100755 (executable)
index 0000000..0e1f796
--- /dev/null
@@ -0,0 +1,83 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+# gen_example_text.sh
+
+self=$0
+
+die_usage() {
+    echo "Usage: $self <example.txt>"
+    exit 1
+}
+
+die() {
+    echo "$@"
+    exit 1
+}
+
+include_block() {
+    local on_block
+    while IFS=$'\n' read -r t_line; do
+        case "$t_line" in
+            \~*\ ${block_name})
+                if [ "x$on_block" == "xyes" ]; then
+                    return 0;
+                else
+                    on_block=yes
+                fi
+                ;;
+            *)
+                if [ "x$on_block" == "xyes" ]; then
+                    echo "$t_line"
+                fi
+                ;;
+        esac
+    done
+    echo "WARNING: failed to find text for block $block_name" >&2
+    return 1
+}
+
+txt=$1
+[ -f "$txt" ] || die_usage
+read -r template < "$txt"
+case "$template" in
+    @TEMPLATE*) template=${txt%/*}/${template##@TEMPLATE } ;;
+    *) die "Failed to parse template name from '$template'" ;;
+esac
+
+fence="~~~~~~~~~"
+fence="${fence}${fence}"
+fence="${fence}${fence}"
+fence="${fence}${fence}"
+while IFS=$'\n' read -r line; do
+    case "$line" in
+        @TEMPLATE*)
+            template=${template##@TEMPLATE }
+            template=${template%.c}.txt
+            ;;
+        @DEFAULT)
+            include_block < "$template"
+            ;;
+        ~~~*)
+            block_name=${line##~* }
+            [ "$block_name" == "INTRODUCTION" ] || echo "$fence"
+            ;;
+        *)  echo "$line"
+            ;;
+    esac
+done < "$txt"
+
+echo
+echo "Putting It All Together"
+echo "======================="
+echo "${fence}"
+${self%/*}/gen_example_code.sh "${txt}"
+echo "${fence}"
diff --git a/examples/includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.cfg.php b/examples/includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.cfg.php
new file mode 100644 (file)
index 0000000..06f7979
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+
+$symbol_arr = array(
+
+// Greek symbols
+'alpha' => array( 'input'=>'alpha','tag'=>'mi', 'output'=>'&#' . hexdec('03B1') . ';'),
+'beta'  => array( 'input'=>'beta','tag'=>'mi', 'output'=>'&#' . hexdec('03B2') . ';'),
+'chi'   => array( 'input'=>'chi','tag'=>'mi', 'output'=>'&#' . hexdec('03C7') . ';'),
+'delta' => array( 'input'=>'delta','tag'=>'mi', 'output'=>'&#' . hexdec('03B4') . ';'),
+'Delta' => array( 'input'=>'Delta','tag'=>'mo', 'output'=>'&#' . hexdec('0394') . ';'),
+'epsi'  => array( 'input'=>'epsi','tag'=>'mi', 'output'=>'&#' . hexdec('03B5') . ';'),
+'varepsilon'    => array( 'input'=>'varepsilon','tag'=>'mi', 'output'=>'&#' . hexdec('025B') . ';'),
+'eta'   => array( 'input'=>'eta','tag'=>'mi', 'output'=>'&#' . hexdec('03B7') . ';'),
+'gamma' => array( 'input'=>'gamma','tag'=>'mi', 'output'=>'&#' . hexdec('03B3') . ';'),
+'Gamma' => array( 'input'=>'Gamma','tag'=>'mi', 'output'=>'&#' . hexdec('0393') . ';'),
+'iota'  => array( 'input'=>'iota','tag'=>'mi', 'output'=>'&#' . hexdec('03B9') . ';'),
+'kappa' => array( 'input'=>'kappa','tag'=>'mi', 'output'=>'&#' . hexdec('03BA') . ';'),
+'lambda'    => array( 'input'=>'lambda','tag'=>'mi', 'output'=>'&#' . hexdec('03BB') . ';'),
+'Lambda'    => array( 'input'=>'Lambda','tag'=>'mo', 'output'=>'&#' . hexdec('039B') . ';'),
+'mu'    => array( 'input'=>'mu','tag'=>'mi', 'output'=>'&#' . hexdec('03BC') . ';'),
+'nu'    => array( 'input'=>'nu','tag'=>'mi', 'output'=>'&#' . hexdec('03BD') . ';'),
+'omega' => array( 'input'=>'omega','tag'=>'mi', 'output'=>'&#' . hexdec('03C9') . ';'),
+'Omega' => array( 'input'=>'Omega','tag'=>'mo', 'output'=>'&#' . hexdec('03A9') . ';'),
+'phi'   => array( 'input'=>'phi','tag'=>'mi', 'output'=>'&#' . hexdec('03C6') . ';'),
+'varphi'    => array( 'input'=>'varphi','tag'=>'mi', 'output'=>'&#' . hexdec('03D5') . ';'),
+'Phi'   => array( 'input'=>'Phi','tag'=>'mo', 'output'=>'&#' . hexdec('03A6') . ';'),
+'pi'    => array( 'input'=>'pi','tag'=>'mi', 'output'=>'&#' . hexdec('03C0') . ';'),
+'Pi'    => array( 'input'=>'Pi','tag'=>'mo', 'output'=>'&#' . hexdec('03A0') . ';'),
+'psi'   => array( 'input'=>'psi','tag'=>'mi', 'output'=>'&#' . hexdec('03C8') . ';'),
+'rho'   => array( 'input'=>'rho','tag'=>'mi', 'output'=>'&#' . hexdec('03C1') . ';'),
+'sigma' => array( 'input'=>'sigma','tag'=>'mi', 'output'=>'&#' . hexdec('03C3') . ';'),
+'Sigma' => array( 'input'=>'Sigma','tag'=>'mo', 'output'=>'&#' . hexdec('03A3') . ';'),
+'tau'   => array( 'input'=>'tau','tag'=>'mi', 'output'=>'&#' . hexdec('03C4') . ';'),
+'theta' => array( 'input'=>'theta','tag'=>'mi', 'output'=>'&#' . hexdec('03B8') . ';'),
+'vartheta'  => array( 'input'=>'vartheta','tag'=>'mi', 'output'=>'&#' . hexdec('03D1') . ';'),
+'Theta' => array( 'input'=>'Theta','tag'=>'mo', 'output'=>'&#' . hexdec('0398') . ';'),
+'upsilon'   => array( 'input'=>'upsilon','tag'=>'mi', 'output'=>'&#' . hexdec('03C5') . ';'),
+'xi'    => array( 'input'=>'xi','tag'=>'mi', 'output'=>'&#' . hexdec('03BE') . ';'),
+'Xi'    => array( 'input'=>'alpha','tag'=>'mo', 'output'=>'&#' . hexdec('039E') . ';'),
+'zeta'  => array( 'input'=>'zeta','tag'=>'mi', 'output'=>'&#' . hexdec('03B6') . ';'),
+
+// Binary operation symbols
+'*'     => array( 'input'=>'*','tag'=>'mo', 'output'=>'&#' . hexdec('22C5') . ';'),
+'**'    => array( 'input'=>'**','tag'=>'mo', 'output'=>'&#' . hexdec('22C6') . ';'),
+'//'    => array( 'input'=>'//','tag'=>'mo', 'output'=>'/'),
+'\\\\'  => array( 'input'=>'\\\\','tag'=>'mo', 'output'=>'\\'),
+'xx'    => array( 'input'=>'xx','tag'=>'mo', 'output'=>'&#' . hexdec('00D7') . ';'),
+'-:'    => array( 'input'=>'-:','tag'=>'mo', 'output'=>'&#' . hexdec('00F7') . ';'),
+'@'     => array( 'input'=>'@','tag'=>'mo', 'output'=>'&#' . hexdec('2218') . ';'),
+'o+'    => array( 'input'=>'o+','tag'=>'mo', 'output'=>'&#' . hexdec('2295') . ';'),
+'ox'    => array( 'input'=>'ox','tag'=>'mo', 'output'=>'&#' . hexdec('2297') . ';'),
+'sum'   => array( 'input'=>'sum','tag'=>'mo', 'output'=>'&#' . hexdec('2211') . ';', 'underover'=>TRUE),
+'prod'  => array( 'input'=>'prod','tag'=>'mo', 'output'=>'&#' . hexdec('220F') . ';', 'underover'=>TRUE),
+'^^'    => array( 'input'=>'^^','tag'=>'mo', 'output'=>'&#' . hexdec('2227') . ';'),
+'^^^'   => array( 'input'=>'^^^','tag'=>'mo', 'output'=>'&#' . hexdec('22C0') . ';', 'underover'=>TRUE),
+'vv'    => array( 'input'=>'vv','tag'=>'mo', 'output'=>'&#' . hexdec('2228') . ';'),
+'vvv'   => array( 'input'=>'vvv','tag'=>'mo', 'output'=>'&#' . hexdec('22C1') . ';', 'underover'=>TRUE),
+'nn'    => array( 'input'=>'nn','tag'=>'mo', 'output'=>'&#' . hexdec('2229') . ';'),
+'nnn'   => array( 'input'=>'nnn','tag'=>'mo', 'output'=>'&#' . hexdec('22C5') . ';', 'underover'=>TRUE),
+'uu'    => array( 'input'=>'uu','tag'=>'mo', 'output'=>'&#' . hexdec('222A') . ';'),
+'uuu'   => array( 'input'=>'uuu','tag'=>'mo', 'output'=>'&#' . hexdec('22C3') . ';', 'underover'=>TRUE),
+
+// Binary relation symbols
+'!='    => array( 'input'=>'!=','tag'=>'mo', 'output'=>'&#' . hexdec('2260') . ';'),
+':='    => array( 'input'=>':=','tag'=>'mo', 'output'=>':=' ),              /* 2005-06-05 wes */
+'<'     => array( 'input'=>'<','tag'=>'mo', 'output'=>'&lt;'),
+'lt'    => array( 'input'=>'lt','tag'=>'mo', 'output'=>'&lt;'),             /* 2005-06-05 wes */
+'<='    => array( 'input'=>'<=','tag'=>'mo', 'output'=>'&#' . hexdec('2264') . ';'),
+'lt='   => array( 'input'=>'lt=','tag'=>'mo', 'output'=>'&#' . hexdec('2264') . ';'),
+'le'    => array( 'input'=>'le','tag'=>'mo', 'output'=>'&#' . hexdec('2264') . ';'),    /* 2005-06-05 wes */
+'>'     => array( 'input'=>'>','tag'=>'mo', 'output'=>'&gt;'),
+'>='    => array( 'input'=>'>=','tag'=>'mo', 'output'=>'&#' . hexdec('2265') . ';'),
+'qeq'   => array( 'input'=>'geq','tag'=>'mo', 'output'=>'&#' . hexdec('2265') . ';'),
+'-<'    => array( 'input'=>'-<','tag'=>'mo', 'output'=>'&#' . hexdec('227A') . ';'),
+'-lt'   => array( 'input'=>'-lt','tag'=>'mo', 'output'=>'&#' . hexdec('227A') . ';'),
+'>-'    => array( 'input'=>'>-','tag'=>'mo', 'output'=>'&#' . hexdec('227B') . ';'),
+'in'    => array( 'input'=>'in','tag'=>'mo', 'output'=>'&#' . hexdec('2208') . ';'),
+'!in'   => array( 'input'=>'!in','tag'=>'mo', 'output'=>'&#' . hexdec('2209') . ';'),
+'sub'   => array( 'input'=>'sub','tag'=>'mo', 'output'=>'&#' . hexdec('2282') . ';'),
+'sup'   => array( 'input'=>'sup','tag'=>'mo', 'output'=>'&#' . hexdec('2283') . ';'),
+'sube'  => array( 'input'=>'sube','tag'=>'mo', 'output'=>'&#' . hexdec('2286') . ';'),
+'supe'  => array( 'input'=>'supe','tag'=>'mo', 'output'=>'&#' . hexdec('2287') . ';'),
+'-='    => array( 'input'=>'-=','tag'=>'mo', 'output'=>'&#' . hexdec('2261') . ';'),
+'~='    => array( 'input'=>'~=','tag'=>'mo', 'output'=>'&#' . hexdec('2245') . ';'),
+'~~'    => array( 'input'=>'~~','tag'=>'mo', 'output'=>'&#' . hexdec('2248') . ';'),
+'prop'  => array( 'input'=>'prop','tag'=>'mo', 'output'=>'&#' . hexdec('221D') . ';'),
+
+// Logical symbols
+'and'   => array( 'input'=>'and','tag'=>'mtext', 'output'=>'and', 'space'=>'1ex'),
+'or'    => array( 'input'=>'or','tag'=>'mtext', 'output'=>'or', 'space'=>'1ex'),
+'not'   => array( 'input'=>'not','tag'=>'mo', 'output'=>'&#' . hexdec('00AC') . ';'),
+'=>'    => array( 'input'=>'=>','tag'=>'mo', 'output'=>'&#' . hexdec('21D2') . ';'),
+'if'    => array( 'input'=>'if','tag'=>'mo', 'output'=>'if', 'space'=>'1ex'),
+'iff'   => array( 'input'=>'iff','tag'=>'mo', 'output'=>'&#' . hexdec('21D4') . ';'),
+'<=>'   => array( 'input'=>'iff','tag'=>'mo', 'output'=>'&#' . hexdec('21D4') . ';'), /* 2005-06-07 wes */
+'AA'    => array( 'input'=>'AA','tag'=>'mo', 'output'=>'&#' . hexdec('2200') . ';'),
+'EE'    => array( 'input'=>'EE','tag'=>'mo', 'output'=>'&#' . hexdec('2203') . ';'),
+'_|_'   => array( 'input'=>'_|_','tag'=>'mo', 'output'=>'&#' . hexdec('22A5') . ';'),
+'TT'    => array( 'input'=>'TT','tag'=>'mo', 'output'=>'&#' . hexdec('22A4') . ';'),
+'|-'    => array( 'input'=>'|-','tag'=>'mo', 'output'=>'&#' . hexdec('22A2') . ';'),
+'|='    => array( 'input'=>'|=','tag'=>'mo', 'output'=>'&#' . hexdec('22A8') . ';'),
+
+// Miscellaneous symbols
+'ang'   => array('input'=>'ang','tag'=>'mo','output'=>'&#' . hexdec('2220') . ';'),
+'deg'   => array('input'=>'deg','tag'=>'mo','output'=>'&#' . hexdec('00B0') . ';'),
+'int'   => array( 'input'=>'int','tag'=>'mo', 'output'=>'&#' . hexdec('222B') . ';'),
+'dx'    => array( 'input'=>'dx','tag'=>'mi', 'output'=>'{:d x:}', 'definition'=>TRUE), /* 2005-06-11 wes */
+'dy'    => array( 'input'=>'dy','tag'=>'mi', 'output'=>'{:d y:}', 'definition'=>TRUE), /* 2005-06-11 wes */
+'dz'    => array( 'input'=>'dz','tag'=>'mi', 'output'=>'{:d z:}', 'definition'=>TRUE), /* 2005-06-11 wes */
+'dt'    => array( 'input'=>'dt','tag'=>'mi', 'output'=>'{:d t:}', 'definition'=>TRUE), /* 2005-06-11 wes */
+'oint'  => array( 'input'=>'oint','tag'=>'mo', 'output'=>'&#' . hexdec('222E') . ';'),
+'del'   => array( 'input'=>'del','tag'=>'mo', 'output'=>'&#' . hexdec('2202') . ';'),
+'grad'  => array( 'input'=>'grad','tag'=>'mo', 'output'=>'&#' . hexdec('2207') . ';'),
+'+-'    => array( 'input'=>'+-','tag'=>'mo', 'output'=>'&#' . hexdec('00B1') . ';'),
+'O/'    => array( 'input'=>'0/','tag'=>'mo', 'output'=>'&#' . hexdec('2205') . ';'),
+'oo'    => array( 'input'=>'oo','tag'=>'mo', 'output'=>'&#' . hexdec('221E') . ';'),
+'aleph' => array( 'input'=>'aleph','tag'=>'mo', 'output'=>'&#' . hexdec('2135') . ';'),
+'...'   => array( 'input'=>'int','tag'=>'mo', 'output'=>'...'),
+'~' => array( 'input'=>'!~','tag'=>'mo', 'output'=>'&#' . hexdec('0020') . ';'),
+'\\ '   => array( 'input'=>'~','tag'=>'mo', 'output'=>'&#' . hexdec('00A0') . ';'),
+'quad'  => array( 'input'=>'quad','tag'=>'mo', 'output'=>'&#' . hexdec('00A0') . ';&#' . hexdec('00A0') . ';'),
+'qquad' => array( 'input'=>'qquad','tag'=>'mo', 'output'=>  '&#' . hexdec('00A0') . ';&#' . hexdec('00A0') . ';&#' . hexdec('00A0') . ';'),
+'cdots' => array( 'input'=>'cdots','tag'=>'mo', 'output'=>'&#' . hexdec('22EF') . ';'),
+'vdots' => array( 'input'=>'vdots','tag'=>'mo', 'output'=>'&#' . hexdec('22EE') . ';'), /* 2005-06-11 wes */
+'ddots' => array( 'input'=>'ddots','tag'=>'mo', 'output'=>'&#' . hexdec('22F1') . ';'), /* 2005-06-11 wes */
+'diamond'   => array( 'input'=>'diamond','tag'=>'mo', 'output'=>'&#' . hexdec('22C4') . ';'),
+'square'    => array( 'input'=>'square','tag'=>'mo', 'output'=>'&#' . hexdec('25A1') . ';'),
+'|_'    => array( 'input'=>'|_','tag'=>'mo', 'output'=>'&#' . hexdec('230A') . ';'),
+'_|'    => array( 'input'=>'_|','tag'=>'mo', 'output'=>'&#' . hexdec('230B') . ';'),
+'|~'    => array( 'input'=>'|~','tag'=>'mo', 'output'=>'&#' . hexdec('2308') . ';'),
+'~|'    => array( 'input'=>'~|','tag'=>'mo', 'output'=>'&#' . hexdec('2309') . ';'),
+'CC'    => array( 'input'=>'CC','tag'=>'mo', 'output'=>'&#' . hexdec('2102') . ';'),
+'NN'    => array( 'input'=>'NN','tag'=>'mo', 'output'=>'&#' . hexdec('2115') . ';'),
+'QQ'    => array( 'input'=>'QQ','tag'=>'mo', 'output'=>'&#' . hexdec('211A') . ';'),
+'RR'    => array( 'input'=>'RR','tag'=>'mo', 'output'=>'&#' . hexdec('211D') . ';'),
+'ZZ'    => array( 'input'=>'ZZ','tag'=>'mo', 'output'=>'&#' . hexdec('2124') . ';'),
+
+// Standard functions
+'lim'   => array( 'input'=>'lim','tag'=>'mo', 'output'=>'lim', 'underover'=>TRUE),
+'Lim'   => array( 'input'=>'Lim','tag'=>'mo', 'output'=>'Lim', 'underover'=>TRUE), /* 2005-06-11 wes */
+'sin'   => array( 'input'=>'sin','tag'=>'mo', 'output'=>'sin', 'unary'=>TRUE, 'func'=>TRUE),
+'cos'   => array( 'input'=>'cos', 'tag'=>'mo', 'output'=>'cos', 'unary'=>TRUE, 'func'=>TRUE),
+'tan'   => array( 'input'=>'tan', 'tag'=>'mo', 'output'=>'tan', 'unary'=>TRUE, 'func'=>TRUE),
+'arcsin'    => array( 'input'=>'arcsin','tag'=>'mo', 'output'=>'arcsin', 'unary'=>TRUE, 'func'=>TRUE), //2006-9-7 DL
+'arccos'    => array( 'input'=>'arccos', 'tag'=>'mo', 'output'=>'arccos', 'unary'=>TRUE, 'func'=>TRUE), //2006-9-7 DL
+'arctan'    => array( 'input'=>'arctan', 'tag'=>'mo', 'output'=>'arctan', 'unary'=>TRUE, 'func'=>TRUE), //2006-9-7 DL
+'sinh'  => array( 'input'=>'sinh','tag'=>'mo', 'output'=>'sinh', 'unary'=>TRUE, 'func'=>TRUE),
+'cosh'  => array( 'input'=>'cosh', 'tag'=>'mo', 'output'=>'cosh', 'unary'=>TRUE, 'func'=>TRUE),
+'tanh'  => array( 'input'=>'tanh', 'tag'=>'mo', 'output'=>'tanh', 'unary'=>TRUE, 'func'=>TRUE),
+'cot'   => array( 'input'=>'cot','tag'=>'mo', 'output'=>'cot', 'unary'=>TRUE, 'func'=>TRUE),
+'sec'   => array( 'input'=>'sec', 'tag'=>'mo', 'output'=>'sec', 'unary'=>TRUE, 'func'=>TRUE),
+'csc'   => array( 'input'=>'csc', 'tag'=>'mo', 'output'=>'csc', 'unary'=>TRUE, 'func'=>TRUE),
+'coth'  => array( 'input'=>'coth','tag'=>'mo', 'output'=>'coth', 'unary'=>TRUE, 'func'=>TRUE),
+'sech'  => array( 'input'=>'sech', 'tag'=>'mo', 'output'=>'sech', 'unary'=>TRUE, 'func'=>TRUE),
+'csch'  => array( 'input'=>'csch', 'tag'=>'mo', 'output'=>'csch', 'unary'=>TRUE, 'func'=>TRUE),
+'log'   => array( 'input'=>'log', 'tag'=>'mo', 'output'=>'log', 'unary'=>TRUE, 'func'=>TRUE),
+'ln'    => array( 'input'=>'ln', 'tag'=>'mo', 'output'=>'ln', 'unary'=>TRUE, 'func'=>TRUE),
+'det'   => array( 'input'=>'det', 'tag'=>'mo', 'output'=>'det', 'unary'=>TRUE, 'func'=>TRUE),
+'dim'   => array( 'input'=>'dim', 'tag'=>'mo', 'output'=>'dim'),
+'mod'   => array( 'input'=>'mod', 'tag'=>'mo', 'output'=>'mod'),
+'gcd'   => array( 'input'=>'gcd', 'tag'=>'mo', 'output'=>'gcd', 'unary'=>TRUE, 'func'=>TRUE),
+'lcm'   => array( 'input'=>'lcm', 'tag'=>'mo', 'output'=>'lcm', 'unary'=>TRUE, 'func'=>TRUE),
+'lub'   => array( 'input'=>'lub', 'tag'=>'mo', 'output'=>'lub'), /* 2005-06-11 wes */
+'glb'   => array( 'input'=>'glb', 'tag'=>'mo', 'output'=>'glb'), /* 2005-06-11 wes */
+'min'   => array( 'input'=>'min', 'tag'=>'mo', 'output'=>'min', 'underover'=>TRUE), /* 2005-06-11 wes */
+'max'   => array( 'input'=>'max', 'tag'=>'mo', 'output'=>'max', 'underover'=>TRUE), /* 2005-06-11 wes */
+'f' => array( 'input'=>'f','tag'=>'mi', 'output'=>'f', 'unary'=>TRUE, 'func'=>TRUE), //2006-9-7 DL
+'g' => array( 'input'=>'g', 'tag'=>'mi', 'output'=>'g', 'unary'=>TRUE, 'func'=>TRUE), //2006-9-7 DL
+
+// Arrows
+'uarr'  => array( 'input'=>'uarr', 'tag'=>'mo', 'output'=>'&#' . hexdec('2191') . ';'),
+'darr'  => array( 'input'=>'darr', 'tag'=>'mo', 'output'=>'&#' . hexdec('2193') . ';'),
+'rarr'  => array( 'input'=>'rarr', 'tag'=>'mo', 'output'=>'&#' . hexdec('2192') . ';'),
+'->'    => array( 'input'=>'->', 'tag'=>'mo', 'output'=>'&#' . hexdec('2192') . ';'),
+'|->'   => array( 'input'=>'|->', 'tag'=>'mo', 'output'=>'&#' . hexdec('21A6') . ';'), /* 2005-06-11 wes */
+'larr'  => array( 'input'=>'larr', 'tag'=>'mo', 'output'=>'&#' . hexdec('2190') . ';'),
+'harr'  => array( 'input'=>'harr', 'tag'=>'mo', 'output'=>'&#' . hexdec('2194') . ';'),
+'rArr'  => array( 'input'=>'rArr', 'tag'=>'mo', 'output'=>'&#' . hexdec('21D2') . ';'),
+'lArr'  => array( 'input'=>'lArr', 'tag'=>'mo', 'output'=>'&#' . hexdec('21D0') . ';'),
+'hArr'  => array( 'input'=>'hArr', 'tag'=>'mo', 'output'=>'&#' . hexdec('21D4') . ';'),
+
+// Commands with argument
+'sqrt'  => array( 'input'=>'sqrt', 'tag'=>'msqrt', 'output'=>'sqrt', 'unary'=>TRUE ),
+'root'  => array( 'input'=>'root', 'tag'=>'mroot', 'output'=>'root', 'binary'=>TRUE ),
+'frac'  => array( 'input'=>'frac', 'tag'=>'mfrac', 'output'=>'/', 'binary'=>TRUE),
+'/'     => array( 'input'=>'/', 'tag'=>'mfrac', 'output'=>'/', 'infix'=>TRUE),
+'_'     => array( 'input'=>'_', 'tag'=>'msub', 'output'=>'_', 'infix'=>TRUE),
+'^'     => array( 'input'=>'^', 'tag'=>'msup', 'output'=>'^', 'infix'=>TRUE),
+'hat'   => array( 'input'=>'hat', 'tag'=>'mover', 'output'=>'&#' . hexdec('005E') . ';', 'unary'=>TRUE, 'acc'=>TRUE),
+'bar'   => array( 'input'=>'bar', 'tag'=>'mover', 'output'=>'&#' . hexdec('00AF') . ';', 'unary'=>TRUE, 'acc'=>TRUE),
+'vec'   => array( 'input'=>'vec', 'tag'=>'mover', 'output'=>'&#' . hexdec('2192') . ';', 'unary'=>TRUE, 'acc'=>TRUE),
+'dot'   => array( 'input'=>'dot', 'tag'=>'mover', 'output'=>'.', 'unary'=>TRUE, 'acc'=>TRUE),
+'ddot'  => array( 'input'=>'ddot', 'tag'=>'mover', 'output'=>'..', 'unary'=>TRUE, 'acc'=>TRUE),
+'ul'    => array( 'input'=>'ul', 'tag'=>'munder', 'output'=>'&#' . hexdec('0332') . ';', 'unary'=>TRUE, 'acc'=>TRUE),
+'avec'  => array( 'input'=>'avec', 'tag'=>'munder', 'output'=>'~', 'unary'=>TRUE, 'acc'=>TRUE),
+'text'  => array( 'input'=>'text', 'tag'=>'mtext', 'output'=>'text', 'unary'=>TRUE),
+'mbox'  => array( 'input'=>'mbox', 'tag'=>'mtext', 'output'=>'mbox', 'unary'=>TRUE),
+'"' => array( 'input'=>'"', 'tag'=>'mtext','output'=>'mbox', 'unary'=>TRUE),
+
+/* 2005-06-05 wes: added stackrel */
+'stackrel' => array( 'input'=>'stackrel', 'tag'=>'mover', 'output'=>'stackrel', 'binary'=>TRUE),
+
+// Grouping brackets
+'('     => array( 'input'=>'(', 'tag'=>'mo', 'output'=>'(', 'left_bracket'=>TRUE),
+')'     => array( 'input'=>')', 'tag'=>'mo', 'output'=>')', 'right_bracket'=>TRUE),
+'['     => array( 'input'=>'[', 'tag'=>'mo', 'output'=>'[', 'left_bracket'=>TRUE),
+']'     => array( 'input'=>']', 'tag'=>'mo', 'output'=>']', 'right_bracket'=>TRUE),
+'{'     => array( 'input'=>'{', 'tag'=>'mo', 'output'=>'{', 'left_bracket'=>TRUE),
+'}'     => array( 'input'=>'}', 'tag'=>'mo', 'output'=>'}', 'right_bracket'=>TRUE),
+'(:'    => array( 'input'=>'(:', 'tag'=>'mo', 'output'=>'&#' . hexdec('2329') . ';', 'left_bracket'=>TRUE),
+':)'    => array( 'input'=>':)', 'tag'=>'mo', 'output'=>'&#' . hexdec('232A') . ';', 'right_bracket'=>TRUE),
+'{:'    => array( 'input'=>'{:', 'tag'=>'mo', 'output'=>'{:', 'left_bracket'=>TRUE, 'invisible'=>TRUE),
+':}'    => array( 'input'=>':}', 'tag'=>'mo', 'output'=>':}', 'right_bracket'=>TRUE ,'invisible'=>TRUE),
+'<<'    => array( 'input'=>'<<', 'tag'=>'mo', 'output'=>'&#' . hexdec('2329') . ';', 'left_bracket'=>TRUE), // 2005-06-07 wes
+'>>'    => array( 'input'=>'>>', 'tag'=>'mo', 'output'=>'&#' . hexdec('232A') . ';', 'right_bracket'=>TRUE) // 2005-06-07 wes
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.class.php b/examples/includes/ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.class.php
new file mode 100644 (file)
index 0000000..5fb1060
--- /dev/null
@@ -0,0 +1,1119 @@
+<?php
+
+/****
+ * ASCIIMathPHP and associated classes:
+ * -- XMLNode
+ * -- MathMLNode extends XMLNode
+ *
+ * These classes are a PHP port of ASCIIMath
+ * Version 1.3 Feb 19 2004, (c) Peter Jipsen http://www.chapman.edu/~jipsen
+ *
+ * ASCIIMathPHP Version 1.11, 26 April 2006, (c) Kee-Lin Steven Chan (kc56@cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License (at http://www.gnu.org/copyleft/gpl.html)
+ * for more details.
+ *
+ * ChangeLog
+ *
+ * Ver 2.0
+ * -- PHP5 only version of ASCIIMathPHP
+ *
+ * Ver 1.12.1
+ * -- Included the missing setCurrExpr() method
+ *
+ * Ver 1.12
+ * -- Added changes that David Lippman <DLippman@pierce.ctc.edu> made to bring ASCIIMathPHP up to
+ * ASCIIMath 1.4.7 functionality.
+ * -- Added parseIntExpr, for intermediate expression parsing rule, allowing x^2/x^3 to render as (x^2)/(x^3)
+ * -- Added quotes as another way of designating text; "hello" is equivalent to text(hello)
+ * -- Added FUNC designator to allow sin, cos, etc to act as functions, so sin(x)/x renders as {sin(x)}/x
+ *
+ * Ver 1.11
+ * -- Fixed bug that stopped script execution for incomplete expressions
+ * -- Changed the algorithm for parsing expressions so that it matches the longest string possible (greedy)
+ *
+ * Ver 1.10
+ * -- Added definition support
+ * -- Added stackrel support
+ * -- Added a bunch of different symbols etc. >>, << and definitions like dx, dy, dz etc.
+ *
+ * Ver 1.02
+ * -- Fixed bug with mbox and text
+ * -- Fixed spacing bug with mbox and text
+ *
+ * Ver 1.01
+ * -- Fixed Bug that did not parse symbols greater than a single character
+ * correctly when appearing at end of expression.
+ *
+ ***/
+
+class XMLNode
+{
+    // Private variables
+    var $_id;
+    var $_name;
+    var $_content;
+    var $_mt_elem_flg;
+    var $_attr_arr;
+    var $_child_arr;
+    var $_nmspc;
+    var $_nmspc_alias;
+    var $_parent_id;
+    var $_parent_node;
+
+    function XMLNode($id = NULL)
+    {
+        $this->_id = isset($id) ? $id : md5(uniqid(rand(),1));
+        $this->_name = '';
+        $this->_content = '';
+        $this->_mt_elem_flg = FALSE;
+        $this->_attr_arr = array();
+        $this->_child_arr = array();
+        $this->_nmspc = '';
+        $this->_nmspc_alias = '';
+        $this->_parent_id = FALSE;
+        $this->_parent_node = NULL;
+    }
+
+    function addChild(&$node)
+    {
+        $this->_child_arr[$node->getId()] = $node;
+        $node->setParentId($this->_id);
+        $node->setParentNode($this);
+    }
+
+    function addChildArr(&$node_arr)
+    {
+        $key_arr = array_keys($node_arr);
+        $num_key = count($key_arr);
+
+        for ($i = 0; $i < $num_key; $i++) {
+            $node = $node_arr[$key_arr[$i]];
+            $this->addChild($node);
+        }
+    }
+
+    function insertChildBefore($idx,&$node)
+    {
+        $key_arr = array_keys($this->_child_arr);
+        $num_key = count($key_arr);
+        $tmp_arr = arry();
+
+        for ($i = 0;$i < $num_key;$i++) {
+            if ($i == $idx) {
+                $tmp_arr[$node->getId()] = $node;
+            }
+            $tmp_arr[$key_arr[$i]] = $this->_child_arr[$key_arr[$i]];
+        }
+        $this->_child_arr = $tmp_arr;
+    }
+
+    function insertChildAfter($idx,&$node)
+    {
+        $key_arr = array_keys($this->_child_arr);
+        $num_key = count($key_arr);
+        $tmp_arr = arry();
+
+        for ($i = 0;$i < $num_key;$i++) {
+            $tmp_arr[$key_arr[$i]] = $this->_child_arr[$key_arr[$i]];
+            if ($i == $idx) {
+                $tmp_arr[$node->getId()] = $node;
+            }
+        }
+        $this->_child_arr = $tmp_arr;
+    }
+
+    function setId($id)
+    {
+        $this->_id = $id;
+    }
+
+    function setName($name)
+    {
+        $this->_name = $name;
+    }
+
+    function setNamepace($nmspc)
+    {
+        $this->_nmspc = $nmspc;
+    }
+
+    function setNamespaceAlias($nmspc_alias)
+    {
+        $this->_nmspc_alias = $nmspc_alias;
+    }
+
+    function setContent($content)
+    {
+        $this->_content = $content;
+    }
+
+    function setEmptyElem($mt_elem_flg)
+    {
+        $this->_mt_elem_flg = $mt_elem_flg;
+    }
+
+    function setAttr($attr_nm,$attr_val)
+    {
+        $this->_attr_arr[$attr_nm] = $attr_val;
+    }
+
+    function setAttrArr($attr_arr)
+    {
+        $this->_attr_arr = $attr_arr;
+    }
+
+    function setParentId($id)
+    {
+        $this->_parent_id = $id;
+    }
+
+    function setParentNode(&$node)
+    {
+        $this->_parent_node = $node;
+    }
+
+    function getId()
+    {
+        return($this->_id);
+    }
+
+    function getName()
+    {
+        return($this->_name);
+    }
+
+    function getNamespace()
+    {
+        return($this->_nmspc);
+    }
+
+    function getNamespaceAlias()
+    {
+        return($this->_nmspc_alias);
+    }
+
+    function getContent()
+    {
+        return($this->_content);
+    }
+
+    function getAttr($attr_nm)
+    {
+        if (isset($this->_attr_arr[$attr_nm])) {
+            return($this->_attr_arr[$attr_nm]);
+        } else {
+            return(NULL);
+        }
+    }
+
+    function getAttrArr()
+    {
+        return($this->_attr_arr);
+    }
+
+    function getParentId()
+    {
+        return($this->parent_id);
+    }
+
+    function getParentNode()
+    {
+        return($this->_parent_node);
+    }
+
+    function getChild($id)
+    {
+        if (isset($this->_child_arr[$id])) {
+            return($this->_child_arr[$id]);
+        } else {
+            return(FALSE);
+        }
+    }
+
+    function getFirstChild()
+    {
+        $id_arr = array_keys($this->_child_arr);
+        $num_child = count($id_arr);
+
+        if ($num_child > 0) {
+            return($this->_child_arr[$id_arr[0]]);
+        } else {
+            return(FALSE);
+        }
+    }
+
+    function getLastChild()
+    {
+        $id_arr = array_keys($this->_child_arr);
+        $num_child = count($id_arr);
+
+        if ($num_child > 0) {
+            return($this->_child_arr[$id_arr[$num_child - 1]]);
+        } else {
+            return(FALSE);
+        }
+    }
+
+    function getChildByIdx($idx)
+    {
+        $id_arr = array_keys($this->_child_arr);
+
+        if (isset($this->_child_arr[$id_arr[$idx]])) {
+            return($this->_child_arr[$id_arr[$idx]]);
+        } else {
+            return(FALSE);
+        }
+    }
+
+    function getNumChild()
+    {
+        return(count($this->_child_arr));
+    }
+
+    function removeChild($id)
+    {
+        unset($this->_child_arr[$id]);
+    }
+
+    function removeChildByIdx($idx)
+    {
+        $key_arr = array_keys($this->_child_arr);
+        unset($this->_child_arr[$key_arr[$idx]]);
+    }
+
+    function removeFirstChild()
+    {
+        $key_arr = array_keys($this->_child_arr);
+        unset($this->_child_arr[$key_arr[0]]);
+    }
+
+    function removeLastChild()
+    {
+        $key_arr = array_keys($this->_child_arr);
+        unset($this->_child_arr[$key_arr[count($key_arr)-1]]);
+    }
+
+    function dumpXML($indent_str = "\t")
+    {
+        $attr_txt = $this->_dumpAttr();
+        $name = $this->_dumpName();
+        $xmlns = $this->_dumpXmlns();
+        $lvl = $this->_getCurrentLevel();
+        $indent = str_pad('',$lvl,$indent_str);
+
+        if ($this->_mt_elem_flg) {
+            $tag = "$indent<$name$xmlns$attr_txt />";
+            return($tag);
+        } else {
+            $key_arr = array_keys($this->_child_arr);
+            $num_child = count($key_arr);
+
+            $tag = "$indent<$name$xmlns$attr_txt>$this->_content";
+
+            for ($i = 0;$i < $num_child;$i++) {
+                $node = $this->_child_arr[$key_arr[$i]];
+
+                $child_txt = $node->dumpXML($indent_str);
+                $tag .= "\n$child_txt";
+            }
+
+            $tag .= ($num_child > 0 ? "\n$indent</$name>" : "</$name>");
+            return($tag);
+        }
+    }
+
+    function _dumpAttr()
+    {
+        $id_arr = array_keys($this->_attr_arr);
+        $id_arr_cnt = count($id_arr);
+        $attr_txt = '';
+
+        for($i = 0;$i < $id_arr_cnt;$i++) {
+            $key = $id_arr[$i];
+            $attr_txt .= " $key=\"{$this->_attr_arr[$key]}\"";
+        }
+
+        return($attr_txt);
+    }
+
+    function _dumpName()
+    {
+        $alias = $this->getNamespaceAlias();
+        if ($alias == '') {
+            return($this->getName());
+        } else {
+            return("$alias:" . $this->getName());
+        }
+    }
+
+    function _dumpXmlns()
+    {
+        $nmspc = $this->getNamespace();
+        $alias = $this->getNamespaceAlias();
+
+        if ($nmspc != '') {
+            if ($alias == '') {
+                return(" xmlns=\"" . $nmspc . "\"");
+            } else {
+                return(" xmlns:$alias=\"" . $nmspc . "\"");
+            }
+        } else {
+            return('');
+        }
+    }
+
+    function _getCurrentLevel()
+    {
+        if ($this->_parent_id === FALSE) {
+            return(0);
+        } else {
+            $node = $this->getParentNode();
+            $lvl = $node->_getCurrentLevel();
+            $lvl++;
+            return($lvl);
+        }
+    }
+}
+
+class MathMLNode extends XMLNode
+{
+    function MathMLNode($id = NULL)
+    {
+        parent::XMLNode($id);
+    }
+
+    function removeBrackets()
+    {
+        if ($this->_name == 'mrow') {
+            if ($c_node_0 = $this->getFirstChild()) {
+                $c_node_0->isLeftBracket() ? $this->removeFirstChild() : 0;
+            }
+
+            if ($c_node_0 = $this->getLastChild()) {
+                $c_node_0->isRightBracket() ? $this->removeLastChild() : 0;
+            }
+        }
+    }
+
+    function isLeftBracket()
+    {
+        switch ($this->_content) {
+            case '{':
+            case '[':
+            case '(':
+                return(TRUE);
+                break;
+        }
+        return(FALSE);
+    }
+
+    function isRightBracket()
+    {
+        switch ($this->_content) {
+            case '}':
+            case ']':
+            case ')':
+                return(TRUE);
+                break;
+        }
+        return(FALSE);
+    }
+}
+
+class ASCIIMathPHP
+{
+    var $_expr;
+    var $_curr_expr;
+    var $_prev_expr;
+    var $_symbol_arr;
+    var $_node_arr;
+    var $_node_cntr;
+
+    function ASCIIMathPHP($symbol_arr,$expr = NULL)
+    {
+        $this->_symbol_arr = $symbol_arr;
+        if (isset($expr)) {
+            $this->setExpr($expr);
+        }
+    }
+
+    /**
+     * Returns an empty node (containing a non-breaking space) 26-Apr-2006
+     *
+     * Used when an expression is incomplete
+     *
+     * @return object
+     *
+     * @access private
+     */
+    function emptyNode()
+    {
+        $tmp_node = $this->createNode();
+        $tmp_node->setName('mn');
+        $tmp_node->setContent('&#' . hexdec('200B') . ';');
+        return $tmp_node;
+    }
+
+    function pushExpr($prefix) // 2005-06-11 wes
+    {
+        $this->_curr_expr = $prefix . $this->_curr_expr;
+    }
+
+    function setExpr($expr)
+    {
+        $this->_expr = $expr;
+        $this->_curr_expr = $expr;
+        $this->_prev_expr = $expr;
+
+        $this->_node_arr = array();
+        $this->_node_cntr = 0;
+    }
+
+    function genMathML($attr_arr = NULL)
+    {
+        // <math> node
+        $node_0 = $this->createNode();
+        $node_0->setName('math');
+        $node_0->setNamepace('http://www.w3.org/1998/Math/MathML');
+
+        // <mstyle> node
+        if (isset($attr_arr)) {
+            $node_1 = $this->createNode();
+            $node_1->setName('mstyle');
+            $node_1->setAttrArr($attr_arr);
+
+            $node_arr = $this->parseExpr();
+
+            $node_1->addChildArr($node_arr);
+            $node_0->addChild($node_1);
+        } else {
+            $node_arr = $this->parseExpr();
+            $node_0->addChildArr($node_arr);
+        }
+
+        return TRUE;
+    }
+
+    /*
+    function  mergeNodeArr(&$node_arr_0,&$node_arr_1)
+    {
+        $key_arr_0 = array_keys($node_arr_0);
+        $key_arr_1 = array_keys($node_arr_1);
+
+        $num_key_0 = count($key_arr_0);
+        $num_key_1 = count($key_arr_1);
+
+        $merge_arr = array();
+
+        for ($i = 0;$i < $num_key_0;$i++) {
+            $merge_arr[$key_arr_0[$i]] = $node_arr_0[$key_arr_0[$i]];
+        }
+
+        for ($j = 0;$j < $num_key_1;$i++) {
+            $merge_arr[$key_arr_1[$i]] = $node_arr_1[$key_arr_1[$i]];
+        }
+
+        return($merge_arr);
+    }
+    */
+
+    //Broken out of parseExpr Sept 7, 2006 David Lippman for
+    //ASCIIMathML 1.4.7 compatibility
+    function  parseIntExpr()
+    {
+        $sym_0 = $this->getSymbol();
+        $node_0 = $this->parseSmplExpr();
+        $sym = $this->getSymbol();
+
+        if (isset($sym['infix']) && $sym['input'] != '/') {
+            $this->chopExpr($sym['symlen']);
+            $node_1 = $this->parseSmplExpr();
+
+            if ($node_1 === FALSE) { //show box in place of missing argument
+                $node_1 = $this->emptyNode();//??
+            } else {
+                $node_1->removeBrackets();
+            }
+
+            // If 'sub' -- subscript
+            if ($sym['input'] == '_') {
+
+                $sym_1 = $this->getSymbol();
+
+                // If 'sup' -- superscript
+                if ($sym_1['input'] == '^') {
+                    $this->chopExpr($sym_1['symlen']);
+                    $node_2 = $this->parseSmplExpr();
+                    $node_2->removeBrackets();
+
+                    $node_3 = $this->createNode();
+                    $node_3->setName(isset($sym_0['underover']) ? 'munderover' : 'msubsup');
+                    $node_3->addChild($node_0);
+                    $node_3->addChild($node_1);
+                    $node_3->addChild($node_2);
+
+                    $node_4 = $this->createNode();
+                    $node_4->setName('mrow');
+                    $node_4->addChild($node_3);
+
+                    return $node_4;
+                } else {
+                    $node_2 = $this->createNode();
+                    $node_2->setName(isset($sym_0['underover']) ? 'munder' : 'msub');
+                    $node_2->addChild($node_0);
+                    $node_2->addChild($node_1);
+
+                    return $node_2;
+                }
+            } else {
+                $node_2 = $this->createNode();
+                $node_2->setName($sym['tag']);
+                $node_2->addChild($node_0);
+                $node_2->addChild($node_1);
+
+                return($node_2);
+            }
+        } elseif ($node_0 !== FALSE) {
+            return($node_0);
+        } else {
+            return $this->emptyNode();
+        }
+
+    }
+
+    function  parseExpr()
+    {
+        // Child/Fragment array
+        $node_arr = array();
+
+        // Deal whole expressions like 'ax + by + c = 0' etc.
+        do {
+            $sym_0 = $this->getSymbol();
+            $node_0 = $this->parseIntExpr();
+            $sym = $this->getSymbol();
+            // var_dump($sym);
+
+            if (isset($sym['infix']) && $sym['input'] == '/') {
+                $this->chopExpr($sym['symlen']);
+                $node_1 = $this->parseIntExpr();
+
+                if ($node_1 === FALSE) { //should show box in place of missing argument
+                    $node_1 = $this->emptyNode();
+                    continue;
+                }
+
+                $node_1->removeBrackets();
+
+                // If 'div' -- divide
+                $node_0->removeBrackets();
+                $node_2 = $this->createNode();
+                $node_2->setName($sym['tag']);
+                $node_2->addChild($node_0);
+                $node_2->addChild($node_1);
+                $node_arr[$node_2->getId()] = $node_2;
+
+            } elseif ($node_0 !== FALSE) {
+                $node_arr[$node_0->getId()] = $node_0;
+            }
+        } while (!isset($sym['right_bracket']) && $sym !== FALSE && $sym['output'] != '');
+
+        //var_dump($sym);
+        // Possibly to deal with matrices
+        if (isset($sym['right_bracket'])) {
+            $node_cnt = count($node_arr);
+            $key_node_arr = array_keys($node_arr);
+
+            if ($node_cnt > 1) {
+                $node_5 = $node_arr[$key_node_arr[$node_cnt-1]];
+                $node_6 = $node_arr[$key_node_arr[$node_cnt-2]];
+            } else {
+                $node_5 = FALSE;
+                $node_6 = FALSE;
+            }
+
+            // Dealing with matrices
+            if ($node_5 !== FALSE && $node_6 !== FALSE &&
+                $node_cnt > 1 &&
+                $node_5->getName() == 'mrow' &&
+                $node_6->getName() == 'mo' &&
+                $node_6->getContent() == ',') {
+
+                // Checking if Node 5 has a LastChild
+                if ($node_7 = $node_5->getLastChild()) {
+                    $node_7_cntnt = $node_7->getContent();
+                } else {
+                    $node_7_cntnt = FALSE;
+                }
+
+                // If there is a right bracket
+                if ($node_7 !== FALSE && ($node_7_cntnt == ']' || $node_7_cntnt == ')')) {
+
+                    // Checking if Node 5 has a firstChild
+                    if ($node_8 = $node_5->getFirstChild()) {
+                        $node_8_cntnt = $node_8->getContent();
+                    } else {
+                        $node_8_cntnt = FALSE;
+                    }
+
+                    // If there is a matching left bracket
+                    if ($node_8 !== FALSE &&
+                        (($node_8_cntnt == '(' && $node_7_cntnt == ')' && $sym['output'] != '}') ||
+                        ($node_8_cntnt == '[' && $node_7_cntnt == ']'))) {
+
+                        $is_mtrx_flg = TRUE;
+                        $comma_pos_arr = array();
+
+                        $i = 0;
+
+                        while ($i < $node_cnt && $is_mtrx_flg) {
+                            $tmp_node = $node_arr[$key_node_arr[$i]];
+
+                            if($tmp_node_first = $tmp_node->getFirstChild()) {
+                                $tnfc = $tmp_node_first->getContent();
+                            } else {
+                                $tnfc = FALSE;
+                            }
+
+                            if($tmp_node_last = $tmp_node->getLastChild()) {
+                                $tnlc = $tmp_node_last->getContent();
+                            } else {
+                                $tnlc = FALSE;
+                            }
+
+                            if (isset($key_node_arr[$i+1])) {
+                                $next_tmp_node = $node_arr[$key_node_arr[$i+1]];
+                                $ntnn = $next_tmp_node->getName();
+                                $ntnc = $next_tmp_node->getContent();
+                            } else {
+                                $ntnn = FALSE;
+                                $ntnc = FALSE;
+                            }
+
+                            // Checking each node in node array for matrix criteria
+                            if ($is_mtrx_flg) {
+                                $is_mtrx_flg = $tmp_node->getName() == 'mrow' &&
+                                    ($i == $node_cnt-1 || $ntnn == 'mo' && $ntnc == ',') &&
+                                    $tnfc == $node_8_cntnt && $tnlc == $node_7_cntnt;
+                            }
+
+                            if ($is_mtrx_flg) {
+                                for ($j = 0;$j < $tmp_node->getNumChild();$j++) {
+                                    $tmp_c_node = $tmp_node->getChildByIdx($j);
+
+                                    if ($tmp_c_node->getContent() == ',') {
+                                        $comma_pos_arr[$i][] = $j;
+                                    }
+                                }
+                            }
+
+                            if ($is_mtrx_flg && $i > 1) {
+
+                                $cnt_cpan = isset($comma_pos_arr[$i]) ? count($comma_pos_arr[$i]) : NULL;
+                                $cnt_cpap = isset($comma_pos_arr[$i-2]) ? count($comma_pos_arr[$i-2]) : NULL;
+                                $is_mtrx_flg = $cnt_cpan == $cnt_cpap;
+                            }
+
+                            $i += 2;
+                        }
+
+                        // If the node passes the matrix tests
+                        if ($is_mtrx_flg) {
+                            $tab_node_arr = array();
+
+                            for ($i = 0;$i < $node_cnt;$i += 2) {
+                                $tmp_key_node_arr = array_keys($node_arr);
+                                if (!($tmp_node = $node_arr[$tmp_key_node_arr[0]])) {
+                                    break;
+                                }
+                                $num_child = $tmp_node->getNumChild();
+                                $k = 0;
+
+                                $tmp_node->removeFirstChild();
+
+                                $row_node_arr = array();
+                                $row_frag_node_arr = array();
+
+                                for ($j = 1;$j < ($num_child-1);$j++) {
+                                    if (isset($comma_pos_arr[$i][$k]) &&
+                                        $j == $comma_pos_arr[$i][$k]) {
+
+                                        $tmp_node->removeFirstChild();
+
+                                        $tmp_c_node = $this->createNode();
+                                        $tmp_c_node->setName('mtd');
+                                        $tmp_c_node->addChildArr($row_frag_node_arr);
+                                        $row_frag_node_arr = array();
+
+                                        $row_node_arr[$tmp_c_node->getId()] = $tmp_c_node;
+
+                                        $k++;
+                                    } else {
+
+                                        if ($tmp_c_node = $tmp_node->getFirstChild()) {
+                                            $row_frag_node_arr[$tmp_c_node->getId()] = $tmp_c_node;
+                                            $tmp_node->removeFirstChild();
+                                        }
+                                    }
+                                }
+
+                                $tmp_c_node = $this->createNode();
+                                $tmp_c_node->setName('mtd');
+                                $tmp_c_node->addChildArr($row_frag_node_arr);
+
+                                $row_node_arr[$tmp_c_node->getId()] = $tmp_c_node;
+
+                                if (count($node_arr) > 2) {
+                                    $tmp_key_node_arr = array_keys($node_arr);
+                                    unset($node_arr[$tmp_key_node_arr[0]]);
+                                    unset($node_arr[$tmp_key_node_arr[1]]);
+                                }
+
+                                $tmp_c_node = $this->createNode();
+                                $tmp_c_node->setName('mtr');
+                                $tmp_c_node->addChildArr($row_node_arr);
+
+                                $tab_node_arr[$tmp_c_node->getId()] = $tmp_c_node;
+                            }
+
+                            $tmp_c_node = $this->createNode();
+                            $tmp_c_node->setName('mtable');
+                            $tmp_c_node->addChildArr($tab_node_arr);
+
+                            if (isset($sym['invisible'])) {
+                                $tmp_c_node->setAttr('columnalign','left');
+                            }
+
+                            $key_node_arr = array_keys($node_arr);
+                            $tmp_c_node->setId($key_node_arr[0]);
+
+                            $node_arr[$tmp_c_node->getId()] = $tmp_c_node;
+                        }
+                    }
+                }
+            }
+
+            $this->chopExpr($sym['symlen']);
+            if (!isset($sym['invisible'])) {
+                $node_7 = $this->createNode();
+                $node_7->setName('mo');
+                $node_7->setContent($sym['output']);
+                $node_arr[$node_7->getId()] = $node_7;
+            }
+        }
+
+        return($node_arr);
+    }
+
+    function  parseSmplExpr()
+    {
+        $sym = $this->getSymbol();
+
+        if (!$sym || isset($sym['right_bracket'])) //return FALSE;
+            return $this->emptyNode();
+
+        $this->chopExpr($sym['symlen']);
+
+        // 2005-06-11 wes: add definition type support
+        if(isset($sym['definition'])) {
+            $this->pushExpr($sym['output']);
+            $sym = $this->getSymbol();
+            $this->chopExpr($sym['symlen']);
+        }
+
+        if (isset($sym['left_bracket'])) {
+            $node_arr = $this->parseExpr();
+
+            if (isset($sym['invisible'])) {
+                $node_0 = $this->createNode();
+                $node_0->setName('mrow');
+                $node_0->addChildArr($node_arr);
+
+                return($node_0);
+            } else {
+                $node_0 = $this->createNode();
+                $node_0->setName('mo');
+                $node_0->setContent($sym['output']);
+
+                $node_1 = $this->createNode();
+                $node_1->setName('mrow');
+                $node_1->addChild($node_0);
+                $node_1->addChildArr($node_arr);
+
+                return($node_1);
+            }
+        } elseif (isset($sym['unary'])) {
+
+            if ($sym['input'] == 'sqrt') {
+                $node_0 = $this->parseSmplExpr();
+                $node_0->removeBrackets();
+
+                $node_1 = $this->createNode();
+                $node_1->setName($sym['tag']);
+                $node_1->addChild($node_0);
+
+                return($node_1);
+            } elseif (isset($sym['func'])) { //added 2006-9-7 David Lippman
+                $expr = ltrim($this->getCurrExpr());
+                $st = $expr{0};
+                $node_0 = $this->parseSmplExpr();
+                //$node_0->removeBrackets();
+                if ($st=='^' || $st == '_' || $st=='/' || $st=='|' || $st==',') {
+                    $node_1 = $this->createNode();
+                    $node_1->setName($sym['tag']);
+                    $node_1->setContent($sym['output']);
+                    $this->setCurrExpr($expr);
+                    return($node_1);
+                } else {
+                    $node_1 = $this->createNode();
+                    $node_1->setName('mrow');
+                    $node_2 = $this->createNode();
+                    $node_2->setName($sym['tag']);
+                    $node_2->setContent($sym['output']);
+                    $node_1->addChild($node_2);
+                    $node_1->addChild($node_0);
+                    return($node_1);
+                }
+            } elseif ($sym['input'] == 'text' || $sym['input'] == 'mbox' || $sym['input'] == '"') {
+                $expr = ltrim($this->getCurrExpr());
+                if ($sym['input']=='"') {
+                    $end_brckt = '"';
+                    $txt = substr($expr,0,strpos($expr,$end_brckt));
+                } else {
+                    switch($expr{0}) {
+                        case '(':
+                            $end_brckt = ')';
+                            break;
+                        case '[':
+                            $end_brckt = ']';
+                            break;
+                        case '{':
+                            $end_brckt = '}';
+                            break;
+                        default:
+                            $end_brckt = chr(11); // A character that will never be matched.
+                            break;
+                    }
+                    $txt = substr($expr,1,strpos($expr,$end_brckt)-1);
+                }
+
+                //$txt = substr($expr,1,strpos($expr,$end_brckt)-1);
+                $len = strlen($txt);
+
+                $node_0 = $this->createNode();
+                $node_0->setName('mrow');
+
+                if ($len > 0) {
+                    if ($txt{0} == " ") {
+                        $node_1 = $this->createNode();
+                        $node_1->setName('mspace');
+                        $node_1->setAttr('width','1ex');
+
+                        $node_0->addChild($node_1);
+                    }
+
+                    $node_3 = $this->createNode();
+                    $node_3->setName($sym['tag']);
+                    $node_3->setContent(trim($txt));
+
+                    $node_0->addChild($node_3);
+
+                    if ($len > 1 && $txt{$len-1} == " ") {
+                        $node_2 = $this->createNode();
+                        $node_2->setName('mspace');
+                        $node_2->setAttr('width','1ex');
+
+                        $node_0->addChild($node_2);
+                    }
+
+                    $this->chopExpr($len+2);
+                }
+                return($node_0);
+
+            } elseif (isset($sym['acc'])) {
+                $node_0 = $this->parseSmplExpr();
+                $node_0->removeBrackets();
+
+                $node_1 = $this->createNode();
+                $node_1->setName($sym['tag']);
+                $node_1->addChild($node_0);
+
+                $node_2 = $this->createNode();
+                $node_2->setName('mo');
+                $node_2->setContent($sym['output']);
+
+                $node_1->addChild($node_2);
+                return($node_1);
+            } else {
+                // Font change commands -- to complete
+            }
+        } elseif (isset($sym['binary'])) {
+            $node_arr = array();
+
+            $node_0 = $this->parseSmplExpr();
+            $node_0->removeBrackets();
+
+            $node_1 = $this->parseSmplExpr();
+            $node_1->removeBrackets();
+
+            /* 2005-06-05 wes: added stackrel */
+            if ($sym['input'] == 'root' || $sym['input'] == 'stackrel') {
+                $node_arr[$node_1->getId()] = $node_1;
+                $node_arr[$node_0->getId()] = $node_0;
+            } elseif ($sym['input'] == 'frac') {
+                $node_arr[$node_0->getId()] = $node_0;
+                $node_arr[$node_1->getId()] = $node_1;
+            }
+
+            $node_2 = $this->createNode();
+            $node_2->setName($sym['tag']);
+            $node_2->addChildArr($node_arr);
+
+            return($node_2);
+        } elseif (isset($sym['infix'])) {
+            $node_0 = $this->createNode();
+            $node_0->setName('mo');
+            $node_0->setContent($sym['output']);
+
+            return($node_0);
+        } elseif (isset($sym['space'])) {
+            $node_0 = $this->createNode();
+            $node_0->setName('mrow');
+
+            $node_1 = $this->createNode();
+            $node_1->setName('mspace');
+            $node_1->setAttr('width',$sym['space']);
+
+            $node_2 = $this->createNode();
+            $node_2->setName($sym['tag']);
+            $node_2->setContent($sym['output']);
+
+            $node_3 = $this->createNode();
+            $node_3->setName('mspace');
+            $node_3->setAttr('width',$sym['space']);
+
+            $node_0->addChild($node_1);
+            $node_0->addChild($node_2);
+            $node_0->addChild($node_3);
+
+            return($node_0);
+        } else {
+
+            // A constant
+            $node_0 = $this->createNode();
+            $node_0->setName($sym['tag']);
+            $node_0->setContent($sym['output']);
+            return($node_0);
+        }
+
+        // Return an empty node
+        return $this->emptyNode();
+    }
+
+    function getMathML()
+    {
+        $root = $this->_node_arr[0];
+        return($root->dumpXML());
+    }
+
+    function getCurrExpr()
+    {
+        return($this->_curr_expr);
+    }
+
+    function setCurrExpr($str)
+    {
+        $this->_curr_expr = $str;
+    }
+
+    function getExpr()
+    {
+        return($this->_expr);
+    }
+
+    function getPrevExpr()
+    {
+        return($this->_prev_expr);
+    }
+
+    function  createNode()
+    {
+        $node = new MathMLNode($this->_node_cntr);
+        // $node->setNamespaceAlias('m');
+        $this->_node_arr[$this->_node_cntr] = $node;
+        $this->_node_cntr++;
+        return($node);
+    }
+
+    /**
+     * Gets the largest symbol in the expression (greedy). Changed from non-greedy 26-Apr-2006
+     *
+     * @parameter boolean[optional] Chop original string?
+     *
+     * @return mixed
+     *
+     * @access private
+     */
+    function getSymbol($chop_flg = FALSE)
+    {
+        // Implemented a reverse symbol matcher.
+        // Instead of going front to back, it goes back to front. Steven 26-Apr-2006
+        $chr_cnt = strlen($this->_curr_expr);
+
+        if ($chr_cnt == 0) return FALSE;
+
+        for ($i = $chr_cnt; $i > 0; $i--) {
+            $sym_0 = substr($this->_curr_expr,0,$i);
+
+            // Reading string for numeric values
+            if (is_numeric($sym_0)) {
+
+                if ($chop_flg) $this->chopExpr($i);
+                return array('input'=>$sym_0, 'tag'=>'mn', 'output'=>$sym_0, 'symlen'=>$i);
+
+            } elseif (isset($this->_symbol_arr[$sym_0])) {
+
+                if ($chop_flg) $this->chopExpr($i);
+                $sym_arr = $this->_symbol_arr[$sym_0];
+                $sym_arr['symlen'] = $i;
+                return $sym_arr;
+            }
+        }
+
+        // Reading string for alphabetic constants and the minus sign
+        $char = $this->_curr_expr{0};
+        $len_left = $chop_flg ? $this->chopExpr(1) : strlen($this->_curr_expr)-1;
+
+        // Deals with expressions of length 1
+        if ($len_left == 0 && isset($this->_symbol_arr[$char])) {
+            $sym_arr = $this->_symbol_arr[$char];
+            $sym_arr['symlen'] = 1;
+            return $sym_arr;
+        } else {
+            $tag = preg_match('/[a-z]/i',$char) ? 'mi' : 'mo';
+            return array('input'=>$char, 'tag'=>$tag, 'output'=>$char, 'symlen'=>1);
+        }
+    }
+
+    function chopExpr($strlen)
+    {
+        $this->_prev_expr = $this->_curr_expr;
+
+        if ($strlen == strlen($this->_curr_expr)) {
+            $this->_curr_expr = '';
+            return(0);
+        } else {
+            $this->_curr_expr = ltrim(substr($this->_curr_expr,$strlen));
+            return(strlen($this->_curr_expr));
+        }
+    }
+}
+?>
\ No newline at end of file
diff --git a/examples/includes/ASCIIMathPHP-2.0/htmlMathML.js b/examples/includes/ASCIIMathPHP-2.0/htmlMathML.js
new file mode 100644 (file)
index 0000000..f81a1d2
--- /dev/null
@@ -0,0 +1,86 @@
+/* March 19, 2004 MathHTML (c) Peter Jipsen http://www.chapman.edu/~jipsen
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+(at http://www.gnu.org/copyleft/gpl.html) for more details.*/
+
+function convertMath(node) {// for Gecko
+  if (node.nodeType==1) {
+    var newnode = 
+      document.createElementNS("http://www.w3.org/1998/Math/MathML",
+        node.nodeName.toLowerCase());
+    for(var i=0; i < node.attributes.length; i++) {
+           if (node.attributes[i].nodeName == 'displaystyle') {
+             newnode.setAttribute(node.attributes[i].nodeName,node.attributes[i].nodeValue);
+           }
+    }
+    for (var i=0; i<node.childNodes.length; i++) {
+      var st = node.childNodes[i].nodeValue;
+      if (st==null || st.slice(0,1)!=" " && st.slice(0,1)!="\n") 
+        newnode.appendChild(convertMath(node.childNodes[i]));
+    }
+    return newnode;
+  }
+  else return node;
+}
+function convert() {
+       
+       if (document.createElementNS) {
+               var mmlnode = document.getElementsByTagName("span");
+               
+               for (var i=0; i<mmlnode.length; i++) {
+                       var tmp_node = mmlnode[i];
+                       if (tmp_node.className == 'asciimath') {
+                               tmp_node.replaceChild(convertMath(tmp_node.firstChild),tmp_node.firstChild);
+                               /*
+                               for (var j=0;j<tmp_node.childNodes.length;j++) {
+                                       if (tmp_node.childNodes[j].nodeType != 3) {
+                                               
+                                       }
+                               }
+                               */
+                       }
+               }
+       } else {
+               var st,node,newnode;
+               var mmlnode = document.getElementsByTagName("math");
+               
+               for (var i=0; i<mmlnode.length; i++) {
+                       var str = "";
+                       node = mmlnode[i];
+                       while (node.nodeName!="/MATH" && node.nextSibling) {
+                               st = node.nodeName.toLowerCase();
+                               if (st=="#text") { 
+                                       str += node.nodeValue;
+                               } else {
+                                       str += (st.slice(0,1)=="/" ? "</m:"+st.slice(1) : "<m:"+st);
+                                       if (st.slice(0,1)!="/") {
+                                               for(var j=0; j < node.attributes.length; j++) {
+                                                       if (node.attributes[j].nodeValue!="italic" &&
+                                                        node.attributes[j].nodeValue!="" &&
+                                                        node.attributes[j].nodeValue!="inherit" &&
+                                                        node.attributes[j].nodeValue!=undefined) {
+                                                        str += " "+node.attributes[j].nodeName+"="+
+                                                            "\""+node.attributes[j].nodeValue+"\"";
+                                                       }
+                                               }
+                                       }
+                                       str += ">";
+                               }
+                               node = node.nextSibling;
+                               node.parentNode.removeChild(node.previousSibling);
+                       }
+                       
+                       if (str != '') {
+                               str += "</m:math>";
+                               newnode = document.createElement("span");
+                               node.parentNode.replaceChild(newnode,node);
+                               newnode.innerHTML = str;
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/examples/includes/HTML-Toc-0.91/.gitattributes b/examples/includes/HTML-Toc-0.91/.gitattributes
new file mode 100644 (file)
index 0000000..aecf250
--- /dev/null
@@ -0,0 +1 @@
+* -crlf
diff --git a/examples/includes/HTML-Toc-0.91/Changes b/examples/includes/HTML-Toc-0.91/Changes
new file mode 100644 (file)
index 0000000..81f8339
--- /dev/null
@@ -0,0 +1,26 @@
+Revision history for Perl extension HTML::Toc.\r
+\r
+2001-09-03   Freddy Vulto <fvu@fvu.myweb.nl>\r
+\r
+       Release 0.91\r
+\r
+       - Tested on Cygwin.\r
+       - Used Unix file type for source files.\r
+       - Updated documentation.\r
+       - Prohibited call with undefined parameter to HTML::Parser->parse() from\r
+         HTML::_tokenTocEndParser->parse() which caused havoc with version 3.25\r
+         of HTML::Parser.\r
+       - Specified 'HTML::Parser' as module that needs to be available in order\r
+         to use HTML::Toc.\r
+       - Added protected method HTML::TocGenerator::_setActiveAnchorName().\r
+         This method replaces the incongruous access of \r
+         'HTML::TocUpdator::_doDeleteTokens' by HTML::TocGenerator.\r
+         HTML::TocUpdator now overrides '_setActiveAnchorName()' to allow\r
+         the ancestor call to HTML::TocGenerator only when '_doDeleteTokens'\r
+         equals false.\r
+\r
+2001-08-09   Freddy Vulto <fvu@fvu.myweb.nl>\r
+\r
+       Release 0.90\r
+\r
+       - First release.\r
diff --git a/examples/includes/HTML-Toc-0.91/MANIFEST b/examples/includes/HTML-Toc-0.91/MANIFEST
new file mode 100644 (file)
index 0000000..e90f3a8
--- /dev/null
@@ -0,0 +1,26 @@
+Changes\r
+Toc.pod\r
+Toc.pm\r
+TocGenerator.pm\r
+TocInsertor.pm\r
+TocUpdator.pm\r
+Makefile.PL\r
+MANIFEST\r
+t/extend.t\r
+t/format.t\r
+t/generate.t\r
+t/insert.t\r
+t/manualTest.t\r
+t/options.t\r
+t/podExamples.t\r
+t/propagate.t\r
+t/siteMap.t\r
+t/update.t\r
+t/ManualTest/manualTest1.htm\r
+t/SiteMap/index.htm\r
+t/SiteMap/SubDir1/index.htm\r
+t/SiteMap/SubDir1/SubSubDir1/index.htm\r
+t/SiteMap/SubDir2/index.htm\r
+t/SiteMap/SubDir2/SubSubDir1/index.htm\r
+t/SiteMap/SubDir2/SubSubDir2/index.htm\r
+t/SiteMap/SubDir3/index.htm\r
diff --git a/examples/includes/HTML-Toc-0.91/Makefile.PL b/examples/includes/HTML-Toc-0.91/Makefile.PL
new file mode 100644 (file)
index 0000000..434d4fd
--- /dev/null
@@ -0,0 +1,8 @@
+use ExtUtils::MakeMaker;\r
+\r
+WriteMakefile(\r
+    'NAME'                   => 'HTML::Toc',\r
+    'VERSION_FROM'     => 'Toc.pm',\r
+    'PREREQ_PM'                => {'HTML::Parser' => 0},\r
+        'MAN3PODS'       => {},\r
+);\r
diff --git a/examples/includes/HTML-Toc-0.91/Toc.pm b/examples/includes/HTML-Toc-0.91/Toc.pm
new file mode 100644 (file)
index 0000000..ae2e8d8
--- /dev/null
@@ -0,0 +1,549 @@
+#=== HTML::Toc ================================================================
+# function: HTML Table of Contents
+
+
+package HTML::Toc;
+
+
+use strict;
+
+
+BEGIN {
+       use vars qw($VERSION);
+
+       $VERSION = '0.91';
+}
+
+
+use constant FILE_FILTER             => '.*';
+use constant GROUP_ID_H              => 'h';
+use constant LEVEL_1                 => 1;
+use constant NUMBERING_STYLE_DECIMAL => 'decimal';
+
+       # Templates
+
+       # Anchor templates
+use constant TEMPLATE_ANCHOR_NAME       => '$groupId."-".$node';
+use constant TEMPLATE_ANCHOR_HREF_BEGIN       => 
+                                       '"<a href=#$anchorName>"';
+use constant TEMPLATE_ANCHOR_HREF_BEGIN_FILE  => 
+                                       '"<a href=$file#$anchorName>"';
+use constant TEMPLATE_ANCHOR_HREF_END         => '"</a>"';
+use constant TEMPLATE_ANCHOR_NAME_BEGIN => 
+                                       '"<a name=$anchorName>"';
+use constant TEMPLATE_ANCHOR_NAME_END   => '"</a>"';
+use constant TOKEN_UPDATE_BEGIN_OF_ANCHOR_NAME_BEGIN => 
+                                       '<!-- #BeginTocAnchorNameBegin -->';
+use constant TOKEN_UPDATE_END_OF_ANCHOR_NAME_BEGIN   => 
+                                       '<!-- #EndTocAnchorNameBegin -->';
+use constant TOKEN_UPDATE_BEGIN_OF_ANCHOR_NAME_END => 
+                                       '<!-- #BeginTocAnchorNameEnd -->';
+use constant TOKEN_UPDATE_END_OF_ANCHOR_NAME_END   => 
+                                       '<!-- #EndTocAnchorNameEnd -->';
+use constant TOKEN_UPDATE_BEGIN_NUMBER      => 
+                                       '<!-- #BeginTocNumber -->';
+use constant TOKEN_UPDATE_END_NUMBER        => 
+                                       '<!-- #EndTocNumber -->';
+use constant TOKEN_UPDATE_BEGIN_TOC         => 
+                                       '<!-- #BeginToc -->';
+use constant TOKEN_UPDATE_END_TOC           => 
+                                       '<!-- #EndToc -->';
+
+use constant TEMPLATE_TOKEN_NUMBER      => '"$node &nbsp;"';
+
+       # Level templates
+use constant TEMPLATE_LEVEL             => '"<li>$text\n"';
+use constant TEMPLATE_LEVEL_BEGIN       => '"<ul>\n"';
+use constant TEMPLATE_LEVEL_END         => '"</ul>\n"';
+
+
+END {}
+
+
+#--- HTML::Toc::new() ---------------------------------------------------------
+# function: Constructor
+
+sub new {
+               # Get arguments
+       my ($aType) = @_;
+               # Local variables
+       my $self;
+
+       $self = bless({}, $aType);
+               # Default to empty 'options' array
+       $self->{options} = {};
+               # Empty toc
+       $self->{_toc} = "";
+               # Hash reference to array for each groupId, each array element
+               # referring to the group of the level indicated by the array index.
+               # For example, with the default 'tokenGroups', '_levelGroups' would
+               # look like: 
+               #
+               # {'h'} => [\$group1, \$group2, \$group3, \$group4, \$group5, \$group6];
+               #
+       $self->{_levelGroups} = undef;
+               # Set default options
+       $self->_setDefaults();
+       return $self;
+}  # new()
+
+
+#--- HTML::Toc::_compareLevels() ----------------------------------------------
+# function: Compare levels.
+# args:     - $aLevel: pointer to level
+#           - $aGroupLevel
+#           - $aPreviousLevel
+#           - $aPreviousGroupLevel
+# returns:  0 if new level equals previous level, 1 if new level exceeds
+#           previous level, -1 if new level is smaller then previous level.
+
+sub _compareLevels {
+               # Get arguments
+       my (
+               $self, $aLevel, $aPreviousLevel, $aGroupLevel, $aPreviousGroupLevel 
+       ) = @_;
+               # Local variables
+       my ($result);
+               # Levels equals?
+       if (
+               ($aLevel == $aPreviousLevel) &&
+               ($aGroupLevel == $aPreviousGroupLevel)
+       ) {
+               # Yes, levels are equals;
+                       # Indicate so
+               $result = 0;
+       }
+       else {
+               # No, levels differ;
+                       # Bias to new level being smaller than previous level;
+               $result = -1;
+                       # Must groups not be nested and do group levels differ?
+               if (
+                       ($self->{options}{'doNestGroup'} == 0) &&
+                       ($aGroupLevel != $aPreviousGroupLevel)
+               ) {
+                       # Yes, groups must be kept apart and the group levels differ;
+                               # Level is greater than previous level?
+                       if (
+                               ($aLevel > $aPreviousLevel)
+                       ) {
+                               # Yes, level is greater than previous level;
+                                       # Indicate so
+                               $result = 1;
+                       }
+               }
+               else {
+                       # No, group must be nested;
+                               # Level is greater than previous level?
+                       if (
+                               ($aLevel > $aPreviousLevel) ||
+                               ($aGroupLevel > $aPreviousGroupLevel)
+                       ) {
+                               # Yes, level is greater than previous level;
+                                       # Indicate so
+                               $result = 1;
+                       }
+               }
+       }
+               # Return value
+       return $result;
+}  # _compareLevels()
+
+
+#--- HTML::TocGenerator::_formatLevelIndent() ---------------------------------
+# function: Format indent.
+# args:     - $aText: text to indent
+#           - $aLevel: Level.
+#           - $aGroupLevel: Group level.
+#           - $aAdd
+#           - $aGlobalLevel
+
+sub _formatLevelIndent {
+               # Get arguments
+       my ($self, $aText, $aAdd, $aGlobalLevel) = @_;
+               # Local variables
+       my ($levelIndent, $indent, $nrOfIndents);
+               # Alias indentation option
+       $levelIndent = $self->{options}{'levelIndent'}; #=~ s/[0-9]+/&/;
+               # Calculate number of indents
+       $nrOfIndents = ($aGlobalLevel + $aAdd) * $levelIndent;
+               # Assemble indents
+       $indent = pack("A$nrOfIndents");
+               # Return value
+       return $indent . $aText;
+}  # _formatLevelIndent()
+
+
+#--- HTML::Toc::_formatToc() --------------------------------------------------
+# function: Format ToC.
+# args:     - aPreviousLevel
+#           - aPreviousGroupLevel
+#           - aToc: ToC to format.
+#           - aHeaderLines
+# note:     Recursive function this is.
+
+sub _formatToc {
+               # Get arguments
+       my (
+               $self, $aPreviousLevel, $aPreviousGroupLevel, $aToc, $aHeaderLines, 
+               $aGlobalLevel
+       ) = @_;
+               # Local variables
+       my ($level, $groupLevel, $line, $groupId, $text, $compareStatus);
+       my ($anchorName, $globalLevel, $node, $sequenceNr);
+
+       LOOP: {
+                       # Lines need processing?
+               while (scalar(@$aHeaderLines) > 0) {
+                       # Yes, lines need processing;
+                               # Get line
+                       $line = shift @$aHeaderLines;
+                               
+                               # Determine levels
+                       ($level, $groupLevel, $groupId, $node, $sequenceNr, 
+                       $anchorName, $text) = split(
+                               / /, $line, 7
+                       );
+                               # Must level and group be processed?
+                       if (
+                               ($level =~ m/$self->{options}{'levelToToc'}/) &&
+                               ($groupId =~ m/$self->{options}{'groupToToc'}/)
+                       ) {
+                               # Yes, level must be processed;
+                                       # Compare levels
+                               $compareStatus = $self->_compareLevels(
+                                       $level, $aPreviousLevel, $groupLevel, $aPreviousGroupLevel
+                               );
+
+                               COMPARE_LEVELS: {
+
+                                               # Equals?
+                                       if ($compareStatus == 0) {
+                                               # Yes, levels are equal;
+                                                       # Format level
+                                               $$aToc .= $self->_formatLevelIndent(
+                                                       ref($self->{_templateLevel}) eq "CODE" ?
+                                                               &{$self->{_templateLevel}}(
+                                                                       $level, $groupId, $node, $sequenceNr, $text
+                                                               ) :
+                                                               eval($self->{_templateLevel}),
+                                                       0, $aGlobalLevel
+                                               );
+                                       }
+
+                                               # Greater?
+                                       if ($compareStatus > 0) {
+                                               # Yes, new level is greater than previous level;
+                                                       # Must level be single-stepped?
+                                               if (
+                                                       $self->{options}{'doSingleStepLevel'} && 
+                                                       ($aPreviousLevel) && 
+                                                       ($level > $aPreviousLevel)
+                                               ) {
+                                                       # Yes, level must be single-stepped;
+                                                               # Make sure, new level is increased one step only
+                                                       $level = $aPreviousLevel + 1;
+                                               }
+                                                       # Increase global level
+                                               $aGlobalLevel++;
+                                                       # Format begin of level
+                                               $$aToc .= $self->_formatLevelIndent(
+                                                       eval($self->{_templateLevelBegin}), -1, $aGlobalLevel
+                                               );
+                                                       # Process line again
+                                               unshift @$aHeaderLines, $line;
+                                                       # Assemble TOC (recursive) for next level
+                                               $self->_formatToc(
+                                                       $level, $groupLevel, $aToc, $aHeaderLines, $aGlobalLevel
+                                               );
+                                                       # Format end of level
+                                               $$aToc .= $self->_formatLevelIndent(
+                                                       eval($self->{_templateLevelEnd}), -1, $aGlobalLevel
+                                               );
+                                                       # Decrease global level
+                                               $aGlobalLevel--;
+                                                       # Exit loop
+                                               last COMPARE_LEVELS;
+                                       }
+
+                                               # Smaller?
+                                       if ($compareStatus < 0) {
+                                               # Yes, new level is smaller than previous level;
+                                                       # Process line again
+                                               unshift @$aHeaderLines, $line;
+                                                       # End loop
+                                               last LOOP;
+                                       }
+                               }
+                       }
+               }
+       }
+}      # _formatToc()
+
+
+#--- HTML::Toc::_parseTokenGroups() -------------------------------------------
+# function: Parse token groups
+
+sub _parseTokenGroups {
+               # Get arguments
+       my ($self) = @_;
+               # Local variables
+       my ($group, $levelGroups, $numberingStyle);
+
+               # Clear any previous 'levelGroups'
+       $self->{_levelGroups} = undef;
+               # Determine default 'numberingStyle'
+       $numberingStyle = defined($self->{options}{'numberingStyle'}) ?
+               $self->{options}{'numberingStyle'} : NUMBERING_STYLE_DECIMAL;
+
+               # Loop through groups
+       foreach $group (@{$self->{options}{'tokenToToc'}}) {
+                       # 'groupId' is specified?
+               if (! defined($group->{'groupId'})) {
+                       # No, 'groupId' isn't specified;
+                               # Set default groupId
+                       $group->{'groupId'} = GROUP_ID_H;
+               }
+                       # 'level' is specified?
+               if (! defined($group->{'level'})) {
+                       # No, 'level' isn't specified;
+                               # Set default level
+                       $group->{'level'} = LEVEL_1;
+               }
+                       # 'numberingStyle' is specified?
+               if (! defined($group->{'numberingStyle'})) {
+                       # No, 'numberingStyle' isn't specified;
+                               # Set default numberingStyle
+                       $group->{'numberingStyle'} = $numberingStyle;
+               }
+                       # Add group to '_levelGroups' variabele
+               $self->{_levelGroups}{$group->{'groupId'}}[$group->{'level'} - 1] = 
+                       $group;
+       }
+}  # _parseTokenGroups()
+
+
+#--- HTML::Toc::_setDefaults() ------------------------------------------------
+# function: Set default options.
+
+sub _setDefaults {
+               # Get arguments
+       my ($self) = @_;
+               # Set default options
+       $self->setOptions(
+               {
+                       'attributeToExcludeToken' => '-',
+                       'attributeToTocToken'     => '@',
+                       'insertionPoint'          => 'after <body>',
+                       'levelToToc'              => '.*',
+                       'groupToToc'              => '.*',
+                       'doNumberToken'           => 0,
+                       'doLinkToFile'            => 0,
+                       'doLinkToToken'           => 1,
+                       'doLinkToId'              => 0,
+                       'doSingleStepLevel'       => 1,
+                       'linkUri'                 => '',
+                       'levelIndent'             => 3,
+                       'doNestGroup'             => 0,
+                       'doUseExistingAnchors'    => 1,
+                       'doUseExistingIds'        => 1,
+                       'tokenToToc'              => [
+                               {
+                                       'level'  => 1,
+                                       'tokenBegin' => '<h1>'
+                               }, {
+                                       'level'  => 2,
+                                       'tokenBegin' => '<h2>'
+                               }, {
+                                       'level'  => 3,
+                                       'tokenBegin' => '<h3>'
+                               }, {
+                                       'level'  => 4,
+                                       'tokenBegin' => '<h4>'
+                               }, {
+                                       'level'  => 5,
+                                       'tokenBegin' => '<h5>'
+                               }, {
+                                       'level'  => 6,
+                                       'tokenBegin' => '<h6>'
+                               }
+                       ],
+                       'header'            =>
+                               "\n<!-- Table of Contents generated by Perl - HTML::Toc -->\n",
+                       'footer'            =>
+                               "\n<!-- End of generated Table of Contents -->\n",
+               }
+       );
+}  # _setDefaults()
+
+
+#--- HTML::Toc::clear() -------------------------------------------------------
+# function: Clear ToC.
+
+sub clear {
+               # Get arguments
+       my ($self) = @_;
+               # Clear ToC
+       $self->{_toc}          = "";
+       $self->{toc}           = "";
+       $self->{groupIdLevels} = undef;
+       $self->{levels}        = undef;
+}   # clear()
+
+
+#--- HTML::Toc::format() ------------------------------------------------------
+# function: Format ToC.
+# returns:  Formatted ToC.
+
+sub format {
+               # Get arguments
+       my ($self) = @_;
+               # Local variables;
+       my $toc = "";
+       my @tocLines = split(/\r\n|\n/, $self->{_toc});
+               # Format table of contents
+       $self->_formatToc("0", "0", \$toc, \@tocLines, 0);
+               # Remove last newline
+       $toc =~ s/\n$//m;
+               # Add header & footer
+       $toc = $self->{options}{'header'} . $toc . $self->{options}{'footer'};
+               # Return value
+       return $toc;
+}      # format()
+
+
+#--- HTML::Toc::parseOptions() ------------------------------------------------
+# function: Parse options.
+
+sub parseOptions {
+               # Get arguments
+       my ($self) = @_;
+               # Alias options
+       my $options = $self->{options};
+
+               # Parse token groups
+       $self->_parseTokenGroups();
+
+               # Link ToC to tokens?
+       if ($self->{options}{'doLinkToToken'}) {
+               # Yes, link ToC to tokens;
+                       # Determine anchor href template begin
+               $self->{_templateAnchorHrefBegin} =
+                       defined($options->{'templateAnchorHrefBegin'}) ?
+                               $options->{'templateAnchorHrefBegin'} :
+                               $options->{'doLinkToFile'} ? 
+                                       TEMPLATE_ANCHOR_HREF_BEGIN_FILE : TEMPLATE_ANCHOR_HREF_BEGIN;
+
+                       # Determine anchor href template end
+               $self->{_templateAnchorHrefEnd} =
+                       defined($options->{'templateAnchorHrefEnd'}) ?
+                               $options->{'templateAnchorHrefEnd'} :
+                               TEMPLATE_ANCHOR_HREF_END;
+
+                       # Determine anchor name template
+               $self->{_templateAnchorName} =
+                       defined($options->{'templateAnchorName'}) ?
+                               $options->{'templateAnchorName'} :
+                               TEMPLATE_ANCHOR_NAME;
+
+                       # Determine anchor name template begin
+               $self->{_templateAnchorNameBegin} =
+                       defined($options->{'templateAnchorNameBegin'}) ?
+                               $options->{'templateAnchorNameBegin'} :
+                               TEMPLATE_ANCHOR_NAME_BEGIN;
+
+                       # Determine anchor name template end
+               $self->{_templateAnchorNameEnd} =
+                       defined($options->{'templateAnchorNameEnd'}) ?
+                               $options->{'templateAnchorNameEnd'} :
+                               TEMPLATE_ANCHOR_NAME_END;
+       }
+
+               # Determine token number template
+       $self->{_templateTokenNumber} = 
+               defined($options->{'templateTokenNumber'}) ?
+                       $options->{'templateTokenNumber'} :
+                       TEMPLATE_TOKEN_NUMBER;
+
+               # Determine level template
+       $self->{_templateLevel} =
+               defined($options->{'templateLevel'}) ?
+                       $options->{'templateLevel'} :
+                       TEMPLATE_LEVEL;
+
+               # Determine level begin template
+       $self->{_templateLevelBegin} =
+               defined($options->{'templateLevelBegin'}) ?
+                       $options->{'templateLevelBegin'} :
+                       TEMPLATE_LEVEL_BEGIN;
+
+               # Determine level end template
+       $self->{_templateLevelEnd} =
+               defined($options->{'templateLevelEnd'}) ?
+                       $options->{'templateLevelEnd'} :
+                       TEMPLATE_LEVEL_END;
+
+               # Determine 'anchor name begin' begin update token
+       $self->{_tokenUpdateBeginOfAnchorNameBegin} =
+               defined($options->{'tokenUpdateBeginOfAnchorNameBegin'}) ?
+                       $options->{'tokenUpdateBeginOfAnchorNameBegin'} :
+                       TOKEN_UPDATE_BEGIN_OF_ANCHOR_NAME_BEGIN;
+
+               # Determine 'anchor name begin' end update token
+       $self->{_tokenUpdateEndOfAnchorNameBegin} =
+               defined($options->{'tokenUpdateEndOfAnchorNameBegin'}) ?
+                       $options->{'tokenUpdateEndOfAnchorNameBegin'} :
+                       TOKEN_UPDATE_END_OF_ANCHOR_NAME_BEGIN;
+
+               # Determine 'anchor name end' begin update token
+       $self->{_tokenUpdateBeginOfAnchorNameEnd} =
+               defined($options->{'tokenUpdateBeginOfAnchorNameEnd'}) ?
+                       $options->{'tokenUpdateBeginOfAnchorNameEnd'} :
+                       TOKEN_UPDATE_BEGIN_OF_ANCHOR_NAME_END;
+
+               # Determine 'anchor name end' end update token
+       $self->{_tokenUpdateEndOfAnchorNameEnd} =
+               defined($options->{'tokenUpdateEndOfAnchorNameEnd'}) ?
+                       $options->{'tokenUpdateEndOfAnchorNameEnd'} :
+                       TOKEN_UPDATE_END_OF_ANCHOR_NAME_END;
+
+               # Determine number begin update token
+       $self->{_tokenUpdateBeginNumber} =
+               defined($options->{'tokenUpdateBeginNumber'}) ?
+                       $options->{'tokenUpdateBeginNumber'} :
+                       TOKEN_UPDATE_BEGIN_NUMBER;
+
+               # Determine number end update token
+       $self->{_tokenUpdateEndNumber} =
+               defined($options->{'tokenUpdateEndNumber'}) ?
+                       $options->{'tokenUpdateEndNumber'} :
+                       TOKEN_UPDATE_END_NUMBER;
+
+               # Determine toc begin update token
+       $self->{_tokenUpdateBeginToc} =
+               defined($options->{'tokenUpdateBeginToc'}) ?
+                       $options->{'tokenUpdateBeginToc'} :
+                       TOKEN_UPDATE_BEGIN_TOC;
+
+               # Determine toc end update token
+       $self->{_tokenUpdateEndToc} =
+               defined($options->{'tokenUpdateEndToc'}) ?
+                       $options->{'tokenUpdateEndToc'} :
+                       TOKEN_UPDATE_END_TOC;
+
+}  # parseOptions()
+
+
+#--- HTML::Toc::setOptions() --------------------------------------------------
+# function: Set options.
+# args:     - aOptions: Reference to hash containing options.
+
+sub setOptions {
+               # Get arguments
+       my ($self, $aOptions) = @_;
+               # Add options
+       %{$self->{options}} = (%{$self->{options}}, %$aOptions);
+}  # setOptions()
+
+
+1;
diff --git a/examples/includes/HTML-Toc-0.91/Toc.pod b/examples/includes/HTML-Toc-0.91/Toc.pod
new file mode 100644 (file)
index 0000000..6348503
--- /dev/null
@@ -0,0 +1,1710 @@
+=head1 NAME
+
+HTML::Toc - Generate, insert and update HTML Table of Contents.
+
+=head1 DESCRIPTION
+
+Generate, insert and update HTML Table of Contents.
+
+=head1 Introduction
+
+The HTML::Toc consists out of the following packages:
+
+    HTML::Toc
+    HTML::TocGenerator
+    HTML::TocInsertor
+    HTML::TocUpdator
+
+HTML::Toc is the object which will eventually hold the Table of Contents.  HTML::TocGenerator does the actual generation of the ToC.  HTML::TocInsertor handles the insertion of the ToC in the source.  HTML::TocUpdator takes care of updating previously inserted ToCs.
+
+HTML::Parser is the base object of HTML::TocGenerator, HTML::TocInsertor and HTML::TocUpdator.  Each of these objects uses its predecessor as its ancestor, as shown in the UML diagram underneath:
+    
+    +---------------------+
+    |    HTML::Parser     |
+    +---------------------+
+    +---------------------+
+    |    +parse()         |
+    |    +parse_file()    |
+    +----------+----------+
+              /_\
+               |
+    +----------+----------+  <<uses>>  +-----------+
+    | HTML::TocGenerator  + - - - - - -+ HTML::Toc |
+    +---------------------+            +-----------+
+    +---------------------+            +-----------+
+    | +extend()           |            | +clear()  |
+    | +extendFromFile()   |            | +format() |
+    | +generate()         |            +-----+-----+
+    | +generateFromFile() |                  :
+    +----------+----------+                  :
+              /_\                            :
+               |                             :
+    +----------+----------+     <<uses>>     :
+    |  HTML::TocInsertor  + - - - - - - - - -+
+    +---------------------+                  :
+    +---------------------+                  :
+    |  +insert()          |                  :
+    |  +insertIntoFile()  |                  :
+    +----------+----------+                  :
+              /_\                            :
+               |                             :
+    +----------+----------+     <<uses>>     :
+    |  HTML::TocUpdator   + - - - - - - - - -+
+    +---------------------+
+    +---------------------+
+    |  +insert()          |
+    |  +insertIntoFile()  |
+    |  +update()          |
+    |  +updateFile()      |
+    +---------------------+
+
+When generating a ToC you'll have to decide which object you want to use:
+
+    TocGenerator:
+        for generating a ToC without inserting the ToC into the source
+    TocInsertor:
+        for generating a ToC and inserting the ToC into the source
+    TocUpdator:
+        for generating and inserting a ToC, removing any previously
+        inserted ToC elements
+
+Thus in tabular view, each object is capable of:
+
+                   generating   inserting   updating
+                   ---------------------------------
+    TocGenerator        X
+    TocInsertor         X           X
+    TocUpdator          X           X           X
+
+=head2 Generating
+
+The code underneath will generate a ToC of the HTML headings C<<h1>>..C<<h6>> from a file C<index.htm>:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+
+    my $toc          = HTML::Toc->new();
+    my $tocGenerator = HTML::TocGenerator->new();
+
+    $tocGenerator->generateFromFile($toc, 'index.htm');
+    print $toc->format();
+
+For example, with C<index.htm> containing:
+
+    <html>
+    <body>
+       <h1>Chapter</h1>
+    </body>
+    </html>
+
+the output will be:
+
+    
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1>Chapter</a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+=head2 Inserting
+
+This code will generate a ToC of HTML headings C<<h1>>..C<<h6>> of file C<index.htm>, and insert the ToC after the C<<body>> tag at the same time:
+
+    use HTML::Toc;
+    use HTML::TocInsertor;
+
+    my $toc         = HTML::Toc->new();
+    my $tocInsertor = HTML::TocInsertor->new();
+
+    $tocInsertor->insertIntoFile($toc, 'index.htm');
+
+For example, with C<index.htm> containing:
+
+    <html>
+    <body>
+       <h1>Chapter</h1>
+    </body>
+    </html>
+
+the output will be:
+
+    <html>
+    <body>
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1>Chapter</a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+       <a name=h-1><h1>Chapter</h1></a>
+    </body>
+    </html>
+
+If you're planning to update the inserted ToC, you'd better use C<TocUpdator> to insert the ToC.  C<TocUpdator> marks the inserted ToC elements with update tokens.  These update tokens allow C<TocUpdator> to identify and remove the ToC elements during a future update session.  This code uses C<TocUpdator> instead of C<TocInsertor>:
+
+    use HTML::Toc;
+    use HTML::TocUpdator;
+
+    my $toc        = HTML::Toc->new();
+    my $tocUpdator = HTML::TocUpdator->new();
+
+    $tocUpdator->insertIntoFile($toc, 'index.htm');
+
+When applying the code above on 'index.htm':
+
+    <html>
+    <body>
+       <h1>
+       Chapter
+       </h1>
+    </body>
+    </html>
+
+the output will contain additional update tokens:
+
+    <!-- #BeginToc -->
+    <!-- #EndToc -->
+    <!-- #BeginTocAnchorNameBegin -->
+    <!-- #EndTocAnchorNameBegin -->
+    <!-- #BeginTocAnchorNameEnd -->
+    <!-- #EndTocAnchorNameEnd -->
+
+around the inserted ToC elements:
+
+    <html>
+    <body><!-- #BeginToc-->
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1> Chapter </a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+    <!-- #EndToc -->
+       <!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1>
+       Chapter
+       </h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+    </body>
+    </html>
+
+Instead of C<HTML::TocUpdator::insertIntoFile> you can also use C<HTML::TocUpdator::updateFile()>.  C<HTML::TocUpdator::updateFile()> will also insert the ToC, whether there is a ToC already inserted or not.
+
+=head2 Updating
+
+This code will generate a ToC of HTML headings C<<h1>>..C<<h6>> of file C<indexToc.htm>, and insert or update the ToC after the C<<body>> tag at the same time:
+
+    use HTML::Toc;
+    use HTML::TocUpdator;
+
+    my $toc        = HTML::Toc->new();
+    my $tocUpdator = HTML::TocUpdator->new();
+
+    $tocUpdator->updateFile($toc, 'indexToc.htm');
+
+For example, with C<indexToc.htm> containing:
+
+    <html>
+    <body><!-- #BeginToc -->
+    foo
+    <!-- #EndToc -->
+       <!-- #BeginTocAnchorNameBegin -->bar<!-- #EndTocAnchorNameBegin --><h1>
+       Chapter
+       </h1><!-- #BeginTocAnchorNameEnd -->foo<!-- #EndTocAnchorNameEnd -->
+    </body>h
+    </html>
+
+the output will be:
+
+    <html>
+    <body><!-- #BeginToc -->
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1> Chapter </a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+    <!-- #EndToc -->
+       <!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1>
+       Chapter
+       </h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+    </body>
+    </html>
+
+All text between the update tokens will be replaced.  So be warned: all manual changes made to text between update tokens will be removed unrecoverable after calling C<HTML::TocUpdator::update()> or C<HTML::TocUpdator::updateFile()>.
+
+=head2 Formatting
+
+The ToC isn't generated all at once.  There are two stages involved: generating and formatting.  Generating the ToC actually means storing a preliminary ToC in C<HTML::Toc-E<gt>{_toc}>.  This preliminary, tokenized ToC has to be turned into something useful by calling C<HTML::Toc-E<gt>format()>.  For an example, see paragraph 'L<Generating|"generating">'.
+
+=head1 Advanced
+
+The ToC generation can be modified in a variety of ways.  The following paragraphs each explain a single modification.  An example of most of the modifications can be found in the C<manualTest.t> test file.  Within this test, a manual containing:
+
+    preface
+    introduction
+    table of contents
+    table of figures
+    table of tables
+    parts
+    chapters
+    appendixes
+    bibliography
+
+is formatted.
+
+=head2 Using attribute value as ToC text
+
+Normally, the ToC will be made of text between specified ToC tokens.  It's also possible to use the attribute value of a token as a ToC text.  This can be done by specifying the attribute marked with an L<attributeToTocToken|"attributeToTocToken"> within the L<tokenBegin|"tokenBegin"> token.  For example, suppose you want to generate a ToC of the C<alt> attributes of the following image tokens:
+
+    <body>
+       <img src=test1.gif alt="First picture">
+       <img src=test2.gif alt="Second picture">
+    </body>
+
+This would be the code:
+
+    use HTML::Toc;
+    use HTML::TocInsertor;
+
+    my $toc         = HTML::Toc->new();
+    my $tocInsertor = HTML::TocInsertor->new();
+
+    $toc->setOptions({
+       'tokenToToc'   => [{
+          'groupId'    => 'image',
+          'tokenBegin' => '<img alt=@>'
+       }],
+    });
+    $tocInsertor->insertIntoFile($toc, $filename);
+
+and the output will be:
+
+    <body>
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#image-1>First picture</a>
+       <li><a href=#image-2>Second picture</a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+       <a name=image-1><img src=test1.gif alt="First picture"></a>
+       <a name=image-2><img src=test2.gif alt="Second picture"></a>
+    </body>
+
+=head2 Generate single ToC of multiple files
+
+Besides generating a ToC of a single file, it's also possible to generate a single ToC of multiple files.  This can be done by specifying either an array of files as the file argument and/or by extending an existing ToC.
+
+=head3 Specify an array of files
+
+For example, suppose you want to generate a ToC of both C<doc1.htm>:
+
+    <body>
+       <h1>Chapter of document 1</h1>
+    </body>
+
+and C<doc2.htm>:
+
+    <body>
+       <h1>Chapter of document 2</h1>
+    </body>
+
+Here's the code to do so by specifying an array of files:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+
+    my $toc          = HTML::Toc->new();
+    my $tocGenerator = HTML::TocGenerator->new();
+
+    $toc->setOptions({'doLinkToFile' => 1});
+    $tocGenerator->generateFromFile($toc, ['doc1.htm', 'doc2.htm']);
+    print $toc->format();
+
+And the output will be:
+
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=doc1.htm#h-1>Chapter of document 1</a>
+       <li><a href=doc2.htm#h-2>Chapter of document 2</a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+=head3 Extend an existing ToC
+
+It's also possible to extend an existing ToC.  For example, suppose we want the generate a ToC of file C<doc1.htm>:
+
+    <body>
+       <h1>Chapter of document 1</h1>
+    </body>
+
+and extend this ToC with text from C<doc2.htm>:
+
+    <body>
+       <h1>Chapter of document 2</h1>
+    </body>
+
+Here's the code to do so:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+
+    my $toc          = HTML::Toc->new();
+    my $tocGenerator = HTML::TocGenerator->new();
+
+    $toc->setOptions({'doLinkToFile' => 1});
+    $tocGenerator->generateFromFile($toc, 'doc1.htm');
+    $tocGenerator->extendFromFile($toc, 'doc2.htm');
+    print $toc->format();
+
+And the output will be:
+
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=doc1.htm#h-1>Chapter of document 1</a>
+       <li><a href=doc2.htm#h-2>Chapter of document 2</a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+=head2 Generate multiple ToCs
+
+It's possible to generate multiple ToCs at once by specifying a C<HTML::Toc> object array as the ToC argument.  For example, suppose you want to generate a default ToC of HTML headings <h1>..<h6> as well as a ToC of the C<alt> image attributes of the following text:
+
+    <body>
+       <h1>Header One</h1>
+       <img src=test1.gif alt="First picture" id=image_001>
+       <h2>Paragraph One</h2>
+       <img src=test2.gif alt="Second picture" id=image_002>
+    </body>
+
+Here's how you would do so:
+
+    use HTML::Toc;
+    use HTML::TocInsertor;
+
+    my $toc1        = HTML::Toc->new();
+    my $toc2        = HTML::Toc->new();
+    my $tocInsertor = HTML::TocInsertor->new();
+
+    $toc2->setOptions({
+       'tokenToToc'   => [{
+          'groupId'    => 'image',
+          'tokenBegin' => '<img alt=@>'
+       }],
+    });
+    $tocInsertor->insertIntoFile([$toc1, $toc2], $filename);
+
+And the output will be:
+
+    <body>
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1>Header One</a>
+       <ul>
+          <li><a href=#h-1.1>Paragraph One</a>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#image-1>First picture</a>
+       <li><a href=#image-2>Second picture</a>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+       <a name=h-1><h1>Header One</h1></a>
+       <a name=image-1><img src=test1.gif alt="First picture"></a>
+       <a name=h-1.1><h2>Paragraph One</h2></a>
+       <a name=image-2><img src=test2.gif alt="Second picture"></a>
+    </body>
+
+=head2 Generate multiple groups in one ToC
+
+You may want to generate a ToC consisting of multiple ToC groups.
+
+=head3 Specify an additional 'Appendix' group
+
+Suppose you want to generate a ToC with one group for the normal headings, and one group for the appendix headings, using this source file:
+
+    <body>
+       <h1>Chapter</h1>
+       <h2>Paragraph</h2>
+       <h3>Subparagraph</h3>
+       <h1>Chapter</h1>
+       <h1 class=appendix>Appendix Chapter</h1>
+       <h2 class=appendix>Appendix Paragraph</h2>
+    </body>
+
+With the code underneath:
+
+    use HTML::Toc;
+    use HTML::TocInsertor;
+
+    my $toc         = HTML::Toc->new();
+    my $tocInsertor = HTML::TocInsertor->new();
+
+    $toc->setOptions({
+       'tokenToToc' => [{
+             'tokenBegin' => '<h1 class=-appendix>'
+          }, {
+             'tokenBegin' => '<h2 class=-appendix>',
+             'level'      => 2
+          }, {
+             'groupId'    => 'appendix',
+             'tokenBegin' => '<h1 class=appendix>',
+          }, {
+             'groupId'    => 'appendix',
+             'tokenBegin' => '<h2 class=appendix>',
+             'level'      => 2
+          }]
+    });
+    $tocInsertor->insertIntoFile($toc, $filename);
+
+the output will be:
+
+    <body>
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1>Chapter</a>
+       <ul>
+          <li><a href=#h-1.1>Paragraph</a>
+       </ul>
+       <li><a href=#h-2>Chapter</a>
+    </ul>
+    <ul>
+       <li><a href=#appendix-1>Appendix Chapter</a>
+       <ul>
+          <li><a href=#appendix-1.1>Appendix Paragraph</a>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+       <a name=h-1><h1>Chapter</h1></a>
+       <a name=h-1.1><h2>Paragraph</h2></a>
+       <h3>Subparagraph</h3>
+       <a name=h-2><h1>Chapter</h1></a>
+       <a name=appendix-1><h1 class=appendix>Appendix Chapter</h1></a>
+       <a name=appendix-1.1><h2 class=appendix>Appendix Paragraph</h2></a>
+    </body>
+
+=head3 Specify an additional 'Part' group
+
+Suppose you want to generate a ToC of a document which is divided in multiple parts like this file underneath:
+
+    <body>
+       <h1 class=part>First Part</h1>
+       <h1>Chapter</h1>
+       <h2>Paragraph</h2>
+       <h1 class=part>Second Part</h1>
+       <h1>Chapter</h1>
+       <h2>Paragraph</h2>
+    </body>
+
+With the code underneath:
+
+    use HTML::Toc;
+    use HTML::TocInsertor;
+
+    my $toc         = HTML::Toc->new();
+    my $tocInsertor = HTML::TocInsertor->new();
+
+    $toc->setOptions({
+       'doNumberToken'    => 1,
+       'tokenToToc' => [{
+             'tokenBegin' => '<h1 class=-part>'
+          }, {
+             'tokenBegin' => '<h2 class=-part>',
+             'level'      => 2,
+          }, {
+             'groupId'        => 'part',
+             'tokenBegin'     => '<h1 class=part>',
+             'level'          => 1,
+             'numberingStyle' => 'upper-alpha'
+          }]
+    });
+    $tocInsertor->insertIntoFile($toc, $filename);
+
+the output will be:
+
+    <body>
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#part-A>First Part</a>
+    </ul>
+    <ul>
+       <li><a href=#h-1>Chapter</a>
+       <ul>
+          <li><a href=#h-1.1>Paragraph</a>
+       </ul>
+    </ul>
+    <ul>
+       <li><a href=#part-B>Second Part</a>
+    </ul>
+    <ul>
+       <li><a href=#h-2>Chapter</a>
+       <ul>
+          <li><a href=#h-2.1>Paragraph</a>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+       <a name=part-A><h1 class=part>A &nbsp;First Part</h1></a>
+       <a name=h-1><h1>1 &nbsp;Chapter</h1></a>
+       <a name=h-1.1><h2>1.1 &nbsp;Paragraph</h2></a>
+       <a name=part-B><h1 class=part>B &nbsp;Second Part</h1></a>
+       <a name=h-2><h1>2 &nbsp;Chapter</h1></a>
+       <a name=h-2.1><h2>2.1 &nbsp;Paragraph</h2></a>
+    </body>
+
+=head2 Number ToC entries
+
+By default, the generated ToC will list its entries unnumbered.  If you want to number the ToC entries, two options are available.  Either you can specify a numbered list by modifying L<templateLevelBegin|"templateLevelBegin"> and L<templateLevelEnd|"templateLevelEnd">.  Or when the ToC isn't a simple numbered list, you can use the numbers generated by HTML::TocGenerator.
+
+=head3 Specify numbered list
+
+By modifying L<templateLevelBegin|"templateLevelBegin"> and L<templateLevelEnd|"templateLevelEnd"> you can specify a numbered ToC:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+
+    my $toc          = HTML::Toc->new();
+    my $tocGenerator = HTML::TocGenerator->new();
+
+    $toc->setOptions({
+        'templateLevelBegin' => '"<ol>\n"',
+        'templateLevelEnd'   => '"</ol>\n"',
+    });
+    $tocGenerator->generateFromFile($toc, 'index.htm');
+    print $toc->format();
+
+For instance with the original file containing:
+
+    <body>
+        <h1>Chapter</h1>
+        <h2>Paragraph</h2>
+    </body>
+
+The formatted ToC now will contain C<ol> instead of C<ul> tags:
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ol>
+       <li><a href=#h-1>Chapter</a>
+       <ol>
+          <li><a href=#h-1.1>Paragraph</a>
+       </ol>
+    </ol>
+    <!-- End of generated Table of Contents -->
+
+See also: L<Using CSS for ToC formatting|"Using CSS for ToC formatting">.
+
+=head3 Use generated numbers
+
+Instead of using the HTML ordered list (OL), it's also possible to use the generated numbers to number to ToC nodes.  This can be done by modifying L<templateLevel|"templateLevel">:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+
+    my $toc          = HTML::Toc->new();
+    my $tocGenerator = HTML::TocGenerator->new();
+
+    $toc->setOptions({
+               'templateLevel' => '"<li>$node &nbsp;$text\n"',
+    });
+    $tocGenerator->generateFromFile($toc, 'index.htm');
+    print $toc->format();
+
+For instance with the original file containing:
+
+    <body>
+        <h1>Chapter</h1>
+        <h2>Paragraph</h2>
+    </body>
+
+The formatted ToC now will have the node numbers hard-coded:
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li>1 &nbsp;<a href=#h-1>Chapter</a>
+       <ul>
+          <li>1.1 &nbsp;<a href=#h-1.1>Paragraph</a>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+See also: L<Using CSS for ToC formatting|"Using CSS for ToC formatting">.
+
+=head2 Using CSS for ToC formatting
+
+Suppose you want to display a ToC with upper-alpha numbered appendix headings.  To accomplish this, you can specify a CSS style within the source document:
+
+    <html>
+    <head>
+       <style type="text/css">
+          ol.toc_appendix1 { list-style-type: upper-alpha }
+       </style>
+    </head>
+    <body>
+       <h1 class=appendix>Appendix</h1>
+       <h2 class=appendix>Appendix Paragraph</h2>
+       <h1 class=appendix>Appendix</h1>
+       <h2 class=appendix>Appendix Paragraph</h2>
+    </body>
+    </html>
+
+Here's the code:
+
+    my $toc          = new HTML::Toc;
+    my $tocInsertor  = new HTML::TocInsertor;
+
+    $toc->setOptions({
+       'templateLevelBegin'   => '"<ol class=toc_$groupId$level>\n"',
+       'templateLevelEnd'     => '"</ol>\n"',
+       'doNumberToken'        => 1,
+       'tokenToToc' => [{
+             'groupId'        => 'appendix',
+             'tokenBegin'     => '<h1>',
+             'numberingStyle' => 'upper-alpha'
+          }, {
+             'groupId'        => 'appendix',
+             'tokenBegin'     => '<h2>',
+             'level'          => 2,
+         }]
+    });
+    $tocInsertor->insertIntoFile($toc, $filename);
+
+Which whill result in the following output:
+
+    <html>
+    <head>
+       <style type="text/css">
+          ol.toc_appendix1 { list-style-type: upper-alpha }
+       </style>
+    </head>
+    <body>
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ol class=toc_appendix1>
+       <li><a href=#appendix-A>Appendix</a>
+       <ol class=toc_appendix2>
+          <li><a href=#appendix-A.1>Appendix Paragraph</a>
+       </ol>
+       <li><a href=#appendix-B>Appendix</a>
+       <ol class=toc_appendix2>
+          <li><a href=#appendix-B.1>Appendix Paragraph</a>
+       </ol>
+    </ol>
+    <!-- End of generated Table of Contents -->
+
+       <a name=appendix-A><h1>A &nbsp;Appendix</h1></a>
+       <a name=appendix-A.1><h2>A.1 &nbsp;Appendix Paragraph</h2></a>
+       <a name=appendix-B><h1>B &nbsp;Appendix</h1></a>
+       <a name=appendix-B.1><h2>B.1 &nbsp;Appendix Paragraph</h2></a>
+    </body>
+    </html>
+
+=head2 Creating site map
+
+Suppose you want to generate a table of contents of the E<lt>titleE<gt> tags of the files in the following directory structure:
+
+    path               file
+
+    .                  index.htm, <title>Main</title>
+    |- SubDir1         index.htm, <title>Sub1</title>
+    |  |- SubSubDir1   index.htm, <title>SubSub1</title>
+    |
+    |- SubDir2         index.htm, <title>Sub2</title>
+    |  |- SubSubDir1   index.htm, <title>SubSub1</title>
+    |  |- SubSubDir2   index.htm, <title>SubSub2</title>
+    |
+    |- SubDir3         index.htm, <title>Sub3</title>
+
+By specifying 'fileSpec' which determine how many slashes (/) each file may contain for a specific level:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+    use File::Find;
+
+    my $toc          = HTML::Toc->new;
+    my $tocGenerator = HTML::TocGenerator->new;
+    my @fileList;
+
+    sub wanted {
+          # Add file to 'fileList' if extension matches '.htm'
+       push (@fileList, $File::Find::name) if (m/\.htm$/);
+    }
+
+    $toc->setOptions({
+       'doLinkToFile'       => 1,
+       'templateAnchorName' => '""',
+       'templateAnchorHref' => '"<a href=$file"."#".$groupId.$level.">"',
+       'doLinkTocToToken'   => 1,
+       'tokenToToc'         => [{
+          'groupId'         => 'dir',
+          'level'           => 1,
+          'tokenBegin'      => '<title>',
+          'tokenEnd'        => '</title>',
+          'fileSpec'        => '\./[^/]+$'
+       }, {
+          'groupId'         => 'dir',
+          'level'           => 2,
+          'tokenBegin'      => '<title>',
+          'tokenEnd'        => '</title>',
+          'fileSpec'        => '\./[^/]+?/[^/]+$'
+       }, {
+          'groupId'         => 'dir',
+          'level'           => 3,
+          'tokenBegin'      => '<title>',
+          'tokenEnd'        => '</title>',
+          'fileSpec'        => '\./[^/]+?/[^/]+?/[^/]+$'
+       }]
+    });
+
+       # Traverse directory structure
+    find({wanted => \&wanted, no_chdir => 1}, '.');
+       # Generate ToC of case-insensitively sorted file list
+    $tocGenerator->extendFromFile(
+       $toc, [sort {uc($a) cmp uc($b)} @fileList]
+    );
+    print $toc->format();
+
+the following ToC will be generated:
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=./index.htm#>Main</a>
+       <ul>
+          <li><a href=./SubDir1/index.htm#>Sub1</a>
+          <ul>
+             <li><a href=./SubDir1/SubSubDir1/index.htm#>SubSub1</a>
+          </ul>
+          <li><a href=./SubDir2/index.htm#>Sub2</a>
+          <ul>
+             <li><a href=./SubDir2/SubSubDir1/index.htm#>SubSub1</a>
+             <li><a href=./SubDir2/SubSubDir2/index.htm#>SubSub2</a>
+          </ul>
+          <li><a href=./SubDir3/index.htm#>Sub3</a>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+=head1 Methods
+
+=head2 HTML::Toc::clear()
+
+    syntax:  $toc->clear()
+    returns: --
+
+Clear the ToC.
+
+=head2 HTML::Toc::format()
+
+    syntax:  $scalar = $toc->format()
+    returns: Formatted ToC.
+
+Format tokenized ToC.
+
+=head2 HTML::TocGenerator::extend()
+
+    syntax:  $tocGenerator->extend($toc, $string [, $options])
+    args:    - $toc:     (reference to array of) HTML::Toc object(s) to extend
+             - $string:  string to retrieve ToC from
+             - $options: hash reference containing generator options.
+
+Extend ToC from specified string.  For generator options, see L<HTML::TocGenerator Options|"HTML::TocGenerator Options">
+
+=head2 HTML::TocGenerator::extendFromFile()
+
+    syntax:  $tocGenerator->extendFromFile($toc, $filename [, $options])
+    args:    - $toc:      (reference to array of) HTML::Toc object(s) to extend
+             - $filename: (reference to array of) file(s) to extend ToC from
+             - $options:  hash reference containing generator options.
+
+Extend ToC from specified file.  For generator options, see L<HTML::TocGenerator Options|"HTML::TocGenerator Options">.  For an example, see L<Extend an existing ToC>.
+
+=head2 HTML::TocGenerator::generate()
+
+    syntax:  $tocGenerator->generate($toc, $string [, $options])
+    args:    - $toc:     (reference to array of) HTML::Toc object(s) to generate
+             - $string:  string to retrieve ToC from
+             - $options: hash reference containing generator options.
+
+Generate ToC from specified string.  Before generating, the ToC will be cleared.  For extending an existing ToC, use the L<HTML::TocGenerator::extend()|"HTML::TocGenerator::extend()"> method.  For generator options, see L<HTML::TocGenerator Options|"HTML::TocGenerator Options">.
+
+=head2 HTML::TocGenerator::generateFromFile()
+
+    syntax:  $tocGenerator->generateFromFile($toc, $filename [, $options])
+    args:    - $toc:      (reference to array of) HTML::Toc object(s) to 
+                          generate
+             - $filename: (reference to array of) file(s) to generate ToC from
+             - $options:  hash reference containing generator options.
+
+Generate ToC from specified file.  Before generating, the ToC will be cleared.  For extending an extisting ToC, use the L<HTML::TocGenerator::extendFromFile()|"HTML::TocGenerator::extendFromFile()"> method.  For generator options, see L<HTML::TocGenerator Options|"HTML::TocGenerator Options">.
+
+=head2 HTML::TocInsertor::insert()
+
+    syntax:  $tocInsertor->insert($toc, $string [, $options])
+    args:    - $toc:     (reference to array of) HTML::Toc object(s) to insert
+             - $string:  string to insert ToC in
+             - $options: hash reference containing insertor options.
+
+Insert ToC into specified string.  For insertor options, see L<HTML::TocInsertor Options|"HTML::TocInsertor Options">.
+
+=head2 HTML::TocInsertor::insertIntoFile()
+
+    syntax:  $tocInsertor->insertIntoFile($toc, $filename [, $options])
+    args:    - $toc:      (reference to array of) HTML::Toc object(s) to insert
+             - $filename: (reference to array of) file(s) to insert ToC in
+             - $options:  hash reference containing insertor options.
+
+Insert ToC into specified file.  For insertor options, see L<HTML::TocInsertor Options|"HTML::TocInsertor Options">.
+
+=head2 HTML::TocUpdator::insert()
+
+    syntax:  $tocUpdator->insert($toc, $string [, $options])
+    args:    - $toc:     (reference to array of) HTML::Toc object(s) to insert
+             - $string:  string to insert ToC in
+             - $options: hash reference containing updator options.
+
+Insert ToC into specified string.  Differs from L<HTML::TocInsertor::insert()|"HTML::TocInsertor::insert()"> in that inserted text will be surrounded with update tokens in order for C<HTML::TocUpdator> to be able to update this text the next time an update is issued.  For updator options, see L<HTML::TocUpdator Options|"HTML::TocUpdator Options">.
+
+=head2 HTML::TocUpdator::insertIntoFile()
+
+    syntax:  $tocUpdator->insertIntoFile($toc, $filename [, $options])
+    args:    - $toc:      (reference to array of) HTML::Toc object(s) to insert
+             - $filename: (reference to array of) file(s) to insert ToC in
+             - $options:  hash reference containing updator options.
+
+Insert ToC into specified file.  Differs from L<HTML::TocInsertor::insert()|"HTML::TocInsertor::insert()"> in that inserted text will be surrounded with update tokens in order for C<HTML::TocUpdator> to be able to update this text the next time an update is issued.  For updator options, see L<HTML::TocUpdator Options|"HTML::TocUpdator Options">.
+
+=head2 HTML::TocUpdator::update()
+
+    syntax:  $tocUpdator->update($toc, $string [, $options])
+    args:    - $toc:     (reference to array of) HTML::Toc object(s) to insert
+             - $string:  string to update ToC in
+             - $options: hash reference containing updator options.
+
+Update ToC within specified string.  For updator options, see L<HTML::TocUpdator Options|"HTML::TocUpdator Options">.
+
+=head2 HTML::TocUpdator::updateFile()
+
+    syntax:  $tocUpdator->updateFile($toc, $filename [, $options])
+    args:    - $toc:      (reference to array of) HTML::Toc object(s) to insert
+             - $filename: (reference to array of) file(s) to update ToC in
+             - $options:  hash reference containing updator options.
+
+Update ToC of specified file.  For updator options, see L<HTML::TocUpdator Options|"HTML::TocUpdator Options">.
+
+=head1 Parser Options
+
+When generating a ToC, additional options may be specified which influence the way the ToCs are generated using either C<TocGenerator>, C<TocInsertor> or C<TocUpdator>.  The options must be specified as a hash reference.  For example:
+
+    $tocGenerator->generateFromFile($toc, $filename, {doUseGroupsGlobal => 1});
+
+Available options are:
+
+=over 4
+
+=item L<doGenerateToc|"doGenerateToc">
+
+=item L<doUseGroupsGlobal|"doUseGroupsGlobal">
+
+=item L<output|"output">
+
+=item L<outputFile|"outputFile">
+
+=back
+
+=head2 doGenerateToc
+
+    syntax:         [0|1]
+    default:        1
+    applicable to:  TocInsertor, TocUpdator
+
+True (1) if ToC must be generated.  False (0) if ToC must be inserted only.
+
+=head2 doUseGroupsGlobal
+
+    syntax:         [0|1]
+    default:        0
+    applicable to:  TocGenerator, TocInsertor, TocUpdator
+
+True (1) if group levels must be used globally accross ToCs.  False (0) if not.  This option only makes sense when an array of ToCs is specified.  For example, suppose you want to generate two ToCs, one ToC for '<h1>' tokens and one ToC for '<h2>' tokens, of the file 'index.htm':
+
+    <h1>Chapter</h1>
+    <h2>Paragraph</h2>
+
+Using the default setting of 'doUseGroupsGlobal' => 0:
+
+    use HTML::Toc;
+    use HTML::TocGenerator;
+
+    my $toc1         = HTML::Toc->new();
+    my $toc2         = HTML::Toc->new();
+    my $tocGenerator = HTML::TocGenerator->new();
+
+    $toc1->setOptions({
+       'header'     => '',
+       'footer'     => '',
+       'tokenToToc' => [{'tokenBegin' => '<h1>'}]
+    });
+    $toc2->setOptions({
+       'header'     => '',
+       'footer'     => '',
+       'tokenToToc' => [{'tokenBegin' => '<h2>'}]
+    });
+    $tocGenerator->generateFromFile([$toc1, $toc2], 'index.htm');
+    print $toc1->format() . "\n\n" . $toc2->format();
+
+the output will be:
+
+    <ul>
+       <li><a href=#h-1>Chapter</a>
+    </ul>
+
+    <ul>
+       <li><a href=#h-1>Paragraph</a>
+    </ul>
+
+Each ToC will use its own numbering scheme.  Now if 'C<doUseGroupsGlobal = 1>' is specified:
+
+    $tocGenerator->generateFromFile(
+       [$toc1, $toc2], 'index.htm', {'doUseGroupsGlobal' => 1}
+    );
+
+the output will be:
+
+    <ul>
+       <li><a href=#h-1>Chapter</a>
+    </ul>
+
+    <ul>
+       <li><a href=#h-2>Paragraph</a>
+    </ul>
+
+using a global numbering scheme for all ToCs.
+
+=head2 output
+
+    syntax:         reference to scalar
+    default:        none
+    applicable to:  TocInsertor, TocUpdator
+
+Reference to scalar where the output must be stored in.
+
+=head2 outputFile
+
+    syntax:         scalar
+    default:        none
+    applicable to:  TocInsertor, TocUpdator
+
+Filename to write output to.  If no filename is specified, output will be written to standard output.
+
+=head1 HTML::Toc Options
+
+The C<HTML::Toc> options can be grouped in the following categories:
+
+=over 4
+
+=item L<Generate options|"Generate options">
+
+=item L<Insert options|"Insert options">
+
+=item L<Update options|"Update options">
+
+=item L<Format options|"Format options">
+
+=back
+
+The ToC options must be specified using the 'setOptions' method.  For example:
+
+    my $toc = new HTML::Toc;
+
+    $toc->setOptions({
+       'doNumberToken' => 1,
+       'footer'        => '<!-- End Of ToC -->'
+       'tokenToToc'    => [{
+          'level'          => 1,
+          'tokenBegin'     => '<h1>',
+          'numberingStyle' => 'lower-alpha'
+       }]
+    });
+
+=head2 Generate options
+
+=over 4
+
+=item Token groups
+
+=over 4
+
+=item L<tokenToToc|"tokenToToc">
+
+=over 4
+
+=item L<doNumberToken|"doNumberToken">
+
+=item L<fileSpec|"fileSpec">
+
+=item L<groupId|"groupId">
+
+=item L<level|"level">
+
+=item L<tokenBegin|"tokenBegin">
+
+=item L<tokenEnd|"tokenEnd">
+
+=item L<numberingStyle|"numberingStyle">
+
+=back
+
+=item L<groupToToc|"groupToToc">
+
+=item L<levelToToc|"levelToToc">
+
+=back
+
+=item Numbering tokens
+
+=over 4
+
+=item L<doNumberToken|"doNumberToken">
+
+=item L<numberingStyle|"numberingStyle">
+
+=item L<templateTokenNumber|"templateTokenNumber">
+
+=back
+
+=item Miscellaneous
+
+=over 4
+
+=item L<attributeToExcludeToken|"attributeToExcludeToken">
+
+=item L<attributeToTocToken|"attributeToTocToken">
+
+=item L<groupToToc|"groupToToc">
+
+=item L<levelToToc|"levelToToc">
+
+=back
+
+=item Linking ToC to tokens
+
+=over 4
+
+=item L<doLinkToToken|"doLinkToToken">
+
+=item L<doLinkToFile|"doLinkToFile">
+
+=item L<doLinkToId|"doLinkToId">
+
+=item L<templateAnchorName|"templateAnchorName">
+
+=item L<templateAnchorHrefBegin|"templateAnchorHrefBegin">
+
+=item L<templateAnchorHrefEnd|"templateAnchorHrefEnd">
+
+=item L<templateAnchorNameBegin|"templateAnchorNameBegin">
+
+=item L<templateAnchorNameEnd|"templateAnchorNameEnd">
+
+=back
+
+=back
+
+=head2 Insert options
+
+=over 4
+
+=item L<insertionPoint|"insertionPoint">
+
+=back
+
+=head2 Update options
+
+=over 4
+
+=item L<tokenUpdateBeginAnchorName|"tokenUpdateBeginAnchorName">
+
+=item L<tokenUpdateEndAnchorName|"tokenUpdateEndAnchorName">
+
+=item L<tokenUpdateBeginToc|"tokenUpdateBeginToc">
+
+=item L<tokenUpdateEndToc|"tokenUpdateEndToc">
+
+=item L<tokenUpdateBeginNumber|"tokenUpdateBeginNumber">
+
+=item L<tokenUpdateEndNumber|"tokenUpdateEndNumber">
+
+=back
+
+=head2 Format options
+
+=over 4
+
+=item L<doSingleStepLevel|"doSingleStepLevel">
+
+=item L<doNestGroup|"doNestGroup">
+
+=item L<footer|"footer">
+
+=item L<groupToToc|"groupToToc">
+
+=item L<header|"header">
+
+=item L<levelIndent|"levelIndent">
+
+=item L<levelToToc|"levelToToc">
+
+=item L<templateLevelBegin|"templateLevelBegin">
+
+=item L<templateLevelEnd|"templateLevelEnd">
+
+=back
+
+=head1 HTML::Toc Options Reference
+
+=head2 attributeToExcludeToken
+
+    syntax:  $scalar
+    default: '-'
+
+Token which marks an attribute value in a L<tokenBegin|"tokenBegin"> or L<insertionPoint|"insertionPoint"> token as an attribute value a token should not have to be marked as a ToC token.  See also: L<Using attribute value as ToC entry|"Using attribute value as ToC text">.
+
+=head2 attributeToTocToken
+
+    syntax:  $scalar
+    default: '@'
+
+Token which marks an attribute in a L<tokenBegin|"tokenBegin"> token as an attribute which must be used as ToC text.  See also: L<Using attribute value as ToC entry|"Using attribute value as ToC text">.
+
+=head2 doLinkToToken
+
+    syntax:  [0|1]
+    default: 1
+
+True (1) if ToC must be linked to tokens, False (0) if not.  Note that 'HTML::TocInsertor' must be used to do the actual insertion of the anchor name within the source data.
+
+=head2 doLinkToFile
+
+    syntax:  [0|1]
+    default: 0
+
+True (1) if ToC must be linked to file, False (0) if not.  In effect only when L<doLinkToToken|"doLinkToToken"> equals True (1) and L<templateAnchorHrefBegin|"templateAnchorHrefBegin"> isn't specified.
+
+=head2 doLinkToId
+
+    syntax:  [0|1]
+    default: 0
+
+True (1) if ToC must be linked to tokens by using token ids.  False (0) if ToC must be linked to tokens by using anchor names.
+
+=head2 doNestGroup
+
+    syntax:  [0|1]
+    default: 0
+
+True (1) if groups must be nested in the formatted ToC, False (0) if not.  In effect only when multiple groups are specified within the L<tokenToToc|"tokenToToc"> setting.  For an example, see L<Generate multiple groups in one ToC|"Generate multiple groups in one ToC">.
+
+=head2 doNumberToken
+
+    syntax:  [0|1]
+    default: 0
+
+True (1) if tokens which are used for the ToC generation must be numbered.  This option may be specified both as a global ToC option or within a L<tokenToToc|"tokenToToc"> group.  When specified within a C<tokenToToc> option, the C<doNumberToken> applies to that group only.  For an example, see L<Specify an additional 'Part' group|"Specify an additional 'Part' group">.
+
+=head2 doSingleStepLevel
+
+    syntax:  [0|1]
+    default: 1
+
+True (1) if levels of a formatted ToC must advance one level at a time.  For example, when generating a ToC of a file with a missing '<h2>':
+
+    <h1>Chapter</h1>
+    <h3>Paragraph</h3>
+
+By default, an empty indentation level will be inserted in the ToC:
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1>Header 1</a>
+       <ul>
+          <ul>
+             <li><a href=#h-1.0.1>Header 3</a>
+          </ul>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+After specifying:
+
+    $toc->setOptions({'doSingleStepLevel' => 0});
+
+the ToC will not have an indentation level inserted for level 2:
+
+    <!-- Table of Contents generated by Perl - HTML::Toc -->
+    <ul>
+       <li><a href=#h-1>Header 1</a>
+       <ul>
+             <li><a href=#h-1.0.1>Header 3</a>
+       </ul>
+    </ul>
+    <!-- End of generated Table of Contents -->
+
+=head2 fileSpec
+
+    syntax:  <regexp>
+    default: undef
+
+Specifies which files should match the current level.  Valid only if L<doLinkToFile|"doLinkToFile"> equals 1.  For an example, see L<Site map|"Site map">.
+
+=head2 footer
+
+    syntax:  $scalar
+    default: "\n<!-- End of generated Table of Contents -->\n"
+
+String to output at end of ToC.
+
+=head2 groupId
+
+    syntax:  $scalar
+    default: 'h'
+
+Sets the group id attribute of a tokenGroup.  With this attribute it's possible to divide the ToC into multiple groups.  Each group has its own numbering scheme.  For example, to generate a ToC of both normal headings and 'appendix' headings, specify the following ToC settings:
+
+    $toc->setOptions({
+       'tokenToToc' => [{
+              'tokenBegin' => '<h1 class=-appendix>'
+           }, {
+              'groupId' => 'appendix',
+              'tokenBegin' => '<h1 class=appendix>'
+       }]
+    });
+
+=head2 groupToToc
+
+    syntax:  <regexp>
+    default: '.*'
+
+Determines which groups to use for generating the ToC.  For example, to create a ToC for groups [a-b] only, specify:
+
+    'groupToToc => '[a-b]'
+
+This option is evaluated during both ToC generation and ToC formatting.  This enables you to generate a ToC of all groups, but - after generating - format only specified groups:
+
+    $toc->setOptions({'groupToToc' => '.*'});
+    $tocGenerator->generateToc($toc, ...);
+        # Get ToC of all groups
+    $fullToc = $toc->format();
+        # Get ToC of 'appendix' group only
+    $toc->setOptions({'groupToToc' => 'appendix'});
+    $appendixToc = $toc->format();
+
+=head2 header
+
+    syntax:  $scalar
+    default: "\n<!-- Table of Contents generated by Perl - HTML::Toc -->\n"
+
+String to output at begin of ToC.
+
+
+=head2 insertionPoint
+
+    syntax:  [<before|after|replace>] <token>
+    default: 'after <body>'
+    token:   <[/]tag{ attribute=[-|@]<regexp>}> |
+             <text regexp> |
+             <declaration regexp> |
+             <comment regexp>
+
+Determines the point within the source, where the ToC should be inserted.  When specifying a start tag as the insertion point token, attributes to be included may be specified as well.  Note that the attribute value must be specified as a regular expression.  For example, to specify the C<<h1 class=header>> tag as insertion point:
+
+    '<h1 class=^header$>'
+
+Examples of valid 'insertionPoint' tokens are:
+
+    '<h1>'
+    '</h1>'
+    '<!-- ToC -->'
+    '<!ToC>'
+    'ToC will be placed here'
+
+It is also possible to specify attributes to exclude, by prefixing the value with an L<attributeToExcludeToken|"attributeToExcludeToken">, default a minus sign (-).  For example, to specify the C<<h1>> tag as insertion point, excluding all C<<h1 class=header>> tags:
+
+    '<h1 class=-^header$>'
+
+See also L<tokenBegin|"tokenBegin">.
+
+=head2 level
+
+    syntax:  number
+    default: 1
+
+Number which identifies at which level the tokengroup should be incorporated into the ToC.  See also: L<tokenToToc|"tokenToToc">.
+
+=head2 levelIndent
+
+    syntax:  number
+    default: 3
+
+Sets the number of spaces each level will be indented, when formatting the ToC.
+
+=head2 levelToToc
+
+    syntax:  <regexp>
+    default: '.*'
+
+Determines which group levels to use for generating the ToC.  For example, to create a ToC for levels 1-2 only, specify:
+
+    'levelToToc => '[1-2]'
+
+This option is evaluated during both ToC generation and ToC formatting.  This enables you to generate a ToC of all levels, but - after generating - retrieve only specified levels:
+
+    $toc->setOptions({'levelToToc' => '.*'});
+    $tocGenerator->generateToc($toc, ...);
+        # Get ToC of all levels
+    $fullToc = $toc->getToc();
+        # Get ToC of level 1 only
+    $toc->setOptions({'levelToToc' => '1'});
+    $level1Toc = $toc->getToc();
+
+=head2 numberingStyle
+
+    syntax:  [decimal|lower-alpha|upper-alpha|lower-roman|upper-roman]}
+    default: decimal
+
+Determines which numbering style to use for a token group when L<doLinkToToken|"doLinkToToken"> is set to True (1).  When specified as a main ToC option, the setting will be the default for all groups.  When specified within a tokengroup, this setting will override any default for that particular tokengroup, e.g.:
+
+    $toc->setOptions({
+       'doNumberToken' => 1,
+       'tokenToToc' => [{
+          'level'          => 1,
+          'tokenBegin'     => '<h1>',
+          'numberingStyle' => 'lower-alpha'
+       }]
+    });
+
+If C<roman> style is specified, be sure to have the Roman module installed, available from L<http://www.perl.com/CPAN/modules/by-module/Roman>.
+
+=head2 templateAnchorName
+
+    syntax:  <expression|function reference>
+    default: '$groupId."-".$node'
+
+Anchor name to use when L<doLinkToToken|"doLinkToToken"> is set to True (1).  The anchor name is passed to both L<templateAnchorHrefBegin|"templateAnchorHrefBegin"> and L<templateAnchorNameBegin|"templateAnchorNameBegin">.  The template may be specified as either an expression or a function reference.  The expression may contain the following variables:
+
+    $file
+    $groupId
+    $level
+    $node
+
+If C<templateAnchorHrefBegin> is a function reference to a function returning the anchor, like in:
+
+    $toc->setOptions({'templateAnchorName' => \&assembleAnchorName});
+
+the function will be called with the following arguments:
+
+    $anchorName = assembleAnchorName($file, $groupId, $level, $node);
+
+=head2 templateAnchorHrefBegin
+
+    syntax:  <expression|function reference>
+    default: '"<a href=#$anchorName>"' or
+             '"<a href=$file#$anchorName>"',
+             depending on 'doLinkToFile' being 0 or 1 respectively.
+
+Anchor reference begin token to use when L<doLinkToToken|"doLinkToToken"> is set to True (1).  The template may be specified as either an expression or a function reference.  The expression may contain the following variables:
+
+    $file
+    $groupId
+    $level
+    $node
+    $anchorName
+
+If C<templateAnchorHrefBegin> is a function reference to a function returning the anchor, like in:
+
+    $toc->setOptions({'templateAnchorHrefBegin' => \&assembleAnchorHrefBegin});
+
+the function will be called with the following arguments:
+
+    $anchorHrefBegin = &assembleAnchorHrefBegin(
+       $file, $groupId, $level, $node, $anchorName
+    );
+
+See also: L<templateAnchorName|"templateAnchorName">, L<templateAnchorHrefEnd|"templateAnchorHrefEnd">.
+
+=head2 templateAnchorHrefEnd
+
+    syntax:  <expression|function reference>
+    default: '"</a>"'
+
+Anchor reference end token to use when L<doLinkToToken|"doLinkToToken"> is set to True (1).  The template may be specified as either an expression or a function reference.  If L<templateAnchorHrefEnd|"templateAnchorHrefEnd"> is a function reference to a function returning the anchor end, like in:
+
+    $toc->setOptions({'templateAnchorHrefEnd' => \&assembleAnchorHrefEnd});
+
+the function will be called without arguments:
+
+    $anchorHrefEnd = &assembleAnchorHrefEnd;
+
+See also: L<templateAnchorHrefBegin|"templateAnchorHrefBegin">.
+
+=head2 templateAnchorNameBegin
+
+    syntax:  <expression|function reference>
+    default: '"<a name=$anchorName>"'
+
+Anchor name begin token to use when L<doLinkToToken|"doLinkToToken"> is set to True (1).  The template may be specified as either an expression or a function reference.  The expression may contain the following variables:
+
+    $file
+    $groupId
+    $level
+    $node
+    $anchorName
+
+If C<templateAnchorNameBegin> is a function reference to a function returning the anchor name, like in:
+
+    $toc->setOptions({'templateAnchorNameBegin' => \&assembleAnchorNameBegin});
+
+the function will be called with the following arguments:
+
+    $anchorNameBegin = assembleAnchorNameBegin(
+        $file, $groupId, $level, $node, $anchorName
+    );
+
+See also: L<templateAnchorName|"templateAnchorName">, L<templateAnchorNameEnd|"templateAnchorNameEnd">.
+
+=head2 templateAnchorNameEnd
+
+    syntax:  <expression|function reference>
+    default: '"</a>"'
+
+Anchor name end token to use when L<doLinkToToken|"doLinkToToken"> is set to True (1).  The template may be specified as either an expression or a function reference.  If L<templateAnchorNameEnd|"templateAnchorNameEnd"> is a function reference to a function returning the anchor end, like in:
+
+    $toc->setOptions({'templateAnchorNameEnd' => \&assembleAnchorNameEnd});
+
+the function will be called without arguments:
+
+    $anchorNameEnd = &assembleAnchorNameEnd;
+
+See also: L<templateAnchorNameBegin|"templateAnchorNameBegin">.
+
+=head2 templateLevel
+
+    syntax:  <expression|function reference>
+    default: '"<li>$text\n"'
+
+Expression to use when formatting a ToC node.  The template may be specified as either an expression or a function reference.  The expression may contain the following variables:
+
+    $level
+    $groupId
+    $node
+    $sequenceNr
+    $text
+
+If C<templateLevel> is a function reference to a function returning the ToC node, like in:
+
+    $toc->setOptions({'templateLevel' => \&AssembleTocNode});
+
+the function will be called with the following arguments:
+
+    $tocNode = &AssembleTocNode(
+        $level, $groupId, $node, $sequenceNr, $text
+    );
+
+=head2 templateLevelBegin
+
+    syntax:  <expression>
+    default: '"<ul>\n"'
+
+Expression to use when formatting begin of ToC level.  See L<templateLevel|"templateLevel"> for list of available variables to use within the expression.  For example, to give each ToC level a class name to use with Cascading Style Sheets (CSS), use the expression:
+
+    '"<ul class=toc_$groupId$level>\n"'
+
+which will result in each ToC group being given a class name:
+
+    <ul class=toc_h1>
+       <li>Header
+    </ul>
+
+For an example, see L<Using CSS for ToC formatting|"Using CSS for ToC formatting">.
+
+=head2 templateLevelEnd
+
+    syntax:  <expression>
+    default: '"<ul>\n"'
+
+Expression to use when formatting end of ToC level.  See L<templateLevel|"templateLevel"> for a list of available variables to use within the expression.  The default expression is:
+
+    '"</ul>\n"'
+
+For an example, see L<Using CSS for ToC formatting|"Using CSS for ToC formatting">.
+
+=head2 templateTokenNumber
+
+    syntax:  <expression|function reference>
+    default: '"$node &nbsp;"'
+
+Token number to use when L<doNumberToken|"doNumberToken"> equals True (1).  The template may be specified as either an expression or a function reference.  The expression has access to the following variables:
+
+    $file
+    $groupId
+    $groupLevel
+    $level
+    $node
+    $toc
+
+If C<templateTokenNumber> is a function reference to a function returning the token number, like in:
+
+    $toc->setOptions({'templateTokenNumber' => \&assembleTokenNumber});
+
+the function will be called with the following arguments:
+
+    $number = &assembleTokenNumber(
+        $node, $groupId, $file, $groupLevel, $level, $toc
+    );
+
+=head2 tokenBegin
+
+    syntax:  <token>
+    default: '<h1>'
+    token:   <[/]tag{ attribute=[-|@]<regexp>}> |
+             <text regexp> |
+             <declaration regexp> |
+             <comment regexp>
+
+This scalar defines the token that will trigger text to be put into the ToC.  Any start tag, end tag, comment, declaration or text string can be specified.  Examples of valid 'tokenBegin' tokens are:
+
+    '<h1>'
+    '</end>'
+    '<!-- Start ToC entry -->'
+    '<!Start ToC entry>'
+    'ToC entry'
+
+When specifying a start tag, attributes to be included may be specified as well.  Note that the attribute value is used as a regular expression.  For example, to specify the C<<h1 class=header>> tag as tokenBegin:
+
+    '<h1 class=^header$>'
+
+It is also possible to specify attributes to exclude, by prefixing the value with an L<attributeToExcludeToken|"attributeToExcludeToken">, default a minus sign (-).  For example, to specify the C<<h1>> tag as tokenBegin, excluding all C<<h1 class=header>> tags:
+
+    '<h1 class=-^header$>'
+
+Also, you can specify here an attribute value which has to be used as ToC text, by prefixing the value with an L<attributeToTocToken|"">, default an at sign (@).  For example, to use the class value as ToC text:
+
+    '<h1 class=@>'
+
+See L<Generate multiple ToCs|"Generate multiple ToCs"> for an elaborated example using the C<attributeToTocToken> to generate a ToC of image C<alt> attribute values.
+
+See also: L<tokenEnd|"tokenEnd">, L<tokenToToc|"tokenToToc">.
+
+=head2 tokenEnd
+
+    syntax:  $scalar
+    default: empty string ('') or end tag counterpart of 'tokenBegin' if 
+             'tokenBegin' is a start tag
+
+The 'tokenEnd' definition applies to the same rules as L<tokenBegin|"tokenBegin">.
+
+See also: L<tokenBegin|"tokenBegin">, L<tokenToToc|"tokenToToc">.
+
+=head2 tokenToToc
+
+    syntax:  [{array of hashrefs}]
+    default: [{
+                'level'      => 1,
+                'tokenBegin' => '<h1>'
+             }, {
+                'level'      => 2,
+                'tokenBegin' => '<h2>'
+             }, {
+                'level'      => 3,
+                'tokenBegin' => '<h3>'
+             }, {
+                'level'      => 4,
+                'tokenBegin' => '<h4>'
+             }, {
+                'level'      => 5,
+                'tokenBegin' => '<h5>'
+             }, {
+                'level'      => 6,
+                'tokenBegin' => '<h6>'
+             }]
+
+This hash define the tokens that must act as ToC entries.  Each tokengroup may contain a L<groupId|"groupId">, L<level|"level">, L<numberingStyle|"numberingStyle">, L<tokenBegin|"tokenBegin"> and L<tokenEnd|"tokenEnd"> identifier.
+
+=head2 tokenUpdateBeginAnchorName
+
+    syntax:  <string>
+    default: '<!-- #BeginTocAnchorNameBegin -->';
+
+This token marks the begin of an anchor name, inserted by C<HTML::TocInsertor>.  This option is used by C<HTML::TocUpdator>.
+
+=head2 tokenUpdateEndAnchorName
+
+    syntax:  <string>
+    default: '<!-- #EndTocAnchorName -->';
+
+This option is used by C<HTML::TocUpdator>, to mark the end of an inserted anchor name.
+
+=head2 tokenUpdateBeginNumber
+
+    syntax:  <string>
+    default: '<!-- #BeginTocNumber -->';
+
+This option is used by C<HTML::TocUpdator>, to mark the begin of an inserted number.
+
+=head2 tokenUpdateEndNumber
+
+    syntax:  <string>
+    default: '<!-- #EndTocAnchorName -->';
+
+This option is used by C<HTML::TocUpdator>, to mark the end of an inserted number.
+
+=head2 tokenUpdateBeginToc
+
+    syntax:  <string>
+    default: '<!-- #BeginToc -->';
+
+This option is used by C<HTML::TocUpdator>, to mark the begin of an inserted ToC.
+
+=head2 tokenUpdateEndToc
+
+    syntax:  <string>
+    default: '<!-- #EndToc -->';
+
+This option is used by C<HTML::TocUpdator>, to mark the end of an inserted ToC.
+
+=head1 Known issues
+
+=head2 Cygwin
+
+In order for the test files to run on Cygwin without errors, the 'UNIX' default text file type has to be selected during the Cygwin setup.
+When extracting the tar.gz file with WinZip the 'TAR file smart CR/LF conversion' has to be turned off via {Options|Configuration...|Miscellaneous} in order for the files 'toc.pod' and './manualTest/manualTest1.htm' to be left in UNIX format.
+
+=head2 Nested anchors
+
+HTML::Toc can only link to existing anchors if these anchors are placed outside of the ToC tokens.  Otherwise a warning will be given.  For example, generating a L<linked|"doLinkToToken"> ToC of C<E<lt>h1E<gt>> tokens of the following text:
+
+    <a name=foo><h1>Header</h1></a>
+
+will go all right, whereas:
+
+    <h1><a name=foo>Header</a></h1>
+
+will yield the warning:
+
+    warning (1): Nested anchor '<a name=foo>' within anchor '<a name=h-1>'.
+
+since anchor names aren't allowed to be nested according to the HTML 4.01 specification.
+
+=head1 AUTHOR
+
+Freddy Vulto E<lt>L<"fvu@fvu.myweb.nl">E<gt>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2001 Freddy Vulto.  All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
diff --git a/examples/includes/HTML-Toc-0.91/TocGenerator.pm b/examples/includes/HTML-Toc-0.91/TocGenerator.pm
new file mode 100644 (file)
index 0000000..8c49194
--- /dev/null
@@ -0,0 +1,1793 @@
+#=== HTML::TocGenerator =======================================================
+# function: Generate 'HTML::Toc' table of contents.
+# note:     - 'TT' is an abbrevation of 'TocToken'.
+
+
+package HTML::TocGenerator;
+
+
+use strict;
+use HTML::Parser;
+
+
+BEGIN {
+       use vars qw(@ISA $VERSION);
+
+       $VERSION = '0.91';
+
+       @ISA = qw(HTML::Parser);
+}
+
+
+       # Warnings
+use constant WARNING_NESTED_ANCHOR_PS_WITHIN_PS               => 1;
+use constant WARNING_TOC_ATTRIBUTE_PS_NOT_AVAILABLE_WITHIN_PS => 2;
+
+
+use constant TOC_TOKEN_ID       => 0;
+use constant TOC_TOKEN_INCLUDE  => 1;
+use constant TOC_TOKEN_EXCLUDE  => 2;
+use constant TOC_TOKEN_TOKENS   => 3;
+use constant TOC_TOKEN_GROUP    => 4;
+use constant TOC_TOKEN_TOC      => 5;
+
+       # Token types
+use constant TT_TAG_BEGIN                => 0;
+use constant TT_TAG_END                  => 1;
+use constant TT_TAG_TYPE_END             => 2;
+use constant TT_INCLUDE_ATTRIBUTES_BEGIN => 3;
+use constant TT_EXCLUDE_ATTRIBUTES_BEGIN => 4;
+use constant TT_INCLUDE_ATTRIBUTES_END   => 5;
+use constant TT_EXCLUDE_ATTRIBUTES_END   => 6;
+use constant TT_GROUP                    => 7;
+use constant TT_TOC                      => 8;
+use constant TT_ATTRIBUTES_TOC           => 9;
+
+
+use constant CONTAINMENT_INCLUDE => 0;
+use constant CONTAINMENT_EXCLUDE => 1;
+
+use constant TEMPLATE_ANCHOR            => '$groupId."-".$node';
+use constant TEMPLATE_ANCHOR_HREF       => 
+                                       '"<a href=#".' . TEMPLATE_ANCHOR . '.">"';
+use constant TEMPLATE_ANCHOR_HREF_FILE  => 
+                                       '"<a href=".$file."#".' . TEMPLATE_ANCHOR . '.">"';
+use constant TEMPLATE_ANCHOR_NAME       => 
+                                       '"<a name=".' . TEMPLATE_ANCHOR . '.">"';
+
+use constant TEMPLATE_TOKEN_NUMBER      => '"$node &nbsp"';
+
+
+use constant TT_TOKENTYPE_START        => 0;
+use constant TT_TOKENTYPE_END          => 1;
+use constant TT_TOKENTYPE_TEXT         => 2;
+use constant TT_TOKENTYPE_COMMENT      => 3;
+use constant TT_TOKENTYPE_DECLARATION  => 4;
+
+
+END {}
+
+
+#--- HTML::TocGenerator::new() ------------------------------------------------
+# function: Constructor
+
+sub new {
+               # Get arguments
+       my ($aType) = @_;
+       my $self = $aType->SUPER::new;
+               # Bias to not generate ToC
+       $self->{_doGenerateToc} = 0;
+               # Bias to not use global groups
+       $self->{_doUseGroupsGlobal} = 0;
+               # Output
+       $self->{output} = "";
+               # Reset internal variables
+       $self->_resetBatchVariables();
+
+       $self->{options} = {};
+
+       return $self;
+}  # new()
+
+
+#--- HTML::TocGenerator::_deinitializeBatch() ---------------------------------
+
+sub _deinitializeBatch() {
+               # Get arguments
+       my ($self) = @_;
+}  # _deinitializeBatch()
+
+
+#--- HTML::TocGenerator::_deinitializeExtenderBatch() -------------------------
+
+sub _deinitializeExtenderBatch() {
+               # Get arguments
+       my ($self) = @_;
+               # Do general batch deinitialization
+       $self->_deinitializeBatch();
+               # Indicate end of ToC generation
+       $self->{_doGenerateToc} = 0;
+               # Reset batch variables
+       $self->_resetBatchVariables();
+}  # _deinitializeExtenderBatch()
+
+
+#--- HTML::TocGenerator::_deinitializeGeneratorBatch() ------------------------
+
+sub _deinitializeGeneratorBatch() {
+               # Get arguments
+       my ($self) = @_;
+               # Do 'extender' batch deinitialization
+       $self->_deinitializeExtenderBatch();
+}  # _deinitializeBatchGenerator()
+
+
+#--- HTML::TocGenerator::_doesHashContainHash() -------------------------------
+# function: Determines whether hash1 matches regular expressions of hash2.
+# args:     - $aHash1
+#           - $aHash2
+#           - $aContainmentType: 0 (include) or 1 (exclude)
+# returns:  True (1) if hash1 satisfies hash2, 0 if not.  For example, with the
+#           following hashes:
+#
+#              %hash1 = {                                                      %hash2 = {
+#                 'class' => 'header'                          'class' => '^h'
+#                 'id'    => 'intro'         }
+#              }
+#
+#           the routine will return 1 if 'aContainmentType' equals 0, cause
+#           'hash1' satisfies the conditions of 'hash2'.  The routine will
+#           return 0 if 'aContainmentType' equals 1, cause 'hash1' doesn't
+#           exclude the conditions of 'hash2'.
+# note:     Class function.
+
+sub _doesHashContainHash {
+               # Get arguments
+       my ($aHash1, $aHash2, $aContainmentType) = @_;
+               # Local variables
+       my ($key1, $value1, $key2, $value2, $result);
+               # Bias to success
+       $result = 1;
+               # Loop through hash2
+       HASH2: while (($key2, $value2) = each %$aHash2) {
+               # Yes, values are available;
+                       # Get value1
+               $value1 = $aHash1->{$key2};
+                       # Does value1 match criteria of value2?
+               if (defined($value1) && $value1 =~ m/$value2/) {
+                       # Yes, value1 matches criteria of value2;
+                               # Containment type was exclude?
+                       if ($aContainmentType == CONTAINMENT_EXCLUDE) {
+                               # Yes, containment type was exclude;
+                                       # Indicate condition fails
+                               $result = 0;
+                                       # Reset 'each' iterator which we're going to break
+                               keys %$aHash2;
+                                       # Break loop
+                               last HASH2;
+                       }
+               }
+               else {
+                       # No, value1 didn't match criteria of value2;
+                               # Containment type was include?
+                       if ($aContainmentType == CONTAINMENT_INCLUDE) {
+                               # Yes, containment type was include;
+                                       # Indicate condition fails
+                               $result = 0;
+                                       # Reset 'each' iterator which we're going to break
+                               keys %$aHash2;
+                                       # Break loop
+                               last HASH2;
+                       }
+               }
+       }
+               # Return value
+       return $result;
+}  # _doesHashContainHash()
+
+
+#--- HTML::TocGenerator::_extend() --------------------------------------------
+# function: Extend ToC.
+#           - $aString: String to parse.
+
+sub _extend {
+               # Get arguments
+       my ($self, $aFile) = @_;
+               # Local variables
+       my ($file);
+               # Parse string
+       $self->parse($aFile);
+               # Flush remaining buffered text
+       $self->eof();
+}  # _extend()
+
+
+#--- HTML::TocGenerator::_extendFromFile() ------------------------------------
+# function: Extend ToC.
+#           - $aFile: (reference to array of) file to parse.
+
+sub _extendFromFile {
+               # Get arguments
+       my ($self, $aFile) = @_;
+               # Local variables
+       my ($file, @files);
+               # Dereference array reference or make array of file specification
+       @files = (ref($aFile) =~ m/ARRAY/) ? @$aFile : ($aFile);
+               # Loop through files
+       foreach $file (@files) {
+                       # Store filename
+               $self->{_currentFile} = $file;
+                       # Parse file
+               $self->parse_file($file);
+                       # Flush remaining buffered text
+               $self->eof();
+       }
+}  # _extendFromFile()
+
+
+#--- HTML::TocGenerator::_formatHeadingLevel() --------------------------------
+# function: Format heading level.
+# args:     - $aLevel: Level of current heading
+#           - $aClass: Class of current heading
+#           - $aGroup: Group of current heading
+#           - $aToc: Toc of current heading
+
+sub _formatHeadingLevel {
+               # Get arguments
+       my ($self, $aLevel, $aClass, $aGroup, $aToc) = @_;
+               # Local variables
+       my ($result, $headingNumber, $numberingStyle);
+
+       $headingNumber = $self->_getGroupIdManager($aToc)->
+               {levels}{$aClass}[$aLevel - 1] || 0;
+
+               # Alias numbering style of current group
+       $numberingStyle = $aGroup->{numberingStyle};
+
+       SWITCH: {
+               if ($numberingStyle eq "decimal") {
+                       $result = $headingNumber;
+                       last SWITCH;
+               }
+               if ($numberingStyle eq "lower-alpha") {
+                       $result = chr($headingNumber + ord('a') - 1);
+                       last SWITCH;
+               }
+               if ($numberingStyle eq "upper-alpha") {
+                       $result = chr($headingNumber + ord('A') - 1);
+                       last SWITCH;
+               }
+               if ($numberingStyle eq "lower-roman") {
+                       require Roman;
+                       $result = Roman::roman($headingNumber);
+                       last SWITCH;
+               }
+               if ($numberingStyle eq "upper-roman") {
+                       require Roman;
+                       $result = Roman::Roman($headingNumber);
+                       last SWITCH;
+               }
+               die "Unknown case: $numberingStyle";
+       }
+               # Return value
+       return $result;
+}      # _formatHeadingLevel()
+
+
+#--- HTML::TocGenerator::_formatTocNode() -------------------------------------
+# function: Format heading node.
+# args:     - $aLevel: Level of current heading
+#           - $aClass: Class of current heading
+#           - $aGroup: Group of current heading
+#           - $aToc: Toc of current heading
+
+sub _formatTocNode {
+               # Get arguments
+       my ($self, $aLevel, $aClass, $aGroup, $aToc) = @_;
+               # Local variables
+       my ($result, $level, $levelGroups);
+
+               # Alias 'levelGroups' of right 'groupId'
+       $levelGroups = $aToc->{_levelGroups}{$aGroup->{'groupId'}};
+               # Loop through levels
+       for ($level = 1; $level <= $aLevel; $level++) {
+                       # If not first level, add dot
+               $result = ($result ? $result . "." : $result);
+                       # Format heading level using argument group
+               $result .= $self->_formatHeadingLevel(
+                       $level, $aClass, @{$levelGroups}[$level - 1], $aToc
+               );
+       }
+               # Return value
+       return $result;
+}  # _formatTocNode()
+       
+       
+#--- HTML::TocGenerator::_generate() ------------------------------------------
+# function: Generate ToC.
+# args:     - $aString: Reference to string to parse
+
+sub _generate {
+               # Get arguments
+       my ($self, $aString) = @_;
+               # Local variables
+       my ($toc);
+               # Loop through ToCs
+       foreach $toc (@{$self->{_tocs}}) {
+                       # Clear ToC
+               $toc->clear();
+       }
+               # Extend ToCs
+       $self->_extend($aString);
+}  # _generate()
+
+
+#--- HTML::TocGenerator::_generateFromFile() ----------------------------------
+# function: Generate ToC.
+# args:     - $aFile: (reference to array of) file to parse.
+
+sub _generateFromFile {
+               # Get arguments
+       my ($self, $aFile) = @_;
+               # Local variables
+       my ($toc);
+               # Loop through ToCs
+       foreach $toc (@{$self->{_tocs}}) {
+                       # Clear ToC
+               $toc->clear();
+       }
+               # Extend ToCs
+       $self->_extendFromFile($aFile);
+}  # _generateFromFile()
+
+
+#--- HTML::TocGenerator::_getGroupIdManager() ---------------------------------
+# function: Get group id manager.
+# args:     - $aToc: Active ToC.
+# returns:  Group id levels.
+
+sub _getGroupIdManager {
+               # Get arguments
+       my ($self, $aToc) = @_;
+               # Local variables
+       my ($result);
+               # Global groups?
+       if ($self->{options}{'doUseGroupsGlobal'}) {
+               # Yes, global groups;
+               $result = $self;
+       }
+       else {
+               # No, local groups;
+               $result = $aToc;
+       }
+               # Return value
+       return $result;
+}  # _getGroupIdManager()
+
+
+#--- HTML::TocGenerator::_initializeBatch() -----------------------------------
+# function: Initialize batch.  This function is called once when a parse batch
+#           is started.
+# args:     - $aTocs: Reference to array of tocs.
+
+sub _initializeBatch {
+               # Get arguments
+       my ($self, $aTocs) = @_;
+               # Local variables
+       my ($toc);
+
+               # Store reference to tocs
+               
+               # Is ToC specification reference to array?
+       if (ref($aTocs) =~ m/ARRAY/) {
+               # Yes, ToC specification is reference to array;
+                       # Store array reference
+               $self->{_tocs} = $aTocs;
+       }
+       else {
+               # No, ToC specification is reference to ToC object;
+                       # Wrap reference in array reference, containing only one element
+               $self->{_tocs} = [$aTocs];
+       }
+               # Loop through ToCs
+       foreach $toc (@{$self->{_tocs}}) {
+                       # Parse ToC options
+               $toc->parseOptions();
+       }
+}  # _initializeBatch()
+
+
+#--- HTML::TocGenerator::_initializeExtenderBatch() --------------------------
+# function: Initialize 'extender' batch.  This function is called once when a 
+#           parse batch is started.
+# args:     - $aTocs: Reference to array of tocs.
+
+sub _initializeExtenderBatch {
+               # Get arguments
+       my ($self, $aTocs) = @_;
+               # Do general batch initialization
+       $self->_initializeBatch($aTocs);
+               # Parse ToC options
+       $self->_parseTocOptions();
+               # Indicate start of batch
+       $self->{_doGenerateToc} = 1;
+}  # _initializeExtenderBatch()
+
+
+#--- HTML::TocGenerator::_initializeGeneratorBatch() --------------------------
+# function: Initialize generator batch.  This function is called once when a 
+#           parse batch is started.
+# args:     - $aTocs: Reference to array of tocs.
+#           - $aOptions: optional options
+
+sub _initializeGeneratorBatch {
+               # Get arguments
+       my ($self, $aTocs, $aOptions) = @_;
+               # Add invocation options
+       $self->setOptions($aOptions);
+               # Option 'doUseGroupsGlobal' specified?
+       if (!defined($self->{options}{'doUseGroupsGlobal'})) {
+               # No, options 'doUseGroupsGlobal' not specified;
+                       # Default to no 'doUseGroupsGlobal'
+               $self->{options}{'doUseGroupsGlobal'} = 0;
+       }
+               # Global groups?
+       if ($self->{options}{'doUseGroupsGlobal'}) {
+               # Yes, global groups;
+                       # Reset groups and levels
+               $self->_resetStackVariables();
+       }
+               # Do 'extender' batch initialization
+       $self->_initializeExtenderBatch($aTocs);
+}  # _initializeGeneratorBatch()
+
+
+#--- HTML::TocGenerator::_linkTocToToken() ------------------------------------
+# function: Link ToC to token.
+# args:     - $aToc: ToC to add token to.
+#           - $aFile
+#           - $aGroupId
+#           - $aLevel
+#           - $aNode
+#           - $aGroupLevel
+#           - $aLinkType
+#           - $aTokenAttributes: reference to hash containing attributes of 
+#                currently parsed token
+
+sub _linkTocToToken {
+               # Get arguments
+       my (
+               $self, $aToc, $aFile, $aGroupId, $aLevel, $aNode, $aGroupLevel, 
+               $aDoLinkToId, $aTokenAttributes
+       ) = @_;
+               # Local variables
+       my ($file, $groupId, $level, $node, $anchorName);
+       my ($doInsertAnchor, $doInsertId);
+
+               # Fill local arguments to be used by templates
+       $file    = $aFile;
+       $groupId = $aGroupId;
+       $level   = $aLevel;
+       $node    = $aNode;
+       
+               # Assemble anchor name
+       $anchorName = 
+               ref($aToc->{_templateAnchorName}) eq "CODE" ?
+                       &{$aToc->{_templateAnchorName}}(
+                               $aFile, $aGroupId, $aLevel, $aNode
+                       ) : 
+                       eval($aToc->{_templateAnchorName});
+
+               # Bias to insert anchor name
+       $doInsertAnchor = 1;
+       $doInsertId     = 0;
+               # Link to 'id'?
+       if ($aDoLinkToId) {
+               # Yes, link to 'id';
+                       # Indicate to insert anchor id
+               $doInsertAnchor = 0;
+               $doInsertId     = 1;
+                       # Id attribute is available?
+               if (defined($aTokenAttributes->{id})) {
+                       # Yes, id attribute is available;
+                               # Use existing ids?
+                       if ($aToc->{options}{'doUseExistingIds'}) {
+                               # Yes, use existing ids;
+                                       # Use existing id
+                               $anchorName = $aTokenAttributes->{id};
+                                       # Indicate to not insert id
+                               $doInsertId = 0;
+                       }
+               }
+
+       }
+       else {
+               # No, link to 'name';
+                       # Anchor name is currently active?
+               if (defined($self->{_activeAnchorName})) {
+                       # Yes, anchor name is currently active;
+                               # Use existing anchors?
+                       if ($aToc->{options}{'doUseExistingAnchors'}) {
+                               # Yes, use existing anchors;
+                                       # Use existing anchor name
+                               $anchorName = $self->{_activeAnchorName};
+                                       # Indicate to not insert anchor name
+                               $doInsertAnchor = 0;
+                       }
+                       else {
+                               # No, don't use existing anchors; insert new anchor;
+                                       # 
+                       }
+               }
+       }
+
+               # Add reference to ToC
+       $aToc->{_toc} .= 
+               ref($aToc->{_templateAnchorHrefBegin}) eq "CODE" ?
+                       &{$aToc->{_templateAnchorHrefBegin}}(
+                               $aFile, $aGroupId, $aLevel, $aNode, $anchorName
+                       ) : 
+                       eval($aToc->{_templateAnchorHrefBegin});
+
+               # Bias to not output anchor name end
+       $self->{_doOutputAnchorNameEnd} = 0;
+               # Must anchor be inserted?
+       if ($doInsertAnchor) {
+               # Yes, anchor must be inserted;
+                       # Allow adding of anchor name begin token to text by calling 
+                       # 'anchorNameBegin' method
+               $self->anchorNameBegin(
+                       ref($aToc->{_templateAnchorNameBegin}) eq "CODE" ?
+                               &{$aToc->{_templateAnchorNameBegin}}(
+                                       $aFile, $aGroupId, $aLevel, $aNode, $anchorName
+                               ) :
+                               eval($aToc->{_templateAnchorNameBegin}),
+                       $aToc
+               );
+       }
+
+               # Must anchorId attribute be inserted?
+       if ($doInsertId) {
+               # Yes, anchorId attribute must be inserted;
+                       # Allow adding of anchorId attribute to text by calling 'anchorId'
+                       # method
+               $self->anchorId($anchorName);
+       }
+}  # _linkTocToToken()
+
+
+#--- HTML::TocGenerator::_outputAnchorNameEndConditionally() ------------------
+# function: Output 'anchor name end' if necessary
+# args:     - $aToc: ToC of which 'anchor name end' must be output.
+
+sub _outputAnchorNameEndConditionally {
+               # Get arguments
+       my ($self, $aToc) = @_;
+               # Must anchor name end be output?
+       if ($self->{_doOutputAnchorNameEnd}) {
+               # Yes, output anchor name end;
+                       # Allow adding of anchor to text by calling 'anchorNameEnd' 
+                       # method
+               $self->anchorNameEnd(
+                       ref($aToc->{_templateAnchorNameEnd}) eq "CODE" ?
+                               &{$aToc->{_templateAnchorNameEnd}} :
+                               eval($aToc->{_templateAnchorNameEnd}),
+                       $aToc
+               );
+       }
+}  # _outputAnchorNameEndConditionally()
+
+
+#--- HTML::TocGenerator::_parseTocOptions() -----------------------------------
+# function: Parse ToC options.
+
+sub _parseTocOptions {
+               # Get arguments
+       my ($self) = @_;
+               # Local variables
+       my ($toc, $group, $tokens, $tokenType, $i);
+               # Create parsers for ToC tokens
+       $self->{_tokensTocBegin} = [];
+       my $tokenTocBeginParser = HTML::_TokenTocBeginParser->new(
+               $self->{_tokensTocBegin}
+       );
+       my $tokenTocEndParser = HTML::_TokenTocEndParser->new();
+               # Loop through ToCs
+       foreach $toc (@{$self->{_tocs}}) {
+                       # Reference parser ToC to current ToC
+               $tokenTocBeginParser->setToc($toc);
+                       # Loop through 'tokenToToc' groups
+               foreach $group (@{$toc->{options}{'tokenToToc'}}) {
+                               # Reference parser group to current group
+                       $tokenTocBeginParser->setGroup($group);
+                               # Parse 'tokenToToc' group
+                       $tokenTocBeginParser->parse($group->{'tokenBegin'});
+                               # Flush remaining buffered text
+                       $tokenTocBeginParser->eof();
+                       $tokenTocEndParser->parse(
+                               $group->{'tokenEnd'}, 
+                               $tokenTocBeginParser->{_lastAddedToken},
+                               $tokenTocBeginParser->{_lastAddedTokenType}
+                       );
+                               # Flush remaining buffered text
+                       $tokenTocEndParser->eof();
+               }
+       }
+}  # _parseTocOptions()
+
+
+#--- HTML::TocGenerator::_processTocEndingToken() -----------------------------
+# function: Process ToC-ending-token.
+# args:     - $aTocToken: token which acts as ToC-ending-token.
+
+sub _processTocEndingToken {
+               # Get arguments
+       my ($self, $aTocToken) = @_;
+               # Local variables
+       my ($toc);
+               # Aliases
+       $toc = $aTocToken->[TT_TOC];
+               # Link ToC to tokens?
+       if ($toc->{options}{'doLinkToToken'}) {
+               # Yes, link ToC to tokens;
+                       # Add anchor href end
+               $toc->{_toc} .= 
+                       (ref($toc->{_templateAnchorHrefEnd}) eq "CODE") ?
+                               &{$toc->{_templateAnchorHrefEnd}} : 
+                               eval($toc->{_templateAnchorHrefEnd});
+
+                       # Output anchor name end only if necessary
+               $self->_outputAnchorNameEndConditionally($toc);
+       }
+}  # _processTocEndingToken()
+
+
+#--- HTML::TocGenerator::_processTocStartingToken() ---------------------------
+# function: Process ToC-starting-token.
+# args:     - $aTocToken: token which acts as ToC-starting-token.
+#           - $aTokenType: type of token.  Can be either TT_TOKENTYPE_START,
+#                _END, _TEXT, _COMMENT or _DECLARATION.
+#           - $aTokenAttributes: reference to hash containing attributes of 
+#                currently parsed token
+#           - $aTokenOrigText: reference to original token text
+
+sub _processTocStartingToken {
+               # Get arguments
+       my ($self, $aTocToken, $aTokenType, $aTokenAttributes, $aTokenOrigText) = @_;
+               # Local variables
+       my ($i, $level, $doLinkToId, $node, $groupLevel);
+       my ($file, $tocTokenId, $groupId, $toc, $attribute);
+               # Aliases
+       $file        = $self->{_currentFile};
+       $toc                = $aTocToken->[TT_TOC];
+       $level      = $aTocToken->[TT_GROUP]{'level'};
+       $groupId            = $aTocToken->[TT_GROUP]{'groupId'};
+
+               # Retrieve 'doLinkToId' setting from either group options or toc options
+       $doLinkToId = (defined($aTocToken->[TT_GROUP]{'doLinkToId'})) ?
+               $aTocToken->[TT_GROUP]{'doLinkToId'} : $toc->{options}{'doLinkToId'}; 
+       
+               # Link to 'id' and tokenType isn't 'start'?
+       if (($doLinkToId) && ($aTokenType != TT_TOKENTYPE_START)) {
+               # Yes, link to 'id' and tokenType isn't 'start';
+                       # Indicate to *not* link to 'id'
+               $doLinkToId = 0;
+       }
+
+       if (ref($level) eq "CODE") {
+               $level = &$level($self->{_currentFile}, $node);
+       }
+       if (ref($groupId) eq "CODE") {
+               $groupId = &$groupId($self->{_currentFile}, $node);
+       }
+
+               # Determine class level
+
+       my $groupIdManager = $self->_getGroupIdManager($toc);
+               # Known group?
+       if (!exists($groupIdManager->{groupIdLevels}{$groupId})) {
+               # No, unknown group;
+                       # Add group
+               $groupIdManager->{groupIdLevels}{$groupId} = keys(
+                       %{$groupIdManager->{groupIdLevels}}
+               ) + 1;
+       }
+       $groupLevel = $groupIdManager->{groupIdLevels}{$groupId};
+
+               # Temporarily allow symbolic references
+       #no strict qw(refs);
+               # Increase level
+       $groupIdManager->{levels}{$groupId}[$level - 1] += 1;
+               # Reset remaining levels of same group
+       for ($i = $level; $i < @{$groupIdManager->{levels}{$groupId}}; $i++) {
+               $groupIdManager->{levels}{$groupId}[$i] = 0;
+       }
+
+               # Assemble numeric string indicating current level
+       $node = $self->_formatTocNode(
+               $level, $groupId, $aTocToken->[TT_GROUP], $toc
+       );
+
+               # Add newline if _toc not empty
+       if ($toc->{_toc}) { 
+               $toc->{_toc} .= "\n";
+       }
+
+               # Add toc item info
+       $toc->{_toc} .= "$level $groupLevel $groupId $node " .
+               $groupIdManager->{levels}{$groupId}[$level - 1] . " ";
+
+               # Add value of 'id' attribute if available
+       if (defined($aTokenAttributes->{id})) {
+               $toc->{_toc} .= $aTokenAttributes->{id};
+       }
+       $toc->{_toc} .= " ";
+               # Link ToC to tokens?
+       if ($toc->{options}{'doLinkToToken'}) {
+               # Yes, link ToC to tokens;
+                       # Link ToC to token
+               $self->_linkTocToToken(
+                       $toc, $file, $groupId, $level, $node, $groupLevel, $doLinkToId,
+                       $aTokenAttributes
+               );
+       }
+
+               # Number tokens?
+       if (
+               $aTocToken->[TT_GROUP]{'doNumberToken'} || 
+               (
+                       ! defined($aTocToken->[TT_GROUP]{'doNumberToken'}) && 
+                       $toc->{options}{'doNumberToken'}
+               )
+       ) {
+               # Yes, number tokens;
+                       # Add number by calling 'number' method
+               $self->number(
+                       ref($toc->{_templateTokenNumber}) eq "CODE" ?
+                               &{$toc->{_templateTokenNumber}}(
+                                       $node, $groupId, $file, $groupLevel, $level, $toc
+                               ) : 
+                               eval($toc->{_templateTokenNumber}),
+                       $toc
+               );
+       }
+
+               # Must attribute be used as ToC text?
+       if (defined($aTocToken->[TT_ATTRIBUTES_TOC])) {
+               # Yes, attribute must be used as ToC text;
+                       # Loop through attributes
+               foreach $attribute (@{$aTocToken->[TT_ATTRIBUTES_TOC]}) {
+                               # Attribute is available?
+                       if (defined($$aTokenAttributes{$attribute})) {
+                               # Yes, attribute is available;
+                                       # Add attribute value to ToC
+                               $self->_processTocText($$aTokenAttributes{$attribute}, $toc);
+                       }
+                       else {
+                               # No, attribute isn't available;
+                                       # Show warning
+                               $self->_showWarning(
+                                       WARNING_TOC_ATTRIBUTE_PS_NOT_AVAILABLE_WITHIN_PS,
+                                       [$attribute, $$aTokenOrigText]
+                               );
+                       }
+                               # Output anchor name end only if necessary
+                       #$self->_outputAnchorNameEndConditionally($toc);
+                               # End attribute
+                       $self->_processTocEndingToken($aTocToken);
+               }
+       }
+       else {
+               # No, attribute mustn't be used as ToC text;
+                       # Add end token to 'end token array'
+               push(
+                       @{$self->{_tokensTocEnd}[$aTocToken->[TT_TAG_TYPE_END]]}, $aTocToken
+               );
+       }
+}  # _processTocStartingToken()
+
+
+#--- HTML::TocGenerator::_processTocText() ------------------------------------
+# function: This function processes text which must be added to the preliminary
+#           ToC.
+# args:     - $aText: Text to add to ToC.
+#           - $aToc: ToC to add text to.
+
+sub _processTocText {
+               # Get arguments
+       my ($self, $aText, $aToc) = @_;
+               # Add text to ToC
+       $aToc->{_toc} .= $aText;
+}  # _processTocText()
+
+
+#--- HTML::TocGenerator::_processTokenAsTocEndingToken() ----------------------
+# function: Check for token being a token to use for triggering the end of
+#           a ToC line and process it accordingly.
+# args:     - $aTokenType: type of token: 'start', 'end', 'comment' or 'text'.
+#           - $aTokenId: token id of currently parsed token
+
+sub _processTokenAsTocEndingToken {
+               # Get arguments
+       my ($self, $aTokenType, $aTokenId) = @_;
+               # Local variables
+       my ($i, $tokenId, $toc, $tokens);
+               # Loop through dirty start tokens
+       $i = 0;
+
+               # Alias token array of right type
+       $tokens = $self->{_tokensTocEnd}[$aTokenType];
+               # Loop through token array
+       while ($i < scalar @$tokens) {
+                       # Aliases
+               $tokenId = $tokens->[$i][TT_TAG_END];
+                       # Does current end tag equals dirty tag?
+               if ($aTokenId eq $tokenId) {
+                       # Yes, current end tag equals dirty tag;
+                               # Process ToC-ending-token
+                       $self->_processTocEndingToken($tokens->[$i]);
+                               # Remove dirty tag from array, automatically advancing to
+                               # next token
+                       splice(@$tokens, $i, 1);
+               }
+               else {
+                       # No, current end tag doesn't equal dirty tag;
+                               # Advance to next token
+                       $i++;
+               }
+       }
+}  # _processTokenAsTocEndingToken()
+
+
+#--- HTML::TocGenerator::_processTokenAsTocStartingToken() --------------------
+# function: Check for token being a ToC-starting-token and process it 
+#           accordingly.
+# args:     - $aTokenType: type of token.  Can be either TT_TOKENTYPE_START,
+#                _END, _TEXT, _COMMENT or _DECLARATION.
+#           - $aTokenId: token id of currently parsed token
+#           - $aTokenAttributes: reference to hash containing attributes of 
+#                currently parsed token
+#           - $aTokenOrigText: reference to original text of token
+# returns:  1 if successful, i.e. token is processed as ToC-starting-token, 0
+#           if not.
+
+sub _processTokenAsTocStartingToken {
+               # Get arguments
+       my ($self, $aTokenType, $aTokenId, $aTokenAttributes, $aTokenOrigText) = @_;
+               # Local variables
+       my ($level, $levelToToc, $groupId, $groupToToc);
+       my ($result, $tocToken, $tagBegin, @tokensTocBegin, $fileSpec);
+               # Bias to token not functioning as ToC-starting-token
+       $result = 0;
+               # Loop through start tokens of right type
+       foreach $tocToken (@{$self->{_tokensTocBegin}[$aTokenType]}) {
+                       # Alias file filter
+               $fileSpec = $tocToken->[TT_GROUP]{'fileSpec'};
+                       # File matches?
+               if (!defined($fileSpec) || (
+                       defined($fileSpec) &&
+                       ($self->{_currentFile} =~ m/$fileSpec/)
+               )) {
+                       # Yes, file matches;
+                               # Alias tag begin
+                       $tagBegin = $tocToken->[TT_TAG_BEGIN];
+                               # Tag and attributes match?
+                       if (
+                               defined($tagBegin) && 
+                               ($aTokenId =~ m/$tagBegin/) && 
+                               HTML::TocGenerator::_doesHashContainHash(
+                                       $aTokenAttributes, $tocToken->[TT_INCLUDE_ATTRIBUTES_BEGIN], 0
+                               ) &&
+                               HTML::TocGenerator::_doesHashContainHash(
+                                       $aTokenAttributes, $tocToken->[TT_EXCLUDE_ATTRIBUTES_BEGIN], 1
+                               )
+                       ) {
+                               # Yes, tag and attributes match;
+                                       # Aliases
+                               $level      = $tocToken->[TT_GROUP]{'level'};
+                               $levelToToc = $tocToken->[TT_TOC]{options}{'levelToToc'};
+                               $groupId     = $tocToken->[TT_GROUP]{'groupId'}; 
+                               $groupToToc = $tocToken->[TT_TOC]{options}{'groupToToc'};
+                                       # Must level and group be processed?
+                               if (
+                                       ($level =~ m/$levelToToc/) &&
+                                       ($groupId =~ m/$groupToToc/)
+                               ) {
+                                       # Yes, level and group must be processed;
+                                               # Indicate token acts as ToC-starting-token
+                                       $result = 1;
+                                               # Process ToC-starting-token
+                                       $self->_processTocStartingToken(
+                                               $tocToken, $aTokenType, $aTokenAttributes, $aTokenOrigText
+                                       );
+                               }
+                       }
+               }
+       }
+               # Return value
+       return $result;
+}  # _processTokenAsTocStartingToken()
+
+
+#--- HTML::TocGenerator::_resetBatchVariables() -------------------------------
+# function: Reset variables which are set because of batch invocation.
+
+sub _resetBatchVariables {
+               # Get arguments
+       my ($self) = @_;
+
+               # Filename of current file being parsed, empty string if not available
+       $self->{_currentFile} = "";
+               # Arrays containing start, end, comment, text & declaration tokens which 
+               # must trigger the ToC assembling.  Each array element may contain a 
+               # reference to an array containing the following elements:
+               #
+      #    TT_TAG_BEGIN                => 0;
+      #    TT_TAG_END                  => 1;
+      #    TT_TAG_TYPE_END             => 2;
+      #    TT_INCLUDE_ATTRIBUTES_BEGIN => 3;
+      #    TT_EXCLUDE_ATTRIBUTES_BEGIN => 4;
+      #    TT_INCLUDE_ATTRIBUTES_END   => 5;
+      #    TT_EXCLUDE_ATTRIBUTES_END   => 6;
+      #    TT_GROUP                    => 7;
+      #    TT_TOC                      => 8;
+               #    TT_ATTRIBUTES_TOC           => 9;
+               #
+       $self->{_tokensTocBegin} = [
+               [],  # TT_TOKENTYPE_START      
+               [],  # TT_TOKENTYPE_END        
+               [],  # TT_TOKENTYPE_COMMENT    
+               [],  # TT_TOKENTYPE_TEXT       
+               []   # TT_TOKENTYPE_DECLARATION
+       ];
+       $self->{_tokensTocEnd} = [
+               [],  # TT_TOKENTYPE_START      
+               [],  # TT_TOKENTYPE_END        
+               [],  # TT_TOKENTYPE_COMMENT    
+               [],  # TT_TOKENTYPE_TEXT       
+               []   # TT_TOKENTYPE_DECLARATION
+       ];
+               # TRUE if ToCs have been initialized, FALSE if not.
+       $self->{_doneInitializeTocs} = 0;
+               # Array of ToCs to process
+       $self->{_tocs} = [];
+               # Active anchor name
+       $self->{_activeAnchorName} = undef;
+}  # _resetBatchVariables()
+
+
+#--- HTML::TocGenerator::_resetStackVariables() -------------------------------
+# function: Reset variables which cumulate during ToC generation.
+
+sub _resetStackVariables {
+               # Get arguments
+       my ($self) = @_;
+               # Reset variables
+       $self->{levels}        = undef;
+       $self->{groupIdLevels} = undef;
+}  # _resetStackVariables()
+
+
+#--- HTML::TocGenerator::_setActiveAnchorName() -------------------------------
+# function: Set active anchor name.
+# args:     - aAnchorName: Name of anchor name to set active.
+
+sub _setActiveAnchorName {
+               # Get arguments
+       my ($self, $aAnchorName) = @_;
+               # Set active anchor name
+       $self->{_activeAnchorName} = $aAnchorName;
+}  # _setActiveAnchorName()
+
+
+#--- HTML::TocGenerator::_showWarning() ---------------------------------------
+# function: Show warning.
+# args:     - aWarningNr: Number of warning to show.
+#           - aWarningArgs: Arguments to display within the warning.
+
+sub _showWarning {
+               # Get arguments
+       my ($self, $aWarningNr, $aWarningArgs) = @_;
+               # Local variables
+       my (%warnings);
+               # Set warnings
+       %warnings = (
+               WARNING_NESTED_ANCHOR_PS_WITHIN_PS()               => 
+                       "Nested anchor '%s' within anchor '%s'.", 
+               WARNING_TOC_ATTRIBUTE_PS_NOT_AVAILABLE_WITHIN_PS() =>
+                       "ToC attribute '%s' not available within token '%s'.",
+       );
+               # Show warning
+       print STDERR "warning ($aWarningNr): " . sprintf($warnings{"$aWarningNr"}, @$aWarningArgs) . "\n";
+}  # _showWarning()
+
+
+#--- HTML::TocGenerator::anchorId() -------------------------------------------
+# function: Anchor id processing method.  Leave it up to the descendant to do 
+#           something useful with it.
+# args:     - $aAnchorId
+#           - $aToc: Reference to ToC to which anchorId belongs.
+
+sub anchorId {
+}  # anchorId()
+
+
+#--- HTML::TocGenerator::anchorNameBegin() ------------------------------------
+# function: Anchor name begin processing method.  Leave it up to the descendant
+#           to do something useful with it.
+# args:     - $aAnchorName
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameBegin {
+}  # anchorNameBegin()
+
+
+#--- HTML::TocGenerator::anchorNameEnd() --------------------------------------
+# function: Anchor name end processing method.  Leave it up to the descendant
+#           to do something useful with it.
+# args:     - $aAnchorName
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameEnd {
+}  # anchorNameEnd()
+
+
+#--- HTML::TocGenerator::comment() --------------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Must a ToC be generated?
+       if ($self->{_doGenerateToc}) {
+               # Yes, a ToC must be generated
+                       # Process end tag as ToC-starting-token
+               $self->_processTokenAsTocStartingToken(
+                       TT_TOKENTYPE_COMMENT, $aComment, undef, \$aComment
+               );
+                       # Process end tag as token which ends ToC registration
+               $self->_processTokenAsTocEndingToken(
+                       TT_TOKENTYPE_COMMENT, $aComment
+               );
+       }
+}  # comment()
+
+
+#--- HTML::TocGenerator::end() ------------------------------------------------
+# function: This function is called every time a closing tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aOrigText: tag name including brackets.
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Local variables
+       my ($tag, $toc, $i);
+               # Must a ToC be generated?
+       if ($self->{_doGenerateToc}) {
+               # Yes, a ToC must be generated
+                       # Process end tag as ToC-starting-token
+               $self->_processTokenAsTocStartingToken(
+                       TT_TOKENTYPE_END, $aTag, undef, \$aOrigText
+               );
+                       # Process end tag as ToC-ending-token
+               $self->_processTokenAsTocEndingToken(
+                       TT_TOKENTYPE_END, $aTag
+               );
+                       # Tag is of type 'anchor'?
+               if (defined($self->{_activeAnchorName}) && ($aTag eq "a")) {
+                       # Yes, tag is of type 'anchor';
+                               # Reset dirty anchor
+                       $self->{_activeAnchorName} = undef;
+               }
+       }
+}  # end()
+
+
+#--- HTML::TocGenerator::extend() ---------------------------------------------
+# function: Extend ToCs.
+# args:     - $aTocs: Reference to array of ToC objects
+#           - $aString: String to parse.
+
+sub extend {
+               # Get arguments
+       my ($self, $aTocs, $aString) = @_;
+               # Initialize TocGenerator batch
+       $self->_initializeExtenderBatch($aTocs);
+               # Extend ToCs
+       $self->_extend($aString);
+               # Deinitialize TocGenerator batch
+       $self->_deinitializeExtenderBatch();
+}  # extend()
+
+
+#--- HTML::TocGenerator::extendFromFile() -------------------------------------
+# function: Extend ToCs.
+# args:     - @aTocs: Reference to array of ToC objects
+#           - @aFiles: Reference to array of files to parse.
+
+sub extendFromFile {
+               # Get arguments
+       my ($self, $aTocs, $aFiles) = @_;
+               # Initialize TocGenerator batch
+       $self->_initializeExtenderBatch($aTocs);
+               # Extend ToCs
+       $self->_extendFromFile($aFiles);
+               # Deinitialize TocGenerator batch
+       $self->_deinitializeExtenderBatch();
+}  # extendFromFile()
+
+
+#--- HTML::TocGenerator::generate() -------------------------------------------
+# function: Generate ToC.
+# args:     - $aToc: Reference to (array of) ToC object(s)
+#           - $aString: Reference to string to parse
+#           - $aOptions: optional options
+
+sub generate {
+               # Get arguments
+       my ($self, $aToc, $aString, $aOptions) = @_;
+               # Initialize TocGenerator batch
+       $self->_initializeGeneratorBatch($aToc, $aOptions);
+               # Do generate ToC
+       $self->_generate($aString);
+               # Deinitialize TocGenerator batch
+       $self->_deinitializeGeneratorBatch();
+}  # generate()
+
+
+#--- HTML::TocGenerator::generateFromFile() -----------------------------------
+# function: Generate ToC.
+# args:     - $aToc: Reference to (array of) ToC object(s)
+#           - $aFile: (reference to array of) file to parse.
+#           - $aOptions: optional options
+
+sub generateFromFile {
+               # Get arguments
+       my ($self, $aToc, $aFile, $aOptions) = @_;
+               # Initialize TocGenerator batch
+       $self->_initializeGeneratorBatch($aToc, $aOptions);
+               # Do generate ToC
+       $self->_generateFromFile($aFile);
+               # Deinitialize TocGenerator batch
+       $self->_deinitializeGeneratorBatch();
+}  # generateFromFile()
+
+
+#--- HTML::TocGenerator::number() ---------------------------------------------
+# function: Heading number processing method.  Leave it up to the descendant
+#           to do something useful with it.
+# args:     - $aNumber
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub number {
+               # Get arguments
+       my ($self, $aNumber, $aToc) = @_;
+}  # number()
+
+
+#--- HTML::TocGenerator::parse() ----------------------------------------------
+# function: Parse scalar.
+# args:     - $aString: string to parse
+
+sub parse {
+               # Get arguments
+       my ($self, $aString) = @_;
+               # Call ancestor
+       $self->SUPER::parse($aString);
+}  # parse()
+
+
+#--- HTML::TocGenerator::parse_file() -----------------------------------------
+# function: Parse file.
+
+sub parse_file {
+               # Get arguments
+       my ($self, $aFile) = @_;
+               # Call ancestor
+       $self->SUPER::parse_file($aFile);
+}  # parse_file()
+
+
+#--- HTML::TocGenerator::setOptions() -----------------------------------------
+# function: Set options.
+# args:     - aOptions: Reference to hash containing options.
+
+sub setOptions {
+               # Get arguments
+       my ($self, $aOptions) = @_;
+               # Options are defined?
+       if (defined($aOptions)) {
+               # Yes, options are defined; add to options
+               %{$self->{options}} = (%{$self->{options}}, %$aOptions);
+       }
+}  # setOptions()
+
+
+#--- HTML::TocGenerator::start() ----------------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all tag attributes (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+       $self->{isTocToken} = 0;
+               # Start tag is of type 'anchor name'?
+       if ($aTag eq "a" && defined($aAttr->{name})) {
+               # Yes, start tag is of type 'anchor name';
+                       # Is another anchor already active?
+               if (defined($self->{_activeAnchorName})) {
+                       # Yes, another anchor is already active;
+                               # Is the first anchor inserted by 'TocGenerator'?
+                       if ($self->{_doOutputAnchorNameEnd}) {
+                               # Yes, the first anchor is inserted by 'TocGenerator';
+                                       # Show warning
+                               $self->_showWarning(
+                                       WARNING_NESTED_ANCHOR_PS_WITHIN_PS,
+                                       [$aOrigText, $self->{_activeAnchorName}]
+                               );
+                       }
+               }
+                       # Set active anchor name
+               $self->_setActiveAnchorName($aAttr->{name});
+       }
+               # Must a ToC be generated?
+       if ($self->{_doGenerateToc}) {
+               # Yes, a ToC must be generated
+                       # Process start tag as ToC token
+               $self->{isTocToken} = $self->_processTokenAsTocStartingToken(
+                       TT_TOKENTYPE_START, $aTag, $aAttr, \$aOrigText
+               );
+                       # Process end tag as ToC-ending-token
+               $self->_processTokenAsTocEndingToken(
+                       TT_TOKENTYPE_START, $aTag
+               );
+       }
+}  # start()
+
+
+#--- HTML::TocGenerator::text() -----------------------------------------------
+# function: This function is called every time plain text is encountered.
+# args:     - @_: array containing data.
+
+sub text {
+               # Get arguments
+       my ($self, $aText) = @_;
+               # Local variables
+       my ($text, $toc, $i, $token, $tokens);
+               # Must a ToC be generated?
+       if ($self->{_doGenerateToc}) {
+               # Yes, a ToC must be generated
+                       # Are there dirty start tags?
+
+                       # Loop through token types
+               foreach $tokens (@{$self->{_tokensTocEnd}}) {
+                               # Loop though tokens
+                       foreach $token (@$tokens) {
+                                       # Add text to toc
+
+                                       # Alias
+                               $toc = $token->[TT_TOC];
+                                       # Remove possible newlines from text
+                               ($text = $aText) =~ s/\s*\n\s*/ /g;
+                                       # Add text to toc
+                               $self->_processTocText($text, $toc);
+                       }
+               }
+       }
+}  # text()
+
+
+
+
+#=== HTML::_TokenTocParser ====================================================
+# function: Parse 'toc tokens'.  'Toc tokens' mark HTML code which is to be
+#           inserted into the ToC.
+# note:     Used internally.
+
+package HTML::_TokenTocParser;
+
+
+BEGIN {
+       use vars qw(@ISA);
+
+       @ISA = qw(HTML::Parser);
+}
+
+
+END {}
+
+
+#--- HTML::_TokenTocParser::new() ---------------------------------------------
+# function: Constructor
+
+sub new {
+               # Get arguments
+       my ($aType) = @_;
+               # Create instance
+       my $self = $aType->SUPER::new;
+
+               # Return instance
+       return $self;
+}  # new()
+
+
+#--- HTML::_TokenTocParser::_parseAttributes() --------------------------------
+# function: Parse attributes.
+# args:     - $aAttr: Reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aIncludeAttributes: Reference to hash to which 'include
+#                attributes' must be added.
+#           - $aExcludeAttributes: Reference to hash to which 'exclude
+#                attributes' must be added.
+#           - $aTocAttributes: Reference to hash to which 'ToC attributes' 
+#                must be added.
+
+sub _parseAttributes {
+               # Get arguments
+       my (
+               $self, $aAttr, $aIncludeAttributes, $aExcludeAttributes,
+               $aTocAttributes
+       ) = @_;
+               # Local variables
+       my ($key, $value);
+       my ($attributeToExcludeToken, $attributeToTocToken);
+               # Get token which marks attributes which must be excluded
+       $attributeToExcludeToken = $self->{_toc}{options}{'attributeToExcludeToken'};
+       $attributeToTocToken     = $self->{_toc}{options}{'attributeToTocToken'};
+               # Loop through attributes
+       while (($key, $value) = each %$aAttr) {
+                       # Attribute value equals 'ToC token'?
+               if ($value =~ m/$attributeToTocToken/) {
+                       # Yes, attribute value equals 'ToC token';
+                               # Add attribute to 'ToC attributes'
+                       push @$aTocAttributes, $key;
+               }
+               else {
+                       # No, attribute isn't 'ToC' token;
+                               # Attribute value starts with 'exclude token'?
+                       if ($value =~ m/^$attributeToExcludeToken(.*)/) {
+                               # Yes, attribute value starts with 'exclude token';
+                                       # Add attribute to 'exclude attributes'
+                               $$aExcludeAttributes{$key} = "$1";
+                       }
+                       else {
+                               # No, attribute key doesn't start with '-';
+                                       # Add attribute to 'include attributes'
+                               $$aIncludeAttributes{$key} = $value;
+                       }
+               }
+       }
+}  # _parseAttributes()
+
+
+
+
+#=== HTML::_TokenTocBeginParser ===============================================
+# function: Parse 'toc tokens'.  'Toc tokens' mark HTML code which is to be
+#           inserted into the ToC.
+# note:     Used internally.
+
+package HTML::_TokenTocBeginParser;
+
+
+BEGIN {
+       use vars qw(@ISA);
+
+       @ISA = qw(HTML::_TokenTocParser);
+}
+
+END {}
+
+
+#--- HTML::_TokenTocBeginParser::new() ----------------------------------------
+# function: Constructor
+
+sub new {
+               # Get arguments
+       my ($aType, $aTokenArray) = @_;
+               # Create instance
+       my $self = $aType->SUPER::new;
+               # Reference token array
+       $self->{tokens} = $aTokenArray;
+               # Reference to last added token
+       $self->{_lastAddedToken}     = undef;
+       $self->{_lastAddedTokenType} = undef;
+               # Return instance
+       return $self;
+}  # new()
+
+
+#--- HTML::_TokenTocBeginParser::_processAttributes() -------------------------
+# function: Process attributes.
+# args:     - $aAttributes: Attributes to parse.
+
+sub _processAttributes {
+               # Get arguments
+       my ($self, $aAttributes) = @_;
+               # Local variables
+       my (%includeAttributes, %excludeAttributes, @tocAttributes);
+
+               # Parse attributes
+       $self->_parseAttributes(
+               $aAttributes, \%includeAttributes, \%excludeAttributes, \@tocAttributes
+       );
+               # Include attributes are specified?
+       if (keys(%includeAttributes) > 0) {
+               # Yes, include attributes are specified;
+                       # Store include attributes
+               @${$self->{_lastAddedToken}}[
+                       HTML::TocGenerator::TT_INCLUDE_ATTRIBUTES_BEGIN
+               ] = \%includeAttributes;
+       }
+               # Exclude attributes are specified?
+       if (keys(%excludeAttributes) > 0) {
+               # Yes, exclude attributes are specified;
+                       # Store exclude attributes
+               @${$self->{_lastAddedToken}}[
+                       HTML::TocGenerator::TT_EXCLUDE_ATTRIBUTES_BEGIN
+               ] = \%excludeAttributes;
+       }
+               # Toc attributes are specified?
+       if (@tocAttributes > 0) {
+               # Yes, toc attributes are specified;
+                       # Store toc attributes
+               @${$self->{_lastAddedToken}}[
+                       HTML::TocGenerator::TT_ATTRIBUTES_TOC
+               ] = \@tocAttributes;
+       }
+}  # _processAttributes()
+
+
+#--- HTML::_TokenTocBeginParser::_processToken() ------------------------------
+# function: Process token.
+# args:     - $aTokenType: Type of token to process.
+#           - $aTag: Tag of token.
+
+sub _processToken {
+               # Get arguments
+       my ($self, $aTokenType, $aTag) = @_;
+               # Local variables
+       my ($tokenArray, $index);
+               # Push element on array of update tokens
+       $index = push(@{$self->{tokens}[$aTokenType]}, []) - 1;
+               # Alias token array to add element to
+       $tokenArray = $self->{tokens}[$aTokenType];
+               # Indicate last updated token array element
+       $self->{_lastAddedTokenType} = $aTokenType;
+       $self->{_lastAddedToken}     = \$$tokenArray[$index];
+               # Add fields
+       $$tokenArray[$index][HTML::TocGenerator::TT_TAG_BEGIN] = $aTag;
+       $$tokenArray[$index][HTML::TocGenerator::TT_GROUP]     = $self->{_group};
+       $$tokenArray[$index][HTML::TocGenerator::TT_TOC]       = $self->{_toc};
+}  # _processToken()
+
+
+#--- HTML::_TokenTocBeginParser::comment() ------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_COMMENT, $aComment);
+}  # comment()
+
+
+#--- HTML::_TokenTocBeginParser::declaration() --------------------------------
+# function: This function is called every time a markup declaration is
+#           encountered by HTML::Parser.
+# args:     - $aDeclaration: Markup declaration.
+
+sub declaration {
+               # Get arguments
+       my ($self, $aDeclaration) = @_;
+               # Process token
+       $self->_processToken(
+               HTML::TocGenerator::TT_TOKENTYPE_DECLARATION, $aDeclaration
+       );
+}  # declaration()
+
+       
+#--- HTML::_TokenTocBeginParser::end() ----------------------------------------
+# function: This function is called every time a closing tag is encountered
+#           by HTML::Parser.
+# args:     - $aTag: tag name (in lower case).
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_END, $aTag);
+}  # end()
+
+
+#--- HTML::_TokenTocBeginParser::parse() --------------------------------------
+# function: Parse begin token.
+# args:     - $aToken: 'toc token' to parse
+
+sub parse {
+               # Get arguments
+       my ($self, $aString) = @_;
+               # Call ancestor
+       $self->SUPER::parse($aString);
+}  # parse()
+
+
+#--- HTML::_TokenTocBeginParser->setGroup() -----------------------------------
+# function: Set current 'tokenToToc' group.
+
+sub setGroup {
+               # Get arguments
+       my ($self, $aGroup) = @_;
+               # Set current 'tokenToToc' group
+       $self->{_group} = $aGroup;
+}  # setGroup()
+
+
+#--- HTML::_TokenTocBeginParser->setToc() -------------------------------------
+# function: Set current ToC.
+
+sub setToc {
+               # Get arguments
+       my ($self, $aToc) = @_;
+               # Set current ToC
+       $self->{_toc} = $aToc;
+}  # setToc()
+
+
+#--- HTML::_TokenTocBeginParser::start() --------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all attribute keys (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_START, $aTag);
+               # Process attributes
+       $self->_processAttributes($aAttr);
+}  # start()
+
+
+#--- HTML::_TokenTocBeginParser::text() ---------------------------------------
+# function: This function is called every time plain text is encountered.
+# args:     - @_: array containing data.
+
+sub text {
+               # Get arguments
+       my ($self, $aText) = @_;
+               # Was token already created and is last added token of type 'text'?
+       if (
+               defined($self->{_lastAddedToken}) && 
+               $self->{_lastAddedTokenType} == HTML::TocGenerator::TT_TOKENTYPE_TEXT
+       ) {
+               # Yes, token is already created;
+                       # Add tag to existing token
+               @${$self->{_lastAddedToken}}[HTML::TocGenerator::TT_TAG_BEGIN] .= $aText;
+       }
+       else {
+               # No, token isn't created;
+                       # Process token
+               $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_TEXT, $aText);
+       }
+}  # text()
+
+
+
+
+#=== HTML::_TokenTocEndParser =================================================
+# function: Parse 'toc tokens'.  'Toc tokens' mark HTML code which is to be
+#           inserted into the ToC.
+# note:     Used internally.
+
+package HTML::_TokenTocEndParser;
+
+
+BEGIN {
+       use vars qw(@ISA);
+
+       @ISA = qw(HTML::_TokenTocParser);
+}
+
+
+END {}
+
+
+#--- HTML::_TokenTocEndParser::new() ------------------------------------------
+# function: Constructor
+# args:     - $aType: Class type.
+
+sub new {
+               # Get arguments
+       my ($aType) = @_;
+               # Create instance
+       my $self = $aType->SUPER::new;
+               # Reference to last added token
+       $self->{_lastAddedToken} = undef;
+               # Return instance
+       return $self;
+}  # new()
+
+
+#--- HTML::_TokenTocEndParser::_processAttributes() ---------------------------
+# function: Process attributes.
+# args:     - $aAttributes: Attributes to parse.
+
+sub _processAttributes {
+               # Get arguments
+       my ($self, $aAttributes) = @_;
+               # Local variables
+       my (%includeAttributes, %excludeAttributes);
+
+               # Parse attributes
+       $self->_parseAttributes(
+               $aAttributes, \%includeAttributes, \%excludeAttributes
+       );
+               # Include attributes are specified?
+       if (keys(%includeAttributes) > 0) {
+               # Yes, include attributes are specified;
+                       # Store include attributes
+               @${$self->{_Token}}[
+                       HTML::TocGenerator::TT_INCLUDE_ATTRIBUTES_END
+               ] = \%includeAttributes;
+       }
+               # Exclude attributes are specified?
+       if (keys(%excludeAttributes) > 0) {
+               # Yes, exclude attributes are specified;
+                       # Store exclude attributes
+               @${$self->{_Token}}[
+                       HTML::TocGenerator::TT_EXCLUDE_ATTRIBUTES_END
+               ] = \%excludeAttributes;
+       }
+}  # _processAttributes()
+
+
+#--- HTML::_TokenTocEndParser::_processToken() --------------------------------
+# function: Process token.
+# args:     - $aTokenType: Type of token to process.
+#           - $aTag: Tag of token.
+
+sub _processToken {
+               # Get arguments
+       my ($self, $aTokenType, $aTag) = @_;
+               # Update token
+       @${$self->{_token}}[HTML::TocGenerator::TT_TAG_TYPE_END] = $aTokenType;
+       @${$self->{_token}}[HTML::TocGenerator::TT_TAG_END]      = $aTag;
+               # Indicate token type which has been processed
+       $self->{_lastAddedTokenType} = $aTokenType;
+}  # _processToken()
+
+
+#--- HTML::_TokenTocEndParser::comment() --------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_COMMENT, $aComment);
+}  # comment()
+
+
+#--- HTML::_TokenTocDeclarationParser::declaration() --------------------------
+# function: This function is called every time a markup declaration is
+#           encountered by HTML::Parser.
+# args:     - $aDeclaration: Markup declaration.
+
+sub declaration {
+               # Get arguments
+       my ($self, $aDeclaration) = @_;
+               # Process token
+       $self->_processToken(
+               HTML::TocGenerator::TT_TOKENTYPE_DECLARATION, $aDeclaration
+       );
+}  # declaration()
+
+       
+#--- HTML::_TokenTocEndParser::end() ------------------------------------------
+# function: This function is called every time a closing tag is encountered
+#           by HTML::Parser.
+# args:     - $aTag: tag name (in lower case).
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_END, $aTag);
+}  # end()
+
+
+#--- HTML::_TokenTocEndParser::parse() ----------------------------------------
+# function: Parse token.
+# args:     - $aString: 'toc token' to parse
+#           - $aToken: Reference to token
+#           - $aTokenTypeBegin: Type of begin token
+
+sub parse {
+               # Get arguments
+       my ($self, $aString, $aToken, $aTokenTypeBegin) = @_;
+               # Token argument specified?
+       if (defined($aToken)) {
+               # Yes, token argument is specified;
+                       # Store token reference
+               $self->{_token} = $aToken;
+       }
+               # End tag defined?
+       if (! defined($aString)) {
+               # No, end tag isn't defined;
+                       # Last added tokentype was of type 'start'?
+               if (
+                       (defined($aTokenTypeBegin)) &&
+                       ($aTokenTypeBegin == HTML::TocGenerator::TT_TOKENTYPE_START) 
+               ) {
+                       # Yes, last added tokentype was of type 'start';
+                               # Assume end tag
+                       $self->_processToken(
+                               HTML::TocGenerator::TT_TAG_END,
+                               @${$self->{_token}}[HTML::TocGenerator::TT_TAG_BEGIN]
+                       );
+               }
+       }
+       else {
+                       # Call ancestor
+               $self->SUPER::parse($aString);
+       }
+}  # parse()
+
+
+#--- HTML::_TokenTocEndParser::start() ----------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all attribute keys (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_START, $aTag);
+               # Process attributes
+       $self->_processAttributes($aAttr);
+}  # start()
+
+
+#--- HTML::_TokenTocEndParser::text() -----------------------------------------
+# function: This function is called every time plain text is encountered.
+# args:     - @_: array containing data.
+
+sub text {
+               # Get arguments
+       my ($self, $aText) = @_;
+
+               # Is token already created?
+       if (defined($self->{_lastAddedTokenType})) {
+               # Yes, token is already created;
+                       # Add tag to existing token
+               @${$self->{_token}}[HTML::TocGenerator::TT_TAG_END] .= $aText;
+       }
+       else {
+               # No, token isn't created;
+                       # Process token
+               $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_TEXT, $aText);
+       }
+}  # text()
+
+
+1;
diff --git a/examples/includes/HTML-Toc-0.91/TocInsertor.pm b/examples/includes/HTML-Toc-0.91/TocInsertor.pm
new file mode 100644 (file)
index 0000000..b554870
--- /dev/null
@@ -0,0 +1,1066 @@
+#--- TocInsertor.pm -----------------------------------------------------------
+# function: Insert Table of Contents HTML::Toc, generated by 
+#           HTML::TocGenerator.
+# note:     - The term 'propagate' is used as a shortcut for the process of 
+#             both generating and inserting a ToC at the same time.
+#           - 'TIP' is an abbreviation of 'Toc Insertion Point'.
+
+
+package HTML::TocInsertor;
+
+
+use strict;
+use FileHandle;
+use HTML::TocGenerator;
+
+
+BEGIN {
+       use vars qw(@ISA $VERSION);
+
+       $VERSION = '0.91';
+
+       @ISA = qw(HTML::TocGenerator);
+}
+
+       # TocInsertionPoint (TIP) constants
+       
+use constant TIP_PREPOSITION_REPLACE => 'replace';
+use constant TIP_PREPOSITION_BEFORE  => 'before';
+use constant TIP_PREPOSITION_AFTER   => 'after';
+
+use constant TIP_TOKEN_ID           => 0;
+use constant TIP_PREPOSITION        => 1;
+use constant TIP_INCLUDE_ATTRIBUTES => 2;
+use constant TIP_EXCLUDE_ATTRIBUTES => 3;
+use constant TIP_TOC                => 4;
+
+use constant MODE_DO_NOTHING   => 0;   # 0b00
+use constant MODE_DO_INSERT    => 1;   # 0b01
+use constant MODE_DO_PROPAGATE => 3;   # 0b11
+
+END {}
+
+
+#--- HTML::TocInsertor::new() -------------------------------------------------
+# function: Constructor.
+
+sub new {
+               # Get arguments
+       my ($aType) = @_;
+       my $self = $aType->SUPER::new;
+               # TRUE if insertion point token must be output, FALSE if not
+       $self->{_doOutputInsertionPointToken} = 1;
+               # Reset batch variables
+       $self->_resetBatchVariables;
+               # Bias to not insert ToC
+       $self->{hti__Mode} = MODE_DO_NOTHING;
+
+               # TODO: Initialize output
+
+       return $self;
+}  # new()
+
+
+#--- HTML::TocInsertor::_deinitializeOutput() ---------------------------------
+# function: Deinitialize output.
+
+sub _deinitializeOutput {
+               # Get arguments
+       my ($self) = @_;
+               # Filehandle is defined?
+       if (defined($self->{_outputFileHandle})) {
+               # Yes, filehandle is defined;
+                       # Restore selected filehandle
+               select($self->{_oldFileHandle});
+                       # Undefine filehandle, closing it automatically
+               undef $self->{_outputFileHandle};
+       }
+}  # _deinitializeOutput()
+
+
+#--- HTML::TocInsertor::_initializeOutput() -----------------------------------
+# function: Initialize output.
+
+sub _initializeOutput {
+               # Get arguments
+       my ($self) = @_;
+               # Bias to write to outputfile
+       my $doOutputToFile = 1;
+
+               # Is output specified?
+       if (defined($self->{options}{'output'})) {
+               # Yes, output is specified;
+                       # Indicate to not output to outputfile
+               $doOutputToFile = 0;
+                       # Alias output reference
+               $self->{_output} = $self->{options}{'output'};
+                       # Clear output
+               ${$self->{_output}} = "";
+       }
+
+               # Is output file specified?
+       if (defined($self->{options}{'outputFile'})) {
+               # Yes, output file is specified;
+                       # Indicate to output to outputfile
+               $doOutputToFile = 1;
+                       # Open file
+               $self->{_outputFileHandle} = 
+                       new FileHandle ">" . $self->{options}{'outputFile'};
+
+                       # Backup currently selected filehandle
+               $self->{_oldFileHandle} = select;
+                       # Set new default filehandle
+               select($self->{_outputFileHandle});
+       }
+
+               # Alias output-to-file indicator
+       $self->{_doOutputToFile} = $doOutputToFile;
+}  # _initializeOutput()
+
+
+#--- HTML::TocInsertor::_deinitializeInsertorBatch() --------------------------
+# function: Deinitialize insertor batch.
+
+sub _deinitializeInsertorBatch {
+               # Get arguments
+       my ($self) = @_;
+               # Indicate ToC insertion has finished
+       $self->{_isTocInsertionPointPassed} = 0;
+               # Write buffered output
+       $self->_writeBufferedOutput();
+               # Propagate?
+       if ($self->{hti__Mode} == MODE_DO_PROPAGATE) {
+               # Yes, propagate;
+                       # Deinitialize generator batch
+               $self->_deinitializeGeneratorBatch();
+       }
+       else {
+               # No, insert only;
+                       # Do general batch deinitialization
+               $self->_deinitializeBatch();
+       }
+               # Deinitialize output
+       $self->_deinitializeOutput();
+               # Indicate end of batch
+       $self->{hti__Mode} = MODE_DO_NOTHING;
+               # Reset batch variables
+       $self->_resetBatchVariables();
+}  # _deinitializeInsertorBatch()
+
+
+#--- HTML::TocInsertor::_initializeInsertorBatch() ----------------------------
+# function: Initialize insertor batch.
+# args:     - $aTocs: Reference to array of tocs.
+#           - $aOptions: optional options
+
+sub _initializeInsertorBatch {
+               # Get arguments
+       my ($self, $aTocs, $aOptions) = @_;
+               # Add invocation options
+       $self->setOptions($aOptions);
+               # Option 'doGenerateToc' specified?
+       if (!defined($self->{options}{'doGenerateToc'})) {
+               # No, options 'doGenerateToc' not specified;
+                       # Default to 'doGenerateToc'
+               $self->{options}{'doGenerateToc'} = 1;
+       }
+               # Propagate?
+       if ($self->{options}{'doGenerateToc'}) {
+               # Yes, propagate;
+                       # Indicate mode
+               $self->{hti__Mode} = MODE_DO_PROPAGATE;
+                       # Initialize generator batch
+                       # NOTE: This method takes care of calling '_initializeBatch()'
+               $self->_initializeGeneratorBatch($aTocs);
+       }
+       else {
+               # No, insert;
+                       # Indicate mode
+               $self->{hti__Mode} = MODE_DO_INSERT;
+                       # Do general batch initialization
+               $self->_initializeBatch($aTocs);
+       }
+               # Initialize output
+       $self->_initializeOutput();
+               # Parse ToC insertion points
+       $self->_parseTocInsertionPoints();
+}  # _initializeInsertorBatch()
+
+
+#--- HTML::TocInsertor::_insert() ---------------------------------------------
+# function: Insert ToC in string.
+# args:     - $aString: Reference to string to parse.
+# note:     Used internally.
+
+sub _insert {
+               # Get arguments
+       my ($self, $aString) = @_;
+               # Propagate?
+       if ($self->{options}{'doGenerateToc'}) {
+               # Yes, propagate;
+                       # Generate & insert ToC
+               $self->_generate($aString);
+       }
+       else {
+               # No, just insert ToC
+                       # Insert by parsing file
+               $self->parse($aString);
+                       # Flush remaining buffered text
+               $self->eof();
+       }
+}  # _insert()
+
+
+#--- HTML::TocInsertor::_insertIntoFile() -------------------------------------
+# function: Do insert generated ToCs in file.
+# args:     - $aToc: (reference to array of) ToC object(s) to insert.
+#           - $aFile: (reference to array of) file(s) to parse for insertion
+#                points.
+#           - $aOptions: optional insertor options
+# note:     Used internally.
+
+sub _insertIntoFile {
+               # Get arguments
+       my ($self, $aFile) = @_;
+               # Local variables;
+       my ($file, @files);
+               # Dereference array reference or make array of file specification
+       @files = (ref($aFile) =~ m/ARRAY/) ? @$aFile : ($aFile);
+               # Loop through files
+       foreach $file (@files) {
+                       # Propagate?
+               if ($self->{options}{'doGenerateToc'}) {
+                       # Yes, propagate;
+                               # Generate and insert ToC
+                       $self->_generateFromFile($file);
+               }
+               else {
+                       # No, just insert ToC
+                               # Insert by parsing file
+                       $self->parse_file($file);
+               }
+       }
+}  # _insertIntoFile()
+
+
+#--- HTML::TocInsertor::_parseTocInsertionPoints() ----------------------------
+# function: Parse ToC insertion point specifier.
+
+sub _parseTocInsertionPoints {
+               # Get arguments
+       my ($self) = @_;
+               # Local variables
+       my ($tipPreposition, $tipToken, $toc, $tokenTipParser);
+               # Create parser for TIP tokens
+       $tokenTipParser = HTML::_TokenTipParser->new(
+               $self->{_tokensTip}
+       );
+               # Loop through ToCs
+       foreach $toc (@{$self->{_tocs}}) {
+                       # Split TIP in preposition and token
+               ($tipPreposition, $tipToken) = split(
+                       '\s+', $toc->{options}{'insertionPoint'}, 2
+               );
+                       # Known preposition?
+               if (
+                       ($tipPreposition ne TIP_PREPOSITION_REPLACE) &&
+                       ($tipPreposition ne TIP_PREPOSITION_BEFORE) &&
+                       ($tipPreposition ne TIP_PREPOSITION_AFTER)
+               ) {
+                       # No, unknown preposition;
+                               # Use default preposition
+                       $tipPreposition = TIP_PREPOSITION_AFTER;
+                               # Use entire 'insertionPoint' as token
+                       $tipToken = $toc->{options}{'insertionPoint'};
+               }
+                       # Indicate current ToC to parser
+               $tokenTipParser->setToc($toc);
+                       # Indicate current preposition to parser
+               $tokenTipParser->setPreposition($tipPreposition);
+                       # Parse ToC Insertion Point
+               $tokenTipParser->parse($tipToken);
+                       # Flush remaining buffered text
+               $tokenTipParser->eof();
+       }
+}  # _parseTocInsertionPoints()
+
+
+#--- HTML::TocInsertor::_processTokenAsInsertionPoint() -----------------------
+# function: Check for token being a ToC insertion point (Tip) token and
+#           process it accordingly.
+# args:     - $aTokenType: type of token: start, end, comment or text.
+#           - $aTokenId: token id of currently parsed token
+#           - $aTokenAttributes: attributes of currently parsed token
+#           - $aOrigText: complete token
+# returns:  1 if successful -- token is processed as insertion point, 0
+#           if not.
+
+sub _processTokenAsInsertionPoint {
+               # Get arguments
+       my ($self, $aTokenType, $aTokenId, $aTokenAttributes, $aOrigText) = @_;
+               # Local variables
+       my ($i, $result, $tipToken, $tipTokenId, $tipTokens);
+               # Bias to token not functioning as a ToC insertion point (Tip) token
+       $result = 0;
+               # Alias ToC insertion point (Tip) array of right type
+       $tipTokens = $self->{_tokensTip}[$aTokenType];
+               # Loop through tipTokens
+       $i = 0;
+       while ($i < scalar @{$tipTokens}) {
+                       # Aliases
+               $tipToken                                = $tipTokens->[$i];
+               $tipTokenId                              = $tipToken->[TIP_TOKEN_ID];
+                       # Id & attributes match?
+               if (
+                       ($aTokenId =~ m/$tipTokenId/) && (
+                               HTML::TocGenerator::_doesHashContainHash(
+                                       $aTokenAttributes, $tipToken->[TIP_INCLUDE_ATTRIBUTES], 0
+                               ) &&
+                               HTML::TocGenerator::_doesHashContainHash(
+                                       $aTokenAttributes, $tipToken->[TIP_EXCLUDE_ATTRIBUTES], 1
+                               )
+                       )
+               ) {
+                       # Yes, id and attributes match;
+                               # Process ToC insertion point
+                       $self->_processTocInsertionPoint($tipToken);
+                               # Indicate token functions as ToC insertion point
+                       $result = 1;
+                               # Remove Tip token, automatically advancing to next token
+                       splice(@$tipTokens, $i, 1);
+               }
+               else {
+                       # No, tag doesn't match ToC insertion point
+                               # Advance to next start token
+                       $i++;
+               }
+       }
+               # Token functions as ToC insertion point?
+       if ($result) {
+               # Yes, token functions as ToC insertion point;
+                       # Process insertion point(s)
+               $self->_processTocInsertionPoints($aOrigText);
+       }
+               # Return value
+       return $result;
+}  # _processTokenAsInsertionPoint()
+
+
+#--- HTML::TocInsertor::toc() -------------------------------------------------
+# function: Toc processing method.  Add toc reference to scenario.
+# args:     - $aScenario: Scenario to add ToC reference to.
+#           - $aToc: Reference to ToC to insert.
+# note:     The ToC hasn't been build yet; only a reference to the ToC to be
+#           build is inserted.
+
+sub toc {
+               # Get arguments
+       my ($self, $aScenario, $aToc) = @_;
+               # Add toc to scenario
+       push(@$aScenario, $aToc);
+}  # toc()
+
+
+#--- HTML::TocInsertor::_processTocInsertionPoint() ----------------------------
+# function: Process ToC insertion point.
+# args:     - $aTipToken: Reference to token array item which matches the ToC 
+#                insertion point.
+
+sub _processTocInsertionPoint {
+               # Get arguments
+       my ($self, $aTipToken) = @_;
+               # Local variables
+       my ($tipToc, $tipPreposition); 
+       
+               # Aliases
+       $tipToc         = $aTipToken->[TIP_TOC];
+       $tipPreposition = $aTipToken->[TIP_PREPOSITION];
+
+       SWITCH: {
+                       # Replace token with ToC?
+               if ($tipPreposition eq TIP_PREPOSITION_REPLACE) {
+                       # Yes, replace token;
+                               # Indicate ToC insertion point has been passed
+                       $self->{_isTocInsertionPointPassed} = 1;
+                               # Add ToC reference to scenario reference by calling 'toc' method
+                       $self->toc($self->{_scenarioAfterToken}, $tipToc);
+                       #push(@{$self->{_scenarioAfterToken}}, $tipTokenToc);
+                               # Indicate token itself must not be output
+                       $self->{_doOutputInsertionPointToken} = 0;
+                       last SWITCH;
+               }
+                       # Output ToC before token?
+               if ($tipPreposition eq TIP_PREPOSITION_BEFORE) {
+                       # Yes, output ToC before token;
+                               # Indicate ToC insertion point has been passed
+                       $self->{_isTocInsertionPointPassed} = 1;
+                               # Add ToC reference to scenario reference by calling 'toc' method
+                       $self->toc($self->{_scenarioBeforeToken}, $tipToc);
+                       #push(@{$self->{_scenarioBeforeToken}}, $tipTokenToc);
+                       last SWITCH;
+               }
+                       # Output ToC after token?
+               if ($tipPreposition eq TIP_PREPOSITION_AFTER) {
+                       # Yes, output ToC after token;
+                               # Indicate ToC insertion point has been passed
+                       $self->{_isTocInsertionPointPassed} = 1;
+                               # Add ToC reference to scenario reference by calling 'toc' method
+                       $self->toc($self->{_scenarioAfterToken}, $tipToc);
+                       #push(@{$self->{_scenarioAfterToken}}, $tipTokenToc);
+                       last SWITCH;
+               }
+       }
+}  # _processTocInsertionPoint()
+
+
+#--- HTML::TocInsertor::_processTocInsertionPoints() --------------------------
+# function: Process ToC insertion points
+# args:     - $aTokenText: Text of token which acts as insertion point for one
+#                or multiple ToCs.
+
+sub _processTocInsertionPoints {
+               # Get arguments
+       my ($self, $aTokenText) = @_;
+               # Local variables
+       my ($outputPrefix, $outputSuffix);
+               # Extend scenario
+       push(@{$self->{_scenario}}, @{$self->{_scenarioBeforeToken}});
+
+       if ($outputPrefix = $self->{_outputPrefix}) {
+               push(@{$self->{_scenario}}, \$outputPrefix);
+               $self->{_outputPrefix} = "";
+       }
+
+               # Must insertion point token be output?
+       if ($self->{_doOutputInsertionPointToken}) {
+               # Yes, output insertion point token;
+               push(@{$self->{_scenario}}, \$aTokenText);
+       }
+
+       if ($outputSuffix = $self->{_outputSuffix}) {
+               push(@{$self->{_scenario}}, \$outputSuffix);
+               $self->{_outputSuffix} = "";
+       }
+
+       push(@{$self->{_scenario}}, @{$self->{_scenarioAfterToken}});
+               # Add new act to scenario for output to come
+       my $output = "";
+       push(@{$self->{_scenario}}, \$output);
+               # Write output, processing possible '_outputSuffix'
+       #$self->_writeOrBufferOutput("");
+               # Reset helper scenario's
+       $self->{_scenarioBeforeToken} = [];
+       $self->{_scenarioAfterToken}  = [];
+               # Reset bias value to output insertion point token
+       $self->{_doOutputInsertionPointToken} = 1;
+
+}  # _processTocInsertionPoints()
+
+
+#--- HTML::Toc::_resetBatchVariables() ----------------------------------------
+# function: Reset batch variables.
+
+sub _resetBatchVariables {
+       my ($self) = @_;
+               # Call ancestor
+       $self->SUPER::_resetBatchVariables();
+               # Array containing references to scalars.  This array depicts the order
+               # in which output must be performed after the first ToC Insertion Point
+               # has been passed.
+       $self->{_scenario}            = [];
+               # Helper scenario
+       $self->{_scenarioBeforeToken} = [];
+               # Helper scenario
+       $self->{_scenarioAfterToken}  = [];
+               # Arrays containing start, end, comment, text & declaration tokens which 
+               # must trigger the ToC insertion.  Each array element may contain a 
+               # reference to an array containing the following elements:
+       $self->{_tokensTip} = [
+               [],     # TT_TOKENTYPE_START
+               [],     # TT_TOKENTYPE_END
+               [],     # TT_TOKENTYPE_COMMENT
+               [],     # TT_TOKENTYPE_TEXT
+               []              # TT_TOKENTYPE_DECLARATION
+       ];
+               # 1 if ToC insertion point has been passed, 0 if not
+       $self->{_isTocInsertionPointPassed} = 0;
+               # Tokens after ToC
+       $self->{outputBuffer} = "";
+               # Trailing text after parsed token
+       $self->{_outputSuffix} = "";
+               # Preceding text before parsed token
+       $self->{_outputPrefix} = "";
+}  # _resetBatchVariables()
+
+
+#--- HTML::TocInsertor::_writeBufferedOutput() --------------------------------
+# function: Write buffered output to output device(s).
+
+sub _writeBufferedOutput {
+               # Get arguments
+       my ($self) = @_;
+               # Local variables
+       my ($scene);
+               # Must ToC be parsed?
+       if ($self->{options}{'parseToc'}) {
+               # Yes, ToC must be parsed;
+                       # Parse ToC
+               #$self->parse($self->{toc});
+                       # Output tokens after ToC
+               #$self->_writeOrBufferOutput($self->{outputBuffer});
+       }
+       else {
+               # No, ToC needn't be parsed;
+                       # Output scenario
+               foreach $scene (@{$self->{_scenario}}) {
+                               # Is scene a reference to a scalar?
+                       if (ref($scene) eq "SCALAR") {
+                               # Yes, scene is a reference to a scalar;
+                                       # Output scene
+                               $self->_writeOutput($$scene);
+                       }
+                       else {
+                               # No, scene must be reference to HTML::Toc;
+                                       # Output toc
+                               $self->_writeOutput($scene->format());
+                       }
+               }
+       }
+}  # _writeBufferedOutput()
+
+
+#--- HTML::TocInsertor::_writeOrBufferOutput() --------------------------------
+# function: Write processed HTML to output device(s).
+# args:     - aOutput: scalar to write
+# note:     If '_isTocInsertionPointPassed' text is buffered before being 
+#           output because the ToC has to be generated before it can be output.
+#           Only after the entire data has been parsed, the ToC and the 
+#           following text will be output.
+
+sub _writeOrBufferOutput {
+               # Get arguments
+       my ($self, $aOutput) = @_;
+
+               # Add possible output prefix and suffix
+       $aOutput = $self->{_outputPrefix} . $aOutput . $self->{_outputSuffix};
+               # Clear output prefix and suffix
+       $self->{_outputPrefix} = "";
+       $self->{_outputSuffix} = "";
+
+               # Has ToC insertion point been passed?
+       if ($self->{_isTocInsertionPointPassed}) {
+               # Yes, ToC insertion point has been passed;
+                       # Buffer output; add output to last '_scenario' item
+               my $index = scalar(@{$self->{_scenario}}) - 1;
+               ${$self->{_scenario}[$index]} .= $aOutput;
+       }
+       else {
+               # No, ToC insertion point hasn't been passed;
+                       # Write output
+               $self->_writeOutput($aOutput);
+       }
+}  # _writeOrBufferOutput()
+
+
+#--- HTML::TocInsertor::_writeOutput() ----------------------------------------
+# function: Write processed HTML to output device(s).
+# args:     - aOutput: scalar to write
+
+sub _writeOutput {
+               # Get arguments
+       my ($self, $aOutput) = @_;
+               # Write output to scalar;
+       ${$self->{_output}} .= $aOutput if (defined($self->{_output}));
+               # Write output to output file
+       print $aOutput if ($self->{_doOutputToFile})
+}  # _writeOutput()
+
+
+#--- HTML::TocGenerator::anchorId() -------------------------------------------
+# function: Anchor id processing method.
+# args:     - $aAnchorId
+
+sub anchorId {
+               # Get arguments
+       my ($self, $aAnchorId) = @_;
+               # Indicate id must be added to start tag
+       $self->{_doAddAnchorIdToStartTag} = 1;
+       $self->{_anchorId} = $aAnchorId;
+}  # anchorId()
+
+
+#--- HTML::TocInsertor::anchorNameBegin() -------------------------------------
+# function: Process anchor name begin, generated by HTML::TocGenerator.
+# args:     - $aAnchorNameBegin: Anchor name begin tag to output.
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameBegin {
+               # Get arguments
+       my ($self, $aAnchorNameBegin, $aToc) = @_;
+               # Is another anchorName active?
+       if (defined($self->{_activeAnchorName})) {
+               # Yes, another anchorName is active;
+                       # Show warning
+               print "Warn\n";
+               $self->_showWarning(
+                       HTML::TocGenerator::WARNING_NESTED_ANCHOR_PS_WITHIN_PS,
+                       [$aAnchorNameBegin, $self->{_activeAnchorName}]
+               );
+       }
+               # Store anchor name as output prefix
+       $self->{_outputPrefix} = $aAnchorNameBegin;
+               # Indicate active anchor name
+       $self->{_activeAnchorName} = $aAnchorNameBegin;
+               # Indicate anchor name end must be output
+       $self->{_doOutputAnchorNameEnd} = 1;
+}      # anchorNameBegin()
+
+
+#--- HTML::TocInsertor::anchorNameEnd() ---------------------------------------
+# function: Process anchor name end, generated by HTML::TocGenerator.
+# args:     - $aAnchorNameEnd: Anchor name end tag to output.
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameEnd {
+               # Get arguments
+       my ($self, $aAnchorNameEnd) = @_;
+               # Store anchor name as output prefix
+       $self->{_outputSuffix} .= $aAnchorNameEnd;
+               # Indicate deactive anchor name
+       $self->{_activeAnchorName} = undef;
+}      # anchorNameEnd()
+
+
+#--- HTML::TocInsertor::comment() ---------------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Local variables
+       my ($tocInsertionPointToken, $doOutput, $origText);
+               # Allow ancestor to process the comment tag
+       $self->SUPER::comment($aComment);
+               # Assemble original comment
+       $origText = "<!--$aComment-->";
+               # Must ToCs be inserted?
+       if ($self->{hti__Mode} & MODE_DO_INSERT) {
+               # Yes, ToCs must be inserted;
+                       # Processing comment as ToC insertion point is successful?
+               if (! $self->_processTokenAsInsertionPoint(
+                       HTML::TocGenerator::TT_TOKENTYPE_COMMENT, $aComment, undef, $origText
+               )) {
+                       # No, comment isn't a ToC insertion point;
+                               # Output comment normally
+                       $self->_writeOrBufferOutput($origText);
+               }
+       }
+}  # comment()
+
+
+#--- HTML::TocInsertor::declaration() -----------------------------------------
+# function: This function is called every time a declaration is encountered
+#           by HTML::Parser.
+
+sub declaration {
+               # Get arguments
+       my ($self, $aDeclaration) = @_;
+               # Allow ancestor to process the declaration tag
+       $self->SUPER::declaration($aDeclaration);
+               # Must ToCs be inserted?
+       if ($self->{hti__Mode} & MODE_DO_INSERT) {
+               # Yes, ToCs must be inserted;
+                       # Processing declaration as ToC insertion point is successful?
+               if (! $self->_processTokenAsInsertionPoint(
+                       HTML::TocGenerator::TT_TOKENTYPE_DECLARATION, $aDeclaration, undef, 
+                       "<!$aDeclaration>"
+               )) {
+                       # No, declaration isn't a ToC insertion point;
+                               # Output declaration normally
+                       $self->_writeOrBufferOutput("<!$aDeclaration>");
+               }
+       }
+}  # declaration()
+
+
+#--- HTML::TocInsertor::end() -------------------------------------------------
+# function: This function is called every time a closing tag is encountered
+#           by HTML::Parser.
+# args:     - $aTag: tag name (in lower case).
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Allow ancestor to process the end tag
+       $self->SUPER::end($aTag, $aOrigText);
+               # Must ToCs be inserted?
+       if ($self->{hti__Mode} & MODE_DO_INSERT) {
+               # Yes, ToCs must be inserted;
+                       # Processing end tag as ToC insertion point is successful?
+               if (! $self->_processTokenAsInsertionPoint(
+                       HTML::TocGenerator::TT_TOKENTYPE_END, $aTag, undef, $aOrigText
+               )) {
+                       # No, end tag isn't a ToC insertion point;
+                               # Output end tag normally
+                       $self->_writeOrBufferOutput($aOrigText);
+               }
+       }
+}  # end()
+
+
+#--- HTML::TocInsertor::insert() ----------------------------------------------
+# function: Insert ToC in string.
+# args:     - $aToc: (reference to array of) ToC object to insert
+#           - $aString: string to insert ToC in
+#           - $aOptions: hash reference with optional insertor options
+
+sub insert {
+               # Get arguments
+       my ($self, $aToc, $aString, $aOptions) = @_;
+               # Initialize TocInsertor batch
+       $self->_initializeInsertorBatch($aToc, $aOptions);
+               # Do insert Toc
+       $self->_insert($aString);
+               # Deinitialize TocInsertor batch
+       $self->_deinitializeInsertorBatch();
+}  # insert()
+
+
+#--- HTML::TocInsertor::insertIntoFile() --------------------------------------
+# function: Insert ToCs in file.
+# args:     - $aToc: (reference to array of) ToC object(s) to insert.
+#           - $aFile: (reference to array of) file(s) to parse for insertion
+#                points.
+#           - $aOptions: optional insertor options
+
+sub insertIntoFile {
+               # Get arguments
+       my ($self, $aToc, $aFile, $aOptions) = @_;
+               # Initialize TocInsertor batch
+       $self->_initializeInsertorBatch($aToc, $aOptions);
+               # Do insert ToCs into file
+       $self->_insertIntoFile($aFile);
+               # Deinitialize TocInsertor batch
+       $self->_deinitializeInsertorBatch();
+}  # insertIntoFile()
+
+
+#--- HTML::TocInsertor::number() ----------------------------------------------
+# function: Process heading number generated by HTML::Toc.
+# args:     - $aNumber
+
+sub number {
+               # Get arguments
+       my ($self, $aNumber) = @_;
+               # Store heading number as output suffix
+       $self->{_outputSuffix} .= $aNumber;
+}      # number()
+
+
+#--- HTML::TocInsertor::propagateFile() ---------------------------------------
+# function: Propagate ToC; generate & insert ToC, using file as input.
+# args:     - $aToc: (reference to array of) ToC object to insert
+#           - $aFile: (reference to array of) file to parse for insertion
+#                points.
+#           - $aOptions: optional insertor options
+
+sub propagateFile {
+               # Get arguments
+       my ($self, $aToc, $aFile, $aOptions) = @_;
+               # Local variables;
+       my ($file, @files);
+               # Initialize TocInsertor batch
+       $self->_initializeInsertorBatch($aToc, $aOptions);
+               # Dereference array reference or make array of file specification
+       @files = (ref($aFile) =~ m/ARRAY/) ? @$aFile : ($aFile);
+               # Loop through files
+       foreach $file (@files) {
+                       # Generate and insert ToC
+               $self->_generateFromFile($file);
+       }
+               # Deinitialize TocInsertor batch
+       $self->_deinitializeInsertorBatch();
+}  # propagateFile()
+
+
+#--- HTML::TocInsertor::start() -----------------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all tag attributes (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+               # Local variables
+       my ($doOutput, $i, $tocToken, $tag, $anchorId);
+               # Let ancestor process the start tag
+       $self->SUPER::start($aTag, $aAttr, $aAttrSeq, $aOrigText);
+               # Must ToC be inserted?
+       if ($self->{hti__Mode} & MODE_DO_INSERT) {
+               # Yes, ToC must be inserted;
+                       # Processing start tag as ToC insertion point is successful?
+               if (! $self->_processTokenAsInsertionPoint(
+                       HTML::TocGenerator::TT_TOKENTYPE_START, $aTag, $aAttr, $aOrigText
+               )) {
+                       # No, start tag isn't a ToC insertion point;
+                               # Add anchor id?
+                       if ($self->{_doAddAnchorIdToStartTag}) {
+                               # Yes, anchor id must be added;
+                                       # Reset indicator;
+                               $self->{_doAddAnchorIdToStartTag} = 0;
+                                       # Alias anchor id
+                               $anchorId = $self->{_anchorId};
+                                       # Attribute 'id' already exists?
+                               if (defined($aAttr->{id})) {
+                                       # Yes, attribute 'id' already exists;
+                                               # Show warning
+                                       print STDERR "WARNING: Overwriting existing id attribute '" .
+                                               $aAttr->{id} . "' of tag $aOrigText\n";
+                                       
+                                               # Add anchor id to start tag
+                                       $aOrigText =~ s/(id)=\S*([\s>])/$1=$anchorId$2/i;
+                               }
+                               else {
+                                       # No, attribute 'id' doesn't exist;
+                                               # Add anchor id to start tag
+                                       $aOrigText =~ s/>/ id=$anchorId>/;
+                               }
+                       }
+                               # Output start tag normally
+                       $self->_writeOrBufferOutput($aOrigText);
+               }
+       }
+}  # start()
+
+
+#--- HTML::TocInsertor::text() ------------------------------------------------
+# function: This function is called every time plain text is encountered.
+# args:     - @_: array containing data.
+
+sub text {
+               # Get arguments
+       my ($self, $aText) = @_;
+               # Let ancestor process the text
+       $self->SUPER::text($aText);
+               # Must ToC be inserted?
+       if ($self->{hti__Mode} & MODE_DO_INSERT) {
+               # Yes, ToC must be inserted;
+                       # Processing text as ToC insertion point is successful?
+               if (! $self->_processTokenAsInsertionPoint(
+                       HTML::TocGenerator::TT_TOKENTYPE_TEXT, $aText, undef, $aText
+               )) {
+                       # No, text isn't a ToC insertion point;
+                               # Output text normally
+                       $self->_writeOrBufferOutput($aText);
+               }
+       }
+}  # text()
+
+
+
+
+#=== HTML::_TokenTipParser ====================================================
+# function: Parse 'TIP tokens'.  'TIP tokens' mark HTML code which is to be
+#           used as the ToC Insertion Point.
+# note:     Used internally.
+
+package HTML::_TokenTipParser;
+
+
+BEGIN {
+       use vars qw(@ISA);
+
+       @ISA = qw(HTML::_TokenTocParser);
+}
+
+
+END {}
+
+
+#--- HTML::_TokenTipParser::new() ---------------------------------------------
+# function: Constructor
+
+sub new {
+               # Get arguments
+       my ($aType, $aTokenArray) = @_;
+               # Create instance
+       my $self = $aType->SUPER::new;
+               # Reference token array
+       $self->{tokens} = $aTokenArray;
+               # Reference to last added token
+       $self->{_lastAddedToken}     = undef;
+       $self->{_lastAddedTokenType} = undef;
+               # Return instance
+       return $self;
+}  # new()
+
+
+#--- HTML::_TokenTipParser::_processAttributes() ------------------------------
+# function: Process attributes.
+# args:     - $aAttributes: Attributes to parse.
+
+sub _processAttributes {
+               # Get arguments
+       my ($self, $aAttributes) = @_;
+               # Local variables
+       my (%includeAttributes, %excludeAttributes);
+
+               # Parse attributes
+       $self->_parseAttributes(
+               $aAttributes, \%includeAttributes, \%excludeAttributes
+       );
+               # Include attributes are specified?
+       if (keys(%includeAttributes) > 0) {
+               # Yes, include attributes are specified;
+                       # Store include attributes
+               @${$self->{_lastAddedToken}}[
+                       HTML::TocInsertor::TIP_INCLUDE_ATTRIBUTES
+               ] = \%includeAttributes;
+       }
+               # Exclude attributes are specified?
+       if (keys(%excludeAttributes) > 0) {
+               # Yes, exclude attributes are specified;
+                       # Store exclude attributes
+               @${$self->{_lastAddedToken}}[
+                       HTML::TocInsertor::TIP_EXCLUDE_ATTRIBUTES
+               ] = \%excludeAttributes;
+       }
+}  # _processAttributes()
+
+
+#--- HTML::_TokenTipParser::_processToken() -----------------------------------
+# function: Process token.
+# args:     - $aTokenType: Type of token to process.
+#           - $aTag: Tag of token.
+
+sub _processToken {
+               # Get arguments
+       my ($self, $aTokenType, $aTag) = @_;
+               # Local variables
+       my ($tokenArray, $index);
+               # Push element on array of update tokens
+       $index = push(@{$self->{tokens}[$aTokenType]}, []) - 1;
+               # Alias token array to add element to
+       $tokenArray = $self->{tokens}[$aTokenType];
+               # Indicate last updated token array element
+       $self->{_lastAddedTokenType} = $aTokenType;
+       $self->{_lastAddedToken}     = \$$tokenArray[$index];
+               # Add fields
+       $$tokenArray[$index][HTML::TocInsertor::TIP_TOC]         = $self->{_toc};
+       $$tokenArray[$index][HTML::TocInsertor::TIP_TOKEN_ID]   = $aTag;
+       $$tokenArray[$index][HTML::TocInsertor::TIP_PREPOSITION] =
+               $self->{_preposition};
+}  # _processToken()
+
+
+#--- HTML::_TokenTipParser::comment() -----------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_COMMENT, $aComment);
+}  # comment()
+
+
+#--- HTML::_TokenTipParser::declaration() --------------------------------
+# function: This function is called every time a markup declaration is
+#           encountered by HTML::Parser.
+# args:     - $aDeclaration: Markup declaration.
+
+sub declaration {
+               # Get arguments
+       my ($self, $aDeclaration) = @_;
+               # Process token
+       $self->_processToken(
+               HTML::TocGenerator::TT_TOKENTYPE_DECLARATION, $aDeclaration
+       );
+}  # declaration()
+
+       
+#--- HTML::_TokenTipParser::end() ----------------------------------------
+# function: This function is called every time a closing tag is encountered
+#           by HTML::Parser.
+# args:     - $aTag: tag name (in lower case).
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_END, $aTag);
+}  # end()
+
+
+#--- HTML::_TokenTipParser->setPreposition() ----------------------------------
+# function: Set current preposition.
+
+sub setPreposition {
+               # Get arguments
+       my ($self, $aPreposition) = @_;
+               # Set current ToC
+       $self->{_preposition} = $aPreposition;
+}  # setPreposition()
+
+
+#--- HTML::_TokenTipParser->setToc() ------------------------------------------
+# function: Set current ToC.
+
+sub setToc {
+               # Get arguments
+       my ($self, $aToc) = @_;
+               # Set current ToC
+       $self->{_toc} = $aToc;
+}  # setToc()
+
+
+#--- HTML::_TokenTipParser::start() --------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all attribute keys (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+               # Process token
+       $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_START, $aTag);
+               # Process attributes
+       $self->_processAttributes($aAttr);
+}  # start()
+
+
+#--- HTML::_TokenTipParser::text() ---------------------------------------
+# function: This function is called every time plain text is encountered.
+# args:     - @_: array containing data.
+
+sub text {
+               # Get arguments
+       my ($self, $aText) = @_;
+               # Was token already created and is last added token of type 'text'?
+       if (
+               defined($self->{_lastAddedToken}) && 
+               $self->{_lastAddedTokenType} == HTML::TocGenerator::TT_TOKENTYPE_TEXT
+       ) {
+               # Yes, token is already created;
+                       # Add tag to existing token
+               @${$self->{_lastAddedToken}}[HTML::TocGenerator::TT_TAG_BEGIN] .= $aText;
+       }
+       else {
+               # No, token isn't created;
+                       # Process token
+               $self->_processToken(HTML::TocGenerator::TT_TOKENTYPE_TEXT, $aText);
+       }
+}  # text()
+
+
+1;
diff --git a/examples/includes/HTML-Toc-0.91/TocUpdator.pm b/examples/includes/HTML-Toc-0.91/TocUpdator.pm
new file mode 100644 (file)
index 0000000..affca9d
--- /dev/null
@@ -0,0 +1,693 @@
+#==== HTML::TocUpdator ========================================================
+# function: Update 'HTML::Toc' table of contents.
+# note:     - 'TUT' is an abbreviation of 'Toc Update Token'.
+
+
+package HTML::TocUpdator;
+
+
+use strict;
+use HTML::TocInsertor;
+
+
+BEGIN {
+       use vars qw(@ISA $VERSION);
+
+       $VERSION = '0.91';
+
+       @ISA = qw(HTML::TocInsertor);
+}
+
+
+use constant TUT_TOKENTYPE_START    => 0;
+use constant TUT_TOKENTYPE_END      => 1;
+use constant TUT_TOKENTYPE_TEXT     => 2;
+use constant TUT_TOKENTYPE_COMMENT  => 3;
+
+use constant MODE_DO_NOTHING   => 0;   # 0b00
+use constant MODE_DO_INSERT    => 1;   # 0b01
+use constant MODE_DO_UPDATE    => 3;   # 0b11
+
+
+END {}
+
+
+#--- HTML::TocUpdator::new() --------------------------------------------------
+# function: Constructor.
+
+sub new {
+               # Get arguments
+       my ($aType) = @_;
+       my $self = $aType->SUPER::new;
+               # Bias to not update ToC
+       $self->{htu__Mode} = MODE_DO_NOTHING;
+               # Bias to not delete tokens
+       $self->{_doDeleteTokens} = 0;
+               # Reset batch variables
+       #$self->_resetBatchVariables;
+
+       $self->{options} = {};
+               
+               # TODO: Initialize output
+
+       return $self;
+}  # new()
+
+
+#--- HTML::TocUpdator::_deinitializeUpdatorBatch() --------------------------
+# function: Deinitialize updator batch.
+# args:     - $aTocs: Reference to array of tocs.
+
+sub _deinitializeUpdatorBatch {
+               # Get arguments
+       my ($self, $aTocs) = @_;
+               # Indicate end of ToC updating
+       $self->{htu__Mode} = MODE_DO_NOTHING;
+               # Deinitialize insertor batch
+       $self->_deinitializeInsertorBatch();
+}  # _deinitializeUpdatorBatch()
+
+
+#--- HTML::TokenUpdator::_doesHashEqualHash() ---------------------------------
+# function: Determines whether hash1 equals hash2.
+# args:     - $aHash1
+#           - $aHash2
+# returns:  True (1) if hash1 equals hash2, 0 if not.  For example, with the
+#           following hashes:
+#
+#              %hash1 = {                     %hash2 = {
+#                 'class' => 'header',          'class' => 'header',
+#                 'id'    => 'intro1'           'id'    => 'intro2'
+#              }                             }
+#
+#           the routine will return 0, cause the hash fields 'id' differ.
+# note:     Class function.
+
+sub _doesHashEqualHash {
+               # Get arguments
+       my ($aHash1, $aHash2) = @_;
+               # Local variables
+       my ($key1, $value1, $key2, $value2, $result);
+               # Bias to success
+       $result = 1;
+               # Loop through hash1 while values available
+       HASH1: while (($key1, $value1) = each %$aHash1) {
+               # Yes, values are available;
+                       # Value1 differs from value2?
+               if ($value1 ne $aHash2->{$key1}) {
+                       # Yes, hashes differ;
+                               # Indicate condition fails
+                       $result = 0;
+                               # Reset 'each' iterator which we're going to break
+                       keys %$aHash2;
+                               # Break loop
+                       last HASH1;
+               }
+       }
+               # Return value
+       return $result;
+}  # _doesHashEqualHash()
+
+
+#--- HTML::TokenUpdator::_doesTagExistInArray() -------------------------------
+# function: Check whether tag & attributes matches any of the tags & attributes
+#           in the specified array.  The array must consist of elements with 
+#           format:
+#
+#              [$tag, \%attributes]
+#
+# args:     - $aTag: tag to search for
+#           - $aAttributes: tag attributes to search for
+#           - $aArray: Array to search in.
+# returns:  1 if tag does exist in array, 0 if not.
+# note:     Class function.
+
+sub _doesTagExistInArray {
+               # Get arguments
+       my ($aTag, $aAttributes, $aArray) = @_;
+               # Local variables
+       my ($tag, $result);
+               # Bias to non-existing tag
+       $result = 0;
+               # Loop through existing tags
+       TAG: foreach $tag (@{$aArray}) {
+               if (defined(@{$tag}[0])) {
+                               # Does tag equals any existing tag?
+                       if ($aTag eq @{$tag}[0]) {
+                               # Yes, tag equals existing tag;
+                                       # Do hashes equal?
+                               if (HTML::TocUpdator::_doesHashEqualHash(
+                                       $aAttributes, @{$tag}[1]
+                               )) {
+                                       # Yes, hashes are the same;
+                                               # Indicate tag exists in array
+                                       $result = 1;
+                                               # Break loop
+                                       last TAG;
+                               }
+                       }
+               }
+       }
+               # Return value
+       return $result;
+}  # _doesTagExistInArray()
+
+
+#--- HTML::TocUpdator::_initializeUpdatorBatch() ----------------------------
+# function: Initialize insertor batch.
+# args:     - $aMode: Mode.  Can be either MODE_DO_INSERT or MODE_DO_UPDATE
+#           - $aTocs: Reference to array of tocs.
+#           - $aOptions: optional options
+# note:     Updating actually means: deleting the old ToC and inserting a new
+#           ToC.  That's why we're calling 'insertor' methods here.
+
+sub _initializeUpdatorBatch {
+               # Get arguments
+       my ($self, $aMode, $aTocs, $aOptions) = @_;
+               # Initialize insertor batch
+       $self->_initializeInsertorBatch($aTocs, $aOptions);
+               # Parse ToC update templates
+       $self->_parseTocUpdateTokens();
+               # Indicate start of ToC updating
+       $self->{htu__Mode} = $aMode;
+}  # _initializeUpdatorBatch()
+
+
+#--- HTML::TocUpdator::_parseTocUpdateTokens() --------------------------------
+# function: Parse ToC insertion point specifier.
+
+sub _parseTocUpdateTokens {
+               # Get arguments
+       my ($self) = @_;
+               # Local variables
+       my ($toc, $tokenType, $tokenPreposition, $token);
+       my ($tocInsertionPoint, $tocInsertionPointTokenAttributes);
+               # Create parser for update begin tokens
+       my $tokenUpdateBeginParser = HTML::_TokenUpdateParser->new(
+               $self->{_tokensUpdateBegin}
+       );
+               # Create parser for update end tokens
+       my $tokenUpdateEndParser = HTML::_TokenUpdateParser->new(
+               $self->{_tokensUpdateEnd}
+       );
+
+               # Loop through ToCs
+       foreach $toc (@{$self->{_tocs}}) {
+                       # Parse update tokens
+               $tokenUpdateBeginParser->parse(
+                       $toc->{_tokenUpdateBeginOfAnchorNameBegin}
+               );
+               $tokenUpdateBeginParser->parse($toc->{_tokenUpdateBeginOfAnchorNameEnd});
+               $tokenUpdateBeginParser->parse($toc->{_tokenUpdateBeginNumber});
+               $tokenUpdateBeginParser->parse($toc->{_tokenUpdateBeginToc});
+
+               $tokenUpdateEndParser->parse($toc->{_tokenUpdateEndOfAnchorNameBegin});
+               $tokenUpdateEndParser->parse($toc->{_tokenUpdateEndOfAnchorNameEnd});
+               $tokenUpdateEndParser->parse($toc->{_tokenUpdateEndNumber});
+               $tokenUpdateEndParser->parse($toc->{_tokenUpdateEndToc});
+       }
+}  # _parseTocUpdateTokens()
+
+
+#--- HTML::TocUpdator::_resetBatchVariables() ---------------------------------
+# function: Reset batch variables
+
+sub _resetBatchVariables {
+               # Get arguments
+       my ($self) = @_;
+               # Call ancestor
+       $self->SUPER::_resetBatchVariables();
+               # Arrays containing start, end, comment & text tokens which indicate
+               # the begin of ToC tokens.  The tokens are stored in keys of hashes to 
+               # avoid storing duplicates as an array would.
+       $self->{_tokensUpdateBegin} = [
+               [],     # ['<start tag>', <attributes>]
+               {},     # {'<end tag>' => ''}
+               {},     # {'<text>'    => ''}
+               {}              # {'<comment>' => ''}
+       ];
+               # Arrays containing start, end, comment & text tokens which indicate
+               # the end of ToC tokens.  The tokens are stored in keys of hashes to 
+               # avoid storing duplicates as an array would.
+       $self->{_tokensUpdateEnd} = [
+               [],     # ['<start tag>', <attributes>]
+               {},     # {'<end tag>' => ''}
+               {},     # {'<text>'    => ''}
+               {}              # {'<comment>' => ''}
+       ];
+}  # _resetBatchVariables()
+
+
+#--- HTML::TocUpdator::_setActiveAnchorName() ---------------------------------
+# function: Set active anchor name.
+# args:     - aAnchorName: Name of anchor name to set active.
+
+sub _setActiveAnchorName {
+               # Get arguments
+       my ($self, $aAnchorName) = @_;
+               # Are tokens being deleted?
+       if (! $self->{_doDeleteTokens}) {
+               # No, tokens aren't being deleted;
+                       # Call ancestor to set anchor name
+               $self->SUPER::_setActiveAnchorName($aAnchorName);
+       }
+}  # _setActiveAnchorName()
+
+
+#--- HTML::TocUpdator::_update() ----------------------------------------------
+# function: Update ToC in string.
+# args:     - $aMode: Mode.  Can be either MODE_DO_UPDATE or MODE_DO_INSERT.
+#           - $aToc: (reference to array of) ToC object to update
+#           - $aString: string to update ToC of
+#           - $aOptions: optional updator options
+# note:     Used internally.
+
+sub _update {
+               # Get arguments
+       my ($self, $aMode, $aToc, $aString, $aOptions) = @_;
+               # Initialize TocUpdator batch
+       $self->_initializeUpdatorBatch($aMode, $aToc, $aOptions);
+               # Start updating ToC by starting ToC insertion
+       $self->_insert($aString);
+               # Deinitialize TocUpdator batch
+       $self->_deinitializeUpdatorBatch();
+}  # update()
+
+
+#--- HTML::TocUpdator::_updateFile() ------------------------------------------
+# function: Update ToCs in file.
+# args:     - $aMode: Mode.  Can be either MODE_DO_UPDATE or MODE_DO_INSERT.
+#           - $aToc: (reference to array of) ToC object to update
+#           - $aFile: (reference to array of) file to parse for updating.
+#           - $aOptions: optional updator options
+# note:     Used internally.
+
+sub _updateFile {
+               # Get arguments
+       my ($self, $aMode, $aToc, $aFile, $aOptions) = @_;
+               # Initialize TocUpdator batch
+       $self->_initializeUpdatorBatch($aMode, $aToc, $aOptions);
+               # Start updating ToC by starting ToC insertion
+       $self->_insertIntoFile($aFile);
+               # Deinitialize TocUpdator batch
+       $self->_deinitializeUpdatorBatch();
+}  # _updateFile()
+
+
+#--- HTML::TocUpdator::_writeOrBufferOutput() ---------------------------------
+# function: Write processed HTML to output device(s).
+# args:     - aOutput: scalar to write
+
+sub _writeOrBufferOutput {
+               # Get arguments
+       my ($self, $aOutput) = @_;
+               # Delete output?
+       if (! $self->{_doDeleteTokens}) {
+               # No, don't delete output;
+                       # Call ancestor
+               $self->SUPER::_writeOrBufferOutput($aOutput);
+       }
+}  # _writeOrBufferOutput()
+
+
+#--- HTML::TocUpdator::anchorNameBegin() --------------------------------------
+# function: Process 'anchor name begin' generated by HTML::Toc.
+# args:     - $aAnchorName: Anchor name begin tag to output.
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameBegin {
+               # Get arguments
+       my ($self, $aAnchorNameBegin, $aToc) = @_;
+               # Call ancestor
+       $self->SUPER::anchorNameBegin($aAnchorNameBegin);
+               # Must ToC be inserted or updated?
+       if ($self->{htu__Mode} != MODE_DO_NOTHING) {
+               # Yes, ToC must be inserted or updated;
+                       # Surround anchor name with update tags
+               $self->{_outputPrefix} = 
+                       $aToc->{_tokenUpdateBeginOfAnchorNameBegin} .
+                       $self->{_outputPrefix} . 
+                       $aToc->{_tokenUpdateEndOfAnchorNameBegin};
+       }
+}      # anchorNameBegin()
+
+
+#--- HTML::TocUpdator::anchorNameEnd() ----------------------------------------
+# function: Process 'anchor name end' generated by HTML::Toc.
+# args:     - $aAnchorNameEnd: Anchor name end tag to output.
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub anchorNameEnd {
+               # Get arguments
+       my ($self, $aAnchorNameEnd, $aToc) = @_;
+               # Call ancestor
+       $self->SUPER::anchorNameEnd($aAnchorNameEnd);
+               # Must ToC be inserted or updated?
+       if ($self->{htu__Mode} != MODE_DO_NOTHING) {
+               # Yes, ToC must be inserted or updated;
+                       # Surround anchor name with update tags
+               $self->{_outputSuffix} = 
+                       $aToc->{_tokenUpdateBeginOfAnchorNameEnd} .
+                       $self->{_outputSuffix} . 
+                       $aToc->{_tokenUpdateEndOfAnchorNameEnd};
+       }
+}      # anchorNameEnd()
+
+
+#--- HTML::TocUpdator::comment() ----------------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Must ToC be updated?
+       if ($self->{htu__Mode} == MODE_DO_UPDATE) {
+               # Yes, ToC must be updated;
+                       # Updator is currently deleting tokens?
+               if ($self->{_doDeleteTokens}) {
+                       # Yes, tokens must be deleted;
+                               # Call ancestor
+                       $self->SUPER::comment($aComment);
+
+                               # Look for update end token
+
+                               # Does comment matches update end token?
+                       if (defined(
+                               $self->{_tokensUpdateEnd}[TUT_TOKENTYPE_COMMENT]{$aComment}
+                       )) {
+                               # Yes, comment matches update end token;
+                                       # Indicate to stop deleting tokens
+                               $self->{_doDeleteTokens} = 0;
+                       }
+               }
+               else {
+                       # No, tokens mustn't be deleted;
+
+                               # Look for update begin token
+
+                               # Does comment matches update begin token?
+                       if (defined(
+                               $self->{_tokensUpdateBegin}[TUT_TOKENTYPE_COMMENT]{$aComment}
+                       )) {
+                               # Yes, comment matches update begin token;
+                                       # Indicate to start deleting tokens
+                               $self->{_doDeleteTokens} = 1;
+                       }
+                               # Call ancestor
+                       $self->SUPER::comment($aComment);
+               }
+       }
+       else {
+               # No, ToC mustn't be updated;
+                       # Call ancestor
+               $self->SUPER::comment($aComment);
+       }
+}  # comment()
+
+
+#--- HTML::TocUpdator::end() --------------------------------------------------
+# function: This function is called every time a closing tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aOrigText: tag name including brackets.
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Call ancestor
+       $self->SUPER::end($aTag, $aOrigText);
+               # Must ToC be updated?
+       if ($self->{htu__Mode} == MODE_DO_UPDATE) {
+               # Yes, ToC must be updated;
+                       # Updator is currently deleting tokens?
+               if ($self->{_doDeleteTokens}) {
+                       # Yes, tokens must be deleted;
+                               # Does end tag matches update end token?
+                       if (defined(
+                               $self->{_tokensUpdateEnd}[TUT_TOKENTYPE_END]{$aTag}
+                       )) {
+                               # Yes, end tag matches update end token;
+                                       # Indicate to stop deleting tokens
+                               $self->{_doDeleteTokens} = 0;
+                       }
+               }
+       }
+}  # end()
+
+
+#--- HTML::TocUpdator::insert() -----------------------------------------------
+# function: Insert ToC in string.
+# args:     - $aToc: (reference to array of) ToC object to update
+#           - $aString: string to insert ToC in.
+#           - $aOptions: optional updator options
+
+sub insert {
+               # Get arguments
+       my ($self, $aToc, $aString, $aOptions) = @_;
+               # Do start insert
+       $self->_update(MODE_DO_INSERT, $aToc, $aString, $aOptions);
+}  # insert()
+
+
+#--- HTML::TocUpdator::insertIntoFile() --------------------------------------
+# function: Insert ToC in file.
+# args:     - $aToc: (reference to array of) ToC object to update
+#           - $aFile: File to insert ToC in.
+#           - $aOptions: optional updator options
+
+sub insertIntoFile {
+               # Get arguments
+       my ($self, $aToc, $aFile, $aOptions) = @_;
+               # Do start insert
+       $self->_updateFile(MODE_DO_INSERT, $aToc, $aFile, $aOptions);
+}  # insertIntoFile()
+
+
+#--- HTML::TocUpdator::number() -----------------------------------------------
+# function: Process heading number generated by HTML::Toc.
+# args:     - $aNumber
+#           - $aToc: Reference to ToC to which anchorname belongs.
+
+sub number {
+               # Get arguments
+       my ($self, $aNumber, $aToc) = @_;
+               # Call ancestor
+       $self->SUPER::number($aNumber);
+               # Must ToC be inserted or updated?
+       if ($self->{htu__Mode} != MODE_DO_NOTHING) {
+               # Yes, ToC must be inserted or updated;
+                       # Surround number with update tags
+               $self->{_outputSuffix} = 
+                       $aToc->{_tokenUpdateBeginNumber} .
+                       $self->{_outputSuffix} . 
+                       $aToc->{_tokenUpdateEndNumber};
+       }
+}      # number()
+
+
+#--- HTML::TocUpdator::start() ------------------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all tag attributes (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+               # Must ToC be updated?
+       if ($self->{htu__Mode} == MODE_DO_UPDATE) {
+               # Yes, ToC must be updated;
+                       # Does start tag matches token update begin tag?
+               if (HTML::TocUpdator::_doesTagExistInArray(
+                       $aTag, $aAttr, $self->{_tokensUpdateBegin}[TUT_TOKENTYPE_START]
+               )) {
+                       # Yes, start tag matches token update tag;
+                               # Indicate to delete tokens
+                       $self->{_doDeleteTokens} = 1;
+               }
+       }
+               # Let ancestor process the start tag
+       $self->SUPER::start($aTag, $aAttr, $aAttrSeq, $aOrigText);
+}  # start()
+
+
+#--- HTML::TocUpdator::toc() --------------------------------------------------
+# function: Toc processing method.  Add toc reference to scenario.
+# args:     - $aScenario: Scenario to add ToC reference to.
+#           - $aToc: Reference to ToC to insert.
+# note:     The ToC hasn't been build yet; only a reference to the ToC to be
+#           build is inserted.
+
+sub toc {
+               # Get arguments
+       my ($self, $aScenario, $aToc) = @_;
+
+               # Surround toc with update tokens
+
+               # Add update begin token
+       push(@$aScenario, \$aToc->{_tokenUpdateBeginToc});
+               # Call ancestor
+       $self->SUPER::toc($aScenario, $aToc);
+               # Add update end token
+       push(@$aScenario, \$aToc->{_tokenUpdateEndToc});
+}  # toc()
+
+
+#--- HTML::TocUpdator::_processTocText() --------------------------------------
+# function: Toc text processing function.
+# args:     - $aText: Text to add to ToC.
+#           - $aToc: ToC to add text to.
+
+sub _processTocText {
+               # Get arguments
+       my ($self, $aText, $aToc) = @_;
+               # Delete output?
+       if (! $self->{_doDeleteTokens}) {
+               # No, don't delete output;
+                       # Call ancestor
+               $self->SUPER::_processTocText($aText, $aToc);
+       }
+}  # _processTocText()
+
+
+#--- HTML::TocUpdator::update() -----------------------------------------------
+# function: Update ToC in string.
+# args:     - $aToc: (reference to array of) ToC object to update
+#           - $aString: string to update ToC of
+#           - $aOptions: optional updator options
+
+sub update {
+               # Get arguments
+       my ($self, $aToc, $aString, $aOptions) = @_;
+               # Do start update
+       $self->_update(MODE_DO_UPDATE, $aToc, $aString, $aOptions);
+}  # update()
+
+
+#--- HTML::TocUpdator::updateFile() -------------------------------------------
+# function: Update ToC of file.
+# args:     - $aToc: (reference to array of) ToC object to update
+#           - $aFile: (reference to array of) file to parse for updating.
+#           - $aOptions: optional updator options
+
+sub updateFile {
+               # Get arguments
+       my ($self, $aToc, $aFile, $aOptions) = @_;
+               # Do start update
+       $self->_updateFile(MODE_DO_UPDATE, $aToc, $aFile, $aOptions);
+}  # update()
+
+
+
+
+#=== HTML::_TokenUpdateParser =================================================
+# function: Parse 'update tokens'.  'Update tokens' mark HTML code which is
+#           inserted by 'HTML::TocInsertor'.
+# note:     Used internally.
+
+package HTML::_TokenUpdateParser;
+
+
+BEGIN {
+       use vars qw(@ISA);
+
+       @ISA = qw(HTML::Parser);
+}
+
+END {}
+
+
+#--- HTML::_TokenUpdateParser::new() ------------------------------------------
+# function: Constructor
+
+sub new {
+               # Get arguments
+       my ($aType, $aTokenArray) = @_;
+               # Create instance
+       my $self = $aType->SUPER::new;
+               # Reference token array
+       $self->{tokens} = $aTokenArray;
+               # Return instance
+       return $self;
+}  # new()
+
+
+#--- HTML::_TokenUpdateParser::comment() --------------------------------------
+# function: Process comment.
+# args:     - $aComment: comment text with '<!--' and '-->' tags stripped off.
+
+sub comment {
+               # Get arguments
+       my ($self, $aComment) = @_;
+               # Add token to array of update tokens
+       $self->{tokens}[HTML::TocUpdator::TUT_TOKENTYPE_COMMENT]{$aComment} = '';
+}  # comment()
+
+
+#--- HTML::_TokenUpdateParser::end() ------------------------------------------
+# function: This function is called every time a closing tag is encountered
+#           by HTML::Parser.
+# args:     - $aTag: tag name (in lower case).
+
+sub end {
+               # Get arguments
+       my ($self, $aTag, $aOrigText) = @_;
+               # Add token to array of update tokens
+       $self->{tokens}[HTML::TocUpdator::TUT_TOKENTYPE_END]{$aTag} = '';
+}  # end()
+
+
+#--- HTML::_TokenUpdateParser::parse() ----------------------------------------
+# function: Parse token.
+# args:     - $aToken: 'update token' to parse
+
+sub parse {
+               # Get arguments
+       my ($self, $aString) = @_;
+               # Call ancestor
+       $self->SUPER::parse($aString);
+}  # parse()
+
+
+#--- HTML::_TokenUpdateParser::start() ----------------------------------------
+# function: This function is called every time an opening tag is encountered.
+# args:     - $aTag: tag name (in lower case).
+#           - $aAttr: reference to hash containing all tag attributes (in lower
+#                case).
+#           - $aAttrSeq: reference to array containing all tag attributes (in 
+#                lower case) in the original order
+#           - $aOrigText: the original HTML text
+
+sub start {
+               # Get arguments
+       my ($self, $aTag, $aAttr, $aAttrSeq, $aOrigText) = @_;
+               # Does token exist in array?
+       if (! HTML::TocUpdator::_doesTagExistInArray(
+               $aTag, $aAttr, $self->{tokens}[HTML::TocUpdator::TUT_TOKENTYPE_START]
+       )) {
+               # No, token doesn't exist in array;
+                       # Add token to array of update tokens
+               push(
+                       @{$self->{tokens}[HTML::TocUpdator::TUT_TOKENTYPE_START]},
+                       [$aTag, $aAttr]
+               );
+       }
+}  # start()
+
+
+#--- HTML::_TokenUpdateParser::text() -----------------------------------------
+# function: This function is called every time plain text is encountered.
+# args:     - @_: array containing data.
+
+sub text {
+               # Get arguments
+       my ($self, $aText) = @_;
+               # Add token to array of update tokens
+       $self->{tokens}[HTML::TocUpdator::TUT_TOKENTYPE_TEXT]{$aText} = '';
+}  # text()
+
+
+1;
diff --git a/examples/includes/HTML-Toc-0.91/t/ManualTest/manualTest1.htm b/examples/includes/HTML-Toc-0.91/t/ManualTest/manualTest1.htm
new file mode 100644 (file)
index 0000000..1bd250f
--- /dev/null
@@ -0,0 +1,92 @@
+<html>
+<head>
+   <title>Manual</title>
+    <style type="text/css">
+       ul.toc_appendix1 { 
+         list-style-type: none;
+         margin-left: 0;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h2 {
+         list-style-type: none;
+       }
+       ul.toc_h3 {
+         list-style-type: none;
+       }
+       ul.toc_part1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_prelude1 {
+         list-style: none;
+       }
+       p.captionFigure {
+         font-style: italic;
+         font-weight: bold;
+       }
+       p.captionTable {
+         font-style: italic;
+         font-weight: bold;
+       }
+    </style>
+</head>
+<body>
+
+<h1 class=prelude>Preface</h1>
+Better C than never.
+
+<h1 class=hidden>Table of Contents</h1>
+<!-- Table of Contents -->
+
+<h1 class=prelude>Table of Figures</h1>
+<!-- Table of Figures -->
+
+<h1 class=prelude>Table of Tables</h1>
+<!-- Table of Tables -->
+
+<h1 class=prelude>Introduction</h1>
+Thanks to standardisation and the excellent work of the QWERTY corporation it is possible to learn C with almost any C manual.
+<p class=captionTable>Compile Steps</p>
+<ul><pre>
+   Parser
+   Compiler
+   Linker
+</pre></ul>
+
+<h1 class=part>Disks</h1>
+<h1>Compiler Disk v1</h1>
+<img src=img.gif alt="Contents Compiler Disk v1">
+<p class=captionFigure>Contents Compiler Disk v1</p>
+
+<h2>System</h2>
+<h2>Standard Library</h2>
+
+<h1>Compiler Disk v2</h1>
+<img src=img.gif alt="Contents Compiler Disk v2">
+<p class=captionFigure>Contents Compiler Disk v2</p>
+
+<h2>System</h2>
+<h3>parser.com</h3>
+<h3>compiler.com</h3>
+<h3>linker.com</h3>
+<h2>Standard Library</h2>
+
+<h1>Library System Disk</h1>
+<h1 class=part>Personal</h1>
+<h1>Tips & Tricks</h1>
+<h1 class=part>Appendixes</h1>
+<h1 class=appendix>Functions Standard Library v1</h1>
+<h1 class=appendix>Functions Standard Library v2</h1>
+<h1 class=appendix>Functions Graphic Library</h1>
+<h1 class=prelude>Bibliography</h1>
+</body>
+</html>
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir1/SubSubDir1/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir1/SubSubDir1/index.htm
new file mode 100644 (file)
index 0000000..5288cde
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>SubSub1</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir1/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir1/index.htm
new file mode 100644 (file)
index 0000000..c938212
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>Sub1</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/SubSubDir1/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/SubSubDir1/index.htm
new file mode 100644 (file)
index 0000000..5288cde
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>SubSub1</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/SubSubDir2/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/SubSubDir2/index.htm
new file mode 100644 (file)
index 0000000..eaadf8c
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>SubSub2</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir2/index.htm
new file mode 100644 (file)
index 0000000..8445eb1
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>Sub2</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir3/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/SubDir3/index.htm
new file mode 100644 (file)
index 0000000..cf9aa99
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>Sub3</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/SiteMap/index.htm b/examples/includes/HTML-Toc-0.91/t/SiteMap/index.htm
new file mode 100644 (file)
index 0000000..864b0b5
--- /dev/null
@@ -0,0 +1,5 @@
+<html>\r
+<head>\r
+<title>Main</title>\r
+</head>\r
+</html>\r
diff --git a/examples/includes/HTML-Toc-0.91/t/extend.t b/examples/includes/HTML-Toc-0.91/t/extend.t
new file mode 100644 (file)
index 0000000..fe9daee
--- /dev/null
@@ -0,0 +1,87 @@
+#--- generate.t ---------------------------------------------------------------
+# function: Test ToC generation.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 4; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+
+my ($filename);
+my $toc          = HTML::Toc->new;
+my $tocGenerator = HTML::TocGenerator->new;
+
+$toc->setOptions({
+       'doLinkToToken' => 0,
+       'levelIndent'       => 0,
+       'header'            => '',
+       'footer'            => '',
+});
+
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT';
+<h1>Header</h1>
+EOT
+       close(FILE);
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- 1. extend ----------------------------------------------------------------
+
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+       # Extend ToC
+$tocGenerator->extend($toc, "<h1>Header</h1>");
+       # Test ToC
+ok($toc->format(), "<ul>\n<li>Header\n<li>Header\n</ul>");
+
+
+#--- 2. extendFromFile --------------------------------------------------------
+
+       # Generate ToC
+$tocGenerator->generateFromFile($toc, $filename);
+       # Extend ToC
+$tocGenerator->extendFromFile($toc, $filename);
+       # Test ToC
+ok($toc->format(), "<ul>\n<li>Header\n<li>Header\n</ul>");
+
+
+#--- 3. extendFromFiles -------------------------------------------------------
+
+       # Generate ToC
+$tocGenerator->generateFromFile($toc, $filename);
+       # Extend ToC
+$tocGenerator->extendFromFile($toc, [$filename, $filename]);
+       # Test ToC
+ok($toc->format(), "<ul>\n<li>Header\n<li>Header\n<li>Header\n</ul>");
+
+
+#--- 4. linkTocToToken --------------------------------------------------------
+
+$toc->setOptions({
+       'doLinkToToken' => 1,
+});
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+       # Extend ToC
+$tocGenerator->extend($toc, "<h1>Header</h1>");
+       # Test ToC
+ok($toc->format() . "\n", <<'EOT');
+<ul>
+<li><a href=#h-1>Header</a>
+<li><a href=#h-2>Header</a>
+</ul>
+EOT
diff --git a/examples/includes/HTML-Toc-0.91/t/format.t b/examples/includes/HTML-Toc-0.91/t/format.t
new file mode 100644 (file)
index 0000000..62d2b6c
--- /dev/null
@@ -0,0 +1,157 @@
+#--- format.t -----------------------------------------------------------------
+# function: Test ToC formatting.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 6; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+
+my ($output, $content, $filename);
+my $toc          = HTML::Toc->new;
+my $tocGenerator = HTML::TocGenerator->new;
+my $tocInsertor  = HTML::TocInsertor->new;
+
+$toc->setOptions({
+       'doLinkToToken'  => 0,
+       'levelIndent'       => 0,
+       'insertionPoint'    => 'before <h1>',
+       'header'            => '',
+       'footer'            => '',
+});
+
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<h1>Header</h1>
+EOT
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- 1. templateLevelBegin ----------------------------------------------------
+
+$toc->setOptions({
+       'templateLevelBegin' => '"<ul class=toc_$groupId$level>\n"'
+});
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+ok($output, "<ul class=toc_h1>\n<li>Header\n</ul><h1>Header</h1>");
+$toc->setOptions({'templateLevelBegin' => undef});
+
+
+#--- 2. levelToToc -----------------------------------------------------------
+
+$tocGenerator->generate($toc, "<h1>Header1</h1>\n<h2>Header2</h2>");
+$toc->setOptions({'levelToToc' => '1'});
+ok($toc->format(), "<ul>\n<li>Header1\n</ul>");
+$toc->setOptions({'levelToToc' => '.*'});
+
+
+#--- 3. groupToToc -----------------------------------------------------------
+
+$toc->setOptions({
+       'tokenToToc' => [{
+               'level' => 1,
+               'tokenBegin' => '<h1 class=-foo>'
+       }, {
+               'groupId' => 'foo',
+               'level' => 1,
+               'tokenBegin' => '<h1 class=foo>'
+       }]
+});
+$tocGenerator->generate($toc, "<h1>Header1</h1>\n<h1 class=foo>Foo</h1>");
+$toc->setOptions({'groupToToc' => 'foo'});
+ok($toc->format(), "<ul>\n<li>Foo\n</ul>");
+$toc->setOptions({'groupToToc' => '.*'});
+
+
+#--- 4. header & footer -------------------------------------------------------
+
+$toc->setOptions({
+       'tokenToToc' => [{
+               'level'      => 1,
+               'tokenBegin' => '<h1>'
+       }],
+       'header' => '<!-- TocHeader -->',
+       'footer' => '<!-- TocFooter -->',
+});
+$tocInsertor->insert($toc, "<h1>Header1</h1>", {'output' => \$output});
+ok("$output\n", <<EOT);
+<!-- TocHeader --><ul>
+<li>Header1
+</ul><!-- TocFooter --><h1>Header1</h1>
+EOT
+
+
+       # Test 'doSingleStepLevel' => 1
+TestSingleStepLevel1();
+       # Test 'doSingleStepLevel' => 0
+TestSingleStepLevel0();
+
+
+#--- 5. TestSingleStepLevel1 --------------------------------------------------
+
+sub TestSingleStepLevel1 {
+       my $toc          = new HTML::Toc;
+       my $tocGenerator = new HTML::TocGenerator;
+       
+               # Generate ToC
+       $tocGenerator->generate($toc, <<EOT);
+<h1>Header 1</h1>
+<h3>Header 3</h3>
+EOT
+               # Compare output
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Header 1</a>
+   <ul>
+      <ul>
+         <li><a href=#h-1.0.1>Header 3</a>
+      </ul>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestSingleStepLevel1()
+
+
+#--- 6. TestSingleStepLevel0 --------------------------------------------------
+
+sub TestSingleStepLevel0 {
+       my $toc          = new HTML::Toc;
+       my $tocGenerator = new HTML::TocGenerator;
+       
+               # Set ToC options
+       $toc->setOptions({'doSingleStepLevel' => 0});
+               # Generate ToC
+       $tocGenerator->generate($toc, <<EOT);
+<h1>Header 1</h1>
+<h3>Header 3</h3>
+EOT
+               # Compare output
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Header 1</a>
+   <ul>
+      <li><a href=#h-1.0.1>Header 3</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestSingleStepLevel0()
diff --git a/examples/includes/HTML-Toc-0.91/t/generate.t b/examples/includes/HTML-Toc-0.91/t/generate.t
new file mode 100644 (file)
index 0000000..869bdf4
--- /dev/null
@@ -0,0 +1,200 @@
+#--- generate.t ---------------------------------------------------------------
+# function: Test ToC generation.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 13; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+
+my ($filename);
+my $toc          = HTML::Toc->new;
+my $tocGenerator = HTML::TocGenerator->new;
+
+$toc->setOptions({
+       'doLinkToToken' => 0,
+       'levelIndent'   => 0,
+       'header'        => '',
+       'footer'        => '',
+});
+
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT';
+<h1>Header</h1>
+EOT
+       close(FILE);
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- 1. generate --------------------------------------------------------------
+
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+ok($toc->format(), "<ul>\n<li>Header\n</ul>");
+
+
+#--- 2. generateFromFile ------------------------------------------------------
+
+$tocGenerator->generateFromFile($toc, $filename);
+ok($toc->format(), "<ul>\n<li>Header\n</ul>");
+
+
+#--- 3. generateFromFiles -----------------------------------------------------
+
+$tocGenerator->generateFromFile($toc, [$filename, $filename]);
+ok($toc->format(), "<ul>\n<li>Header\n<li>Header\n</ul>");
+       
+
+#--- 4. doLinkToToken -----------------------------------------------------
+
+$toc->setOptions({'doLinkToToken' => 1});
+$tocGenerator->generateFromFile($toc, $filename, {'globalGroups' => 1});
+ok($toc->format(), "<ul>\n<li><a href=#h-1>Header</a>\n</ul>");
+
+
+#--- 5. doLinkToFile -------------------------------------------------------
+
+$toc->setOptions({'doLinkToFile' => 1});
+$tocGenerator->generateFromFile($toc, $filename);
+ok($toc->format(), "<ul>\n<li><a href=$filename#h-1>Header</a>\n</ul>");
+
+
+#--- 6. templateAnchorHrefBegin -----------------------------------------------
+
+       # Set options
+$toc->setOptions({'templateAnchorHrefBegin' => '"test-$file"'});
+       # Generate ToC
+$tocGenerator->generateFromFile($toc, $filename);
+       # Test ToC
+ok($toc->format(), "<ul>\n<li>test-".$filename."Header</a>\n</ul>");
+       # Reset options
+$toc->setOptions({'templateAnchorHrefBegin' => undef});
+
+
+#--- 7. templateAnchorHrefBegin function --------------------------------------
+
+sub AssembleAnchorHrefBegin {
+               # Get arguments
+       my ($aFile, $aGroupId, $aLevel, $aNode) = @_;
+               # Return value
+       return $aFile . $aGroupId . $aLevel . $aNode;
+}  # AssembleAnchorHrefBegin()
+
+
+       # Set options
+$toc->setOptions({'templateAnchorHrefBegin' => \&AssembleAnchorHrefBegin});
+       # Generate ToC
+$tocGenerator->generateFromFile($toc, $filename);
+       # Test ToC
+ok($toc->format(), "<ul>\n<li>".$filename."h11Header</a>\n</ul>");
+       # Reset options
+$toc->setOptions({'templateAnchorHrefBegin' => undef});
+
+
+#--- 8. levelToToc no levels available ---------------------------------------
+
+$toc->setOptions({'levelToToc' => '2'});
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+ok($toc->format(), "");
+
+
+#--- 9. levelToToc level 1 ---------------------------------------------------
+
+       # Set options
+$toc->setOptions({
+       'levelToToc' => '1',
+       'doLinkToToken' => 0,
+});
+$tocGenerator->generate($toc, "<h1>Header1</h1>\n<h2>Header2</h2>");
+ok($toc->format(), "<ul>\n<li>Header1\n</ul>");
+
+
+#--- 10. levelToToc level 2 --------------------------------------------------
+
+       # Set options
+$toc->setOptions({
+       'levelToToc' => '2',
+       'doLinkToToken' => 0,
+});
+$tocGenerator->generate($toc, "<h1>Header1</h1>\n<h2>Header2</h2>");
+ok($toc->format(), "<ul>\n<li>Header2\n</ul>");
+       # Restore options
+$toc->setOptions({
+       'levelToToc' => '.*',
+});
+
+
+#--- 11. tokenToToc empty array ----------------------------------------------
+
+       # Set options
+$toc->setOptions({'tokenToToc' => []});
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+ok($toc->format(), "");
+
+
+#--- 12. groups nested --------------------------------------------------------
+
+$toc->setOptions({
+       'doNestGroup' => 1,
+       'tokenToToc' => [
+               {
+                       'level' => 1,
+                       'tokenBegin' => '<h1 class=-appendix>'
+               }, {
+                       'groupId' => 'appendix',
+                       'level' => 1,
+                       'tokenBegin' => '<h1 class=appendix>'
+               }
+       ]
+});
+$tocGenerator->generate(
+       $toc, "<h1>Header1</h1>\n<h1 class=appendix>Appendix</h1>"
+);
+ok($toc->format() . "\n", <<'EOT');
+<ul>
+<li>Header1
+<ul>
+<li>Appendix
+</ul>
+</ul>
+EOT
+
+
+#--- 13. groups not nested ----------------------------------------------------
+
+$toc->setOptions({
+       'doNestGroup' => 0,
+       'tokenToToc' => [
+               {
+                       'level' => 1,
+                       'tokenBegin' => '<h1 class=-appendix>'
+               }, {
+                       'groupId' => 'appendix',
+                       'level' => 1,
+                       'tokenBegin' => '<h1 class=appendix>'
+               }
+       ]
+});
+$tocGenerator->generate(
+       $toc, "<h1>Header1</h1>\n<h1 class=appendix>Appendix</h1>"
+);
+ok($toc->format() . "\n", <<'EOT');
+<ul>
+<li>Header1
+</ul>
+<ul>
+<li>Appendix
+</ul>
+EOT
diff --git a/examples/includes/HTML-Toc-0.91/t/insert.t b/examples/includes/HTML-Toc-0.91/t/insert.t
new file mode 100644 (file)
index 0000000..3f1adba
--- /dev/null
@@ -0,0 +1,336 @@
+#--- insert.t -----------------------------------------------------------------
+# function: Test ToC insertion.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 10; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+
+my ($output, $content, $filename);
+my $toc          = HTML::Toc->new;
+my $tocGenerator = HTML::TocGenerator->new;
+my $tocInsertor  = HTML::TocInsertor->new;
+
+$toc->setOptions({
+       'doLinkToToken'  => 0,
+       'levelIndent'       => 0,
+       'header'            => "",
+       'footer'            => "",
+});
+
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<h1>Header</h1>
+EOT
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- 1. insert before start ---------------------------------------------------
+
+$toc->setOptions({'insertionPoint' => 'before <h1>'});
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+$tocInsertor->insert($toc, "<h1>Header</h1>", {
+       'output'        => \$output,
+       'doGenerateToc' => 0
+});
+       # Test ToC
+ok($output, "<ul>\n<li>Header\n</ul><h1>Header</h1>");
+
+
+#--- 2. insert after start ----------------------------------------------------
+
+$toc->setOptions({'insertionPoint' => 'after <h1>'});
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+$tocInsertor->insert($toc, "<h1>Header</h1>", {
+       'output' => \$output,
+       'doGenerateToc' => 0
+});
+       # Test ToC
+ok($output, "<h1><ul>\n<li>Header\n</ul>Header</h1>");
+
+
+#--- 3. insert before end -----------------------------------------------------
+
+$toc->setOptions({'insertionPoint' => 'before </h1>'});
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+$tocInsertor->insert($toc, "<h1>Header</h1>", {
+       'output' => \$output,
+       'doGenerateToc' => 0
+});
+       # Test ToC
+ok($output, "<h1>Header<ul>\n<li>Header\n</ul></h1>");
+
+
+#--- 4. insert after end ------------------------------------------------------
+
+$toc->setOptions({'insertionPoint' => 'after </h1>'});
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+$tocInsertor->insert($toc, "<h1>Header</h1>", {
+       'output' => \$output,
+       'doGenerateToc' => 0
+});
+       # Test ToC
+ok($output, "<h1>Header</h1><ul>\n<li>Header\n</ul>");
+
+
+#--- 5. outputFile ------------------------------------------------------------
+
+$toc->setOptions({'insertionPoint' => 'before <h1>'});
+       # Generate ToC
+$tocGenerator->generate($toc, "<h1>Header</h1>");
+       # Insert ToC, output to file
+$tocInsertor->insert($toc, "<h1>Header</h1>", {
+       'outputFile' => $filename,
+       'doGenerateToc' => 0
+});
+       # Read outputfile
+open(FILE, "<$filename") || die "Can't open $filename: $!";
+$content = join('', <FILE>);
+close(FILE);
+       # Test ToC
+ok($output, "<ul>\n<li>Header\n</ul><h1>Header</h1>");
+
+
+#--- 6. empty toc -------------------------------------------------------------
+
+$tocGenerator->generate($toc, "");
+$tocInsertor->insert($toc, "", {
+       'output' => \$output,
+       'doGenerateToc' => 0
+});
+ok($output, "");
+
+
+#--- TestAfterDeclaration() ---------------------------------------------------
+# function: Test putting HTML comment after declaration.  
+
+sub TestAfterDeclaration {
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+   $toc->setOptions({
+               'insertionPoint' => "after <!ToC>",
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+<!ToC><body>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+</body>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+<!ToC>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Appendix</a>
+   <ul>
+      <li><a href=#h-1.1>Appendix Paragraph</a>
+   </ul>
+   <li><a href=#h-2>Appendix</a>
+   <ul>
+      <li><a href=#h-2.1>Appendix Paragraph</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+<body>
+   <a name=h-1><h1>Appendix</h1></a>
+   <a name=h-1.1><h2>Appendix Paragraph</h2></a>
+   <a name=h-2><h1>Appendix</h1></a>
+   <a name=h-2.1><h2>Appendix Paragraph</h2></a>
+</body>
+EOT
+}  # TestAfterDeclaration()
+
+
+#--- TestNumberingStyle() -----------------------------------------------------
+# function: Test numberingstyle.
+
+sub TestNumberingStyle {
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+   $toc->setOptions({
+               'numberingStyle'            => 'lower-alpha',
+               'doNumberToken'             => 1,
+      'tokenToToc' => [{
+            'tokenBegin'          => '<h1>',
+                       }, {
+            'tokenBegin'                        => '<h2>',
+            'level'                             => 2,
+                               'numberingStyle'      => 'upper-alpha'
+                       }, {
+            'tokenBegin'                        => '<h3>',
+            'level'                             => 3,
+                               'numberingStyle'      => 'decimal'
+         }]
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+<body>
+   <h1>Chapter</h1>
+   <h2>Paragraph</h2>
+   <h3>Paragraph</h3>
+   <h3>Paragraph</h3>
+   <h3>Paragraph</h3>
+</body>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+<body>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-a>Chapter</a>
+   <ul>
+      <li><a href=#h-a.A>Paragraph</a>
+      <ul>
+         <li><a href=#h-a.A.1>Paragraph</a>
+         <li><a href=#h-a.A.2>Paragraph</a>
+         <li><a href=#h-a.A.3>Paragraph</a>
+      </ul>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+
+   <a name=h-a><h1>a &nbsp;Chapter</h1></a>
+   <a name=h-a.A><h2>a.A &nbsp;Paragraph</h2></a>
+   <a name=h-a.A.1><h3>a.A.1 &nbsp;Paragraph</h3></a>
+   <a name=h-a.A.2><h3>a.A.2 &nbsp;Paragraph</h3></a>
+   <a name=h-a.A.3><h3>a.A.3 &nbsp;Paragraph</h3></a>
+</body>
+EOT
+}  # TestNumberingStyle()
+
+
+#--- TestReplaceComment() -----------------------------------------------------
+# function: Test replacing HTML comment with ToC.
+
+sub TestReplaceComment {
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+   $toc->setOptions({
+               'insertionPoint' => "replace <!-- ToC -->"
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+<!-- ToC -->
+<body>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+</body>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Appendix</a>
+   <ul>
+      <li><a href=#h-1.1>Appendix Paragraph</a>
+   </ul>
+   <li><a href=#h-2>Appendix</a>
+   <ul>
+      <li><a href=#h-2.1>Appendix Paragraph</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+
+<body>
+   <a name=h-1><h1>Appendix</h1></a>
+   <a name=h-1.1><h2>Appendix Paragraph</h2></a>
+   <a name=h-2><h1>Appendix</h1></a>
+   <a name=h-2.1><h2>Appendix Paragraph</h2></a>
+</body>
+EOT
+}  # TestReplaceComment()
+
+
+#--- TestReplaceText() -----------------------------------------------------
+# function: Test replacing HTML comment with ToC.
+
+sub TestReplaceText {
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+   $toc->setOptions({
+               'insertionPoint' => "replace ToC will be placed here[,]"
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+The ToC will be placed here, overnight.
+<body>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+</body>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Appendix</a>
+   <ul>
+      <li><a href=#h-1.1>Appendix Paragraph</a>
+   </ul>
+   <li><a href=#h-2>Appendix</a>
+   <ul>
+      <li><a href=#h-2.1>Appendix Paragraph</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+<body>
+   <a name=h-1><h1>Appendix</h1></a>
+   <a name=h-1.1><h2>Appendix Paragraph</h2></a>
+   <a name=h-2><h1>Appendix</h1></a>
+   <a name=h-2.1><h2>Appendix Paragraph</h2></a>
+</body>
+EOT
+}  # TestReplaceText()
+
+
+       # 7.  Test 'numberingStyle'
+TestNumberingStyle();
+       # 8.  Test replace comment
+TestReplaceComment();
+       # 9.  Test after declaration
+TestAfterDeclaration();
+       # 10.  Test replace text
+TestReplaceText();
diff --git a/examples/includes/HTML-Toc-0.91/t/manualTest.t b/examples/includes/HTML-Toc-0.91/t/manualTest.t
new file mode 100644 (file)
index 0000000..cc19fff
--- /dev/null
@@ -0,0 +1,768 @@
+#--- manual.t -----------------------------------------------------------------
+# function: Test HTML::ToC generating a manual.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 3; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+use HTML::TocUpdator;
+
+
+#--- AssembleTocLine() --------------------------------------------------------
+# function: Assemble ToC line.
+
+sub AssembleTocLine {
+               # Get arguments
+       my ($aLevel, $aGroupId, $aNode, $aSequenceNr, $aText) = @_;
+               # Local variables
+       my ($result);
+
+               # Assemble ToC line
+       SWITCH: {
+               if ($aGroupId eq "prelude") {
+                       $result = "<li>$aText\n";
+                       last SWITCH;
+               }
+               if ($aGroupId eq "part") {
+                       $result = "<li>Part $aNode &nbsp;$aText\n";
+                       last SWITCH;
+               }
+               if ($aGroupId eq "h") {
+                       $result = "<li>$aSequenceNr. &nbsp;$aText\n";
+                       last SWITCH;
+               }
+               else {
+                       $result = "<li>$aNode &nbsp;$aText\n";
+                       last SWITCH;
+               }
+       }
+
+               # Return value
+       return $result;
+}  # AssembleTocLine()
+
+
+#--- AssembleTokenNumber() ----------------------------------------------------
+# function: Assemble token number.
+
+sub AssembleTokenNumber {
+               # Get arguments
+       my ($aNode, $aGroupId, $aFile, $aGroupLevel, $aLevel, $aToc) = @_;
+               # Local variables
+       my ($result);
+               # Assemble token number
+       SWITCH: {
+               if ($aGroupId eq "part") {
+                       $result = "Part $aNode &nbsp;";
+                       last SWITCH;
+               }
+               else {
+                       $result = "$aNode &nbsp;";
+                       last SWITCH;
+               }
+       }
+               # Return value
+       return $result;
+}  # AssembleTokenNumber()
+
+
+#--- TestInsertManualToc ------------------------------------------------------
+# function: Test inserting ToC into manual.
+
+sub TestInsertManualToc {
+       my $output;
+               # Create objects
+       my $toc          = new HTML::Toc;
+       my $tocOfFigures = new HTML::Toc;
+       my $tocOfTables  = new HTML::Toc;
+       my $tocInsertor  = new HTML::TocInsertor;
+       
+               # Set ToC options
+       $toc->setOptions({
+               'doNestGroup'          => 1,
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "replace <!-- Table of Contents -->",
+               'templateLevel'        => \&AssembleTocLine,
+      'templateLevelBegin'   => '"<ul class=toc_$groupId$level>\n"',
+      'templateLevelEnd'     => '"</ul>\n"',
+               'templateTokenNumber'  => \&AssembleTokenNumber,
+      'tokenToToc'           => [{
+            'groupId'        => 'part',
+                          'doNumberToken'  => 1,
+            'level'          => 1,
+            'tokenBegin'     => '<h1 class=part>',
+         }, {
+            'tokenBegin'     => '<h1 class=-[appendix|prelude|hidden|part]>'
+         }, {
+            'tokenBegin'     => '<h2>',
+            'level'          => 2
+         }, {
+            'tokenBegin'     => '<h3>',
+            'level'          => 3
+         }, {
+            'groupId'        => 'appendix',
+            'tokenBegin'     => '<h1 class=appendix>',
+                          'numberingStyle' => 'upper-alpha',
+         }, {
+            'groupId'        => 'appendix',
+            'tokenBegin'     => '<h2 class=appendix>',
+            'level'          => 2
+         }, {
+            'groupId'        => 'prelude',
+            'tokenBegin'     => '<h1 class=prelude>',
+            'level'          => 1,
+                          'doNumberToken'  => 0,
+         }],
+       });
+       $tocOfFigures->setOptions({
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "replace <!-- Table of Figures -->",
+               'templateLevelBegin'   => '"<ol>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'templateTokenNumber'  => '"Figure $node: &nbsp;"',
+               'tokenToToc'           => [{
+                               'groupId'        => 'Figure',
+                               'tokenBegin'     => '<p class=captionFigure>'
+                       }]
+       });
+       $tocOfTables->setOptions({
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "replace <!-- Table of Tables -->",
+               'templateLevelBegin'   => '"<ol>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'templateTokenNumber'  => '"Table $node: &nbsp;"',
+               'tokenToToc'           => [{
+                               'groupId'        => 'Table',
+                               'tokenBegin'     => '<p class=captionTable>'
+                       }]
+       });
+               # Insert ToC
+       $tocInsertor->insertIntoFile(
+               [$toc, $tocOfFigures, $tocOfTables], 
+               't/ManualTest/manualTest1.htm', {
+                        'doUseGroupsGlobal' => 1,
+                        'output'            => \$output,
+                        'outputFile'        => 't/ManualTest/manualTest2.htm'
+               }
+       );
+       ok($output, <<EOT);
+<html>
+<head>
+   <title>Manual</title>
+    <style type="text/css">
+       ul.toc_appendix1 { 
+         list-style-type: none;
+         margin-left: 0;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h2 {
+         list-style-type: none;
+       }
+       ul.toc_h3 {
+         list-style-type: none;
+       }
+       ul.toc_part1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_prelude1 {
+         list-style: none;
+       }
+       p.captionFigure {
+         font-style: italic;
+         font-weight: bold;
+       }
+       p.captionTable {
+         font-style: italic;
+         font-weight: bold;
+       }
+    </style>
+</head>
+<body>
+
+<a name=prelude-1><h1 class=prelude>Preface</h1></a>
+Better C than never.
+
+<h1 class=hidden>Table of Contents</h1>
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul class=toc_prelude1>
+   <li><a href=#prelude-1>Preface</a>
+   <li><a href=#prelude-2>Table of Figures</a>
+   <li><a href=#prelude-3>Table of Tables</a>
+   <li><a href=#prelude-4>Introduction</a>
+   <ul class=toc_part1>
+      <li>Part 1 &nbsp;<a href=#part-1>Disks</a>
+      <ul class=toc_h1>
+         <li>1. &nbsp;<a href=#h-1>Compiler Disk v1</a>
+         <ul class=toc_h2>
+            <li>1. &nbsp;<a href=#h-1.1>System</a>
+            <li>2. &nbsp;<a href=#h-1.2>Standard Library</a>
+         </ul>
+         <li>2. &nbsp;<a href=#h-2>Compiler Disk v2</a>
+         <ul class=toc_h2>
+            <li>1. &nbsp;<a href=#h-2.1>System</a>
+            <ul class=toc_h3>
+               <li>1. &nbsp;<a href=#h-2.1.1>parser.com</a>
+               <li>2. &nbsp;<a href=#h-2.1.2>compiler.com</a>
+               <li>3. &nbsp;<a href=#h-2.1.3>linker.com</a>
+            </ul>
+            <li>2. &nbsp;<a href=#h-2.2>Standard Library</a>
+         </ul>
+         <li>3. &nbsp;<a href=#h-3>Library System Disk</a>
+      </ul>
+      <li>Part 2 &nbsp;<a href=#part-2>Personal</a>
+      <ul class=toc_h1>
+         <li>4. &nbsp;<a href=#h-4>Tips & Tricks</a>
+      </ul>
+      <li>Part 3 &nbsp;<a href=#part-3>Appendixes</a>
+      <ul class=toc_appendix1>
+         <li>A &nbsp;<a href=#appendix-A>Functions Standard Library v1</a>
+         <li>B &nbsp;<a href=#appendix-B>Functions Standard Library v2</a>
+         <li>C &nbsp;<a href=#appendix-C>Functions Graphic Library</a>
+      </ul>
+   </ul>
+   <li><a href=#prelude-5>Bibliography</a>
+</ul>
+<!-- End of generated Table of Contents -->
+
+
+<a name=prelude-2><h1 class=prelude>Table of Figures</h1></a>
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#Figure-1>Contents Compiler Disk v1</a>
+   <li><a href=#Figure-2>Contents Compiler Disk v2</a>
+</ol>
+<!-- End of generated Table of Contents -->
+
+
+<a name=prelude-3><h1 class=prelude>Table of Tables</h1></a>
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#Table-1>Compile Steps</a>
+</ol>
+<!-- End of generated Table of Contents -->
+
+
+<a name=prelude-4><h1 class=prelude>Introduction</h1></a>
+Thanks to standardisation and the excellent work of the QWERTY corporation it is possible to learn C with almost any C manual.
+<a name=Table-1><p class=captionTable>Table 1: &nbsp;Compile Steps</p></a>
+<ul><pre>
+   Parser
+   Compiler
+   Linker
+</pre></ul>
+
+<a name=part-1><h1 class=part>Part 1 &nbsp;Disks</h1></a>
+<a name=h-1><h1>1 &nbsp;Compiler Disk v1</h1></a>
+<img src=img.gif alt="Contents Compiler Disk v1">
+<a name=Figure-1><p class=captionFigure>Figure 1: &nbsp;Contents Compiler Disk v1</p></a>
+
+<a name=h-1.1><h2>1.1 &nbsp;System</h2></a>
+<a name=h-1.2><h2>1.2 &nbsp;Standard Library</h2></a>
+
+<a name=h-2><h1>2 &nbsp;Compiler Disk v2</h1></a>
+<img src=img.gif alt="Contents Compiler Disk v2">
+<a name=Figure-2><p class=captionFigure>Figure 2: &nbsp;Contents Compiler Disk v2</p></a>
+
+<a name=h-2.1><h2>2.1 &nbsp;System</h2></a>
+<a name=h-2.1.1><h3>2.1.1 &nbsp;parser.com</h3></a>
+<a name=h-2.1.2><h3>2.1.2 &nbsp;compiler.com</h3></a>
+<a name=h-2.1.3><h3>2.1.3 &nbsp;linker.com</h3></a>
+<a name=h-2.2><h2>2.2 &nbsp;Standard Library</h2></a>
+
+<a name=h-3><h1>3 &nbsp;Library System Disk</h1></a>
+<a name=part-2><h1 class=part>Part 2 &nbsp;Personal</h1></a>
+<a name=h-4><h1>4 &nbsp;Tips & Tricks</h1></a>
+<a name=part-3><h1 class=part>Part 3 &nbsp;Appendixes</h1></a>
+<a name=appendix-A><h1 class=appendix>A &nbsp;Functions Standard Library v1</h1></a>
+<a name=appendix-B><h1 class=appendix>B &nbsp;Functions Standard Library v2</h1></a>
+<a name=appendix-C><h1 class=appendix>C &nbsp;Functions Graphic Library</h1></a>
+<a name=prelude-5><h1 class=prelude>Bibliography</h1></a>
+</body>
+</html>
+EOT
+}  # TestInsertManualToc()
+
+
+#--- TestInsertManualForUpdating() --------------------------------------------
+# function: Test inserting ToC into manual.
+
+sub TestInsertManualForUpdating {
+       my $output;
+               # Create objects
+       my $toc          = new HTML::Toc;
+       my $tocOfFigures = new HTML::Toc;
+       my $tocOfTables  = new HTML::Toc;
+       my $tocUpdator   = new HTML::TocUpdator;
+       
+               # Set ToC options
+       $toc->setOptions({
+               'doNestGroup'          => 1,
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "after <!-- Table of Contents -->",
+               'templateLevel'        => \&AssembleTocLine,
+      'templateLevelBegin'   => '"<ul class=toc_$groupId$level>\n"',
+      'templateLevelEnd'     => '"</ul>\n"',
+               'templateTokenNumber'  => \&AssembleTokenNumber,
+      'tokenToToc'           => [{
+            'groupId'        => 'part',
+                          'doNumberToken'  => 1,
+            'level'          => 1,
+            'tokenBegin'     => '<h1 class=part>',
+         }, {
+            'tokenBegin'     => '<h1 class=-[appendix|prelude|hidden|part]>'
+         }, {
+            'tokenBegin'     => '<h2>',
+            'level'          => 2
+         }, {
+            'tokenBegin'     => '<h3>',
+            'level'          => 3
+         }, {
+            'groupId'        => 'appendix',
+            'tokenBegin'     => '<h1 class=appendix>',
+                          'numberingStyle' => 'upper-alpha',
+         }, {
+            'groupId'        => 'appendix',
+            'tokenBegin'     => '<h2 class=appendix>',
+            'level'          => 2
+         }, {
+            'groupId'        => 'prelude',
+            'tokenBegin'     => '<h1 class=prelude>',
+            'level'          => 1,
+                          'doNumberToken'  => 0,
+         }],
+       });
+       $tocOfFigures->setOptions({
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "after <!-- Table of Figures -->",
+               'templateLevelBegin'   => '"<ol>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'templateTokenNumber'  => '"Figure $node: &nbsp;"',
+               'tokenToToc'           => [{
+                               'groupId'        => 'Figure',
+                               'tokenBegin'     => '<p class=captionFigure>'
+                       }]
+       });
+       $tocOfTables->setOptions({
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "after <!-- Table of Tables -->",
+               'templateLevelBegin'   => '"<ol>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'templateTokenNumber'  => '"Table $node: &nbsp;"',
+               'tokenToToc'           => [{
+                               'groupId'        => 'Table',
+                               'tokenBegin'     => '<p class=captionTable>'
+                       }]
+       });
+               # Insert ToC
+       $tocUpdator->updateFile(
+               [$toc, $tocOfFigures, $tocOfTables], 
+               't/ManualTest/manualTest1.htm', {
+                        'doUseGroupsGlobal' => 1,
+                        'output'            => \$output,
+                        'outputFile'        => 't/ManualTest/manualTest3.htm'
+               }
+       );
+       ok($output, <<EOT);
+<html>
+<head>
+   <title>Manual</title>
+    <style type="text/css">
+       ul.toc_appendix1 { 
+         list-style-type: none;
+         margin-left: 0;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h2 {
+         list-style-type: none;
+       }
+       ul.toc_h3 {
+         list-style-type: none;
+       }
+       ul.toc_part1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_prelude1 {
+         list-style: none;
+       }
+       p.captionFigure {
+         font-style: italic;
+         font-weight: bold;
+       }
+       p.captionTable {
+         font-style: italic;
+         font-weight: bold;
+       }
+    </style>
+</head>
+<body>
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-1><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Preface</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+Better C than never.
+
+<h1 class=hidden>Table of Contents</h1>
+<!-- Table of Contents --><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul class=toc_prelude1>
+   <li><a href=#prelude-1>Preface</a>
+   <li><a href=#prelude-2>Table of Figures</a>
+   <li><a href=#prelude-3>Table of Tables</a>
+   <li><a href=#prelude-4>Introduction</a>
+   <ul class=toc_part1>
+      <li>Part 1 &nbsp;<a href=#part-1>Disks</a>
+      <ul class=toc_h1>
+         <li>1. &nbsp;<a href=#h-1>Compiler Disk v1</a>
+         <ul class=toc_h2>
+            <li>1. &nbsp;<a href=#h-1.1>System</a>
+            <li>2. &nbsp;<a href=#h-1.2>Standard Library</a>
+         </ul>
+         <li>2. &nbsp;<a href=#h-2>Compiler Disk v2</a>
+         <ul class=toc_h2>
+            <li>1. &nbsp;<a href=#h-2.1>System</a>
+            <ul class=toc_h3>
+               <li>1. &nbsp;<a href=#h-2.1.1>parser.com</a>
+               <li>2. &nbsp;<a href=#h-2.1.2>compiler.com</a>
+               <li>3. &nbsp;<a href=#h-2.1.3>linker.com</a>
+            </ul>
+            <li>2. &nbsp;<a href=#h-2.2>Standard Library</a>
+         </ul>
+         <li>3. &nbsp;<a href=#h-3>Library System Disk</a>
+      </ul>
+      <li>Part 2 &nbsp;<a href=#part-2>Personal</a>
+      <ul class=toc_h1>
+         <li>4. &nbsp;<a href=#h-4>Tips & Tricks</a>
+      </ul>
+      <li>Part 3 &nbsp;<a href=#part-3>Appendixes</a>
+      <ul class=toc_appendix1>
+         <li>A &nbsp;<a href=#appendix-A>Functions Standard Library v1</a>
+         <li>B &nbsp;<a href=#appendix-B>Functions Standard Library v2</a>
+         <li>C &nbsp;<a href=#appendix-C>Functions Graphic Library</a>
+      </ul>
+   </ul>
+   <li><a href=#prelude-5>Bibliography</a>
+</ul>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-2><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Table of Figures</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- Table of Figures --><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#Figure-1>Contents Compiler Disk v1</a>
+   <li><a href=#Figure-2>Contents Compiler Disk v2</a>
+</ol>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-3><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Table of Tables</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- Table of Tables --><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#Table-1>Compile Steps</a>
+</ol>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-4><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Introduction</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+Thanks to standardisation and the excellent work of the QWERTY corporation it is possible to learn C with almost any C manual.
+<!-- #BeginTocAnchorNameBegin --><a name=Table-1><!-- #EndTocAnchorNameBegin --><p class=captionTable><!-- #BeginTocNumber -->Table 1: &nbsp;<!-- #EndTocNumber -->Compile Steps</p><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<ul><pre>
+   Parser
+   Compiler
+   Linker
+</pre></ul>
+
+<!-- #BeginTocAnchorNameBegin --><a name=part-1><!-- #EndTocAnchorNameBegin --><h1 class=part><!-- #BeginTocNumber -->Part 1 &nbsp;<!-- #EndTocNumber -->Disks</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Compiler Disk v1</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<img src=img.gif alt="Contents Compiler Disk v1">
+<!-- #BeginTocAnchorNameBegin --><a name=Figure-1><!-- #EndTocAnchorNameBegin --><p class=captionFigure><!-- #BeginTocNumber -->Figure 1: &nbsp;<!-- #EndTocNumber -->Contents Compiler Disk v1</p><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-1.1><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->1.1 &nbsp;<!-- #EndTocNumber -->System</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-1.2><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->1.2 &nbsp;<!-- #EndTocNumber -->Standard Library</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-2><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->2 &nbsp;<!-- #EndTocNumber -->Compiler Disk v2</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<img src=img.gif alt="Contents Compiler Disk v2">
+<!-- #BeginTocAnchorNameBegin --><a name=Figure-2><!-- #EndTocAnchorNameBegin --><p class=captionFigure><!-- #BeginTocNumber -->Figure 2: &nbsp;<!-- #EndTocNumber -->Contents Compiler Disk v2</p><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->2.1 &nbsp;<!-- #EndTocNumber -->System</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1.1><!-- #EndTocAnchorNameBegin --><h3><!-- #BeginTocNumber -->2.1.1 &nbsp;<!-- #EndTocNumber -->parser.com</h3><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1.2><!-- #EndTocAnchorNameBegin --><h3><!-- #BeginTocNumber -->2.1.2 &nbsp;<!-- #EndTocNumber -->compiler.com</h3><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1.3><!-- #EndTocAnchorNameBegin --><h3><!-- #BeginTocNumber -->2.1.3 &nbsp;<!-- #EndTocNumber -->linker.com</h3><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.2><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->2.2 &nbsp;<!-- #EndTocNumber -->Standard Library</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-3><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->3 &nbsp;<!-- #EndTocNumber -->Library System Disk</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=part-2><!-- #EndTocAnchorNameBegin --><h1 class=part><!-- #BeginTocNumber -->Part 2 &nbsp;<!-- #EndTocNumber -->Personal</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-4><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->4 &nbsp;<!-- #EndTocNumber -->Tips & Tricks</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=part-3><!-- #EndTocAnchorNameBegin --><h1 class=part><!-- #BeginTocNumber -->Part 3 &nbsp;<!-- #EndTocNumber -->Appendixes</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=appendix-A><!-- #EndTocAnchorNameBegin --><h1 class=appendix><!-- #BeginTocNumber -->A &nbsp;<!-- #EndTocNumber -->Functions Standard Library v1</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=appendix-B><!-- #EndTocAnchorNameBegin --><h1 class=appendix><!-- #BeginTocNumber -->B &nbsp;<!-- #EndTocNumber -->Functions Standard Library v2</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=appendix-C><!-- #EndTocAnchorNameBegin --><h1 class=appendix><!-- #BeginTocNumber -->C &nbsp;<!-- #EndTocNumber -->Functions Graphic Library</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-5><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Bibliography</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+</body>
+</html>
+EOT
+}  # TestInsertManualForUpdating()
+
+
+#--- TestUpdateManual() -------------------------------------------------------
+# function: Test inserting ToC into manual.
+
+sub TestUpdateManual {
+       my $output;
+               # Create objects
+       my $toc          = new HTML::Toc;
+       my $tocOfFigures = new HTML::Toc;
+       my $tocOfTables  = new HTML::Toc;
+       my $tocUpdator   = new HTML::TocUpdator;
+       
+               # Set ToC options
+       $toc->setOptions({
+               'doNestGroup'          => 1,
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "after <!-- Table of Contents -->",
+               'templateLevel'        => \&AssembleTocLine,
+      'templateLevelBegin'   => '"<ul class=toc_$groupId$level>\n"',
+      'templateLevelEnd'     => '"</ul>\n"',
+               'templateTokenNumber'  => \&AssembleTokenNumber,
+      'tokenToToc'           => [{
+            'groupId'        => 'part',
+                          'doNumberToken'  => 1,
+            'level'          => 1,
+            'tokenBegin'     => '<h1 class=part>',
+         }, {
+            'tokenBegin'     => '<h1 class=-[appendix|prelude|hidden|part]>'
+         }, {
+            'tokenBegin'     => '<h2>',
+            'level'          => 2
+         }, {
+            'tokenBegin'     => '<h3>',
+            'level'          => 3
+         }, {
+            'groupId'        => 'appendix',
+            'tokenBegin'     => '<h1 class=appendix>',
+                          'numberingStyle' => 'upper-alpha',
+         }, {
+            'groupId'        => 'appendix',
+            'tokenBegin'     => '<h2 class=appendix>',
+            'level'          => 2
+         }, {
+            'groupId'        => 'prelude',
+            'tokenBegin'     => '<h1 class=prelude>',
+            'level'          => 1,
+                          'doNumberToken'  => 0,
+         }],
+       });
+       $tocOfFigures->setOptions({
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "after <!-- Table of Figures -->",
+               'templateLevelBegin'   => '"<ol>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'templateTokenNumber'  => '"Figure $node: &nbsp;"',
+               'tokenToToc'           => [{
+                               'groupId'        => 'Figure',
+                               'tokenBegin'     => '<p class=captionFigure>'
+                       }]
+       });
+       $tocOfTables->setOptions({
+               'doNumberToken'        => 1,
+               'insertionPoint'       => "after <!-- Table of Tables -->",
+               'templateLevelBegin'   => '"<ol>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'templateTokenNumber'  => '"Table $node: &nbsp;"',
+               'tokenToToc'           => [{
+                               'groupId'        => 'Table',
+                               'tokenBegin'     => '<p class=captionTable>'
+                       }]
+       });
+               # Insert ToC
+       $tocUpdator->updateFile(
+               [$toc, $tocOfFigures, $tocOfTables], 
+               't/ManualTest/manualTest3.htm', {
+                        'doUseGroupsGlobal' => 1,
+                        'output'            => \$output,
+                        'outputFile'        => 't/ManualTest/manualTest4.htm'
+               }
+       );
+       ok($output, <<EOT);
+<html>
+<head>
+   <title>Manual</title>
+    <style type="text/css">
+       ul.toc_appendix1 { 
+         list-style-type: none;
+         margin-left: 0;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_h2 {
+         list-style-type: none;
+       }
+       ul.toc_h3 {
+         list-style-type: none;
+       }
+       ul.toc_part1 {
+         list-style-type: none;
+         margin-left: 1;
+         margin-top: 1em;
+         margin-bottom: 1em;
+       }
+       ul.toc_prelude1 {
+         list-style: none;
+       }
+       p.captionFigure {
+         font-style: italic;
+         font-weight: bold;
+       }
+       p.captionTable {
+         font-style: italic;
+         font-weight: bold;
+       }
+    </style>
+</head>
+<body>
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-1><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Preface</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+Better C than never.
+
+<h1 class=hidden>Table of Contents</h1>
+<!-- Table of Contents --><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul class=toc_prelude1>
+   <li><a href=#prelude-1>Preface</a>
+   <li><a href=#prelude-2>Table of Figures</a>
+   <li><a href=#prelude-3>Table of Tables</a>
+   <li><a href=#prelude-4>Introduction</a>
+   <ul class=toc_part1>
+      <li>Part 1 &nbsp;<a href=#part-1>Disks</a>
+      <ul class=toc_h1>
+         <li>1. &nbsp;<a href=#h-1>Compiler Disk v1</a>
+         <ul class=toc_h2>
+            <li>1. &nbsp;<a href=#h-1.1>System</a>
+            <li>2. &nbsp;<a href=#h-1.2>Standard Library</a>
+         </ul>
+         <li>2. &nbsp;<a href=#h-2>Compiler Disk v2</a>
+         <ul class=toc_h2>
+            <li>1. &nbsp;<a href=#h-2.1>System</a>
+            <ul class=toc_h3>
+               <li>1. &nbsp;<a href=#h-2.1.1>parser.com</a>
+               <li>2. &nbsp;<a href=#h-2.1.2>compiler.com</a>
+               <li>3. &nbsp;<a href=#h-2.1.3>linker.com</a>
+            </ul>
+            <li>2. &nbsp;<a href=#h-2.2>Standard Library</a>
+         </ul>
+         <li>3. &nbsp;<a href=#h-3>Library System Disk</a>
+      </ul>
+      <li>Part 2 &nbsp;<a href=#part-2>Personal</a>
+      <ul class=toc_h1>
+         <li>4. &nbsp;<a href=#h-4>Tips & Tricks</a>
+      </ul>
+      <li>Part 3 &nbsp;<a href=#part-3>Appendixes</a>
+      <ul class=toc_appendix1>
+         <li>A &nbsp;<a href=#appendix-A>Functions Standard Library v1</a>
+         <li>B &nbsp;<a href=#appendix-B>Functions Standard Library v2</a>
+         <li>C &nbsp;<a href=#appendix-C>Functions Graphic Library</a>
+      </ul>
+   </ul>
+   <li><a href=#prelude-5>Bibliography</a>
+</ul>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-2><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Table of Figures</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- Table of Figures --><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#Figure-1>Contents Compiler Disk v1</a>
+   <li><a href=#Figure-2>Contents Compiler Disk v2</a>
+</ol>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-3><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Table of Tables</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- Table of Tables --><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#Table-1>Compile Steps</a>
+</ol>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-4><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Introduction</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+Thanks to standardisation and the excellent work of the QWERTY corporation it is possible to learn C with almost any C manual.
+<!-- #BeginTocAnchorNameBegin --><a name=Table-1><!-- #EndTocAnchorNameBegin --><p class=captionTable><!-- #BeginTocNumber -->Table 1: &nbsp;<!-- #EndTocNumber -->Compile Steps</p><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<ul><pre>
+   Parser
+   Compiler
+   Linker
+</pre></ul>
+
+<!-- #BeginTocAnchorNameBegin --><a name=part-1><!-- #EndTocAnchorNameBegin --><h1 class=part><!-- #BeginTocNumber -->Part 1 &nbsp;<!-- #EndTocNumber -->Disks</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Compiler Disk v1</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<img src=img.gif alt="Contents Compiler Disk v1">
+<!-- #BeginTocAnchorNameBegin --><a name=Figure-1><!-- #EndTocAnchorNameBegin --><p class=captionFigure><!-- #BeginTocNumber -->Figure 1: &nbsp;<!-- #EndTocNumber -->Contents Compiler Disk v1</p><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-1.1><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->1.1 &nbsp;<!-- #EndTocNumber -->System</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-1.2><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->1.2 &nbsp;<!-- #EndTocNumber -->Standard Library</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-2><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->2 &nbsp;<!-- #EndTocNumber -->Compiler Disk v2</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<img src=img.gif alt="Contents Compiler Disk v2">
+<!-- #BeginTocAnchorNameBegin --><a name=Figure-2><!-- #EndTocAnchorNameBegin --><p class=captionFigure><!-- #BeginTocNumber -->Figure 2: &nbsp;<!-- #EndTocNumber -->Contents Compiler Disk v2</p><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->2.1 &nbsp;<!-- #EndTocNumber -->System</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1.1><!-- #EndTocAnchorNameBegin --><h3><!-- #BeginTocNumber -->2.1.1 &nbsp;<!-- #EndTocNumber -->parser.com</h3><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1.2><!-- #EndTocAnchorNameBegin --><h3><!-- #BeginTocNumber -->2.1.2 &nbsp;<!-- #EndTocNumber -->compiler.com</h3><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.1.3><!-- #EndTocAnchorNameBegin --><h3><!-- #BeginTocNumber -->2.1.3 &nbsp;<!-- #EndTocNumber -->linker.com</h3><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-2.2><!-- #EndTocAnchorNameBegin --><h2><!-- #BeginTocNumber -->2.2 &nbsp;<!-- #EndTocNumber -->Standard Library</h2><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+
+<!-- #BeginTocAnchorNameBegin --><a name=h-3><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->3 &nbsp;<!-- #EndTocNumber -->Library System Disk</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=part-2><!-- #EndTocAnchorNameBegin --><h1 class=part><!-- #BeginTocNumber -->Part 2 &nbsp;<!-- #EndTocNumber -->Personal</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=h-4><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->4 &nbsp;<!-- #EndTocNumber -->Tips & Tricks</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=part-3><!-- #EndTocAnchorNameBegin --><h1 class=part><!-- #BeginTocNumber -->Part 3 &nbsp;<!-- #EndTocNumber -->Appendixes</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=appendix-A><!-- #EndTocAnchorNameBegin --><h1 class=appendix><!-- #BeginTocNumber -->A &nbsp;<!-- #EndTocNumber -->Functions Standard Library v1</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=appendix-B><!-- #EndTocAnchorNameBegin --><h1 class=appendix><!-- #BeginTocNumber -->B &nbsp;<!-- #EndTocNumber -->Functions Standard Library v2</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=appendix-C><!-- #EndTocAnchorNameBegin --><h1 class=appendix><!-- #BeginTocNumber -->C &nbsp;<!-- #EndTocNumber -->Functions Graphic Library</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+<!-- #BeginTocAnchorNameBegin --><a name=prelude-5><!-- #EndTocAnchorNameBegin --><h1 class=prelude>Bibliography</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+</body>
+</html>
+EOT
+}  # TestUpdateManual()
+
+
+       # Test inserting ToC into manual
+TestInsertManualToc();
+       # Test inserting ToC with update tokens into manual
+TestInsertManualForUpdating();
+       # Test updating ToC
+TestUpdateManual();
diff --git a/examples/includes/HTML-Toc-0.91/t/options.t b/examples/includes/HTML-Toc-0.91/t/options.t
new file mode 100644 (file)
index 0000000..04bedac
--- /dev/null
@@ -0,0 +1,194 @@
+#--- options.t ----------------------------------------------------------------
+# function: Test HTML::ToC.  In particular test the available options.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 5; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+use HTML::TocUpdator;
+
+my ($filename);
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- TestAttributeToExcludeToken() --------------------------------------------
+# function: Test 'HTML::Toc' option 'attributeToExcludeToken'
+
+sub TestAttributeToExcludeToken {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<body>
+   <h1>Chapter 1</h1>
+   <h1 class=appendix>Appendix</h1>
+</body>
+EOT
+
+               # Create objects
+       my $toc          = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+       
+   $toc->setOptions({
+               'attributeToExcludeToken' => 'foo',
+               'tokenToToc' => [{
+                       'tokenBegin' => '<h1 class=foodix>'
+               }]
+   });
+               # Generate ToC
+       $tocGenerator->generateFromFile($toc, $filename);
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Chapter 1</a>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestAttributeToExcludeToken()
+
+
+#--- TestAttributeToTocToken() ------------------------------------------------
+# function: Test 'HTML::Toc' option 'attributeToTocToken'
+
+sub TestAttributeToTocToken {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<body>
+   <img src=test.gif alt=Picture>
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc          = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+       
+   $toc->setOptions({
+       'attributeToTocToken' => 'foo',
+      'tokenToToc'   => [{
+         'groupId'    => 'image',
+         'tokenBegin' => '<img alt=foo>'
+      }],
+   });
+               # Generate ToC
+       $tocGenerator->generateFromFile($toc, $filename);
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#image-1>Picture</a>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestAttributeToTocToken()
+
+
+#--- TestNumberingStyleDecimal ------------------------------------------------
+# function: Test 'decimal' numbering style.
+
+sub TestNumberingStyleDecimal {
+               # Local variables
+       my $output;
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       
+   $toc->setOptions({
+               'doNumberToken' => 1,
+      'tokenToToc'   => [{
+                       'level' => 1,
+                       'tokenBegin' => '<h1>',
+                       'numberingStyle' => 'decimal'
+      }],
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+               # Test ToC
+       ok("$output\n", <<EOT);
+<a name=h-1><h1>1 &nbsp;Header</h1></a>
+EOT
+}  # TestNumberingStyleDecimal()
+
+
+#--- TestNumberingStyleLowerAlpha ---------------------------------------------
+# function: Test 'lower-alpha' numbering style.
+
+sub TestNumberingStyleLowerAlpha {
+               # Local variables
+       my $output;
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       
+   $toc->setOptions({
+               'doNumberToken' => 1,
+      'tokenToToc'   => [{
+                       'level' => 1,
+                       'tokenBegin' => '<h1>',
+                       'numberingStyle' => 'lower-alpha'
+      }],
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+               # Test ToC
+       ok("$output\n", <<EOT);
+<a name=h-a><h1>a &nbsp;Header</h1></a>
+EOT
+}  # TestNumberingStyleLowerAlpha()
+
+
+#--- TestNumberingStyleUpperAlpha ---------------------------------------------
+# function: Test 'upper-alpha' numbering style.
+
+sub TestNumberingStyleUpperAlpha {
+               # Local variables
+       my $output;
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       
+   $toc->setOptions({
+               'doNumberToken' => 1,
+      'tokenToToc'   => [{
+                       'level' => 1,
+                       'tokenBegin' => '<h1>',
+                       'numberingStyle' => 'upper-alpha'
+      }],
+   });
+               # Generate ToC
+       $tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+               # Test ToC
+       ok("$output\n", <<EOT);
+<a name=h-A><h1>A &nbsp;Header</h1></a>
+EOT
+}  # TestNumberingStyleUpperAlpha()
+
+
+       # Test 'attributeToTocToken'
+TestAttributeToTocToken();
+       # Test 'attributeToExcludeToken'
+TestAttributeToExcludeToken();
+       # Test 'numberingStyleDecimal'
+TestNumberingStyleDecimal();
+       # Test 'numberingStyleLowerAlpha'
+TestNumberingStyleLowerAlpha();
+       # Test 'numberingStyleUpperAlpha'
+TestNumberingStyleUpperAlpha();
diff --git a/examples/includes/HTML-Toc-0.91/t/podExamples.t b/examples/includes/HTML-Toc-0.91/t/podExamples.t
new file mode 100644 (file)
index 0000000..6a546e6
--- /dev/null
@@ -0,0 +1,709 @@
+#--- podExamples.t ------------------------------------------------------------
+# function: Test HTML::ToC.  In particular test the examples as described in 
+#           the POD documentation.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 13; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+use HTML::TocUpdator;
+
+my ($filename, $filename2);
+       
+
+BEGIN {
+               # Create test file
+       $filename = "tmp.htm";
+       die "$filename is already there" if -e $filename;
+               # Create test file 2
+       $filename2 = "tmp2.htm";
+       die "$filename2 is already there" if -e $filename2;
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+               # Remove test file 2
+       unlink($filename2) or warn "Can't unlink $filename2: $!";
+}
+
+
+#--- TestExtendFromFile() --------------------------------------------------
+# function: Test 'HTML::TocGenerator->extendFromFile()
+
+sub TestExtendFromFile {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<body>
+   <h1>Chapter of document 1</h1>
+</body>
+EOT
+
+               # Assemble test file 2
+       open(FILE, ">$filename2") || die "Can't create $filename2: $!";
+       print FILE <<'EOT'; close(FILE);
+<html>
+<body>
+   <h1>Chapter of document 2</h1>
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc          = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+       
+               # Set ToC options
+   $toc->setOptions({'doLinkToFile' => 1});
+               # Generate ToC
+       $tocGenerator->generateFromFile($toc, $filename);
+       $tocGenerator->extendFromFile($toc, $filename2);
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=tmp.htm#h-1>Chapter of document 1</a>
+   <li><a href=tmp2.htm#h-2>Chapter of document 2</a>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestExtendFromFile()
+
+
+#--- TestGenerateFromFiles() --------------------------------------------------
+# function: Test 'HTML::TocGenerator->generateFromFile()
+
+sub TestGenerateFromFiles {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<body>
+   <h1>Chapter of document 1</h1>
+</body>
+EOT
+
+               # Assemble test file 2
+       open(FILE, ">$filename2") || die "Can't create $filename2: $!";
+       print FILE <<'EOT'; close(FILE);
+<html>
+<body>
+   <h1>Chapter of document 2</h1>
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc          = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+       
+               # Set ToC options
+   $toc->setOptions({'doLinkToFile' => 1});
+               # Generate ToC
+       $tocGenerator->generateFromFile($toc, [$filename, $filename2]);
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=tmp.htm#h-1>Chapter of document 1</a>
+   <li><a href=tmp2.htm#h-2>Chapter of document 2</a>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestGenerateFromFiles()
+
+
+#--- TestGenerateFromFiles() --------------------------------------------------
+# function: Test 'HTML::TocGenerator->generateFromFile() using multiple files.
+
+sub TestGenerateFromFile {
+               # Assemble test file 1
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<html>
+<body>
+   <h1>Chapter</h1>
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc          = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+       
+               # Generate ToC
+       $tocGenerator->generateFromFile($toc, $filename);
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Chapter</a>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestGenerateFromFile()
+
+
+#--- TestInsertIntoFile() -----------------------------------------------------
+# function: Test 'HTML::TocInsertor->insertIntoFile()
+
+sub TestInsertIntoFile {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<html>
+<body>
+   <h1>Chapter</h1>
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Generate ToC
+       $tocInsertor->insertIntoFile($toc, $filename, {'output' => \$output});
+               # Test ToC
+       ok($output, <<EOT);
+<html>
+<body>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Chapter</a>
+</ul>
+<!-- End of generated Table of Contents -->
+
+   <a name=h-1><h1>Chapter</h1></a>
+</body>
+</html>
+EOT
+}  # TestInsertIntoFile()
+
+
+#--- TestInsertIntoFileUsingTocUpdator() --------------------------------------
+# function: Test 'HTML::TocUpdator->insertIntoFile()
+
+sub TestInsertIntoFileUsingTocUpdator {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<html>
+<body>
+   <h1>
+   Chapter
+   </h1>
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc        = HTML::Toc->new();
+       my $tocUpdator = HTML::TocUpdator->new();
+       my $output;
+       
+               # Generate ToC
+       $tocUpdator->insertIntoFile($toc, $filename, {'output' => \$output});
+               # Test ToC
+       ok($output, <<EOT);
+<html>
+<body><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1> Chapter </a>
+</ul>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+   <!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1>
+   Chapter
+   </h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+</body>
+</html>
+EOT
+}  # TestInsertIntoFileUsingTocUpdator()
+
+
+#--- TestGlobalGroups0() ------------------------------------------------------
+# function: Test 'HTML::TocGenerator' option 'doUseGroupsGlobal = 0'.
+
+sub TestGlobalGroups0 {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<h1>Chapter</h1>
+<h2>Paragraph</h2>
+EOT
+
+               # Create objects
+       my $toc1         = HTML::Toc->new();
+       my $toc2         = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+
+               # Set options
+       $toc1->setOptions({
+               'header'      => '',
+               'footer'      => '',
+               'tokenToToc' => [{'tokenBegin' => '<h1>'}]
+       });
+       $toc2->setOptions({
+               'header'      => '',
+               'footer'      => '',
+               'tokenToToc' => [{'tokenBegin' => '<h2>'}]
+       });
+               # Generate ToC
+       $tocGenerator->generateFromFile([$toc1, $toc2], $filename);
+               # Test ToC
+       ok($toc1->format() . $toc2->format() . "\n", <<'EOT');
+<ul>
+   <li><a href=#h-1>Chapter</a>
+</ul><ul>
+   <li><a href=#h-1>Paragraph</a>
+</ul>
+EOT
+}      # TestGlobalGroups0()
+
+
+#--- TestGlobalGroups1() ------------------------------------------------------
+# function: Test 'HTML::TocGenerator' option 'doUseGroupsGlobal = 0'.
+
+sub TestGlobalGroups1 {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT';
+<h1>Chapter</h1>
+<h2>Paragraph</h2>
+EOT
+       close(FILE);
+
+               # Create objects
+       my $toc1         = HTML::Toc->new();
+       my $toc2         = HTML::Toc->new();
+       my $tocGenerator = HTML::TocGenerator->new();
+
+               # Set options
+       $toc1->setOptions({
+               'header'      => '',
+               'footer'      => '',
+               'tokenToToc' => [{'tokenBegin' => '<h1>'}]
+       });
+       $toc2->setOptions({
+               'header'      => '',
+               'footer'      => '',
+               'tokenToToc' => [{'tokenBegin' => '<h2>'}]
+       });
+               # Generate ToC
+       $tocGenerator->generateFromFile(
+               [$toc1, $toc2], $filename, {'doUseGroupsGlobal' => 1}
+       );
+               # Test ToC
+       ok($toc1->format() . $toc2->format() . "\n", <<'EOT');
+<ul>
+   <li><a href=#h-1>Chapter</a>
+</ul><ul>
+   <li><a href=#h-2>Paragraph</a>
+</ul>
+EOT
+}      # TestGlobalGroups1()
+
+
+#--- TestMultipleGroupsAppendix() ---------------------------------------------
+# function: Test multiple ToCs
+
+sub TestMultipleGroupsAppendix() {
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+       $toc->setOptions({
+               'tokenToToc' => [{
+                               'tokenBegin' => '<h1 class=-appendix>'
+                       }, {
+                               'tokenBegin' => '<h2 class=-appendix>',
+                               'level'      => 2
+                       }, {
+                               'groupId'    => 'appendix',
+                               'tokenBegin' => '<h1 class=appendix>',
+                       }, {
+                               'groupId'    => 'appendix',
+                               'tokenBegin' => '<h2 class=appendix>',
+                               'level'      => 2
+                       }],
+       });
+               # Generate ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+<body>
+   <h1>Chapter</h1>
+   <h2>Paragraph</h2>
+   <h3>Subparagraph</h3>
+   <h1>Chapter</h1>
+   <h1 class=appendix>Appendix Chapter</h1>
+   <h2 class=appendix>Appendix Paragraph</h2>
+</body>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+<body>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Chapter</a>
+   <ul>
+      <li><a href=#h-1.1>Paragraph</a>
+   </ul>
+   <li><a href=#h-2>Chapter</a>
+</ul>
+<ul>
+   <li><a href=#appendix-1>Appendix Chapter</a>
+   <ul>
+      <li><a href=#appendix-1.1>Appendix Paragraph</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+
+   <a name=h-1><h1>Chapter</h1></a>
+   <a name=h-1.1><h2>Paragraph</h2></a>
+   <h3>Subparagraph</h3>
+   <a name=h-2><h1>Chapter</h1></a>
+   <a name=appendix-1><h1 class=appendix>Appendix Chapter</h1></a>
+   <a name=appendix-1.1><h2 class=appendix>Appendix Paragraph</h2></a>
+</body>
+EOT
+}  # TestMultipleGroupsAppendix()
+
+
+#--- TestMultipleGroupsPart() -------------------------------------------------
+# function: Test multiple ToCs
+
+sub TestMultipleGroupsPart() {
+               # Create objects
+       my $toc         = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+       $toc->setOptions({
+               'tokenToToc' => [{
+                               'tokenBegin' => '<h1 class=-part>'
+                       }, {
+                               'tokenBegin' => '<h2 class=-part>',
+                               'level'      => 2,
+                       }, {
+                               'groupId'        => 'part',
+                               'tokenBegin'     => '<h1 class=part>',
+                               'level'          => 1,
+                               'doNumberToken'  => 1,
+                               'numberingStyle' => 'upper-alpha'
+                       }]
+       });
+               # Generate ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+<body>
+   <h1 class=part>First Part</h1>
+   <h1>Chapter</h1>
+   <h2>Paragraph</h2>
+   <h1 class=part>Second Part</h1>
+   <h1>Chapter</h1>
+   <h2>Paragraph</h2>
+</body>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+<body>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#part-A>First Part</a>
+</ul>
+<ul>
+   <li><a href=#h-1>Chapter</a>
+   <ul>
+      <li><a href=#h-1.1>Paragraph</a>
+   </ul>
+</ul>
+<ul>
+   <li><a href=#part-B>Second Part</a>
+</ul>
+<ul>
+   <li><a href=#h-2>Chapter</a>
+   <ul>
+      <li><a href=#h-2.1>Paragraph</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+
+   <a name=part-A><h1 class=part>A &nbsp;First Part</h1></a>
+   <a name=h-1><h1>Chapter</h1></a>
+   <a name=h-1.1><h2>Paragraph</h2></a>
+   <a name=part-B><h1 class=part>B &nbsp;Second Part</h1></a>
+   <a name=h-2><h1>Chapter</h1></a>
+   <a name=h-2.1><h2>Paragraph</h2></a>
+</body>
+EOT
+}  # TestMultipleGroupsPart()
+
+
+#--- TestMultipleTocs() -------------------------------------------------------
+# function: Test multiple ToCs
+
+sub TestMultipleTocs() {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<body>
+   <h1>Header One</h1>
+   <img src=test1.gif alt="First picture">
+   <h2>Paragraph One</h2>
+   <img src=test2.gif alt="Second picture">
+</body>
+EOT
+
+               # Create objects
+       my $toc1        = HTML::Toc->new();
+       my $toc2        = HTML::Toc->new();
+       my $tocInsertor = HTML::TocInsertor->new();
+       my $output;
+       
+               # Set ToC options
+       $toc2->setOptions({
+               'tokenToToc'             => [{
+                       'groupId'    => 'image',
+                       'tokenBegin' => '<img alt=@>'
+               }],
+       });
+               # Generate ToC
+       $tocInsertor->insertIntoFile(
+               [$toc1, $toc2], $filename, {'output' => \$output}
+       );
+               # Test ToC
+       ok($output, <<EOT);
+<body>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1>Header One</a>
+   <ul>
+      <li><a href=#h-1.1>Paragraph One</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#image-1>First picture</a>
+   <li><a href=#image-2>Second picture</a>
+</ul>
+<!-- End of generated Table of Contents -->
+
+   <a name=h-1><h1>Header One</h1></a>
+   <a name=image-1><img src=test1.gif alt="First picture"></a>
+   <a name=h-1.1><h2>Paragraph One</h2></a>
+   <a name=image-2><img src=test2.gif alt="Second picture"></a>
+</body>
+EOT
+}  # TestMultipleTocs()
+
+
+#--- TestSpecifyNumberedList() ------------------------------------------------
+# function: Test specifying numbered list.
+
+sub TestSpecifyNumberedList {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<body>
+   <h1>Chapter</h1>
+       <h2>Paragraph</h2>
+</body>
+EOT
+
+               # Create objects
+       my $toc        = HTML::Toc->new();
+   my $tocGenerator = HTML::TocGenerator->new();
+       
+               # Set ToC options
+       $toc->setOptions({
+               'templateLevelBegin' => '"<ol>\n"',
+               'templateLevelEnd'   => '"</ol>\n"',
+       });
+               # Generate ToC
+       $tocGenerator->generateFromFile($toc, $filename);
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol>
+   <li><a href=#h-1>Chapter</a>
+   <ol>
+      <li><a href=#h-1.1>Paragraph</a>
+   </ol>
+</ol>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestSpecifyNumberedList()
+
+
+#--- TestUpdateFile() ---------------------------------------------------------
+# function: Test 'HTML::TocUpdator->updateFile()'
+
+sub TestUpdateFile {
+               # Assemble test file
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<html>
+<body><!-- #BeginToc -->
+foo
+<!-- #EndToc -->
+   <!-- #BeginTocAnchorNameBegin -->bar<!-- #EndTocAnchorNameBegin --><h1>
+   Chapter
+   </h1><!-- #BeginTocAnchorNameEnd -->foo<!-- #EndTocAnchorNameEnd -->
+</body>
+</html>
+EOT
+
+               # Create objects
+       my $toc        = HTML::Toc->new();
+       my $tocUpdator = HTML::TocUpdator->new();
+       my $output;
+       
+               # Generate ToC
+       $tocUpdator->updateFile($toc, $filename, {'output' => \$output});
+               # Test ToC
+       ok($output, <<EOT);
+<html>
+<body><!-- #BeginToc -->
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=#h-1> Chapter </a>
+</ul>
+<!-- End of generated Table of Contents -->
+<!-- #EndToc -->
+   <!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1>
+   Chapter
+   </h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+</body>
+</html>
+EOT
+}  # TestUpdateFile()
+
+
+#--- TestUsingCSS() -----------------------------------------------------------
+# function: Test multiple ToCs
+
+sub TestUsingCSS() {
+
+               # Create objects
+       my $toc          = new HTML::Toc;
+       my $tocInsertor  = new HTML::TocInsertor;
+       my $output;
+
+   $toc->setOptions({
+               'templateLevelBegin'   => '"<ol class=toc_$groupId$level>\n"',
+               'templateLevelEnd'     => '"</ol>\n"',
+               'doNumberToken'        => 1,
+      'tokenToToc' => [{
+                               'groupId'        => 'appendix',
+            'tokenBegin'     => '<h1>',
+                               'numberingStyle' => 'upper-alpha'
+                       }, {
+                               'groupId'        => 'appendix',
+            'tokenBegin'         => '<h2>',
+            'level'              => 2,
+         }]
+   });
+       $tocInsertor->insert($toc, <<EOT);
+<html>
+<head>
+   <style type="text/css">
+      ol.toc_appendix1 { list-style-type: upper-alpha }
+   </style>
+</head>
+<body>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+</body>
+</html>
+EOT
+               # Insert ToC
+       $tocInsertor->insert($toc, <<EOT, {'output' => \$output});
+<html>
+<head>
+   <style type="text/css">
+      ol.toc_appendix1 { list-style-type: upper-alpha }
+   </style>
+</head>
+<body>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+   <h1>Appendix</h1>
+   <h2>Appendix Paragraph</h2>
+</body>
+</html>
+EOT
+               # Test ToC
+       ok($output, <<EOT);
+<html>
+<head>
+   <style type="text/css">
+      ol.toc_appendix1 { list-style-type: upper-alpha }
+   </style>
+</head>
+<body>
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ol class=toc_appendix1>
+   <li><a href=#appendix-A>Appendix</a>
+   <ol class=toc_appendix2>
+      <li><a href=#appendix-A.1>Appendix Paragraph</a>
+   </ol>
+   <li><a href=#appendix-B>Appendix</a>
+   <ol class=toc_appendix2>
+      <li><a href=#appendix-B.1>Appendix Paragraph</a>
+   </ol>
+</ol>
+<!-- End of generated Table of Contents -->
+
+   <a name=appendix-A><h1>A &nbsp;Appendix</h1></a>
+   <a name=appendix-A.1><h2>A.1 &nbsp;Appendix Paragraph</h2></a>
+   <a name=appendix-B><h1>B &nbsp;Appendix</h1></a>
+   <a name=appendix-B.1><h2>B.1 &nbsp;Appendix Paragraph</h2></a>
+</body>
+</html>
+EOT
+}  # TestUsingCSS()
+
+
+       # Test 'extendFromFile()'
+TestExtendFromFile();
+       # Test 'generateFromFile()'
+TestGenerateFromFile();
+       # Test 'generateFromFiles()'
+TestGenerateFromFiles();
+       # Test 'doUseGroupsGlobal = 0'
+TestGlobalGroups0();
+       # Test 'doUseGroupsGlobal = 1'
+TestGlobalGroups1();
+       # Test 'tocInsertor->insertIntoFile'
+TestInsertIntoFile();
+       # Test 'tocUpdator->insertIntoFile'
+TestInsertIntoFileUsingTocUpdator();
+       # Test additional 'appendix' group
+TestMultipleGroupsAppendix();
+       # Test additional 'part' group
+TestMultipleGroupsPart();
+       # Test multiple ToCs
+TestMultipleTocs();
+       # Test specifying numbered list
+TestSpecifyNumberedList();
+       # Test 'updateFile()'
+TestUpdateFile();
+       # Test using CSS
+TestUsingCSS();
diff --git a/examples/includes/HTML-Toc-0.91/t/propagate.t b/examples/includes/HTML-Toc-0.91/t/propagate.t
new file mode 100644 (file)
index 0000000..63de18d
--- /dev/null
@@ -0,0 +1,176 @@
+#--- propagate.t --------------------------------------------------------------
+# function: Test ToC propagation.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 10; }
+
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+
+my ($output, $content, $filename);
+my $toc          = HTML::Toc->new;
+my $tocGenerator = HTML::TocGenerator->new;
+my $tocInsertor  = HTML::TocInsertor->new;
+
+$toc->setOptions({
+       'doLinkToToken'  => 0,
+       'levelIndent'    => 0,
+       'insertionPoint' => 'before <h1>',
+       'header'         => '',
+       'footer'         => '',
+});
+
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<h1>Header</h1>
+EOT
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- 1. propagate -------------------------------------------------------------
+
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+ok($output, "<ul>\n<li>Header\n</ul><h1>Header</h1>");
+
+
+#--- 2. propagateFile ---------------------------------------------------------
+
+$tocInsertor->insertIntoFile($toc, $filename, {'output' => \$output});
+ok($output, "<ul>\n<li>Header\n</ul><h1>Header</h1>\n");
+
+
+#--- 3. doLinkToToken -----------------------------------------------------
+
+$toc->setOptions({'doLinkToToken' => 1});
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+ok("$output\n", <<'EOT');
+<ul>
+<li><a href=#h-1>Header</a>
+</ul><a name=h-1><h1>Header</h1></a>
+EOT
+
+
+#--- 4. templateAnchorHrefBegin -----------------------------------------------
+
+$toc->setOptions(
+       {'templateAnchorHrefBegin' => '"<$node${file}test${groupId}>"'}
+);
+$tocInsertor->insertIntoFile($toc, $filename, {'output' => \$output});
+ok($output, "<ul>\n<li><1${filename}testh>Header</a>\n</ul><a name=h-1><h1>Header</h1></a>\n");
+$toc->setOptions({'templateAnchorHrefBegin' => undef});
+
+
+#--- 5. templateAnchorNameBegin -----------------------------------------------
+
+$toc->setOptions({
+       'templateAnchorName'      => '"$node$groupId"',
+       'templateAnchorNameBegin' => '"<$anchorName>"'
+});
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+ok($output, "<ul>\n<li><a href=#1h>Header</a>\n</ul><1h><h1>Header</h1></a>");
+$toc->setOptions({'templateAnchorName' => undef});
+
+
+#--- 6. templateAnchorName function -------------------------------------------
+
+sub AssembleAnchorName {
+               # Get arguments
+       my ($aFile, $aGroupId, $aLevel, $aNode) = @_;
+               # Return value
+       return $aFile . $aGroupId . $aLevel . $aNode;
+}  # AssembleAnchorName()
+
+       # Set options
+$toc->setOptions({'templateAnchorNameBegin' => \&AssembleAnchorName});
+       # Propagate ToC
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+       # Test ToC
+ok($output, "<ul>\n<li><a href=#h-1>Header</a>\n</ul>h11<h1>Header</h1></a>");
+       # Restore options
+$toc->setOptions({'templateAnchorNameBegin' => undef});
+
+
+#--- 7. doNumberToken --------------------------------------------------------
+
+       # Set options
+$toc->setOptions({'doNumberToken' => 1});
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+ok("$output\n", <<'EOT');
+<ul>
+<li><a href=#h-1>Header</a>
+</ul><a name=h-1><h1>1 &nbsp;Header</h1></a>
+EOT
+       # Reset options
+$toc->setOptions({
+       'templateTokenNumber' => undef,
+       'doNumberToken'      => 0
+});
+
+
+#--- 8. templateTokenNumber ---------------------------------------------------
+
+       # Set options
+$toc->setOptions({
+       'templateTokenNumber' => '"-$node-"',
+       'doNumberToken'      => 1
+});
+       # Propagate ToC
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+       # Test ToC
+ok("$output\n", <<'EOT');
+<ul>
+<li><a href=#h-1>Header</a>
+</ul><a name=h-1><h1>-1-Header</h1></a>
+EOT
+       # Reset options
+$toc->setOptions({
+       'doNumberToken'      => 0,
+       'templateTokenNumber' => undef
+});
+
+
+#--- 9. numberingStyle --------------------------------------------------------
+
+       # Set options
+$toc->setOptions({
+       'doNumberToken' => 1,
+       'tokenToToc' => [{
+               'level' => 1,
+               'tokenBegin' => '<h1>',
+               'numberingStyle' => 'lower-alpha'
+       }]
+});
+       # Propagate ToC
+$tocInsertor->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+       # Test ToC
+ok("$output\n", <<'EOT');
+<ul>
+<li><a href=#h-a>Header</a>
+</ul><a name=h-a><h1>a &nbsp;Header</h1></a>
+EOT
+       # Reset options
+$toc->setOptions({
+       'doNumberToken' => 0,
+       'tokenToToc' => undef,
+});
+
+
+#--- 10. declaration pass through ---------------------------------------------
+
+$tocInsertor->insert($toc, '<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><h1>Header</h1>', {'output' => \$output});
+       # Test ToC
+ok($output, '<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><h1>Header</h1>');
diff --git a/examples/includes/HTML-Toc-0.91/t/siteMap.t b/examples/includes/HTML-Toc-0.91/t/siteMap.t
new file mode 100644 (file)
index 0000000..074f0bd
--- /dev/null
@@ -0,0 +1,97 @@
+#--- manual.t -----------------------------------------------------------------
+# function: Test HTML::ToC generating a manual.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 1; }
+
+use Data::Dumper;
+use File::Find;
+use HTML::Toc;
+use HTML::TocGenerator;
+use HTML::TocInsertor;
+use HTML::TocUpdator;
+
+
+       # Create objects
+my $toc          = HTML::Toc->new();
+my $tocGenerator = HTML::TocGenerator->new();
+my @fileList;
+
+
+#--- TestSiteMap() ------------------------------------------------------------
+# function: Test specifying numbered list.
+
+sub TestSiteMap {
+               # Set ToC options
+       $toc->setOptions({
+               'doLinkToFile'       => 1,
+               'templateAnchorName' => '""',
+               'templateAnchorHref' => '"<a href=$file"."#".$groupId.$level.">"',
+               'doLinkTocToToken'   => 1,
+               'tokenToToc'         => [{
+                       'groupId'         => 'dir',
+                       'level'           => 1,
+                       'tokenBegin'      => '<title>',
+                       'tokenEnd'        => '</title>',
+                       'fileSpec'        => '\./[^/]+$'
+               }, {
+                       'groupId'         => 'dir',
+                       'level'           => 2,
+                       'tokenBegin'      => '<title>',
+                       'tokenEnd'        => '</title>',
+                       'fileSpec'        => '\./[^/]+?/[^/]+$'
+               }, {
+                       'groupId'         => 'dir',
+                       'level'           => 3,
+                       'tokenBegin'      => '<title>',
+                       'tokenEnd'        => '</title>',
+                       'fileSpec'        => '\./[^/]+?/[^/]+?/[^/]+$'
+               }]
+       });
+               # Change current directory
+       chdir("t/SiteMap");
+               # Find files, filling 'fileList'
+       find({wanted => \&WantedSiteMap, no_chdir => 1}, '.');
+               # Generate ToC of case-insensitively sorted file list
+       $tocGenerator->extendFromFile(
+               $toc, [sort {uc($a) cmp uc($b)} @fileList]
+       );
+               # Restore current directory
+       chdir("../..");
+               # Test ToC
+       ok($toc->format(), <<EOT);
+
+<!-- Table of Contents generated by Perl - HTML::Toc -->
+<ul>
+   <li><a href=./index.htm#>Main</a>
+   <ul>
+      <li><a href=./SubDir1/index.htm#>Sub1</a>
+      <ul>
+         <li><a href=./SubDir1/SubSubDir1/index.htm#>SubSub1</a>
+      </ul>
+      <li><a href=./SubDir2/index.htm#>Sub2</a>
+      <ul>
+         <li><a href=./SubDir2/SubSubDir1/index.htm#>SubSub1</a>
+         <li><a href=./SubDir2/SubSubDir2/index.htm#>SubSub2</a>
+      </ul>
+      <li><a href=./SubDir3/index.htm#>Sub3</a>
+   </ul>
+</ul>
+<!-- End of generated Table of Contents -->
+EOT
+}  # TestSiteMap()
+
+
+#--- WantedSiteMap() ----------------------------------------------------------
+# function: 'Wanted' function, used by File::Find of 'TestSiteMap()'.
+
+sub WantedSiteMap {
+               # Add file to 'fileList' if extension matches '.htm'
+       push (@fileList, $File::Find::name) if (m/\.htm$/);
+} # WantedSiteMap()
+
+
+       # Test site map
+TestSiteMap();
diff --git a/examples/includes/HTML-Toc-0.91/t/update.t b/examples/includes/HTML-Toc-0.91/t/update.t
new file mode 100644 (file)
index 0000000..e4777b6
--- /dev/null
@@ -0,0 +1,114 @@
+#--- update.t -----------------------------------------------------------------
+# function: Test ToC updating.
+
+use strict;
+use Test;
+
+BEGIN { plan tests => 6; }
+
+use HTML::Toc;
+use HTML::TocUpdator;
+
+my ($output, $output2, $content, $filename);
+my $toc         = HTML::Toc->new;
+my $tocUpdator  = HTML::TocUpdator->new;
+
+$toc->setOptions({
+       'doLinkToToken'  => 1,
+       'doNumberToken'  => 1,
+       'levelIndent'    => 0,
+       'insertionPoint' => 'before <h1>',
+       'header'         => '',
+       'footer'         => '',
+});
+
+
+BEGIN {
+               # Create test file
+       $filename = "file$$.htm";
+       die "$filename is already there" if -e $filename;
+       open(FILE, ">$filename") || die "Can't create $filename: $!";
+       print FILE <<'EOT'; close(FILE);
+<h1>Header</h1>
+EOT
+}
+
+
+END {
+               # Remove test file
+       unlink($filename) or warn "Can't unlink $filename: $!";
+}
+
+
+#--- 1. update ----------------------------------------------------------------
+
+$tocUpdator->update($toc, "<h1>Header</h1>", {'output' => \$output});
+ok("$output\n", <<'EOT');
+<!-- #BeginToc --><ul>
+<li><a href=#h-1>Header</a>
+</ul><!-- #EndToc --><!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Header</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+EOT
+
+#--- 2. updateFile ------------------------------------------------------------
+
+$tocUpdator->updateFile($toc, $filename, {'output' => \$output});
+       open(FILE, ">a.out1") || die "Can't create a.out1: $!";
+       print FILE $output; close(FILE);
+$output2 = <<'EOT';
+<!-- #BeginToc --><ul>
+<li><a href=#h-1>Header</a>
+</ul><!-- #EndToc --><!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Header</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+EOT
+       open(FILE, ">a.out2") || die "Can't create a.out2: $!";
+       print FILE $output2; close(FILE);
+ok($output, $output2);
+
+
+#--- 3. insert ----------------------------------------------------------------
+
+$tocUpdator->insert($toc, "<h1>Header</h1>", {'output' => \$output});
+ok("$output\n", <<'EOT');
+<!-- #BeginToc --><ul>
+<li><a href=#h-1>Header</a>
+</ul><!-- #EndToc --><!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Header</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+EOT
+
+#--- 4. insertIntoFile --------------------------------------------------------
+
+$tocUpdator->insertIntoFile($toc, $filename, {'output' => \$output});
+ok($output, <<'EOT');
+<!-- #BeginToc --><ul>
+<li><a href=#h-1>Header</a>
+</ul><!-- #EndToc --><!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Header</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+EOT
+
+
+#--- 5. update twice ----------------------------------------------------------
+
+$tocUpdator->update($toc, "<h1>Header</h1>", {'output' => \$output});
+$tocUpdator->update($toc, $output, {'output' => \$output2});
+ok("$output\n", <<'EOT');
+<!-- #BeginToc --><ul>
+<li><a href=#h-1>Header</a>
+</ul><!-- #EndToc --><!-- #BeginTocAnchorNameBegin --><a name=h-1><!-- #EndTocAnchorNameBegin --><h1><!-- #BeginTocNumber -->1 &nbsp;<!-- #EndTocNumber -->Header</h1><!-- #BeginTocAnchorNameEnd --></a><!-- #EndTocAnchorNameEnd -->
+EOT
+
+
+#--- 6. tokens update begin & end ---------------------------------------------
+
+$toc->setOptions({
+       'tokenUpdateBeginOfAnchorNameBegin' => '<tocAnchorNameBegin>',
+       'tokenUpdateEndOfAnchorNameBegin'   => '</tocAnchorNameBegin>',
+       'tokenUpdateBeginOfAnchorNameEnd'   => '<tocAnchorNameEnd>',
+       'tokenUpdateEndOfAnchorNameEnd'     => '</tocAnchorNameEnd>',
+       'tokenUpdateBeginNumber'            => '<tocNumber>',
+       'tokenUpdateEndNumber'              => '</tocNumber>',
+       'tokenUpdateBeginToc'               => '<toc>',
+       'tokenUpdateEndToc',                => '</toc>'
+});
+$tocUpdator->update($toc, "<h1>Header</h1>", {'output' => \$output});
+ok("$output\n", <<'EOT');
+<toc><ul>
+<li><a href=#h-1>Header</a>
+</ul></toc><tocAnchorNameBegin><a name=h-1></tocAnchorNameBegin><h1><tocNumber>1 &nbsp;</tocNumber>Header</h1><tocAnchorNameEnd></a></tocAnchorNameEnd>
+EOT
diff --git a/examples/includes/PHP-Markdown-Extra-1.2.3/License.text b/examples/includes/PHP-Markdown-Extra-1.2.3/License.text
new file mode 100644 (file)
index 0000000..52c868b
--- /dev/null
@@ -0,0 +1,36 @@
+PHP Markdown & Extra
+Copyright (c) 2004-2008 Michel Fortin  
+<http://www.michelf.com/>  
+All rights reserved.
+
+Based on Markdown  
+Copyright (c) 2003-2006 John Gruber   
+<http://daringfireball.net/>   
+All rights reserved.
+
+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 "Markdown" 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 copyright owner
+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.
diff --git a/examples/includes/PHP-Markdown-Extra-1.2.3/PHP Markdown Extra Readme.text b/examples/includes/PHP-Markdown-Extra-1.2.3/PHP Markdown Extra Readme.text
new file mode 100644 (file)
index 0000000..a1c520e
--- /dev/null
@@ -0,0 +1,731 @@
+PHP Markdown Extra
+==================
+
+Version 1.2.3 - Wed 31 Dec 2008
+
+by Michel Fortin
+<http://www.michelf.com/>
+
+based on Markdown by John Gruber  
+<http://daringfireball.net/>
+
+
+Introduction
+------------
+
+This is a special version of PHP Markdown with extra features. See
+<http://www.michelf.com/projects/php-markdown/extra/> for details.
+
+Markdown is a text-to-HTML conversion tool for web writers. Markdown
+allows you to write using an easy-to-read, easy-to-write plain text
+format, then convert it to structurally valid XHTML (or HTML).
+
+"Markdown" is two things: a plain text markup syntax, and a software 
+tool, written in Perl, that converts the plain text markup to HTML. 
+PHP Markdown is a port to PHP of the original Markdown program by 
+John Gruber.
+
+PHP Markdown can work as a plug-in for WordPress and bBlog, as a 
+modifier for the Smarty templating engine, or as a remplacement for
+textile formatting in any software that support textile.
+
+Full documentation of Markdown's syntax is available on John's 
+Markdown page: <http://daringfireball.net/projects/markdown/>
+
+
+Installation and Requirement
+----------------------------
+
+PHP Markdown requires PHP version 4.0.5 or later.
+
+
+### WordPress ###
+
+PHP Markdown works with [WordPress][wp], version 1.2 or later.
+
+ [wp]: http://wordpress.org/
+
+1.  To use PHP Markdown with WordPress, place the "makrdown.php" file 
+    in the "plugins" folder. This folder is located inside 
+    "wp-content" at the root of your site:
+
+        (site home)/wp-content/plugins/
+
+2.  Activate the plugin with the administrative interface of 
+    WordPress. In the "Plugins" section you will now find Markdown. 
+    To activate the plugin, click on the "Activate" button on the 
+    same line than Markdown. Your entries will now be formatted by 
+    PHP Markdown.
+
+3.  To post Markdown content, you'll first have to disable the 
+       "visual" editor in the User section of WordPress.
+
+You can configure PHP Markdown to not apply to the comments on your 
+WordPress weblog. See the "Configuration" section below.
+
+It is not possible at this time to apply a different set of 
+filters to different entries. All your entries will be formated by 
+PHP Markdown. This is a limitation of WordPress. If your old entries 
+are written in HTML (as opposed to another formatting syntax, like 
+Textile), they'll probably stay fine after installing Markdown.
+
+
+### bBlog ###
+
+PHP Markdown also works with [bBlog][bb].
+
+ [bb]: http://www.bblog.com/
+
+To use PHP Markdown with bBlog, rename "markdown.php" to 
+"modifier.markdown.php" and place the file in the "bBlog_plugins" 
+folder. This folder is located inside the "bblog" directory of 
+your site, like this:
+
+        (site home)/bblog/bBlog_plugins/modifier.markdown.php
+
+Select "Markdown" as the "Entry Modifier" when you post a new 
+entry. This setting will only apply to the entry you are editing.
+
+
+### Replacing Textile in TextPattern ###
+
+[TextPattern][tp] use [Textile][tx] to format your text. You can 
+replace Textile by Markdown in TextPattern without having to change
+any code by using the *Texitle Compatibility Mode*. This may work 
+with other software that expect Textile too.
+
+ [tx]: http://www.textism.com/tools/textile/
+ [tp]: http://www.textpattern.com/
+
+1.  Rename the "markdown.php" file to "classTextile.php". This will
+       make PHP Markdown behave as if it was the actual Textile parser.
+
+2.  Replace the "classTextile.php" file TextPattern installed in your
+       web directory. It can be found in the "lib" directory:
+
+               (site home)/textpattern/lib/
+
+Contrary to Textile, Markdown does not convert quotes to curly ones 
+and does not convert multiple hyphens (`--` and `---`) into en- and 
+em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you 
+can solve this problem by installing the "smartypants.php" file from 
+[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile 
+Compatibility Mode function will use SmartyPants automatically without 
+further modification.
+
+ [psp]: http://www.michelf.com/projects/php-smartypants/
+
+
+### In Your Own Programs ###
+
+You can use PHP Markdown easily in your current PHP program. Simply 
+include the file and then call the Markdown function on the text you 
+want to convert:
+
+    include_once "markdown.php";
+    $my_html = Markdown($my_text);
+
+If you wish to use PHP Markdown with another text filter function 
+built to parse HTML, you should filter the text *after* the Markdown
+function call. This is an example with [PHP SmartyPants][psp]:
+
+    $my_html = SmartyPants(Markdown($my_text));
+
+
+### With Smarty ###
+
+If your program use the [Smarty][sm] template engine, PHP Markdown 
+can now be used as a modifier for your templates. Rename "markdown.php" 
+to "modifier.markdown.php" and put it in your smarty plugins folder.
+
+  [sm]: http://smarty.php.net/
+
+If you are using MovableType 3.1 or later, the Smarty plugin folder is 
+located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow 
+Markdown to work on dynamic pages.
+
+
+### Updating Markdown in Other Programs ###
+
+Many web applications now ship with PHP Markdown, or have plugins to 
+perform the conversion to HTML. You can update PHP Markdown -- or 
+replace it with PHP Markdown Extra -- in many of these programs by 
+swapping the old "markdown.php" file for the new one.
+
+Here is a short non-exhaustive list of some programs and where they 
+hide the "markdown.php" file.
+
+| Program   | Path to Markdown
+| -------   | ----------------
+| [Pivot][] | `(site home)/pivot/includes/markdown/`
+
+If you're unsure if you can do this with your application, ask the 
+developer, or wait for the developer to update his application or 
+plugin with the new version of PHP Markdown.
+
+ [Pivot]: http://pivotlog.net/
+
+
+Configuration
+-------------
+
+By default, PHP Markdown produces XHTML output for tags with empty 
+elements. E.g.:
+
+    <br />
+
+Markdown can be configured to produce HTML-style tags; e.g.:
+
+    <br>
+
+To do this, you  must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX" 
+definition below the "Global default settings" header at the start of 
+the "markdown.php" file.
+
+
+### WordPress-Specific Settings ###
+
+By default, the Markdown plugin applies to both posts and comments on 
+your WordPress weblog. To deactivate one or the other, edit the 
+`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the 
+"WordPress settings" header at the start of the "markdown.php" file.
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+<michel.fortin@michelf.com>
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output PHP Markdown actually produced.
+
+
+Version History
+---------------
+
+Extra 1.2.3 (31 Dec 2008):
+
+*      In WordPress pages featuring more than one post, footnote id prefixes are 
+       now automatically applied with the current post ID to avoid clashes
+       between footnotes belonging to different posts.
+
+*      Fix for a bug introduced in Extra 1.2 where block-level HTML tags where 
+       not detected correctly, thus the addition of erroneous `<p>` tags and
+       interpretation of their content as Markdown-formatted instead of
+       HTML-formatted.
+
+
+Extra 1.2.2 (21 Jun 2008):
+
+*      Fixed a problem where abbreviation definitions, footnote
+       definitions and link references were stripped inside
+       fenced code blocks.
+
+*      Fixed a bug where characters such as `"` in abbreviation
+       definitions weren't properly encoded to HTML entities.
+
+*      Fixed a bug where double quotes `"` were not correctly encoded
+       as HTML entities when used inside a footnote reference id.
+
+
+1.0.1m (21 Jun 2008):
+
+*      Lists can now have empty items.
+
+*      Rewrote the emphasis and strong emphasis parser to fix some issues
+       with odly placed and overlong markers.
+
+
+Extra 1.2.1 (27 May 2008):
+
+*      Fixed a problem where Markdown headers and horizontal rules were
+       transformed into their HTML equivalent inside fenced code blocks.
+
+
+Extra 1.2 (11 May 2008):
+
+*      Added fenced code block syntax which don't require indentation
+       and can start and end with blank lines. A fenced code block
+       starts with a line of consecutive tilde (~) and ends on the
+       next line with the same number of consecutive tilde. Here's an
+       example:
+       
+           ~~~~~~~~~~~~
+               Hello World!
+               ~~~~~~~~~~~~
+
+*      Rewrote parts of the HTML block parser to better accomodate
+       fenced code blocks.
+
+*      Footnotes may now be referenced from within another footnote.
+
+*      Added programatically-settable parser property `predef_attr` for 
+       predefined attribute definitions.
+
+*      Fixed an issue where an indented code block preceded by a blank
+       line containing some other whitespace would confuse the HTML 
+       block parser into creating an HTML block when it should have 
+       been code.
+
+
+1.0.1l (11 May 2008):
+
+*      Now removing the UTF-8 BOM at the start of a document, if present.
+
+*      Now accepting capitalized URI schemes (such as HTTP:) in automatic
+       links, such as `<HTTP://EXAMPLE.COM/>`.
+
+*      Fixed a problem where `<hr@example.com>` was seen as a horizontal
+       rule instead of an automatic link.
+
+*      Fixed an issue where some characters in Markdown-generated HTML
+       attributes weren't properly escaped with entities.
+
+*      Fix for code blocks as first element of a list item. Previously,
+       this didn't create any code block for item 2:
+       
+               *   Item 1 (regular paragraph)
+               
+               *       Item 2 (code block)
+
+*      A code block starting on the second line of a document wasn't seen
+       as a code block. This has been fixed.
+       
+*      Added programatically-settable parser properties `predef_urls` and 
+       `predef_titles` for predefined URLs and titles for reference-style 
+       links. To use this, your PHP code must call the parser this way:
+       
+               $parser = new Markdwon_Parser;
+               $parser->predef_urls = array('linkref' => 'http://example.com');
+               $html = $parser->transform($text);
+       
+       You can then use the URL as a normal link reference:
+       
+               [my link][linkref]      
+               [my link][linkRef]
+               
+       Reference names in the parser properties *must* be lowercase.
+       Reference names in the Markdown source may have any case.
+
+*      Added `setup` and `teardown` methods which can be used by subclassers
+       as hook points to arrange the state of some parser variables before and 
+       after parsing.
+
+
+Extra 1.1.7 (26 Sep 2007):
+
+1.0.1k (26 Sep 2007):
+
+*      Fixed a problem introduced in 1.0.1i where three or more identical
+       uppercase letters, as well as a few other symbols, would trigger
+       a horizontal line.
+
+
+Extra 1.1.6 (4 Sep 2007):
+
+1.0.1j (4 Sep 2007):
+
+*      Fixed a problem introduced in 1.0.1i where the closing `code` and 
+       `pre` tags at the end of a code block were appearing in the wrong 
+       order.
+
+*      Overriding configuration settings by defining constants from an 
+       external before markdown.php is included is now possible without 
+       producing a PHP warning.
+
+
+Extra 1.1.5 (31 Aug 2007):
+
+1.0.1i (31 Aug 2007):
+
+*      Fixed a problem where an escaped backslash before a code span 
+       would prevent the code span from being created. This should now
+       work as expected:
+       
+               Litteral backslash: \\`code span`
+
+*      Overall speed improvements, especially with long documents.
+
+
+Extra 1.1.4 (3 Aug 2007):
+
+1.0.1h (3 Aug 2007):
+
+*      Added two properties (`no_markup` and `no_entities`) to the parser 
+       allowing HTML tags and entities to be disabled.
+
+*      Fix for a problem introduced in 1.0.1g where posting comments in 
+       WordPress would trigger PHP warnings and cause some markup to be 
+       incorrectly filtered by the kses filter in WordPress.
+
+
+Extra 1.1.3 (3 Jul 2007):
+
+*      Fixed a performance problem when parsing some invalid HTML as an HTML 
+       block which was resulting in too much recusion and a segmentation fault 
+       for long documents.
+
+*      The markdown="" attribute now accepts unquoted values.
+
+*      Fixed an issue where underscore-emphasis didn't work when applied on the 
+       first or the last word of an element having the markdown="1" or 
+       markdown="span" attribute set unless there was some surrounding whitespace.
+       This didn't work:
+       
+               <p markdown="1">_Hello_ _world_</p>
+       
+       Now it does produce emphasis as expected.
+
+*      Fixed an issue preventing footnotes from working when the parser's 
+       footnote id prefix variable (fn_id_prefix) is not empty.
+
+*      Fixed a performance problem where the regular expression for strong 
+       emphasis introduced in version 1.1 could sometime be long to process, 
+       give slightly wrong results, and in some circumstances could remove 
+       entirely the content for a whole paragraph.
+
+*      Fixed an issue were abbreviations tags could be incorrectly added 
+       inside URLs and title of links.
+
+*      Placing footnote markers inside a link, resulting in two nested links, is 
+       no longer allowed.
+
+
+1.0.1g (3 Jul 2007):
+
+*      Fix for PHP 5 compiled without the mbstring module. Previous fix to 
+       calculate the length of UTF-8 strings in `detab` when `mb_strlen` is 
+       not available was only working with PHP 4.
+
+*      Fixed a problem with WordPress 2.x where full-content posts in RSS feeds 
+       were not processed correctly by Markdown.
+
+*      Now supports URLs containing literal parentheses for inline links 
+       and images, such as:
+
+               [WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
+
+       Such parentheses may be arbitrarily nested, but must be
+       balanced. Unbalenced parentheses are allowed however when the URL 
+       when escaped or when the URL is enclosed in angle brakets `<>`.
+
+*      Fixed a performance problem where the regular expression for strong 
+       emphasis introduced in version 1.0.1d could sometime be long to process, 
+       give slightly wrong results, and in some circumstances could remove 
+       entirely the content for a whole paragraph.
+
+*      Some change in version 1.0.1d made possible the incorrect nesting of 
+       anchors within each other. This is now fixed.
+
+*      Fixed a rare issue where certain MD5 hashes in the content could
+       be changed to their corresponding text. For instance, this:
+
+               The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
+       
+       was incorrectly changed to this in previous versions of PHP Markdown:
+
+               <p>The MD5 value for "+" is "+".</p>
+
+*      Now convert escaped characters to their numeric character 
+       references equivalent.
+       
+       This fix an integration issue with SmartyPants and backslash escapes. 
+       Since Markdown and SmartyPants have some escapable characters in common, 
+       it was sometime necessary to escape them twice. Previously, two 
+       backslashes were sometime required to prevent Markdown from "eating" the 
+       backslash before SmartyPants sees it:
+       
+               Here are two hyphens: \\--
+       
+       Now, only one backslash will do:
+       
+               Here are two hyphens: \--
+
+
+Extra 1.1.2 (7 Feb 2007)
+
+*      Fixed an issue where headers preceded too closely by a paragraph 
+       (with no blank line separating them) where put inside the paragraph.
+
+*      Added the missing TextileRestricted method that was added to regular
+       PHP Markdown since 1.0.1d but which I forgot to add to Extra.
+
+
+1.0.1f (7 Feb 2007):
+
+*      Fixed an issue with WordPress where manually-entered excerpts, but 
+       not the auto-generated ones, would contain nested paragraphs.
+
+*      Fixed an issue introduced in 1.0.1d where headers and blockquotes 
+       preceded too closely by a paragraph (not separated by a blank line) 
+       where incorrectly put inside the paragraph.
+
+*      Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where 
+       two consecutive code spans would be merged into one when together they 
+       form a valid tag in a multiline paragraph.
+
+*      Fixed an long-prevailing issue where blank lines in code blocks would 
+       be doubled when the code block is in a list item.
+       
+       This was due to the list processing functions relying on artificially 
+       doubled blank lines to correctly determine when list items should 
+       contain block-level content. The list item processing model was thus 
+       changed to avoid the need for double blank lines.
+
+*      Fixed an issue with `<% asp-style %>` instructions used as inline 
+       content where the opening `<` was encoded as `&lt;`.
+
+*      Fixed a parse error occuring when PHP is configured to accept 
+       ASP-style delimiters as boundaries for PHP scripts.
+
+*      Fixed a bug introduced in 1.0.1d where underscores in automatic links
+       got swapped with emphasis tags.
+
+
+Extra 1.1.1 (28 Dec 2006)
+
+*      Fixed a problem where whitespace at the end of the line of an atx-style
+       header would cause tailing `#` to appear as part of the header's content.
+       This was caused by a small error in the regex that handles the definition
+       for the id attribute in PHP Markdown Extra.
+
+*      Fixed a problem where empty abbreviations definitions would eat the 
+       following line as its definition.
+
+*      Fixed an issue with calling the Markdown parser repetitivly with text 
+       containing footnotes. The footnote hashes were not reinitialized properly.
+
+
+1.0.1e (28 Dec 2006)
+
+*      Added support for internationalized domain names for email addresses in 
+       automatic link. Improved the speed at which email addresses are converted 
+       to entities. Thanks to Milian Wolff for his optimisations.
+
+*      Made deterministic the conversion to entities of email addresses in 
+       automatic links. This means that a given email address will always be 
+       encoded the same way.
+
+*      PHP Markdown will now use its own function to calculate the length of an 
+       UTF-8 string in `detab` when `mb_strlen` is not available instead of 
+       giving a fatal error.
+
+
+Extra 1.1 (1 Dec 2006)
+
+*      Added a syntax for footnotes.
+
+*      Added an experimental syntax to define abbreviations.
+
+
+1.0.1d (1 Dec 2006)
+
+*   Fixed a bug where inline images always had an empty title attribute. The 
+       title attribute is now present only when explicitly defined.
+
+*      Link references definitions can now have an empty title, previously if the 
+       title was defined but left empty the link definition was ignored. This can 
+       be useful if you want an empty title attribute in images to hide the 
+       tooltip in Internet Explorer.
+
+*      Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now 
+       correctly mapped to one character instead of the number of bytes.
+
+*      Fixed a small bug with WordPress where WordPress' default filter `wpautop`
+       was not properly deactivated on comment text, resulting in hard line breaks
+       where Markdown do not prescribes them.
+
+*      Added a `TextileRestrited` method to the textile compatibility mode. There
+       is no restriction however, as Markdown does not have a restricted mode at 
+       this point. This should make PHP Markdown work again in the latest 
+       versions of TextPattern.
+
+*   Converted PHP Markdown to a object-oriented design.
+
+*      Changed span and block gamut methods so that they loop over a 
+       customizable list of methods. This makes subclassing the parser a more 
+       interesting option for creating syntax extensions.
+
+*      Also added a "document" gamut loop which can be used to hook document-level 
+       methods (like for striping link definitions).
+
+*      Changed all methods which were inserting HTML code so that they now return 
+       a hashed representation of the code. New methods `hashSpan` and `hashBlock`
+       are used to hash respectivly span- and block-level generated content. This 
+       has a couple of significant effects:
+       
+       1.      It prevents invalid nesting of Markdown-generated elements which 
+           could occur occuring with constructs like `*something [link*][1]`.
+       2.      It prevents problems occuring with deeply nested lists on which 
+           paragraphs were ill-formed.
+       3.      It removes the need to call `hashHTMLBlocks` twice during the the 
+               block gamut.
+       
+       Hashes are turned back to HTML prior output.
+
+*      Made the block-level HTML parser smarter using a specially-crafted regular 
+       expression capable of handling nested tags.
+
+*      Solved backtick issues in tag attributes by rewriting the HTML tokenizer to 
+       be aware of code spans. All these lines should work correctly now:
+       
+               <span attr='`ticks`'>bar</span>
+               <span attr='``double ticks``'>bar</span>
+               `<test a="` content of attribute `">`
+
+*      Changed the parsing of HTML comments to match simply from `<!--` to `-->` 
+       instead using of the more complicated SGML-style rule with paired `--`.
+       This is how most browsers parse comments and how XML defines them too.
+
+*      `<address>` has been added to the list of block-level elements and is now
+       treated as an HTML block instead of being wrapped within paragraph tags.
+
+*      Now only trim trailing newlines from code blocks, instead of trimming
+       all trailing whitespace characters.
+
+*      Fixed bug where this:
+
+               [text](http://m.com "title" )
+               
+       wasn't working as expected, because the parser wasn't allowing for spaces
+       before the closing paren.
+
+*      Filthy hack to support markdown='1' in div tags.
+
+*      _DoAutoLinks() now supports the 'dict://' URL scheme.
+
+*      PHP- and ASP-style processor instructions are now protected as
+       raw HTML blocks.
+
+               <? ... ?>
+               <% ... %>
+
+*      Fix for escaped backticks still triggering code spans:
+
+               There are two raw backticks here: \` and here: \`, not a code span
+
+
+Extra 1.0 - 5 September 2005
+
+*   Added support for setting the id attributes for headers like this:
+       
+        Header 1            {#header1}
+        ========
+       
+        ## Header 2 ##      {#header2}
+       
+    This only work only for headers for now.
+
+*   Tables will now work correctly as the first element of a definition 
+    list. For example, this input:
+
+        Term
+
+        :   Header  | Header
+            ------- | -------
+            Cell    | Cell
+                   
+    used to produce no definition list and a table where the first 
+    header was named ": Header". This is now fixed.
+
+*   Fix for a problem where a paragraph following a table was not 
+    placed between `<p>` tags.
+
+
+Extra 1.0b4 - 1 August 2005
+
+*   Fixed some issues where whitespace around HTML blocks were trigging
+    empty paragraph tags.
+
+*   Fixed an HTML block parsing issue that would cause a block element 
+    following a code span or block with unmatched opening bracket to be
+    placed inside a paragraph.
+
+*   Removed some PHP notices that could appear when parsing definition
+    lists and tables with PHP notice reporting flag set.
+
+
+Extra 1.0b3 - 29 July 2005
+
+*   Definition lists now require a blank line before each term. Solves
+    an ambiguity where the last line of lazy-indented definitions could 
+    be mistaken by PHP Markdown as a new term in the list.
+
+*   Definition lists now support multiple terms per definition.
+
+*   Some special tags were replaced in the output by their md5 hash 
+    key. Things such as this now work as expected:
+       
+        ## Header <?php echo $number ?> ##
+
+
+Extra 1.0b2 - 26 July 2005
+
+*   Definition lists can now take two or more definitions for one term.
+    This should have been the case before, but a bug prevented this 
+    from working right.
+
+*   Fixed a problem where single column table with a pipe only at the
+    end where not parsed as table. Here is such a table:
+       
+        | header
+        | ------
+        | cell
+
+*   Fixed problems with empty cells in the first column of a table with 
+    no leading pipe, like this one:
+       
+        header | header
+        ------ | ------
+               | cell
+
+*   Code spans containing pipes did not within a table. This is now 
+    fixed by parsing code spans before splitting rows into cells.
+
+*   Added the pipe character to the backlash escape character lists.
+
+Extra 1.0b1 (25 Jun 2005)
+
+*   First public release of PHP Markdown Extra.
+
+
+Copyright and License
+---------------------
+
+Copyright (c) 2004-2005 Michel Fortin  
+<http://www.michelf.com/>  
+All rights reserved.
+
+Based on Markdown  
+Copyright (c) 2003-2005 John Gruber   
+<http://daringfireball.net/>   
+All rights reserved.
+
+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 "Markdown" 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 copyright owner
+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.
diff --git a/examples/includes/PHP-Markdown-Extra-1.2.3/markdown.php b/examples/includes/PHP-Markdown-Extra-1.2.3/markdown.php
new file mode 100644 (file)
index 0000000..1b7c042
--- /dev/null
@@ -0,0 +1,2909 @@
+<?php
+#
+# Markdown Extra  -  A text-to-HTML conversion tool for web writers
+#
+# PHP Markdown & Extra
+# Copyright (c) 2004-2008 Michel Fortin
+# <http://www.michelf.com/projects/php-markdown/>
+#
+# Original Markdown
+# Copyright (c) 2004-2006 John Gruber
+# <http://daringfireball.net/projects/markdown/>
+#
+
+
+define( 'MARKDOWN_VERSION',  "1.0.1m" ); # Sat 21 Jun 2008
+define( 'MARKDOWNEXTRA_VERSION',  "1.2.3" ); # Wed 31 Dec 2008
+
+
+#
+# Global default settings:
+#
+
+# Change to ">" for HTML output
+@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX',  " />");
+
+# Define the width of a tab for code blocks.
+@define( 'MARKDOWN_TAB_WIDTH',     4 );
+
+# Optional title attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_TITLE',         "" );
+@define( 'MARKDOWN_FN_BACKLINK_TITLE',     "" );
+
+# Optional class attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_CLASS',         "" );
+@define( 'MARKDOWN_FN_BACKLINK_CLASS',     "" );
+
+
+#
+# WordPress settings:
+#
+
+# Change to false to remove Markdown from posts and/or comments.
+@define( 'MARKDOWN_WP_POSTS',      true );
+@define( 'MARKDOWN_WP_COMMENTS',   true );
+
+
+
+### Standard Function Interface ###
+
+@define( 'MARKDOWN_PARSER_CLASS',  'MarkdownExtra_Parser' );
+
+function Markdown($text) {
+#
+# Initialize the parser and return the result of its transform method.
+#
+    # Setup static parser variable.
+    static $parser;
+    if (!isset($parser)) {
+        $parser_class = MARKDOWN_PARSER_CLASS;
+        $parser = new $parser_class;
+    }
+
+    # Transform text using parser.
+    return $parser->transform($text);
+}
+
+
+### WordPress Plugin Interface ###
+
+/*
+Plugin Name: Markdown Extra
+Plugin URI: http://www.michelf.com/projects/php-markdown/
+Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://www.michelf.com/projects/php-markdown/">More...</a>
+Version: 1.2.2
+Author: Michel Fortin
+Author URI: http://www.michelf.com/
+*/
+
+if (isset($wp_version)) {
+    # More details about how it works here:
+    # <http://www.michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/>
+
+    # Post content and excerpts
+    # - Remove WordPress paragraph generator.
+    # - Run Markdown on excerpt, then remove all tags.
+    # - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
+    if (MARKDOWN_WP_POSTS) {
+        remove_filter('the_content',     'wpautop');
+        remove_filter('the_content_rss', 'wpautop');
+        remove_filter('the_excerpt',     'wpautop');
+        add_filter('the_content',     'mdwp_MarkdownPost', 6);
+        add_filter('the_content_rss', 'mdwp_MarkdownPost', 6);
+        add_filter('get_the_excerpt', 'mdwp_MarkdownPost', 6);
+        add_filter('get_the_excerpt', 'trim', 7);
+        add_filter('the_excerpt',     'mdwp_add_p');
+        add_filter('the_excerpt_rss', 'mdwp_strip_p');
+
+        remove_filter('content_save_pre',  'balanceTags', 50);
+        remove_filter('excerpt_save_pre',  'balanceTags', 50);
+        add_filter('the_content',     'balanceTags', 50);
+        add_filter('get_the_excerpt', 'balanceTags', 9);
+    }
+
+    # Add a footnote id prefix to posts when inside a loop.
+    function mdwp_MarkdownPost($text) {
+        static $parser;
+        if (!$parser) {
+            $parser_class = MARKDOWN_PARSER_CLASS;
+            $parser = new $parser_class;
+        }
+        if (is_single() || is_page() || is_feed()) {
+            $parser->fn_id_prefix = "";
+        } else {
+            $parser->fn_id_prefix = get_the_ID() . ".";
+        }
+        return $parser->transform($text);
+    }
+
+    # Comments
+    # - Remove WordPress paragraph generator.
+    # - Remove WordPress auto-link generator.
+    # - Scramble important tags before passing them to the kses filter.
+    # - Run Markdown on excerpt then remove paragraph tags.
+    if (MARKDOWN_WP_COMMENTS) {
+        remove_filter('comment_text', 'wpautop', 30);
+        remove_filter('comment_text', 'make_clickable');
+        add_filter('pre_comment_content', 'Markdown', 6);
+        add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
+        add_filter('pre_comment_content', 'mdwp_show_tags', 12);
+        add_filter('get_comment_text',    'Markdown', 6);
+        add_filter('get_comment_excerpt', 'Markdown', 6);
+        add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
+
+        global $mdwp_hidden_tags, $mdwp_placeholders;
+        $mdwp_hidden_tags = explode(' ',
+            '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
+        $mdwp_placeholders = explode(' ', str_rot13(
+            'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
+            'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
+    }
+
+    function mdwp_add_p($text) {
+        if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
+            $text = '<p>'.$text.'</p>';
+            $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
+        }
+        return $text;
+    }
+
+    function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
+
+    function mdwp_hide_tags($text) {
+        global $mdwp_hidden_tags, $mdwp_placeholders;
+        return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
+    }
+    function mdwp_show_tags($text) {
+        global $mdwp_hidden_tags, $mdwp_placeholders;
+        return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
+    }
+}
+
+
+### bBlog Plugin Info ###
+
+function identify_modifier_markdown() {
+    return array(
+        'name' => 'markdown',
+        'type' => 'modifier',
+        'nicename' => 'PHP Markdown Extra',
+        'description' => 'A text-to-HTML conversion tool for web writers',
+        'authors' => 'Michel Fortin and John Gruber',
+        'licence' => 'GPL',
+        'version' => MARKDOWNEXTRA_VERSION,
+        'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://www.michelf.com/projects/php-markdown/">More...</a>',
+        );
+}
+
+
+### Smarty Modifier Interface ###
+
+function smarty_modifier_markdown($text) {
+    return Markdown($text);
+}
+
+
+### Textile Compatibility Mode ###
+
+# Rename this file to "classTextile.php" and it can replace Textile everywhere.
+
+if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
+    # Try to include PHP SmartyPants. Should be in the same directory.
+    @include_once 'smartypants.php';
+    # Fake Textile class. It calls Markdown instead.
+    class Textile {
+        function TextileThis($text, $lite='', $encode='') {
+            if ($lite == '' && $encode == '')    $text = Markdown($text);
+            if (function_exists('SmartyPants'))  $text = SmartyPants($text);
+            return $text;
+        }
+        # Fake restricted version: restrictions are not supported for now.
+        function TextileRestricted($text, $lite='', $noimage='') {
+            return $this->TextileThis($text, $lite);
+        }
+        # Workaround to ensure compatibility with TextPattern 4.0.3.
+        function blockLite($text) { return $text; }
+    }
+}
+
+
+
+#
+# Markdown Parser Class
+#
+
+class Markdown_Parser {
+
+    # Regex to match balanced [brackets].
+    # Needed to insert a maximum bracked depth while converting to PHP.
+    var $nested_brackets_depth = 6;
+    var $nested_brackets_re;
+
+    var $nested_url_parenthesis_depth = 4;
+    var $nested_url_parenthesis_re;
+
+    # Table of hash values for escaped characters:
+    var $escape_chars = '\`*_{}[]()>#+-.!';
+    var $escape_chars_re;
+
+    # Change to ">" for HTML output.
+    var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
+    var $tab_width = MARKDOWN_TAB_WIDTH;
+
+    # Change to `true` to disallow markup or entities.
+    var $no_markup = false;
+    var $no_entities = false;
+
+    # Predefined urls and titles for reference links and images.
+    var $predef_urls = array();
+    var $predef_titles = array();
+
+
+    function Markdown_Parser() {
+    #
+    # Constructor function. Initialize appropriate member variables.
+    #
+        $this->_initDetab();
+        $this->prepareItalicsAndBold();
+
+        $this->nested_brackets_re =
+            str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
+            str_repeat('\])*', $this->nested_brackets_depth);
+
+        $this->nested_url_parenthesis_re =
+            str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
+            str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
+
+        $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
+
+        # Sort document, block, and span gamut in ascendent priority order.
+        asort($this->document_gamut);
+        asort($this->block_gamut);
+        asort($this->span_gamut);
+    }
+
+
+    # Internal hashes used during transformation.
+    var $urls = array();
+    var $titles = array();
+    var $html_hashes = array();
+
+    # Status flag to avoid invalid nesting.
+    var $in_anchor = false;
+
+
+    function setup() {
+    #
+    # Called before the transformation process starts to setup parser
+    # states.
+    #
+        # Clear global hashes.
+        $this->urls = $this->predef_urls;
+        $this->titles = $this->predef_titles;
+        $this->html_hashes = array();
+
+        $in_anchor = false;
+    }
+
+    function teardown() {
+    #
+    # Called after the transformation process to clear any variable
+    # which may be taking up memory unnecessarly.
+    #
+        $this->urls = array();
+        $this->titles = array();
+        $this->html_hashes = array();
+    }
+
+
+    function transform($text) {
+    #
+    # Main function. Performs some preprocessing on the input text
+    # and pass it through the document gamut.
+    #
+        $this->setup();
+
+        # Remove UTF-8 BOM and marker character in input, if present.
+        $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
+
+        # Standardize line endings:
+        #   DOS to Unix and Mac to Unix
+        $text = preg_replace('{\r\n?}', "\n", $text);
+
+        # Make sure $text ends with a couple of newlines:
+        $text .= "\n\n";
+
+        # Convert all tabs to spaces.
+        $text = $this->detab($text);
+
+        # Turn block-level HTML blocks into hash entries
+        $text = $this->hashHTMLBlocks($text);
+
+        # Strip any lines consisting only of spaces and tabs.
+        # This makes subsequent regexen easier to write, because we can
+        # match consecutive blank lines with /\n+/ instead of something
+        # contorted like /[ ]*\n+/ .
+        $text = preg_replace('/^[ ]+$/m', '', $text);
+
+        # Run document gamut methods.
+        foreach ($this->document_gamut as $method => $priority) {
+            $text = $this->$method($text);
+        }
+
+        $this->teardown();
+
+        return $text . "\n";
+    }
+
+    var $document_gamut = array(
+        # Strip link definitions, store in hashes.
+        "stripLinkDefinitions" => 20,
+
+        "runBasicBlockGamut"   => 30,
+        );
+
+
+    function stripLinkDefinitions($text) {
+    #
+    # Strips link definitions from text, stores the URLs and titles in
+    # hash references.
+    #
+        $less_than_tab = $this->tab_width - 1;
+
+        # Link defs are in the form: ^[id]: url "optional title"
+        $text = preg_replace_callback('{
+                            ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
+                              [ ]*
+                              \n?               # maybe *one* newline
+                              [ ]*
+                            <?(\S+?)>?          # url = $2
+                              [ ]*
+                              \n?               # maybe one newline
+                              [ ]*
+                            (?:
+                                (?<=\s)         # lookbehind for whitespace
+                                ["(]
+                                (.*?)           # title = $3
+                                [")]
+                                [ ]*
+                            )?  # title is optional
+                            (?:\n+|\Z)
+            }xm',
+            array(&$this, '_stripLinkDefinitions_callback'),
+            $text);
+        return $text;
+    }
+    function _stripLinkDefinitions_callback($matches) {
+        $link_id = strtolower($matches[1]);
+        $this->urls[$link_id] = $matches[2];
+        $this->titles[$link_id] =& $matches[3];
+        return ''; # String that will replace the block
+    }
+
+
+    function hashHTMLBlocks($text) {
+        if ($this->no_markup)  return $text;
+
+        $less_than_tab = $this->tab_width - 1;
+
+        # Hashify HTML blocks:
+        # We only want to do this for block-level HTML tags, such as headers,
+        # lists, and tables. That's because we still want to wrap <p>s around
+        # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+        # phrase emphasis, and spans. The list of tags we're looking for is
+        # hard-coded:
+        #
+        # *  List "a" is made of tags which can be both inline or block-level.
+        #    These will be treated block-level when the start tag is alone on
+        #    its line, otherwise they're not matched here and will be taken as
+        #    inline later.
+        # *  List "b" is made of tags which are always block-level;
+        #
+        $block_tags_a_re = 'ins|del';
+        $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
+                           'script|noscript|form|fieldset|iframe|math';
+
+        # Regular expression for the content of a block tag.
+        $nested_tags_level = 4;
+        $attr = '
+            (?>             # optional tag attributes
+              \s            # starts with whitespace
+              (?>
+                [^>"/]+     # text outside quotes
+              |
+                /+(?!>)     # slash not followed by ">"
+              |
+                "[^"]*"     # text inside double quotes (tolerate ">")
+              |
+                \'[^\']*\'  # text inside single quotes (tolerate ">")
+              )*
+            )?
+            ';
+        $content =
+            str_repeat('
+                (?>
+                  [^<]+         # content without tag
+                |
+                  <\2           # nested opening tag
+                    '.$attr.'   # attributes
+                    (?>
+                      />
+                    |
+                      >', $nested_tags_level).  # end of opening tag
+                      '.*?'.                    # last level nested tag content
+            str_repeat('
+                      </\2\s*>  # closing nested tag
+                    )
+                  |
+                    <(?!/\2\s*> # other tags with a different name
+                  )
+                )*',
+                $nested_tags_level);
+        $content2 = str_replace('\2', '\3', $content);
+
+        # First, look for nested blocks, e.g.:
+        #   <div>
+        #       <div>
+        #       tags for inner block must be indented.
+        #       </div>
+        #   </div>
+        #
+        # The outermost tags must start at the left margin for this to match, and
+        # the inner nested divs must be indented.
+        # We need to do this before the next, more liberal match, because the next
+        # match will start at the first `<div>` and stop at the first `</div>`.
+        $text = preg_replace_callback('{(?>
+            (?>
+                (?<=\n\n)       # Starting after a blank line
+                |               # or
+                \A\n?           # the beginning of the doc
+            )
+            (                       # save in $1
+
+              # Match from `\n<tag>` to `</tag>\n`, handling nested tags
+              # in between.
+
+                        [ ]{0,'.$less_than_tab.'}
+                        <('.$block_tags_b_re.')# start tag = $2
+                        '.$attr.'>          # attributes followed by > and \n
+                        '.$content.'        # content, support nesting
+                        </\2>               # the matching end tag
+                        [ ]*                # trailing spaces/tabs
+                        (?=\n+|\Z)  # followed by a newline or end of document
+
+            | # Special version for tags of group a.
+
+                        [ ]{0,'.$less_than_tab.'}
+                        <('.$block_tags_a_re.')# start tag = $3
+                        '.$attr.'>[ ]*\n    # attributes followed by >
+                        '.$content2.'       # content, support nesting
+                        </\3>               # the matching end tag
+                        [ ]*                # trailing spaces/tabs
+                        (?=\n+|\Z)  # followed by a newline or end of document
+
+            | # Special case just for <hr />. It was easier to make a special
+              # case than to make the other regex more complicated.
+
+                        [ ]{0,'.$less_than_tab.'}
+                        <(hr)               # start tag = $2
+                        '.$attr.'           # attributes
+                        /?>                 # the matching end tag
+                        [ ]*
+                        (?=\n{2,}|\Z)       # followed by a blank line or end of document
+
+            | # Special case for standalone HTML comments:
+
+                    [ ]{0,'.$less_than_tab.'}
+                    (?s:
+                        <!-- .*? -->
+                    )
+                    [ ]*
+                    (?=\n{2,}|\Z)       # followed by a blank line or end of document
+
+            | # PHP and ASP-style processor instructions (<? and <%)
+
+                    [ ]{0,'.$less_than_tab.'}
+                    (?s:
+                        <([?%])         # $2
+                        .*?
+                        \2>
+                    )
+                    [ ]*
+                    (?=\n{2,}|\Z)       # followed by a blank line or end of document
+
+            )
+            )}Sxmi',
+            array(&$this, '_hashHTMLBlocks_callback'),
+            $text);
+
+        return $text;
+    }
+    function _hashHTMLBlocks_callback($matches) {
+        $text = $matches[1];
+        $key  = $this->hashBlock($text);
+        return "\n\n$key\n\n";
+    }
+
+
+    function hashPart($text, $boundary = 'X') {
+    #
+    # Called whenever a tag must be hashed when a function insert an atomic
+    # element in the text stream. Passing $text to through this function gives
+    # a unique text-token which will be reverted back when calling unhash.
+    #
+    # The $boundary argument specify what character should be used to surround
+    # the token. By convension, "B" is used for block elements that needs not
+    # to be wrapped into paragraph tags at the end, ":" is used for elements
+    # that are word separators and "X" is used in the general case.
+    #
+        # Swap back any tag hash found in $text so we do not have to `unhash`
+        # multiple times at the end.
+        $text = $this->unhash($text);
+
+        # Then hash the block.
+        static $i = 0;
+        $key = "$boundary\x1A" . ++$i . $boundary;
+        $this->html_hashes[$key] = $text;
+        return $key; # String that will replace the tag.
+    }
+
+
+    function hashBlock($text) {
+    #
+    # Shortcut function for hashPart with block-level boundaries.
+    #
+        return $this->hashPart($text, 'B');
+    }
+
+
+    var $block_gamut = array(
+    #
+    # These are all the transformations that form block-level
+    # tags like paragraphs, headers, and list items.
+    #
+        "doHeaders"         => 10,
+        "doHorizontalRules" => 20,
+
+        "doLists"           => 40,
+        "doCodeBlocks"      => 50,
+        "doBlockQuotes"     => 60,
+        );
+
+    function runBlockGamut($text) {
+    #
+    # Run block gamut tranformations.
+    #
+        # We need to escape raw HTML in Markdown source before doing anything
+        # else. This need to be done for each block, and not only at the
+        # begining in the Markdown function since hashed blocks can be part of
+        # list items and could have been indented. Indented blocks would have
+        # been seen as a code block in a previous pass of hashHTMLBlocks.
+        $text = $this->hashHTMLBlocks($text);
+
+        return $this->runBasicBlockGamut($text);
+    }
+
+    function runBasicBlockGamut($text) {
+    #
+    # Run block gamut tranformations, without hashing HTML blocks. This is
+    # useful when HTML blocks are known to be already hashed, like in the first
+    # whole-document pass.
+    #
+        foreach ($this->block_gamut as $method => $priority) {
+            $text = $this->$method($text);
+        }
+
+        # Finally form paragraph and restore hashed blocks.
+        $text = $this->formParagraphs($text);
+
+        return $text;
+    }
+
+
+    function doHorizontalRules($text) {
+        # Do Horizontal Rules:
+        return preg_replace(
+            '{
+                ^[ ]{0,3}   # Leading space
+                ([-*_])     # $1: First marker
+                (?>         # Repeated marker group
+                    [ ]{0,2}    # Zero, one, or two spaces.
+                    \1          # Marker character
+                ){2,}       # Group repeated at least twice
+                [ ]*        # Tailing spaces
+                $           # End of line.
+            }mx',
+            "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
+            $text);
+    }
+
+
+    var $span_gamut = array(
+    #
+    # These are all the transformations that occur *within* block-level
+    # tags like paragraphs, headers, and list items.
+    #
+        # Process character escapes, code spans, and inline HTML
+        # in one shot.
+        "parseSpan"           => -30,
+
+        # Process anchor and image tags. Images must come first,
+        # because ![foo][f] looks like an anchor.
+        "doImages"            =>  10,
+        "doAnchors"           =>  20,
+
+        # Make links out of things like `<http://example.com/>`
+        # Must come after doAnchors, because you can use < and >
+        # delimiters in inline links like [this](<url>).
+        "doAutoLinks"         =>  30,
+        "encodeAmpsAndAngles" =>  40,
+
+        "doItalicsAndBold"    =>  50,
+        "doHardBreaks"        =>  60,
+        );
+
+    function runSpanGamut($text) {
+    #
+    # Run span gamut tranformations.
+    #
+        foreach ($this->span_gamut as $method => $priority) {
+            $text = $this->$method($text);
+        }
+
+        return $text;
+    }
+
+
+    function doHardBreaks($text) {
+        # Do hard breaks:
+        return preg_replace_callback('/ {2,}\n/',
+            array(&$this, '_doHardBreaks_callback'), $text);
+    }
+    function _doHardBreaks_callback($matches) {
+        return $this->hashPart("<br$this->empty_element_suffix\n");
+    }
+
+
+    function doAnchors($text) {
+    #
+    # Turn Markdown link shortcuts into XHTML <a> tags.
+    #
+        if ($this->in_anchor) return $text;
+        $this->in_anchor = true;
+
+        #
+        # First, handle reference-style links: [link text] [id]
+        #
+        $text = preg_replace_callback('{
+            (                   # wrap whole match in $1
+              \[
+                ('.$this->nested_brackets_re.') # link text = $2
+              \]
+
+              [ ]?              # one optional space
+              (?:\n[ ]*)?       # one optional newline followed by spaces
+
+              \[
+                (.*?)       # id = $3
+              \]
+            )
+            }xs',
+            array(&$this, '_doAnchors_reference_callback'), $text);
+
+        #
+        # Next, inline-style links: [link text](url "optional title")
+        #
+        $text = preg_replace_callback('{
+            (               # wrap whole match in $1
+              \[
+                ('.$this->nested_brackets_re.') # link text = $2
+              \]
+              \(            # literal paren
+                [ ]*
+                (?:
+                    <(\S*)> # href = $3
+                |
+                    ('.$this->nested_url_parenthesis_re.')  # href = $4
+                )
+                [ ]*
+                (           # $5
+                  ([\'"])   # quote char = $6
+                  (.*?)     # Title = $7
+                  \6        # matching quote
+                  [ ]*  # ignore any spaces/tabs between closing quote and )
+                )?          # title is optional
+              \)
+            )
+            }xs',
+            array(&$this, '_DoAnchors_inline_callback'), $text);
+
+        #
+        # Last, handle reference-style shortcuts: [link text]
+        # These must come last in case you've also got [link test][1]
+        # or [link test](/foo)
+        #
+//      $text = preg_replace_callback('{
+//          (                   # wrap whole match in $1
+//            \[
+//              ([^\[\]]+)      # link text = $2; can\'t contain [ or ]
+//            \]
+//          )
+//          }xs',
+//          array(&$this, '_doAnchors_reference_callback'), $text);
+
+        $this->in_anchor = false;
+        return $text;
+    }
+    function _doAnchors_reference_callback($matches) {
+        $whole_match =  $matches[1];
+        $link_text   =  $matches[2];
+        $link_id     =& $matches[3];
+
+        if ($link_id == "") {
+            # for shortcut links like [this][] or [this].
+            $link_id = $link_text;
+        }
+
+        # lower-case and turn embedded newlines into spaces
+        $link_id = strtolower($link_id);
+        $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+        if (isset($this->urls[$link_id])) {
+            $url = $this->urls[$link_id];
+            $url = $this->encodeAttribute($url);
+
+            $result = "<a href=\"$url\"";
+            if ( isset( $this->titles[$link_id] ) ) {
+                $title = $this->titles[$link_id];
+                $title = $this->encodeAttribute($title);
+                $result .=  " title=\"$title\"";
+            }
+
+            $link_text = $this->runSpanGamut($link_text);
+            $result .= ">$link_text</a>";
+            $result = $this->hashPart($result);
+        }
+        else {
+            $result = $whole_match;
+        }
+        return $result;
+    }
+    function _doAnchors_inline_callback($matches) {
+        $whole_match    =  $matches[1];
+        $link_text      =  $this->runSpanGamut($matches[2]);
+        $url            =  $matches[3] == '' ? $matches[4] : $matches[3];
+        $title          =& $matches[7];
+
+        $url = $this->encodeAttribute($url);
+
+        $result = "<a href=\"$url\"";
+        if (isset($title)) {
+            $title = $this->encodeAttribute($title);
+            $result .=  " title=\"$title\"";
+        }
+
+        $link_text = $this->runSpanGamut($link_text);
+        $result .= ">$link_text</a>";
+
+        return $this->hashPart($result);
+    }
+
+
+    function doImages($text) {
+    #
+    # Turn Markdown image shortcuts into <img> tags.
+    #
+        #
+        # First, handle reference-style labeled images: ![alt text][id]
+        #
+        $text = preg_replace_callback('{
+            (               # wrap whole match in $1
+              !\[
+                ('.$this->nested_brackets_re.')     # alt text = $2
+              \]
+
+              [ ]?              # one optional space
+              (?:\n[ ]*)?       # one optional newline followed by spaces
+
+              \[
+                (.*?)       # id = $3
+              \]
+
+            )
+            }xs',
+            array(&$this, '_doImages_reference_callback'), $text);
+
+        #
+        # Next, handle inline images:  ![alt text](url "optional title")
+        # Don't forget: encode * and _
+        #
+        $text = preg_replace_callback('{
+            (               # wrap whole match in $1
+              !\[
+                ('.$this->nested_brackets_re.')     # alt text = $2
+              \]
+              \s?           # One optional whitespace character
+              \(            # literal paren
+                [ ]*
+                (?:
+                    <(\S*)> # src url = $3
+                |
+                    ('.$this->nested_url_parenthesis_re.')  # src url = $4
+                )
+                [ ]*
+                (           # $5
+                  ([\'"])   # quote char = $6
+                  (.*?)     # title = $7
+                  \6        # matching quote
+                  [ ]*
+                )?          # title is optional
+              \)
+            )
+            }xs',
+            array(&$this, '_doImages_inline_callback'), $text);
+
+        return $text;
+    }
+    function _doImages_reference_callback($matches) {
+        $whole_match = $matches[1];
+        $alt_text    = $matches[2];
+        $link_id     = strtolower($matches[3]);
+
+        if ($link_id == "") {
+            $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+        }
+
+        $alt_text = $this->encodeAttribute($alt_text);
+        if (isset($this->urls[$link_id])) {
+            $url = $this->encodeAttribute($this->urls[$link_id]);
+            $result = "<img src=\"$url\" alt=\"$alt_text\"";
+            if (isset($this->titles[$link_id])) {
+                $title = $this->titles[$link_id];
+                $title = $this->encodeAttribute($title);
+                $result .=  " title=\"$title\"";
+            }
+            $result .= $this->empty_element_suffix;
+            $result = $this->hashPart($result);
+        }
+        else {
+            # If there's no such link ID, leave intact:
+            $result = $whole_match;
+        }
+
+        return $result;
+    }
+    function _doImages_inline_callback($matches) {
+        $whole_match    = $matches[1];
+        $alt_text       = $matches[2];
+        $url            = $matches[3] == '' ? $matches[4] : $matches[3];
+        $title          =& $matches[7];
+
+        $alt_text = $this->encodeAttribute($alt_text);
+        $url = $this->encodeAttribute($url);
+        $result = "<img src=\"$url\" alt=\"$alt_text\"";
+        if (isset($title)) {
+            $title = $this->encodeAttribute($title);
+            $result .=  " title=\"$title\""; # $title already quoted
+        }
+        $result .= $this->empty_element_suffix;
+
+        return $this->hashPart($result);
+    }
+
+
+    function doHeaders($text) {
+        # Setext-style headers:
+        #     Header 1
+        #     ========
+        #
+        #     Header 2
+        #     --------
+        #
+        $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
+            array(&$this, '_doHeaders_callback_setext'), $text);
+
+        # atx-style headers:
+        #   # Header 1
+        #   ## Header 2
+        #   ## Header 2 with closing hashes ##
+        #   ...
+        #   ###### Header 6
+        #
+        $text = preg_replace_callback('{
+                ^(\#{1,6})  # $1 = string of #\'s
+                [ ]*
+                (.+?)       # $2 = Header text
+                [ ]*
+                \#*         # optional closing #\'s (not counted)
+                \n+
+            }xm',
+            array(&$this, '_doHeaders_callback_atx'), $text);
+
+        return $text;
+    }
+    function _doHeaders_callback_setext($matches) {
+        # Terrible hack to check we haven't found an empty list item.
+        if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+            return $matches[0];
+
+        $level = $matches[2]{0} == '=' ? 1 : 2;
+        $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
+        return "\n" . $this->hashBlock($block) . "\n\n";
+    }
+    function _doHeaders_callback_atx($matches) {
+        $level = strlen($matches[1]);
+        $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
+        return "\n" . $this->hashBlock($block) . "\n\n";
+    }
+
+
+    function doLists($text) {
+    #
+    # Form HTML ordered (numbered) and unordered (bulleted) lists.
+    #
+        $less_than_tab = $this->tab_width - 1;
+
+        # Re-usable patterns to match list item bullets and number markers:
+        $marker_ul_re  = '[*+-]';
+        $marker_ol_re  = '\d+[.]';
+        $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+        $markers_relist = array($marker_ul_re, $marker_ol_re);
+
+        foreach ($markers_relist as $marker_re) {
+            # Re-usable pattern to match any entirel ul or ol list:
+            $whole_list_re = '
+                (                               # $1 = whole list
+                  (                             # $2
+                    [ ]{0,'.$less_than_tab.'}
+                    ('.$marker_re.')            # $3 = first list item marker
+                    [ ]+
+                  )
+                  (?s:.+?)
+                  (                             # $4
+                      \z
+                    |
+                      \n{2,}
+                      (?=\S)
+                      (?!                       # Negative lookahead for another list item marker
+                        [ ]*
+                        '.$marker_re.'[ ]+
+                      )
+                  )
+                )
+            '; // mx
+
+            # We use a different prefix before nested lists than top-level lists.
+            # See extended comment in _ProcessListItems().
+
+            if ($this->list_level) {
+                $text = preg_replace_callback('{
+                        ^
+                        '.$whole_list_re.'
+                    }mx',
+                    array(&$this, '_doLists_callback'), $text);
+            }
+            else {
+                $text = preg_replace_callback('{
+                        (?:(?<=\n)\n|\A\n?) # Must eat the newline
+                        '.$whole_list_re.'
+                    }mx',
+                    array(&$this, '_doLists_callback'), $text);
+            }
+        }
+
+        return $text;
+    }
+    function _doLists_callback($matches) {
+        # Re-usable patterns to match list item bullets and number markers:
+        $marker_ul_re  = '[*+-]';
+        $marker_ol_re  = '\d+[.]';
+        $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+        $list = $matches[1];
+        $list_type = preg_match("/$marker_ul_re/", $matches[3]) ? "ul" : "ol";
+
+        $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+
+        $list .= "\n";
+        $result = $this->processListItems($list, $marker_any_re);
+
+        $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+        return "\n". $result ."\n\n";
+    }
+
+    var $list_level = 0;
+
+    function processListItems($list_str, $marker_any_re) {
+    #
+    #   Process the contents of a single ordered or unordered list, splitting it
+    #   into individual list items.
+    #
+        # The $this->list_level global keeps track of when we're inside a list.
+        # Each time we enter a list, we increment it; when we leave a list,
+        # we decrement. If it's zero, we're not in a list anymore.
+        #
+        # We do this because when we're not inside a list, we want to treat
+        # something like this:
+        #
+        #       I recommend upgrading to version
+        #       8. Oops, now this line is treated
+        #       as a sub-list.
+        #
+        # As a single paragraph, despite the fact that the second line starts
+        # with a digit-period-space sequence.
+        #
+        # Whereas when we're inside a list (or sub-list), that line will be
+        # treated as the start of a sub-list. What a kludge, huh? This is
+        # an aspect of Markdown's syntax that's hard to parse perfectly
+        # without resorting to mind-reading. Perhaps the solution is to
+        # change the syntax rules such that sub-lists must start with a
+        # starting cardinal number; e.g. "1." or "a.".
+
+        $this->list_level++;
+
+        # trim trailing blank lines:
+        $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+        $list_str = preg_replace_callback('{
+            (\n)?                           # leading line = $1
+            (^[ ]*)                         # leading whitespace = $2
+            ('.$marker_any_re.'             # list marker and space = $3
+                (?:[ ]+|(?=\n)) # space only required if item is not empty
+            )
+            ((?s:.*?))                      # list item text   = $4
+            (?:(\n+(?=\n))|\n)              # tailing blank line = $5
+            (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
+            }xm',
+            array(&$this, '_processListItems_callback'), $list_str);
+
+        $this->list_level--;
+        return $list_str;
+    }
+    function _processListItems_callback($matches) {
+        $item = $matches[4];
+        $leading_line =& $matches[1];
+        $leading_space =& $matches[2];
+        $marker_space = $matches[3];
+        $tailing_blank_line =& $matches[5];
+
+        if ($leading_line || $tailing_blank_line ||
+            preg_match('/\n{2,}/', $item))
+        {
+            # Replace marker with the appropriate whitespace indentation
+            $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
+            $item = $this->runBlockGamut($this->outdent($item)."\n");
+        }
+        else {
+            # Recursion for sub-lists:
+            $item = $this->doLists($this->outdent($item));
+            $item = preg_replace('/\n+$/', '', $item);
+            $item = $this->runSpanGamut($item);
+        }
+
+        return "<li>" . $item . "</li>\n";
+    }
+
+
+    function doCodeBlocks($text) {
+    #
+    #   Process Markdown `<pre><code>` blocks.
+    #
+        $text = preg_replace_callback('{
+                (?:\n\n|\A\n?)
+                (               # $1 = the code block -- one or more lines, starting with a space/tab
+                  (?>
+                    [ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
+                    .*\n+
+                  )+
+                )
+                ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+            }xm',
+            array(&$this, '_doCodeBlocks_callback'), $text);
+
+        return $text;
+    }
+    function _doCodeBlocks_callback($matches) {
+        $codeblock = $matches[1];
+
+        $codeblock = $this->outdent($codeblock);
+        $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+        # trim leading newlines and trailing newlines
+        $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+        $codeblock = "<pre><code>$codeblock\n</code></pre>";
+        return "\n\n".$this->hashBlock($codeblock)."\n\n";
+    }
+
+
+    function makeCodeSpan($code) {
+    #
+    # Create a code span markup for $code. Called from handleSpanToken.
+    #
+        $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+        return $this->hashPart("<code>$code</code>");
+    }
+
+
+    var $em_relist = array(
+        ''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S)(?![.,:;]\s)',
+        '*' => '(?<=\S)(?<!\*)\*(?!\*)',
+        '_' => '(?<=\S)(?<!_)_(?!_)',
+        );
+    var $strong_relist = array(
+        ''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S)(?![.,:;]\s)',
+        '**' => '(?<=\S)(?<!\*)\*\*(?!\*)',
+        '__' => '(?<=\S)(?<!_)__(?!_)',
+        );
+    var $em_strong_relist = array(
+        ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S)(?![.,:;]\s)',
+        '***' => '(?<=\S)(?<!\*)\*\*\*(?!\*)',
+        '___' => '(?<=\S)(?<!_)___(?!_)',
+        );
+    var $em_strong_prepared_relist;
+
+    function prepareItalicsAndBold() {
+    #
+    # Prepare regular expressions for seraching emphasis tokens in any
+    # context.
+    #
+        foreach ($this->em_relist as $em => $em_re) {
+            foreach ($this->strong_relist as $strong => $strong_re) {
+                # Construct list of allowed token expressions.
+                $token_relist = array();
+                if (isset($this->em_strong_relist["$em$strong"])) {
+                    $token_relist[] = $this->em_strong_relist["$em$strong"];
+                }
+                $token_relist[] = $em_re;
+                $token_relist[] = $strong_re;
+
+                # Construct master expression from list.
+                $token_re = '{('. implode('|', $token_relist) .')}';
+                $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+            }
+        }
+    }
+
+    function doItalicsAndBold($text) {
+        $token_stack = array('');
+        $text_stack = array('');
+        $em = '';
+        $strong = '';
+        $tree_char_em = false;
+
+        while (1) {
+            #
+            # Get prepared regular expression for seraching emphasis tokens
+            # in current context.
+            #
+            $token_re = $this->em_strong_prepared_relist["$em$strong"];
+
+            #
+            # Each loop iteration seach for the next emphasis token.
+            # Each token is then passed to handleSpanToken.
+            #
+            $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+            $text_stack[0] .= $parts[0];
+            $token =& $parts[1];
+            $text =& $parts[2];
+
+            if (empty($token)) {
+                # Reached end of text span: empty stack without emitting.
+                # any more emphasis.
+                while ($token_stack[0]) {
+                    $text_stack[1] .= array_shift($token_stack);
+                    $text_stack[0] .= array_shift($text_stack);
+                }
+                break;
+            }
+
+            $token_len = strlen($token);
+            if ($tree_char_em) {
+                # Reached closing marker while inside a three-char emphasis.
+                if ($token_len == 3) {
+                    # Three-char closing marker, close em and strong.
+                    array_shift($token_stack);
+                    $span = array_shift($text_stack);
+                    $span = $this->runSpanGamut($span);
+                    $span = "<strong><em>$span</em></strong>";
+                    $text_stack[0] .= $this->hashPart($span);
+                    $em = '';
+                    $strong = '';
+                } else {
+                    # Other closing marker: close one em or strong and
+                    # change current token state to match the other
+                    $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+                    $tag = $token_len == 2 ? "strong" : "em";
+                    $span = $text_stack[0];
+                    $span = $this->runSpanGamut($span);
+                    $span = "<$tag>$span</$tag>";
+                    $text_stack[0] = $this->hashPart($span);
+                    $$tag = ''; # $$tag stands for $em or $strong
+                }
+                $tree_char_em = false;
+            } else if ($token_len == 3) {
+                if ($em) {
+                    # Reached closing marker for both em and strong.
+                    # Closing strong marker:
+                    for ($i = 0; $i < 2; ++$i) {
+                        $shifted_token = array_shift($token_stack);
+                        $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+                        $span = array_shift($text_stack);
+                        $span = $this->runSpanGamut($span);
+                        $span = "<$tag>$span</$tag>";
+                        $text_stack[0] .= $this->hashPart($span);
+                        $$tag = ''; # $$tag stands for $em or $strong
+                    }
+                } else {
+                    # Reached opening three-char emphasis marker. Push on token
+                    # stack; will be handled by the special condition above.
+                    $em = $token{0};
+                    $strong = "$em$em";
+                    array_unshift($token_stack, $token);
+                    array_unshift($text_stack, '');
+                    $tree_char_em = true;
+                }
+            } else if ($token_len == 2) {
+                if ($strong) {
+                    # Unwind any dangling emphasis marker:
+                    if (strlen($token_stack[0]) == 1) {
+                        $text_stack[1] .= array_shift($token_stack);
+                        $text_stack[0] .= array_shift($text_stack);
+                    }
+                    # Closing strong marker:
+                    array_shift($token_stack);
+                    $span = array_shift($text_stack);
+                    $span = $this->runSpanGamut($span);
+                    $span = "<strong>$span</strong>";
+                    $text_stack[0] .= $this->hashPart($span);
+                    $strong = '';
+                } else {
+                    array_unshift($token_stack, $token);
+                    array_unshift($text_stack, '');
+                    $strong = $token;
+                }
+            } else {
+                # Here $token_len == 1
+                if ($em) {
+                    if (strlen($token_stack[0]) == 1) {
+                        # Closing emphasis marker:
+                        array_shift($token_stack);
+                        $span = array_shift($text_stack);
+                        $span = $this->runSpanGamut($span);
+                        $span = "<em>$span</em>";
+                        $text_stack[0] .= $this->hashPart($span);
+                        $em = '';
+                    } else {
+                        $text_stack[0] .= $token;
+                    }
+                } else {
+                    array_unshift($token_stack, $token);
+                    array_unshift($text_stack, '');
+                    $em = $token;
+                }
+            }
+        }
+        return $text_stack[0];
+    }
+
+
+    function doBlockQuotes($text) {
+        $text = preg_replace_callback('/
+              (                             # Wrap whole match in $1
+                (?>
+                  ^[ ]*>[ ]?            # ">" at the start of a line
+                    .+\n                    # rest of the first line
+                  (.+\n)*                   # subsequent consecutive lines
+                  \n*                       # blanks
+                )+
+              )
+            /xm',
+            array(&$this, '_doBlockQuotes_callback'), $text);
+
+        return $text;
+    }
+    function _doBlockQuotes_callback($matches) {
+        $bq = $matches[1];
+        # trim one level of quoting - trim whitespace-only lines
+        $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+        $bq = $this->runBlockGamut($bq);        # recurse
+
+        $bq = preg_replace('/^/m', "  ", $bq);
+        # These leading spaces cause problem with <pre> content,
+        # so we need to fix that:
+        $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
+            array(&$this, '_DoBlockQuotes_callback2'), $bq);
+
+        return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
+    }
+    function _doBlockQuotes_callback2($matches) {
+        $pre = $matches[1];
+        $pre = preg_replace('/^  /m', '', $pre);
+        return $pre;
+    }
+
+
+    function formParagraphs($text) {
+    #
+    #   Params:
+    #       $text - string to process with html <p> tags
+    #
+        # Strip leading and trailing lines:
+        $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+        $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+        #
+        # Wrap <p> tags and unhashify HTML blocks
+        #
+        foreach ($grafs as $key => $value) {
+            if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
+                # Is a paragraph.
+                $value = $this->runSpanGamut($value);
+                $value = preg_replace('/^([ ]*)/', "<p>", $value);
+                $value .= "</p>";
+                $grafs[$key] = $this->unhash($value);
+            }
+            else {
+                # Is a block.
+                # Modify elements of @grafs in-place...
+                $graf = $value;
+                $block = $this->html_hashes[$graf];
+                $graf = $block;
+//              if (preg_match('{
+//                  \A
+//                  (                           # $1 = <div> tag
+//                    <div  \s+
+//                    [^>]*
+//                    \b
+//                    markdown\s*=\s*  ([\'"])  #   $2 = attr quote char
+//                    1
+//                    \2
+//                    [^>]*
+//                    >
+//                  )
+//                  (                           # $3 = contents
+//                  .*
+//                  )
+//                  (</div>)                    # $4 = closing tag
+//                  \z
+//                  }xs', $block, $matches))
+//              {
+//                  list(, $div_open, , $div_content, $div_close) = $matches;
+//
+//                  # We can't call Markdown(), because that resets the hash;
+//                  # that initialization code should be pulled into its own sub, though.
+//                  $div_content = $this->hashHTMLBlocks($div_content);
+//
+//                  # Run document gamut methods on the content.
+//                  foreach ($this->document_gamut as $method => $priority) {
+//                      $div_content = $this->$method($div_content);
+//                  }
+//
+//                  $div_open = preg_replace(
+//                      '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
+//
+//                  $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
+//              }
+                $grafs[$key] = $graf;
+            }
+        }
+
+        return implode("\n\n", $grafs);
+    }
+
+
+    function encodeAttribute($text) {
+    #
+    # Encode text for a double-quoted HTML attribute. This function
+    # is *not* suitable for attributes enclosed in single quotes.
+    #
+        $text = $this->encodeAmpsAndAngles($text);
+        $text = str_replace('"', '&quot;', $text);
+        return $text;
+    }
+
+
+    function encodeAmpsAndAngles($text) {
+    #
+    # Smart processing for ampersands and angle brackets that need to
+    # be encoded. Valid character entities are left alone unless the
+    # no-entities mode is set.
+    #
+        if ($this->no_entities) {
+            $text = str_replace('&', '&amp;', $text);
+        } else {
+            # Ampersand-encoding based entirely on Nat Irons's Amputator
+            # MT plugin: <http://bumppo.net/projects/amputator/>
+            $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
+                                '&amp;', $text);;
+        }
+        # Encode remaining <'s
+        $text = str_replace('<', '&lt;', $text);
+
+        return $text;
+    }
+
+
+    function doAutoLinks($text) {
+        $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
+            array(&$this, '_doAutoLinks_url_callback'), $text);
+
+        # Email addresses: <address@domain.foo>
+        $text = preg_replace_callback('{
+            <
+            (?:mailto:)?
+            (
+                [-.\w\x80-\xFF]+
+                \@
+                [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
+            )
+            >
+            }xi',
+            array(&$this, '_doAutoLinks_email_callback'), $text);
+
+        return $text;
+    }
+    function _doAutoLinks_url_callback($matches) {
+        $url = $this->encodeAttribute($matches[1]);
+        $link = "<a href=\"$url\">$url</a>";
+        return $this->hashPart($link);
+    }
+    function _doAutoLinks_email_callback($matches) {
+        $address = $matches[1];
+        $link = $this->encodeEmailAddress($address);
+        return $this->hashPart($link);
+    }
+
+
+    function encodeEmailAddress($addr) {
+    #
+    #   Input: an email address, e.g. "foo@example.com"
+    #
+    #   Output: the email address as a mailto link, with each character
+    #       of the address encoded as either a decimal or hex entity, in
+    #       the hopes of foiling most address harvesting spam bots. E.g.:
+    #
+    #     <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
+    #        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
+    #        &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
+    #        &#101;&#46;&#x63;&#111;&#x6d;</a></p>
+    #
+    #   Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+    #   With some optimizations by Milian Wolff.
+    #
+        $addr = "mailto:" . $addr;
+        $chars = preg_split('/(?<!^)(?!$)/', $addr);
+        $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
+
+        foreach ($chars as $key => $char) {
+            $ord = ord($char);
+            # Ignore non-ascii chars.
+            if ($ord < 128) {
+                $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+                # roughly 10% raw, 45% hex, 45% dec
+                # '@' *must* be encoded. I insist.
+                if ($r > 90 && $char != '@') /* do nothing */;
+                else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
+                else              $chars[$key] = '&#'.$ord.';';
+            }
+        }
+
+        $addr = implode('', $chars);
+        $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+        $addr = "<a href=\"$addr\">$text</a>";
+
+        return $addr;
+    }
+
+
+    function parseSpan($str) {
+    #
+    # Take the string $str and parse it into tokens, hashing embeded HTML,
+    # escaped characters and handling code spans.
+    #
+        $output = '';
+
+        $span_re = '{
+                (
+                    \\\\'.$this->escape_chars_re.'
+                |
+                    (?<![`\\\\])
+                    `+                      # code span marker
+            '.( $this->no_markup ? '' : '
+                |
+                    <!--    .*?     -->     # comment
+                |
+                    <\?.*?\?> | <%.*?%>     # processing instruction
+                |
+                    <[/!$]?[-a-zA-Z0-9:]+   # regular tags
+                    (?>
+                        \s
+                        (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+                    )?
+                    >
+            ').'
+                )
+                }xs';
+
+        while (1) {
+            #
+            # Each loop iteration seach for either the next tag, the next
+            # openning code span marker, or the next escaped character.
+            # Each token is then passed to handleSpanToken.
+            #
+            $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+            # Create token from text preceding tag.
+            if ($parts[0] != "") {
+                $output .= $parts[0];
+            }
+
+            # Check if we reach the end.
+            if (isset($parts[1])) {
+                $output .= $this->handleSpanToken($parts[1], $parts[2]);
+                $str = $parts[2];
+            }
+            else {
+                break;
+            }
+        }
+
+        return $output;
+    }
+
+
+    function handleSpanToken($token, &$str) {
+    #
+    # Handle $token provided by parseSpan by determining its nature and
+    # returning the corresponding value that should replace it.
+    #
+        switch ($token{0}) {
+            case "\\":
+                return $this->hashPart("&#". ord($token{1}). ";");
+            case "`":
+                # Search for end marker in remaining text.
+                if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
+                    $str, $matches))
+                {
+                    $str = $matches[2];
+                    $codespan = $this->makeCodeSpan($matches[1]);
+                    return $this->hashPart($codespan);
+                }
+                return $token; // return as text since no ending marker found.
+            default:
+                return $this->hashPart($token);
+        }
+    }
+
+
+    function outdent($text) {
+    #
+    # Remove one level of line-leading tabs or spaces
+    #
+        return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+    }
+
+
+    # String length function for detab. `_initDetab` will create a function to
+    # hanlde UTF-8 if the default function does not exist.
+    var $utf8_strlen = 'mb_strlen';
+
+    function detab($text) {
+    #
+    # Replace tabs with the appropriate amount of space.
+    #
+        # For each line we separate the line in blocks delemited by
+        # tab characters. Then we reconstruct every line by adding the
+        # appropriate number of space between each blocks.
+
+        $text = preg_replace_callback('/^.*\t.*$/m',
+            array(&$this, '_detab_callback'), $text);
+
+        return $text;
+    }
+    function _detab_callback($matches) {
+        $line = $matches[0];
+        $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+
+        # Split in blocks.
+        $blocks = explode("\t", $line);
+        # Add each blocks to the line.
+        $line = $blocks[0];
+        unset($blocks[0]); # Do not add first block twice.
+        foreach ($blocks as $block) {
+            # Calculate amount of space, insert spaces, insert block.
+            $amount = $this->tab_width -
+                $strlen($line, 'UTF-8') % $this->tab_width;
+            $line .= str_repeat(" ", $amount) . $block;
+        }
+        return $line;
+    }
+    function _initDetab() {
+    #
+    # Check for the availability of the function in the `utf8_strlen` property
+    # (initially `mb_strlen`). If the function is not available, create a
+    # function that will loosely count the number of UTF-8 characters with a
+    # regular expression.
+    #
+        if (function_exists($this->utf8_strlen)) return;
+        $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+            "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
+            $text, $m);');
+    }
+
+
+    function unhash($text) {
+    #
+    # Swap back in all the tags hashed by _HashHTMLBlocks.
+    #
+        return preg_replace_callback('/(.)\x1A[0-9]+\1/',
+            array(&$this, '_unhash_callback'), $text);
+    }
+    function _unhash_callback($matches) {
+        return $this->html_hashes[$matches[0]];
+    }
+
+}
+
+
+#
+# Markdown Extra Parser Class
+#
+
+class MarkdownExtra_Parser extends Markdown_Parser {
+
+    # Prefix for footnote ids.
+    var $fn_id_prefix = "";
+
+    # Optional title attribute for footnote links and backlinks.
+    var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
+    var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
+
+    # Optional class attribute for footnote links and backlinks.
+    var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
+    var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
+
+    # Predefined abbreviations.
+    var $predef_abbr = array();
+
+
+    function MarkdownExtra_Parser() {
+    #
+    # Constructor function. Initialize the parser object.
+    #
+        # Add extra escapable characters before parent constructor
+        # initialize the table.
+        $this->escape_chars .= ':|';
+
+        # Insert extra document, block, and span transformations.
+        # Parent constructor will do the sorting.
+        $this->document_gamut += array(
+            "doFencedCodeBlocks" => 5,
+            "stripFootnotes"     => 15,
+            "stripAbbreviations" => 25,
+            "appendFootnotes"    => 50,
+            );
+        $this->block_gamut += array(
+            "doFencedCodeBlocks" => 5,
+            "doTables"           => 15,
+            "doDefLists"         => 45,
+            );
+        $this->span_gamut += array(
+            "doFootnotes"        => 5,
+            "doAbbreviations"    => 70,
+            );
+
+        parent::Markdown_Parser();
+    }
+
+
+    # Extra variables used during extra transformations.
+    var $footnotes = array();
+    var $footnotes_ordered = array();
+    var $abbr_desciptions = array();
+    var $abbr_word_re = '';
+
+    # Give the current footnote number.
+    var $footnote_counter = 1;
+
+
+    function setup() {
+    #
+    # Setting up Extra-specific variables.
+    #
+        parent::setup();
+
+        $this->footnotes = array();
+        $this->footnotes_ordered = array();
+        $this->abbr_desciptions = array();
+        $this->abbr_word_re = '';
+        $this->footnote_counter = 1;
+
+        foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+            if ($this->abbr_word_re)
+                $this->abbr_word_re .= '|';
+            $this->abbr_word_re .= preg_quote($abbr_word);
+            $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+        }
+    }
+
+    function teardown() {
+    #
+    # Clearing Extra-specific variables.
+    #
+        $this->footnotes = array();
+        $this->footnotes_ordered = array();
+        $this->abbr_desciptions = array();
+        $this->abbr_word_re = '';
+
+        parent::teardown();
+    }
+
+
+    ### HTML Block Parser ###
+
+    # Tags that are always treated as block tags:
+    var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+
+    # Tags treated as block tags only if the opening tag is alone on it's line:
+    var $context_block_tags_re = 'script|noscript|math|ins|del';
+
+    # Tags where markdown="1" default to span mode:
+    var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+
+    # Tags which must not have their contents modified, no matter where
+    # they appear:
+    var $clean_tags_re = 'script|math';
+
+    # Tags that do not need to be closed.
+    var $auto_close_tags_re = 'hr|img';
+
+
+    function hashHTMLBlocks($text) {
+    #
+    # Hashify HTML Blocks and "clean tags".
+    #
+    # We only want to do this for block-level HTML tags, such as headers,
+    # lists, and tables. That's because we still want to wrap <p>s around
+    # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+    # phrase emphasis, and spans. The list of tags we're looking for is
+    # hard-coded.
+    #
+    # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+    # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1"
+    # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
+    #  _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+    # These two functions are calling each other. It's recursive!
+    #
+        #
+        # Call the HTML-in-Markdown hasher.
+        #
+        list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+
+        return $text;
+    }
+    function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
+                                        $enclosing_tag_re = '', $span = false)
+    {
+    #
+    # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+    #
+    # *   $indent is the number of space to be ignored when checking for code
+    #     blocks. This is important because if we don't take the indent into
+    #     account, something like this (which looks right) won't work as expected:
+    #
+    #     <div>
+    #         <div markdown="1">
+    #         Hello World.  <-- Is this a Markdown code block or text?
+    #         </div>  <-- Is this a Markdown code block or a real tag?
+    #     <div>
+    #
+    #     If you don't like this, just don't indent the tag on which
+    #     you apply the markdown="1" attribute.
+    #
+    # *   If $enclosing_tag_re is not empty, stops at the first unmatched closing
+    #     tag with that name. Nested tags supported.
+    #
+    # *   If $span is true, text inside must treated as span. So any double
+    #     newline will be replaced by a single newline so that it does not create
+    #     paragraphs.
+    #
+    # Returns an array of that form: ( processed text , remaining text )
+    #
+        if ($text === '') return array('', '');
+
+        # Regex to check for the presense of newlines around a block tag.
+        $newline_before_re = '/(?:^\n?|\n\n)*$/';
+        $newline_after_re =
+            '{
+                ^                       # Start of text following the tag.
+                (?>[ ]*<!--.*?-->)?     # Optional comment.
+                [ ]*\n                  # Must be followed by newline.
+            }xs';
+
+        # Regex to match any tag.
+        $block_tag_re =
+            '{
+                (                   # $2: Capture hole tag.
+                    </?                 # Any opening or closing tag.
+                        (?>             # Tag name.
+                            '.$this->block_tags_re.'            |
+                            '.$this->context_block_tags_re.'    |
+                            '.$this->clean_tags_re.'            |
+                            (?!\s)'.$enclosing_tag_re.'
+                        )
+                        (?:
+                            (?=[\s"\'/a-zA-Z0-9])   # Allowed characters after tag name.
+                            (?>
+                                ".*?"       |   # Double quotes (can contain `>`)
+                                \'.*?\'     |   # Single quotes (can contain `>`)
+                                .+?             # Anything but quotes and `>`.
+                            )*?
+                        )?
+                    >                   # End of tag.
+                |
+                    <!--    .*?     --> # HTML Comment
+                |
+                    <\?.*?\?> | <%.*?%> # Processing instruction
+                |
+                    <!\[CDATA\[.*?\]\]> # CData Block
+                |
+                    # Code span marker
+                    `+
+                '. ( !$span ? ' # If not in span.
+                |
+                    # Indented code block
+                    (?> ^[ ]*\n? | \n[ ]*\n )
+                    [ ]{'.($indent+4).'}[^\n]* \n
+                    (?>
+                        (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
+                    )*
+                |
+                    # Fenced code block marker
+                    (?> ^ | \n )
+                    [ ]{'.($indent).'}~~~+[ ]*\n
+                ' : '' ). ' # End (if not is span).
+                )
+            }xs';
+
+
+        $depth = 0;     # Current depth inside the tag tree.
+        $parsed = "";   # Parsed text that will be returned.
+
+        #
+        # Loop through every tag until we find the closing tag of the parent
+        # or loop until reaching the end of text if no parent tag specified.
+        #
+        do {
+            #
+            # Split the text using the first $tag_match pattern found.
+            # Text before  pattern will be first in the array, text after
+            # pattern will be at the end, and between will be any catches made
+            # by the pattern.
+            #
+            $parts = preg_split($block_tag_re, $text, 2,
+                                PREG_SPLIT_DELIM_CAPTURE);
+
+            # If in Markdown span mode, add a empty-string span-level hash
+            # after each newline to prevent triggering any block element.
+            if ($span) {
+                $void = $this->hashPart("", ':');
+                $newline = "$void\n";
+                $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+            }
+
+            $parsed .= $parts[0]; # Text before current tag.
+
+            # If end of $text has been reached. Stop loop.
+            if (count($parts) < 3) {
+                $text = "";
+                break;
+            }
+
+            $tag  = $parts[1]; # Tag to handle.
+            $text = $parts[2]; # Remaining text after current tag.
+            $tag_re = preg_quote($tag); # For use in a regular expression.
+
+            #
+            # Check for: Code span marker
+            #
+            if ($tag{0} == "`") {
+                # Find corresponding end marker.
+                $tag_re = preg_quote($tag);
+                if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)'.$tag_re.'(?!`)}',
+                    $text, $matches))
+                {
+                    # End marker found: pass text unchanged until marker.
+                    $parsed .= $tag . $matches[0];
+                    $text = substr($text, strlen($matches[0]));
+                }
+                else {
+                    # Unmatched marker: just skip it.
+                    $parsed .= $tag;
+                }
+            }
+            #
+            # Check for: Indented code block or fenced code block marker.
+            #
+            else if ($tag{0} == "\n" || $tag{0} == "~") {
+                if ($tag{1} == "\n" || $tag{1} == " ") {
+                    # Indented code block: pass it unchanged, will be handled
+                    # later.
+                    $parsed .= $tag;
+                }
+                else {
+                    # Fenced code block marker: find matching end marker.
+                    $tag_re = preg_quote(trim($tag));
+                    if (preg_match('{^(?>.*\n)+?'.$tag_re.' *\n}', $text,
+                        $matches))
+                    {
+                        # End marker found: pass text unchanged until marker.
+                        $parsed .= $tag . $matches[0];
+                        $text = substr($text, strlen($matches[0]));
+                    }
+                    else {
+                        # No end marker: just skip it.
+                        $parsed .= $tag;
+                    }
+                }
+            }
+            #
+            # Check for: Opening Block level tag or
+            #            Opening Context Block tag (like ins and del)
+            #               used as a block tag (tag is alone on it's line).
+            #
+            else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
+                (   preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
+                    preg_match($newline_before_re, $parsed) &&
+                    preg_match($newline_after_re, $text)    )
+                )
+            {
+                # Need to parse tag and following text using the HTML parser.
+                list($block_text, $text) =
+                    $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+
+                # Make sure it stays outside of any paragraph by adding newlines.
+                $parsed .= "\n\n$block_text\n\n";
+            }
+            #
+            # Check for: Clean tag (like script, math)
+            #            HTML Comments, processing instructions.
+            #
+            else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
+                $tag{1} == '!' || $tag{1} == '?')
+            {
+                # Need to parse tag and following text using the HTML parser.
+                # (don't check for markdown attribute)
+                list($block_text, $text) =
+                    $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+
+                $parsed .= $block_text;
+            }
+            #
+            # Check for: Tag with same name as enclosing tag.
+            #
+            else if ($enclosing_tag_re !== '' &&
+                # Same name as enclosing tag.
+                preg_match('{^</?(?:'.$enclosing_tag_re.')\b}', $tag))
+            {
+                #
+                # Increase/decrease nested tag count.
+                #
+                if ($tag{1} == '/')                     $depth--;
+                else if ($tag{strlen($tag)-2} != '/')   $depth++;
+
+                if ($depth < 0) {
+                    #
+                    # Going out of parent element. Clean up and break so we
+                    # return to the calling function.
+                    #
+                    $text = $tag . $text;
+                    break;
+                }
+
+                $parsed .= $tag;
+            }
+            else {
+                $parsed .= $tag;
+            }
+        } while ($depth >= 0);
+
+        return array($parsed, $text);
+    }
+    function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+    #
+    # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+    #
+    # *   Calls $hash_method to convert any blocks.
+    # *   Stops when the first opening tag closes.
+    # *   $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+    #     (it is not inside clean tags)
+    #
+    # Returns an array of that form: ( processed text , remaining text )
+    #
+        if ($text === '') return array('', '');
+
+        # Regex to match `markdown` attribute inside of a tag.
+        $markdown_attr_re = '
+            {
+                \s*         # Eat whitespace before the `markdown` attribute
+                markdown
+                \s*=\s*
+                (?>
+                    (["\'])     # $1: quote delimiter
+                    (.*?)       # $2: attribute value
+                    \1          # matching delimiter
+                |
+                    ([^\s>]*)   # $3: unquoted attribute value
+                )
+                ()              # $4: make $3 always defined (avoid warnings)
+            }xs';
+
+        # Regex to match any tag.
+        $tag_re = '{
+                (                   # $2: Capture hole tag.
+                    </?                 # Any opening or closing tag.
+                        [\w:$]+         # Tag name.
+                        (?:
+                            (?=[\s"\'/a-zA-Z0-9])   # Allowed characters after tag name.
+                            (?>
+                                ".*?"       |   # Double quotes (can contain `>`)
+                                \'.*?\'     |   # Single quotes (can contain `>`)
+                                .+?             # Anything but quotes and `>`.
+                            )*?
+                        )?
+                    >                   # End of tag.
+                |
+                    <!--    .*?     --> # HTML Comment
+                |
+                    <\?.*?\?> | <%.*?%> # Processing instruction
+                |
+                    <!\[CDATA\[.*?\]\]> # CData Block
+                )
+            }xs';
+
+        $original_text = $text;     # Save original text in case of faliure.
+
+        $depth      = 0;    # Current depth inside the tag tree.
+        $block_text = "";   # Temporary text holder for current text.
+        $parsed     = "";   # Parsed text that will be returned.
+
+        #
+        # Get the name of the starting tag.
+        # (This pattern makes $base_tag_name_re safe without quoting.)
+        #
+        if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+            $base_tag_name_re = $matches[1];
+
+        #
+        # Loop through every tag until we find the corresponding closing tag.
+        #
+        do {
+            #
+            # Split the text using the first $tag_match pattern found.
+            # Text before  pattern will be first in the array, text after
+            # pattern will be at the end, and between will be any catches made
+            # by the pattern.
+            #
+            $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+            if (count($parts) < 3) {
+                #
+                # End of $text reached with unbalenced tag(s).
+                # In that case, we return original text unchanged and pass the
+                # first character as filtered to prevent an infinite loop in the
+                # parent function.
+                #
+                return array($original_text{0}, substr($original_text, 1));
+            }
+
+            $block_text .= $parts[0]; # Text before current tag.
+            $tag         = $parts[1]; # Tag to handle.
+            $text        = $parts[2]; # Remaining text after current tag.
+
+            #
+            # Check for: Auto-close tag (like <hr/>)
+            #            Comments and Processing Instructions.
+            #
+            if (preg_match('{^</?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
+                $tag{1} == '!' || $tag{1} == '?')
+            {
+                # Just add the tag to the block as if it was text.
+                $block_text .= $tag;
+            }
+            else {
+                #
+                # Increase/decrease nested tag count. Only do so if
+                # the tag's name match base tag's.
+                #
+                if (preg_match('{^</?'.$base_tag_name_re.'\b}', $tag)) {
+                    if ($tag{1} == '/')                     $depth--;
+                    else if ($tag{strlen($tag)-2} != '/')   $depth++;
+                }
+
+                #
+                # Check for `markdown="1"` attribute and handle it.
+                #
+                if ($md_attr &&
+                    preg_match($markdown_attr_re, $tag, $attr_m) &&
+                    preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+                {
+                    # Remove `markdown` attribute from opening tag.
+                    $tag = preg_replace($markdown_attr_re, '', $tag);
+
+                    # Check if text inside this tag must be parsed in span mode.
+                    $this->mode = $attr_m[2] . $attr_m[3];
+                    $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+                        preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
+
+                    # Calculate indent before tag.
+                    if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+                        $strlen = $this->utf8_strlen;
+                        $indent = $strlen($matches[1], 'UTF-8');
+                    } else {
+                        $indent = 0;
+                    }
+
+                    # End preceding block with this tag.
+                    $block_text .= $tag;
+                    $parsed .= $this->$hash_method($block_text);
+
+                    # Get enclosing tag name for the ParseMarkdown function.
+                    # (This pattern makes $tag_name_re safe without quoting.)
+                    preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+                    $tag_name_re = $matches[1];
+
+                    # Parse the content using the HTML-in-Markdown parser.
+                    list ($block_text, $text)
+                        = $this->_hashHTMLBlocks_inMarkdown($text, $indent,
+                            $tag_name_re, $span_mode);
+
+                    # Outdent markdown text.
+                    if ($indent > 0) {
+                        $block_text = preg_replace("/^[ ]{1,$indent}/m", "",
+                                                    $block_text);
+                    }
+
+                    # Append tag content to parsed text.
+                    if (!$span_mode)    $parsed .= "\n\n$block_text\n\n";
+                    else                $parsed .= "$block_text";
+
+                    # Start over a new block.
+                    $block_text = "";
+                }
+                else $block_text .= $tag;
+            }
+
+        } while ($depth > 0);
+
+        #
+        # Hash last block text that wasn't processed inside the loop.
+        #
+        $parsed .= $this->$hash_method($block_text);
+
+        return array($parsed, $text);
+    }
+
+
+    function hashClean($text) {
+    #
+    # Called whenever a tag must be hashed when a function insert a "clean" tag
+    # in $text, it pass through this function and is automaticaly escaped,
+    # blocking invalid nested overlap.
+    #
+        return $this->hashPart($text, 'C');
+    }
+
+
+    function doHeaders($text) {
+    #
+    # Redefined to add id attribute support.
+    #
+        # Setext-style headers:
+        #     Header 1  {#header1}
+        #     ========
+        #
+        #     Header 2  {#header2}
+        #     --------
+        #
+        $text = preg_replace_callback(
+            '{
+                (^.+?)                              # $1: Header text
+                (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})?    # $2: Id attribute
+                [ ]*\n(=+|-+)[ ]*\n+                # $3: Header footer
+            }mx',
+            array(&$this, '_doHeaders_callback_setext'), $text);
+
+        # atx-style headers:
+        #   # Header 1        {#header1}
+        #   ## Header 2       {#header2}
+        #   ## Header 2 with closing hashes ##  {#header3}
+        #   ...
+        #   ###### Header 6   {#header2}
+        #
+        $text = preg_replace_callback('{
+                ^(\#{1,6})  # $1 = string of #\'s
+                [ ]*
+                (.+?)       # $2 = Header text
+                [ ]*
+                \#*         # optional closing #\'s (not counted)
+                (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
+                [ ]*
+                \n+
+            }xm',
+            array(&$this, '_doHeaders_callback_atx'), $text);
+
+        return $text;
+    }
+    function _doHeaders_attr($attr) {
+        if (empty($attr))  return "";
+        return " id=\"$attr\"";
+    }
+    function _doHeaders_callback_setext($matches) {
+        if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
+            return $matches[0];
+        $level = $matches[3]{0} == '=' ? 1 : 2;
+        $attr  = $this->_doHeaders_attr($id =& $matches[2]);
+        $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
+        return "\n" . $this->hashBlock($block) . "\n\n";
+    }
+    function _doHeaders_callback_atx($matches) {
+        $level = strlen($matches[1]);
+        $attr  = $this->_doHeaders_attr($id =& $matches[3]);
+        $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
+        return "\n" . $this->hashBlock($block) . "\n\n";
+    }
+
+
+    function doTables($text) {
+    #
+    # Form HTML tables.
+    #
+        $less_than_tab = $this->tab_width - 1;
+        #
+        # Find tables with leading pipe.
+        #
+        #   | Header 1 | Header 2
+        #   | -------- | --------
+        #   | Cell 1   | Cell 2
+        #   | Cell 3   | Cell 4
+        #
+        $text = preg_replace_callback('
+            {
+                ^                           # Start of a line
+                [ ]{0,'.$less_than_tab.'}   # Allowed whitespace.
+                [|]                         # Optional leading pipe (present)
+                (.+) \n                     # $1: Header row (at least one pipe)
+
+                [ ]{0,'.$less_than_tab.'}   # Allowed whitespace.
+                [|] ([ ]*[-:]+[-| :]*) \n   # $2: Header underline
+
+                (                           # $3: Cells
+                    (?>
+                        [ ]*                # Allowed whitespace.
+                        [|] .* \n           # Row content.
+                    )*
+                )
+                (?=\n|\Z)                   # Stop at final double newline.
+            }xm',
+            array(&$this, '_doTable_leadingPipe_callback'), $text);
+
+        #
+        # Find tables without leading pipe.
+        #
+        #   Header 1 | Header 2
+        #   -------- | --------
+        #   Cell 1   | Cell 2
+        #   Cell 3   | Cell 4
+        #
+        $text = preg_replace_callback('
+            {
+                ^                           # Start of a line
+                [ ]{0,'.$less_than_tab.'}   # Allowed whitespace.
+                (\S.*[|].*) \n              # $1: Header row (at least one pipe)
+
+                [ ]{0,'.$less_than_tab.'}   # Allowed whitespace.
+                ([-:]+[ ]*[|][-| :]*) \n    # $2: Header underline
+
+                (                           # $3: Cells
+                    (?>
+                        .* [|] .* \n        # Row content
+                    )*
+                )
+                (?=\n|\Z)                   # Stop at final double newline.
+            }xm',
+            array(&$this, '_DoTable_callback'), $text);
+
+        return $text;
+    }
+    function _doTable_leadingPipe_callback($matches) {
+        $head       = $matches[1];
+        $underline  = $matches[2];
+        $content    = $matches[3];
+
+        # Remove leading pipe for each row.
+        $content    = preg_replace('/^ *[|]/m', '', $content);
+
+        return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+    }
+    function _doTable_callback($matches) {
+        $head       = $matches[1];
+        $underline  = $matches[2];
+        $content    = $matches[3];
+
+        # Remove any tailing pipes for each line.
+        $head       = preg_replace('/[|] *$/m', '', $head);
+        $underline  = preg_replace('/[|] *$/m', '', $underline);
+        $content    = preg_replace('/[|] *$/m', '', $content);
+
+        # Reading alignement from header underline.
+        $separators = preg_split('/ *[|] */', $underline);
+        foreach ($separators as $n => $s) {
+            if (preg_match('/^ *-+: *$/', $s))      $attr[$n] = ' align="right"';
+            else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
+            else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
+            else                                    $attr[$n] = '';
+        }
+
+        # Parsing span elements, including code spans, character escapes,
+        # and inline HTML tags, so that pipes inside those gets ignored.
+        $head       = $this->parseSpan($head);
+        $headers    = preg_split('/ *[|] */', $head);
+        $col_count  = count($headers);
+
+        # Write column headers.
+        $text = "<table>\n";
+        $text .= "<thead>\n";
+        $text .= "<tr>\n";
+        foreach ($headers as $n => $header)
+            $text .= "  <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
+        $text .= "</tr>\n";
+        $text .= "</thead>\n";
+
+        # Split content by row.
+        $rows = explode("\n", trim($content, "\n"));
+
+        $text .= "<tbody>\n";
+        foreach ($rows as $row) {
+            # Parsing span elements, including code spans, character escapes,
+            # and inline HTML tags, so that pipes inside those gets ignored.
+            $row = $this->parseSpan($row);
+
+            # Split row by cell.
+            $row_cells = preg_split('/ *[|] */', $row, $col_count);
+            $row_cells = array_pad($row_cells, $col_count, '');
+
+            $text .= "<tr>\n";
+            foreach ($row_cells as $n => $cell)
+                $text .= "  <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
+            $text .= "</tr>\n";
+        }
+        $text .= "</tbody>\n";
+        $text .= "</table>";
+
+        return $this->hashBlock($text) . "\n";
+    }
+
+
+    function doDefLists($text) {
+    #
+    # Form HTML definition lists.
+    #
+        $less_than_tab = $this->tab_width - 1;
+
+        # Re-usable pattern to match any entire dl list:
+        $whole_list_re = '(?>
+            (                               # $1 = whole list
+              (                             # $2
+                [ ]{0,'.$less_than_tab.'}
+                ((?>.*\S.*\n)+)             # $3 = defined term
+                \n?
+                [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+              )
+              (?s:.+?)
+              (                             # $4
+                  \z
+                |
+                  \n{2,}
+                  (?=\S)
+                  (?!                       # Negative lookahead for another term
+                    [ ]{0,'.$less_than_tab.'}
+                    (?: \S.*\n )+?          # defined term
+                    \n?
+                    [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+                  )
+                  (?!                       # Negative lookahead for another definition
+                    [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+                  )
+              )
+            )
+        )'; // mx
+
+        $text = preg_replace_callback('{
+                (?>\A\n?|(?<=\n\n))
+                '.$whole_list_re.'
+            }mx',
+            array(&$this, '_doDefLists_callback'), $text);
+
+        return $text;
+    }
+    function _doDefLists_callback($matches) {
+        # Re-usable patterns to match list item bullets and number markers:
+        $list = $matches[1];
+
+        # Turn double returns into triple returns, so that we can make a
+        # paragraph for the last item in a list, if necessary:
+        $result = trim($this->processDefListItems($list));
+        $result = "<dl>\n" . $result . "\n</dl>";
+        return $this->hashBlock($result) . "\n\n";
+    }
+
+
+    function processDefListItems($list_str) {
+    #
+    #   Process the contents of a single definition list, splitting it
+    #   into individual term and definition list items.
+    #
+        $less_than_tab = $this->tab_width - 1;
+
+        # trim trailing blank lines:
+        $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+        # Process definition terms.
+        $list_str = preg_replace_callback('{
+            (?>\A\n?|\n\n+)                 # leading line
+            (                               # definition terms = $1
+                [ ]{0,'.$less_than_tab.'}   # leading whitespace
+                (?![:][ ]|[ ])              # negative lookahead for a definition
+                                            #   mark (colon) or more whitespace.
+                (?> \S.* \n)+?              # actual term (not whitespace).
+            )
+            (?=\n?[ ]{0,3}:[ ])             # lookahead for following line feed
+                                            #   with a definition mark.
+            }xm',
+            array(&$this, '_processDefListItems_callback_dt'), $list_str);
+
+        # Process actual definitions.
+        $list_str = preg_replace_callback('{
+            \n(\n+)?                        # leading line = $1
+            (                               # marker space = $2
+                [ ]{0,'.$less_than_tab.'}   # whitespace before colon
+                [:][ ]+                     # definition mark (colon)
+            )
+            ((?s:.+?))                      # definition text = $3
+            (?= \n+                         # stop at next definition mark,
+                (?:                         # next term or end of text
+                    [ ]{0,'.$less_than_tab.'} [:][ ]    |
+                    <dt> | \z
+                )
+            )
+            }xm',
+            array(&$this, '_processDefListItems_callback_dd'), $list_str);
+
+        return $list_str;
+    }
+    function _processDefListItems_callback_dt($matches) {
+        $terms = explode("\n", trim($matches[1]));
+        $text = '';
+        foreach ($terms as $term) {
+            $term = $this->runSpanGamut(trim($term));
+            $text .= "\n<dt>" . $term . "</dt>";
+        }
+        return $text . "\n";
+    }
+    function _processDefListItems_callback_dd($matches) {
+        $leading_line   = $matches[1];
+        $marker_space   = $matches[2];
+        $def            = $matches[3];
+
+        if ($leading_line || preg_match('/\n{2,}/', $def)) {
+            # Replace marker with the appropriate whitespace indentation
+            $def = str_repeat(' ', strlen($marker_space)) . $def;
+            $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
+            $def = "\n". $def ."\n";
+        }
+        else {
+            $def = rtrim($def);
+            $def = $this->runSpanGamut($this->outdent($def));
+        }
+
+        return "\n<dd>" . $def . "</dd>\n";
+    }
+
+
+    function doFencedCodeBlocks($text) {
+    #
+    # Adding the fenced code block syntax to regular Markdown:
+    #
+    # ~~~
+    # Code block
+    # ~~~
+    #
+        $less_than_tab = $this->tab_width;
+
+        $text = preg_replace_callback('{
+                (?:\n|\A)
+                # 1: Opening marker
+                (
+                    ~{3,} # Marker: three tilde or more.
+                )
+                [ ]* \n # Whitespace and newline following marker.
+
+                # 2: Content
+                (
+                    (?>
+                        (?!\1 [ ]* \n)  # Not a closing marker.
+                        .*\n+
+                    )+
+                )
+
+                # Closing marker.
+                \1 [ ]* \n
+            }xm',
+            array(&$this, '_doFencedCodeBlocks_callback'), $text);
+
+        return $text;
+    }
+    function _doFencedCodeBlocks_callback($matches) {
+        $codeblock = $matches[2];
+        $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+        $codeblock = preg_replace_callback('/^\n+/',
+            array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
+        $codeblock = "<pre><code>$codeblock</code></pre>";
+        return "\n\n".$this->hashBlock($codeblock)."\n\n";
+    }
+    function _doFencedCodeBlocks_newlines($matches) {
+        return str_repeat("<br$this->empty_element_suffix",
+            strlen($matches[0]));
+    }
+
+
+    #
+    # Redefining emphasis markers so that emphasis by underscore does not
+    # work in the middle of a word.
+    #
+    var $em_relist = array(
+        ''  => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?=\S)(?![.,:;]\s)',
+        '*' => '(?<=\S)(?<!\*)\*(?!\*)',
+        '_' => '(?<=\S)(?<!_)_(?![a-zA-Z0-9_])',
+        );
+    var $strong_relist = array(
+        ''   => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?=\S)(?![.,:;]\s)',
+        '**' => '(?<=\S)(?<!\*)\*\*(?!\*)',
+        '__' => '(?<=\S)(?<!_)__(?![a-zA-Z0-9_])',
+        );
+    var $em_strong_relist = array(
+        ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?=\S)(?![.,:;]\s)',
+        '***' => '(?<=\S)(?<!\*)\*\*\*(?!\*)',
+        '___' => '(?<=\S)(?<!_)___(?![a-zA-Z0-9_])',
+        );
+
+
+    function formParagraphs($text) {
+    #
+    #   Params:
+    #       $text - string to process with html <p> tags
+    #
+        # Strip leading and trailing lines:
+        $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+        $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+        #
+        # Wrap <p> tags and unhashify HTML blocks
+        #
+        foreach ($grafs as $key => $value) {
+            $value = trim($this->runSpanGamut($value));
+
+            # Check if this should be enclosed in a paragraph.
+            # Clean tag hashes & block tag hashes are left alone.
+            $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+
+            if ($is_p) {
+                $value = "<p>$value</p>";
+            }
+            $grafs[$key] = $value;
+        }
+
+        # Join grafs in one text, then unhash HTML tags.
+        $text = implode("\n\n", $grafs);
+
+        # Finish by removing any tag hashes still present in $text.
+        $text = $this->unhash($text);
+
+        return $text;
+    }
+
+
+    ### Footnotes
+
+    function stripFootnotes($text) {
+    #
+    # Strips link definitions from text, stores the URLs and titles in
+    # hash references.
+    #
+        $less_than_tab = $this->tab_width - 1;
+
+        # Link defs are in the form: [^id]: url "optional title"
+        $text = preg_replace_callback('{
+            ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?:  # note_id = $1
+              [ ]*
+              \n?                   # maybe *one* newline
+            (                       # text = $2 (no blank lines allowed)
+                (?:
+                    .+              # actual text
+                |
+                    \n              # newlines but
+                    (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+                    (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed
+                                    # by non-indented content
+                )*
+            )
+            }xm',
+            array(&$this, '_stripFootnotes_callback'),
+            $text);
+        return $text;
+    }
+    function _stripFootnotes_callback($matches) {
+        $note_id = $this->fn_id_prefix . $matches[1];
+        $this->footnotes[$note_id] = $this->outdent($matches[2]);
+        return ''; # String that will replace the block
+    }
+
+
+    function doFootnotes($text) {
+    #
+    # Replace footnote references in $text [^id] with a special text-token
+    # which will be replaced by the actual footnote marker in appendFootnotes.
+    #
+        if (!$this->in_anchor) {
+            $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+        }
+        return $text;
+    }
+
+
+    function appendFootnotes($text) {
+    #
+    # Append footnote list to text.
+    #
+        $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
+            array(&$this, '_appendFootnotes_callback'), $text);
+
+        if (!empty($this->footnotes_ordered)) {
+            $text .= "\n\n";
+            $text .= "<div class=\"footnotes\">\n";
+            $text .= "<hr". MARKDOWN_EMPTY_ELEMENT_SUFFIX ."\n";
+            $text .= "<ol>\n\n";
+
+            $attr = " rev=\"footnote\"";
+            if ($this->fn_backlink_class != "") {
+                $class = $this->fn_backlink_class;
+                $class = $this->encodeAttribute($class);
+                $attr .= " class=\"$class\"";
+            }
+            if ($this->fn_backlink_title != "") {
+                $title = $this->fn_backlink_title;
+                $title = $this->encodeAttribute($title);
+                $attr .= " title=\"$title\"";
+            }
+            $num = 0;
+
+            while (!empty($this->footnotes_ordered)) {
+                $footnote = reset($this->footnotes_ordered);
+                $note_id = key($this->footnotes_ordered);
+                unset($this->footnotes_ordered[$note_id]);
+
+                $footnote .= "\n"; # Need to append newline before parsing.
+                $footnote = $this->runBlockGamut("$footnote\n");
+                $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
+                    array(&$this, '_appendFootnotes_callback'), $footnote);
+
+                $attr = str_replace("%%", ++$num, $attr);
+                $note_id = $this->encodeAttribute($note_id);
+
+                # Add backlink to last paragraph; create new paragraph if needed.
+                $backlink = "<a href=\"#fnref:$note_id\"$attr>&#8617;</a>";
+                if (preg_match('{</p>$}', $footnote)) {
+                    $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
+                } else {
+                    $footnote .= "\n\n<p>$backlink</p>";
+                }
+
+                $text .= "<li id=\"fn:$note_id\">\n";
+                $text .= $footnote . "\n";
+                $text .= "</li>\n\n";
+            }
+
+            $text .= "</ol>\n";
+            $text .= "</div>";
+        }
+        return $text;
+    }
+    function _appendFootnotes_callback($matches) {
+        $node_id = $this->fn_id_prefix . $matches[1];
+
+        # Create footnote marker only if it has a corresponding footnote *and*
+        # the footnote hasn't been used by another marker.
+        if (isset($this->footnotes[$node_id])) {
+            # Transfert footnote content to the ordered list.
+            $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+            unset($this->footnotes[$node_id]);
+
+            $num = $this->footnote_counter++;
+            $attr = " rel=\"footnote\"";
+            if ($this->fn_link_class != "") {
+                $class = $this->fn_link_class;
+                $class = $this->encodeAttribute($class);
+                $attr .= " class=\"$class\"";
+            }
+            if ($this->fn_link_title != "") {
+                $title = $this->fn_link_title;
+                $title = $this->encodeAttribute($title);
+                $attr .= " title=\"$title\"";
+            }
+
+            $attr = str_replace("%%", $num, $attr);
+            $node_id = $this->encodeAttribute($node_id);
+
+            return
+                "<sup id=\"fnref:$node_id\">".
+                "<a href=\"#fn:$node_id\"$attr>$num</a>".
+                "</sup>";
+        }
+
+        return "[^".$matches[1]."]";
+    }
+
+
+    ### Abbreviations ###
+
+    function stripAbbreviations($text) {
+    #
+    # Strips abbreviations from text, stores titles in hash references.
+    #
+        $less_than_tab = $this->tab_width - 1;
+
+        # Link defs are in the form: [id]*: url "optional title"
+        $text = preg_replace_callback('{
+            ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?:  # abbr_id = $1
+            (.*)                    # text = $2 (no blank lines allowed)
+            }xm',
+            array(&$this, '_stripAbbreviations_callback'),
+            $text);
+        return $text;
+    }
+    function _stripAbbreviations_callback($matches) {
+        $abbr_word = $matches[1];
+        $abbr_desc = $matches[2];
+        if ($this->abbr_word_re)
+            $this->abbr_word_re .= '|';
+        $this->abbr_word_re .= preg_quote($abbr_word);
+        $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+        return ''; # String that will replace the block
+    }
+
+
+    function doAbbreviations($text) {
+    #
+    # Find defined abbreviations in text and wrap them in <abbr> elements.
+    #
+        if ($this->abbr_word_re) {
+            // cannot use the /x modifier because abbr_word_re may
+            // contain significant spaces:
+            $text = preg_replace_callback('{'.
+                '(?<![\w\x1A])'.
+                '(?:'.$this->abbr_word_re.')'.
+                '(?![\w\x1A])'.
+                '}',
+                array(&$this, '_doAbbreviations_callback'), $text);
+        }
+        return $text;
+    }
+    function _doAbbreviations_callback($matches) {
+        $abbr = $matches[0];
+        if (isset($this->abbr_desciptions[$abbr])) {
+            $desc = $this->abbr_desciptions[$abbr];
+            if (empty($desc)) {
+                return $this->hashPart("<abbr>$abbr</abbr>");
+            } else {
+                $desc = $this->encodeAttribute($desc);
+                return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
+            }
+        } else {
+            return $matches[0];
+        }
+    }
+
+}
+
+
+/*
+
+PHP Markdown Extra
+==================
+
+Description
+-----------
+
+This is a PHP port of the original Markdown formatter written in Perl
+by John Gruber. This special "Extra" version of PHP Markdown features
+further enhancements to the syntax for making additional constructs
+such as tables and definition list.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like <div> and <table> as well).
+
+For more information about Markdown's syntax, see:
+
+<http://daringfireball.net/projects/markdown/>
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+<michel.fortin@michelf.com>
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+---------------
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra
+Copyright (c) 2004-2008 Michel Fortin
+<http://www.michelf.com/>
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber
+<http://daringfireball.net/>
+All rights reserved.
+
+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 "Markdown" 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 copyright owner
+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.
+
+*/
+?>
\ No newline at end of file
diff --git a/examples/includes/PHP-Markdown-Extra-1.2.3/markdown.php.orig b/examples/includes/PHP-Markdown-Extra-1.2.3/markdown.php.orig
new file mode 100644 (file)
index 0000000..b0ed7c9
--- /dev/null
@@ -0,0 +1,2909 @@
+<?php
+#
+# Markdown Extra  -  A text-to-HTML conversion tool for web writers
+#
+# PHP Markdown & Extra
+# Copyright (c) 2004-2008 Michel Fortin  
+# <http://www.michelf.com/projects/php-markdown/>
+#
+# Original Markdown
+# Copyright (c) 2004-2006 John Gruber  
+# <http://daringfireball.net/projects/markdown/>
+#
+
+
+define( 'MARKDOWN_VERSION',  "1.0.1m" ); # Sat 21 Jun 2008
+define( 'MARKDOWNEXTRA_VERSION',  "1.2.3" ); # Wed 31 Dec 2008
+
+
+#
+# Global default settings:
+#
+
+# Change to ">" for HTML output
+@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX',  " />");
+
+# Define the width of a tab for code blocks.
+@define( 'MARKDOWN_TAB_WIDTH',     4 );
+
+# Optional title attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_TITLE',         "" );
+@define( 'MARKDOWN_FN_BACKLINK_TITLE',     "" );
+
+# Optional class attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_CLASS',         "" );
+@define( 'MARKDOWN_FN_BACKLINK_CLASS',     "" );
+
+
+#
+# WordPress settings:
+#
+
+# Change to false to remove Markdown from posts and/or comments.
+@define( 'MARKDOWN_WP_POSTS',      true );
+@define( 'MARKDOWN_WP_COMMENTS',   true );
+
+
+
+### Standard Function Interface ###
+
+@define( 'MARKDOWN_PARSER_CLASS',  'MarkdownExtra_Parser' );
+
+function Markdown($text) {
+#
+# Initialize the parser and return the result of its transform method.
+#
+  # Setup static parser variable.
+  static $parser;
+  if (!isset($parser)) {
+    $parser_class = MARKDOWN_PARSER_CLASS;
+    $parser = new $parser_class;
+  }
+
+  # Transform text using parser.
+  return $parser->transform($text);
+}
+
+
+### WordPress Plugin Interface ###
+
+/*
+Plugin Name: Markdown Extra
+Plugin URI: http://www.michelf.com/projects/php-markdown/
+Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://www.michelf.com/projects/php-markdown/">More...</a>
+Version: 1.2.2
+Author: Michel Fortin
+Author URI: http://www.michelf.com/
+*/
+
+if (isset($wp_version)) {
+  # More details about how it works here:
+  # <http://www.michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/>
+  
+  # Post content and excerpts
+  # - Remove WordPress paragraph generator.
+  # - Run Markdown on excerpt, then remove all tags.
+  # - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
+  if (MARKDOWN_WP_POSTS) {
+    remove_filter('the_content',     'wpautop');
+        remove_filter('the_content_rss', 'wpautop');
+    remove_filter('the_excerpt',     'wpautop');
+    add_filter('the_content',     'mdwp_MarkdownPost', 6);
+        add_filter('the_content_rss', 'mdwp_MarkdownPost', 6);
+    add_filter('get_the_excerpt', 'mdwp_MarkdownPost', 6);
+    add_filter('get_the_excerpt', 'trim', 7);
+    add_filter('the_excerpt',     'mdwp_add_p');
+    add_filter('the_excerpt_rss', 'mdwp_strip_p');
+    
+    remove_filter('content_save_pre',  'balanceTags', 50);
+    remove_filter('excerpt_save_pre',  'balanceTags', 50);
+    add_filter('the_content',     'balanceTags', 50);
+    add_filter('get_the_excerpt', 'balanceTags', 9);
+  }
+  
+  # Add a footnote id prefix to posts when inside a loop.
+  function mdwp_MarkdownPost($text) {
+    static $parser;
+    if (!$parser) {
+      $parser_class = MARKDOWN_PARSER_CLASS;
+      $parser = new $parser_class;
+    }
+    if (is_single() || is_page() || is_feed()) {
+      $parser->fn_id_prefix = "";
+    } else {
+      $parser->fn_id_prefix = get_the_ID() . ".";
+    }
+    return $parser->transform($text);
+  }
+  
+  # Comments
+  # - Remove WordPress paragraph generator.
+  # - Remove WordPress auto-link generator.
+  # - Scramble important tags before passing them to the kses filter.
+  # - Run Markdown on excerpt then remove paragraph tags.
+  if (MARKDOWN_WP_COMMENTS) {
+    remove_filter('comment_text', 'wpautop', 30);
+    remove_filter('comment_text', 'make_clickable');
+    add_filter('pre_comment_content', 'Markdown', 6);
+    add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
+    add_filter('pre_comment_content', 'mdwp_show_tags', 12);
+    add_filter('get_comment_text',    'Markdown', 6);
+    add_filter('get_comment_excerpt', 'Markdown', 6);
+    add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
+  
+    global $mdwp_hidden_tags, $mdwp_placeholders;
+    $mdwp_hidden_tags = explode(' ',
+      '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
+    $mdwp_placeholders = explode(' ', str_rot13(
+      'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
+      'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
+  }
+  
+  function mdwp_add_p($text) {
+    if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
+      $text = '<p>'.$text.'</p>';
+      $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
+    }
+    return $text;
+  }
+  
+  function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
+
+  function mdwp_hide_tags($text) {
+    global $mdwp_hidden_tags, $mdwp_placeholders;
+    return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
+  }
+  function mdwp_show_tags($text) {
+    global $mdwp_hidden_tags, $mdwp_placeholders;
+    return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
+  }
+}
+
+
+### bBlog Plugin Info ###
+
+function identify_modifier_markdown() {
+  return array(
+    'name' => 'markdown',
+    'type' => 'modifier',
+    'nicename' => 'PHP Markdown Extra',
+    'description' => 'A text-to-HTML conversion tool for web writers',
+    'authors' => 'Michel Fortin and John Gruber',
+    'licence' => 'GPL',
+    'version' => MARKDOWNEXTRA_VERSION,
+    'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://www.michelf.com/projects/php-markdown/">More...</a>',
+    );
+}
+
+
+### Smarty Modifier Interface ###
+
+function smarty_modifier_markdown($text) {
+  return Markdown($text);
+}
+
+
+### Textile Compatibility Mode ###
+
+# Rename this file to "classTextile.php" and it can replace Textile everywhere.
+
+if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
+  # Try to include PHP SmartyPants. Should be in the same directory.
+  @include_once 'smartypants.php';
+  # Fake Textile class. It calls Markdown instead.
+  class Textile {
+    function TextileThis($text, $lite='', $encode='') {
+      if ($lite == '' && $encode == '')    $text = Markdown($text);
+      if (function_exists('SmartyPants'))  $text = SmartyPants($text);
+      return $text;
+    }
+    # Fake restricted version: restrictions are not supported for now.
+    function TextileRestricted($text, $lite='', $noimage='') {
+      return $this->TextileThis($text, $lite);
+    }
+    # Workaround to ensure compatibility with TextPattern 4.0.3.
+    function blockLite($text) { return $text; }
+  }
+}
+
+
+
+#
+# Markdown Parser Class
+#
+
+class Markdown_Parser {
+
+  # Regex to match balanced [brackets].
+  # Needed to insert a maximum bracked depth while converting to PHP.
+  var $nested_brackets_depth = 6;
+  var $nested_brackets_re;
+  
+  var $nested_url_parenthesis_depth = 4;
+  var $nested_url_parenthesis_re;
+
+  # Table of hash values for escaped characters:
+  var $escape_chars = '\`*_{}[]()>#+-.!';
+  var $escape_chars_re;
+
+  # Change to ">" for HTML output.
+  var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
+  var $tab_width = MARKDOWN_TAB_WIDTH;
+  
+  # Change to `true` to disallow markup or entities.
+  var $no_markup = false;
+  var $no_entities = true;
+  
+  # Predefined urls and titles for reference links and images.
+  var $predef_urls = array();
+  var $predef_titles = array();
+
+
+  function Markdown_Parser() {
+  #
+  # Constructor function. Initialize appropriate member variables.
+  #
+    $this->_initDetab();
+    $this->prepareItalicsAndBold();
+  
+    $this->nested_brackets_re = 
+      str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
+      str_repeat('\])*', $this->nested_brackets_depth);
+  
+    $this->nested_url_parenthesis_re = 
+      str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
+      str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
+    
+    $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
+    
+    # Sort document, block, and span gamut in ascendent priority order.
+    asort($this->document_gamut);
+    asort($this->block_gamut);
+    asort($this->span_gamut);
+  }
+
+
+  # Internal hashes used during transformation.
+  var $urls = array();
+  var $titles = array();
+  var $html_hashes = array();
+  
+  # Status flag to avoid invalid nesting.
+  var $in_anchor = false;
+  
+  
+  function setup() {
+  #
+  # Called before the transformation process starts to setup parser 
+  # states.
+  #
+    # Clear global hashes.
+    $this->urls = $this->predef_urls;
+    $this->titles = $this->predef_titles;
+    $this->html_hashes = array();
+    
+    $in_anchor = false;
+  }
+  
+  function teardown() {
+  #
+  # Called after the transformation process to clear any variable 
+  # which may be taking up memory unnecessarly.
+  #
+    $this->urls = array();
+    $this->titles = array();
+    $this->html_hashes = array();
+  }
+
+
+  function transform($text) {
+  #
+  # Main function. Performs some preprocessing on the input text
+  # and pass it through the document gamut.
+  #
+    $this->setup();
+  
+    # Remove UTF-8 BOM and marker character in input, if present.
+    $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
+
+    # Standardize line endings:
+    #   DOS to Unix and Mac to Unix
+    $text = preg_replace('{\r\n?}', "\n", $text);
+
+    # Make sure $text ends with a couple of newlines:
+    $text .= "\n\n";
+
+    # Convert all tabs to spaces.
+    $text = $this->detab($text);
+
+    # Turn block-level HTML blocks into hash entries
+    $text = $this->hashHTMLBlocks($text);
+
+    # Strip any lines consisting only of spaces and tabs.
+    # This makes subsequent regexen easier to write, because we can
+    # match consecutive blank lines with /\n+/ instead of something
+    # contorted like /[ ]*\n+/ .
+    $text = preg_replace('/^[ ]+$/m', '', $text);
+
+    # Run document gamut methods.
+    foreach ($this->document_gamut as $method => $priority) {
+      $text = $this->$method($text);
+    }
+    
+    $this->teardown();
+
+    return $text . "\n";
+  }
+  
+  var $document_gamut = array(
+    # Strip link definitions, store in hashes.
+    "stripLinkDefinitions" => 20,
+    
+    "runBasicBlockGamut"   => 30,
+    );
+
+
+  function stripLinkDefinitions($text) {
+  #
+  # Strips link definitions from text, stores the URLs and titles in
+  # hash references.
+  #
+    $less_than_tab = $this->tab_width - 1;
+
+    # Link defs are in the form: ^[id]: url "optional title"
+    $text = preg_replace_callback('{
+              ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
+                [ ]*
+                \n?       # maybe *one* newline
+                [ ]*
+              <?(\S+?)>?      # url = $2
+                [ ]*
+                \n?       # maybe one newline
+                [ ]*
+              (?:
+                (?<=\s)     # lookbehind for whitespace
+                ["(]
+                (.*?)     # title = $3
+                [")]
+                [ ]*
+              )?  # title is optional
+              (?:\n+|\Z)
+      }xm',
+      array(&$this, '_stripLinkDefinitions_callback'),
+      $text);
+    return $text;
+  }
+  function _stripLinkDefinitions_callback($matches) {
+    $link_id = strtolower($matches[1]);
+    $this->urls[$link_id] = $matches[2];
+    $this->titles[$link_id] =& $matches[3];
+    return ''; # String that will replace the block
+  }
+
+
+  function hashHTMLBlocks($text) {
+    if ($this->no_markup)  return $text;
+
+    $less_than_tab = $this->tab_width - 1;
+
+    # Hashify HTML blocks:
+    # We only want to do this for block-level HTML tags, such as headers,
+    # lists, and tables. That's because we still want to wrap <p>s around
+    # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+    # phrase emphasis, and spans. The list of tags we're looking for is
+    # hard-coded:
+    #
+    # *  List "a" is made of tags which can be both inline or block-level.
+    #    These will be treated block-level when the start tag is alone on 
+    #    its line, otherwise they're not matched here and will be taken as 
+    #    inline later.
+    # *  List "b" is made of tags which are always block-level;
+    #
+    $block_tags_a_re = 'ins|del';
+    $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
+               'script|noscript|form|fieldset|iframe|math';
+
+    # Regular expression for the content of a block tag.
+    $nested_tags_level = 4;
+    $attr = '
+      (?>       # optional tag attributes
+        \s      # starts with whitespace
+        (?>
+        [^>"/]+   # text outside quotes
+        |
+        /+(?!>)   # slash not followed by ">"
+        |
+        "[^"]*"   # text inside double quotes (tolerate ">")
+        |
+        \'[^\']*\'  # text inside single quotes (tolerate ">")
+        )*
+      )?  
+      ';
+    $content =
+      str_repeat('
+        (?>
+          [^<]+     # content without tag
+        |
+          <\2     # nested opening tag
+          '.$attr.' # attributes
+          (?>
+            />
+          |
+            >', $nested_tags_level).  # end of opening tag
+            '.*?'.          # last level nested tag content
+      str_repeat('
+            </\2\s*>  # closing nested tag
+          )
+          |       
+          <(?!/\2\s*> # other tags with a different name
+          )
+        )*',
+        $nested_tags_level);
+    $content2 = str_replace('\2', '\3', $content);
+
+    # First, look for nested blocks, e.g.:
+    #   <div>
+    #     <div>
+    #     tags for inner block must be indented.
+    #     </div>
+    #   </div>
+    #
+    # The outermost tags must start at the left margin for this to match, and
+    # the inner nested divs must be indented.
+    # We need to do this before the next, more liberal match, because the next
+    # match will start at the first `<div>` and stop at the first `</div>`.
+    $text = preg_replace_callback('{(?>
+      (?>
+        (?<=\n\n)   # Starting after a blank line
+        |       # or
+        \A\n?     # the beginning of the doc
+      )
+      (           # save in $1
+
+        # Match from `\n<tag>` to `</tag>\n`, handling nested tags 
+        # in between.
+          
+            [ ]{0,'.$less_than_tab.'}
+            <('.$block_tags_b_re.')# start tag = $2
+            '.$attr.'>      # attributes followed by > and \n
+            '.$content.'    # content, support nesting
+            </\2>       # the matching end tag
+            [ ]*        # trailing spaces/tabs
+            (?=\n+|\Z)  # followed by a newline or end of document
+
+      | # Special version for tags of group a.
+
+            [ ]{0,'.$less_than_tab.'}
+            <('.$block_tags_a_re.')# start tag = $3
+            '.$attr.'>[ ]*\n  # attributes followed by >
+            '.$content2.'   # content, support nesting
+            </\3>       # the matching end tag
+            [ ]*        # trailing spaces/tabs
+            (?=\n+|\Z)  # followed by a newline or end of document
+          
+      | # Special case just for <hr />. It was easier to make a special 
+        # case than to make the other regex more complicated.
+      
+            [ ]{0,'.$less_than_tab.'}
+            <(hr)       # start tag = $2
+            '.$attr.'     # attributes
+            /?>         # the matching end tag
+            [ ]*
+            (?=\n{2,}|\Z)   # followed by a blank line or end of document
+      
+      | # Special case for standalone HTML comments:
+      
+          [ ]{0,'.$less_than_tab.'}
+          (?s:
+            <!-- .*? -->
+          )
+          [ ]*
+          (?=\n{2,}|\Z)   # followed by a blank line or end of document
+      
+      | # PHP and ASP-style processor instructions (<? and <%)
+      
+          [ ]{0,'.$less_than_tab.'}
+          (?s:
+            <([?%])     # $2
+            .*?
+            \2>
+          )
+          [ ]*
+          (?=\n{2,}|\Z)   # followed by a blank line or end of document
+          
+      )
+      )}Sxmi',
+      array(&$this, '_hashHTMLBlocks_callback'),
+      $text);
+
+    return $text;
+  }
+  function _hashHTMLBlocks_callback($matches) {
+    $text = $matches[1];
+    $key  = $this->hashBlock($text);
+    return "\n\n$key\n\n";
+  }
+  
+  
+  function hashPart($text, $boundary = 'X') {
+  #
+  # Called whenever a tag must be hashed when a function insert an atomic 
+  # element in the text stream. Passing $text to through this function gives
+  # a unique text-token which will be reverted back when calling unhash.
+  #
+  # The $boundary argument specify what character should be used to surround
+  # the token. By convension, "B" is used for block elements that needs not
+  # to be wrapped into paragraph tags at the end, ":" is used for elements
+  # that are word separators and "X" is used in the general case.
+  #
+    # Swap back any tag hash found in $text so we do not have to `unhash`
+    # multiple times at the end.
+    $text = $this->unhash($text);
+    
+    # Then hash the block.
+    static $i = 0;
+    $key = "$boundary\x1A" . ++$i . $boundary;
+    $this->html_hashes[$key] = $text;
+    return $key; # String that will replace the tag.
+  }
+
+
+  function hashBlock($text) {
+  #
+  # Shortcut function for hashPart with block-level boundaries.
+  #
+    return $this->hashPart($text, 'B');
+  }
+
+
+  var $block_gamut = array(
+  #
+  # These are all the transformations that form block-level
+  # tags like paragraphs, headers, and list items.
+  #
+    "doHeaders"         => 10,
+    "doHorizontalRules" => 20,
+    
+    "doLists"           => 40,
+    "doCodeBlocks"      => 50,
+    "doBlockQuotes"     => 60,
+    );
+
+  function runBlockGamut($text) {
+  #
+  # Run block gamut tranformations.
+  #
+    # We need to escape raw HTML in Markdown source before doing anything 
+    # else. This need to be done for each block, and not only at the 
+    # begining in the Markdown function since hashed blocks can be part of
+    # list items and could have been indented. Indented blocks would have 
+    # been seen as a code block in a previous pass of hashHTMLBlocks.
+    $text = $this->hashHTMLBlocks($text);
+    
+    return $this->runBasicBlockGamut($text);
+  }
+  
+  function runBasicBlockGamut($text) {
+  #
+  # Run block gamut tranformations, without hashing HTML blocks. This is 
+  # useful when HTML blocks are known to be already hashed, like in the first
+  # whole-document pass.
+  #
+    foreach ($this->block_gamut as $method => $priority) {
+      $text = $this->$method($text);
+    }
+    
+    # Finally form paragraph and restore hashed blocks.
+    $text = $this->formParagraphs($text);
+
+    return $text;
+  }
+  
+  
+  function doHorizontalRules($text) {
+    # Do Horizontal Rules:
+    return preg_replace(
+      '{
+        ^[ ]{0,3} # Leading space
+        ([-*_])   # $1: First marker
+        (?>     # Repeated marker group
+          [ ]{0,2}  # Zero, one, or two spaces.
+          \1      # Marker character
+        ){2,}   # Group repeated at least twice
+        [ ]*    # Tailing spaces
+        $     # End of line.
+      }mx',
+      "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n", 
+      $text);
+  }
+
+
+  var $span_gamut = array(
+  #
+  # These are all the transformations that occur *within* block-level
+  # tags like paragraphs, headers, and list items.
+  #
+    # Process character escapes, code spans, and inline HTML
+    # in one shot.
+    "parseSpan"           => -30,
+
+    # Process anchor and image tags. Images must come first,
+    # because ![foo][f] looks like an anchor.
+    "doImages"            =>  10,
+    "doAnchors"           =>  20,
+    
+    # Make links out of things like `<http://example.com/>`
+    # Must come after doAnchors, because you can use < and >
+    # delimiters in inline links like [this](<url>).
+    "doAutoLinks"         =>  30,
+    "encodeAmpsAndAngles" =>  40,
+
+    "doItalicsAndBold"    =>  50,
+    "doHardBreaks"        =>  60,
+    );
+
+  function runSpanGamut($text) {
+  #
+  # Run span gamut tranformations.
+  #
+    foreach ($this->span_gamut as $method => $priority) {
+      $text = $this->$method($text);
+    }
+
+    return $text;
+  }
+  
+  
+  function doHardBreaks($text) {
+    # Do hard breaks:
+    return preg_replace_callback('/ {2,}\n/', 
+      array(&$this, '_doHardBreaks_callback'), $text);
+  }
+  function _doHardBreaks_callback($matches) {
+    return $this->hashPart("<br$this->empty_element_suffix\n");
+  }
+
+
+  function doAnchors($text) {
+  #
+  # Turn Markdown link shortcuts into XHTML <a> tags.
+  #
+    if ($this->in_anchor) return $text;
+    $this->in_anchor = true;
+    
+    #
+    # First, handle reference-style links: [link text] [id]
+    #
+    $text = preg_replace_callback('{
+      (         # wrap whole match in $1
+        \[
+        ('.$this->nested_brackets_re.') # link text = $2
+        \]
+
+        [ ]?        # one optional space
+        (?:\n[ ]*)?   # one optional newline followed by spaces
+
+        \[
+        (.*?)   # id = $3
+        \]
+      )
+      }xs',
+      array(&$this, '_doAnchors_reference_callback'), $text);
+
+    #
+    # Next, inline-style links: [link text](url "optional title")
+    #
+    $text = preg_replace_callback('{
+      (       # wrap whole match in $1
+        \[
+        ('.$this->nested_brackets_re.') # link text = $2
+        \]
+        \(      # literal paren
+        [ ]*
+        (?:
+          <(\S*)> # href = $3
+        |
+          ('.$this->nested_url_parenthesis_re.')  # href = $4
+        )
+        [ ]*
+        (     # $5
+          ([\'"]) # quote char = $6
+          (.*?)   # Title = $7
+          \6    # matching quote
+          [ ]*  # ignore any spaces/tabs between closing quote and )
+        )?      # title is optional
+        \)
+      )
+      }xs',
+      array(&$this, '_DoAnchors_inline_callback'), $text);
+
+    #
+    # Last, handle reference-style shortcuts: [link text]
+    # These must come last in case you've also got [link test][1]
+    # or [link test](/foo)
+    #
+//    $text = preg_replace_callback('{
+//      (         # wrap whole match in $1
+//        \[
+//        ([^\[\]]+)    # link text = $2; can\'t contain [ or ]
+//        \]
+//      )
+//      }xs',
+//      array(&$this, '_doAnchors_reference_callback'), $text);
+
+    $this->in_anchor = false;
+    return $text;
+  }
+  function _doAnchors_reference_callback($matches) {
+    $whole_match =  $matches[1];
+    $link_text   =  $matches[2];
+    $link_id     =& $matches[3];
+
+    if ($link_id == "") {
+      # for shortcut links like [this][] or [this].
+      $link_id = $link_text;
+    }
+    
+    # lower-case and turn embedded newlines into spaces
+    $link_id = strtolower($link_id);
+    $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+    if (isset($this->urls[$link_id])) {
+      $url = $this->urls[$link_id];
+      $url = $this->encodeAttribute($url);
+      
+      $result = "<a href=\"$url\"";
+      if ( isset( $this->titles[$link_id] ) ) {
+        $title = $this->titles[$link_id];
+        $title = $this->encodeAttribute($title);
+        $result .=  " title=\"$title\"";
+      }
+    
+      $link_text = $this->runSpanGamut($link_text);
+      $result .= ">$link_text</a>";
+      $result = $this->hashPart($result);
+    }
+    else {
+      $result = $whole_match;
+    }
+    return $result;
+  }
+  function _doAnchors_inline_callback($matches) {
+    $whole_match  =  $matches[1];
+    $link_text    =  $this->runSpanGamut($matches[2]);
+    $url      =  $matches[3] == '' ? $matches[4] : $matches[3];
+    $title      =& $matches[7];
+
+    $url = $this->encodeAttribute($url);
+
+    $result = "<a href=\"$url\"";
+    if (isset($title)) {
+      $title = $this->encodeAttribute($title);
+      $result .=  " title=\"$title\"";
+    }
+    
+    $link_text = $this->runSpanGamut($link_text);
+    $result .= ">$link_text</a>";
+
+    return $this->hashPart($result);
+  }
+
+
+  function doImages($text) {
+  #
+  # Turn Markdown image shortcuts into <img> tags.
+  #
+    #
+    # First, handle reference-style labeled images: ![alt text][id]
+    #
+    $text = preg_replace_callback('{
+      (       # wrap whole match in $1
+        !\[
+        ('.$this->nested_brackets_re.')   # alt text = $2
+        \]
+
+        [ ]?        # one optional space
+        (?:\n[ ]*)?   # one optional newline followed by spaces
+
+        \[
+        (.*?)   # id = $3
+        \]
+
+      )
+      }xs', 
+      array(&$this, '_doImages_reference_callback'), $text);
+
+    #
+    # Next, handle inline images:  ![alt text](url "optional title")
+    # Don't forget: encode * and _
+    #
+    $text = preg_replace_callback('{
+      (       # wrap whole match in $1
+        !\[
+        ('.$this->nested_brackets_re.')   # alt text = $2
+        \]
+        \s?     # One optional whitespace character
+        \(      # literal paren
+        [ ]*
+        (?:
+          <(\S*)> # src url = $3
+        |
+          ('.$this->nested_url_parenthesis_re.')  # src url = $4
+        )
+        [ ]*
+        (     # $5
+          ([\'"]) # quote char = $6
+          (.*?)   # title = $7
+          \6    # matching quote
+          [ ]*
+        )?      # title is optional
+        \)
+      )
+      }xs',
+      array(&$this, '_doImages_inline_callback'), $text);
+
+    return $text;
+  }
+  function _doImages_reference_callback($matches) {
+    $whole_match = $matches[1];
+    $alt_text    = $matches[2];
+    $link_id     = strtolower($matches[3]);
+
+    if ($link_id == "") {
+      $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+    }
+
+    $alt_text = $this->encodeAttribute($alt_text);
+    if (isset($this->urls[$link_id])) {
+      $url = $this->encodeAttribute($this->urls[$link_id]);
+      $result = "<img src=\"$url\" alt=\"$alt_text\"";
+      if (isset($this->titles[$link_id])) {
+        $title = $this->titles[$link_id];
+        $title = $this->encodeAttribute($title);
+        $result .=  " title=\"$title\"";
+      }
+      $result .= $this->empty_element_suffix;
+      $result = $this->hashPart($result);
+    }
+    else {
+      # If there's no such link ID, leave intact:
+      $result = $whole_match;
+    }
+
+    return $result;
+  }
+  function _doImages_inline_callback($matches) {
+    $whole_match  = $matches[1];
+    $alt_text   = $matches[2];
+    $url      = $matches[3] == '' ? $matches[4] : $matches[3];
+    $title      =& $matches[7];
+
+    $alt_text = $this->encodeAttribute($alt_text);
+    $url = $this->encodeAttribute($url);
+    $result = "<img src=\"$url\" alt=\"$alt_text\"";
+    if (isset($title)) {
+      $title = $this->encodeAttribute($title);
+      $result .=  " title=\"$title\""; # $title already quoted
+    }
+    $result .= $this->empty_element_suffix;
+
+    return $this->hashPart($result);
+  }
+
+
+  function doHeaders($text) {
+    # Setext-style headers:
+    #   Header 1
+    #   ========
+    #  
+    #   Header 2
+    #   --------
+    #
+    $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
+      array(&$this, '_doHeaders_callback_setext'), $text);
+
+    # atx-style headers:
+    # # Header 1
+    # ## Header 2
+    # ## Header 2 with closing hashes ##
+    # ...
+    # ###### Header 6
+    #
+    $text = preg_replace_callback('{
+        ^(\#{1,6})  # $1 = string of #\'s
+        [ ]*
+        (.+?)   # $2 = Header text
+        [ ]*
+        \#*     # optional closing #\'s (not counted)
+        \n+
+      }xm',
+      array(&$this, '_doHeaders_callback_atx'), $text);
+
+    return $text;
+  }
+  function _doHeaders_callback_setext($matches) {
+    # Terrible hack to check we haven't found an empty list item.
+    if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+      return $matches[0];
+    
+    $level = $matches[2]{0} == '=' ? 1 : 2;
+    $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
+    return "\n" . $this->hashBlock($block) . "\n\n";
+  }
+  function _doHeaders_callback_atx($matches) {
+    $level = strlen($matches[1]);
+    $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
+    return "\n" . $this->hashBlock($block) . "\n\n";
+  }
+
+
+  function doLists($text) {
+  #
+  # Form HTML ordered (numbered) and unordered (bulleted) lists.
+  #
+    $less_than_tab = $this->tab_width - 1;
+
+    # Re-usable patterns to match list item bullets and number markers:
+    $marker_ul_re  = '[*+-]';
+    $marker_ol_re  = '\d+[.]';
+    $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+    $markers_relist = array($marker_ul_re, $marker_ol_re);
+
+    foreach ($markers_relist as $marker_re) {
+      # Re-usable pattern to match any entirel ul or ol list:
+      $whole_list_re = '
+        (               # $1 = whole list
+          (               # $2
+          [ ]{0,'.$less_than_tab.'}
+          ('.$marker_re.')      # $3 = first list item marker
+          [ ]+
+          )
+          (?s:.+?)
+          (               # $4
+            \z
+          |
+            \n{2,}
+            (?=\S)
+            (?!           # Negative lookahead for another list item marker
+            [ ]*
+            '.$marker_re.'[ ]+
+            )
+          )
+        )
+      '; // mx
+      
+      # We use a different prefix before nested lists than top-level lists.
+      # See extended comment in _ProcessListItems().
+    
+      if ($this->list_level) {
+        $text = preg_replace_callback('{
+            ^
+            '.$whole_list_re.'
+          }mx',
+          array(&$this, '_doLists_callback'), $text);
+      }
+      else {
+        $text = preg_replace_callback('{
+            (?:(?<=\n)\n|\A\n?) # Must eat the newline
+            '.$whole_list_re.'
+          }mx',
+          array(&$this, '_doLists_callback'), $text);
+      }
+    }
+
+    return $text;
+  }
+  function _doLists_callback($matches) {
+    # Re-usable patterns to match list item bullets and number markers:
+    $marker_ul_re  = '[*+-]';
+    $marker_ol_re  = '\d+[.]';
+    $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+    
+    $list = $matches[1];
+    $list_type = preg_match("/$marker_ul_re/", $matches[3]) ? "ul" : "ol";
+    
+    $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+    
+    $list .= "\n";
+    $result = $this->processListItems($list, $marker_any_re);
+    
+    $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+    return "\n". $result ."\n\n";
+  }
+
+  var $list_level = 0;
+
+  function processListItems($list_str, $marker_any_re) {
+  #
+  # Process the contents of a single ordered or unordered list, splitting it
+  # into individual list items.
+  #
+    # The $this->list_level global keeps track of when we're inside a list.
+    # Each time we enter a list, we increment it; when we leave a list,
+    # we decrement. If it's zero, we're not in a list anymore.
+    #
+    # We do this because when we're not inside a list, we want to treat
+    # something like this:
+    #
+    #   I recommend upgrading to version
+    #   8. Oops, now this line is treated
+    #   as a sub-list.
+    #
+    # As a single paragraph, despite the fact that the second line starts
+    # with a digit-period-space sequence.
+    #
+    # Whereas when we're inside a list (or sub-list), that line will be
+    # treated as the start of a sub-list. What a kludge, huh? This is
+    # an aspect of Markdown's syntax that's hard to parse perfectly
+    # without resorting to mind-reading. Perhaps the solution is to
+    # change the syntax rules such that sub-lists must start with a
+    # starting cardinal number; e.g. "1." or "a.".
+    
+    $this->list_level++;
+
+    # trim trailing blank lines:
+    $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+    $list_str = preg_replace_callback('{
+      (\n)?             # leading line = $1
+      (^[ ]*)             # leading whitespace = $2
+      ('.$marker_any_re.'       # list marker and space = $3
+        (?:[ ]+|(?=\n)) # space only required if item is not empty
+      )
+      ((?s:.*?))            # list item text   = $4
+      (?:(\n+(?=\n))|\n)        # tailing blank line = $5
+      (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
+      }xm',
+      array(&$this, '_processListItems_callback'), $list_str);
+
+    $this->list_level--;
+    return $list_str;
+  }
+  function _processListItems_callback($matches) {
+    $item = $matches[4];
+    $leading_line =& $matches[1];
+    $leading_space =& $matches[2];
+    $marker_space = $matches[3];
+    $tailing_blank_line =& $matches[5];
+
+    if ($leading_line || $tailing_blank_line || 
+      preg_match('/\n{2,}/', $item))
+    {
+      # Replace marker with the appropriate whitespace indentation
+      $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
+      $item = $this->runBlockGamut($this->outdent($item)."\n");
+    }
+    else {
+      # Recursion for sub-lists:
+      $item = $this->doLists($this->outdent($item));
+      $item = preg_replace('/\n+$/', '', $item);
+      $item = $this->runSpanGamut($item);
+    }
+
+    return "<li>" . $item . "</li>\n";
+  }
+
+
+  function doCodeBlocks($text) {
+  #
+  # Process Markdown `<pre><code>` blocks.
+  #
+    $text = preg_replace_callback('{
+        (?:\n\n|\A\n?)
+        (             # $1 = the code block -- one or more lines, starting with a space/tab
+          (?>
+          [ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
+          .*\n+
+          )+
+        )
+        ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+      }xm',
+      array(&$this, '_doCodeBlocks_callback'), $text);
+
+    return $text;
+  }
+  function _doCodeBlocks_callback($matches) {
+    $codeblock = $matches[1];
+
+    $codeblock = $this->outdent($codeblock);
+    $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+    # trim leading newlines and trailing newlines
+    $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+    $codeblock = "<pre><code>$codeblock\n</code></pre>";
+    return "\n\n".$this->hashBlock($codeblock)."\n\n";
+  }
+
+
+  function makeCodeSpan($code) {
+  #
+  # Create a code span markup for $code. Called from handleSpanToken.
+  #
+    $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+    return $this->hashPart("<code>$code</code>");
+  }
+
+
+  var $em_relist = array(
+    ''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S)(?![.,:;]\s)',
+    '*' => '(?<=\S)(?<!\*)\*(?!\*)',
+    '_' => '(?<=\S)(?<!_)_(?!_)',
+    );
+  var $strong_relist = array(
+    ''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S)(?![.,:;]\s)',
+    '**' => '(?<=\S)(?<!\*)\*\*(?!\*)',
+    '__' => '(?<=\S)(?<!_)__(?!_)',
+    );
+  var $em_strong_relist = array(
+    ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S)(?![.,:;]\s)',
+    '***' => '(?<=\S)(?<!\*)\*\*\*(?!\*)',
+    '___' => '(?<=\S)(?<!_)___(?!_)',
+    );
+  var $em_strong_prepared_relist;
+  
+  function prepareItalicsAndBold() {
+  #
+  # Prepare regular expressions for seraching emphasis tokens in any
+  # context.
+  #
+    foreach ($this->em_relist as $em => $em_re) {
+      foreach ($this->strong_relist as $strong => $strong_re) {
+        # Construct list of allowed token expressions.
+        $token_relist = array();
+        if (isset($this->em_strong_relist["$em$strong"])) {
+          $token_relist[] = $this->em_strong_relist["$em$strong"];
+        }
+        $token_relist[] = $em_re;
+        $token_relist[] = $strong_re;
+        
+        # Construct master expression from list.
+        $token_re = '{('. implode('|', $token_relist) .')}';
+        $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+      }
+    }
+  }
+  
+  function doItalicsAndBold($text) {
+    $token_stack = array('');
+    $text_stack = array('');
+    $em = '';
+    $strong = '';
+    $tree_char_em = false;
+    
+    while (1) {
+      #
+      # Get prepared regular expression for seraching emphasis tokens
+      # in current context.
+      #
+      $token_re = $this->em_strong_prepared_relist["$em$strong"];
+      
+      #
+      # Each loop iteration seach for the next emphasis token. 
+      # Each token is then passed to handleSpanToken.
+      #
+      $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+      $text_stack[0] .= $parts[0];
+      $token =& $parts[1];
+      $text =& $parts[2];
+      
+      if (empty($token)) {
+        # Reached end of text span: empty stack without emitting.
+        # any more emphasis.
+        while ($token_stack[0]) {
+          $text_stack[1] .= array_shift($token_stack);
+          $text_stack[0] .= array_shift($text_stack);
+        }
+        break;
+      }
+      
+      $token_len = strlen($token);
+      if ($tree_char_em) {
+        # Reached closing marker while inside a three-char emphasis.
+        if ($token_len == 3) {
+          # Three-char closing marker, close em and strong.
+          array_shift($token_stack);
+          $span = array_shift($text_stack);
+          $span = $this->runSpanGamut($span);
+          $span = "<strong><em>$span</em></strong>";
+          $text_stack[0] .= $this->hashPart($span);
+          $em = '';
+          $strong = '';
+        } else {
+          # Other closing marker: close one em or strong and
+          # change current token state to match the other
+          $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+          $tag = $token_len == 2 ? "strong" : "em";
+          $span = $text_stack[0];
+          $span = $this->runSpanGamut($span);
+          $span = "<$tag>$span</$tag>";
+          $text_stack[0] = $this->hashPart($span);
+          $$tag = ''; # $$tag stands for $em or $strong
+        }
+        $tree_char_em = false;
+      } else if ($token_len == 3) {
+        if ($em) {
+          # Reached closing marker for both em and strong.
+          # Closing strong marker:
+          for ($i = 0; $i < 2; ++$i) {
+            $shifted_token = array_shift($token_stack);
+            $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+            $span = array_shift($text_stack);
+            $span = $this->runSpanGamut($span);
+            $span = "<$tag>$span</$tag>";
+            $text_stack[0] .= $this->hashPart($span);
+            $$tag = ''; # $$tag stands for $em or $strong
+          }
+        } else {
+          # Reached opening three-char emphasis marker. Push on token 
+          # stack; will be handled by the special condition above.
+          $em = $token{0};
+          $strong = "$em$em";
+          array_unshift($token_stack, $token);
+          array_unshift($text_stack, '');
+          $tree_char_em = true;
+        }
+      } else if ($token_len == 2) {
+        if ($strong) {
+          # Unwind any dangling emphasis marker:
+          if (strlen($token_stack[0]) == 1) {
+            $text_stack[1] .= array_shift($token_stack);
+            $text_stack[0] .= array_shift($text_stack);
+          }
+          # Closing strong marker:
+          array_shift($token_stack);
+          $span = array_shift($text_stack);
+          $span = $this->runSpanGamut($span);
+          $span = "<strong>$span</strong>";
+          $text_stack[0] .= $this->hashPart($span);
+          $strong = '';
+        } else {
+          array_unshift($token_stack, $token);
+          array_unshift($text_stack, '');
+          $strong = $token;
+        }
+      } else {
+        # Here $token_len == 1
+        if ($em) {
+          if (strlen($token_stack[0]) == 1) {
+            # Closing emphasis marker:
+            array_shift($token_stack);
+            $span = array_shift($text_stack);
+            $span = $this->runSpanGamut($span);
+            $span = "<em>$span</em>";
+            $text_stack[0] .= $this->hashPart($span);
+            $em = '';
+          } else {
+            $text_stack[0] .= $token;
+          }
+        } else {
+          array_unshift($token_stack, $token);
+          array_unshift($text_stack, '');
+          $em = $token;
+        }
+      }
+    }
+    return $text_stack[0];
+  }
+
+
+  function doBlockQuotes($text) {
+    $text = preg_replace_callback('/
+        (               # Wrap whole match in $1
+        (?>
+          ^[ ]*>[ ]?      # ">" at the start of a line
+          .+\n          # rest of the first line
+          (.+\n)*         # subsequent consecutive lines
+          \n*           # blanks
+        )+
+        )
+      /xm',
+      array(&$this, '_doBlockQuotes_callback'), $text);
+
+    return $text;
+  }
+  function _doBlockQuotes_callback($matches) {
+    $bq = $matches[1];
+    # trim one level of quoting - trim whitespace-only lines
+    $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+    $bq = $this->runBlockGamut($bq);    # recurse
+
+    $bq = preg_replace('/^/m', "  ", $bq);
+    # These leading spaces cause problem with <pre> content, 
+    # so we need to fix that:
+    $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx', 
+      array(&$this, '_DoBlockQuotes_callback2'), $bq);
+
+    return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
+  }
+  function _doBlockQuotes_callback2($matches) {
+    $pre = $matches[1];
+    $pre = preg_replace('/^  /m', '', $pre);
+    return $pre;
+  }
+
+
+  function formParagraphs($text) {
+  #
+  # Params:
+  #   $text - string to process with html <p> tags
+  #
+    # Strip leading and trailing lines:
+    $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+    $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+    #
+    # Wrap <p> tags and unhashify HTML blocks
+    #
+    foreach ($grafs as $key => $value) {
+      if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
+        # Is a paragraph.
+        $value = $this->runSpanGamut($value);
+        $value = preg_replace('/^([ ]*)/', "<p>", $value);
+        $value .= "</p>";
+        $grafs[$key] = $this->unhash($value);
+      }
+      else {
+        # Is a block.
+        # Modify elements of @grafs in-place...
+        $graf = $value;
+        $block = $this->html_hashes[$graf];
+        $graf = $block;
+//        if (preg_match('{
+//          \A
+//          (             # $1 = <div> tag
+//            <div  \s+
+//            [^>]*
+//            \b
+//            markdown\s*=\s*  ([\'"])  # $2 = attr quote char
+//            1
+//            \2
+//            [^>]*
+//            >
+//          )
+//          (             # $3 = contents
+//          .*
+//          )
+//          (</div>)          # $4 = closing tag
+//          \z
+//          }xs', $block, $matches))
+//        {
+//          list(, $div_open, , $div_content, $div_close) = $matches;
+//
+//          # We can't call Markdown(), because that resets the hash;
+//          # that initialization code should be pulled into its own sub, though.
+//          $div_content = $this->hashHTMLBlocks($div_content);
+//          
+//          # Run document gamut methods on the content.
+//          foreach ($this->document_gamut as $method => $priority) {
+//            $div_content = $this->$method($div_content);
+//          }
+//
+//          $div_open = preg_replace(
+//            '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
+//
+//          $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
+//        }
+        $grafs[$key] = $graf;
+      }
+    }
+
+    return implode("\n\n", $grafs);
+  }
+
+
+  function encodeAttribute($text) {
+  #
+  # Encode text for a double-quoted HTML attribute. This function
+  # is *not* suitable for attributes enclosed in single quotes.
+  #
+    $text = $this->encodeAmpsAndAngles($text);
+    $text = str_replace('"', '&quot;', $text);
+    return $text;
+  }
+  
+  
+  function encodeAmpsAndAngles($text) {
+  #
+  # Smart processing for ampersands and angle brackets that need to 
+  # be encoded. Valid character entities are left alone unless the
+  # no-entities mode is set.
+  #
+    if ($this->no_entities) {
+      $text = str_replace('&', '&amp;', $text);
+    } else {
+      # Ampersand-encoding based entirely on Nat Irons's Amputator
+      # MT plugin: <http://bumppo.net/projects/amputator/>
+      $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', 
+                '&amp;', $text);;
+    }
+    # Encode remaining <'s
+    $text = str_replace('<', '&lt;', $text);
+
+    return $text;
+  }
+
+
+  function doAutoLinks($text) {
+    $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', 
+      array(&$this, '_doAutoLinks_url_callback'), $text);
+
+    # Email addresses: <address@domain.foo>
+    $text = preg_replace_callback('{
+      <
+      (?:mailto:)?
+      (
+        [-.\w\x80-\xFF]+
+        \@
+        [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
+      )
+      >
+      }xi',
+      array(&$this, '_doAutoLinks_email_callback'), $text);
+
+    return $text;
+  }
+  function _doAutoLinks_url_callback($matches) {
+    $url = $this->encodeAttribute($matches[1]);
+    $link = "<a href=\"$url\">$url</a>";
+    return $this->hashPart($link);
+  }
+  function _doAutoLinks_email_callback($matches) {
+    $address = $matches[1];
+    $link = $this->encodeEmailAddress($address);
+    return $this->hashPart($link);
+  }
+
+
+  function encodeEmailAddress($addr) {
+  #
+  # Input: an email address, e.g. "foo@example.com"
+  #
+  # Output: the email address as a mailto link, with each character
+  #   of the address encoded as either a decimal or hex entity, in
+  #   the hopes of foiling most address harvesting spam bots. E.g.:
+  #
+  #   <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
+  #        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
+  #        &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
+  #        &#101;&#46;&#x63;&#111;&#x6d;</a></p>
+  #
+  # Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+  #   With some optimizations by Milian Wolff.
+  #
+    $addr = "mailto:" . $addr;
+    $chars = preg_split('/(?<!^)(?!$)/', $addr);
+    $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
+    
+    foreach ($chars as $key => $char) {
+      $ord = ord($char);
+      # Ignore non-ascii chars.
+      if ($ord < 128) {
+        $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+        # roughly 10% raw, 45% hex, 45% dec
+        # '@' *must* be encoded. I insist.
+        if ($r > 90 && $char != '@') /* do nothing */;
+        else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
+        else              $chars[$key] = '&#'.$ord.';';
+      }
+    }
+    
+    $addr = implode('', $chars);
+    $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+    $addr = "<a href=\"$addr\">$text</a>";
+
+    return $addr;
+  }
+
+
+  function parseSpan($str) {
+  #
+  # Take the string $str and parse it into tokens, hashing embeded HTML,
+  # escaped characters and handling code spans.
+  #
+    $output = '';
+    
+    $span_re = '{
+        (
+          \\\\'.$this->escape_chars_re.'
+        |
+          (?<![`\\\\])
+          `+            # code span marker
+      '.( $this->no_markup ? '' : '
+        |
+          <!--    .*?     -->   # comment
+        |
+          <\?.*?\?> | <%.*?%>   # processing instruction
+        |
+          <[/!$]?[-a-zA-Z0-9:]+ # regular tags
+          (?>
+            \s
+            (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+          )?
+          >
+      ').'
+        )
+        }xs';
+
+    while (1) {
+      #
+      # Each loop iteration seach for either the next tag, the next 
+      # openning code span marker, or the next escaped character. 
+      # Each token is then passed to handleSpanToken.
+      #
+      $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+      
+      # Create token from text preceding tag.
+      if ($parts[0] != "") {
+        $output .= $parts[0];
+      }
+      
+      # Check if we reach the end.
+      if (isset($parts[1])) {
+        $output .= $this->handleSpanToken($parts[1], $parts[2]);
+        $str = $parts[2];
+      }
+      else {
+        break;
+      }
+    }
+    
+    return $output;
+  }
+  
+  
+  function handleSpanToken($token, &$str) {
+  #
+  # Handle $token provided by parseSpan by determining its nature and 
+  # returning the corresponding value that should replace it.
+  #
+    switch ($token{0}) {
+      case "\\":
+        return $this->hashPart("&#". ord($token{1}). ";");
+      case "`":
+        # Search for end marker in remaining text.
+        if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', 
+          $str, $matches))
+        {
+          $str = $matches[2];
+          $codespan = $this->makeCodeSpan($matches[1]);
+          return $this->hashPart($codespan);
+        }
+        return $token; // return as text since no ending marker found.
+      default:
+        return $this->hashPart($token);
+    }
+  }
+
+
+  function outdent($text) {
+  #
+  # Remove one level of line-leading tabs or spaces
+  #
+    return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+  }
+
+
+  # String length function for detab. `_initDetab` will create a function to 
+  # hanlde UTF-8 if the default function does not exist.
+  var $utf8_strlen = 'mb_strlen';
+  
+  function detab($text) {
+  #
+  # Replace tabs with the appropriate amount of space.
+  #
+    # For each line we separate the line in blocks delemited by
+    # tab characters. Then we reconstruct every line by adding the 
+    # appropriate number of space between each blocks.
+    
+    $text = preg_replace_callback('/^.*\t.*$/m',
+      array(&$this, '_detab_callback'), $text);
+
+    return $text;
+  }
+  function _detab_callback($matches) {
+    $line = $matches[0];
+    $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+    
+    # Split in blocks.
+    $blocks = explode("\t", $line);
+    # Add each blocks to the line.
+    $line = $blocks[0];
+    unset($blocks[0]); # Do not add first block twice.
+    foreach ($blocks as $block) {
+      # Calculate amount of space, insert spaces, insert block.
+      $amount = $this->tab_width - 
+        $strlen($line, 'UTF-8') % $this->tab_width;
+      $line .= str_repeat(" ", $amount) . $block;
+    }
+    return $line;
+  }
+  function _initDetab() {
+  #
+  # Check for the availability of the function in the `utf8_strlen` property
+  # (initially `mb_strlen`). If the function is not available, create a 
+  # function that will loosely count the number of UTF-8 characters with a
+  # regular expression.
+  #
+    if (function_exists($this->utf8_strlen)) return;
+    $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+      "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", 
+      $text, $m);');
+  }
+
+
+  function unhash($text) {
+  #
+  # Swap back in all the tags hashed by _HashHTMLBlocks.
+  #
+    return preg_replace_callback('/(.)\x1A[0-9]+\1/', 
+      array(&$this, '_unhash_callback'), $text);
+  }
+  function _unhash_callback($matches) {
+    return $this->html_hashes[$matches[0]];
+  }
+
+}
+
+
+#
+# Markdown Extra Parser Class
+#
+
+class MarkdownExtra_Parser extends Markdown_Parser {
+
+  # Prefix for footnote ids.
+  var $fn_id_prefix = "";
+  
+  # Optional title attribute for footnote links and backlinks.
+  var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
+  var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
+  
+  # Optional class attribute for footnote links and backlinks.
+  var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
+  var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
+  
+  # Predefined abbreviations.
+  var $predef_abbr = array();
+
+
+  function MarkdownExtra_Parser() {
+  #
+  # Constructor function. Initialize the parser object.
+  #
+    # Add extra escapable characters before parent constructor 
+    # initialize the table.
+    $this->escape_chars .= ':|';
+    
+    # Insert extra document, block, and span transformations. 
+    # Parent constructor will do the sorting.
+    $this->document_gamut += array(
+      "doFencedCodeBlocks" => 5,
+      "stripFootnotes"     => 15,
+      "stripAbbreviations" => 25,
+      "appendFootnotes"    => 50,
+      );
+    $this->block_gamut += array(
+      "doFencedCodeBlocks" => 5,
+      "doTables"           => 15,
+      "doDefLists"         => 45,
+      );
+    $this->span_gamut += array(
+      "doFootnotes"        => 5,
+      "doAbbreviations"    => 70,
+      );
+    
+    parent::Markdown_Parser();
+  }
+  
+  
+  # Extra variables used during extra transformations.
+  var $footnotes = array();
+  var $footnotes_ordered = array();
+  var $abbr_desciptions = array();
+  var $abbr_word_re = '';
+  
+  # Give the current footnote number.
+  var $footnote_counter = 1;
+  
+  
+  function setup() {
+  #
+  # Setting up Extra-specific variables.
+  #
+    parent::setup();
+    
+    $this->footnotes = array();
+    $this->footnotes_ordered = array();
+    $this->abbr_desciptions = array();
+    $this->abbr_word_re = '';
+    $this->footnote_counter = 1;
+    
+    foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+      if ($this->abbr_word_re)
+        $this->abbr_word_re .= '|';
+      $this->abbr_word_re .= preg_quote($abbr_word);
+      $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+    }
+  }
+  
+  function teardown() {
+  #
+  # Clearing Extra-specific variables.
+  #
+    $this->footnotes = array();
+    $this->footnotes_ordered = array();
+    $this->abbr_desciptions = array();
+    $this->abbr_word_re = '';
+    
+    parent::teardown();
+  }
+  
+  
+  ### HTML Block Parser ###
+  
+  # Tags that are always treated as block tags:
+  var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+  
+  # Tags treated as block tags only if the opening tag is alone on it's line:
+  var $context_block_tags_re = 'script|noscript|math|ins|del';
+  
+  # Tags where markdown="1" default to span mode:
+  var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+  
+  # Tags which must not have their contents modified, no matter where 
+  # they appear:
+  var $clean_tags_re = 'script|math';
+  
+  # Tags that do not need to be closed.
+  var $auto_close_tags_re = 'hr|img';
+  
+
+  function hashHTMLBlocks($text) {
+  #
+  # Hashify HTML Blocks and "clean tags".
+  #
+  # We only want to do this for block-level HTML tags, such as headers,
+  # lists, and tables. That's because we still want to wrap <p>s around
+  # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+  # phrase emphasis, and spans. The list of tags we're looking for is
+  # hard-coded.
+  #
+  # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+  # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" 
+  # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
+  #  _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+  # These two functions are calling each other. It's recursive!
+  #
+    #
+    # Call the HTML-in-Markdown hasher.
+    #
+    list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+    
+    return $text;
+  }
+  function _hashHTMLBlocks_inMarkdown($text, $indent = 0, 
+                    $enclosing_tag_re = '', $span = false)
+  {
+  #
+  # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+  #
+  # *   $indent is the number of space to be ignored when checking for code 
+  #     blocks. This is important because if we don't take the indent into 
+  #     account, something like this (which looks right) won't work as expected:
+  #
+  #     <div>
+  #         <div markdown="1">
+  #         Hello World.  <-- Is this a Markdown code block or text?
+  #         </div>  <-- Is this a Markdown code block or a real tag?
+  #     <div>
+  #
+  #     If you don't like this, just don't indent the tag on which
+  #     you apply the markdown="1" attribute.
+  #
+  # *   If $enclosing_tag_re is not empty, stops at the first unmatched closing 
+  #     tag with that name. Nested tags supported.
+  #
+  # *   If $span is true, text inside must treated as span. So any double 
+  #     newline will be replaced by a single newline so that it does not create 
+  #     paragraphs.
+  #
+  # Returns an array of that form: ( processed text , remaining text )
+  #
+    if ($text === '') return array('', '');
+
+    # Regex to check for the presense of newlines around a block tag.
+    $newline_before_re = '/(?:^\n?|\n\n)*$/';
+    $newline_after_re = 
+      '{
+        ^           # Start of text following the tag.
+        (?>[ ]*<!--.*?-->)?   # Optional comment.
+        [ ]*\n          # Must be followed by newline.
+      }xs';
+    
+    # Regex to match any tag.
+    $block_tag_re =
+      '{
+        (         # $2: Capture hole tag.
+          </?         # Any opening or closing tag.
+            (?>       # Tag name.
+              '.$this->block_tags_re.'      |
+              '.$this->context_block_tags_re.'  |
+              '.$this->clean_tags_re.'          |
+              (?!\s)'.$enclosing_tag_re.'
+            )
+            (?:
+              (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
+              (?>
+                ".*?"   | # Double quotes (can contain `>`)
+                \'.*?\'     | # Single quotes (can contain `>`)
+                .+?       # Anything but quotes and `>`.
+              )*?
+            )?
+          >         # End of tag.
+        |
+          <!--    .*?     --> # HTML Comment
+        |
+          <\?.*?\?> | <%.*?%> # Processing instruction
+        |
+          <!\[CDATA\[.*?\]\]> # CData Block
+        |
+          # Code span marker
+          `+
+        '. ( !$span ? ' # If not in span.
+        |
+          # Indented code block
+          (?> ^[ ]*\n? | \n[ ]*\n )
+          [ ]{'.($indent+4).'}[^\n]* \n
+          (?>
+            (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
+          )*
+        |
+          # Fenced code block marker
+          (?> ^ | \n )
+          [ ]{'.($indent).'}~~~+[ ]*\n
+        ' : '' ). ' # End (if not is span).
+        )
+      }xs';
+
+    
+    $depth = 0;   # Current depth inside the tag tree.
+    $parsed = ""; # Parsed text that will be returned.
+
+    #
+    # Loop through every tag until we find the closing tag of the parent
+    # or loop until reaching the end of text if no parent tag specified.
+    #
+    do {
+      #
+      # Split the text using the first $tag_match pattern found.
+      # Text before  pattern will be first in the array, text after
+      # pattern will be at the end, and between will be any catches made 
+      # by the pattern.
+      #
+      $parts = preg_split($block_tag_re, $text, 2, 
+                PREG_SPLIT_DELIM_CAPTURE);
+      
+      # If in Markdown span mode, add a empty-string span-level hash 
+      # after each newline to prevent triggering any block element.
+      if ($span) {
+        $void = $this->hashPart("", ':');
+        $newline = "$void\n";
+        $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+      }
+      
+      $parsed .= $parts[0]; # Text before current tag.
+      
+      # If end of $text has been reached. Stop loop.
+      if (count($parts) < 3) {
+        $text = "";
+        break;
+      }
+      
+      $tag  = $parts[1]; # Tag to handle.
+      $text = $parts[2]; # Remaining text after current tag.
+      $tag_re = preg_quote($tag); # For use in a regular expression.
+      
+      #
+      # Check for: Code span marker
+      #
+      if ($tag{0} == "`") {
+        # Find corresponding end marker.
+        $tag_re = preg_quote($tag);
+        if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)'.$tag_re.'(?!`)}',
+          $text, $matches))
+        {
+          # End marker found: pass text unchanged until marker.
+          $parsed .= $tag . $matches[0];
+          $text = substr($text, strlen($matches[0]));
+        }
+        else {
+          # Unmatched marker: just skip it.
+          $parsed .= $tag;
+        }
+      }
+      #
+      # Check for: Indented code block or fenced code block marker.
+      #
+      else if ($tag{0} == "\n" || $tag{0} == "~") {
+        if ($tag{1} == "\n" || $tag{1} == " ") {
+          # Indented code block: pass it unchanged, will be handled 
+          # later.
+          $parsed .= $tag;
+        }
+        else {
+          # Fenced code block marker: find matching end marker.
+          $tag_re = preg_quote(trim($tag));
+          if (preg_match('{^(?>.*\n)+?'.$tag_re.' *\n}', $text, 
+            $matches)) 
+          {
+            # End marker found: pass text unchanged until marker.
+            $parsed .= $tag . $matches[0];
+            $text = substr($text, strlen($matches[0]));
+          }
+          else {
+            # No end marker: just skip it.
+            $parsed .= $tag;
+          }
+        }
+      }
+      #
+      # Check for: Opening Block level tag or
+      #            Opening Context Block tag (like ins and del) 
+      #               used as a block tag (tag is alone on it's line).
+      #
+      else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
+        ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
+          preg_match($newline_before_re, $parsed) &&
+          preg_match($newline_after_re, $text)  )
+        )
+      {
+        # Need to parse tag and following text using the HTML parser.
+        list($block_text, $text) = 
+          $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+        
+        # Make sure it stays outside of any paragraph by adding newlines.
+        $parsed .= "\n\n$block_text\n\n";
+      }
+      #
+      # Check for: Clean tag (like script, math)
+      #            HTML Comments, processing instructions.
+      #
+      else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
+        $tag{1} == '!' || $tag{1} == '?')
+      {
+        # Need to parse tag and following text using the HTML parser.
+        # (don't check for markdown attribute)
+        list($block_text, $text) = 
+          $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+        
+        $parsed .= $block_text;
+      }
+      #
+      # Check for: Tag with same name as enclosing tag.
+      #
+      else if ($enclosing_tag_re !== '' &&
+        # Same name as enclosing tag.
+        preg_match('{^</?(?:'.$enclosing_tag_re.')\b}', $tag))
+      {
+        #
+        # Increase/decrease nested tag count.
+        #
+        if ($tag{1} == '/')           $depth--;
+        else if ($tag{strlen($tag)-2} != '/') $depth++;
+
+        if ($depth < 0) {
+          #
+          # Going out of parent element. Clean up and break so we
+          # return to the calling function.
+          #
+          $text = $tag . $text;
+          break;
+        }
+        
+        $parsed .= $tag;
+      }
+      else {
+        $parsed .= $tag;
+      }
+    } while ($depth >= 0);
+    
+    return array($parsed, $text);
+  }
+  function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+  #
+  # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+  #
+  # *   Calls $hash_method to convert any blocks.
+  # *   Stops when the first opening tag closes.
+  # *   $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+  #     (it is not inside clean tags)
+  #
+  # Returns an array of that form: ( processed text , remaining text )
+  #
+    if ($text === '') return array('', '');
+    
+    # Regex to match `markdown` attribute inside of a tag.
+    $markdown_attr_re = '
+      {
+        \s*     # Eat whitespace before the `markdown` attribute
+        markdown
+        \s*=\s*
+        (?>
+          (["\'])   # $1: quote delimiter   
+          (.*?)   # $2: attribute value
+          \1      # matching delimiter  
+        |
+          ([^\s>]*) # $3: unquoted attribute value
+        )
+        ()        # $4: make $3 always defined (avoid warnings)
+      }xs';
+    
+    # Regex to match any tag.
+    $tag_re = '{
+        (         # $2: Capture hole tag.
+          </?         # Any opening or closing tag.
+            [\w:$]+     # Tag name.
+            (?:
+              (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
+              (?>
+                ".*?"   | # Double quotes (can contain `>`)
+                \'.*?\'     | # Single quotes (can contain `>`)
+                .+?       # Anything but quotes and `>`.
+              )*?
+            )?
+          >         # End of tag.
+        |
+          <!--    .*?     --> # HTML Comment
+        |
+          <\?.*?\?> | <%.*?%> # Processing instruction
+        |
+          <!\[CDATA\[.*?\]\]> # CData Block
+        )
+      }xs';
+    
+    $original_text = $text;   # Save original text in case of faliure.
+    
+    $depth    = 0;  # Current depth inside the tag tree.
+    $block_text = ""; # Temporary text holder for current text.
+    $parsed   = ""; # Parsed text that will be returned.
+
+    #
+    # Get the name of the starting tag.
+    # (This pattern makes $base_tag_name_re safe without quoting.)
+    #
+    if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+      $base_tag_name_re = $matches[1];
+
+    #
+    # Loop through every tag until we find the corresponding closing tag.
+    #
+    do {
+      #
+      # Split the text using the first $tag_match pattern found.
+      # Text before  pattern will be first in the array, text after
+      # pattern will be at the end, and between will be any catches made 
+      # by the pattern.
+      #
+      $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+      
+      if (count($parts) < 3) {
+        #
+        # End of $text reached with unbalenced tag(s).
+        # In that case, we return original text unchanged and pass the
+        # first character as filtered to prevent an infinite loop in the 
+        # parent function.
+        #
+        return array($original_text{0}, substr($original_text, 1));
+      }
+      
+      $block_text .= $parts[0]; # Text before current tag.
+      $tag         = $parts[1]; # Tag to handle.
+      $text        = $parts[2]; # Remaining text after current tag.
+      
+      #
+      # Check for: Auto-close tag (like <hr/>)
+      #      Comments and Processing Instructions.
+      #
+      if (preg_match('{^</?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
+        $tag{1} == '!' || $tag{1} == '?')
+      {
+        # Just add the tag to the block as if it was text.
+        $block_text .= $tag;
+      }
+      else {
+        #
+        # Increase/decrease nested tag count. Only do so if
+        # the tag's name match base tag's.
+        #
+        if (preg_match('{^</?'.$base_tag_name_re.'\b}', $tag)) {
+          if ($tag{1} == '/')           $depth--;
+          else if ($tag{strlen($tag)-2} != '/') $depth++;
+        }
+        
+        #
+        # Check for `markdown="1"` attribute and handle it.
+        #
+        if ($md_attr && 
+          preg_match($markdown_attr_re, $tag, $attr_m) &&
+          preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+        {
+          # Remove `markdown` attribute from opening tag.
+          $tag = preg_replace($markdown_attr_re, '', $tag);
+          
+          # Check if text inside this tag must be parsed in span mode.
+          $this->mode = $attr_m[2] . $attr_m[3];
+          $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+            preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
+          
+          # Calculate indent before tag.
+          if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+            $strlen = $this->utf8_strlen;
+            $indent = $strlen($matches[1], 'UTF-8');
+          } else {
+            $indent = 0;
+          }
+          
+          # End preceding block with this tag.
+          $block_text .= $tag;
+          $parsed .= $this->$hash_method($block_text);
+          
+          # Get enclosing tag name for the ParseMarkdown function.
+          # (This pattern makes $tag_name_re safe without quoting.)
+          preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+          $tag_name_re = $matches[1];
+          
+          # Parse the content using the HTML-in-Markdown parser.
+          list ($block_text, $text)
+            = $this->_hashHTMLBlocks_inMarkdown($text, $indent, 
+              $tag_name_re, $span_mode);
+          
+          # Outdent markdown text.
+          if ($indent > 0) {
+            $block_text = preg_replace("/^[ ]{1,$indent}/m", "", 
+                          $block_text);
+          }
+          
+          # Append tag content to parsed text.
+          if (!$span_mode)  $parsed .= "\n\n$block_text\n\n";
+          else        $parsed .= "$block_text";
+          
+          # Start over a new block.
+          $block_text = "";
+        }
+        else $block_text .= $tag;
+      }
+      
+    } while ($depth > 0);
+    
+    #
+    # Hash last block text that wasn't processed inside the loop.
+    #
+    $parsed .= $this->$hash_method($block_text);
+    
+    return array($parsed, $text);
+  }
+
+
+  function hashClean($text) {
+  #
+  # Called whenever a tag must be hashed when a function insert a "clean" tag
+  # in $text, it pass through this function and is automaticaly escaped, 
+  # blocking invalid nested overlap.
+  #
+    return $this->hashPart($text, 'C');
+  }
+
+
+  function doHeaders($text) {
+  #
+  # Redefined to add id attribute support.
+  #
+    # Setext-style headers:
+    #   Header 1  {#header1}
+    #   ========
+    #  
+    #   Header 2  {#header2}
+    #   --------
+    #
+    $text = preg_replace_callback(
+      '{
+        (^.+?)                # $1: Header text
+        (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})?  # $2: Id attribute
+        [ ]*\n(=+|-+)[ ]*\n+        # $3: Header footer
+      }mx',
+      array(&$this, '_doHeaders_callback_setext'), $text);
+
+    # atx-style headers:
+    # # Header 1        {#header1}
+    # ## Header 2       {#header2}
+    # ## Header 2 with closing hashes ##  {#header3}
+    # ...
+    # ###### Header 6   {#header2}
+    #
+    $text = preg_replace_callback('{
+        ^(\#{1,6})  # $1 = string of #\'s
+        [ ]*
+        (.+?)   # $2 = Header text
+        [ ]*
+        \#*     # optional closing #\'s (not counted)
+        (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
+        [ ]*
+        \n+
+      }xm',
+      array(&$this, '_doHeaders_callback_atx'), $text);
+
+    return $text;
+  }
+  function _doHeaders_attr($attr) {
+    if (empty($attr))  return "";
+    return " id=\"$attr\"";
+  }
+  function _doHeaders_callback_setext($matches) {
+    if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
+      return $matches[0];
+    $level = $matches[3]{0} == '=' ? 1 : 2;
+    $attr  = $this->_doHeaders_attr($id =& $matches[2]);
+    $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
+    return "\n" . $this->hashBlock($block) . "\n\n";
+  }
+  function _doHeaders_callback_atx($matches) {
+    $level = strlen($matches[1]);
+    $attr  = $this->_doHeaders_attr($id =& $matches[3]);
+    $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
+    return "\n" . $this->hashBlock($block) . "\n\n";
+  }
+
+
+  function doTables($text) {
+  #
+  # Form HTML tables.
+  #
+    $less_than_tab = $this->tab_width - 1;
+    #
+    # Find tables with leading pipe.
+    #
+    # | Header 1 | Header 2
+    # | -------- | --------
+    # | Cell 1   | Cell 2
+    # | Cell 3   | Cell 4
+    #
+    $text = preg_replace_callback('
+      {
+        ^             # Start of a line
+        [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+        [|]             # Optional leading pipe (present)
+        (.+) \n           # $1: Header row (at least one pipe)
+        
+        [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+        [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline
+        
+        (             # $3: Cells
+          (?>
+            [ ]*        # Allowed whitespace.
+            [|] .* \n     # Row content.
+          )*
+        )
+        (?=\n|\Z)         # Stop at final double newline.
+      }xm',
+      array(&$this, '_doTable_leadingPipe_callback'), $text);
+    
+    #
+    # Find tables without leading pipe.
+    #
+    # Header 1 | Header 2
+    # -------- | --------
+    # Cell 1   | Cell 2
+    # Cell 3   | Cell 4
+    #
+    $text = preg_replace_callback('
+      {
+        ^             # Start of a line
+        [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+        (\S.*[|].*) \n        # $1: Header row (at least one pipe)
+        
+        [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+        ([-:]+[ ]*[|][-| :]*) \n  # $2: Header underline
+        
+        (             # $3: Cells
+          (?>
+            .* [|] .* \n    # Row content
+          )*
+        )
+        (?=\n|\Z)         # Stop at final double newline.
+      }xm',
+      array(&$this, '_DoTable_callback'), $text);
+
+    return $text;
+  }
+  function _doTable_leadingPipe_callback($matches) {
+    $head   = $matches[1];
+    $underline  = $matches[2];
+    $content  = $matches[3];
+    
+    # Remove leading pipe for each row.
+    $content  = preg_replace('/^ *[|]/m', '', $content);
+    
+    return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+  }
+  function _doTable_callback($matches) {
+    $head   = $matches[1];
+    $underline  = $matches[2];
+    $content  = $matches[3];
+
+    # Remove any tailing pipes for each line.
+    $head   = preg_replace('/[|] *$/m', '', $head);
+    $underline  = preg_replace('/[|] *$/m', '', $underline);
+    $content  = preg_replace('/[|] *$/m', '', $content);
+    
+    # Reading alignement from header underline.
+    $separators = preg_split('/ *[|] */', $underline);
+    foreach ($separators as $n => $s) {
+      if (preg_match('/^ *-+: *$/', $s))    $attr[$n] = ' align="right"';
+      else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
+      else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
+      else                  $attr[$n] = '';
+    }
+    
+    # Parsing span elements, including code spans, character escapes, 
+    # and inline HTML tags, so that pipes inside those gets ignored.
+    $head   = $this->parseSpan($head);
+    $headers  = preg_split('/ *[|] */', $head);
+    $col_count  = count($headers);
+    
+    # Write column headers.
+    $text = "<table>\n";
+    $text .= "<thead>\n";
+    $text .= "<tr>\n";
+    foreach ($headers as $n => $header)
+      $text .= "  <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
+    $text .= "</tr>\n";
+    $text .= "</thead>\n";
+    
+    # Split content by row.
+    $rows = explode("\n", trim($content, "\n"));
+    
+    $text .= "<tbody>\n";
+    foreach ($rows as $row) {
+      # Parsing span elements, including code spans, character escapes, 
+      # and inline HTML tags, so that pipes inside those gets ignored.
+      $row = $this->parseSpan($row);
+      
+      # Split row by cell.
+      $row_cells = preg_split('/ *[|] */', $row, $col_count);
+      $row_cells = array_pad($row_cells, $col_count, '');
+      
+      $text .= "<tr>\n";
+      foreach ($row_cells as $n => $cell)
+        $text .= "  <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
+      $text .= "</tr>\n";
+    }
+    $text .= "</tbody>\n";
+    $text .= "</table>";
+    
+    return $this->hashBlock($text) . "\n";
+  }
+
+  
+  function doDefLists($text) {
+  #
+  # Form HTML definition lists.
+  #
+    $less_than_tab = $this->tab_width - 1;
+
+    # Re-usable pattern to match any entire dl list:
+    $whole_list_re = '(?>
+      (               # $1 = whole list
+        (               # $2
+        [ ]{0,'.$less_than_tab.'}
+        ((?>.*\S.*\n)+)       # $3 = defined term
+        \n?
+        [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+        )
+        (?s:.+?)
+        (               # $4
+          \z
+        |
+          \n{2,}
+          (?=\S)
+          (?!           # Negative lookahead for another term
+          [ ]{0,'.$less_than_tab.'}
+          (?: \S.*\n )+?      # defined term
+          \n?
+          [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+          )
+          (?!           # Negative lookahead for another definition
+          [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+          )
+        )
+      )
+    )'; // mx
+
+    $text = preg_replace_callback('{
+        (?>\A\n?|(?<=\n\n))
+        '.$whole_list_re.'
+      }mx',
+      array(&$this, '_doDefLists_callback'), $text);
+
+    return $text;
+  }
+  function _doDefLists_callback($matches) {
+    # Re-usable patterns to match list item bullets and number markers:
+    $list = $matches[1];
+    
+    # Turn double returns into triple returns, so that we can make a
+    # paragraph for the last item in a list, if necessary:
+    $result = trim($this->processDefListItems($list));
+    $result = "<dl>\n" . $result . "\n</dl>";
+    return $this->hashBlock($result) . "\n\n";
+  }
+
+
+  function processDefListItems($list_str) {
+  #
+  # Process the contents of a single definition list, splitting it
+  # into individual term and definition list items.
+  #
+    $less_than_tab = $this->tab_width - 1;
+    
+    # trim trailing blank lines:
+    $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+    # Process definition terms.
+    $list_str = preg_replace_callback('{
+      (?>\A\n?|\n\n+)         # leading line
+      (               # definition terms = $1
+        [ ]{0,'.$less_than_tab.'} # leading whitespace
+        (?![:][ ]|[ ])        # negative lookahead for a definition 
+                      #   mark (colon) or more whitespace.
+        (?> \S.* \n)+?        # actual term (not whitespace). 
+      )     
+      (?=\n?[ ]{0,3}:[ ])       # lookahead for following line feed 
+                      #   with a definition mark.
+      }xm',
+      array(&$this, '_processDefListItems_callback_dt'), $list_str);
+
+    # Process actual definitions.
+    $list_str = preg_replace_callback('{
+      \n(\n+)?            # leading line = $1
+      (               # marker space = $2
+        [ ]{0,'.$less_than_tab.'} # whitespace before colon
+        [:][ ]+           # definition mark (colon)
+      )
+      ((?s:.+?))            # definition text = $3
+      (?= \n+             # stop at next definition mark,
+        (?:             # next term or end of text
+          [ ]{0,'.$less_than_tab.'} [:][ ]  |
+          <dt> | \z
+        )           
+      )         
+      }xm',
+      array(&$this, '_processDefListItems_callback_dd'), $list_str);
+
+    return $list_str;
+  }
+  function _processDefListItems_callback_dt($matches) {
+    $terms = explode("\n", trim($matches[1]));
+    $text = '';
+    foreach ($terms as $term) {
+      $term = $this->runSpanGamut(trim($term));
+      $text .= "\n<dt>" . $term . "</dt>";
+    }
+    return $text . "\n";
+  }
+  function _processDefListItems_callback_dd($matches) {
+    $leading_line = $matches[1];
+    $marker_space = $matches[2];
+    $def      = $matches[3];
+
+    if ($leading_line || preg_match('/\n{2,}/', $def)) {
+      # Replace marker with the appropriate whitespace indentation
+      $def = str_repeat(' ', strlen($marker_space)) . $def;
+      $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
+      $def = "\n". $def ."\n";
+    }
+    else {
+      $def = rtrim($def);
+      $def = $this->runSpanGamut($this->outdent($def));
+    }
+
+    return "\n<dd>" . $def . "</dd>\n";
+  }
+
+
+  function doFencedCodeBlocks($text) {
+  #
+  # Adding the fenced code block syntax to regular Markdown:
+  #
+  # ~~~
+  # Code block
+  # ~~~
+  #
+    $less_than_tab = $this->tab_width;
+    
+    $text = preg_replace_callback('{
+        (?:\n|\A)
+        # 1: Opening marker
+        (
+          ~{3,} # Marker: three tilde or more.
+        )
+        [ ]* \n # Whitespace and newline following marker.
+        
+        # 2: Content
+        (
+          (?>
+            (?!\1 [ ]* \n)  # Not a closing marker.
+            .*\n+
+          )+
+        )
+        
+        # Closing marker.
+        \1 [ ]* \n
+      }xm',
+      array(&$this, '_doFencedCodeBlocks_callback'), $text);
+
+    return $text;
+  }
+  function _doFencedCodeBlocks_callback($matches) {
+    $codeblock = $matches[2];
+    $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+    $codeblock = preg_replace_callback('/^\n+/',
+      array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
+    $codeblock = "<pre><code>$codeblock</code></pre>";
+    return "\n\n".$this->hashBlock($codeblock)."\n\n";
+  }
+  function _doFencedCodeBlocks_newlines($matches) {
+    return str_repeat("<br$this->empty_element_suffix", 
+      strlen($matches[0]));
+  }
+
+
+  #
+  # Redefining emphasis markers so that emphasis by underscore does not
+  # work in the middle of a word.
+  #
+  var $em_relist = array(
+    ''  => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?=\S)(?![.,:;]\s)',
+    '*' => '(?<=\S)(?<!\*)\*(?!\*)',
+    '_' => '(?<=\S)(?<!_)_(?![a-zA-Z0-9_])',
+    );
+  var $strong_relist = array(
+    ''   => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?=\S)(?![.,:;]\s)',
+    '**' => '(?<=\S)(?<!\*)\*\*(?!\*)',
+    '__' => '(?<=\S)(?<!_)__(?![a-zA-Z0-9_])',
+    );
+  var $em_strong_relist = array(
+    ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?=\S)(?![.,:;]\s)',
+    '***' => '(?<=\S)(?<!\*)\*\*\*(?!\*)',
+    '___' => '(?<=\S)(?<!_)___(?![a-zA-Z0-9_])',
+    );
+
+
+  function formParagraphs($text) {
+  #
+  # Params:
+  #   $text - string to process with html <p> tags
+  #
+    # Strip leading and trailing lines:
+    $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+    
+    $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+    #
+    # Wrap <p> tags and unhashify HTML blocks
+    #
+    foreach ($grafs as $key => $value) {
+      $value = trim($this->runSpanGamut($value));
+      
+      # Check if this should be enclosed in a paragraph.
+      # Clean tag hashes & block tag hashes are left alone.
+      $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+      
+      if ($is_p) {
+        $value = "<p>$value</p>";
+      }
+      $grafs[$key] = $value;
+    }
+    
+    # Join grafs in one text, then unhash HTML tags. 
+    $text = implode("\n\n", $grafs);
+    
+    # Finish by removing any tag hashes still present in $text.
+    $text = $this->unhash($text);
+    
+    return $text;
+  }
+  
+  
+  ### Footnotes
+  
+  function stripFootnotes($text) {
+  #
+  # Strips link definitions from text, stores the URLs and titles in
+  # hash references.
+  #
+    $less_than_tab = $this->tab_width - 1;
+
+    # Link defs are in the form: [^id]: url "optional title"
+    $text = preg_replace_callback('{
+      ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?:  # note_id = $1
+        [ ]*
+        \n?         # maybe *one* newline
+      (           # text = $2 (no blank lines allowed)
+        (?:         
+          .+        # actual text
+        |
+          \n        # newlines but 
+          (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+          (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed 
+                  # by non-indented content
+        )*
+      )   
+      }xm',
+      array(&$this, '_stripFootnotes_callback'),
+      $text);
+    return $text;
+  }
+  function _stripFootnotes_callback($matches) {
+    $note_id = $this->fn_id_prefix . $matches[1];
+    $this->footnotes[$note_id] = $this->outdent($matches[2]);
+    return ''; # String that will replace the block
+  }
+
+
+  function doFootnotes($text) {
+  #
+  # Replace footnote references in $text [^id] with a special text-token 
+  # which will be replaced by the actual footnote marker in appendFootnotes.
+  #
+    if (!$this->in_anchor) {
+      $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+    }
+    return $text;
+  }
+
+  
+  function appendFootnotes($text) {
+  #
+  # Append footnote list to text.
+  #
+    $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
+      array(&$this, '_appendFootnotes_callback'), $text);
+  
+    if (!empty($this->footnotes_ordered)) {
+      $text .= "\n\n";
+      $text .= "<div class=\"footnotes\">\n";
+      $text .= "<hr". MARKDOWN_EMPTY_ELEMENT_SUFFIX ."\n";
+      $text .= "<ol>\n\n";
+      
+      $attr = " rev=\"footnote\"";
+      if ($this->fn_backlink_class != "") {
+        $class = $this->fn_backlink_class;
+        $class = $this->encodeAttribute($class);
+        $attr .= " class=\"$class\"";
+      }
+      if ($this->fn_backlink_title != "") {
+        $title = $this->fn_backlink_title;
+        $title = $this->encodeAttribute($title);
+        $attr .= " title=\"$title\"";
+      }
+      $num = 0;
+      
+      while (!empty($this->footnotes_ordered)) {
+        $footnote = reset($this->footnotes_ordered);
+        $note_id = key($this->footnotes_ordered);
+        unset($this->footnotes_ordered[$note_id]);
+        
+        $footnote .= "\n"; # Need to append newline before parsing.
+        $footnote = $this->runBlockGamut("$footnote\n");        
+        $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
+          array(&$this, '_appendFootnotes_callback'), $footnote);
+        
+        $attr = str_replace("%%", ++$num, $attr);
+        $note_id = $this->encodeAttribute($note_id);
+        
+        # Add backlink to last paragraph; create new paragraph if needed.
+        $backlink = "<a href=\"#fnref:$note_id\"$attr>&#8617;</a>";
+        if (preg_match('{</p>$}', $footnote)) {
+          $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
+        } else {
+          $footnote .= "\n\n<p>$backlink</p>";
+        }
+        
+        $text .= "<li id=\"fn:$note_id\">\n";
+        $text .= $footnote . "\n";
+        $text .= "</li>\n\n";
+      }
+      
+      $text .= "</ol>\n";
+      $text .= "</div>";
+    }
+    return $text;
+  }
+  function _appendFootnotes_callback($matches) {
+    $node_id = $this->fn_id_prefix . $matches[1];
+    
+    # Create footnote marker only if it has a corresponding footnote *and*
+    # the footnote hasn't been used by another marker.
+    if (isset($this->footnotes[$node_id])) {
+      # Transfert footnote content to the ordered list.
+      $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+      unset($this->footnotes[$node_id]);
+      
+      $num = $this->footnote_counter++;
+      $attr = " rel=\"footnote\"";
+      if ($this->fn_link_class != "") {
+        $class = $this->fn_link_class;
+        $class = $this->encodeAttribute($class);
+        $attr .= " class=\"$class\"";
+      }
+      if ($this->fn_link_title != "") {
+        $title = $this->fn_link_title;
+        $title = $this->encodeAttribute($title);
+        $attr .= " title=\"$title\"";
+      }
+      
+      $attr = str_replace("%%", $num, $attr);
+      $node_id = $this->encodeAttribute($node_id);
+      
+      return
+        "<sup id=\"fnref:$node_id\">".
+        "<a href=\"#fn:$node_id\"$attr>$num</a>".
+        "</sup>";
+    }
+    
+    return "[^".$matches[1]."]";
+  }
+    
+  
+  ### Abbreviations ###
+  
+  function stripAbbreviations($text) {
+  #
+  # Strips abbreviations from text, stores titles in hash references.
+  #
+    $less_than_tab = $this->tab_width - 1;
+
+    # Link defs are in the form: [id]*: url "optional title"
+    $text = preg_replace_callback('{
+      ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?:  # abbr_id = $1
+      (.*)          # text = $2 (no blank lines allowed)  
+      }xm',
+      array(&$this, '_stripAbbreviations_callback'),
+      $text);
+    return $text;
+  }
+  function _stripAbbreviations_callback($matches) {
+    $abbr_word = $matches[1];
+    $abbr_desc = $matches[2];
+    if ($this->abbr_word_re)
+      $this->abbr_word_re .= '|';
+    $this->abbr_word_re .= preg_quote($abbr_word);
+    $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+    return ''; # String that will replace the block
+  }
+  
+  
+  function doAbbreviations($text) {
+  #
+  # Find defined abbreviations in text and wrap them in <abbr> elements.
+  #
+    if ($this->abbr_word_re) {
+      // cannot use the /x modifier because abbr_word_re may 
+      // contain significant spaces:
+      $text = preg_replace_callback('{'.
+        '(?<![\w\x1A])'.
+        '(?:'.$this->abbr_word_re.')'.
+        '(?![\w\x1A])'.
+        '}', 
+        array(&$this, '_doAbbreviations_callback'), $text);
+    }
+    return $text;
+  }
+  function _doAbbreviations_callback($matches) {
+    $abbr = $matches[0];
+    if (isset($this->abbr_desciptions[$abbr])) {
+      $desc = $this->abbr_desciptions[$abbr];
+      if (empty($desc)) {
+        return $this->hashPart("<abbr>$abbr</abbr>");
+      } else {
+        $desc = $this->encodeAttribute($desc);
+        return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
+      }
+    } else {
+      return $matches[0];
+    }
+  }
+
+}
+
+
+/*
+
+PHP Markdown Extra
+==================
+
+Description
+-----------
+
+This is a PHP port of the original Markdown formatter written in Perl 
+by John Gruber. This special "Extra" version of PHP Markdown features 
+further enhancements to the syntax for making additional constructs 
+such as tables and definition list.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like <div> and <table> as well).
+
+For more information about Markdown's syntax, see:
+
+<http://daringfireball.net/projects/markdown/>
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+<michel.fortin@michelf.com>
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+--------------- 
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra
+Copyright (c) 2004-2008 Michel Fortin  
+<http://www.michelf.com/>  
+All rights reserved.
+
+Based on Markdown  
+Copyright (c) 2003-2006 John Gruber   
+<http://daringfireball.net/>   
+All rights reserved.
+
+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 "Markdown" 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 copyright owner
+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.
+
+*/
+?>
\ No newline at end of file
diff --git a/examples/includes/PHP-SmartyPants-1.5.1e/PHP SmartyPants Readme.txt b/examples/includes/PHP-SmartyPants-1.5.1e/PHP SmartyPants Readme.txt
new file mode 100644 (file)
index 0000000..39d36dd
--- /dev/null
@@ -0,0 +1,394 @@
+PHP SmartyPants
+===============
+
+Version 1.5.1e - Fri 9 Dec 2005
+
+by Michel Fortin
+<http://www.michelf.com/>
+
+based on work by John Gruber
+<http://daringfireball.net/>
+
+
+Introduction
+------------
+
+PHP SmartyPants is a port to PHP of the original SmartyPants written
+in Perl by John Gruber.
+
+PHP SmartyPants is a free web publishing plug-in for WordPress and
+Smarty template engine that easily translates plain ASCII punctuation
+characters into "smart" typographic punctuation HTML entities.
+SmartyPants can also be invoked as a standalone PHP function.
+
+SmartyPants can perform the following transformations:
+
+*   Straight quotes (`"` and `'`) into "curly" quote HTML entities
+*   Backtick-style quotes (` ``like this'' `) into "curly" quote HTML
+    entities
+*   Dashes (`--` and `---`) into en- and em-dash entities
+*   Three consecutive dots (`...`) into an ellipsis entity
+
+This means you can write, edit, and save using plain old ASCII straight
+quotes, plain dashes, and plain dots, but your published posts (and
+final HTML output) will appear with smart quotes, em-dashes, and proper
+ellipses.
+
+SmartyPants does not modify characters within `<pre>`, `<code>`,
+`<kbd>`, or `<script>` tag blocks. Typically, these tags are used to
+display text where smart quotes and other "smart punctuation" would not
+be appropriate, such as source code or example markup.
+
+
+### Backslash Escapes ###
+
+If you need to use literal straight quotes (or plain hyphens and
+periods), SmartyPants accepts the following backslash escape sequences
+to force non-smart punctuation. It does so by transforming the escape
+sequence into a decimal-encoded HTML entity:
+
+
+    Escape  Value  Character
+    ------  -----  ---------
+      \\    &#92;    \
+      \"    &#34;    "
+      \'    &#39;    '
+      \.    &#46;    .
+      \-    &#45;    -
+      \`    &#96;    `
+
+
+This is useful, for example, when you want to use straight quotes as
+foot and inch marks:
+
+    6\'2\" tall
+
+translates into:
+
+    6&#39;2&#34; tall
+
+in SmartyPants's HTML output. Which, when rendered by a web browser,
+looks like:
+
+    6'2" tall
+
+
+Installation and Requirement
+----------------------------
+
+PHP SmartyPants require PHP version 4.0.5 or later.
+
+
+### WordPress ###
+
+WordPress already include a filter called "Texturize" with the same
+goal as SmartyPants. You could still find some usefulness to
+PHP SmartyPants if you are not happy enough with the standard algorithm.
+
+PHP SmartyPants works with [WordPress][wp], version 1.2 or later.
+
+[wp]: http://wordpress.org/
+
+1.  To use PHP SmartyPants with WordPress, place the "smartypants.php"
+    file in the "plugins" folder. This folder is hidden inside
+    "wp-content" at the root of your site:
+
+        (site home)/wp-content/plugins/smartypants.php
+
+2.  Activate the plugin with the administrative interface of WordPress.
+    In the "Plugins" section you will now find SmartyPants. To activate
+    the plugin, click on the "Activate" button on the same line than
+    SmartyPants. Your entries will now be filtered by PHP SmartyPants.
+
+Note: It is not possible at this time to apply a different set of
+filters to different entries. All your entries will be filtered by
+PHP SmartyPants if the plugin is active. This is currently a limitation
+of WordPress.
+
+
+### Blosxom ###
+
+SmartyPants works with Blosxom version 2.0 or later.
+
+1.  Rename the "SmartyPants.pl" plug-in to "SmartyPants" (case is
+    important). Movable Type requires plug-ins to have a ".pl"
+    extension; Blosxom forbids it (at least as of this writing).
+
+2.  Copy the "SmartyPants" plug-in file to your Blosxom plug-ins folder.
+    If you're not sure where your Blosxom plug-ins folder is, see the
+    Blosxom documentation for information.
+
+3.  That's it. The entries in your weblog should now automatically have
+    SmartyPants's default transformations applied.
+
+4.  If you wish to configure SmartyPants's behavior, open the
+    "SmartyPants" plug-in, and edit the value of the `$smartypants_attr`
+    configuration variable, located near the top of the script. The
+    default value is 1; see "Options", below, for the full list of
+    supported values.
+
+
+### In your programs ###
+
+You can use PHP SmartyPants easily in your current PHP program. Simply
+include the file and then call the `SmartyPants` function on the text
+you want to convert:
+
+       include_once "smartypants.php";
+       $my_text = SmartyPants($my_text);
+
+
+### With Smarty ###
+
+If your program use the [Smarty][sm] template engine, PHP SmartyPants
+can now be used as a modifier for your templates. Rename
+"smartypants.php" to "modifier.smartypants.php" and put it in your
+smarty plugins folder.
+
+[sm]: http://smarty.php.net/
+
+
+Options and Configuration
+-------------------------
+
+Settings are specified by editing the value of the `$smartypants_attr`
+variable in the "smartypants.php" file. For users of the Smarty template
+engine, the "smartypants" modifier also takes an optional attribute where
+you can specify configuration options, like this:
+`{$var|smartypants:1}` (where "1" is the configuration option).
+
+Numeric values are the easiest way to configure SmartyPants's behavior:
+
+"0"
+    Suppress all transformations. (Do nothing.)
+
+"1"
+    Performs default SmartyPants transformations: quotes (including
+    backticks-style), em-dashes, and ellipses. `--` (dash dash) is
+    used to signify an em-dash; there is no support for en-dashes.
+
+"2"
+    Same as smarty_pants="1", except that it uses the old-school
+    typewriter shorthand for dashes: `--` (dash dash) for en-dashes,
+    `---` (dash dash dash) for em-dashes.
+
+"3"
+    Same as smarty_pants="2", but inverts the shorthand for dashes: `--`
+    (dash dash) for em-dashes, and `---` (dash dash dash) for en-dashes.
+
+"-1"
+    Stupefy mode. Reverses the SmartyPants transformation process,
+    turning the HTML entities produced by SmartyPants into their ASCII
+    equivalents. E.g. `&#8220;` is turned into a simple double-quote
+    (`"`), `&#8212;` is turned into two dashes, etc. This is useful if you
+    wish to suppress smart punctuation in specific pages, such as
+    RSS feeds.
+
+The following single-character attribute values can be combined to
+toggle individual transformations from within the smarty_pants
+attribute. For example, to educate normal quotes and em-dashes, but not
+ellipses or backticks-style quotes:
+
+    $smartypants_attr = "qd";
+
+Or inside a Smarty template:
+
+    {$var|smartypants:"qd"}
+
+"q"
+    Educates normal quote characters: (`"`) and (`'`).
+
+"b"
+    Educates ` ``backticks'' ` double quotes.
+
+"B"
+    Educates backticks-style double quotes and ` `single' ` quotes.
+
+"d"
+    Educates em-dashes.
+
+"D"
+    Educates em-dashes and en-dashes, using old-school typewriter
+    shorthand: (dash dash) for en-dashes, (dash dash dash) for
+    em-dashes.
+
+"i"
+    Educates em-dashes and en-dashes, using inverted old-school
+    typewriter shorthand: (dash dash) for em-dashes, (dash dash dash)
+    for en-dashes.
+
+"e"
+    Educates ellipses.
+
+"w"
+    Translates any instance of `&quot;` into a normal double-quote
+    character. This should be of no interest to most people, but of
+    particular interest to anyone who writes their posts using
+    Dreamweaver, as Dreamweaver inexplicably uses this entity to
+    represent a literal double-quote character. SmartyPants only
+    educates normal quotes, not entities (because ordinarily, entities
+    are used for the explicit purpose of representing the specific
+    character they represent). The "w" option must be used in
+    conjunction with one (or both) of the other quote options ("q" or
+    "b"). Thus, if you wish to apply all SmartyPants transformations
+    (quotes, en- and em-dashes, and ellipses) and also translate
+    `&quot;` entities into regular quotes so SmartyPants can educate
+    them, you should pass the following to the smarty_pants attribute:
+
+        $smartypants_attr = "qDew";
+
+    Inside a Smarty template, this will be:
+
+        {$var|smartypants:"qDew"}
+
+
+Caveats
+-------
+
+### Why You Might Not Want to Use Smart Quotes in Your Weblog ###
+
+For one thing, you might not care.
+
+Most normal, mentally stable individuals do not take notice of proper
+typographic punctuation. Many design and typography nerds, however,
+break out in a nasty rash when they encounter, say, a restaurant sign
+that uses a straight apostrophe to spell "Joe's".
+
+If you're the sort of person who just doesn't care, you might well want
+to continue not caring. Using straight quotes -- and sticking to the
+7-bit ASCII character set in general -- is certainly a simpler way to
+live.
+
+Even if you *do* care about accurate typography, you still might want to
+think twice before educating the quote characters in your weblog. One
+side effect of publishing curly quote HTML entities is that it makes
+your weblog a bit harder for others to quote from using copy-and-paste.
+What happens is that when someone copies text from your blog, the copied
+text contains the 8-bit curly quote characters (as well as the 8-bit
+characters for em-dashes and ellipses, if you use these options). These
+characters are not standard across different text encoding methods,
+which is why they need to be encoded as HTML entities.
+
+People copying text from your weblog, however, may not notice that
+you're using curly quotes, and they'll go ahead and paste the unencoded
+8-bit characters copied from their browser into an email message or
+their own weblog. When pasted as raw "smart quotes", these characters
+are likely to get mangled beyond recognition.
+
+That said, my own opinion is that any decent text editor or email client
+makes it easy to stupefy smart quote characters into their 7-bit
+equivalents, and I don't consider it my problem if you're using an
+indecent text editor or email client.
+
+### Algorithmic Shortcomings ###
+
+One situation in which quotes will get curled the wrong way is when
+apostrophes are used at the start of leading contractions. For example:
+
+    'Twas the night before Christmas.
+
+In the case above, SmartyPants will turn the apostrophe into an opening
+single-quote, when in fact it should be a closing one. I don't think
+this problem can be solved in the general case -- every word processor
+I've tried gets this wrong as well. In such cases, it's best to use the
+proper HTML entity for closing single-quotes (`&#8217;` or `&rsquo;`) by
+hand.
+
+
+Bugs
+----
+
+To file bug reports or feature requests (other than topics listed in the
+Caveats section above) please send email to:
+
+<michel.fortin@michelf.com>
+
+If the bug involves quotes being curled the wrong way, please send
+example text to illustrate.
+
+
+Version History
+---------------
+
+1.5.1e (9 Dec 2005)
+
+*      Corrected a bug that prevented special characters from being
+    escaped.
+
+
+1.5.1d (6 Jun 2005)
+
+*      Correct a small bug in `_TokenizeHTML` where a Doctype declaration
+       was not seen as HTML, making curly quotes inside it.
+
+
+1.5.1c (13 Dec 2004)
+
+*      Changed a regular expression in `_TokenizeHTML` that could lead
+       to a segmentation fault with PHP 4.3.8 on Linux.
+
+
+1.5.1b (6 Sep 2004)
+
+*      Corrected a problem with quotes immediately following a dash
+       with no space between: `Text--"quoted text"--text.`
+
+*      PHP SmartyPants can now be used as a modifier by the Smarty
+       template engine. Rename the file to "modifier.smartypants.php"
+       and put it in your smarty plugins folder.
+
+*      Replaced a lot of spaces characters by tabs, saving about 4 KB.
+
+
+1.5.1a (30 Jun 2004)
+
+*      PHP Markdown and PHP Smartypants now share the same `_TokenizeHTML`
+       function when loaded simultanously.
+
+*      Changed the internals of `_TokenizeHTML` to lower the PHP version
+       requirement to PHP 4.0.5.
+
+
+1.5.1 (6 Jun 2004)
+
+*      Initial release of PHP SmartyPants, based on version 1.5.1 of the
+       original SmartyPants written in Perl.
+
+
+Copyright and License
+---------------------
+
+Copyright (c) 2005 Michel Fortin
+<http://www.michelf.com/>
+All rights reserved.
+
+Copyright (c) 2003-2004 John Gruber
+<http://daringfireball.net/>
+All rights reserved.
+
+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 "SmartyPants" 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 copyright owner
+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.
diff --git a/examples/includes/PHP-SmartyPants-1.5.1e/smartypants.php b/examples/includes/PHP-SmartyPants-1.5.1e/smartypants.php
new file mode 100644 (file)
index 0000000..cc0dd96
--- /dev/null
@@ -0,0 +1,860 @@
+<?php
+
+#
+# SmartyPants  -  Smart punctuation for web sites
+#
+# by John Gruber
+# <http://daringfireball.net>
+#
+# PHP port by Michel Fortin
+# <http://www.michelf.com/>
+#
+# Copyright (c) 2003-2004 John Gruber
+# Copyright (c) 2004-2005 Michel Fortin
+#
+
+
+global  $SmartyPantsPHPVersion, $SmartyPantsSyntaxVersion,
+        $smartypants_attr, $sp_tags_to_skip;
+
+$SmartyPantsPHPVersion    = '1.5.1e'; # Fru 9 Dec 2005
+$SmartyPantsSyntaxVersion = '1.5.1';  # Fri 12 Mar 2004
+
+
+# Configurable variables:
+$smartypants_attr = "1";  # Change this to configure.
+                          #  1 =>  "--" for em-dashes; no en-dash support
+                          #  2 =>  "---" for em-dashes; "--" for en-dashes
+                          #  3 =>  "--" for em-dashes; "---" for en-dashes
+                          #  See docs for more configuration options.
+
+# Globals:
+$sp_tags_to_skip = '<(/?)(?:pre|code|kbd|script|math)[\s>]';
+
+
+# -- WordPress plugin interface -----------------------------------------------
+/*
+Plugin Name: SmartyPants
+Plugin URI: http://www.michelf.com/projects/php-smartypants/
+Description: SmartyPants is a web publishing utility that translates plain ASCII punctuation characters into &#8220;smart&#8221; typographic punctuation HTML entities. This plugin <strong>replace the default WordPress Texturize algorithm</strong> for the content and the title of your posts, the comments body and author name, and everywhere else Texturize normally apply. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>.
+Version: 1.5.1e
+Author: Michel Fortin
+Author URI: http://www.michelf.com/
+*/
+if (isset($wp_version)) {
+    # Remove default Texturize filter that would conflict with SmartyPants.
+    remove_filter('category_description', 'wptexturize');
+    remove_filter('list_cats', 'wptexturize');
+    remove_filter('comment_author', 'wptexturize');
+    remove_filter('comment_text', 'wptexturize');
+    remove_filter('single_post_title', 'wptexturize');
+    remove_filter('the_title', 'wptexturize');
+    remove_filter('the_content', 'wptexturize');
+    remove_filter('the_excerpt', 'wptexturize');
+    # Add SmartyPants filter with priority 10 (same as Texturize).
+    add_filter('category_description', 'SmartyPants', 10);
+    add_filter('list_cats', 'SmartyPants', 10);
+    add_filter('comment_author', 'SmartyPants', 10);
+    add_filter('comment_text', 'SmartyPants', 10);
+    add_filter('single_post_title', 'SmartyPants', 10);
+    add_filter('the_title', 'SmartyPants', 10);
+    add_filter('the_content', 'SmartyPants', 10);
+    add_filter('the_excerpt', 'SmartyPants', 10);
+}
+
+# -- Smarty Modifier Interface ------------------------------------------------
+function smarty_modifier_smartypants($text, $attr = NULL) {
+    return SmartyPants($text, $attr);
+}
+
+
+
+function SmartyPants($text, $attr = NULL, $ctx = NULL) {
+    global $smartypants_attr, $sp_tags_to_skip;
+    # Paramaters:
+    $text;   # text to be parsed
+    $attr;   # value of the smart_quotes="" attribute
+    $ctx;    # MT context object (unused)
+    if ($attr == NULL) $attr = $smartypants_attr;
+
+    # Options to specify which transformations to make:
+    $do_stupefy = FALSE;
+    $convert_quot = 0;  # should we translate &quot; entities into normal quotes?
+
+    # Parse attributes:
+    # 0 : do nothing
+    # 1 : set all
+    # 2 : set all, using old school en- and em- dash shortcuts
+    # 3 : set all, using inverted old school en and em- dash shortcuts
+    #
+    # q : quotes
+    # b : backtick quotes (``double'' only)
+    # B : backtick quotes (``double'' and `single')
+    # d : dashes
+    # D : old school dashes
+    # i : inverted old school dashes
+    # e : ellipses
+    # w : convert &quot; entities to " for Dreamweaver users
+
+    if ($attr == "0") {
+        # Do nothing.
+        return $text;
+    }
+    else if ($attr == "1") {
+        # Do everything, turn all options on.
+        $do_quotes    = 1;
+        $do_backticks = 1;
+        $do_dashes    = 1;
+        $do_ellipses  = 1;
+    }
+    else if ($attr == "2") {
+        # Do everything, turn all options on, use old school dash shorthand.
+        $do_quotes    = 1;
+        $do_backticks = 1;
+        $do_dashes    = 2;
+        $do_ellipses  = 1;
+    }
+    else if ($attr == "3") {
+        # Do everything, turn all options on, use inverted old school dash shorthand.
+        $do_quotes    = 1;
+        $do_backticks = 1;
+        $do_dashes    = 3;
+        $do_ellipses  = 1;
+    }
+    else if ($attr == "-1") {
+        # Special "stupefy" mode.
+        $do_stupefy   = 1;
+    }
+    else {
+        $chars = preg_split('//', $attr);
+        foreach ($chars as $c){
+            if      ($c == "q") { $do_quotes    = 1; }
+            else if ($c == "b") { $do_backticks = 1; }
+            else if ($c == "B") { $do_backticks = 2; }
+            else if ($c == "d") { $do_dashes    = 1; }
+            else if ($c == "D") { $do_dashes    = 2; }
+            else if ($c == "i") { $do_dashes    = 3; }
+            else if ($c == "e") { $do_ellipses  = 1; }
+            else if ($c == "w") { $convert_quot = 1; }
+            else {
+                # Unknown attribute option, ignore.
+            }
+        }
+    }
+
+    $tokens = _TokenizeHTML($text);
+    $result = '';
+    $in_pre = 0;  # Keep track of when we're inside <pre> or <code> tags.
+
+    $prev_token_last_char = "";     # This is a cheat, used to get some context
+                                    # for one-character tokens that consist of
+                                    # just a quote char. What we do is remember
+                                    # the last character of the previous text
+                                    # token, to use as context to curl single-
+                                    # character quote tokens correctly.
+
+    foreach ($tokens as $cur_token) {
+        if ($cur_token[0] == "tag") {
+            # Don't mess with quotes inside tags.
+            $result .= $cur_token[1];
+            if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) {
+                $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1;
+            }
+        } else {
+            $t = $cur_token[1];
+            $last_char = substr($t, -1); # Remember last char of this token before processing.
+            if (! $in_pre) {
+                $t = ProcessEscapes($t);
+
+                if ($convert_quot) {
+                    $t = preg_replace('/&quot;/', '"', $t);
+                }
+
+                if ($do_dashes) {
+                    if ($do_dashes == 1) $t = EducateDashes($t);
+                    if ($do_dashes == 2) $t = EducateDashesOldSchool($t);
+                    if ($do_dashes == 3) $t = EducateDashesOldSchoolInverted($t);
+                }
+
+                if ($do_ellipses) $t = EducateEllipses($t);
+
+                # Note: backticks need to be processed before quotes.
+                if ($do_backticks) {
+                    $t = EducateBackticks($t);
+                    if ($do_backticks == 2) $t = EducateSingleBackticks($t);
+                }
+
+                if ($do_quotes) {
+                    if ($t == "'") {
+                        # Special case: single-character ' token
+                        if (preg_match('/\S/', $prev_token_last_char)) {
+                            $t = "&#8217;";
+                        }
+                        else {
+                            $t = "&#8216;";
+                        }
+                    }
+                    else if ($t == '"') {
+                        # Special case: single-character " token
+                        if (preg_match('/\S/', $prev_token_last_char)) {
+                            $t = "&#8221;";
+                        }
+                        else {
+                            $t = "&#8220;";
+                        }
+                    }
+                    else {
+                        # Normal case:
+                        $t = EducateQuotes($t);
+                    }
+                }
+
+                if ($do_stupefy) $t = StupefyEntities($t);
+            }
+            $prev_token_last_char = $last_char;
+            $result .= $t;
+        }
+    }
+
+    return $result;
+}
+
+
+function SmartQuotes($text, $attr = NULL, $ctx = NULL) {
+    global $smartypants_attr, $sp_tags_to_skip;
+    # Paramaters:
+    $text;   # text to be parsed
+    $attr;   # value of the smart_quotes="" attribute
+    $ctx;    # MT context object (unused)
+    if ($attr == NULL) $attr = $smartypants_attr;
+
+    $do_backticks;   # should we educate ``backticks'' -style quotes?
+
+    if ($attr == 0) {
+        # do nothing;
+        return $text;
+    }
+    else if ($attr == 2) {
+        # smarten ``backticks'' -style quotes
+        $do_backticks = 1;
+    }
+    else {
+        $do_backticks = 0;
+    }
+
+    # Special case to handle quotes at the very end of $text when preceded by
+    # an HTML tag. Add a space to give the quote education algorithm a bit of
+    # context, so that it can guess correctly that it's a closing quote:
+    $add_extra_space = 0;
+    if (preg_match("/>['\"]\\z/", $text)) {
+        $add_extra_space = 1; # Remember, so we can trim the extra space later.
+        $text .= " ";
+    }
+
+    $tokens = _TokenizeHTML($text);
+    $result = '';
+    $in_pre = 0;  # Keep track of when we're inside <pre> or <code> tags
+
+    $prev_token_last_char = "";     # This is a cheat, used to get some context
+                                    # for one-character tokens that consist of
+                                    # just a quote char. What we do is remember
+                                    # the last character of the previous text
+                                    # token, to use as context to curl single-
+                                    # character quote tokens correctly.
+
+    foreach ($tokens as $cur_token) {
+        if ($cur_token[0] == "tag") {
+            # Don't mess with quotes inside tags
+            $result .= $cur_token[1];
+            if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) {
+                $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1;
+            }
+        } else {
+            $t = $cur_token[1];
+            $last_char = substr($t, -1); # Remember last char of this token before processing.
+            if (! $in_pre) {
+                $t = ProcessEscapes($t);
+                if ($do_backticks) {
+                    $t = EducateBackticks($t);
+                }
+
+                if ($t == "'") {
+                    # Special case: single-character ' token
+                    if (preg_match('/\S/', $prev_token_last_char)) {
+                        $t = "&#8217;";
+                    }
+                    else {
+                        $t = "&#8216;";
+                    }
+                }
+                else if ($t == '"') {
+                    # Special case: single-character " token
+                    if (preg_match('/\S/', $prev_token_last_char)) {
+                        $t = "&#8221;";
+                    }
+                    else {
+                        $t = "&#8220;";
+                    }
+                }
+                else {
+                    # Normal case:
+                    $t = EducateQuotes($t);
+                }
+
+            }
+            $prev_token_last_char = $last_char;
+            $result .= $t;
+        }
+    }
+
+    if ($add_extra_space) {
+        preg_replace('/ \z/', '', $result);  # Trim trailing space if we added one earlier.
+    }
+    return $result;
+}
+
+
+function SmartDashes($text, $attr = NULL, $ctx = NULL) {
+    global $smartypants_attr, $sp_tags_to_skip;
+    # Paramaters:
+    $text;   # text to be parsed
+    $attr;   # value of the smart_dashes="" attribute
+    $ctx;    # MT context object (unused)
+    if ($attr == NULL) $attr = $smartypants_attr;
+
+    # reference to the subroutine to use for dash education, default to EducateDashes:
+    $dash_sub_ref = 'EducateDashes';
+
+    if ($attr == 0) {
+        # do nothing;
+        return $text;
+    }
+    else if ($attr == 2) {
+        # use old smart dash shortcuts, "--" for en, "---" for em
+        $dash_sub_ref = 'EducateDashesOldSchool';
+    }
+    else if ($attr == 3) {
+        # inverse of 2, "--" for em, "---" for en
+        $dash_sub_ref = 'EducateDashesOldSchoolInverted';
+    }
+
+    $tokens;
+    $tokens = _TokenizeHTML($text);
+
+    $result = '';
+    $in_pre = 0;  # Keep track of when we're inside <pre> or <code> tags
+    foreach ($tokens as $cur_token) {
+        if ($cur_token[0] == "tag") {
+            # Don't mess with quotes inside tags
+            $result .= $cur_token[1];
+            if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) {
+                $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1;
+            }
+        } else {
+            $t = $cur_token[1];
+            if (! $in_pre) {
+                $t = ProcessEscapes($t);
+                $t = $dash_sub_ref($t);
+            }
+            $result .= $t;
+        }
+    }
+    return $result;
+}
+
+
+function SmartEllipses($text, $attr = NULL, $ctx = NULL) {
+    # Paramaters:
+    $text;   # text to be parsed
+    $attr;   # value of the smart_ellipses="" attribute
+    $ctx;    # MT context object (unused)
+    if ($attr == NULL) $attr = $smartypants_attr;
+
+    if ($attr == 0) {
+        # do nothing;
+        return $text;
+    }
+
+    $tokens;
+    $tokens = _TokenizeHTML($text);
+
+    $result = '';
+    $in_pre = 0;  # Keep track of when we're inside <pre> or <code> tags
+    foreach ($tokens as $cur_token) {
+        if ($cur_token[0] == "tag") {
+            # Don't mess with quotes inside tags
+            $result .= $cur_token[1];
+            if (preg_match("@$sp_tags_to_skip@", $cur_token[1], $matches)) {
+                $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1;
+            }
+        } else {
+            $t = $cur_token[1];
+            if (! $in_pre) {
+                $t = ProcessEscapes($t);
+                $t = EducateEllipses($t);
+            }
+            $result .= $t;
+        }
+    }
+    return $result;
+}
+
+
+function EducateQuotes($_) {
+#
+#   Parameter:  String.
+#
+#   Returns:    The string, with "educated" curly quote HTML entities.
+#
+#   Example input:  "Isn't this fun?"
+#   Example output: &#8220;Isn&#8217;t this fun?&#8221;
+#
+    # Make our own "punctuation" character class, because the POSIX-style
+    # [:PUNCT:] is only available in Perl 5.6 or later:
+    $punct_class = "[!\"#\\$\\%'()*+,-.\\/:;<=>?\\@\\[\\\\\]\\^_`{|}~]";
+
+    # Special case if the very first character is a quote
+    # followed by punctuation at a non-word-break. Close the quotes by brute force:
+    $_ = preg_replace(
+        array("/^'(?=$punct_class\\B)/", "/^\"(?=$punct_class\\B)/"),
+        array('&#8217;',                 '&#8221;'), $_);
+
+
+    # Special case for double sets of quotes, e.g.:
+    #   <p>He said, "'Quoted' words in a larger quote."</p>
+    $_ = preg_replace(
+        array("/\"'(?=\w)/",    "/'\"(?=\w)/"),
+        array('&#8220;&#8216;', '&#8216;&#8220;'), $_);
+
+    # Special case for decade abbreviations (the '80s):
+    $_ = preg_replace("/'(?=\\d{2}s)/", '&#8217;', $_);
+
+    $close_class = '[^\ \t\r\n\[\{\(\-]';
+    $dec_dashes = '&\#8211;|&\#8212;';
+
+    # Get most opening single quotes:
+    $_ = preg_replace("{
+        (
+            \\s          |   # a whitespace char, or
+            &nbsp;      |   # a non-breaking space entity, or
+            --          |   # dashes, or
+            &[mn]dash;  |   # named dash entities
+            $dec_dashes |   # or decimal entities
+            &\\#x201[34];    # or hex
+        )
+        '                   # the quote
+        (?=\\w)              # followed by a word character
+        }x", '\1&#8216;', $_);
+    # Single closing quotes:
+    $_ = preg_replace("{
+        ($close_class)?
+        '
+        (?(1)|          # If $1 captured, then do nothing;
+          (?=\\s | s\\b)  # otherwise, positive lookahead for a whitespace
+        )               # char or an 's' at a word ending position. This
+                        # is a special case to handle something like:
+                        # \"<i>Custer</i>'s Last Stand.\"
+        }xi", '\1&#8217;', $_);
+
+    # Any remaining single quotes should be opening ones:
+    $_ = str_replace("'", '&#8216;', $_);
+
+
+    # Get most opening double quotes:
+    $_ = preg_replace("{
+        (
+            \\s          |   # a whitespace char, or
+            &nbsp;      |   # a non-breaking space entity, or
+            --          |   # dashes, or
+            &[mn]dash;  |   # named dash entities
+            $dec_dashes |   # or decimal entities
+            &\\#x201[34];    # or hex
+        )
+        \"                   # the quote
+        (?=\\w)              # followed by a word character
+        }x", '\1&#8220;', $_);
+
+    # Double closing quotes:
+    $_ = preg_replace("{
+        ($close_class)?
+        \"
+        (?(1)|(?=\\s))   # If $1 captured, then do nothing;
+                           # if not, then make sure the next char is whitespace.
+        }x", '\1&#8221;', $_);
+
+    # Any remaining quotes should be opening ones.
+    $_ = str_replace('"', '&#8220;', $_);
+
+    return $_;
+}
+
+
+function EducateBackticks($_) {
+#
+#   Parameter:  String.
+#   Returns:    The string, with ``backticks'' -style double quotes
+#               translated into HTML curly quote entities.
+#
+#   Example input:  ``Isn't this fun?''
+#   Example output: &#8220;Isn't this fun?&#8221;
+#
+
+    $_ = str_replace(array("``",       "''",),
+                     array('&#8220;', '&#8221;'), $_);
+    return $_;
+}
+
+
+function EducateSingleBackticks($_) {
+#
+#   Parameter:  String.
+#   Returns:    The string, with `backticks' -style single quotes
+#               translated into HTML curly quote entities.
+#
+#   Example input:  `Isn't this fun?'
+#   Example output: &#8216;Isn&#8217;t this fun?&#8217;
+#
+
+    $_ = str_replace(array("`",       "'",),
+                     array('&#8216;', '&#8217;'), $_);
+    return $_;
+}
+
+
+function EducateDashes($_) {
+#
+#   Parameter:  String.
+#
+#   Returns:    The string, with each instance of "--" translated to
+#               an em-dash HTML entity.
+#
+
+    $_ = str_replace('--', '&#8212;', $_);
+    return $_;
+}
+
+
+function EducateDashesOldSchool($_) {
+#
+#   Parameter:  String.
+#
+#   Returns:    The string, with each instance of "--" translated to
+#               an en-dash HTML entity, and each "---" translated to
+#               an em-dash HTML entity.
+#
+
+    #                      em         en
+    $_ = str_replace(array("---",     "--",),
+                     array('&#8212;', '&#8211;'), $_);
+    return $_;
+}
+
+
+function EducateDashesOldSchoolInverted($_) {
+#
+#   Parameter:  String.
+#
+#   Returns:    The string, with each instance of "--" translated to
+#               an em-dash HTML entity, and each "---" translated to
+#               an en-dash HTML entity. Two reasons why: First, unlike the
+#               en- and em-dash syntax supported by
+#               EducateDashesOldSchool(), it's compatible with existing
+#               entries written before SmartyPants 1.1, back when "--" was
+#               only used for em-dashes.  Second, em-dashes are more
+#               common than en-dashes, and so it sort of makes sense that
+#               the shortcut should be shorter to type. (Thanks to Aaron
+#               Swartz for the idea.)
+#
+
+    #                      en         em
+    $_ = str_replace(array("---",     "--",),
+                     array('&#8211;', '&#8212;'), $_);
+    return $_;
+}
+
+
+function EducateEllipses($_) {
+#
+#   Parameter:  String.
+#   Returns:    The string, with each instance of "..." translated to
+#               an ellipsis HTML entity. Also converts the case where
+#               there are spaces between the dots.
+#
+#   Example input:  Huh...?
+#   Example output: Huh&#8230;?
+#
+
+    $_ = str_replace(array("...",     ". . .",), '&#8230;', $_);
+    return $_;
+}
+
+
+function StupefyEntities($_) {
+#
+#   Parameter:  String.
+#   Returns:    The string, with each SmartyPants HTML entity translated to
+#               its ASCII counterpart.
+#
+#   Example input:  &#8220;Hello &#8212; world.&#8221;
+#   Example output: "Hello -- world."
+#
+
+                        #  en-dash    em-dash
+    $_ = str_replace(array('&#8211;', '&#8212;'),
+                     array('-',       '--'), $_);
+
+    # single quote         open       close
+    $_ = str_replace(array('&#8216;', '&#8217;'), "'", $_);
+
+    # double quote         open       close
+    $_ = str_replace(array('&#8220;', '&#8221;'), '"', $_);
+
+    $_ = str_replace('&#8230;', '...', $_); # ellipsis
+
+    return $_;
+}
+
+
+function ProcessEscapes($_) {
+#
+#   Parameter:  String.
+#   Returns:    The string, with after processing the following backslash
+#               escape sequences. This is useful if you want to force a "dumb"
+#               quote or other character to appear.
+#
+#               Escape  Value
+#               ------  -----
+#               \\      &#92;
+#               \"      &#34;
+#               \'      &#39;
+#               \.      &#46;
+#               \-      &#45;
+#               \`      &#96;
+#
+    $_ = str_replace(
+        array('\\\\',  '\"',    "\'",    '\.',    '\-',    '\`'),
+        array('&#92;', '&#34;', '&#39;', '&#46;', '&#45;', '&#96;'), $_);
+
+    return $_;
+}
+
+
+# _TokenizeHTML is shared between PHP SmartyPants and PHP Markdown.
+# We only define it if it is not already defined.
+if (!function_exists('_TokenizeHTML')) :
+function _TokenizeHTML($str) {
+#
+#   Parameter:  String containing HTML markup.
+#   Returns:    An array of the tokens comprising the input
+#               string. Each token is either a tag (possibly with nested,
+#               tags contained therein, such as <a href="<MTFoo>">, or a
+#               run of text between tags. Each element of the array is a
+#               two-element array; the first is either 'tag' or 'text';
+#               the second is the actual value.
+#
+#
+#   Regular expression derived from the _tokenize() subroutine in
+#   Brad Choate's MTRegex plugin.
+#   <http://www.bradchoate.com/past/mtregex.php>
+#
+    $index = 0;
+    $tokens = array();
+
+    $match = '(?s:<!(?:--.*?--\s*)+>)|'.    # comment
+             '(?s:<\?.*?\?>)|'.             # processing instruction
+                                            # regular tags
+             '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)';
+
+    $parts = preg_split("{($match)}", $str, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+    foreach ($parts as $part) {
+        if (++$index % 2 && $part != '')
+            $tokens[] = array('text', $part);
+        else
+            $tokens[] = array('tag', $part);
+    }
+    return $tokens;
+}
+endif;
+
+
+/*
+
+PHP SmartyPants
+===============
+
+Description
+-----------
+
+This is a PHP translation of the original SmartyPants quote educator written in
+Perl by John Gruber.
+
+SmartyPants is a web publishing utility that translates plain ASCII
+punctuation characters into "smart" typographic punctuation HTML
+entities. SmartyPants can perform the following transformations:
+
+*   Straight quotes (`"` and `'`) into "curly" quote HTML entities
+*   Backticks-style quotes (` ``like this'' `) into "curly" quote HTML
+    entities
+*   Dashes (`--` and `---`) into en- and em-dash entities
+*   Three consecutive dots (`...`) into an ellipsis entity
+
+SmartyPants does not modify characters within `<pre>`, `<code>`, `<kbd>`,
+`<script>`, or `<math>` tag blocks. Typically, these tags are used to
+display text where smart quotes and other "smart punctuation" would not
+be appropriate, such as source code or example markup.
+
+
+### Backslash Escapes ###
+
+If you need to use literal straight quotes (or plain hyphens and
+periods), SmartyPants accepts the following backslash escape sequences
+to force non-smart punctuation. It does so by transforming the escape
+sequence into a decimal-encoded HTML entity:
+
+    Escape  Value  Character
+    ------  -----  ---------
+      \\    &#92;    \
+      \"    &#34;    "
+      \'    &#39;    '
+      \.    &#46;    .
+      \-    &#45;    -
+      \`    &#96;    `
+
+This is useful, for example, when you want to use straight quotes as
+foot and inch marks: 6'2" tall; a 17" iMac.
+
+
+Bugs
+----
+
+To file bug reports or feature requests (other than topics listed in the
+Caveats section above) please send email to:
+
+<michel.fortin@michelf.com>
+
+If the bug involves quotes being curled the wrong way, please send example
+text to illustrate.
+
+
+### Algorithmic Shortcomings ###
+
+One situation in which quotes will get curled the wrong way is when
+apostrophes are used at the start of leading contractions. For example:
+
+    'Twas the night before Christmas.
+
+In the case above, SmartyPants will turn the apostrophe into an opening
+single-quote, when in fact it should be a closing one. I don't think
+this problem can be solved in the general case -- every word processor
+I've tried gets this wrong as well. In such cases, it's best to use the
+proper HTML entity for closing single-quotes (`&#8217;`) by hand.
+
+
+Version History
+---------------
+
+1.5.1e (9 Dec 2005)
+
+*   Corrected a bug that prevented special characters from being
+    escaped.
+
+
+1.5.1d (25 May 2005)
+
+*   Corrected a small bug in `_TokenizeHTML` where a Doctype declaration
+    was not seen as HTML (smart quotes where applied inside).
+
+
+1.5.1c (13 Dec 2004)
+
+*   Changed a regular expression in `_TokenizeHTML` that could lead to
+    a segmentation fault with PHP 4.3.8 on Linux.
+
+
+1.5.1b (6 Sep 2004)
+
+*   Corrected a problem with quotes immediately following a dash
+    with no space between: `Text--"quoted text"--text.`
+
+*   PHP SmartyPants can now be used as a modifier by the Smarty
+    template engine. Rename the file to "modifier.smartypants.php"
+    and put it in your smarty plugins folder.
+
+*   Replaced a lot of space characters by tabs, saving about 4 KB.
+
+
+1.5.1a (30 Jun 2004)
+
+*   PHP Markdown and PHP Smartypants now share the same `_TokenizeHTML`
+    function when loaded simultanously.
+
+*   Changed the internals of `_TokenizeHTML` to lower the PHP version
+    requirement to PHP 4.0.5.
+
+
+1.5.1 (6 Jun 2004)
+
+*   Initial release of PHP SmartyPants, based on version 1.5.1 of the
+    original SmartyPants written in Perl.
+
+
+Author
+------
+
+John Gruber
+<http://daringfireball.net/>
+
+Ported to PHP by Michel Fortin
+<http://www.michelf.com/>
+
+
+Additional Credits
+------------------
+
+Portions of this plug-in are based on Brad Choate's nifty MTRegex plug-in.
+Brad Choate also contributed a few bits of source code to this plug-in.
+Brad Choate is a fine hacker indeed. (<http://bradchoate.com/>)
+
+Jeremy Hedley (<http://antipixel.com/>) and Charles Wiltgen
+(<http://playbacktime.com/>) deserve mention for exemplary beta testing.
+
+
+Copyright and License
+---------------------
+
+Copyright (c) 2003 John Gruber
+<http://daringfireball.net/>
+All rights reserved.
+
+Copyright (c) 2004-2005 Michel Fortin
+<http://www.michelf.com>
+
+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 "SmartyPants" 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 copyright owner 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.
+
+*/
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/contrib/aliased.php b/examples/includes/geshi/contrib/aliased.php
new file mode 100644 (file)
index 0000000..4680ffb
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * Another GeSHi example script
+ *
+ * Configure your Apache server with 'AcceptPathInfo true' and something like
+ * 'Alias /viewmysource /var/www/geshi/contrib/aliased.php'. Don't forget
+ * to protect this alias as necessary.
+ *
+ * Usage - visit /viewmysource/file.name.ext to see that file with syntax
+ * highlighting, where "viewmysource" is the name of the alias you set up.
+ * You can use this without an alias too, just by visiting
+ * aliased.php/file.name.ext.
+ *
+ * @author  Ross Golder <ross@golder.org>
+ * @version $Id: aliased.php 785 2006-07-19 10:09:45Z oracleshinoda $
+ */
+
+// Your config here
+define("SOURCE_ROOT", "/var/www/your/source/root/");
+
+// Assume you've put geshi in the include_path already
+require_once("geshi.php");
+
+// Get path info
+$path = SOURCE_ROOT.$_SERVER['PATH_INFO'];
+
+// Check for dickheads trying to use '../' to get to sensitive areas
+$base_path_len = strlen(SOURCE_ROOT);
+$real_path = realpath($path);
+if(strncmp($real_path, SOURCE_ROOT, $base_path_len)) {
+    exit("Stop that.");
+}
+
+// Check file exists
+if(!file_exists($path)) {
+    exit("File not found ($path).");
+}
+
+// Gather contents
+$contents = file_get_contents($path);
+
+// Prepare GeSHi instance
+$geshi =& new GeSHi($contents, "PHP");
+$geshi->set_header_type(GESHI_HEADER_PRE);
+$geshi->enable_classes();
+$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 10);
+$geshi->set_overall_style('color: #000066; border: 1px solid #d0d0d0; background-color: #f0f0f0;', true);
+$geshi->set_line_style('font: normal normal 95% \'Courier New\', Courier, monospace; color: #003030;', 'font-weight: bold; color: #006060;', true);
+$geshi->set_code_style('color: #000020;', 'color: #000020;');
+$geshi->set_link_styles(GESHI_LINK, 'color: #000060;');
+$geshi->set_link_styles(GESHI_HOVER, 'background-color: #f0f000;');
+$geshi->set_header_content('Source code viewer');
+$geshi->set_header_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;');
+$geshi->set_footer_content('Parsed in <TIME> seconds,  using GeSHi <VERSION>');
+$geshi->set_footer_content_style('font-family: Verdana, Arial, sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;');
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>Source code viewer - <?php echo $path; ?></title>
+    <style type="text/css">
+    <!--
+    <?php
+        // Output the stylesheet. Note it doesn't output the <style> tag
+    echo $geshi->get_stylesheet();
+    ?>
+    html {
+        background-color: #f0f0f0;
+    }
+    body {
+        font-family: Verdana, Arial, sans-serif;
+        margin: 10px;
+        border: 2px solid #e0e0e0;
+        background-color: #fcfcfc;
+        padding: 5px;
+    }
+    h2 {
+        margin: .1em 0 .2em .5em;
+        border-bottom: 1px solid #b0b0b0;
+        color: #b0b0b0;
+        font-weight: normal;
+        font-size: 150%;
+    }
+    h3 {
+        margin: .1em 0 .2em .5em;
+        color: #b0b0b0;
+        font-weight: normal;
+        font-size: 120%;
+    }
+    #footer {
+        text-align: center;
+        font-size: 80%;
+        color: #a9a9a9;
+    }
+    #footer a {
+        color: #9999ff;
+    }
+    textarea {
+        border: 1px solid #b0b0b0;
+        font-size: 90%;
+        color: #333;
+        margin-left: 20px;
+    }
+    select, input {
+        margin-left: 20px;
+    }
+    p {
+        font-size: 90%;
+        margin-left: .5em;
+    }
+    -->
+    </style>
+</head>
+<body>
+<?php
+// The fun part :)
+echo $geshi->parse_code();
+?>
+<hr/>
+</body>
+</html>
diff --git a/examples/includes/geshi/contrib/cssgen.php b/examples/includes/geshi/contrib/cssgen.php
new file mode 100644 (file)
index 0000000..b75edc8
--- /dev/null
@@ -0,0 +1,456 @@
+<?php
+/*************************************************************************************
+ * cssgen.php
+ * ----------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie
+ * Release Version: 1.0.8.1
+ * Date Started: 2004/05/20
+ *
+ * Application to generate custom CSS files for GeSHi (based on an idea by Andreas
+ * Gohr)
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+set_magic_quotes_runtime(0);
+//
+// Functions
+//
+
+function make_header ( $title )
+{
+    echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>GeSHi CSS Generator :: ' . $title . ' </title>
+    <style type="text/css" media="screen">
+    <!--
+        html {
+            font-family: Verdana, Arial, sans-serif;
+            font-size: 80%;
+            background-color: #d0d0d0;
+        }
+        body {
+            margin: 10px;
+            padding: 5px;
+            border: 1px solid #f0f0f0;
+            background-color: #f6f6f6;
+        }
+        h1 {
+            border-bottom: 2px solid #e0e0e0;
+            font-weight: normal;
+            font-size: 150%;
+            color: #c0c0c0;
+        }
+        input, textarea {
+            border: 1px solid #d0d0d0;
+        }
+        th {
+            text-align: right;
+            font-weight: normal;
+        }
+        pre {
+            font-size: 110%;
+            color: #202020;
+        }
+        #footer {
+            color: #b0b0b0;
+            text-align: center;
+            font-size: 90%;
+            margin: 0 auto;
+            border-top: 1px solid #e0e0e0;
+        }
+        #footer a {
+            color: #c0c0c0;
+        }
+    -->
+    </style>
+    <script type="text/javascript">
+    function select (state)
+    {
+        var cboxes = document.getElementsByTagName(\'input\');
+        for (var i = 0; i < cboxes.length; i++) {
+            if (cboxes[i].type == "checkbox") {
+                if (state == "true") {
+                    cboxes[i].checked = true;
+                } else if (state == "false") {
+                    cboxes[i].checked = false;
+                } else if (state == "invert") {
+                    cboxes[i].checked = !cboxes[i].checked;
+                }
+            }
+        }
+    }
+    </script>
+</head>
+<body>
+<h1>' . $title . '</h1>
+';
+}
+
+function make_footer ()
+{
+    echo '<div id="footer"><a href="http://qbnz.com/highlighter/">GeSHi</a> &copy; Nigel McNie, 2004, released under the GPL</div></body>
+</html>';
+}
+
+
+function get_var ( $var_name )
+{
+    if ( isset($_GET[$var_name]) )
+    {
+        return str_replace("\'", "'", $_GET[$var_name]);
+    }
+    elseif ( isset($_POST[$var_name]) )
+    {
+        return str_replace("\'", "'", $_POST[$var_name]);
+    }
+    return null;
+}
+
+
+
+//
+// Unset everything
+//
+foreach ( $_REQUEST as $var )
+{
+    unset($$var);
+}
+foreach ( array(
+    '_POST' => 'HTTP_POST_VARS',
+    '_GET' => 'HTTP_GET_VARS',
+    '_COOKIE' => 'HTTP_COOKIE_VARS',
+    '_SERVER' => 'HTTP_SERVER_VARS',
+    '_ENV' => 'HTTP_ENV_VARS',
+    '_FILES' => 'HTTP_POST_FILES')  as $array => $other )
+{
+    if ( !isset($$array) )
+    {
+        $$array = $$other;
+    }
+    unset($$other);
+}
+
+
+// Get what step we're up to
+$step = get_var('step');
+
+if ( !$step || $step == 1 )
+{
+    $errors = 0;
+    make_header('Step 1');
+    echo "Welcome to the GeSHi CSS generator.<br /><pre>Searching for GeSHi...          ";
+
+    // Find GeSHi
+    $geshi_path = get_var('geshi-path');
+    $geshi_lang_path = get_var('geshi-lang-path');
+
+    if ( !$geshi_path )
+    {
+        $geshi_path = '../geshi.php';
+    }
+    if ( !$geshi_lang_path )
+    {
+        $geshi_lang_path = '../geshi/';
+    }
+
+
+    if ( is_file($geshi_path) && is_readable($geshi_path) )
+    {
+        // Get file contents and see if GeSHi is in here
+        $file = @file($geshi_path);
+        $contents = '';
+        foreach ( $file as $line )
+        {
+            $contents .= $line;
+        }
+        if ( strpos($contents, '<?php
+/**
+ * GeSHi - Generic Syntax Highlighter') !== false )
+         {
+            echo '<span style="color: green;">Found at ' . realpath($geshi_path) . '</span>';
+        }
+        else
+        {
+            ++$errors;
+            $no_geshi_dot_php_error = true;
+            echo '<span style="color: red;">Not found</span>';
+        }
+    }
+    else
+    {
+        ++$errors;
+        $no_geshi_dot_php_error = true;
+        echo '<span style="color: red;">Not found</span>';
+    }
+
+    // Find language files
+    echo "\nSearching for language files... ";
+    if ( is_readable($geshi_lang_path . 'css-gen.cfg') )
+    {
+
+        echo '<span style="color: green;">Found at ' . realpath($geshi_lang_path) . '</span>';
+    }
+    else
+    {
+        ++$errors;
+        $no_lang_dir_error = true;
+        echo '<span style="color: red;">Not found</span>';
+    }
+    echo "</pre>\n";
+
+    if ( $errors > 0 )
+    {
+        // We're gonna have to ask for the paths...
+        echo 'Unfortunately CSSGen could not detect the following paths. Please input them and press &quot;submit&quot; to try again.';
+        echo "
+<form action=\"cssgen.php\" method=\"post\">";
+        if ( $no_geshi_dot_php_error )
+        {
+            echo "
+<br />geshi.php: <input type=\"text\" name=\"geshi-path\" value=\"" . realpath('../geshi.php') . "\" size=\"50\" />";
+        }
+        else
+        {
+            echo '<input type="hidden" name="geshi-path" value="' . htmlspecialchars($geshi_path) . '" />';
+        }
+        if ( $no_lang_dir_error )
+        {
+            echo "
+<br />language files directory: <input type=\"text\" name=\"geshi-lang-path\" value=\"" . realpath('../geshi/') . "/\" size=\"50\" /> (should have a trailing slash)";
+        }
+        else
+        {
+            echo '<input type="hidden" name="geshi-lang-path" value="' . $geshi_lang_path . '" />';
+        }
+
+        echo "
+<br /><input type=\"submit\" value=\"Search\" /></form>";
+    }
+    else
+    {
+        // no errors - echo continue form
+        echo 'Everything seems to be detected successfully. Use the button to continue.
+<br /><br /><form action="cssgen.php?step=2" method="post">
+<input type="hidden" name="geshi-path" value="' . realpath($geshi_path) . '" /><input type="hidden" name="geshi-lang-path" value="' . realpath($geshi_lang_path) . '" />
+<input type="submit" value="Step 2" />';
+    }
+
+    make_footer();
+}
+// Step 2
+elseif ( $step == 2 )
+{
+    make_header('Step 2');
+
+    $geshi_path = get_var('geshi-path');
+    $geshi_lang_path = get_var('geshi-lang-path');
+
+    $dh = opendir($geshi_lang_path);
+    $lang_files = array();
+    $file = readdir($dh);
+    while ( $file !== false )
+    {
+        if ( $file == '.' || $file == '..' || $file == 'CVS' || $file == 'css-gen.cfg' )
+        {
+            $file = readdir($dh);
+            continue;
+        }
+        $lang_files[] = $file;
+        $file = readdir($dh);
+    }
+    closedir($dh);
+    sort($lang_files);
+
+    // Now installed languages are in $lang_files
+
+    echo '<form action="cssgen.php?step=3" method="post" id="step2">
+What languages are you wanting to make this stylesheet for?<br /><br />
+Detected languages:<br />';
+
+    foreach ( $lang_files as $lang )
+    {
+        $lang = substr($lang, 0, strpos($lang, '.'));
+        if ($lang) {
+            echo "<input type=\"checkbox\" name=\"langs[$lang]\" checked=\"checked\" />&nbsp;$lang<br />\n";
+        }
+    }
+
+    echo "Select: <a href=\"javascript:select('true')\">All</a>, <a href=\"javascript:select('false')\">None</a>, <a href=\"javascript:select('invert')\">Invert</a><br />\n";
+
+    echo 'If you\'d like any other languages not detected here to be supported, please enter
+them here, one per line:<br /><textarea rows="4" cols="20" name="extra-langs"></textarea><br />
+';
+
+    echo '<br />Styles:
+<table>
+    <tr><th>Style for the overall code block:</th><td><input type="text" name="overall" value="border: 1px dotted #a0a0a0; font-family: \'Courier New\', Courier, monospace; background-color: #f0f0f0; color: #0000bb;" /></td></tr>
+    <tr><th>Default Styles</th><td><input type="text" name="default-styles" value="font-weight:normal;background:transparent;color:#000; padding-left: 5px;" /></td></tr>
+    <tr><th>Keywords I (if, do, while etc)</th><td><input type="text" name="keywords-1" value="color: #a1a100;" /></td></tr>
+    <tr><th>Keywords II (null, true, false etc)</th><td><input type="text" name="keywords-2" value="color: #000; font-weight: bold;" /></td></tr>
+    <tr><th>Inbuilt Functions (echo, print etc)</th><td><input type="text" name="keywords-3" value="color: #000066;" /></td></tr>
+    <tr><th>Data Types (int, boolean etc)</th><td><input type="text" name="keywords-4" value="color: #f63333;" /></td></tr>
+
+    <tr><th>Comments (//, <!--  --> etc)</th><td><input type="text" name="comments" value="color: #808080;" /></td></tr>
+    <tr><th>Escaped Characters (\n, \t etc)</th><td><input type="text" name="escaped-chars" value="color: #000033; font-weight: bold;" /></td></tr>
+    <tr><th>Brackets ( ([{}]) etc)</th><td><input type="text" name="brackets" value="color: #66cc66;" /></td></tr>
+    <tr><th>Strings ("foo" etc)</th><td><input type="text" name="strings" value="color: #ff0000;" /></td></tr>
+    <tr><th>Numbers (1, -54, 2.5 etc)</th><td><input type="text" name="numbers" value="color: #ff33ff;" /></td></tr>
+    <tr><th>Methods (Foo.bar() etc)</th><td><input type="text" name="methods" value="color: #006600;" /></td></tr>
+</table>';
+
+    echo '<input type="hidden" name="geshi-path" value="' . realpath($geshi_path) . '" /><input type="hidden" name="geshi-lang-path" value="' . realpath($geshi_lang_path) . '" />
+<input type="submit" value="Step 3" /></form>';
+
+    make_footer();
+}
+// Step 3
+elseif ( $step == 3 )
+{
+    make_header('Step 3');
+    echo '<p>Here is your completed stylesheet. Note that it may not be perfect - no regular expression styles are included for one thing,
+you\'ll have to add those yourself (php and xml are just two languages that use them), and line numbers are not included, however
+it includes most of the basic information.</p>';
+
+    // Make the stylesheet
+    $part_selector_1 = '';
+    $part_selector_2 = '';
+    $part_selector_3 = '';
+
+    $langs = get_var('langs');
+    $extra_langs = trim(get_var('extra-langs'));
+    if ( $extra_langs != '' )
+    {
+        $l = explode("\r\n", $extra_langs);
+        foreach ( $l as $lng )
+        {
+            $langs[$lng] = true;
+        }
+    }
+
+
+    foreach ( $langs as $lang => $dummy )
+    {
+        $part_selector_1 .= ".$lang {PART}, ";
+        $part_selector_2 .= ".$lang {PART1}, .$lang {PART2}, ";
+        $part_selector_3 .= ".$lang {PART1}, .$lang {PART2}, .$lang {PART3}, ";
+    }
+    $part_selector_1 = substr($part_selector_1, 0, -2);
+    $part_selector_2 = substr($part_selector_2, 0, -2);
+    $part_selector_3 = substr($part_selector_3, 0, -2);
+
+
+    $default_styles = get_var('default-styles');
+    $ol_selector = str_replace('{PART}', 'ol', $part_selector_1);
+    $overall_styles = get_var('overall');
+    $overall_selector = str_replace('{PART}', '', $part_selector_1);
+
+    $stylesheet = "/* GeSHi (c) Nigel McNie 2004 (http://qbnz.com/highlighter) */";
+
+    if ( $overall != '' )
+    {
+        $stylesheet .= "\n$overall_selector {{$overall_styles}}";
+    }
+    if ( $default_styles != '' )
+    {
+        $default_selector = str_replace(array('{PART1}', '{PART2}'), array('.de1', '.de2'), $part_selector_2);
+        $stylesheet .= "\n$default_selector {{$default_styles}}";
+    }
+
+    // Do keywords
+    $keywords_1 = get_var('keywords-1');
+    $keyword_selector_1 = str_replace('{PART}', '.kw1', $part_selector_1);
+    if ( $keywords_1 != '' )
+    {
+        $stylesheet .= "\n$keyword_selector_1 {{$keywords_1}}";
+    }
+
+    $keywords_2 = get_var('keywords-2');
+    $keyword_selector_2 = str_replace('{PART}', '.kw2', $part_selector_1);
+    if ( $keywords_2 != '' )
+    {
+        $stylesheet .= "\n$keyword_selector_2 {{$keywords_2}}";
+    }
+
+    $keywords_3 = get_var('keywords-3');
+    $keyword_selector_3 = str_replace('{PART}', '.kw3', $part_selector_1);
+    if ( $keywords_3 != '' )
+    {
+        $stylesheet .= "\n$keyword_selector_3 {{$keywords_3}}";
+    }
+
+    $keywords_4 = get_var('keywords-4');
+    $keyword_selector_4 = str_replace('{PART}', '.kw4', $part_selector_1);
+    if ( $keywords_4 != '' )
+    {
+        $stylesheet .= "\n$keyword_selector_4 {{$keywords_4}}";
+    }
+
+    // Do other lexics
+    $comments = get_var('comments');
+    $comment_selector = str_replace(array('{PART1}', '{PART2}', '{PART3}'), array('.co1', '.co2', '.coMULTI'), $part_selector_3);
+    if ( $comments != '' )
+    {
+        $stylesheet .= "\n$comment_selector {{$comments}}";
+    }
+
+    $esc = get_var('escaped-chars');
+    $esc_selector = str_replace('{PART}', '.es0', $part_selector_1);
+    if ( $esc != '' )
+    {
+        $stylesheet .= "\n$esc_selector {{$esc}}";
+    }
+
+    $brackets = get_var('brackets');
+    $brk_selector = str_replace('{PART}', '.br0', $part_selector_1);
+    if ( $brackets != '' )
+    {
+        $stylesheet .= "\n$brk_selector {{$brackets}}";
+    }
+
+    $strings = get_var('strings');
+    $string_selector = str_replace('{PART}', '.st0', $part_selector_1);
+    if ( $strings != '' )
+    {
+        $stylesheet .= "\n$string_selector {{$strings}}";
+    }
+
+    $numbers = get_var('numbers');
+    $num_selector = str_replace('{PART}', '.nu0', $part_selector_1);
+    if ( $numbers != '' )
+    {
+        $stylesheet .= "\n$num_selector {{$numbers}}";
+    }
+
+    $methods = get_var('methods');
+    $method_selector = str_replace('{PART}', '.me0', $part_selector_1);
+    if ( $methods != '' )
+    {
+        $stylesheet .= "\n$method_selector {{$methods}}";
+    }
+
+    echo "<pre>$stylesheet</pre>";
+
+    make_footer();
+}
+
+?>
diff --git a/examples/includes/geshi/contrib/cssgen2.php b/examples/includes/geshi/contrib/cssgen2.php
new file mode 100644 (file)
index 0000000..cc3c39c
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/**
+ *  A simple script which outputs the CSS classes for all languages
+ *  supported by GeSHi. You can access it directly to download
+ *  the CSS file. On *NIX you can also do a simple `php cssgen.php > geshi.css`.
+ *
+ *   This file is part of GeSHi.
+ *
+ *  GeSHi is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GeSHi is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GeSHi; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @package    geshi
+ * @subpackage contrib
+ * @author     revulo <revulon@gmail.com>
+ * @copyright  2008 revulo
+ * @license    http://gnu.org/copyleft/gpl.html GNU GPL
+ *
+ */
+
+require dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'geshi.php';
+$geshi = new GeSHi;
+
+$languages = array();
+if ($handle = opendir($geshi->language_path)) {
+    while (($file = readdir($handle)) !== false) {
+        $pos = strpos($file, '.');
+        if ($pos > 0 && substr($file, $pos) == '.php') {
+            $languages[] = substr($file, 0, $pos);
+        }
+    }
+    closedir($handle);
+}
+sort($languages);
+
+header('Content-Type: application/octet-stream');
+header('Content-Disposition: attachment; filename="geshi.css"');
+
+echo "/**\n".
+     " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann\n" .
+     " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
+     " */\n";
+
+foreach ($languages as $language) {
+    $geshi->set_language($language);
+    // note: the false argument is required for stylesheet generators, see API documentation
+    $css = $geshi->get_stylesheet(false);
+    echo preg_replace('/^\/\*\*.*?\*\//s', '', $css);
+}
diff --git a/examples/includes/geshi/contrib/example.php b/examples/includes/geshi/contrib/example.php
new file mode 100644 (file)
index 0000000..32e6f0c
--- /dev/null
@@ -0,0 +1,217 @@
+<?php
+/**
+ * GeSHi example script
+ *
+ * Just point your browser at this script (with geshi.php in the parent directory,
+ * and the language files in subdirectory "../geshi/")
+ *
+ * @author  Nigel McNie
+ * @version $Id: example.php 1512 2008-07-21 21:05:40Z benbe $
+ */
+header('Content-Type: text/html; charset=utf-8');
+
+error_reporting(E_ALL);
+
+// Rudimentary checking of where GeSHi is. In a default install it will be in ../, but
+// it could be in the current directory if the include_path is set. There's nowhere else
+// we can reasonably guess.
+if (is_readable('../geshi.php')) {
+    $path = '../';
+} elseif (is_readable('geshi.php')) {
+    $path = './';
+} else {
+    die('Could not find geshi.php - make sure it is in your include path!');
+}
+require $path . 'geshi.php';
+
+$fill_source = false;
+if (isset($_POST['submit'])) {
+    if (get_magic_quotes_gpc()) {
+        $_POST['source'] = stripslashes($_POST['source']);
+    }
+    if (!strlen(trim($_POST['source']))) {
+        $_POST['language'] = preg_replace('#[^a-zA-Z0-9\-_]#', '', $_POST['language']);
+        $_POST['source'] = implode('', @file($path . 'geshi/' . $_POST['language'] . '.php'));
+        $_POST['language'] = 'php';
+    } else {
+        $fill_source = true;
+    }
+
+    // Here's a free demo of how GeSHi works.
+
+    // First the initialisation: source code to highlight and the language to use. Make sure
+    // you sanitise correctly if you use $_POST of course - this very script has had a security
+    // advisory against it in the past because of this. Please try not to use this script on a
+    // live site.
+    $geshi = new GeSHi($_POST['source'], $_POST['language']);
+
+    // Use the PRE_VALID header. This means less output source since we don't have to output &nbsp;
+    // everywhere. Of course it also means you can't set the tab width.
+    // HEADER_PRE_VALID puts the <pre> tag inside the list items (<li>) thus producing valid HTML markup.
+    // HEADER_PRE puts the <pre> tag around the list (<ol>) which is invalid in HTML 4 and XHTML 1
+    // HEADER_DIV puts a <div> tag arount the list (valid!) but needs to replace whitespaces with &nbsp
+    //            thus producing much larger overhead. You can set the tab width though.
+    $geshi->set_header_type(GESHI_HEADER_PRE_VALID);
+
+    // Enable CSS classes. You can use get_stylesheet() to output a stylesheet for your code. Using
+    // CSS classes results in much less output source.
+    $geshi->enable_classes();
+
+    // Enable line numbers. We want fancy line numbers, and we want every 5th line number to be fancy
+    $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 5);
+
+    // Set the style for the PRE around the code. The line numbers are contained within this box (not
+    // XHTML compliant btw, but if you are liberally minded about these things then you'll appreciate
+    // the reduced source output).
+    $geshi->set_overall_style('font: normal normal 90% monospace; color: #000066; border: 1px solid #d0d0d0; background-color: #f0f0f0;', false);
+
+    // Set the style for line numbers. In order to get style for line numbers working, the <li> element
+    // is being styled. This means that the code on the line will also be styled, and most of the time
+    // you don't want this. So the set_code_style reverts styles for the line (by using a <div> on the line).
+    // So the source output looks like this:
+    //
+    // <pre style="[set_overall_style styles]"><ol>
+    // <li style="[set_line_style styles]"><div style="[set_code_style styles]>...</div></li>
+    // ...
+    // </ol></pre>
+    $geshi->set_line_style('color: #003030;', 'font-weight: bold; color: #006060;', true);
+    $geshi->set_code_style('color: #000020;', true);
+
+    // Styles for hyperlinks in the code. GESHI_LINK for default styles, GESHI_HOVER for hover style etc...
+    // note that classes must be enabled for this to work.
+    $geshi->set_link_styles(GESHI_LINK, 'color: #000060;');
+    $geshi->set_link_styles(GESHI_HOVER, 'background-color: #f0f000;');
+
+    // Use the header/footer functionality. This puts a div with content within the PRE element, so it is
+    // affected by the styles set by set_overall_style. So if the PRE has a border then the header/footer will
+    // appear inside it.
+    $geshi->set_header_content('<SPEED> <TIME> GeSHi &copy; 2004-2007, Nigel McNie, 2007-2008 Benny Baumann. View source of example.php for example of using GeSHi');
+    $geshi->set_header_content_style('font-family: sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;');
+
+    // You can use <TIME> and <VERSION> as placeholders
+    $geshi->set_footer_content('Parsed in <TIME> seconds at <SPEED>, using GeSHi <VERSION>');
+    $geshi->set_footer_content_style('font-family: sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;');
+} else {
+    // make sure we don't preselect any language
+    $_POST['language'] = null;
+}
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>GeSHi examples</title>
+    <style type="text/css">
+    <!--
+    <?php
+    if (isset($_POST['submit'])) {
+        // Output the stylesheet. Note it doesn't output the <style> tag
+        echo $geshi->get_stylesheet(true);
+    }
+    ?>
+    html {
+        background-color: #f0f0f0;
+    }
+    body {
+        font-family: Verdana, Arial, sans-serif;
+        margin: 10px;
+        border: 2px solid #e0e0e0;
+        background-color: #fcfcfc;
+        padding: 5px;
+    }
+    h2 {
+        margin: .1em 0 .2em .5em;
+        border-bottom: 1px solid #b0b0b0;
+        color: #b0b0b0;
+        font-weight: normal;
+        font-size: 150%;
+    }
+    h3 {
+        margin: .1em 0 .2em .5em;
+        color: #b0b0b0;
+        font-weight: normal;
+        font-size: 120%;
+    }
+    #footer {
+        text-align: center;
+        font-size: 80%;
+        color: #a9a9a9;
+    }
+    #footer a {
+        color: #9999ff;
+    }
+    textarea {
+        border: 1px solid #b0b0b0;
+        font-size: 90%;
+        color: #333;
+        margin-left: 20px;
+    }
+    select, input {
+        margin-left: 20px;
+    }
+    p {
+        font-size: 90%;
+        margin-left: .5em;
+    }
+    -->
+    </style>
+</head>
+<body>
+<h2>GeSHi Example Script</h2>
+<p>To use this script, make sure that <strong>geshi.php</strong> is in the parent directory or in your
+include_path, and that the language files are in a subdirectory of GeSHi's directory called <strong>geshi/</strong>.</p>
+<p>Enter your source and a language to highlight the source in and submit, or just choose a language to
+have that language file highlighted in PHP.</p>
+<?php
+if (isset($_POST['submit'])) {
+    // The fun part :)
+    echo $geshi->parse_code();
+    echo '<hr />';
+}
+?>
+<form action="<?php echo basename($_SERVER['PHP_SELF']); ?>" method="post">
+<h3>Source to highlight</h3>
+<p>
+<textarea rows="10" cols="60" name="source" id="source"><?php echo $fill_source ? htmlspecialchars($_POST['source']) : '' ?></textarea>
+</p>
+<h3>Choose a language</h3>
+<p>
+<select name="language" id="language">
+<?php
+if (!($dir = @opendir(dirname(__FILE__) . '/geshi'))) {
+    if (!($dir = @opendir(dirname(__FILE__) . '/../geshi'))) {
+        echo '<option>No languages available!</option>';
+    }
+}
+$languages = array();
+while ($file = readdir($dir)) {
+    if ( $file[0] == '.' || strpos($file, '.', 1) === false) {
+        continue;
+    }
+    $lang = substr($file, 0,  strpos($file, '.'));
+    $languages[] = $lang;
+}
+closedir($dir);
+sort($languages);
+foreach ($languages as $lang) {
+    if (isset($_POST['language']) && $_POST['language'] == $lang) {
+        $selected = 'selected="selected"';
+    } else {
+        $selected = '';
+    }
+    echo '<option value="' . $lang . '" '. $selected .'>' . $lang . "</option>\n";
+}
+
+?>
+</select>
+</p>
+<p>
+<input type="submit" name="submit" value="Highlight Source" />
+<input type="submit" name="clear" onclick="document.getElementById('source').value='';document.getElementById('language').value='';return false" value="clear" />
+</p>
+</form>
+<div id="footer">GeSHi &copy; Nigel McNie, 2004, released under the GNU GPL<br />
+For a better demonstration, check out the <a href="http://qbnz.com/highlighter/demo.php">online demo</a>
+</div>
+</body>
+</html>
diff --git a/examples/includes/geshi/contrib/langcheck.php b/examples/includes/geshi/contrib/langcheck.php
new file mode 100644 (file)
index 0000000..0a2ca32
--- /dev/null
@@ -0,0 +1,666 @@
+<?php
+/**
+ * GeSHi example script
+ *
+ * Just point your browser at this script (with geshi.php in the parent directory,
+ * and the language files in subdirectory "../geshi/")
+ *
+ * @author  Nigel McNie
+ * @version $Id: langcheck.php 1971 2008-12-25 15:14:14Z benbe $
+ */
+header('Content-Type: text/html; charset=utf-8');
+
+set_time_limit(0);
+error_reporting(E_ALL);
+$time_start = explode(' ', microtime());
+
+define ('TYPE_NOTICE', 0);
+define ('TYPE_WARNING', 1);
+define ('TYPE_ERROR', 2);
+
+$error_abort = false;
+$error_cache = array();
+function output_error_cache(){
+    global $error_cache, $error_abort;
+
+    if(count($error_cache)) {
+        echo "<span style=\"color: #F00; font-weight: bold;\">Failed</span><br />";
+        echo "<ol>\n";
+        foreach($error_cache as $error_msg) {
+            echo "<li>";
+            switch($error_msg['t']) {
+                case TYPE_NOTICE:
+                    echo "<span style=\"color: #080; font-weight: bold;\">NOTICE:</span>";
+                    break;
+                case TYPE_WARNING:
+                    echo "<span style=\"color: #CC0; font-weight: bold;\">WARNING:</span>";
+                    break;
+                case TYPE_ERROR:
+                    echo "<span style=\"color: #F00; font-weight: bold;\">ERROR:</span>";
+                    break;
+            }
+            echo " " . $error_msg['m'] . "</li>";
+        }
+        echo "</ol>\n";
+    } else {
+        echo "<span style=\"color: #080; font-weight: bold;\">OK</span><br />";
+    }
+    echo "\n";
+
+    $error_cache = array();
+}
+
+function report_error($type, $message) {
+    global $error_cache, $error_abort;
+
+    $error_cache[] = array('t' => $type, 'm' => $message);
+    if(TYPE_ERROR == $type) {
+        $error_abort = true;
+    }
+}
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>GeSHi Language File Validation Script</title>
+    <style type="text/css">
+    <!--
+    html {
+        background-color: #f0f0f0;
+    }
+    body {
+        font-family: Verdana, Arial, sans-serif;
+        margin: 10px;
+        border: 2px solid #e0e0e0;
+        background-color: #fcfcfc;
+        padding: 5px;
+        font-size: 10pt;
+    }
+    h2 {
+        margin: .1em 0 .2em .5em;
+        border-bottom: 1px solid #b0b0b0;
+        color: #b0b0b0;
+        font-weight: normal;
+        font-size: 150%;
+    }
+    h3 {
+        margin: .1em 0 .2em .5em;
+        color: #b0b0b0;
+        font-weight: normal;
+        font-size: 120%;
+    }
+    #footer {
+        text-align: center;
+        font-size: 80%;
+        color: #a9a9a9;
+    }
+    #footer a {
+        color: #9999ff;
+    }
+    textarea {
+        border: 1px solid #b0b0b0;
+        font-size: 90%;
+        color: #333;
+        margin-left: 20px;
+    }
+    select, input {
+        margin-left: 20px;
+    }
+    p {
+        font-size: 90%;
+        margin-left: .5em;
+    }
+    -->
+    </style>
+</head>
+<body>
+<h2>GeSHi Language File Validation Script</h2>
+<p>To use this script, make sure that <strong>geshi.php</strong> is in the
+parent directory or in your include_path, and that the language files are in a
+subdirectory of GeSHi's directory called <strong>geshi/</strong>.</p>
+<p>Everything else will be done by this script automatically. After the script
+finished you should see messages of what could cause trouble with GeSHi or where
+your language files can be improved. Please be patient, as this might take some time.</p>
+
+<ol>
+<li>Checking where to find GeSHi installation ... <?php
+// Rudimentary checking of where GeSHi is. In a default install it will be in ../, but
+// it could be in the current directory if the include_path is set. There's nowhere else
+// we can reasonably guess.
+if (is_readable('../geshi.php')) {
+    $path = '../';
+} elseif (is_readable('geshi.php')) {
+    $path = './';
+} else {
+    report_error(TYPE_ERROR, 'Could not find geshi.php - make sure it is in your include path!');
+}
+
+if(!$error_abort) {
+    require $path . 'geshi.php';
+
+    if(!class_exists('GeSHi')) {
+        report_error(TYPE_ERROR, 'The GeSHi class was not found, although it seemed we loaded the correct file!');
+    }
+}
+
+if(!$error_abort) {
+    if(!defined('GESHI_LANG_ROOT')) {
+        report_error(TYPE_ERROR, 'There\'s no information present on where to find the language files!');
+    } else if(!is_dir(GESHI_LANG_ROOT)) {
+        report_error(TYPE_ERROR, 'The path "'.GESHI_LANG_ROOT.'" given, does not ressemble a directory!');
+    } else if(!is_readable(GESHI_LANG_ROOT)) {
+        report_error(TYPE_ERROR, 'The path "'.GESHI_LANG_ROOT.'" is not readable to this script!');
+    }
+}
+
+output_error_cache();
+
+if(!$error_abort) {
+    echo "</li>\n<li>Listing available language files ... ";
+
+    if (!($dir = @opendir(GESHI_LANG_ROOT))) {
+        report_error(TYPE_ERROR, 'Error requesting listing for available language files!');
+    }
+
+    $languages = array();
+
+    if(!$error_abort) {
+        while ($file = readdir($dir)) {
+            if (!$file || $file[0] == '.' || strpos($file, '.') === false) {
+                continue;
+            }
+            $lang = substr($file, 0,  strpos($file, '.'));
+            $languages[] = $lang;
+        }
+        closedir($dir);
+    }
+
+    $languages = array_unique($languages);
+    sort($languages);
+
+    if(!count($languages)) {
+        report_error(TYPE_WARNING, 'Unable to locate any usable language files in "'.GESHI_LANG_ROOT.'"!');
+    }
+
+    output_error_cache();
+}
+
+if (isset($_REQUEST['show']) && in_array($_REQUEST['show'], $languages)) {
+    $languages = array($_REQUEST['show']);
+}
+
+if(!$error_abort) {
+    foreach ($languages as $lang) {
+        echo "</li>\n<li>Validating language file for '$lang' ... ";
+
+        $langfile = GESHI_LANG_ROOT . $lang . '.php';
+
+        unset($language_data);
+
+        if(!is_file($langfile)) {
+            report_error(TYPE_ERROR, 'The path "' .$langfile. '" does not ressemble a regular file!');
+        } else if(!is_readable($langfile)) {
+            report_error(TYPE_ERROR, 'Cannot read file "' .$langfile. '"!');
+        } else {
+            $langfile_content = file_get_contents($langfile);
+            if(preg_match("/\?>(?:\r?\n|\r(?!\n)){2,}\Z/", $langfile_content)) {
+                report_error(TYPE_ERROR, 'Language file contains trailing empty lines at EOF!');
+            }
+            if(!preg_match("/\?>(?:\r?\n|\r(?!\n))?\Z/", $langfile_content)) {
+                report_error(TYPE_ERROR, 'Language file contains no PHP end marker at EOF!');
+            }
+            if(preg_match("/\t/", $langfile_content)) {
+                report_error(TYPE_NOTICE, 'Language file contains unescaped tabulator chars (probably for indentation)!');
+            }
+            if(preg_match('/^(?:    )*(?!    )(?! \*) /m', $langfile_content)) {
+                report_error(TYPE_NOTICE, 'Language file contains irregular indentation (other than 4 spaces per indentation level)!');
+            }
+
+            if(!preg_match("/\/\*\*((?!\*\/).)*?Author:((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not contain a specification of an author!');
+            }
+            if(!preg_match("/\/\*\*((?!\*\/).)*?Copyright:((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not contain a specification of the copyright!');
+            }
+            if(!preg_match("/\/\*\*((?!\*\/).)*?Release Version:((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not contain a specification of the release version!');
+            }
+            if(!preg_match("/\/\*\*((?!\*\/).)*?Date Started:((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not contain a specification of the date it was started!');
+            }
+            if(!preg_match("/\/\*\*((?!\*\/).)*?This file is part of GeSHi\.((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not state that it belongs to GeSHi!');
+            }
+            if(!preg_match("/\/\*\*((?!\*\/).)*?language file for GeSHi\.((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not state that it is a language file for GeSHi!');
+            }
+            if(!preg_match("/\/\*\*((?!\*\/).)*?GNU General Public License((?!\*\/).)*?\*\//s", $langfile_content)) {
+                report_error(TYPE_WARNING, 'Language file does not state that it is provided under the terms of the GNU GPL!');
+            }
+
+            unset($langfile_content);
+
+            include $langfile;
+
+            if(!isset($language_data)) {
+                report_error(TYPE_ERROR, 'Language file does not contain a $language_data structure to check!');
+            } else if (!is_array($language_data)) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data structure which is not an array!');
+            }
+        }
+
+        if(!$error_abort) {
+            if(!isset($language_data['LANG_NAME'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'LANG_NAME\'] specification!');
+            } else if (!is_string($language_data['LANG_NAME'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'LANG_NAME\'] specification which is not a string!');
+            }
+
+            if(!isset($language_data['COMMENT_SINGLE'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'COMMENT_SIGNLE\'] structure to check!');
+            } else if (!is_array($language_data['COMMENT_SINGLE'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_SINGLE\'] structure which is not an array!');
+            }
+
+            if(!isset($language_data['COMMENT_MULTI'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'COMMENT_MULTI\'] structure to check!');
+            } else if (!is_array($language_data['COMMENT_MULTI'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_MULTI\'] structure which is not an array!');
+            }
+
+            if(isset($language_data['COMMENT_REGEXP'])) {
+                if (!is_array($language_data['COMMENT_REGEXP'])) {
+                    report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_REGEXP\'] structure which is not an array!');
+                }
+            }
+
+            if(!isset($language_data['QUOTEMARKS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'QUOTEMARKS\'] structure to check!');
+            } else if (!is_array($language_data['QUOTEMARKS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'QUOTEMARKS\'] structure which is not an array!');
+            }
+
+            if(isset($language_data['HARDQUOTE'])) {
+                if (!is_array($language_data['HARDQUOTE'])) {
+                    report_error(TYPE_ERROR, 'Language file contains a $language_data[\'HARDQUOTE\'] structure which is not an array!');
+                }
+            }
+
+            if(!isset($language_data['ESCAPE_CHAR'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'ESCAPE_CHAR\'] specification to check!');
+            } else if (!is_string($language_data['ESCAPE_CHAR'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'ESCAPE_CHAR\'] specification which is not a string!');
+            } else if (1 < strlen($language_data['ESCAPE_CHAR'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'ESCAPE_CHAR\'] specification is not empty or exactly one char!');
+            }
+
+            if(!isset($language_data['CASE_KEYWORDS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'CASE_KEYWORDS\'] specification!');
+            } else if (!is_int($language_data['CASE_KEYWORDS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_KEYWORDS\'] specification which is not an integer!');
+            } else if (GESHI_CAPS_NO_CHANGE != $language_data['CASE_KEYWORDS'] &&
+                GESHI_CAPS_LOWER != $language_data['CASE_KEYWORDS'] &&
+                GESHI_CAPS_UPPER != $language_data['CASE_KEYWORDS']) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_KEYWORDS\'] specification which is neither of GESHI_CAPS_NO_CHANGE, GESHI_CAPS_LOWER nor GESHI_CAPS_UPPER!');
+            }
+
+            if(!isset($language_data['KEYWORDS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'KEYWORDS\'] structure to check!');
+            } else if (!is_array($language_data['KEYWORDS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'KEYWORDS\'] structure which is not an array!');
+            } else {
+                foreach($language_data['KEYWORDS'] as $kw_key => $kw_value) {
+                    if(!is_integer($kw_key)) {
+                        report_error(TYPE_WARNING, "Language file contains an key '$kw_key' in \$language_data['KEYWORDS'] that is not integer!");
+                    } else if (!is_array($kw_value)) {
+                        report_error(TYPE_ERROR, "Language file contains a \$language_data['CASE_SENSITIVE']['$kw_value'] structure which is not an array!");
+                    }
+                }
+            }
+
+            if(!isset($language_data['SYMBOLS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'SYMBOLS\'] structure to check!');
+            } else if (!is_array($language_data['SYMBOLS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'SYMBOLS\'] structure which is not an array!');
+            }
+
+            if(!isset($language_data['CASE_SENSITIVE'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'CASE_SENSITIVE\'] structure to check!');
+            } else if (!is_array($language_data['CASE_SENSITIVE'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_SENSITIVE\'] structure which is not an array!');
+            } else {
+                foreach($language_data['CASE_SENSITIVE'] as $cs_key => $cs_value) {
+                    if(!is_integer($cs_key)) {
+                        report_error(TYPE_WARNING, "Language file contains an key '$cs_key' in \$language_data['CASE_SENSITIVE'] that is not integer!");
+                    } else if (!is_bool($cs_value)) {
+                        report_error(TYPE_ERROR, "Language file contains a Case Sensitivity specification for \$language_data['CASE_SENSITIVE']['$cs_value'] which is not a boolean!");
+                    }
+                }
+            }
+
+            if(!isset($language_data['URLS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'URLS\'] structure to check!');
+            } else if (!is_array($language_data['URLS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'URLS\'] structure which is not an array!');
+            } else {
+                foreach($language_data['URLS'] as $url_key => $url_value) {
+                    if(!is_integer($url_key)) {
+                        report_error(TYPE_WARNING, "Language file contains an key '$url_key' in \$language_data['URLS'] that is not integer!");
+                    } else if (!is_string($url_value)) {
+                        report_error(TYPE_ERROR, "Language file contains a Documentation URL specification for \$language_data['URLS']['$url_value'] which is not a string!");
+                    } else if (preg_match('#&([^;]*(=|$))#U', $url_value)) {
+                        report_error(TYPE_ERROR, "Language file contains unescaped ampersands (&amp;) in \$language_data['URLS']!");
+                    }
+                }
+            }
+
+            if(!isset($language_data['OOLANG'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'OOLANG\'] specification!');
+            } else if (!is_int($language_data['OOLANG']) && !is_bool($language_data['OOLANG'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OOLANG\'] specification which is neither boolean nor integer!');
+            } else if (false !== $language_data['OOLANG'] &&
+                true !== $language_data['OOLANG'] &&
+                2 !== $language_data['OOLANG']) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OOLANG\'] specification which is neither of false, true or 2!');
+            }
+
+            if(!isset($language_data['OBJECT_SPLITTERS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'OBJECT_SPLITTERS\'] structure to check!');
+            } else if (!is_array($language_data['OBJECT_SPLITTERS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OBJECT_SPLITTERS\'] structure which is not an array!');
+            }
+
+            if(!isset($language_data['REGEXPS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'REGEXPS\'] structure to check!');
+            } else if (!is_array($language_data['REGEXPS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'REGEXPS\'] structure which is not an array!');
+            }
+
+            if(!isset($language_data['STRICT_MODE_APPLIES'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'STRICT_MODE_APPLIES\'] specification!');
+            } else if (!is_int($language_data['STRICT_MODE_APPLIES'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STRICT_MODE_APPLIES\'] specification which is not an integer!');
+            } else if (GESHI_MAYBE != $language_data['STRICT_MODE_APPLIES'] &&
+                GESHI_ALWAYS != $language_data['STRICT_MODE_APPLIES'] &&
+                GESHI_NEVER != $language_data['STRICT_MODE_APPLIES']) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STRICT_MODE_APPLIES\'] specification which is neither of GESHI_MAYBE, GESHI_ALWAYS nor GESHI_NEVER!');
+            }
+
+            if(!isset($language_data['SCRIPT_DELIMITERS'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'SCRIPT_DELIMITERS\'] structure to check!');
+            } else if (!is_array($language_data['SCRIPT_DELIMITERS'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'SCRIPT_DELIMITERS\'] structure which is not an array!');
+            }
+
+            if(!isset($language_data['HIGHLIGHT_STRICT_BLOCK'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'HIGHLIGHT_STRICT_BLOCK\'] structure to check!');
+            } else if (!is_array($language_data['HIGHLIGHT_STRICT_BLOCK'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'HIGHLIGHT_STRICT_BLOCK\'] structure which is not an array!');
+            }
+
+            if(isset($language_data['TAB_WIDTH'])) {
+                if (!is_int($language_data['TAB_WIDTH'])) {
+                    report_error(TYPE_ERROR, 'Language file contains a $language_data[\'TAB_WIDTH\'] specification which is not an integer!');
+                } else if (1 > $language_data['TAB_WIDTH']) {
+                    report_error(TYPE_ERROR, 'Language file contains a $language_data[\'TAB_WIDTH\'] specification which is less than 1!');
+                }
+            }
+
+            if(isset($language_data['PARSER_CONTROL'])) {
+                if (!is_array($language_data['PARSER_CONTROL'])) {
+                    report_error(TYPE_ERROR, 'Language file contains a $language_data[\'PARSER_CONTROL\'] structure which is not an array!');
+                }
+            }
+
+            if(!isset($language_data['STYLES'])) {
+                report_error(TYPE_ERROR, 'Language file contains no $language_data[\'STYLES\'] structure to check!');
+            } else if (!is_array($language_data['STYLES'])) {
+                report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STYLES\'] structure which is not an array!');
+            } else {
+                $style_arrays = array('KEYWORDS', 'COMMENTS', 'ESCAPE_CHAR',
+                    'BRACKETS', 'STRINGS', 'NUMBERS', 'METHODS', 'SYMBOLS',
+                    'REGEXPS', 'SCRIPT');
+                foreach($style_arrays as $style_kind) {
+                    if(!isset($language_data['STYLES'][$style_kind])) {
+                        report_error(TYPE_ERROR, "Language file contains no \$language_data['STYLES']['$style_kind'] structure to check!");
+                    } else if (!is_array($language_data['STYLES'][$style_kind])) {
+                        report_error(TYPE_ERROR, "Language file contains a \$language_data['STYLES\']['$style_kind'] structure which is not an array!");
+                    } else {
+                        foreach($language_data['STYLES'][$style_kind] as $sk_key => $sk_value) {
+                            if(!is_int($sk_key) && ('COMMENTS' != $style_kind && 'MULTI' != $sk_key)
+                                && !(('STRINGS' == $style_kind || 'ESCAPE_CHAR' == $style_kind) && 'HARD' == $sk_key)) {
+                                report_error(TYPE_WARNING, "Language file contains an key '$sk_key' in \$language_data['STYLES']['$style_kind'] that is not integer!");
+                            } else if (!is_string($sk_value)) {
+                                report_error(TYPE_WARNING, "Language file contains a CSS specification for \$language_data['STYLES']['$style_kind'][$key] which is not a string!");
+                            }
+                        }
+                    }
+                }
+
+                unset($style_arrays);
+            }
+        }
+
+        if(!$error_abort) {
+            //Initial sanity checks survived? --> Let's dig deeper!
+            foreach($language_data['KEYWORDS'] as $key => $keywords) {
+                if(!isset($language_data['CASE_SENSITIVE'][$key])) {
+                    report_error(TYPE_ERROR, "Language file contains no \$language_data['CASE_SENSITIVE'] specification for keyword group $key!");
+                }
+                if(!isset($language_data['URLS'][$key])) {
+                    report_error(TYPE_ERROR, "Language file contains no \$language_data['URLS'] specification for keyword group $key!");
+                }
+                if(empty($keywords)) {
+                    report_error(TYPE_WARNING, "Language file contains an empty keyword list in \$language_data['KEYWORDS'] for group $key!");
+                }
+                foreach($keywords as $id => $kw) {
+                    if(!is_string($kw)) {
+                        report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['KEYWORDS'][$key][$id]!");
+                    } else if (!strlen($kw)) {
+                        report_error(TYPE_ERROR, "Language file contains an empty string entry at \$language_data['KEYWORDS'][$key][$id]!");
+                    } else if (preg_match('/^([\(\)\{\}\[\]\^=.,:;\-+\*\/%\$\"\'\?]|&[\w#]\w*;)+$/i', $kw)) {
+                        report_error(TYPE_NOTICE, "Language file contains an keyword ('$kw') at \$language_data['KEYWORDS'][$key][$id] which seems to be better suited for the symbols section!");
+                    }
+                }
+                if(count($keywords) != count(array_unique($keywords))) {
+                    $kw_diffs = array_count_values($keywords);
+                    foreach($kw_diffs as $kw => $kw_count) {
+                        if($kw_count > 1) {
+                            report_error(TYPE_WARNING, "Language file contains per-group duplicate keyword '$kw' in \$language_data['KEYWORDS'][$key]!");
+                        }
+                    }
+                }
+            }
+
+            $disallowed_before = "(?<![a-zA-Z0-9\$_\|\#;>|^&";
+            $disallowed_after = "(?![a-zA-Z0-9_\|%\\-&;";
+
+            foreach($language_data['KEYWORDS'] as $key => $keywords) {
+                foreach($language_data['KEYWORDS'] as $key2 => $keywords2) {
+                    if($key2 <= $key) {
+                        continue;
+                    }
+                    $kw_diffs = array_intersect($keywords, $keywords2);
+                    foreach($kw_diffs as $kw) {
+                        if(isset($language_data['PARSER_CONTROL']['KEYWORDS'])) {
+                            //Check the precondition\post-cindition for the involved keyword groups
+                            $g1_pre = $disallowed_before;
+                            $g2_pre = $disallowed_before;
+                            $g1_post = $disallowed_after;
+                            $g2_post = $disallowed_after;
+                            if(isset($language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'])) {
+                                $g1_pre = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
+                                $g2_pre = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
+                            }
+                            if(isset($language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'])) {
+                                $g1_post = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
+                                $g2_post = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
+                            }
+
+                            if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_BEFORE'])) {
+                                $g1_pre = $language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_BEFORE'];
+                            }
+                            if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_AFTER'])) {
+                                $g1_post = $language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_AFTER'];
+                            }
+
+                            if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_BEFORE'])) {
+                                $g2_pre = $language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_BEFORE'];
+                            }
+                            if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_AFTER'])) {
+                                $g2_post = $language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_AFTER'];
+                            }
+
+                            if($g1_pre != $g2_pre || $g1_post != $g2_post) {
+                                continue;
+                            }
+                        }
+                        report_error(TYPE_WARNING, "Language file contains cross-group duplicate keyword '$kw' in \$language_data['KEYWORDS'][$key] and \$language_data['KEYWORDS'][$key2]!");
+                    }
+                }
+            }
+            foreach($language_data['CASE_SENSITIVE'] as $key => $keywords) {
+                if(!isset($language_data['KEYWORDS'][$key]) && $key != GESHI_COMMENTS) {
+                    report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['CASE_SENSITIVE'] specification for non-existing keyword group $key!");
+                }
+            }
+            foreach($language_data['URLS'] as $key => $keywords) {
+                if(!isset($language_data['KEYWORDS'][$key])) {
+                    report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['URLS'] specification for non-existing keyword group $key!");
+                }
+            }
+            foreach($language_data['STYLES']['KEYWORDS'] as $key => $keywords) {
+                if(!isset($language_data['KEYWORDS'][$key])) {
+                    report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['STYLES']['KEYWORDS'] specification for non-existing keyword group $key!");
+                }
+            }
+
+            foreach($language_data['COMMENT_SINGLE'] as $ck => $cv) {
+                if(!is_int($ck)) {
+                    report_error(TYPE_WARNING, "Language file contains an key '$ck' in \$language_data['COMMENT_SINGLE'] that is not integer!");
+                }
+                if(!is_string($cv)) {
+                    report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['COMMENT_SINGLE'][$ck]!");
+                }
+                if(!isset($language_data['STYLES']['COMMENTS'][$ck])) {
+                    report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['COMMENTS'] specification for comment group $ck!");
+                }
+            }
+            if(isset($language_data['COMMENT_REGEXP'])) {
+                foreach($language_data['COMMENT_REGEXP'] as $ck => $cv) {
+                    if(!is_int($ck)) {
+                        report_error(TYPE_WARNING, "Language file contains an key '$ck' in \$language_data['COMMENT_REGEXP'] that is not integer!");
+                    }
+                    if(!is_string($cv)) {
+                        report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['COMMENT_REGEXP'][$ck]!");
+                    }
+                    if(!isset($language_data['STYLES']['COMMENTS'][$ck])) {
+                        report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['COMMENTS'] specification for comment group $ck!");
+                    }
+                }
+            }
+            foreach($language_data['STYLES']['COMMENTS'] as $ck => $cv) {
+                if($ck != 'MULTI' && !isset($language_data['COMMENT_SINGLE'][$ck]) &&
+                    !isset($language_data['COMMENT_REGEXP'][$ck])) {
+                    report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['COMMENTS'] specification for Single Line or Regular-Expression Comment key $ck!");
+                }
+            }
+            if (isset($language_data['STYLES']['STRINGS']['HARD'])) {
+                if (empty($language_data['HARDQUOTE'])) {
+                    report_error(TYPE_NOTICE, "Language file contains superfluous \$language_data['STYLES']['STRINGS'] specification for key 'HARD', but no 'HARDQUOTE's are defined!");
+                }
+                unset($language_data['STYLES']['STRINGS']['HARD']);
+            }
+            foreach($language_data['STYLES']['STRINGS'] as $sk => $sv) {
+                if($sk && !isset($language_data['QUOTEMARKS'][$sk])) {
+                    report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['STRINGS'] specification for non-existing quotemark key $sk!");
+                }
+            }
+
+            foreach($language_data['REGEXPS'] as $rk => $rv) {
+                if(!is_int($rk)) {
+                    report_error(TYPE_WARNING, "Language file contains an key '$rk' in \$language_data['REGEXPS'] that is not integer!");
+                }
+                if(is_string($rv)) {
+                    //Check for unmasked / in regular expressions ...
+                    if(empty($rv)) {
+                        report_error(TYPE_WARNING, "Language file contains an empty regular expression at \$language_data['REGEXPS'][$rk]!");
+                    } else {
+                        if(preg_match("/(?<!\\\\)\//s", $rv)) {
+                            report_error(TYPE_WARNING, "Language file contains a regular expression with an unmasked / character at \$language_data['REGEXPS'][$rk]!");
+                        } elseif (preg_match("/(?<!<)(\\\\\\\\)*\\\\\|(?!>)/s", $rv)) {
+                            report_error(TYPE_WARNING, "Language file contains a regular expression with an unescaped match for a pipe character '|' which needs escaping as '&lt;PIPE&gt;' instead at \$language_data['REGEXPS'][$rk]!");
+                        }
+                    }
+                } elseif(is_array($rv)) {
+                    if(!isset($rv[GESHI_SEARCH])) {
+                        report_error(TYPE_ERROR, "Language file contains no GESHI_SEARCH entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+                    } elseif(!is_string($rv[GESHI_SEARCH])) {
+                        report_error(TYPE_ERROR, "Language file contains a GESHI_SEARCH entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+                    } else {
+                        if(preg_match("/(?<!\\\\)\//s", $rv[GESHI_SEARCH])) {
+                            report_error(TYPE_WARNING, "Language file contains a regular expression with an unmasked / character at \$language_data['REGEXPS'][$rk]!");
+                        } elseif (preg_match("/(?<!<)(\\\\\\\\)*\\\\\|(?!>)/s", $rv[GESHI_SEARCH])) {
+                            report_error(TYPE_WARNING, "Language file contains a regular expression with an unescaped match for a pipe character '|' which needs escaping as '&lt;PIPE&gt;' instead at \$language_data['REGEXPS'][$rk]!");
+                        }
+                    }
+                    if(!isset($rv[GESHI_REPLACE])) {
+                        report_error(TYPE_WARNING, "Language file contains no GESHI_REPLACE entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+                    } elseif(!is_string($rv[GESHI_REPLACE])) {
+                        report_error(TYPE_ERROR, "Language file contains a GESHI_REPLACE entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+                    }
+                    if(!isset($rv[GESHI_MODIFIERS])) {
+                        report_error(TYPE_WARNING, "Language file contains no GESHI_MODIFIERS entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+                    } elseif(!is_string($rv[GESHI_MODIFIERS])) {
+                        report_error(TYPE_ERROR, "Language file contains a GESHI_MODIFIERS entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+                    }
+                    if(!isset($rv[GESHI_BEFORE])) {
+                        report_error(TYPE_WARNING, "Language file contains no GESHI_BEFORE entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+                    } elseif(!is_string($rv[GESHI_BEFORE])) {
+                        report_error(TYPE_ERROR, "Language file contains a GESHI_BEFORE entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+                    }
+                    if(!isset($rv[GESHI_AFTER])) {
+                        report_error(TYPE_WARNING, "Language file contains no GESHI_AFTER entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+                    } elseif(!is_string($rv[GESHI_AFTER])) {
+                        report_error(TYPE_ERROR, "Language file contains a GESHI_AFTER entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+                    }
+                } else {
+                    report_error(TYPE_WARNING, "Language file contains an non-string and non-array entry at \$language_data['REGEXPS'][$rk]!");
+                }
+                if(!isset($language_data['STYLES']['REGEXPS'][$rk])) {
+                    report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['REGEXPS'] specification for regexp group $rk!");
+                }
+            }
+            foreach($language_data['STYLES']['REGEXPS'] as $rk => $rv) {
+                if(!isset($language_data['REGEXPS'][$rk])) {
+                    report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['REGEXPS'] specification for regexp key $rk!");
+                }
+            }
+
+
+        }
+
+        output_error_cache();
+
+        flush();
+
+        if($error_abort) {
+            break;
+        }
+    }
+}
+?></li>
+</ol>
+
+<p>Validation process completed in <?
+$time_end = explode(' ', microtime());
+$time_diff = $time_end[0] + $time_end[1] - $time_start[0] - $time_start[1];
+
+echo sprintf("%.2f", $time_diff);
+?> seconds.</p>
+
+<div id="footer">GeSHi &copy; 2004-2007 Nigel McNie, 2007-2008 Benny Baumann, released under the GNU GPL</div>
+</body>
+</html>
diff --git a/examples/includes/geshi/docs/BUGS b/examples/includes/geshi/docs/BUGS
new file mode 100644 (file)
index 0000000..8a5cf04
--- /dev/null
@@ -0,0 +1,29 @@
+
+                      BUGS - list of known bugs in GeSHi
+                                Version 1.0.8
+
+- Number highlighting is quite poor [possibly better now]
+- I'm not happy with URLS - there still could be extra bugs, and it's rather unflexible
+  (see TODO for a possible fix)
+- "Important" sections for some reason seem to have their spans added after every
+  newline up until the next lexic, instead of stopping at the <END GeSHi> part. In fact,
+  context sensitiveness is quite poor...
+- Using the extra line number highlighting feature without actually using line numbers
+  will result in malformed XHTML (not sure about this one though...)
+- Slow!!! Especially for source with lots of strings in it. GeSHi will work acceptably
+  for sourcecode under 5K (for simple language files like SQL, a 100K file can be
+  highlighted in just 6 seconds), but above about 25K things get a little slow... If
+  you're using this as part of some larger software, you may want to think about
+  making some sort of "cache" effect to speed things up and reduce server load.
+- The result is built by string replacement instead of by building another string based
+  on the source, that would be much safer. The focus of releases beyond 1.0.7 will be on
+  changing this behaviour, which may well fix some of the other bugs mentioned above.
+- As of 1.0.7.1, dots (.) are allowed before keywords. This may change highlighting of some
+  things slightly, if you notice anything odd about the highlighting then please report
+  it to me.
+- Perl/Javascript /.../ regex syntax is only supported basically and there's no
+  guarantee it is working all the time.
+- The <pre> header output is not XHTML compliant. Please use the <div> header instead.
+
+Send any bug reports to BenBE@omorphia.de, or submit them via the bug tracker at
+sourceforge (http://sourceforge.net/tracker/?group_id=114997&atid=670231)
diff --git a/examples/includes/geshi/docs/CHANGES b/examples/includes/geshi/docs/CHANGES
new file mode 100644 (file)
index 0000000..d64c4e5
--- /dev/null
@@ -0,0 +1,682 @@
+
+              CHANGES - Changelog for GeSHi (geshi.php only)
+
+Changes to the code are listed under the version they occured in, with who suggested
+it by each one (if there's nobody listed as suggesting it I dreamed it up :)). Users
+who suggested an idea often also provided the code that was used as a basis for the
+changes - thanks to all who suggested these ideas and gave me the code to show me how!
+
+Language files listed under each version were made by the author beside them, and then
+modified by me for consistency/bug fixing.
+
+Please send any bug reports to BenBE@omorphia.de, or use the bug report tracker
+at sourceforge (http://sourceforge.net/tracker/?group_id=114997&atid=670231)
+
+Version 1.0.8.3
+  -  Added language files
+     * DCS (Stelio Passaris)
+     * Locomotive Basic (Nacho Cabanes)
+     * LSL2 (Linden Scripting Language) (William Fry)
+     * Modula-3 (Martin Bishop)
+     * Oberon-2 (Mike Mol)
+     * Rebol (Lecanu Guillaume)
+  -  Fixed a problem where HardEscapes weren't working when no escape char was given (BenBE)
+  -  Added a PARSER_CONTROL setting to treat whitespace inside of keywords in
+     the language file as "any whitespace" in the source (i.e. "CREATE TABLE"
+     in SQL will match "CREATE\s+TABLE" instead of literally matching) (BenBE)
+  -  Added a possibility to allow setting the style for escape characters (BenBE)
+  -  Improvements to language files (BenBE)
+     * Added some missing Perl keywords and obscure default variables (BenBE)
+     * Allow for escaped colons to appear in CSS names (BenBE, simon)
+     * Added multiline continuation suppoert of preprocessor defines for
+       C, C for Mac, C++ and CC++ with Qt support (BenBE)
+     * keywords for C-based languages are case-sensitive (BenBE)
+     * Broken AutoIt highlighting (BenBE)
+     * Problem with escaped backslash in PHP and D (BenBE)
+     * Added some more functions for PHP (BenBE)
+     * Some changes for AppleScript (Stefan Klieme)
+     * Forbid highlighting keywords followed by / in bash (BenBE)
+     * Updated the LaTeX file to link some keywords (BenBE)
+     * Additional text rendered when matching special variables for PowerShell (BenBE)
+     * Added some more keywords for ABAP (BenBE, Sandra Rossi, Jacob Laursen)
+Version 1.0.8.2
+  -  Added language files
+     * Brainfuck \ Brainfork (Benny Baumann)
+     * HQ9+ (Benny Baumann)
+     * INTERCAL (Benny Baumann)
+     * LOLcode (Benny Baumann)
+     * LScript (Beau McGuigan)
+     * Pixel Bender (Richard Olsson)
+     * ProvideX (Jeff Wilder)
+     * VIM Script (Swaroop C H)
+     * Visual Prolog (Thomas Linder Puls)
+     * Whitespace (Benny Baumann)
+  -  Changed priority for COMMENT_REGEXP compared to String highlighting (BenBE)
+  -  Fixed correct escaping of spaces inside of URLs (BenBE)
+  -  Updated the list of common file extensions (BenBE)
+  -  Updated the language file check script in contrib/ (BenBE)
+  -  Fixed a problem with link targets resulting in unclickable links (SF#2379120, BenBE)
+  -  Fixed an undefined variable issue in langcheck.php (BenBE)
+  -  Improvements to language files (BenBE)
+     * eMail Header highlighting now uses the correct delimiters for keywords (BenBE)
+     * eMail (RFC822\mbox) highlighting now highlights IPs, MIME types and
+       subfield assignments correctly (BenBE)
+     * Minor style changes in COBOL to improve loading performance (BenBE)
+     * Added some missing keywords for D (BenBE)
+     * Removed duplicate keywords from Progres, SAS and TSQL (BenBE)
+     * Fixed Heredoc Syntax for Bash (SF#2185319, BenBE)
+     * Moved symbol-lookalike sequences from keyword groups to separate symbol group
+       for languages asp, klonec, klonecpp, php, php-brief (BenBE)
+     * Fixed a lot of duplicate keyword warnings (BenBE)
+     * Added missing keywords to the Python language file,
+       introducing support for Python 3.0. (SF#2441839, milian)
+     * Updated documentation links for TypoScript (SF#2014276, BenBE)
+     * Fixed a problem with tag and attribute names in XML highlighting (SF#2276119, BenBE)
+     * Improved MySQL language file (BenBE, JavaWoman)
+     * Some commentss accidentially mistaken for DocComments (SF#2454897, BenBE)
+     * Added improved Escape Char handling for c, c_mac, cpp and cpp_qt (SF#2458743, BenBE)
+Version 1.0.8.1
+  -  Added language files
+     * AviSynth (Ryan Jones)
+     * eMail \ mbox (Benny Baumann)
+     * GNU Make (Neil Bird)
+     * Oracle 11i support (Simon Redhead)
+     * Prolog (Benny Baumann)
+     * SciLab (Christophe David)
+     * TeraTerm macro language (Boris Maisuradze)
+  -  Added support for Escape Regular Expressions (BenBE)
+     * Implemented C-style Escapes in PHP (BenBE)
+     * Introduced support for \xAB and \007 style Char Escapes in PHP (BenBE)
+     * Implemented Variable Highlighting in PHP (BenBE)
+     * Implemented Variable Highlighting in Bash (milian)
+  -  Fixed a problem with PCRE patterns for Keyword matching sometimes producing
+     very large strings, that could not be handled by some versions of PCRE lib,
+     causing broken highlighting an Regexp Compile errors (BenBE, milian)
+  -  Fixed broken highlighting of bash commands like `dbus-send --dest=org.....`,
+     i.e. the dest was highlighted as variable declaration (milian)
+  -  Fixed broken highlighting of some symbols in their escaped form (BenBE)
+     (<SEMI> and <PIPE> were accidentially filtered even though they are valid)
+  -  Fixed a "memory leak" in the *_regexp_caches (milian)
+  -  Fixed broken Escape chars if classes were disabled
+  -  start_line_numbers_at() was ignored when GESHI_HEADER_PRE_TABLE was set (revulo)
+  -  Fixed a problem allowing Remote Code Inclusion under certain circumstances (BenBE)
+  -  Changes to default CSS in order to make the GESHI_HEADER_PRE_TABLE align properly,
+     even on Windows / Mac systems with strange fonts (milian, revulo, ^RT)
+  -  Minor style changes to the following languages:
+     * cpp-qt (milian)
+     * MySQL (BenBE)
+     * PHP (BenBE)
+  -  Improvements to language files (BenBE, milian)
+     * Added MinSpareThread\MaxSpareThreads to Apache highlighter (BenBE)
+     * Added new Keyword group for APT sources.list highlighter (BenBE)
+     * Fixed highlighting in LaTeX for \begin{} and \end{}, i.e. the stuff inside
+       the curly braces. (milian, thanks for the report go to Matthias Pospiech)
+     * Improved String support for D (BenBE)
+     * MySQL was seriously broken (BenBE)
+     * Reworked Keyword groups for MySQL to allow for more configuration (BenBE)
+     * Improved Mirc script language file (milian)
+     * Improved C++ Qt language file (milian)
+     * Minor bug with Transpose Operator in Matlab (BenBE, Daniele de Rigo)
+     * Highlighting of Batch Files for Windows (BenBE)
+     * Updated AutoIt to include latest changes for AutoIt v3.2.12.1 (BenBE, Thierry)
+     * Fixed duplicate keyword warnings for Perl, Tcl and Typoscript (BenBE)
+     * Fixed Doc-URL getting reparsed by highlighted keywords of other groups (BenBE, Jordi Boggiano)
+Version 1.0.8
+  -  Added language files
+     * APT sources.list (milian)
+     * Boo (Marcus Griep)
+     * CIL (Common Intermediate Language, .NET Assembly) (Marcus Griep)
+     * COBOL (Benny Baumann)
+     * Gnuplot (milian)
+     * KLoneC (Mickael Auger)
+     * KLoneC++ (Mickael Auger)
+     * PIC16xxx assembler (Phil Mattison)
+     * POV-Ray (Carl Fürstenberg)
+     * PowerShell (Frode Aarebrot)
+     * Progress (Marco Aurelio de Pasqual)
+     * TypoScript (Jan-Philipp Halle)
+     * Xorg configuration (milian)
+  -  Make GeSHi's constructor arguments optional, so something like `$foo = new GeSHi;` is possible. (milian)
+  -  Added an optimizer for lists to regular expressions. Using these cached lists results in a speedup of approx. 50%.
+     The slightly increased memory consumption (~150KB for PHP language file) is more than worth it! (milian)
+  -  Some more memory & speed optimizations all over GeSHi (milian)
+     * Reduced memory overhead when highlighting keywords (BenBE)
+     * Keyword Linking now uses considerably less strtolower calls (milian)
+     * Cache Symbol Search Regexp and make Symbol Highlighting faster (milian)
+     * Use more native functions like substr_replace and strcasecmp to speed things up (milian)
+     * Use considerably less strlen() calls on various points by caching the results (milian)
+     * Properly set comments to be case insensitive where appropriate to increase performance (milian)
+     * Improve the performance of the strict mode tokenizer, making highlighting of languages like
+       HTML, ColdFusion or XML faster (milian)
+     * Setup caches for parsing on demand to make stylesheet generators fast (milian)
+  -  Various improvements to Strict Block Handling (BenBE, milian)
+     * Added support for RegExp-based Strict Blocks (BenBE)
+     * Fixed highlighting incorrectly stopping at ?> in PHP (SF#1330968, BenBE)
+     * Languages with STRICT_MODE_APPLIES = GESHI_MAYBE default to strict mode now. When no highlightable
+       code is found in this mode, we fallback to the same setting as if GESHI_NEVER was set. That way it
+       should not be needed to call enable_strictmode() manually. (milian)
+  -  Added new GESHI_HEADER_PRE_VALID type which uses the following markup: (milian)
+     * With line numbers:     <div>header<ol><li><pre>...</pre></li>...</ol></div>
+     * Without line numbers:  <pre>header...CODE...</pre>
+     => valid HTML and no need for &nbsp; indentation
+  -  Added new GESHI_HEADER_PRE_TABLE type which can be used to prevent linenumber-selection in Firefox
+     on copy'n'paste. (milian)
+  -  set_language will not reset any language settings by default anymore.
+     * Added $force_reset param for to force full reload of a language. (milian)
+     * Make sure strict_mode is set properly when doing repeated set_language calls (milian)
+  -  Fixed some problems with old PHP versions (SF#1975625, milian, BenBE)
+  -  Fixed broken use with Suhosin Patch when /e modifier was disabled (SF#2021800, BenBE)
+  -  Added support for external style information files to override language defaults without modifying language files (BenBE)
+  -  The overall_class is now up to the user, and the language-code is _always_ added as a class (milian)
+  -  Fixed Economy Mode for GeSHi::get_stylesheet() - now it just makes so much more sense! (milian)
+  -  Fixed Economy Mode when COMMENT_REGEXP are used (BenBE)
+  -  Changed the default encoding to use UTF-8, due to SF#2037598, BenBE)
+  -  Improved overall string support:
+     * Added support for multichar string delimiters (SF#1932083, BenBE)
+     * Fixed problems of unfinished strings and comments producing invalid XHTML (SF#1996353, BenBE)
+     * Multichar Quotemarks sometimes had inconsistent behaviour (BenBE)
+     * Support for multiple styles of strings depending on the starter (BenBE)
+     * Properly handle escapes in strings, i.e. '\\' was not working properly before (milian)
+     * Fixed escape char support when an escape char is followed by multi-byte chars (SF#2037598, BenBE)
+  -  Improved flexibility in language files (BenBE, milian)
+     * Added PARSER_CONTROL for OOLANG method highlighting (SF#1923060, BenBE)
+     * Added possibility to define strict blocks using an Regexp (BenBE)
+     * Removed explicit escaping of / in Regular Expressions (BenBE)
+     * Ignoring empty keyword groups when highlighting (milian)
+     * Make language_permissions configurable in language files via ['PARSER_CONTROL']['ENABLE_FLAGS']
+       this makes is_a calls unneeded and thus prevents PHP notices in PHP 5.x (milian)
+     * Extended support for number formats now covering the most common formats (SF#1923058, BenBE)
+     * Lifted a limitation that keywords had to have at least 2 subsequent letters (BenBE)
+     * Changed behaviour of PARSER_CONTROL now allowing to provide the full Lookahead and Lookbehind
+       expressions used as delimiters inside keywords instead of a simple char group (BenBE)
+     * Fixed improper handling of newlines in REGEXPS so this does not produce invalid html anylonger (milian)
+  -  Some typos and mistakes in the documentation (BenBE)
+  -  Added a script to contrib/ to verify language files are correct (BenBE)
+  -  Fixed loads of compliancy warnings detected with that automated compliance testing script (BenBE)
+  -  Many other improvements to various language files (BenBE, milian)
+     * Reduce strict errors & notices for language files (milian)
+     * Fixed symbol highlighting with C++ sometimes missing keywords after ; and comments (BenBE)
+     * Improved comment handling with TCL (Lars Hellström, BenBE)
+     * Fixed broken handling with XML comments (BenBE, SF#1849233)
+     * Fixed HTML comments spawning multiple lines producing invalid XHTML output (SF#1738173, BenBE)
+     * Added support for parameters beginning with dash in BASH language (BenBE)
+     * Support Apache's configuration sections, see http://httpd.apache.org/docs/2.2/sections.html (milian)
+     * Minor issue with PHP Heredoc and Nowdoc syntax sometimes not getting highlighted (BenBE)
+     * Updated Objective-C language file (SF#2013961, Quinn Taylor, BenBE)
+     * Added some keywords for VHDL (beshig, BenBE)
+     * Fixed severly broken ColdFusion language file (milian)
+     * Fixed some incorrectly highlighted things with the CSS language file (milian, BenBE)
+     * Improved Smarty language file (milian)
+     * Improved CSS language file (milian)
+     * Improved Pascal language file (milian)
+     * Improved LaTeX language file (Андрей Парамонов, BenBE)
+     * Fixed a regular expression in mIRC language file that caused a warning message to be issued (BenBE)
+     * Removed <, > and / from HTML names, now only containing the real tag names (BenBE)
+     * Use spaces instead of tabs for indendation in language files to have a consistent
+       coding standard accross geshi files (milian)
+     * Added some comment styles, keywords and added index highlighting (Chusslove Illich, Часлав Илић)
+  -  Removed some private methods which were only called at exactly one place (milian)
+     * format_header_content
+     * format_footer_content
+     * get_attributes
+  -  Second part of default style changes. Affected in this release:
+     * C++
+     * C++ (QT)
+     * CSS
+     * VHDL
+Version 1.0.7.22
+  -  Added language files
+     * glSlang (BenBE)
+     * KiXtart (Riley McArdle)
+     * Lotus Notes @Formulas (Richard Civil)
+     * LotusScript (Richard Civil)
+     * MXML (David Spurr)
+     * Scala (Franco Lombardo)
+     * ActionScript 3 (Jordi Boggiano)
+     * GNU Gettext .po/.pot (Milian Wolff)
+     * Verilog (Günter Dannoritzer)
+  -  Fixed a problem not yet addressed in 1.0.7.21 regarding highlighting of
+     symbols that caused some extra characters to be added in the output or
+     broke highlighting and standard compliance due to missing escaping of
+     internally used characters (SF#192320 and SF#1926259, BenBE)
+  -  Fixed missing style information for ocaml language file (The_PHP_Jedi)
+  -  Fixed a bug causing masses of warnings in rendered output if language file
+     miss style information (The_PHP_Jedi, BenBE)
+  -  Missing tab width information could lead to warnings (BenBE)
+  -  Missing symbol information for ASP (SF#1952038, nfsupport, BenBE)
+  -  Empty delimiter message with OOoBasic (BenBE, Ccornell)
+  -  Escaping of comments in LaTeX ignored (SF#1749806, BenBE)
+  -  Modified Math environment $$ in LaTeX to be non-greedy (BenBE)
+  -  Added possibility to match a regexp as comment (SF#1914640, SF#1945301, SF#1934832, BenBE)
+  -  Introduced C-Style multiline continuation comments (SF#1914640, SF#1945301, BenBE)
+  -  Introduced Fortran Comments (SF#1914640, SF#1934832, BenBE)
+  -  Implemented Heredoc and Nowdoc Syntax for PHP and Perl (SF#1914640, BenBE)
+  -  Implemented Compiler Directives for Delphi (SF#1914640, BenBE)
+  -  Implemented minimalistic support for JavaScript \ Perl Regular Expressions (SF#1786665, SF#1754333, SF#1956631, BenBE)
+  -  Fixed Strings in Matlab to be handled as comments instead of regexps, to prevent keywords being linked (BenBE)
+  -  Applied PARSER_CONTROL fix of CPP for CPP-QT-Derivative (BenBE)
+  -  Fixed incorrect treatment of unequally long multiline comment separators (related to SF #1891630, BenBE)
+  -  Added PARSER_CONTROL settings for keywords in ASM language file (SF#1835148, BenBE)
+  -  Fixed missing CASSE_SENSITIVE entry for DOS language file (SF#1956314, BenBE)
+  -  Fixed accidential highlighting of keywords in argument names (SF#1956456, Milian Wolff, BenBE)
+  -  Fixed yet again some #-related bash problem (SF#1956459, Milian Wolff, BenBE)
+  -  Added backticks as symbols (Milian Wolff)
+  -  Example script remembers selections and source submitted (Milian Wolff)
+  -  Example script allows remembered source and preselected language to be cleared (Milian Wolff)
+  -  Example script now properly includes geshi and doesn't suppress error messages anylonger. (Milian Wolff)
+  -  Code cleanup by using direct string indexing instead of substr with length 1 (Milian Wolff)
+  -  Optimized generation of code parts in strict mode (Milian Wolff)
+  -  Optimized COMMENT_REGEXP by using an incremental regexp cache (Milian Wolff, BenBE)
+  -  Fixed a problem that rarely skipped highlighting of escaped chars which usually should have gotten highlighted (BenBE)
+  -  Optimized generation of highlighted strings to use fast skip forward while highlighting them (Milian Wolff, BenBE)
+  -  Optimization using basic rework of indent function improving tab expansion performance (BenBE)
+  -  Lots of other minor optimizations based on coding style improvements (Milian Wolff)
+  -  Implemented setting to force spans to be closed before newlines, see SF#1727398 (Milian Wolff)
+  -  Added missing credits for D language file to THANKS file (SF#1720899, BenBE)
+  -  Optimization to prevent loading the current language file twice (Milian Wolff)
+  -  Optimization: Use file_get_contents() to load sourcecode from files.
+     Even if GeSHi worked with PHP 4.1 before, it doesn't now. (Milian Wolff)
+  -  Added description of extra language features (SF#1970248, BenBE)
+  -  Added support for highlighting the C# using and namespace directives (SF #1395677, BenBE)
+  -  Added support for highlighting the Java import and package directives (SF #1395677, BenBE)
+  -  Fixed minor problem in Haskell cuasing accidential start of comment (SF#1987221, BenBE)
+  -  Fixed minor issue causing loads of warnings if a language files defines no symbols (BenBE)
+  -  Updated some aspects of the documentation and included further hints (BenBE)
+  -  First of series of color scheme changes. Affected languages (sofar):
+     * Assembler (x86)
+     * Bash
+     * C
+     * C#
+     * Delphi
+     * Fortran77
+     * glSlang
+     * Java & Java 5
+     * JavaScript
+     * OCaml
+     * OpenOffice.org Basic
+     * Pascal
+     * Perl
+     * PHP and PHP-Brief
+Version 1.0.7.21
+  -  Added language files
+     * Basic4GL (Matthew Webb)
+  -  Fixed problem with mIRC language highlighting spaces only (BenBE)
+  -  Language files can now specify a function to be called to decide the
+     colour of a regular expression match
+  -  Added single quote to Lua (Darrin Roenfanz)
+  -  Compare comments case insensitively (fixes AutoIT comments somewhat)
+     (Daniel Gordon)
+  -  Fixed symbols not being highlighted at all (SF #1767953, BenBE)
+  -  Fixed brackets not correctly managed (SF #1767954, BenBE)
+  -  Changed default languages for some extensions
+  -  Included color and character information for symbol highlighting in some languages (BenBE)
+  -  Fixed a problem with extension detection if default was used (BenBE)
+  -  Fixed a highlighting problem with the LaTeX language (SF #1776182, BenBE)
+  -  Added a new parameter for enable_highlighting to reduce source duplication (SF #1786104, BenBE)
+  -  Updated doxygen documentation to include since tags and some missing parameters
+  -  Disabled symbol highlighting by default (doesn't affect brackets, cf. documentation) (BenBE)
+  -  Added a check for set_case_keywords for the given param to be supported (BenBE)
+  -  Minor rework of the HTML documentation layout \ W3C compliance (BenBE)
+  -  Fixed highlighting error in bash language avoiding keywords in comments (SF #1786314, SF #1564839, BenBE)
+  -  Fixed template params for C++ and C# not being highlighted (SF #1772919, BenBE)
+  -  Fixed more reported problems about mirc highlighting
+  -  Added some missing keywords for VB.NET
+  -  Fixed some warnings in DOS language file (Florian Angehrn)
+  -  Add possibility to handle more than one extra line style (SF #1698255, German Rumm, BenBE)
+  -  Fixed handling of URLs when output case differs from URL case (SF #1815504, Tom Samstag, BenBE)
+  -  Fixed POD (Plain Old Documentation) format problems breaking highlighting of Perl (SF #1891630, Shannon Wynter, BenBE)
+  -  Fixed a problem with mIRC when & was used for identifiers (SF #1875552, BenBE)
+Version 1.0.7.20
+  -  Added language files
+     * Genero (logic) and Per (forms) (FOURJ's Genero 4GL) (Lars Gersmann)
+     * Haskell (Dagit)
+     * ABAP (Andres Picazo)
+     * Motorola 68k Assembler (for MC68HC908GP32 Microcontroller) (BenBE)
+     * Dot (Adrien Friggeri)
+  -  Fixed java documentation search for keywords to actually go to the
+     documentation (spaze)
+  -  Applied fix for bug 1688864 (bad regexes) (Tim Starling)
+  -  Fixed comment CSS rule in visualfoxpro
+  -  ThinBASIC language update (Eros Olmi)
+  -  mIRC language update (BenBE)
+  -  Fixed outdated documentation URL of Perl language file (RuralMoon by BenBE)
+  -  Fixed tab replacement code not generating the correct number of spaces in
+     some cases (Guillermo Calvo)
+  -  Fixed two typos in Z80 language file
+  -  Applied fix for bug 1730168 (Daniel Naber)
+  -  Applied fix for bug 1705482 (Jason Frame)
+     * Configurable line endings (Replace \n by custom string)
+     * per-language tab-widths (Adjustable for width>=1)
+     * Included defaults for ASM (x86, m68k, z80), C, C (Mac), C++, C++ (QT), C#,
+       Delphi, CSS,, HTML, PHP, PHP (Brief), QBasic, Ruby, XML
+  -  Added a possibility to force generation of a surrounding tag around
+     the highlighted source
+  -  Applied fix for additional keywords for the bash language
+     (cf. http://bash.thefreebizhost.com/bash_geshi.php, BenBE / Jan G)
+  -  Fix bad colour definition in GML language (Andreas Gohr)
+  -  Fixed phpdoc comments not being indented one space if they should be (Andy
+     Hassall)
+Version 1.0.7.19
+  -  Added language files
+     * X++ (Simon Butcher)
+     * Rails (Moises Deniz)
+  -  Fixed invalid HTML being generated and doctypes not being highlighted over
+     multiple lines properly when line numbers are on (Validome)
+  -  Improved the ruby syntax highlighting by basing it off the Rails file
+  -  Changed some regular expressions to possibly help with badly performing
+     regex support in PHP (Tim Starling)
+  -  Allow {TIME}, {LANGUAGE} and {VERSION} to be used in the header as well as
+     the normal <TIME>/<LANGUAGE>/<VERSION> (AthanD)
+  -  Changed comment regex in bash to prevent malformed XHTML (rv1971)
+Version 1.0.7.18
+  -  Added language files
+     * ZiLOG Z80 Assembly (BenBE)
+  -  Fixed incorrect highlighting when the starter of a multiline comment is
+     longer than the ender (Robert Anthony).
+  -  Fixed "</span" generated if a multiline comment is the last thing in the
+     source (related to the above).
+  -  Added #cs => #ce comment markers to AutoIT (Robert Anthony)
+  -  Fixed spelling mistake for keyword in Python (wd3)
+  -  Added a method to enable/disable keyword linking (Ian McKellar)
+  -  Improved empty line detection for HTML output (BenBE)
+  -  Changed code style of geshi.php, and removed tabs
+Version 1.0.7.17
+  -  Fixed up ends of files having too many newlines (binarygroop)
+  -  Removed background colour on keyword group in eiffel (Julian Tschannen)
+  -  Removed GESHI_DIR_SEPARATOR constant usage, it's unnecessary (Aleksey Zapparov)
+  -  Added /* ... */ comments to coldfusion (Jeff Howden)
+Version 1.0.7.16
+  -  Added language files
+     * ActionScript (Steffen Krause)
+     * C++/QT (Iulian M)
+     * PL/SQL (Victor Engmark)
+  -  Fixed up my e-mail address everywhere
+  -  Fixed notice with "error" property (IZIU Zielona Góra)
+  -  Added some entries to the get_language_name_from_extension table
+     (Stebastian Schuberth)
+Version 1.0.7.15
+  - Added language files
+     * BNF (Rowan Rodrik van der Molen)
+     * IO (me, thanks to Johnathan Wright)
+     * mIRC (Alberto de Areba Sánchez)
+  -  Fixed use of colon in XML (Grigory Rubtsov)
+  -  Fixed notices in text.php, reg.php and latex.php when $this is not
+     available (Clemens Weiß)
+  -  Made third parameter of geshi_highlight optional (Gaetano Giunta)
+  -  Fix incorrect highlighting of the $# variable in bash (Michael Knight)
+  -  Fixed single line comment mistake in thinbasic.php (Eros Olmi)
+Version 1.0.7.14
+  -  Added language files
+     * thinBasic (Eros Olmi)
+     * LaTeX (Matthais Pospiech)
+  -  Removed extra newlines at the end of some files
+  -  Fixed SF bug 1556404 - check before using $this in language files
+     (Clemens Weiß)
+Version 1.0.7.13
+  -  Added language files
+     * Uno IDL (Cedric Bosdonnat)
+  -  Fixed add_ids causing odd XHTML (RyanJ)
+  -  Fixed extra newline being added to end of result (Andreas Gohr)
+Version 1.0.7.12
+  -  Fixed lines being collapsed when they contain just a space (artlover)
+  -  Allowed matching for regexes using start/end matchers at the start/end
+     of the code (Sheri)
+  -  Added (dubious) fix for google "I'm feeling lucky" search for java keywords
+     (dubious in that it doesn't work for me)
+  -  mysql - Made the symbols into their own keyword group as the symbol group
+     isn't used. Added a style for multiline comments.
+  -  Added a couple of php5 keywords to the php language files.
+  -  Allow XML tags to have dashes.
+  -  Changed LANG_NAME for many languages to be more sensible/correct case
+     (Matthias Mohr)
+  -  Added case-sensitivity indices to python
+Version 1.0.7.11
+  -  Added language files
+     * Smalltalk (Bananeweizen)
+  -  Minor style improvements to matlab
+  -  Moved a couple of functions to the correct group in smarty (arwan)
+Version 1.0.7.10
+  -  Added language files
+     * TCL (Reid van Melle)
+     * Winbatch (Craig Storey)
+     * Groovy (Ivan F. Villanueva B.)
+     * Text (SmokingRope)
+     * Reg (SmokingRope)
+  -  Removed \ as an escape character in T-SQL (Dave Jackson)
+  -  Reset extra lines to highlight if source is changed (Diogo Resende)
+  -  Allow setting of lexic permissions in language files (SmokingRope)
+  -  Allow regexes to set a CSS class name (SmokingRope)
+  -  Added URL support to DOS language (mastrboy)
+Version 1.0.7.9
+  -  Added language files
+     * Fortran (Cedric Arrabie)
+     * SAS (Galen Johnson)
+     * CFDG (John Horigan)
+  -  Fixed & in URL in java5 (Clemens Weiß)
+  -  Added MD5 and SHA1 to mysql keywords (polarina)
+  -  Fixes for highlight_lines_extra with line numbers (ithcy)
+  -  Fixed backslash characters being removed (ArTourter)
+Version 1.0.7.8
+  -  Fixed blank at start of MySQL file (W. Tasin)
+  -  Fixed smarty functions being broken (ultrabob)
+  -  Changed keyword and regexp detection and parsing
+     slightly to allow more "meta characters" (like #) in
+     keywords
+  -  Minor fixes for XML and GML
+Version 1.0.7.7
+  -  Added language files
+     * T-SQL (Duncan Lock)
+     * Robots.txt (Christian Lescuyer)
+     * AutoIT (mastrboy)
+     * Java 5 (Clemens Bruckmann)
+     * ColdFusion (Diego)
+  -  A few keyword changes in java, removed :: object splitter (amphi)
+  -  Now using a simpler regular expression for numbers (Brice Bernard)
+  -  Fixed ah, bh etc. regs being highlighted as numbers (Unknown)
+Version 1.0.7.6
+  -  Fix backtick-string highlighting in ruby (Juan J. Martínez)
+  -  Add =begin multiline comments in ruby (Juan J. Martínez)
+  -  Added support for :keywords and ::access in lisp (Denis Mashkevich)
+  -  Prevented number highlighting if they are just after underscores (Joce)
+  -  Removed escape characters for strings in XML and HTML (floele)
+  -  Added instanceof keyword to java (jgottschling)
+  -  Fixed comments in ASP (SBD)
+  -  Removed unnecessary keyword style index from ini
+  -  Added support for " strings in ini
+  -  Removed unnecessary regex style index from blitzbasic
+  -  Keyword case of URL-ed keywords should be defined by language file (Benny Baumann)
+  -  Added "Hardquote" feature, provides more accurate string highlighting (Cliff Stanford)
+  -  Used hardquote support for @"..." strings in C# (Cliff Stanford)
+  -  Used hardquote support for ' strings in perl (Cliff Stanford)
+  -  Fixed setting of language path (Cliff Stanford)
+  -  Display source correctly formatted with line numbers (if requested) if an error
+     has occured (several people)
+  -  Having no source to highlight is not an error condition anymore
+  -  Delphi language updated to include more keywords and types (BenBE)
+  -  Updated NSIS to version 2.11 (deguix)
+Version 1.0.7.5
+  -  Fix for using escape characters to escape newlines breaking XHTML compliance (Yves Goergen)
+  -  Fixed method highlighting in VB (Matt Beale)
+  -  Fixed multiline comment highlighting in SQL (MrBaseball34)
+  -  Fixed two ">" symbols being outputted when using a footer but not CSS classes (MrBaseball34)
+  -  Marked important block stuff as deprecated
+  -  Some documentation tidyup
+  -  Updated GML language file (Jos? Jorge Enr?quez Rodr?guez)
+  -  THANKS file tidied up
+  -  Fixed double </a> for elements in HTML (Yves Goergen)
+  -  Added some keywords for ASM (Dreuzzo)
+Version 1.0.7.4
+  -  Added language files
+     * MySQL (Carl Fürstenberg)
+     * BlitzBasic (Pàdraig O`Connel)
+  -  Fixed up geshi_highlight function: it now correctly uses <code> instead of <div> (Remi Faure)
+  -  When using GESHI_HEADER_NONE, remove the <ol> if line numbering is not enabled
+  -  Commented example.php so people can use it as a guide better
+  -  Fixed extra newline being generated if a comment is at the end
+     of the source (many people, including Yves Goergen)
+  -  Fixed up some documentation issues
+  -  Some minor language file fixes (C++, Lua) (Lua fixes by chromix)
+  -  Fixed up no </span> in XML and other strict languages (regression from 1.0.7.3 fix: removed
+        unnecessary </span> when using strict mode) (Daniel Ecer, drskrud),
+Version 1.0.7.3
+  -  Added language files
+     * Scheme (Jon Raphaelson)
+     * Ocaml and Ocaml-brief (Flaie)
+     * Ruby (Amit Gupta)
+  -  Make urls generated for java highlighting XHTML compliant (Tim Van Wassenhove)
+  -  Removed unnecessary </span> when using strict mode (Tim Van Wassenhove)
+  -  Fixed warning in dos.php about undefined constant (Tim Van Wassenhove)
+  -  Fixed security hole in contrib/example.php - able to view any file if source
+     not set and language is set to wierd value (Maksymilian Arciemowicz)
+Version 1.0.7.2
+  -  Added language files
+     * Inno (Thomas Klinger)
+     * Ini (Deguix)
+     * DOS (Batchfile) (Alessandro Staltali)
+     * Applescript (Stephan Klimek)
+     * Freebasic (Roberto Rossi)
+     * SDLBasic (Roberto Rossi)
+     * ActionScript (links to French documentation) (NikO)
+  -  NSIS language file updated (deguix)
+  -  Lua language file updated (Roberto Rossi)
+  -  Bugfix: Styles incorrectly overriding default styles instead of being merged
+     in set_*_styles methods (Stebastian Werner)
+  -  Added GESHI_HEADER_NONE as valid header type. This still allows header content.
+Version 1.0.7.1
+  -  Added language files:
+     * Div (Gabriel Lorenzo)
+     * GML (José Jorge Enríquez Rodríguez)
+     * Eiffel (Zoran Simic)
+  -  Minor change to rules regarding when keywords can appear - now dots (.) are
+     allowed before keywords. (NikO)
+  -  Bugfix: the line style for non-fancy lines when fancy highlighting is enabled
+     is now applied (Amit Gupta)
+Version 1.0.7
+  -  Added language files:
+     * Diff (Conny Brunnkvist)
+     * VHDL (Alexander Krause)
+     * D (Thomas Kuehne)
+     * Matlab (Florian Knorn)
+  -  Python highlighting improved (thither, Federico Quagliata)
+  -  Changed file comments to use phpdoc syntax, and changed code style to be more
+        like PEAR
+  -  Fixed bug in set_code_style: Second parameter is now optional
+  -  The $_GESHI_ERRORS array is gone, error messages are internal to the GeSHi class
+  -  Changed name of XML language to XML from HTML
+  -  Removed min and max tab width checks
+  -  Backported GeSHi 1.1.X's automatic language file path detection so you no longer
+     need to use the third parameter of the constructor or set_language_path except for
+     special circumstances.
+  -  Source is checked to make sure it is not empty else an error occurs
+  -  Removed excess characters after ?> in ada.php, apache.php and cpp.php that caused
+     http headers to be sent (psichron)
+  -  Removed second "foreach" keyword for smarty language file that was causing
+     duplication (Iss)
+  -  Added underscore to allowed characters in match for XML tags (anonymous)
+  -  Added some missing java keywords like "abstract" and "transient"
+  -  Added "list" and "continue" PHP keywords
+  -  set_language resets error status and strict mode (Andrew Black)
+  -  Removed margin:0 declaration from cssgen.php (Andrzej Kubaszek)
+  -  Fixed multiline comment selector in cssgen.php (Andrzej Kubaszek)
+Version 1.0.6
+  -  Added support for smart tabs - tabs that behave just like normal tabs when in
+     GESHI_HEADER_DIV mode.
+  -  Partial patch for UTF-8 encoding applied (doesn't quite work however...)
+Version 1.0.5
+  -  Added language files:
+     * MPASM (Bakalex)
+     * Oracle 8 (Guy Wicks)
+  -  Fixed bug where not using an encoding type would sometime result in warnings (although
+     there still seems to be issues with encoding in general that I'm trying to gather more
+     data on) (Alexander Spennemann)
+  -  Removed "margin: 0" from <ol> in an attempt to make line numbers visible in IE again
+     by default (untested, but I don't really care if it works... get firefox! ;))
+  -  Added note on php5 support (Karim Scheik)
+  -  Added two new methods: load_from_file and get_language_name_from_extension, that can
+     help automate file highlighting (though the extension array at this time is quite bare)
+     (David Gartner, Brian Cheesman)
+Version 1.0.4
+  -  Fixed many version-reporting bugs (Jack Lloyd)
+  -  Fixed bug where methods were not having the correct CSS generated for them
+     by get_stylesheet() (Jack Lloyd)
+  -  Added new keywords to C and C++ files (Jack Lloyd)
+  -  Added section on case sensitivity to documentation that wasn't in the other versions
+Version 1.0.3
+  -  Added language files:
+     * Smarty (Alan Juden)
+     * C# (Alan Juden)
+     * VB.NET (Alan Juden)
+     * C for Macs (M. Uli Kusterer)
+     * Objective C (M. Uli Kusterer)
+  -  Links can have a target attribute (Andreas Gohr)
+  -  Fixed multiline string bug if not using classes
+  -  Added method set_encoding that allows you to set the character
+     set used by calls to htmlentities() in GeSHi
+  -  You can now specify an array of object splitters, and each
+     type of method separated by each object splitter can be highlighted
+     differently
+  -  If a language uses a case sensitive keyword group and that group
+     has a URL associated with it, the keyword will not be lowercased
+     in the URL (M. Uli Kusterer)
+Version 1.0.2
+  -  Added language files:
+     * Actionscript (Steffen Krause)
+     * ASP (Amit Gupta)
+     * Bash (Andreas Gohr)
+     * CADDCL (Roberto Rossi)
+     * CadLisp (Roberto Rossi)
+     * C++ (Dennis Bayer)
+     * Delphi (Járja Norbert)
+     * Javascript (Ben Keen)
+     * Lisp (Roberto Rossi)
+     * OpenOffice.org BASIC (Roberto Rossi)
+     * Perl (Andreas Gohr and Ben Keen)
+     * Python (Roberto Rossi)
+     * VisualFoxPro (Roberto Armellin)
+     * XML (Nigel McNie, from an idea/file by Christian Weiske)
+  -  Added contrib/ directory with script to create one external stylesheet
+     from many languages(base script by Andreas Gohr, modified by Nigel McNie),
+     and an example script (needs lotsa work...)
+  -  Code lines can have their own unique ID (for use with javascript)
+     (suggested by Andreas von Oettingen)
+  -  Certain rows can be specified to be highlighted differently (suggested by
+     Andreas von Oettingen)
+  -  Getter available for human-readable language name (suggested by Simon Patterson)
+  -  Line numbers aren't highlighted when a user selects the code
+  -  Contextual highlighting with <BEGIN GeSHi> ... <END GeSHi> in the code (which
+     can be disabled)
+  -  Functions can be made into URLs to appropriate documentation (suggested
+     by cybot_tm). Also thanks to Marcin Gryszkalis for the links for C, Java
+     and Perl.
+  -  Code can have a header and footer
+  -  Time taken to parse the code is recorded and made available with the get_time()
+     method
+  -  error() now returns a human-readable error message
+  -  Function geshi_highlight added to make it even easier to highlight on the fly
+  -  Advanced regular expression handling
+  -  Bug fixes to lexic_permission handling
+Version 1.0.1
+  -  Added methods set_symbols_style() and set_symbols_highlighting(). These should be used
+     instead of set_brackets_style and set_brackets_highlighting respectively.
+  -  Added a new field - language_path - that can be set either when the constructor is
+     called, or by the new method set_language_path(), that specifies a path to the directory
+     containing the language files (bug reported by bbspliff)
+  -  Added a new method set_case_keywords(), that allows the auto-casing feature to be
+     changed on the fly instead of simply being specified in the language file
+  -  If there is an error the source that is outputted is now handled much better
+  -  Lines are broken in the source only by \n now, not by \r\n (to save on output source)
+  -  Indentation moved into its own method
+  -  Method header() modified to allow the user to choose whether the code is surrounded in
+     a <div> or a <pre> (see documentation for benefits of both). Method footer() likewise
+     modified.
+  -  Method get_stylesheet() modified so that a smaller comment is outputted in economy mode,
+     and bugs with when line number classes are outputted in economy mode have been fixed
+  -  Bug where spans had two quotes at the end of the attributes fixed (ie. <span style=".."">)
+  -  Added language files:
+     * Ada (Tux)
+     * Apache log file (Tux)
+     * ASM (Tux)
+     * NSIS (Tux)
+     * Pascal (Tux)
+Version 1.0.0
+  -  Initial Release
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/COPYING b/examples/includes/geshi/docs/COPYING
new file mode 100644 (file)
index 0000000..5b6e7c6
--- /dev/null
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/examples/includes/geshi/docs/README b/examples/includes/geshi/docs/README
new file mode 100644 (file)
index 0000000..a08e78e
--- /dev/null
@@ -0,0 +1,33 @@
+
+        GeSHi - GEneric Syntax HIghlighter
+        ----------------------------------
+                 Version 1.0.8
+
+Author:          Nigel McNie, Benny Baumann
+Email:           nigel@geshi.org, BenBE@omorphia.de
+GeSHi Website:   http://qbnz.com/highlighter
+
+GeSHi is a generic syntax highlighter, written in PHP. You simply
+input the source code you wish to highlight with the language you
+wish to use, and the output will be a file syntax highlighted to
+XHTML standards.
+
+For more information on how to use GeSHi, please consult the
+documentation. If you got this readme from a GeSHi package, then
+the documentation is available in the docs/ directory. Documentation
+is also available at http://qbnz.com/highlighter/documentation.php
+
+If you think you've found a bug in GeSHi, contact me with a bug
+report at BenBE@omorphia.de, or submit it to the bug tracker at
+http://sourceforge.net/tracker/?group_id=114997&atid=670231. Be
+aware that minor highlighting errors may well just be incorrect
+language files, but if you do find something major please contact me.
+
+And if you're using GeSHi as a plugin/mod for some other software,
+please tell me about it! It's worth a link to you, and I can give
+you specialist help if you need it.
+
+GeSHi is free software, released under the GNU GPL. Please see the
+COPYING file for more information. If you do modify this program,
+please tell me about it! Perhaps you've made a good improvement that
+I can learn from :)
diff --git a/examples/includes/geshi/docs/THANKS b/examples/includes/geshi/docs/THANKS
new file mode 100644 (file)
index 0000000..9580567
--- /dev/null
@@ -0,0 +1,163 @@
+
+             THANKS - List of credits for GeSHi
+
+I owe these people/groups my thanks for help with GeSHi. Thanks, guys!
+
+- Amit Gupta            - Thanks for all that constructive criticism - it's
+                          a great help for making GeSHi even better. And
+                          thanks for the Wordpress plugin! (Anyone who is
+                          interested in the plugin can visit:
+                          http://blog.igeek.info/still-fresh/category/wp-plugins/igsyntax-hiliter/)
+- Andreas Gohr          - Thanks for language files and for using GeSHi for DokuWiki
+                          (http://www.splitbrain.org/dokuwiki/wiki:dokuwiki). And thanks
+                          for all your criticisms and for that stylesheet-maker code :).
+                          Also, thanks for the UTF-8 patch.
+- Andreas von Oettingen - Thanks for those great ideas! :)
+- bbspliff              - Thanks for pointing out that bug (pity I already
+                          found it though ;))
+- Benny Baumann         - Thanks for your innumerable suggestions for improvements, and your
+                          work on Delphi support :)
+- Ben Keen              - Thanks for the language files and pointing out some
+                          ideas for future releases. Lookin' forward to seeing that
+                          software soon! ;)
+- Brian Cheesman        - Thanks for using GeSHi in phpCvsView, and for the suggestion about
+                          extension => language lookup
+- Christian Weiske      - Thanks for the inspiration for creating advanced regexp
+                          highlighting :D
+- Cliff Stanford        - Thanks for the hardquote support for C# and Perl (can be used elsewhere
+                          I'm sure)
+- David Gartner         - Thanks for using GeSHi in net2ftp, and for the idea about a load_from_file
+                          method
+- forum.qbasicnews.com  - Thanks for putting up with the crappy versions
+                          that I "forced" on you guys before ;)
+- Jack Lloyd            - Thanks for pointing out the versioning and method CSS bugs, and giving
+                          me the extra C/C++ keywords
+- Karim Scheik          - Thanks for the php5 support report
+- Marcin Gryszkalis     - Thanks for those links for C, Java, Perl
+- M. Uli Kusterer       - Thanks for the idea about URL case conversion
+- Milian Wolff          - Thanks for the loads of optimizations
+                        - Thanks for helping with implementation of various features
+- Roberto Armellin      - Thanks for pointing out some flaws in GeSHi (that will be solved
+                          in 1.2 guaranteed)
+- Sterling Christensen  - Thanks for those links to language specs
+- Tux                   - Thanks for making all those language files :D
+- zbw                   - Thanks for proving a phpBB port was possible
+
+PEOPE WHO MADE LANGUAGE FILES
+
+- ABAP                   Andres Picazo
+- Actionscript           Steffen Krause (french translation by NikO)
+- ActionScript 3         Jordi Boggiano (version for ActionScript3 and MXML)
+- Ada                    Tux
+- Apache                 Tux
+- Applescript            Stephan Klimek
+- Apt sources.list       Milian Wolff
+- ASM                    Tux
+- ASP                    Amit Gupta
+- AutoIT                 mastrboy
+- AviSynth               Ryan Jones
+- Bash                   Andreas Gohr
+- Basic4GL               Matthew Webb
+- BlitzBasic             P�draig O`Connel
+- BNF                    Rowan Rodrik van der Molen
+- Boo                    Marcus Griep
+- Brainfuck \ Brainfork  Benny Baumann
+- C++                    Dennis Bayer, M. Uli Kusterer
+- C++/QT                 Iulian M
+- C#                     Alan Juden
+- C for Macs             M. Uli Kusterer
+- CADDCL                 Roberto Rossi
+- CadLisp                Roberto Rossi
+- CDFG                   John Horigan
+- CIL                    Marcus Griep
+- COBOL                  Benny Baumann
+- ColdFusion             Diego
+- D                      Thomas Kuehne
+- DCS                    Stelio Passaris
+- Delphi                 Járja Norbert, Benny Baumann
+- Div                    Gabriel Lorenzo
+- DOS                    Alessandro Staltari
+- Eiffel                 Zoran Simic
+- eMail \ mbox           Benny Baumann
+- FreeBasic              Roberto Rossi
+- Fortran                Cedric Arrabie
+- glSlang                Benny Baumann
+- Gettext                Milian Wolff
+- GNU make               Neil Bird
+- Gnuplot                Milian Wolff
+- GML                    José Jorge Enríquez Rodríguez
+- Groovy                 Ivan F. Villanueva B.
+- Haskell                Dagit
+- HQ9+                   Benny Baumann
+- Ini                    Deguix
+- Inno                   Thomas Klinger
+- INTERCAL               Benny Baumann
+- Java 5                 Clemens Bruckmann
+- Javascript             Ben Keen
+- KiXtart                Riley McArdle
+- KLone C                Mickael Auger
+- KLone C++              Mickael Auger
+- LaTeX                  Matthais Pospiech
+- Lisp                   Roberto Rossi
+- Locomotive Basic       Nacho Cabanes
+- LOLcode                Benny Baumann
+- LScript                Beau McGuigan
+- LSL2                   William Fry
+- Lua                    Roberto Rossi
+- m86k                   Benny Baumann
+- mIRC                   Alberto de Areba Sánchez
+- Modula-3               Martin Bishop
+- MPASM                  Bakalex
+- MXML                   David Spurr
+- MySQL                  Carl Fürstenberg, Marjolein Katsma
+- NSIS                   Tux, Deguix
+- Oberon-2               Mike Mol
+- Objective C            M. Uli Kusterer
+- Ocaml                  Flaie
+- Ocaml-brief            Flaie
+- OpenOffice.org BASIC   Roberto Rossi
+- Oracle 8               Guy Wicks
+- Oracle 11i             Simon Redhead
+- Pascal                 Tux
+- Perl                   Andreas Gohr, Ben Keen
+- PIC16xxx assembler     Phil Mattison
+- Pixel Bender           Richard Olsson
+- PL/SQL                 Victor Engmark
+- POV-Ray                Carl Fürstenberg
+- PowerShell             Frode Aarebrot
+- Progress               Marco Aurelio de Pasqual
+- Prolog                 Benny Baumann
+- ProvideX               Jeff Wilder
+- Python                 Roberto Rossi
+- Rails                  Moises Deniz
+- Rebol                  Lecanu Guillaume
+- Reg                    SmokingRope
+- Robots                 Christian Lescuyer
+- Ruby                   Amit Gupta, Moises Deniz
+- SAS                    Galen Johnson
+- SDLBasic               Roberto Rossi
+- Scheme                 Jon Raphaelson
+- SciLab                 Christophe David
+- Smalltalk              Bananeweizen
+- Smarty                 Alan Juden
+- T-SQL                  Duncan Lock
+- TeraTerm               Boris Maisuradze
+- Text                   SmokingRope
+- TCL                    Reid van Melle
+- thinBasic              Eros Olmi
+- TypoScript             Jan-Philipp Halle
+- Uno IDL                Cedric Bosdonnat
+- VB                     Roberto Rossi
+- VB.NET                 Alan Juden
+- Verilog                Günter Dannoritzer
+- VIM Script             Swaroop C H
+- Visual FoxPro          Roberto Armellin
+- Visual Prolog          Thomas Linder Puls
+- Whitespace             Benny Baumann
+- Winbatch               Craig Storey
+- X++                    Simon Butcher
+- Xorg config            Milian Wolff
+- Z80 Assembler          Benny Baumann
+
+Do you want your name in here? Help me out! Make a language file, or suggest a new
+feature, or make a plugin for GeSHi for some other software, then tell me about it!
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/TODO b/examples/includes/geshi/docs/TODO
new file mode 100644 (file)
index 0000000..ee71c77
--- /dev/null
@@ -0,0 +1,71 @@
+       TODO - List of things to do as of 2005/01/29
+
+Suggestions for things to add are welcome, if you have a feature request you
+can either post it to the forums:
+
+http://qbnz.com/highlighter/forum.php
+
+Or to the feature request tracker:
+
+http://sourceforge.net/tracker/?group_id=114997&atid=670234
+
+
+  TODO for version 1.0.8.x
+
+- Rework the load_from_file method and the one for getting a file extension,
+  as documented in the source.
+- use analogous vars to $next_comment_regexp_pos for more GeSHi structures,
+  should reduce number of functions called and hence improve performance
+- make a set of default colours which can be used in the language files.
+  this way we can give languages a uniform look and maybe even add "themes"
+- Get better coverage in our coderepo
+- README / INSTALL / ... file for phpdoc integration => take geshi-doc.*?
+- rework HARDQUOTE + styles, currently this is a bit of a mess imo (milian)
+- Allow per-keywordgroup AutoCaps/NoCaps
+- Complete API to support latest features
+    set_number_style ($key missing)
+    set_string_style ($key missing)
+    set_case_keywords (support for per_keywordgroup AutoCaps)
+
+
+  TODO for version 1.2.0
+
+- Rewrite engine to use remove/replace method (will hopefully almost
+  eliminate the need for regular expressions except for numbers/methods
+  etc). This will also assist for making different output formats [DONE]
+- "Intelligent" output format - eg if the user doesn't want lines to
+  wrap and wants line numbers don't use <ol>, use the <table> method
+  instead. (This saves on output)
+- Clear split between "public" and "private" methods [DONE]
+- PHP5 version
+- "Themes" for styles - basically pre-made stylesheets that can be used
+  to highlight code of any language in a similar manner [DONE]
+- "Dialects" for languages - eg php4, php5. One master language definition
+  file, and a bunch of "specialised" dialect files for each language
+  Ability to specify a "specialised" dialect as default? [DONE]
+- Look at load/memory usage and try to reduce
+- Make tabs into tab-stops like a normal editor [DONE]
+- Ability to add more than one multiline comment or string [DONE]
+- Ability to specify that strings cannot be multiline [DONE]
+- Create a "wrapper" class for ultra-easy use
+- Code written in a style that conforms to a phpdoc utility [DONE, PEAR]
+- Dig functions/methods out of code and where they are called make an internal
+  link back to their definition
+
+
+  TODO for version 2.0.0
+
+- Support for multiple output formats (XHTML, XML, PDF, RTF etc) [DONE IN 1.2]
+- Support for auto-indent/code "beautifing"
+- Option for "Lite" highlighting - aims for speed and low server load
+- "Intelligent" highlighting inside comments, and ability to highlight
+  source in multiple languages at once (eg PHP+HTML) [DONE IN 1.2]
+- Perhaps a script on the GeSHi site that would map urls to appropriate
+  definitions and relocate the user? (eg, java documentation is
+  structured in such a way that urls are not able to be used with GeSHi.
+  Instead the URL could become:
+  http://qbnz.com/highlighter/redirect.php?lang=java&kw=KeyWord
+  and that script would redirect to the correct location.
+  [BETTER FIX IN 1.2]
+
+              $Id: TODO 1727 2008-08-08 13:36:52Z benbe $
diff --git a/examples/includes/geshi/docs/api/__filesource/fsource_geshi_core_geshi.php.html b/examples/includes/geshi/docs/api/__filesource/fsource_geshi_core_geshi.php.html
new file mode 100644 (file)
index 0000000..3d79982
--- /dev/null
@@ -0,0 +1,4616 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title>File Source for geshi.php</title>
+                       <link rel="stylesheet" href="../media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               <h1>Source for file geshi.php</h1>
+<p>Documentation is available at <a href="../geshi/core/_geshi.php.html">geshi.php</a></p>
+<div class="src-code">
+<div class="src-code"><ol><li><div class="src-line"><a name="a1"></a><span class="src-php">&lt;?php</span></div></li>
+<li><div class="src-line"><a name="a2"></a><span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a3"></a><span class="src-doc">&nbsp;*&nbsp;GeSHi&nbsp;-&nbsp;Generic&nbsp;Syntax&nbsp;Highlighter</span></div></li>
+<li><div class="src-line"><a name="a4"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a5"></a><span class="src-doc">&nbsp;*&nbsp;The&nbsp;GeSHi&nbsp;class&nbsp;for&nbsp;Generic&nbsp;Syntax&nbsp;Highlighting.&nbsp;Please&nbsp;refer&nbsp;to&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a6"></a><span class="src-doc">&nbsp;*&nbsp;documentation&nbsp;at&nbsp;http://qbnz.com/highlighter/documentation.php&nbsp;for&nbsp;more</span></div></li>
+<li><div class="src-line"><a name="a7"></a><span class="src-doc">&nbsp;*&nbsp;information&nbsp;about&nbsp;how&nbsp;to&nbsp;use&nbsp;this&nbsp;class.</span></div></li>
+<li><div class="src-line"><a name="a8"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a9"></a><span class="src-doc">&nbsp;*&nbsp;For&nbsp;changes,&nbsp;release&nbsp;notes,&nbsp;TODOs&nbsp;etc,&nbsp;see&nbsp;the&nbsp;relevant&nbsp;files&nbsp;in&nbsp;the&nbsp;docs/</span></div></li>
+<li><div class="src-line"><a name="a10"></a><span class="src-doc">&nbsp;*&nbsp;directory.</span></div></li>
+<li><div class="src-line"><a name="a11"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a12"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;&nbsp;This&nbsp;file&nbsp;is&nbsp;part&nbsp;of&nbsp;GeSHi.</span></div></li>
+<li><div class="src-line"><a name="a13"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a14"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;GeSHi&nbsp;is&nbsp;free&nbsp;software;&nbsp;you&nbsp;can&nbsp;redistribute&nbsp;it&nbsp;and/or&nbsp;modify</span></div></li>
+<li><div class="src-line"><a name="a15"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;it&nbsp;under&nbsp;the&nbsp;terms&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;as&nbsp;published&nbsp;by</span></div></li>
+<li><div class="src-line"><a name="a16"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;the&nbsp;Free&nbsp;Software&nbsp;Foundation;&nbsp;either&nbsp;version&nbsp;2&nbsp;of&nbsp;the&nbsp;License,&nbsp;or</span></div></li>
+<li><div class="src-line"><a name="a17"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;(at&nbsp;your&nbsp;option)&nbsp;any&nbsp;later&nbsp;version.</span></div></li>
+<li><div class="src-line"><a name="a18"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a19"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;GeSHi&nbsp;is&nbsp;distributed&nbsp;in&nbsp;the&nbsp;hope&nbsp;that&nbsp;it&nbsp;will&nbsp;be&nbsp;useful,</span></div></li>
+<li><div class="src-line"><a name="a20"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;but&nbsp;WITHOUT&nbsp;ANY&nbsp;WARRANTY;&nbsp;without&nbsp;even&nbsp;the&nbsp;implied&nbsp;warranty&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a21"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;MERCHANTABILITY&nbsp;or&nbsp;FITNESS&nbsp;FOR&nbsp;A&nbsp;PARTICULAR&nbsp;PURPOSE.&nbsp;&nbsp;See&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a22"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License&nbsp;for&nbsp;more&nbsp;details.</span></div></li>
+<li><div class="src-line"><a name="a23"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a24"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;You&nbsp;should&nbsp;have&nbsp;received&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;GNU&nbsp;General&nbsp;Public&nbsp;License</span></div></li>
+<li><div class="src-line"><a name="a25"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;along&nbsp;with&nbsp;GeSHi;&nbsp;if&nbsp;not,&nbsp;write&nbsp;to&nbsp;the&nbsp;Free&nbsp;Software</span></div></li>
+<li><div class="src-line"><a name="a26"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;Foundation,&nbsp;Inc.,&nbsp;59&nbsp;Temple&nbsp;Place,&nbsp;Suite&nbsp;330,&nbsp;Boston,&nbsp;MA&nbsp;&nbsp;02111-1307&nbsp;&nbsp;USA</span></div></li>
+<li><div class="src-line"><a name="a27"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a28"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@package</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;geshi</span></div></li>
+<li><div class="src-line"><a name="a29"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@subpackage</span><span class="src-doc">&nbsp;core</span></div></li>
+<li><div class="src-line"><a name="a30"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@author</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nigel&nbsp;McNie&nbsp;&lt;nigel@geshi.org&gt;,&nbsp;Benny&nbsp;Baumann&nbsp;&lt;BenBE@omorphia.de&gt;</span></div></li>
+<li><div class="src-line"><a name="a31"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@copyright</span><span class="src-doc">&nbsp;&nbsp;(C)&nbsp;2004&nbsp;-&nbsp;2007&nbsp;Nigel&nbsp;McNie,&nbsp;(C)&nbsp;2007&nbsp;-&nbsp;2008&nbsp;Benny&nbsp;Baumann</span></div></li>
+<li><div class="src-line"><a name="a32"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@license</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;http://gnu.org/copyleft/gpl.html&nbsp;GNU&nbsp;GPL</span></div></li>
+<li><div class="src-line"><a name="a33"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a34"></a><span class="src-doc">&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a35"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a36"></a><span class="src-comm">//</span></div></li>
+<li><div class="src-line"><a name="a37"></a><span class="src-comm">//&nbsp;GeSHi&nbsp;Constants</span></div></li>
+<li><div class="src-line"><a name="a38"></a><span class="src-comm">//&nbsp;You&nbsp;should&nbsp;use&nbsp;these&nbsp;constant&nbsp;names&nbsp;in&nbsp;your&nbsp;programs&nbsp;instead&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a39"></a><span class="src-comm">//&nbsp;their&nbsp;values&nbsp;-&nbsp;you&nbsp;never&nbsp;know&nbsp;when&nbsp;a&nbsp;value&nbsp;may&nbsp;change&nbsp;in&nbsp;a&nbsp;future</span></div></li>
+<li><div class="src-line"><a name="a40"></a><span class="src-comm">//&nbsp;version</span></div></li>
+<li><div class="src-line"><a name="a41"></a><span class="src-comm">//</span></div></li>
+<li><div class="src-line"><a name="a42"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a43"></a><span class="src-doc">/**&nbsp;The&nbsp;version&nbsp;of&nbsp;this&nbsp;GeSHi&nbsp;file&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a44"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_VERSION'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'1.0.8.2'</span><span class="src-sym">,</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a45"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a46"></a><span class="src-comm">//&nbsp;Define&nbsp;the&nbsp;root&nbsp;directory&nbsp;for&nbsp;the&nbsp;GeSHi&nbsp;code&nbsp;tree</span></div></li>
+<li><div class="src-line"><a name="a47"></a><span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/defined">defined</a><span class="src-sym">(</span><span class="src-str">'GESHI_ROOT'</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a48"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**&nbsp;The&nbsp;root&nbsp;directory&nbsp;for&nbsp;GeSHi&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a49"></a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ROOT'</span><span class="src-sym">,&nbsp;</span><span class="src-id">dirname</span><span class="src-sym">(</span>__FILE__<span class="src-sym">)&nbsp;</span>.&nbsp;<span class="src-id">DIRECTORY_SEPARATOR</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a50"></a><span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a51"></a><span class="src-doc">/**&nbsp;The&nbsp;language&nbsp;file&nbsp;directory&nbsp;for&nbsp;GeSHi</span></div></li>
+<li><div class="src-line"><a name="a52"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;@access&nbsp;private&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a53"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_LANG_ROOT'</span><span class="src-sym">,&nbsp;</span><span class="src-id">GESHI_ROOT&nbsp;</span>.&nbsp;<span class="src-str">'geshi'&nbsp;</span>.&nbsp;<span class="src-id">DIRECTORY_SEPARATOR</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a54"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a55"></a><span class="src-comm">//&nbsp;Define&nbsp;if&nbsp;GeSHi&nbsp;should&nbsp;be&nbsp;paranoid&nbsp;about&nbsp;security</span></div></li>
+<li><div class="src-line"><a name="a56"></a><span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/defined">defined</a><span class="src-sym">(</span><span class="src-str">'GESHI_SECURITY_PARANOID'</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a57"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**&nbsp;Tells&nbsp;GeSHi&nbsp;to&nbsp;be&nbsp;paranoid&nbsp;about&nbsp;security&nbsp;settings&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a58"></a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_SECURITY_PARANOID'</span><span class="src-sym">,&nbsp;</span><span class="src-id">false</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a59"></a><span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a60"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a61"></a><span class="src-comm">//&nbsp;Line&nbsp;numbers&nbsp;-&nbsp;use&nbsp;with&nbsp;enable_line_numbers()</span></div></li>
+<li><div class="src-line"><a name="a62"></a><span class="src-doc">/**&nbsp;Use&nbsp;no&nbsp;line&nbsp;numbers&nbsp;when&nbsp;building&nbsp;the&nbsp;result&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a63"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NO_LINE_NUMBERS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a64"></a><span class="src-doc">/**&nbsp;Use&nbsp;normal&nbsp;line&nbsp;numbers&nbsp;when&nbsp;building&nbsp;the&nbsp;result&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a65"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NORMAL_LINE_NUMBERS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a66"></a><span class="src-doc">/**&nbsp;Use&nbsp;fancy&nbsp;line&nbsp;numbers&nbsp;when&nbsp;building&nbsp;the&nbsp;result&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a67"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_FANCY_LINE_NUMBERS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a68"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a69"></a><span class="src-comm">//&nbsp;Container&nbsp;HTML&nbsp;type</span></div></li>
+<li><div class="src-line"><a name="a70"></a><span class="src-doc">/**&nbsp;Use&nbsp;nothing&nbsp;to&nbsp;surround&nbsp;the&nbsp;source&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a71"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_HEADER_NONE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a72"></a><span class="src-doc">/**&nbsp;Use&nbsp;a&nbsp;&quot;div&quot;&nbsp;to&nbsp;surround&nbsp;the&nbsp;source&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a73"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_HEADER_DIV'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a74"></a><span class="src-doc">/**&nbsp;Use&nbsp;a&nbsp;&quot;pre&quot;&nbsp;to&nbsp;surround&nbsp;the&nbsp;source&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a75"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_HEADER_PRE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a76"></a><span class="src-doc">/**&nbsp;Use&nbsp;a&nbsp;pre&nbsp;to&nbsp;wrap&nbsp;lines&nbsp;when&nbsp;line&nbsp;numbers&nbsp;are&nbsp;enabled&nbsp;or&nbsp;to&nbsp;wrap&nbsp;the&nbsp;whole&nbsp;code.&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a77"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_HEADER_PRE_VALID'</span><span class="src-sym">,&nbsp;</span><span class="src-num">3</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a78"></a><span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a79"></a><span class="src-doc">&nbsp;*&nbsp;Use&nbsp;a&nbsp;&quot;table&quot;&nbsp;to&nbsp;surround&nbsp;the&nbsp;source:</span></div></li>
+<li><div class="src-line"><a name="a80"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a81"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;&lt;table&gt;</span></div></li>
+<li><div class="src-line"><a name="a82"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&lt;thead&gt;&lt;tr&gt;&lt;td&nbsp;colspan=&quot;2&quot;&gt;$header&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;</span></div></li>
+<li><div class="src-line"><a name="a83"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;$linenumbers&lt;/pre&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;$code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;</span></div></li>
+<li><div class="src-line"><a name="a84"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&lt;tfooter&gt;&lt;tr&gt;&lt;td&nbsp;colspan=&quot;2&quot;&gt;$footer&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;</span></div></li>
+<li><div class="src-line"><a name="a85"></a><span class="src-doc">&nbsp;*&nbsp;&nbsp;&lt;/table&gt;</span></div></li>
+<li><div class="src-line"><a name="a86"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a87"></a><span class="src-doc">&nbsp;*&nbsp;this&nbsp;is&nbsp;essentially&nbsp;only&nbsp;a&nbsp;workaround&nbsp;for&nbsp;Firefox,&nbsp;see&nbsp;sf#1651996&nbsp;or&nbsp;take&nbsp;a&nbsp;look&nbsp;at</span></div></li>
+<li><div class="src-line"><a name="a88"></a><span class="src-doc">&nbsp;*&nbsp;https://bugzilla.mozilla.org/show_bug.cgi?id=365805</span></div></li>
+<li><div class="src-line"><a name="a89"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-tag">@note</span><span class="src-doc">&nbsp;when&nbsp;linenumbers&nbsp;are&nbsp;disabled&nbsp;this&nbsp;is&nbsp;essentially&nbsp;the&nbsp;same&nbsp;as&nbsp;GESHI_HEADER_PRE</span></div></li>
+<li><div class="src-line"><a name="a90"></a><span class="src-doc">&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a91"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_HEADER_PRE_TABLE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">4</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a92"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a93"></a><span class="src-comm">//&nbsp;Capatalisation&nbsp;constants</span></div></li>
+<li><div class="src-line"><a name="a94"></a><span class="src-doc">/**&nbsp;Lowercase&nbsp;keywords&nbsp;found&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a95"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_CAPS_NO_CHANGE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a96"></a><span class="src-doc">/**&nbsp;Uppercase&nbsp;keywords&nbsp;found&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a97"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_CAPS_UPPER'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a98"></a><span class="src-doc">/**&nbsp;Leave&nbsp;keywords&nbsp;found&nbsp;as&nbsp;the&nbsp;case&nbsp;that&nbsp;they&nbsp;are&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a99"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_CAPS_LOWER'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a100"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a101"></a><span class="src-comm">//&nbsp;Link&nbsp;style&nbsp;constants</span></div></li>
+<li><div class="src-line"><a name="a102"></a><span class="src-doc">/**&nbsp;Links&nbsp;in&nbsp;the&nbsp;source&nbsp;in&nbsp;the&nbsp;:link&nbsp;state&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a103"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_LINK'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a104"></a><span class="src-doc">/**&nbsp;Links&nbsp;in&nbsp;the&nbsp;source&nbsp;in&nbsp;the&nbsp;:hover&nbsp;state&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a105"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_HOVER'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a106"></a><span class="src-doc">/**&nbsp;Links&nbsp;in&nbsp;the&nbsp;source&nbsp;in&nbsp;the&nbsp;:active&nbsp;state&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a107"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ACTIVE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a108"></a><span class="src-doc">/**&nbsp;Links&nbsp;in&nbsp;the&nbsp;source&nbsp;in&nbsp;the&nbsp;:visited&nbsp;state&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a109"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_VISITED'</span><span class="src-sym">,&nbsp;</span><span class="src-num">3</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a110"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a111"></a><span class="src-comm">//&nbsp;Important&nbsp;string&nbsp;starter/finisher</span></div></li>
+<li><div class="src-line"><a name="a112"></a><span class="src-comm">//&nbsp;Note&nbsp;that&nbsp;if&nbsp;you&nbsp;change&nbsp;these,&nbsp;they&nbsp;should&nbsp;be&nbsp;as-is:&nbsp;i.e.,&nbsp;don't</span></div></li>
+<li><div class="src-line"><a name="a113"></a><span class="src-comm">//&nbsp;write&nbsp;them&nbsp;as&nbsp;if&nbsp;they&nbsp;had&nbsp;been&nbsp;run&nbsp;through&nbsp;htmlentities()</span></div></li>
+<li><div class="src-line"><a name="a114"></a><span class="src-doc">/**&nbsp;The&nbsp;starter&nbsp;for&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;source&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a115"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_START_IMPORTANT'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'&lt;BEGIN&nbsp;GeSHi&gt;'</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a116"></a><span class="src-doc">/**&nbsp;The&nbsp;ender&nbsp;for&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;source&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a117"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_END_IMPORTANT'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'&lt;END&nbsp;GeSHi&gt;'</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a118"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a119"></a><span class="src-comm">/**#@+</span></div></li>
+<li><div class="src-line"><a name="a120"></a><span class="src-comm">&nbsp;*&nbsp;&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a121"></a><span class="src-comm">&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a122"></a><span class="src-comm">//&nbsp;When&nbsp;strict&nbsp;mode&nbsp;applies&nbsp;for&nbsp;a&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a123"></a><span class="src-doc">/**&nbsp;Strict&nbsp;mode&nbsp;never&nbsp;applies&nbsp;(this&nbsp;is&nbsp;the&nbsp;most&nbsp;common)&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a124"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NEVER'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a125"></a><span class="src-doc">/**&nbsp;Strict&nbsp;mode&nbsp;*might*&nbsp;apply,&nbsp;and&nbsp;can&nbsp;be&nbsp;enabled&nbsp;or</span></div></li>
+<li><div class="src-line"><a name="a126"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;disabled&nbsp;by&nbsp;</span><span class="src-doc-inlinetag">{@link&nbsp;GeSHi-&gt;enable_strict_mode()}</span><span class="src-doc">&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a127"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_MAYBE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a128"></a><span class="src-doc">/**&nbsp;Strict&nbsp;mode&nbsp;always&nbsp;applies&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a129"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ALWAYS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a130"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a131"></a><span class="src-comm">//&nbsp;Advanced&nbsp;regexp&nbsp;handling&nbsp;constants,&nbsp;used&nbsp;in&nbsp;language&nbsp;files</span></div></li>
+<li><div class="src-line"><a name="a132"></a><span class="src-doc">/**&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regex&nbsp;array&nbsp;defining&nbsp;what&nbsp;to&nbsp;search&nbsp;for&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a133"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_SEARCH'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a134"></a><span class="src-doc">/**&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regex&nbsp;array&nbsp;defining&nbsp;what&nbsp;bracket&nbsp;group&nbsp;in&nbsp;a</span></div></li>
+<li><div class="src-line"><a name="a135"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;matched&nbsp;search&nbsp;to&nbsp;use&nbsp;as&nbsp;a&nbsp;replacement&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a136"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_REPLACE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a137"></a><span class="src-doc">/**&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regex&nbsp;array&nbsp;defining&nbsp;any&nbsp;modifiers&nbsp;to&nbsp;the&nbsp;regular&nbsp;expression&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a138"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_MODIFIERS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a139"></a><span class="src-doc">/**&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regex&nbsp;array&nbsp;defining&nbsp;what&nbsp;bracket&nbsp;group&nbsp;in&nbsp;a</span></div></li>
+<li><div class="src-line"><a name="a140"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;matched&nbsp;search&nbsp;to&nbsp;put&nbsp;before&nbsp;the&nbsp;replacement&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a141"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_BEFORE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">3</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a142"></a><span class="src-doc">/**&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regex&nbsp;array&nbsp;defining&nbsp;what&nbsp;bracket&nbsp;group&nbsp;in&nbsp;a</span></div></li>
+<li><div class="src-line"><a name="a143"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;matched&nbsp;search&nbsp;to&nbsp;put&nbsp;after&nbsp;the&nbsp;replacement&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a144"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_AFTER'</span><span class="src-sym">,&nbsp;</span><span class="src-num">4</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a145"></a><span class="src-doc">/**&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regex&nbsp;array&nbsp;defining&nbsp;a&nbsp;custom&nbsp;keyword&nbsp;to&nbsp;use</span></div></li>
+<li><div class="src-line"><a name="a146"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;this&nbsp;regexp's&nbsp;html&nbsp;tag&nbsp;class&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a147"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_CLASS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">5</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a148"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a149"></a><span class="src-doc">/**&nbsp;Used&nbsp;in&nbsp;language&nbsp;files&nbsp;to&nbsp;mark&nbsp;comments&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a150"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_COMMENTS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a151"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a152"></a><span class="src-doc">/**&nbsp;Used&nbsp;to&nbsp;work&nbsp;around&nbsp;missing&nbsp;PHP&nbsp;features&nbsp;**/</span></div></li>
+<li><div class="src-line"><a name="a153"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_PHP_PRE_433'</span><span class="src-sym">,&nbsp;</span><span class="src-sym">!</span><span class="src-sym">(</span><span class="src-id">version_compare</span><span class="src-sym">(</span><span class="src-id">PHP_VERSION</span><span class="src-sym">,&nbsp;</span><span class="src-str">'4.3.3'</span><span class="src-sym">)&nbsp;</span>===&nbsp;<span class="src-num">1</span><span class="src-sym">))</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a154"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a155"></a><span class="src-doc">/**&nbsp;make&nbsp;sure&nbsp;we&nbsp;can&nbsp;call&nbsp;stripos&nbsp;**/</span></div></li>
+<li><div class="src-line"><a name="a156"></a><span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/function_exists">function_exists</a><span class="src-sym">(</span><span class="src-str">'stripos'</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a157"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;offset&nbsp;param&nbsp;of&nbsp;preg_match&nbsp;is&nbsp;not&nbsp;supported&nbsp;below&nbsp;PHP&nbsp;4.3.3</span></div></li>
+<li><div class="src-line"><a name="a158"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-id">GESHI_PHP_PRE_433</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a159"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a160"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@ignore</span></div></li>
+<li><div class="src-line"><a name="a161"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a162"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><a href="http://www.php.net/stripos">stripos</a><span class="src-sym">(</span><span class="src-var">$haystack</span><span class="src-sym">,&nbsp;</span><span class="src-var">$needle</span><span class="src-sym">,&nbsp;</span><span class="src-var">$offset&nbsp;</span>=&nbsp;<span class="src-id">null</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a163"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/is_null">is_null</a><span class="src-sym">(</span><span class="src-var">$offset</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a164"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$haystack&nbsp;</span>=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$haystack</span><span class="src-sym">,&nbsp;</span><span class="src-var">$offset</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a165"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a166"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-str">'/'</span>.&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$needle</span><span class="src-sym">,&nbsp;</span><span class="src-str">'/'</span><span class="src-sym">)&nbsp;</span>.&nbsp;<span class="src-str">'/'</span><span class="src-sym">,&nbsp;</span><span class="src-var">$haystack</span><span class="src-sym">,&nbsp;</span><span class="src-var">$match</span><span class="src-sym">,&nbsp;</span><span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a167"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a168"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a169"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a170"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a171"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a172"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">else&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a173"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a174"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@ignore</span></div></li>
+<li><div class="src-line"><a name="a175"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a176"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><a href="http://www.php.net/stripos">stripos</a><span class="src-sym">(</span><span class="src-var">$haystack</span><span class="src-sym">,&nbsp;</span><span class="src-var">$needle</span><span class="src-sym">,&nbsp;</span><span class="src-var">$offset&nbsp;</span>=&nbsp;<span class="src-id">null</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a177"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-str">'/'</span>.&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$needle</span><span class="src-sym">,&nbsp;</span><span class="src-str">'/'</span><span class="src-sym">)&nbsp;</span>.&nbsp;<span class="src-str">'/'</span><span class="src-sym">,&nbsp;</span><span class="src-var">$haystack</span><span class="src-sym">,&nbsp;</span><span class="src-var">$match</span><span class="src-sym">,&nbsp;</span><span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">,&nbsp;</span><span class="src-var">$offset</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a178"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a179"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a180"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a181"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a182"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a183"></a><span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a184"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a185"></a><span class="src-doc">/**&nbsp;some&nbsp;old&nbsp;PHP&nbsp;/&nbsp;PCRE&nbsp;subpatterns&nbsp;only&nbsp;support&nbsp;up&nbsp;to&nbsp;xxx&nbsp;subpatterns&nbsp;in</span></div></li>
+<li><div class="src-line"><a name="a186"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;regular&nbsp;expressions.&nbsp;Set&nbsp;this&nbsp;to&nbsp;false&nbsp;if&nbsp;your&nbsp;PCRE&nbsp;lib&nbsp;is&nbsp;up&nbsp;to&nbsp;date</span></div></li>
+<li><div class="src-line"><a name="a187"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;@see&nbsp;GeSHi-&gt;optimize_regexp_list()</span></div></li>
+<li><div class="src-line"><a name="a188"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;**/</span></div></li>
+<li><div class="src-line"><a name="a188"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a189"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_MAX_PCRE_SUBPATTERNS'</span><span class="src-sym">,&nbsp;</span><span class="src-num">500</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a190"></a><span class="src-doc">/**&nbsp;it's&nbsp;also&nbsp;important&nbsp;not&nbsp;to&nbsp;generate&nbsp;too&nbsp;long&nbsp;regular&nbsp;expressions</span></div></li>
+<li><div class="src-line"><a name="a191"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;generous&nbsp;here...&nbsp;but&nbsp;keep&nbsp;in&nbsp;mind,&nbsp;that&nbsp;when&nbsp;reaching&nbsp;this&nbsp;limit&nbsp;we</span></div></li>
+<li><div class="src-line"><a name="a192"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;still&nbsp;have&nbsp;to&nbsp;close&nbsp;open&nbsp;patterns.&nbsp;12k&nbsp;should&nbsp;do&nbsp;just&nbsp;fine&nbsp;on&nbsp;a&nbsp;16k&nbsp;limit.</span></div></li>
+<li><div class="src-line"><a name="a193"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;@see&nbsp;GeSHi-&gt;optimize_regexp_list()</span></div></li>
+<li><div class="src-line"><a name="a194"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;**/</span></div></li>
+<li><div class="src-line"><a name="a194"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a195"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_MAX_PCRE_LENGTH'</span><span class="src-sym">,&nbsp;</span><span class="src-num">12288</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a196"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a197"></a><span class="src-comm">//Number&nbsp;format&nbsp;specification</span></div></li>
+<li><div class="src-line"><a name="a198"></a><span class="src-doc">/**&nbsp;Basic&nbsp;number&nbsp;format&nbsp;for&nbsp;integers&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a199"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_INT_BASIC'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//Default&nbsp;integers&nbsp;\d+</span></div></li>
+<li><div class="src-line"><a name="a200"></a><span class="src-doc">/**&nbsp;Enhanced&nbsp;number&nbsp;format&nbsp;for&nbsp;integers&nbsp;like&nbsp;seen&nbsp;in&nbsp;C&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a201"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_INT_CSTYLE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//Default&nbsp;C-Style&nbsp;\d+[lL]?</span></div></li>
+<li><div class="src-line"><a name="a202"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;binary&nbsp;numbers&nbsp;with&nbsp;a&nbsp;suffix&nbsp;&quot;b&quot;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a203"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_BIN_SUFFIX'</span><span class="src-sym">,&nbsp;</span><span class="src-num">16</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//[01]+[bB]</span></div></li>
+<li><div class="src-line"><a name="a204"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;binary&nbsp;numbers&nbsp;with&nbsp;a&nbsp;prefix&nbsp;%&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a205"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_BIN_PREFIX_PERCENT'</span><span class="src-sym">,&nbsp;</span><span class="src-num">32</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//%[01]+</span></div></li>
+<li><div class="src-line"><a name="a206"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;binary&nbsp;numbers&nbsp;with&nbsp;a&nbsp;prefix&nbsp;0b&nbsp;(C)&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a207"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_BIN_PREFIX_0B'</span><span class="src-sym">,&nbsp;</span><span class="src-num">64</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//0b[01]+</span></div></li>
+<li><div class="src-line"><a name="a208"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;octal&nbsp;numbers&nbsp;with&nbsp;a&nbsp;leading&nbsp;zero&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a209"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_OCT_PREFIX'</span><span class="src-sym">,&nbsp;</span><span class="src-num">256</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//0[0-7]+</span></div></li>
+<li><div class="src-line"><a name="a210"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;octal&nbsp;numbers&nbsp;with&nbsp;a&nbsp;suffix&nbsp;of&nbsp;o&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a211"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_OCT_SUFFIX'</span><span class="src-sym">,&nbsp;</span><span class="src-num">512</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//[0-7]+[oO]</span></div></li>
+<li><div class="src-line"><a name="a212"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;hex&nbsp;numbers&nbsp;with&nbsp;a&nbsp;prefix&nbsp;0x&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a213"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_HEX_PREFIX'</span><span class="src-sym">,&nbsp;</span><span class="src-num">4096</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//0x[0-9a-fA-F]+</span></div></li>
+<li><div class="src-line"><a name="a214"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;hex&nbsp;numbers&nbsp;with&nbsp;a&nbsp;suffix&nbsp;of&nbsp;h&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a215"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_HEX_SUFFIX'</span><span class="src-sym">,&nbsp;</span><span class="src-num">8192</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//[0-9][0-9a-fA-F]*h</span></div></li>
+<li><div class="src-line"><a name="a216"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;floating-point&nbsp;numbers&nbsp;without&nbsp;support&nbsp;for&nbsp;scientific&nbsp;notation&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a217"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_FLT_NONSCI'</span><span class="src-sym">,&nbsp;</span><span class="src-num">65536</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//\d+\.\d+</span></div></li>
+<li><div class="src-line"><a name="a218"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;floating-point&nbsp;numbers&nbsp;without&nbsp;support&nbsp;for&nbsp;scientific&nbsp;notation&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a219"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_FLT_NONSCI_F'</span><span class="src-sym">,&nbsp;</span><span class="src-num">131072</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//\d+(\.\d+)?f</span></div></li>
+<li><div class="src-line"><a name="a220"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;floating-point&nbsp;numbers&nbsp;with&nbsp;support&nbsp;for&nbsp;scientific&nbsp;notation&nbsp;(E)&nbsp;and&nbsp;optional&nbsp;leading&nbsp;zero&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a221"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_FLT_SCI_SHORT'</span><span class="src-sym">,&nbsp;</span><span class="src-num">262144</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//\.\d+e\d+</span></div></li>
+<li><div class="src-line"><a name="a222"></a><span class="src-doc">/**&nbsp;Number&nbsp;format&nbsp;to&nbsp;highlight&nbsp;floating-point&nbsp;numbers&nbsp;with&nbsp;support&nbsp;for&nbsp;scientific&nbsp;notation&nbsp;(E)&nbsp;and&nbsp;required&nbsp;leading&nbsp;digit&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a223"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_NUMBER_FLT_SCI_ZERO'</span><span class="src-sym">,&nbsp;</span><span class="src-num">524288</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-comm">//\d+(\.\d+)?e\d+</span></div></li>
+<li><div class="src-line"><a name="a224"></a><span class="src-comm">//Custom&nbsp;formats&nbsp;are&nbsp;passed&nbsp;by&nbsp;RX&nbsp;array</span></div></li>
+<li><div class="src-line"><a name="a225"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a226"></a><span class="src-comm">//&nbsp;Error&nbsp;detection&nbsp;-&nbsp;use&nbsp;these&nbsp;to&nbsp;analyse&nbsp;faults</span></div></li>
+<li><div class="src-line"><a name="a227"></a><span class="src-doc">/**&nbsp;No&nbsp;sourcecode&nbsp;to&nbsp;highlight&nbsp;was&nbsp;specified</span></div></li>
+<li><div class="src-line"><a name="a228"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span></div></li>
+<li><div class="src-line"><a name="a229"></a><span class="src-doc">&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a230"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ERROR_NO_INPUT'</span><span class="src-sym">,&nbsp;</span><span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a231"></a><span class="src-doc">/**&nbsp;The&nbsp;language&nbsp;specified&nbsp;does&nbsp;not&nbsp;exist&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a232"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ERROR_NO_SUCH_LANG'</span><span class="src-sym">,&nbsp;</span><span class="src-num">2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a233"></a><span class="src-doc">/**&nbsp;GeSHi&nbsp;could&nbsp;not&nbsp;open&nbsp;a&nbsp;file&nbsp;for&nbsp;reading&nbsp;(generally&nbsp;a&nbsp;language&nbsp;file)&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a234"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ERROR_FILE_NOT_READABLE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">3</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a235"></a><span class="src-doc">/**&nbsp;The&nbsp;header&nbsp;type&nbsp;passed&nbsp;to&nbsp;</span><span class="src-doc-inlinetag">{@link&nbsp;GeSHi-&gt;set_header_type()}</span><span class="src-doc">&nbsp;was&nbsp;invalid&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a236"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ERROR_INVALID_HEADER_TYPE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">4</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a237"></a><span class="src-doc">/**&nbsp;The&nbsp;line&nbsp;number&nbsp;type&nbsp;passed&nbsp;to&nbsp;</span><span class="src-doc-inlinetag">{@link&nbsp;GeSHi-&gt;enable_line_numbers()}</span><span class="src-doc">&nbsp;was&nbsp;invalid&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a238"></a><a href="http://www.php.net/define">define</a><span class="src-sym">(</span><span class="src-str">'GESHI_ERROR_INVALID_LINE_NUMBER_TYPE'</span><span class="src-sym">,&nbsp;</span><span class="src-num">5</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a239"></a><span class="src-comm">/**#@-*/</span></div></li>
+<li><div class="src-line"><a name="a240"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a241"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a242"></a><span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a243"></a><span class="src-doc">&nbsp;*&nbsp;The&nbsp;GeSHi&nbsp;Class.</span></div></li>
+<li><div class="src-line"><a name="a244"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a245"></a><span class="src-doc">&nbsp;*&nbsp;Please&nbsp;refer&nbsp;to&nbsp;the&nbsp;documentation&nbsp;for&nbsp;GeSHi&nbsp;1.0.X&nbsp;that&nbsp;is&nbsp;available</span></div></li>
+<li><div class="src-line"><a name="a246"></a><span class="src-doc">&nbsp;*&nbsp;at&nbsp;http://qbnz.com/highlighter/documentation.php&nbsp;for&nbsp;more&nbsp;information</span></div></li>
+<li><div class="src-line"><a name="a247"></a><span class="src-doc">&nbsp;*&nbsp;about&nbsp;how&nbsp;to&nbsp;use&nbsp;this&nbsp;class.</span></div></li>
+<li><div class="src-line"><a name="a248"></a><span class="src-doc">&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a249"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@package</span><span class="src-doc">&nbsp;&nbsp;&nbsp;geshi</span></div></li>
+<li><div class="src-line"><a name="a250"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@author</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;Nigel&nbsp;McNie&nbsp;&lt;nigel@geshi.org&gt;,&nbsp;Benny&nbsp;Baumann&nbsp;&lt;BenBE@omorphia.de&gt;</span></div></li>
+<li><div class="src-line"><a name="a251"></a><span class="src-doc">&nbsp;*&nbsp;</span><span class="src-doc-coretag">@copyright</span><span class="src-doc">&nbsp;(C)&nbsp;2004&nbsp;-&nbsp;2007&nbsp;Nigel&nbsp;McNie,&nbsp;(C)&nbsp;2007&nbsp;-&nbsp;2008&nbsp;Benny&nbsp;Baumann</span></div></li>
+<li><div class="src-line"><a name="a252"></a><span class="src-doc">&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a253"></a><span class="src-key">class&nbsp;</span><a href="../geshi/core/GeSHi.html">GeSHi</a>&nbsp;<span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a254"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">/**#@+</span></div></li>
+<li><div class="src-line"><a name="a255"></a><span class="src-comm">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a256"></a><span class="src-comm">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a257"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a258"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;source&nbsp;code&nbsp;to&nbsp;highlight</span></div></li>
+<li><div class="src-line"><a name="a259"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a260"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a261"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$source&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a262"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a263"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a264"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;language&nbsp;to&nbsp;use&nbsp;when&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a265"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a266"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a267"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$language&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a268"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a269"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a270"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;data&nbsp;for&nbsp;the&nbsp;language&nbsp;used</span></div></li>
+<li><div class="src-line"><a name="a271"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a272"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a273"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$language_data&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a274"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a275"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a276"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;language&nbsp;files</span></div></li>
+<li><div class="src-line"><a name="a277"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a278"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a279"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$language_path&nbsp;</span>=&nbsp;<span class="src-id">GESHI_LANG_ROOT</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a280"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a281"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a282"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;error&nbsp;message&nbsp;associated&nbsp;with&nbsp;an&nbsp;error</span></div></li>
+<li><div class="src-line"><a name="a283"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a284"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;check&nbsp;err&nbsp;reporting&nbsp;works</span></div></li>
+<li><div class="src-line"><a name="a285"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a286"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$error&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a287"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a288"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a289"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Possible&nbsp;error&nbsp;messages</span></div></li>
+<li><div class="src-line"><a name="a290"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a291"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a292"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$error_messages&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></div></li>
+<li><div class="src-line"><a name="a293"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_ERROR_NO_SUCH_LANG&nbsp;</span>=&gt;&nbsp;<span class="src-str">'GeSHi&nbsp;could&nbsp;not&nbsp;find&nbsp;the&nbsp;language&nbsp;{LANGUAGE}&nbsp;(using&nbsp;path&nbsp;{PATH})'</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a294"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_ERROR_FILE_NOT_READABLE&nbsp;</span>=&gt;&nbsp;<span class="src-str">'The&nbsp;file&nbsp;specified&nbsp;for&nbsp;load_from_file&nbsp;was&nbsp;not&nbsp;readable'</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a295"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_ERROR_INVALID_HEADER_TYPE&nbsp;</span>=&gt;&nbsp;<span class="src-str">'The&nbsp;header&nbsp;type&nbsp;specified&nbsp;is&nbsp;invalid'</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a296"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_ERROR_INVALID_LINE_NUMBER_TYPE&nbsp;</span>=&gt;&nbsp;<span class="src-str">'The&nbsp;line&nbsp;number&nbsp;type&nbsp;specified&nbsp;is&nbsp;invalid'</span></div></li>
+<li><div class="src-line"><a name="a297"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a298"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a299"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a300"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Whether&nbsp;highlighting&nbsp;is&nbsp;strict&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a301"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a302"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a303"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$strict_mode&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a304"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a305"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a306"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Whether&nbsp;to&nbsp;use&nbsp;CSS&nbsp;classes&nbsp;in&nbsp;output</span></div></li>
+<li><div class="src-line"><a name="a307"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a308"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a309"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$use_classes&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a310"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a311"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a312"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;type&nbsp;of&nbsp;header&nbsp;to&nbsp;use.&nbsp;Can&nbsp;be&nbsp;one&nbsp;of&nbsp;the&nbsp;following</span></div></li>
+<li><div class="src-line"><a name="a313"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;values:</span></div></li>
+<li><div class="src-line"><a name="a314"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a315"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;-&nbsp;GESHI_HEADER_PRE:&nbsp;Source&nbsp;is&nbsp;outputted&nbsp;in&nbsp;a&nbsp;&quot;pre&quot;&nbsp;HTML&nbsp;element.</span></div></li>
+<li><div class="src-line"><a name="a316"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;-&nbsp;GESHI_HEADER_DIV:&nbsp;Source&nbsp;is&nbsp;outputted&nbsp;in&nbsp;a&nbsp;&quot;div&quot;&nbsp;HTML&nbsp;element.</span></div></li>
+<li><div class="src-line"><a name="a317"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;-&nbsp;GESHI_HEADER_NONE:&nbsp;No&nbsp;header&nbsp;is&nbsp;outputted.</span></div></li>
+<li><div class="src-line"><a name="a318"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a319"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">int&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a320"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a321"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$header_type&nbsp;</span>=&nbsp;<span class="src-id">GESHI_HEADER_PRE</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a322"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a323"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a324"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Array&nbsp;of&nbsp;permissions&nbsp;for&nbsp;which&nbsp;lexics&nbsp;should&nbsp;be&nbsp;highlighted</span></div></li>
+<li><div class="src-line"><a name="a325"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a326"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a327"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$lexic_permissions&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></div></li>
+<li><div class="src-line"><a name="a328"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'KEYWORDS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a329"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'COMMENTS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'MULTI'&nbsp;</span>=&gt;&nbsp;<span class="src-id">true</span><span class="src-sym">)</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a330"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'REGEXPS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a331"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'ESCAPE_CHAR'&nbsp;</span>=&gt;&nbsp;<span class="src-id">true</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a332"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'BRACKETS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">true</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a333"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'SYMBOLS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">false</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a334"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'STRINGS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">true</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a335"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'NUMBERS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">true</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a336"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'METHODS'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">true</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a337"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'SCRIPT'&nbsp;</span>=&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">true</span></div></li>
+<li><div class="src-line"><a name="a338"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a339"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a340"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a341"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;time&nbsp;it&nbsp;took&nbsp;to&nbsp;parse&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a342"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">double&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a343"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a344"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$time&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a345"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a346"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a347"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;content&nbsp;of&nbsp;the&nbsp;header&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a348"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a349"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a350"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$header_content&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a351"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a352"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a353"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;content&nbsp;of&nbsp;the&nbsp;footer&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a354"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a355"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a356"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$footer_content&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a357"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a358"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a359"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;style&nbsp;of&nbsp;the&nbsp;header&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a360"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a361"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a362"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$header_content_style&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a363"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a364"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a365"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;style&nbsp;of&nbsp;the&nbsp;footer&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a366"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a367"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a368"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$footer_content_style&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a369"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a370"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a371"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Tells&nbsp;if&nbsp;a&nbsp;block&nbsp;around&nbsp;the&nbsp;highlighted&nbsp;source&nbsp;should&nbsp;be&nbsp;forced</span></div></li>
+<li><div class="src-line"><a name="a372"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;if&nbsp;not&nbsp;using&nbsp;line&nbsp;numbering</span></div></li>
+<li><div class="src-line"><a name="a373"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a374"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a375"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$force_code_block&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a376"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a377"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a378"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;styles&nbsp;for&nbsp;hyperlinks&nbsp;in&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a379"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a380"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a381"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$link_styles&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a382"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a383"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a384"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Whether&nbsp;important&nbsp;blocks&nbsp;should&nbsp;be&nbsp;recognised&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a385"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a386"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span></div></li>
+<li><div class="src-line"><a name="a387"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;REMOVE&nbsp;THIS&nbsp;FUNCTIONALITY!</span></div></li>
+<li><div class="src-line"><a name="a388"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a389"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$enable_important_blocks&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a390"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a391"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a392"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Styles&nbsp;for&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a393"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a394"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span></div></li>
+<li><div class="src-line"><a name="a395"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;As&nbsp;above&nbsp;-&nbsp;rethink&nbsp;the&nbsp;whole&nbsp;idea&nbsp;of&nbsp;important&nbsp;blocks&nbsp;as&nbsp;it&nbsp;is&nbsp;buggy&nbsp;and</span></div></li>
+<li><div class="src-line"><a name="a396"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;will&nbsp;be&nbsp;hard&nbsp;to&nbsp;implement&nbsp;in&nbsp;1.2</span></div></li>
+<li><div class="src-line"><a name="a397"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a398"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$important_styles&nbsp;</span>=&nbsp;<span class="src-str">'font-weight:&nbsp;bold;&nbsp;color:&nbsp;red;'</span><span class="src-sym">;&nbsp;</span><span class="src-comm">//&nbsp;Styles&nbsp;for&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a399"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a400"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a401"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Whether&nbsp;CSS&nbsp;IDs&nbsp;should&nbsp;be&nbsp;added&nbsp;to&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a402"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a403"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a404"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$add_ids&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a405"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a406"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a407"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Lines&nbsp;that&nbsp;should&nbsp;be&nbsp;highlighted&nbsp;extra</span></div></li>
+<li><div class="src-line"><a name="a408"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a409"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a410"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$highlight_extra_lines&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a411"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a412"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a413"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Styles&nbsp;of&nbsp;lines&nbsp;that&nbsp;should&nbsp;be&nbsp;highlighted&nbsp;extra</span></div></li>
+<li><div class="src-line"><a name="a414"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a415"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a416"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$highlight_extra_lines_styles&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a417"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a418"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a419"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Styles&nbsp;of&nbsp;extra-highlighted&nbsp;lines</span></div></li>
+<li><div class="src-line"><a name="a420"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a421"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a422"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$highlight_extra_lines_style&nbsp;</span>=&nbsp;<span class="src-str">'background-color:&nbsp;#ffc;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a423"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a424"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a425"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;line&nbsp;ending</span></div></li>
+<li><div class="src-line"><a name="a426"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;If&nbsp;null,&nbsp;nl2br()&nbsp;will&nbsp;be&nbsp;used&nbsp;on&nbsp;the&nbsp;result&nbsp;string.</span></div></li>
+<li><div class="src-line"><a name="a427"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Otherwise,&nbsp;all&nbsp;instances&nbsp;of&nbsp;\n&nbsp;will&nbsp;be&nbsp;replaced&nbsp;with&nbsp;$line_ending</span></div></li>
+<li><div class="src-line"><a name="a428"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a429"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a430"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$line_ending&nbsp;</span>=&nbsp;<span class="src-id">null</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a431"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a432"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a433"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Number&nbsp;at&nbsp;which&nbsp;line&nbsp;numbers&nbsp;should&nbsp;start&nbsp;at</span></div></li>
+<li><div class="src-line"><a name="a434"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">int&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a435"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a436"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$line_numbers_start&nbsp;</span>=&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a437"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a438"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a439"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;overall&nbsp;style&nbsp;for&nbsp;this&nbsp;code&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a440"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a441"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a442"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$overall_style&nbsp;</span>=&nbsp;<span class="src-str">'font-family:monospace;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a443"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a444"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a445"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;The&nbsp;style&nbsp;for&nbsp;the&nbsp;actual&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a446"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a447"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a448"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$code_style&nbsp;</span>=&nbsp;<span class="src-str">'font:&nbsp;normal&nbsp;normal&nbsp;1em/1.2em&nbsp;monospace;&nbsp;margin:0;&nbsp;padding:0;&nbsp;background:none;&nbsp;vertical-align:top;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a449"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a450"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a451"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;overall&nbsp;class&nbsp;for&nbsp;this&nbsp;code&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a452"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a453"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a454"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$overall_class&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a455"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a456"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a457"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;overall&nbsp;ID&nbsp;for&nbsp;this&nbsp;code&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a458"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a459"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a460"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$overall_id&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a461"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a462"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a463"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Line&nbsp;number&nbsp;styles</span></div></li>
+<li><div class="src-line"><a name="a464"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a465"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a466"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$line_style1&nbsp;</span>=&nbsp;<span class="src-str">'font-weight:&nbsp;normal;&nbsp;vertical-align:top;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a467"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a468"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a469"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Line&nbsp;number&nbsp;styles&nbsp;for&nbsp;fancy&nbsp;lines</span></div></li>
+<li><div class="src-line"><a name="a470"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a471"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a472"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$line_style2&nbsp;</span>=&nbsp;<span class="src-str">'font-weight:&nbsp;bold;&nbsp;vertical-align:top;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a473"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a474"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a475"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Style&nbsp;for&nbsp;line&nbsp;numbers&nbsp;when&nbsp;GESHI_HEADER_PRE_TABLE&nbsp;is&nbsp;chosen</span></div></li>
+<li><div class="src-line"><a name="a476"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a477"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a478"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$table_linenumber_style&nbsp;</span>=&nbsp;<span class="src-str">'width:1px;text-align:right;margin:0;padding:0&nbsp;2px;vertical-align:top;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a479"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a480"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a481"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Flag&nbsp;for&nbsp;how&nbsp;line&nbsp;numbers&nbsp;are&nbsp;displayed</span></div></li>
+<li><div class="src-line"><a name="a482"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a483"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a484"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$line_numbers&nbsp;</span>=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a485"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a486"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a487"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Flag&nbsp;to&nbsp;decide&nbsp;if&nbsp;multi&nbsp;line&nbsp;spans&nbsp;are&nbsp;allowed.&nbsp;Set&nbsp;it&nbsp;to&nbsp;false&nbsp;to&nbsp;make&nbsp;sure</span></div></li>
+<li><div class="src-line"><a name="a488"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;each&nbsp;tag&nbsp;is&nbsp;closed&nbsp;before&nbsp;and&nbsp;reopened&nbsp;after&nbsp;each&nbsp;linefeed.</span></div></li>
+<li><div class="src-line"><a name="a489"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a490"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a491"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$allow_multiline_span&nbsp;</span>=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a492"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a493"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a494"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;&quot;nth&quot;&nbsp;value&nbsp;for&nbsp;fancy&nbsp;line&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a495"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">int&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a496"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a497"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$line_nth_row&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a498"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a499"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a500"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;size&nbsp;of&nbsp;tab&nbsp;stops</span></div></li>
+<li><div class="src-line"><a name="a501"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">int&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a502"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a503"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$tab_width&nbsp;</span>=&nbsp;<span class="src-num">8</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a504"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a505"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a506"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Should&nbsp;we&nbsp;use&nbsp;language-defined&nbsp;tab&nbsp;stop&nbsp;widths?</span></div></li>
+<li><div class="src-line"><a name="a507"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">int&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a508"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a509"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$use_language_tab_width&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a510"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a511"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a512"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Default&nbsp;target&nbsp;for&nbsp;keyword&nbsp;links</span></div></li>
+<li><div class="src-line"><a name="a513"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a514"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a515"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$link_target&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a516"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a517"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a518"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;encoding&nbsp;to&nbsp;use&nbsp;for&nbsp;entity&nbsp;encoding</span></div></li>
+<li><div class="src-line"><a name="a519"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;NOTE:&nbsp;Used&nbsp;with&nbsp;Escape&nbsp;Char&nbsp;Sequences&nbsp;to&nbsp;fix&nbsp;UTF-8&nbsp;handling&nbsp;(cf.&nbsp;SF#2037598)</span></div></li>
+<li><div class="src-line"><a name="a520"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a521"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a522"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$encoding&nbsp;</span>=&nbsp;<span class="src-str">'utf-8'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a523"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a524"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a525"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Should&nbsp;keywords&nbsp;be&nbsp;linked?</span></div></li>
+<li><div class="src-line"><a name="a526"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a527"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a528"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$keyword_links&nbsp;</span>=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a529"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a530"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a531"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Currently&nbsp;loaded&nbsp;language&nbsp;file</span></div></li>
+<li><div class="src-line"><a name="a532"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a533"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.7.22</span></div></li>
+<li><div class="src-line"><a name="a534"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a535"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$loaded_language&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a536"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a537"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a538"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Wether&nbsp;the&nbsp;caches&nbsp;needed&nbsp;for&nbsp;parsing&nbsp;are&nbsp;built&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a539"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a540"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">bool&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a541"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a542"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a543"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$parse_cache_built&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a544"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a545"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a546"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Work&nbsp;around&nbsp;for&nbsp;Suhosin&nbsp;Patch&nbsp;with&nbsp;disabled&nbsp;/e&nbsp;modifier</span></div></li>
+<li><div class="src-line"><a name="a547"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a548"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Note&nbsp;from&nbsp;suhosins&nbsp;author&nbsp;in&nbsp;config&nbsp;file:</span></div></li>
+<li><div class="src-line"><a name="a549"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;blockquote&gt;</span></div></li>
+<li><div class="src-line"><a name="a550"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;The&nbsp;/e&nbsp;modifier&nbsp;inside&nbsp;&lt;code&gt;preg_replace()&lt;/code&gt;&nbsp;allows&nbsp;code&nbsp;execution.</span></div></li>
+<li><div class="src-line"><a name="a551"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;Often&nbsp;it&nbsp;is&nbsp;the&nbsp;cause&nbsp;for&nbsp;remote&nbsp;code&nbsp;execution&nbsp;exploits.&nbsp;It&nbsp;is&nbsp;wise&nbsp;to</span></div></li>
+<li><div class="src-line"><a name="a552"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;deactivate&nbsp;this&nbsp;feature&nbsp;and&nbsp;test&nbsp;where&nbsp;in&nbsp;the&nbsp;application&nbsp;it&nbsp;is&nbsp;used.</span></div></li>
+<li><div class="src-line"><a name="a553"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;The&nbsp;developer&nbsp;using&nbsp;the&nbsp;/e&nbsp;modifier&nbsp;should&nbsp;be&nbsp;made&nbsp;aware&nbsp;that&nbsp;he&nbsp;should</span></div></li>
+<li><div class="src-line"><a name="a554"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;use&nbsp;&lt;code&gt;preg_replace_callback()&lt;/code&gt;&nbsp;instead</span></div></li>
+<li><div class="src-line"><a name="a555"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;/blockquote&gt;</span></div></li>
+<li><div class="src-line"><a name="a556"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a557"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">array&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a558"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a559"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a560"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$_kw_replace_group&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a561"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$_rx_key&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a562"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a563"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a564"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;some&nbsp;&quot;callback&nbsp;parameters&quot;&nbsp;for&nbsp;handle_multiline_regexps</span></div></li>
+<li><div class="src-line"><a name="a565"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a566"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a567"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a568"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@var&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a569"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a570"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$_hmr_before&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a571"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$_hmr_replace&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a572"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$_hmr_after&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a573"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">var&nbsp;</span><span class="src-var">$_hmr_key&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a574"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a575"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">/**#@-*/</span></div></li>
+<li><div class="src-line"><a name="a576"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a577"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a578"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Creates&nbsp;a&nbsp;new&nbsp;GeSHi&nbsp;object,&nbsp;with&nbsp;source&nbsp;and&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a579"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a580"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;source&nbsp;code&nbsp;to&nbsp;highlight</span></div></li>
+<li><div class="src-line"><a name="a581"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;language&nbsp;to&nbsp;highlight&nbsp;the&nbsp;source&nbsp;with</span></div></li>
+<li><div class="src-line"><a name="a582"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;path&nbsp;to&nbsp;the&nbsp;language&nbsp;file&nbsp;directory.&nbsp;&lt;b&gt;This</span></div></li>
+<li><div class="src-line"><a name="a583"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is&nbsp;deprecated!&lt;/b&gt;&nbsp;I've&nbsp;backported&nbsp;the&nbsp;auto&nbsp;path</span></div></li>
+<li><div class="src-line"><a name="a584"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detection&nbsp;from&nbsp;the&nbsp;1.1.X&nbsp;dev&nbsp;branch,&nbsp;so&nbsp;now&nbsp;it</span></div></li>
+<li><div class="src-line"><a name="a585"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;should&nbsp;be&nbsp;automatically&nbsp;set&nbsp;correctly.&nbsp;If&nbsp;you&nbsp;have</span></div></li>
+<li><div class="src-line"><a name="a586"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;renamed&nbsp;the&nbsp;language&nbsp;directory&nbsp;however,&nbsp;you&nbsp;will</span></div></li>
+<li><div class="src-line"><a name="a587"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;still&nbsp;need&nbsp;to&nbsp;set&nbsp;the&nbsp;path&nbsp;using&nbsp;this&nbsp;parameter&nbsp;or</span></div></li>
+<li><div class="src-line"><a name="a588"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-doc-inlinetag">{@link&nbsp;GeSHi-&gt;set_language_path()}</span></div></li>
+<li><div class="src-line"><a name="a589"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a590"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a591"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><a href="../geshi/core/GeSHi.html#methodGeSHi">GeSHi</a><span class="src-sym">(</span><span class="src-var">$source&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">,&nbsp;</span><span class="src-var">$language&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">,&nbsp;</span><span class="src-var">$path&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a592"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$source</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a593"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_source">set_source</a><span class="src-sym">(</span><span class="src-var">$source</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a594"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a595"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$language</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a596"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_language">set_language</a><span class="src-sym">(</span><span class="src-var">$language</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a597"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a598"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_language_path">set_language_path</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a599"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a600"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a601"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-doc">/**</span></div></li>
+<li><div class="src-line"><a name="a602"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;an&nbsp;error&nbsp;message&nbsp;associated&nbsp;with&nbsp;the&nbsp;last&nbsp;GeSHi&nbsp;operation,</span></div></li>
+<li><div class="src-line"><a name="a603"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;or&nbsp;false&nbsp;if&nbsp;no&nbsp;error&nbsp;has&nbsp;occured</span></div></li>
+<li><div class="src-line"><a name="a604"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a605"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">string</span><span class="src-doc">|</span><span class="src-doc-type">false</span><span class="src-doc">An&nbsp;error&nbsp;message&nbsp;if&nbsp;there&nbsp;has&nbsp;been&nbsp;an&nbsp;error,&nbsp;else&nbsp;false</span></div></li>
+<li><div class="src-line"><a name="a606"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a607"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a608"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><a href="../geshi/core/GeSHi.html#methoderror">error</a><span class="src-sym">(</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a609"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a610"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Put&nbsp;some&nbsp;template&nbsp;variables&nbsp;for&nbsp;debugging&nbsp;here&nbsp;...</span></div></li>
+<li><div class="src-line"><a name="a611"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$debug_tpl_vars&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></div></li>
+<li><div class="src-line"><a name="a612"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'{LANGUAGE}'&nbsp;</span>=&gt;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a613"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'{PATH}'&nbsp;</span>=&gt;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_path</span></div></li>
+<li><div class="src-line"><a name="a614"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a615"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$msg&nbsp;</span>=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span></div></li>
+<li><div class="src-line"><a name="a616"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$debug_tpl_vars</span><span class="src-sym">)</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a617"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_values">array_values</a><span class="src-sym">(</span><span class="src-var">$debug_tpl_vars</span><span class="src-sym">)</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a618"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error_messages</span><span class="src-sym">[</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a619"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a620"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-str">&quot;</span><span class="src-str">&lt;br&nbsp;/&gt;&lt;strong&gt;GeSHi&nbsp;Error:&lt;/strong&gt;&nbsp;<span class="src-var">$msg</span>&nbsp;(code&nbsp;{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-var">error</span><span class="src-sym">}</span>)&lt;br&nbsp;/&gt;</span><span class="src-str"><span class="src-str">"</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a621"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a622"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a623"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a624"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a625"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a626"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Gets&nbsp;a&nbsp;human-readable&nbsp;language&nbsp;name&nbsp;(thanks&nbsp;to&nbsp;Simon&nbsp;Patterson</span></div></li>
+<li><div class="src-line"><a name="a627"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;for&nbsp;the&nbsp;idea&nbsp;:))</span></div></li>
+<li><div class="src-line"><a name="a628"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a629"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;The&nbsp;name&nbsp;for&nbsp;the&nbsp;current&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a630"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a631"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a632"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">get_language_name</span><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a633"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_ERROR_NO_SUCH_LANG</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a634"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'LANG_NAME'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&nbsp;(Unknown&nbsp;Language)'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a635"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a636"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'LANG_NAME'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a637"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a638"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a639"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a640"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;source&nbsp;code&nbsp;for&nbsp;this&nbsp;object</span></div></li>
+<li><div class="src-line"><a name="a641"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a642"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;source&nbsp;code&nbsp;to&nbsp;highlight</span></div></li>
+<li><div class="src-line"><a name="a643"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a644"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a645"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_source">set_source</a><span class="src-sym">(</span><span class="src-var">$source</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a646"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">source</span>&nbsp;=&nbsp;<span class="src-var">$source</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a647"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a648"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a649"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a650"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a651"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;language&nbsp;for&nbsp;this&nbsp;object</span></div></li>
+<li><div class="src-line"><a name="a652"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a653"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-tag">@note</span><span class="src-doc">&nbsp;since&nbsp;1.0.8&nbsp;this&nbsp;function&nbsp;won't&nbsp;reset&nbsp;language-settings&nbsp;by&nbsp;default&nbsp;anymore!</span></div></li>
+<li><div class="src-line"><a name="a654"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;you&nbsp;need&nbsp;this&nbsp;set&nbsp;$force_reset&nbsp;=&nbsp;true</span></div></li>
+<li><div class="src-line"><a name="a655"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a656"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;name&nbsp;of&nbsp;the&nbsp;language&nbsp;to&nbsp;use</span></div></li>
+<li><div class="src-line"><a name="a657"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a658"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a659"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_language">set_language</a><span class="src-sym">(</span><span class="src-var">$language</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$force_reset</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a660"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$force_reset</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a661"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">loaded_language</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a662"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a663"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a664"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Clean&nbsp;up&nbsp;the&nbsp;language&nbsp;name&nbsp;to&nbsp;prevent&nbsp;malicious&nbsp;code&nbsp;injection</span></span></div></li>
+<li><div class="src-line"><a name="a665"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$language</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span><span class="src-str">'#[^a-zA-Z0-9\-_]#'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">''</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$language</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a666"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a667"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$language</span>&nbsp;=&nbsp;<a href="http://www.php.net/strtolower">strtolower</a><span class="src-sym">(</span><span class="src-var">$language</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a668"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a669"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Retreive&nbsp;the&nbsp;full&nbsp;filename</span></span></div></li>
+<li><div class="src-line"><a name="a670"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$file_name</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_path</span>&nbsp;.&nbsp;<span class="src-var">$language</span>&nbsp;.&nbsp;<span class="src-str">'.php'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a671"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$file_name</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">loaded_language</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a672"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;language&nbsp;is&nbsp;already&nbsp;loaded!</span></span></div></li>
+<li><div class="src-line"><a name="a673"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a674"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a675"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a676"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language</span>&nbsp;=&nbsp;<span class="src-var">$language</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a677"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a678"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a679"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">strict_mode</span>&nbsp;=&nbsp;<span class="src-id">GESHI_NEVER</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a680"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a681"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;we&nbsp;can&nbsp;read&nbsp;the&nbsp;desired&nbsp;file</span></span></div></li>
+<li><div class="src-line"><a name="a682"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/is_readable">is_readable</a><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a683"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span>&nbsp;=&nbsp;<span class="src-id">GESHI_ERROR_NO_SUCH_LANG</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a684"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a685"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a686"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a687"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Load&nbsp;the&nbsp;language&nbsp;for&nbsp;parsing</span></span></div></li>
+<li><div class="src-line"><a name="a688"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">load_language</span><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a689"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a690"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a691"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a692"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;path&nbsp;to&nbsp;the&nbsp;directory&nbsp;containing&nbsp;the&nbsp;language&nbsp;files.&nbsp;Note</span></div></li>
+<li><div class="src-line"><a name="a693"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;that&nbsp;this&nbsp;path&nbsp;is&nbsp;relative&nbsp;to&nbsp;the&nbsp;directory&nbsp;of&nbsp;the&nbsp;script&nbsp;that&nbsp;included</span></div></li>
+<li><div class="src-line"><a name="a694"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;geshi.php,&nbsp;NOT&nbsp;geshi.php&nbsp;itself.</span></div></li>
+<li><div class="src-line"><a name="a695"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a696"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;path&nbsp;to&nbsp;the&nbsp;language&nbsp;directory</span></div></li>
+<li><div class="src-line"><a name="a697"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a698"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span><span class="src-doc">&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;language&nbsp;files&nbsp;should&nbsp;now&nbsp;be&nbsp;automatically</span></div></li>
+<li><div class="src-line"><a name="a699"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detected,&nbsp;so&nbsp;this&nbsp;method&nbsp;should&nbsp;no&nbsp;longer&nbsp;be&nbsp;needed.&nbsp;The</span></div></li>
+<li><div class="src-line"><a name="a700"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.1.X&nbsp;branch&nbsp;handles&nbsp;manual&nbsp;setting&nbsp;of&nbsp;the&nbsp;path&nbsp;differently</span></div></li>
+<li><div class="src-line"><a name="a701"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;so&nbsp;this&nbsp;method&nbsp;will&nbsp;disappear&nbsp;in&nbsp;1.2.0.</span></div></li>
+<li><div class="src-line"><a name="a702"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a703"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_language_path">set_language_path</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a704"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">,</span><span class="src-str">':'</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a705"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Security&nbsp;Fix&nbsp;to&nbsp;prevent&nbsp;external&nbsp;directories&nbsp;using&nbsp;fopen&nbsp;wrappers.</span></span></div></li>
+<li><div class="src-line"><a name="a706"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-id">DIRECTORY_SEPARATOR</span>&nbsp;==&nbsp;<span class="src-str">&quot;\\&quot;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a707"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-str">'#^[a-zA-Z]:#'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$path</span><span class="src-sym">)</span>&nbsp;||&nbsp;<span class="src-id">false</span>&nbsp;!==&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">,</span>&nbsp;<span class="src-str">':'</span><span class="src-sym">,</span>&nbsp;<span class="src-num">2</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a708"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a709"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a710"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a711"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a712"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a713"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a714"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-str">'#[^/a-zA-Z0-9_\.\-\\\s:]#'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$path</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a715"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Security&nbsp;Fix&nbsp;to&nbsp;prevent&nbsp;external&nbsp;directories&nbsp;using&nbsp;fopen&nbsp;wrappers.</span></span></div></li>
+<li><div class="src-line"><a name="a716"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a717"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a718"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_SECURITY_PARANOID&quot;&gt;GESHI_SECURITY_PARANOID&lt;/a&gt;</span>&nbsp;&amp;&amp;&nbsp;<span class="src-id">false</span>&nbsp;!==&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/.'</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a719"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Security&nbsp;Fix&nbsp;to&nbsp;prevent&nbsp;external&nbsp;directories&nbsp;using&nbsp;fopen&nbsp;wrappers.</span></span></div></li>
+<li><div class="src-line"><a name="a720"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a721"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a722"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_SECURITY_PARANOID&quot;&gt;GESHI_SECURITY_PARANOID&lt;/a&gt;</span>&nbsp;&amp;&amp;&nbsp;<span class="src-id">false</span>&nbsp;!==&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'..'</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a723"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Security&nbsp;Fix&nbsp;to&nbsp;prevent&nbsp;external&nbsp;directories&nbsp;using&nbsp;fopen&nbsp;wrappers.</span></span></div></li>
+<li><div class="src-line"><a name="a724"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a725"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a726"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a727"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_path</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-str">'/'</span>&nbsp;==&nbsp;<span class="src-var">$path</span><span class="src-sym">[</span><a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$path</span><span class="src-sym">)</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-var">$path</span>&nbsp;:&nbsp;<span class="src-var">$path</span>&nbsp;.&nbsp;<span class="src-str">'/'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a728"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_language">set_language</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;otherwise&nbsp;set_language_path&nbsp;has&nbsp;no&nbsp;effect</span></span></div></li>
+<li><div class="src-line"><a name="a729"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a730"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a731"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a732"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a733"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;type&nbsp;of&nbsp;header&nbsp;to&nbsp;be&nbsp;used.</span></div></li>
+<li><div class="src-line"><a name="a734"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a735"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;If&nbsp;GESHI_HEADER_DIV&nbsp;is&nbsp;used,&nbsp;the&nbsp;code&nbsp;is&nbsp;surrounded&nbsp;in&nbsp;a&nbsp;&quot;div&quot;.This</span></div></li>
+<li><div class="src-line"><a name="a736"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;means&nbsp;more&nbsp;source&nbsp;code&nbsp;but&nbsp;more&nbsp;control&nbsp;over&nbsp;tab&nbsp;width&nbsp;and&nbsp;line-wrapping.</span></div></li>
+<li><div class="src-line"><a name="a737"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;GESHI_HEADER_PRE&nbsp;means&nbsp;that&nbsp;a&nbsp;&quot;pre&quot;&nbsp;is&nbsp;used&nbsp;-&nbsp;less&nbsp;source,&nbsp;but&nbsp;less</span></div></li>
+<li><div class="src-line"><a name="a738"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;control.&nbsp;Default&nbsp;is&nbsp;GESHI_HEADER_PRE.</span></div></li>
+<li><div class="src-line"><a name="a739"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a740"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;From&nbsp;1.0.7.2,&nbsp;you&nbsp;can&nbsp;use&nbsp;GESHI_HEADER_NONE&nbsp;to&nbsp;specify&nbsp;that&nbsp;no&nbsp;header&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a741"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;should&nbsp;be&nbsp;outputted.</span></div></li>
+<li><div class="src-line"><a name="a742"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a743"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">The&nbsp;type&nbsp;of&nbsp;header&nbsp;to&nbsp;be&nbsp;used</span></div></li>
+<li><div class="src-line"><a name="a744"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a745"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a746"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_header_type">set_header_type</a><span class="src-sym">(</span><span class="src-var">$type</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a747"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;we&nbsp;got&nbsp;a&nbsp;valid&nbsp;header&nbsp;type</span></span></div></li>
+<li><div class="src-line"><a name="a748"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$type</span><span class="src-sym">,</span>&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_NONE&quot;&gt;GESHI_HEADER_NONE&lt;/a&gt;</span><span class="src-sym">,</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_DIV&quot;&gt;GESHI_HEADER_DIV&lt;/a&gt;</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a749"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE&quot;&gt;GESHI_HEADER_PRE&lt;/a&gt;</span><span class="src-sym">,</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">,</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE&quot;&gt;GESHI_HEADER_PRE_TABLE&lt;/a&gt;</span><span class="src-sym">)))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a750"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span>&nbsp;=&nbsp;<span class="src-id">GESHI_ERROR_INVALID_HEADER_TYPE</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a751"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a752"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a753"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a754"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Set&nbsp;that&nbsp;new&nbsp;header&nbsp;type</span></span></div></li>
+<li><div class="src-line"><a name="a755"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">header_type</span>&nbsp;=&nbsp;<span class="src-var">$type</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a756"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a757"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a758"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a759"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;the&nbsp;code&nbsp;that&nbsp;will&nbsp;be&nbsp;outputted</span></div></li>
+<li><div class="src-line"><a name="a760"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;when&nbsp;this&nbsp;object&nbsp;is&nbsp;parsed.&nbsp;The&nbsp;style&nbsp;should&nbsp;be&nbsp;a</span></div></li>
+<li><div class="src-line"><a name="a761"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;string&nbsp;of&nbsp;valid&nbsp;stylesheet&nbsp;declarations</span></div></li>
+<li><div class="src-line"><a name="a762"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a763"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;overall&nbsp;style&nbsp;for&nbsp;the&nbsp;outputted&nbsp;code&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a764"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;styles&nbsp;with&nbsp;the&nbsp;current&nbsp;styles&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a765"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a766"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a767"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_overall_style">set_overall_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a768"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a769"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">overall_style</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a770"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a771"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">overall_style</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a772"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a773"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a774"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a775"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a776"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;overall&nbsp;classname&nbsp;for&nbsp;this&nbsp;block&nbsp;of&nbsp;code.&nbsp;This</span></div></li>
+<li><div class="src-line"><a name="a777"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;class&nbsp;can&nbsp;then&nbsp;be&nbsp;used&nbsp;in&nbsp;a&nbsp;stylesheet&nbsp;to&nbsp;style&nbsp;this&nbsp;object's</span></div></li>
+<li><div class="src-line"><a name="a778"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;output</span></div></li>
+<li><div class="src-line"><a name="a779"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a780"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;class&nbsp;name&nbsp;to&nbsp;use&nbsp;for&nbsp;this&nbsp;block&nbsp;of&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a781"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a782"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a783"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_overall_class">set_overall_class</a><span class="src-sym">(</span><span class="src-var">$class</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a784"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">overall_class</span>&nbsp;=&nbsp;<span class="src-var">$class</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a785"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a786"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a787"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a788"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;overall&nbsp;id&nbsp;for&nbsp;this&nbsp;block&nbsp;of&nbsp;code.&nbsp;This&nbsp;id&nbsp;can&nbsp;then</span></div></li>
+<li><div class="src-line"><a name="a789"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;be&nbsp;used&nbsp;in&nbsp;a&nbsp;stylesheet&nbsp;to&nbsp;style&nbsp;this&nbsp;object's&nbsp;output</span></div></li>
+<li><div class="src-line"><a name="a790"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a791"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;ID&nbsp;to&nbsp;use&nbsp;for&nbsp;this&nbsp;block&nbsp;of&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a792"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a793"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a794"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_overall_id">set_overall_id</a><span class="src-sym">(</span><span class="src-var">$id</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a795"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">overall_id</span>&nbsp;=&nbsp;<span class="src-var">$id</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a796"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a797"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a798"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a799"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;whether&nbsp;CSS&nbsp;classes&nbsp;should&nbsp;be&nbsp;used&nbsp;to&nbsp;highlight&nbsp;the&nbsp;source.&nbsp;Default</span></div></li>
+<li><div class="src-line"><a name="a800"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;is&nbsp;off,&nbsp;calling&nbsp;this&nbsp;method&nbsp;with&nbsp;no&nbsp;arguments&nbsp;will&nbsp;turn&nbsp;it&nbsp;on</span></div></li>
+<li><div class="src-line"><a name="a801"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a802"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;classes&nbsp;on&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a803"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a804"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a805"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_classes">enable_classes</a><span class="src-sym">(</span><span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a806"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">use_classes</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a807"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a808"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a809"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a810"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;style&nbsp;for&nbsp;the&nbsp;actual&nbsp;code.&nbsp;This&nbsp;should&nbsp;be&nbsp;a&nbsp;string</span></div></li>
+<li><div class="src-line"><a name="a811"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;containing&nbsp;valid&nbsp;stylesheet&nbsp;declarations.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a812"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a813"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a814"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a815"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Note:&nbsp;Use&nbsp;this&nbsp;method&nbsp;to&nbsp;override&nbsp;any&nbsp;style&nbsp;changes&nbsp;you&nbsp;made&nbsp;to</span></div></li>
+<li><div class="src-line"><a name="a816"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;line&nbsp;numbers&nbsp;if&nbsp;you&nbsp;are&nbsp;using&nbsp;line&nbsp;numbers,&nbsp;else&nbsp;the&nbsp;line&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a817"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;code&nbsp;will&nbsp;have&nbsp;the&nbsp;same&nbsp;style&nbsp;as&nbsp;the&nbsp;line&nbsp;number!&nbsp;Consult&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a818"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;GeSHi&nbsp;documentation&nbsp;for&nbsp;more&nbsp;information&nbsp;about&nbsp;this.</span></div></li>
+<li><div class="src-line"><a name="a819"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a820"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;use&nbsp;for&nbsp;actual&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a821"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;current&nbsp;styles&nbsp;with&nbsp;the&nbsp;new&nbsp;styles</span></div></li>
+<li><div class="src-line"><a name="a822"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a823"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a824"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_code_style">set_code_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a825"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a826"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">code_style</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a827"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a828"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">code_style</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a829"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a830"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a831"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a832"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a833"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;the&nbsp;line&nbsp;numbers.</span></div></li>
+<li><div class="src-line"><a name="a834"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a835"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;style&nbsp;for&nbsp;the&nbsp;line&nbsp;numbers&nbsp;that&nbsp;are&nbsp;&quot;normal&quot;</span></div></li>
+<li><div class="src-line"><a name="a836"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string</span><span class="src-doc">|</span><span class="src-doc-type">boolean</span><span class="src-doc">If&nbsp;a&nbsp;string,&nbsp;this&nbsp;is&nbsp;the&nbsp;style&nbsp;of&nbsp;the&nbsp;line</span></div></li>
+<li><div class="src-line"><a name="a837"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;numbers&nbsp;that&nbsp;are&nbsp;&quot;fancy&quot;,&nbsp;otherwise&nbsp;if&nbsp;boolean&nbsp;then&nbsp;this</span></div></li>
+<li><div class="src-line"><a name="a838"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;defines&nbsp;whether&nbsp;the&nbsp;normal&nbsp;styles&nbsp;should&nbsp;be&nbsp;merged&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a839"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;normal&nbsp;styles&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a840"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">If&nbsp;set,&nbsp;is&nbsp;the&nbsp;flag&nbsp;for&nbsp;whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;&quot;fancy&quot;</span></div></li>
+<li><div class="src-line"><a name="a841"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styles&nbsp;with&nbsp;the&nbsp;current&nbsp;styles&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a842"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a843"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a844"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_line_style">set_line_style</a><span class="src-sym">(</span><span class="src-var">$style1</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style2</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a845"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;we&nbsp;got&nbsp;2&nbsp;or&nbsp;three&nbsp;parameters</span></span></div></li>
+<li><div class="src-line"><a name="a846"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_bool">is_bool</a><span class="src-sym">(</span><span class="src-var">$style2</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a847"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-var">$style2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a848"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$style2</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a849"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a850"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a851"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Actually&nbsp;set&nbsp;the&nbsp;new&nbsp;styles</span></span></div></li>
+<li><div class="src-line"><a name="a852"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a853"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_style1</span>&nbsp;=&nbsp;<span class="src-var">$style1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a854"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_style2</span>&nbsp;=&nbsp;<span class="src-var">$style2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a855"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a856"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_style1</span>&nbsp;.=&nbsp;<span class="src-var">$style1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a857"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_style2</span>&nbsp;.=&nbsp;<span class="src-var">$style2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a858"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a859"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a860"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a861"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a862"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;whether&nbsp;line&nbsp;numbers&nbsp;should&nbsp;be&nbsp;displayed.</span></div></li>
+<li><div class="src-line"><a name="a863"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a864"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Valid&nbsp;values&nbsp;for&nbsp;the&nbsp;first&nbsp;parameter&nbsp;are:</span></div></li>
+<li><div class="src-line"><a name="a865"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a866"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;GESHI_NO_LINE_NUMBERS:&nbsp;Line&nbsp;numbers&nbsp;will&nbsp;not&nbsp;be&nbsp;displayed</span></div></li>
+<li><div class="src-line"><a name="a867"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;GESHI_NORMAL_LINE_NUMBERS:&nbsp;Line&nbsp;numbers&nbsp;will&nbsp;be&nbsp;displayed</span></div></li>
+<li><div class="src-line"><a name="a868"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;GESHI_FANCY_LINE_NUMBERS:&nbsp;Fancy&nbsp;line&nbsp;numbers&nbsp;will&nbsp;be&nbsp;displayed</span></div></li>
+<li><div class="src-line"><a name="a869"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a870"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;For&nbsp;fancy&nbsp;line&nbsp;numbers,&nbsp;the&nbsp;second&nbsp;parameter&nbsp;is&nbsp;used&nbsp;to&nbsp;signal&nbsp;which&nbsp;lines</span></div></li>
+<li><div class="src-line"><a name="a871"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;are&nbsp;to&nbsp;be&nbsp;fancy.&nbsp;For&nbsp;example,&nbsp;if&nbsp;the&nbsp;value&nbsp;of&nbsp;this&nbsp;parameter&nbsp;is&nbsp;5&nbsp;then&nbsp;every</span></div></li>
+<li><div class="src-line"><a name="a872"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;5th&nbsp;line&nbsp;will&nbsp;be&nbsp;fancy.</span></div></li>
+<li><div class="src-line"><a name="a873"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a874"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">How&nbsp;line&nbsp;numbers&nbsp;should&nbsp;be&nbsp;displayed</span></div></li>
+<li><div class="src-line"><a name="a875"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">Defines&nbsp;which&nbsp;lines&nbsp;are&nbsp;fancy</span></div></li>
+<li><div class="src-line"><a name="a876"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a877"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a878"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_line_numbers">enable_line_numbers</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$nth_row</span>&nbsp;=&nbsp;<span class="src-num">5</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a879"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;!=&nbsp;<span class="src-var">$flag</span>&nbsp;&amp;&amp;&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NORMAL_LINE_NUMBERS&quot;&gt;GESHI_NORMAL_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;!=&nbsp;<span class="src-var">$flag</span></span></div></li>
+<li><div class="src-line"><a name="a880"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS&quot;&gt;GESHI_FANCY_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;!=&nbsp;<span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a881"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span>&nbsp;=&nbsp;<span class="src-id">GESHI_ERROR_INVALID_LINE_NUMBER_TYPE</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a882"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a883"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_numbers</span>&nbsp;=&nbsp;<span class="src-var">$flag</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a884"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_nth_row</span>&nbsp;=&nbsp;<span class="src-var">$nth_row</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a885"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a886"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a887"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a888"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;wether&nbsp;spans&nbsp;and&nbsp;other&nbsp;HTML&nbsp;markup&nbsp;generated&nbsp;by&nbsp;GeSHi&nbsp;can</span></div></li>
+<li><div class="src-line"><a name="a889"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;span&nbsp;over&nbsp;multiple&nbsp;lines&nbsp;or&nbsp;not.&nbsp;Defaults&nbsp;to&nbsp;true&nbsp;to&nbsp;reduce&nbsp;overhead.</span></div></li>
+<li><div class="src-line"><a name="a890"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Set&nbsp;it&nbsp;to&nbsp;false&nbsp;if&nbsp;you&nbsp;want&nbsp;to&nbsp;manipulate&nbsp;the&nbsp;output&nbsp;or&nbsp;manually&nbsp;display</span></div></li>
+<li><div class="src-line"><a name="a891"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;code&nbsp;in&nbsp;an&nbsp;ordered&nbsp;list.</span></div></li>
+<li><div class="src-line"><a name="a892"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a893"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Wether&nbsp;multiline&nbsp;spans&nbsp;are&nbsp;allowed&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a894"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.7.22</span></div></li>
+<li><div class="src-line"><a name="a895"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a896"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_multiline_span">enable_multiline_span</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a897"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">allow_multiline_span</span>&nbsp;=&nbsp;(bool)&nbsp;<span class="src-var">$flag</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a898"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a899"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a900"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a901"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Get&nbsp;current&nbsp;setting&nbsp;for&nbsp;multiline&nbsp;spans,&nbsp;see&nbsp;GeSHi-&gt;enable_multiline_span().</span></div></li>
+<li><div class="src-line"><a name="a902"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a903"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@see</span><span class="src-doc">&nbsp;enable_multiline_span</span></div></li>
+<li><div class="src-line"><a name="a904"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">bool&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a905"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a906"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodget_multiline_span">get_multiline_span</a><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a907"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">allow_multiline_span</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a908"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a909"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a910"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a911"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;style&nbsp;for&nbsp;a&nbsp;keyword&nbsp;group.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a912"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a913"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a914"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a915"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;change&nbsp;the&nbsp;styles&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a916"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;keywords</span></div></li>
+<li><div class="src-line"><a name="a917"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a918"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a919"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a920"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a921"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_keyword_group_style">set_keyword_group_style</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a922"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Set&nbsp;the&nbsp;style&nbsp;for&nbsp;this&nbsp;keyword&nbsp;group</span></span></div></li>
+<li><div class="src-line"><a name="a923"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a924"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a925"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a926"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a927"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a928"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a929"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Update&nbsp;the&nbsp;lexic&nbsp;permissions</span></span></div></li>
+<li><div class="src-line"><a name="a930"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a931"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a932"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a933"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a934"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a935"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a936"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;a&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a937"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a938"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;turn&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a939"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;that&nbsp;group&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a940"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a941"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a942"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_keyword_group_highlighting">set_keyword_group_highlighting</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a943"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a944"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a945"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a946"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a947"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;comment&nbsp;groups.&nbsp;&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a948"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a949"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a950"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a951"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;comment&nbsp;group&nbsp;to&nbsp;change&nbsp;the&nbsp;styles&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a952"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;comments</span></div></li>
+<li><div class="src-line"><a name="a953"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a954"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a955"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a956"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a957"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_comments_style">set_comments_style</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a958"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a959"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a960"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a961"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a962"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a963"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a964"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a965"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a966"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;comment&nbsp;groups</span></div></li>
+<li><div class="src-line"><a name="a967"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a968"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;comment&nbsp;group&nbsp;to&nbsp;turn&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a969"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;that&nbsp;group&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a970"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a971"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a972"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_comments_highlighting">set_comments_highlighting</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a973"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a974"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a975"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a976"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a977"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;escaped&nbsp;characters.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a978"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a979"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a980"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a981"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;escape&nbsp;characters</span></div></li>
+<li><div class="src-line"><a name="a982"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a983"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a984"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a985"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a986"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_escape_characters_style">set_escape_characters_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a987"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a988"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a989"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a990"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a991"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a992"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a993"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a994"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a995"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;escaped&nbsp;characters</span></div></li>
+<li><div class="src-line"><a name="a996"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a997"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;escape&nbsp;characters&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a998"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a999"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1000"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_escape_characters_highlighting">set_escape_characters_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1001"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1002"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1003"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1004"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1005"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;brackets.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a1006"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1007"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a1008"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1009"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;method&nbsp;is&nbsp;DEPRECATED:&nbsp;use&nbsp;set_symbols_style&nbsp;instead.</span></div></li>
+<li><div class="src-line"><a name="a1010"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;method&nbsp;will&nbsp;be&nbsp;removed&nbsp;in&nbsp;1.2.X</span></div></li>
+<li><div class="src-line"><a name="a1011"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1012"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;brackets</span></div></li>
+<li><div class="src-line"><a name="a1013"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a1014"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a1015"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1016"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span><span class="src-doc">&nbsp;In&nbsp;favour&nbsp;of&nbsp;set_symbols_style</span></div></li>
+<li><div class="src-line"><a name="a1017"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1018"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_brackets_style">set_brackets_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1019"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1020"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1021"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1022"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1023"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1024"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1025"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1026"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1027"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;brackets</span></div></li>
+<li><div class="src-line"><a name="a1028"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1029"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;method&nbsp;is&nbsp;DEPRECATED:&nbsp;use&nbsp;set_symbols_highlighting&nbsp;instead.</span></div></li>
+<li><div class="src-line"><a name="a1030"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;method&nbsp;will&nbsp;be&nbsp;remove&nbsp;in&nbsp;1.2.X</span></div></li>
+<li><div class="src-line"><a name="a1031"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1032"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;brackets&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1033"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1034"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span><span class="src-doc">&nbsp;In&nbsp;favour&nbsp;of&nbsp;set_symbols_highlighting</span></div></li>
+<li><div class="src-line"><a name="a1035"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1036"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_brackets_highlighting">set_brackets_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1037"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1038"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1039"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1040"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1041"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;symbols.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a1042"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1043"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a1044"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1045"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;symbols</span></div></li>
+<li><div class="src-line"><a name="a1046"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a1047"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a1048"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;Tells&nbsp;the&nbsp;group&nbsp;of&nbsp;symbols&nbsp;for&nbsp;which&nbsp;style&nbsp;should&nbsp;be&nbsp;set.</span></div></li>
+<li><div class="src-line"><a name="a1049"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.1</span></div></li>
+<li><div class="src-line"><a name="a1050"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1051"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_symbols_style">set_symbols_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$group</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1052"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Update&nbsp;the&nbsp;style&nbsp;of&nbsp;symbols</span></span></div></li>
+<li><div class="src-line"><a name="a1053"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1054"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1055"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1056"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1057"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1058"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1059"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;For&nbsp;backward&nbsp;compatibility</span></span></div></li>
+<li><div class="src-line"><a name="a1060"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-num">0</span>&nbsp;==&nbsp;<span class="src-var">$group</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1061"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_brackets_style">set_brackets_style</a>&nbsp;<span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1062"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1063"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1064"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1065"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1066"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;symbols</span></div></li>
+<li><div class="src-line"><a name="a1067"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1068"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;symbols&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1069"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1070"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1071"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_symbols_highlighting">set_symbols_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1072"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Update&nbsp;lexic&nbsp;permissions&nbsp;for&nbsp;this&nbsp;symbol&nbsp;group</span></span></div></li>
+<li><div class="src-line"><a name="a1073"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1074"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1075"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;For&nbsp;backward&nbsp;compatibility</span></span></div></li>
+<li><div class="src-line"><a name="a1076"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_brackets_highlighting">set_brackets_highlighting</a>&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1077"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1078"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1079"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1080"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;strings.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a1081"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1082"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a1083"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1084"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;escape&nbsp;characters</span></div></li>
+<li><div class="src-line"><a name="a1085"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a1086"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a1087"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1088"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1089"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_strings_style">set_strings_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1090"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1091"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1092"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1093"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1094"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1095"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1096"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1097"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1098"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;strings</span></div></li>
+<li><div class="src-line"><a name="a1099"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1100"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;strings&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1101"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1102"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1103"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_strings_highlighting">set_strings_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1104"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1105"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1106"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1107"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1108"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;numbers.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a1109"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1110"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a1111"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1112"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;numbers</span></div></li>
+<li><div class="src-line"><a name="a1113"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a1114"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a1115"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1116"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1117"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_numbers_style">set_numbers_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1118"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1119"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1120"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1121"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1122"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1123"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1124"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1125"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1126"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;numbers</span></div></li>
+<li><div class="src-line"><a name="a1127"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1128"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;numbers&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1129"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1130"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1131"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_numbers_highlighting">set_numbers_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1132"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1133"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1134"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1135"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1136"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;methods.&nbsp;$key&nbsp;is&nbsp;a&nbsp;number&nbsp;that&nbsp;references&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1137"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;appropriate&nbsp;&quot;object&nbsp;splitter&quot;&nbsp;-&nbsp;see&nbsp;the&nbsp;language&nbsp;file&nbsp;for&nbsp;the&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a1138"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;you&nbsp;are&nbsp;highlighting&nbsp;to&nbsp;get&nbsp;this&nbsp;number.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a1139"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1140"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a1141"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1142"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;object&nbsp;splitter&nbsp;to&nbsp;change&nbsp;the&nbsp;styles&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a1143"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;methods</span></div></li>
+<li><div class="src-line"><a name="a1144"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a1145"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a1146"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1147"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1148"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_methods_style">set_methods_style</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1149"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1150"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1151"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1152"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1153"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1154"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1155"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1156"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1157"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;methods</span></div></li>
+<li><div class="src-line"><a name="a1158"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1159"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;methods&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1160"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1161"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1162"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_methods_highlighting">set_methods_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1163"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1164"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1165"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1166"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1167"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;styles&nbsp;for&nbsp;regexps.&nbsp;If&nbsp;$preserve_defaults&nbsp;is</span></div></li>
+<li><div class="src-line"><a name="a1168"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;true,&nbsp;then&nbsp;styles&nbsp;are&nbsp;merged&nbsp;with&nbsp;the&nbsp;default&nbsp;styles,&nbsp;with&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1169"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;user&nbsp;defined&nbsp;styles&nbsp;having&nbsp;priority</span></div></li>
+<li><div class="src-line"><a name="a1170"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1171"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;style&nbsp;to&nbsp;make&nbsp;the&nbsp;regular&nbsp;expression&nbsp;matches</span></div></li>
+<li><div class="src-line"><a name="a1172"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;merge&nbsp;the&nbsp;new&nbsp;styles&nbsp;with&nbsp;the&nbsp;old&nbsp;or&nbsp;just</span></div></li>
+<li><div class="src-line"><a name="a1173"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;overwrite&nbsp;them</span></div></li>
+<li><div class="src-line"><a name="a1174"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1175"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1176"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_regexps_style">set_regexps_style</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$preserve_defaults</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1177"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$preserve_defaults</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1178"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1179"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1180"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1181"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1182"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1183"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1184"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1185"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;highlighting&nbsp;on/off&nbsp;for&nbsp;regexps</span></div></li>
+<li><div class="src-line"><a name="a1186"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1187"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;regular&nbsp;expression&nbsp;group&nbsp;to&nbsp;turn&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1188"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;turn&nbsp;highlighting&nbsp;for&nbsp;the&nbsp;regular&nbsp;expression&nbsp;group&nbsp;on&nbsp;or&nbsp;off</span></div></li>
+<li><div class="src-line"><a name="a1189"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1190"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1191"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_regexps_highlighting">set_regexps_highlighting</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1192"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1193"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1194"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1195"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1196"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;whether&nbsp;a&nbsp;set&nbsp;of&nbsp;keywords&nbsp;are&nbsp;checked&nbsp;for&nbsp;in&nbsp;a&nbsp;case&nbsp;sensitive&nbsp;manner</span></div></li>
+<li><div class="src-line"><a name="a1197"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1198"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;change&nbsp;the&nbsp;case&nbsp;sensitivity&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a1199"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;check&nbsp;in&nbsp;a&nbsp;case&nbsp;sensitive&nbsp;manner&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a1200"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1201"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1202"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_case_sensitivity">set_case_sensitivity</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$case</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1203"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$case</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1204"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1205"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1206"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1207"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;case&nbsp;that&nbsp;keywords&nbsp;should&nbsp;use&nbsp;when&nbsp;found.&nbsp;Use&nbsp;the&nbsp;constants:</span></div></li>
+<li><div class="src-line"><a name="a1208"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1209"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;GESHI_CAPS_NO_CHANGE:&nbsp;leave&nbsp;keywords&nbsp;as-is</span></div></li>
+<li><div class="src-line"><a name="a1210"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;GESHI_CAPS_UPPER:&nbsp;convert&nbsp;all&nbsp;keywords&nbsp;to&nbsp;uppercase&nbsp;where&nbsp;found</span></div></li>
+<li><div class="src-line"><a name="a1211"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;GESHI_CAPS_LOWER:&nbsp;convert&nbsp;all&nbsp;keywords&nbsp;to&nbsp;lowercase&nbsp;where&nbsp;found</span></div></li>
+<li><div class="src-line"><a name="a1212"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1213"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">A&nbsp;constant&nbsp;specifying&nbsp;what&nbsp;to&nbsp;do&nbsp;with&nbsp;matched&nbsp;keywords</span></div></li>
+<li><div class="src-line"><a name="a1214"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.1</span></div></li>
+<li><div class="src-line"><a name="a1215"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1216"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_case_keywords">set_case_keywords</a><span class="src-sym">(</span><span class="src-var">$case</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1217"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$case</span><span class="src-sym">,</span>&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a1218"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_CAPS_NO_CHANGE&quot;&gt;GESHI_CAPS_NO_CHANGE&lt;/a&gt;</span><span class="src-sym">,</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_CAPS_UPPER&quot;&gt;GESHI_CAPS_UPPER&lt;/a&gt;</span><span class="src-sym">,</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_CAPS_LOWER&quot;&gt;GESHI_CAPS_LOWER&lt;/a&gt;</span><span class="src-sym">)))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1219"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_KEYWORDS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$case</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1220"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1221"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1222"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1223"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1224"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;how&nbsp;many&nbsp;spaces&nbsp;a&nbsp;tab&nbsp;is&nbsp;substituted&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a1225"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1226"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Widths&nbsp;below&nbsp;zero&nbsp;are&nbsp;ignored</span></div></li>
+<li><div class="src-line"><a name="a1227"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1228"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">The&nbsp;tab&nbsp;width</span></div></li>
+<li><div class="src-line"><a name="a1229"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1230"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1231"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_tab_width">set_tab_width</a><span class="src-sym">(</span><span class="src-var">$width</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1232"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">tab_width</span>&nbsp;=&nbsp;<a href="http://www.php.net/intval">intval</a><span class="src-sym">(</span><span class="src-var">$width</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1233"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1234"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;it&nbsp;fit's&nbsp;the&nbsp;constraints:</span></span></div></li>
+<li><div class="src-line"><a name="a1235"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">tab_width</span>&nbsp;<&nbsp;<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1236"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Return&nbsp;it&nbsp;to&nbsp;the&nbsp;default</span></span></div></li>
+<li><div class="src-line"><a name="a1237"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">tab_width</span>&nbsp;=&nbsp;<span class="src-num">8</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1238"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1239"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1240"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1241"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1242"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;whether&nbsp;or&nbsp;not&nbsp;to&nbsp;use&nbsp;tab-stop&nbsp;width&nbsp;specifed&nbsp;by&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a1243"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1244"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;use&nbsp;language-specific&nbsp;tab-stop&nbsp;widths</span></div></li>
+<li><div class="src-line"><a name="a1245"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.7.20</span></div></li>
+<li><div class="src-line"><a name="a1246"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1247"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_use_language_tab_width">set_use_language_tab_width</a><span class="src-sym">(</span><span class="src-var">$use</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1248"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">use_language_tab_width</span>&nbsp;=&nbsp;(bool)&nbsp;<span class="src-var">$use</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1249"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1250"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1251"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1252"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;the&nbsp;tab&nbsp;width&nbsp;to&nbsp;use,&nbsp;based&nbsp;on&nbsp;the&nbsp;current&nbsp;language&nbsp;and&nbsp;user</span></div></li>
+<li><div class="src-line"><a name="a1253"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;preference</span></div></li>
+<li><div class="src-line"><a name="a1254"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1255"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">Tab&nbsp;width</span></div></li>
+<li><div class="src-line"><a name="a1256"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.7.20</span></div></li>
+<li><div class="src-line"><a name="a1257"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1258"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodget_real_tab_width">get_real_tab_width</a><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1259"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">use_language_tab_width</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a1260"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'TAB_WIDTH'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1261"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">tab_width</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1262"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1263"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'TAB_WIDTH'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1264"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1265"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1266"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1267"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1268"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Enables/disables&nbsp;strict&nbsp;highlighting.&nbsp;Default&nbsp;is&nbsp;off,&nbsp;calling&nbsp;this</span></div></li>
+<li><div class="src-line"><a name="a1269"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;method&nbsp;without&nbsp;parameters&nbsp;will&nbsp;turn&nbsp;it&nbsp;on.&nbsp;See&nbsp;documentation</span></div></li>
+<li><div class="src-line"><a name="a1270"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;for&nbsp;more&nbsp;details&nbsp;on&nbsp;strict&nbsp;mode&nbsp;and&nbsp;where&nbsp;to&nbsp;use&nbsp;it.</span></div></li>
+<li><div class="src-line"><a name="a1271"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1272"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;to&nbsp;enable&nbsp;strict&nbsp;mode&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a1273"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1274"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1275"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_strict_mode">enable_strict_mode</a><span class="src-sym">(</span><span class="src-var">$mode</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1276"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_MAYBE</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STRICT_MODE_APPLIES'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1277"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">strict_mode</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$mode</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">GESHI_ALWAYS</span>&nbsp;:&nbsp;<span class="src-id">GESHI_NEVER</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1278"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1279"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1280"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1281"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1282"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Disables&nbsp;all&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a1283"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1284"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1285"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;&nbsp;Rewrite&nbsp;with&nbsp;array&nbsp;traversal</span></div></li>
+<li><div class="src-line"><a name="a1286"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span><span class="src-doc">&nbsp;In&nbsp;favour&nbsp;of&nbsp;enable_highlighting</span></div></li>
+<li><div class="src-line"><a name="a1287"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1288"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methoddisable_highlighting">disable_highlighting</a><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1289"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodenable_highlighting">enable_highlighting</a><span class="src-sym">(</span><span class="src-id">false</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1290"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1291"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1292"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1293"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Enables&nbsp;all&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a1294"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1295"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;optional&nbsp;flag&nbsp;parameter&nbsp;was&nbsp;added&nbsp;in&nbsp;version&nbsp;1.0.7.21&nbsp;and&nbsp;can&nbsp;be&nbsp;used</span></div></li>
+<li><div class="src-line"><a name="a1296"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;to&nbsp;enable&nbsp;(true)&nbsp;or&nbsp;disable&nbsp;(false)&nbsp;all&nbsp;highlighting.</span></div></li>
+<li><div class="src-line"><a name="a1297"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1298"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1299"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">A&nbsp;flag&nbsp;specifying&nbsp;whether&nbsp;to&nbsp;enable&nbsp;or&nbsp;disable&nbsp;all&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a1300"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;&nbsp;Rewrite&nbsp;with&nbsp;array&nbsp;traversal</span></div></li>
+<li><div class="src-line"><a name="a1301"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1302"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_highlighting">enable_highlighting</a><span class="src-sym">(</span><span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1303"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-var">$flag</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1304"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$value</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1305"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$value</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1306"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$value</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$k</span>&nbsp;=&gt;&nbsp;<span class="src-var">$v</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1307"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$flag</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1308"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1309"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1310"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$flag</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1311"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1312"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1313"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1314"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Context&nbsp;blocks</span></span></div></li>
+<li><div class="src-line"><a name="a1315"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">enable_important_blocks</span>&nbsp;=&nbsp;<span class="src-var">$flag</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1316"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1317"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1318"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1319"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Given&nbsp;a&nbsp;file&nbsp;extension,&nbsp;this&nbsp;method&nbsp;returns&nbsp;either&nbsp;a&nbsp;valid&nbsp;geshi&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a1320"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;name,&nbsp;or&nbsp;the&nbsp;empty&nbsp;string&nbsp;if&nbsp;it&nbsp;couldn't&nbsp;be&nbsp;found</span></div></li>
+<li><div class="src-line"><a name="a1321"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1322"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;extension&nbsp;to&nbsp;get&nbsp;a&nbsp;language&nbsp;name&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a1323"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">array&nbsp;</span><span class="src-doc">&nbsp;A&nbsp;lookup&nbsp;array&nbsp;to&nbsp;use&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;one</span></div></li>
+<li><div class="src-line"><a name="a1324"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.5</span></div></li>
+<li><div class="src-line"><a name="a1325"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;Re-think&nbsp;about&nbsp;how&nbsp;this&nbsp;method&nbsp;works&nbsp;(maybe&nbsp;make&nbsp;it&nbsp;private&nbsp;and/or&nbsp;make&nbsp;it</span></div></li>
+<li><div class="src-line"><a name="a1326"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;extension-&gt;lang&nbsp;lookup?)</span></div></li>
+<li><div class="src-line"><a name="a1327"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;static?</span></div></li>
+<li><div class="src-line"><a name="a1328"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1329"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodget_language_name_from_extension">get_language_name_from_extension</a><span class="src-sym">(</span>&nbsp;<span class="src-var">$extension</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$lookup</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1330"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>&nbsp;<span class="src-sym">!</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$lookup</span><span class="src-sym">)</span>&nbsp;||&nbsp;<span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$lookup</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1331"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lookup</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a1332"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'actionscript'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'as'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1333"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'ada'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'a'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'ada'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'adb'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'ads'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1334"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'apache'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'conf'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1335"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'asm'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'ash'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'asm'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'inc'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1336"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'asp'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'asp'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1337"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'bash'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'sh'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1338"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'bf'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'bf'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1339"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'c'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'c'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'h'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1340"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'c_mac'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'c'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'h'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1341"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'caddcl'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1342"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'cadlisp'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1343"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'cdfg'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'cdfg'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1344"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'cobol'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'cbl'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1345"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'cpp'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'cpp'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'hpp'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'C'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'H'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'CPP'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'HPP'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1346"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'csharp'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'cs'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1347"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'css'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'css'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1348"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'d'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'d'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1349"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'delphi'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'dpk'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'dpr'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'pp'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'pas'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1350"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'diff'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'diff'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'patch'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1351"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'dos'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'bat'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'cmd'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1352"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'gettext'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'po'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'pot'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1353"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'gml'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'gml'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1354"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'gnuplot'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'plt'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1355"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'groovy'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'groovy'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1356"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'haskell'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'hs'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1357"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'html4strict'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'html'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'htm'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1358"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'ini'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'ini'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'desktop'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1359"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'java'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'java'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1360"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'javascript'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'js'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1361"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'klonec'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'kl1'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1362"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'klonecpp'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'klx'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1363"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'latex'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'tex'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1364"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'lisp'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'lisp'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1365"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'lua'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'lua'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1366"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'matlab'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'m'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1367"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'mpasm'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1368"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'mysql'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'sql'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1369"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'nsis'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1370"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'objc'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1371"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'oobas'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1372"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'oracle8'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1373"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'oracle10'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1374"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'pascal'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'pas'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1375"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'perl'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'pl'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'pm'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1376"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'php'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'php'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'php5'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'phtml'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'phps'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1377"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'povray'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'pov'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1378"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'providex'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'pvc'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'pvx'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1379"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'prolog'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'pl'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1380"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'python'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'py'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1381"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'qbasic'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'bi'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1382"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'reg'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'reg'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1383"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'ruby'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'rb'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1384"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'sas'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'sas'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1385"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'scala'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'scala'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1386"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'scheme'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'scm'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1387"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'scilab'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'sci'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1388"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'smalltalk'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'st'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1389"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'smarty'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1390"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'tcl'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'tcl'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1391"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'vb'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'bas'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1392"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'vbnet'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1393"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'visualfoxpro'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1394"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'whitespace'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'ws'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1395"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'xml'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'xml'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'svg'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1396"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'z80'</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'z80'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'asm'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'inc'</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a1397"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1398"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1399"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1400"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$lookup</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$lang</span>&nbsp;=&gt;&nbsp;<span class="src-var">$extensions</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1401"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$extension</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$extensions</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1402"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$lang</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1403"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1404"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1405"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1406"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1407"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1408"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1409"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Given&nbsp;a&nbsp;file&nbsp;name,&nbsp;this&nbsp;method&nbsp;loads&nbsp;its&nbsp;contents&nbsp;in,&nbsp;and&nbsp;attempts</span></div></li>
+<li><div class="src-line"><a name="a1410"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;to&nbsp;set&nbsp;the&nbsp;language&nbsp;automatically.&nbsp;An&nbsp;optional&nbsp;lookup&nbsp;table&nbsp;can&nbsp;be</span></div></li>
+<li><div class="src-line"><a name="a1411"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;passed&nbsp;for&nbsp;looking&nbsp;up&nbsp;the&nbsp;language&nbsp;name.&nbsp;If&nbsp;not&nbsp;specified&nbsp;a&nbsp;default</span></div></li>
+<li><div class="src-line"><a name="a1412"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;table&nbsp;is&nbsp;used</span></div></li>
+<li><div class="src-line"><a name="a1413"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1414"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;language&nbsp;table&nbsp;is&nbsp;in&nbsp;the&nbsp;form</span></div></li>
+<li><div class="src-line"><a name="a1415"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;pre&gt;array(</span></div></li>
+<li><div class="src-line"><a name="a1416"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;'lang_name'&nbsp;=&gt;&nbsp;array('extension',&nbsp;'extension',&nbsp;...),</span></div></li>
+<li><div class="src-line"><a name="a1417"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;'lang_name'&nbsp;...</span></div></li>
+<li><div class="src-line"><a name="a1418"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;);&lt;/pre&gt;</span></div></li>
+<li><div class="src-line"><a name="a1419"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1420"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;filename&nbsp;to&nbsp;load&nbsp;the&nbsp;source&nbsp;from</span></div></li>
+<li><div class="src-line"><a name="a1421"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">array&nbsp;</span><span class="src-doc">&nbsp;A&nbsp;lookup&nbsp;array&nbsp;to&nbsp;use&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;one</span></div></li>
+<li><div class="src-line"><a name="a1422"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;Complete&nbsp;rethink&nbsp;of&nbsp;this&nbsp;and&nbsp;above&nbsp;method</span></div></li>
+<li><div class="src-line"><a name="a1423"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.5</span></div></li>
+<li><div class="src-line"><a name="a1424"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1425"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodload_from_file">load_from_file</a><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$lookup</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1426"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_readable">is_readable</a><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1427"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_source">set_source</a><span class="src-sym">(</span><a href="http://www.php.net/file_get_contents">file_get_contents</a><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1428"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_language">set_language</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodget_language_name_from_extension">get_language_name_from_extension</a><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><a href="http://www.php.net/strrchr">strrchr</a><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'.'</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$lookup</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1429"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1430"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span>&nbsp;=&nbsp;<span class="src-id">GESHI_ERROR_FILE_NOT_READABLE</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1431"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1432"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1433"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1434"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1435"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Adds&nbsp;a&nbsp;keyword&nbsp;to&nbsp;a&nbsp;keyword&nbsp;group&nbsp;for&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a1436"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1437"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;add&nbsp;the&nbsp;keyword&nbsp;to</span></div></li>
+<li><div class="src-line"><a name="a1438"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;word&nbsp;to&nbsp;add&nbsp;to&nbsp;the&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1439"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1440"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1441"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodadd_keyword">add_keyword</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$word</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1442"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1443"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$word</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1444"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1445"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//NEW&nbsp;in&nbsp;1.0.8&nbsp;don't&nbsp;recompile&nbsp;the&nbsp;whole&nbsp;optimized&nbsp;regexp,&nbsp;simply&nbsp;append&nbsp;it</span></span></div></li>
+<li><div class="src-line"><a name="a1446"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">parse_cache_built</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1447"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$subkey</span>&nbsp;=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1448"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$subkey</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-str">'|'</span>&nbsp;.&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1449"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1450"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1451"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1452"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1453"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1454"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Removes&nbsp;a&nbsp;keyword&nbsp;from&nbsp;a&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1455"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1456"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;remove&nbsp;the&nbsp;keyword&nbsp;from</span></div></li>
+<li><div class="src-line"><a name="a1457"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;word&nbsp;to&nbsp;remove&nbsp;from&nbsp;the&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1458"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">bool&nbsp;</span><span class="src-doc">&nbsp;&nbsp;Wether&nbsp;to&nbsp;automatically&nbsp;recompile&nbsp;the&nbsp;optimized&nbsp;regexp&nbsp;list&nbsp;or&nbsp;not.</span></div></li>
+<li><div class="src-line"><a name="a1459"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Note:&nbsp;if&nbsp;you&nbsp;set&nbsp;this&nbsp;to&nbsp;false&nbsp;and&nbsp;@see&nbsp;GeSHi-&gt;parse_code()&nbsp;was&nbsp;already&nbsp;called&nbsp;once,</span></div></li>
+<li><div class="src-line"><a name="a1460"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;the&nbsp;current&nbsp;language,&nbsp;you&nbsp;have&nbsp;to&nbsp;manually&nbsp;call&nbsp;@see&nbsp;GeSHi-&gt;optimize_keyword_group()</span></div></li>
+<li><div class="src-line"><a name="a1461"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;the&nbsp;removed&nbsp;keyword&nbsp;will&nbsp;stay&nbsp;in&nbsp;cache&nbsp;and&nbsp;still&nbsp;be&nbsp;highlighted!&nbsp;On&nbsp;the&nbsp;other&nbsp;hand</span></div></li>
+<li><div class="src-line"><a name="a1462"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it&nbsp;might&nbsp;be&nbsp;too&nbsp;expensive&nbsp;to&nbsp;recompile&nbsp;the&nbsp;regexp&nbsp;list&nbsp;for&nbsp;every&nbsp;removal&nbsp;if&nbsp;you&nbsp;want&nbsp;to</span></div></li>
+<li><div class="src-line"><a name="a1463"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remove&nbsp;a&nbsp;lot&nbsp;of&nbsp;keywords.</span></div></li>
+<li><div class="src-line"><a name="a1464"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1465"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1466"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodremove_keyword">remove_keyword</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$word</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$recompile</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1467"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$key_to_remove</span>&nbsp;=&nbsp;<a href="http://www.php.net/array_search">array_search</a><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1468"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$key_to_remove</span>&nbsp;!==&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1469"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key_to_remove</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1470"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1471"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//NEW&nbsp;in&nbsp;1.0.8,&nbsp;optionally&nbsp;recompile&nbsp;keyword&nbsp;group</span></span></div></li>
+<li><div class="src-line"><a name="a1472"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$recompile</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">parse_cache_built</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1473"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodoptimize_keyword_group">optimize_keyword_group</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1474"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1475"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1476"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1477"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1478"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1479"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Creates&nbsp;a&nbsp;new&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1480"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1481"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;create</span></div></li>
+<li><div class="src-line"><a name="a1482"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;styles&nbsp;for&nbsp;the&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1483"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Whether&nbsp;the&nbsp;keyword&nbsp;group&nbsp;is&nbsp;case&nbsp;sensitive&nbsp;ornot</span></div></li>
+<li><div class="src-line"><a name="a1484"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">array&nbsp;</span><span class="src-doc">&nbsp;The&nbsp;words&nbsp;to&nbsp;use&nbsp;for&nbsp;the&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1485"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1486"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1487"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodadd_keyword_group">add_keyword_group</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$styles</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$case_sensitive</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$words</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1488"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$words</span>&nbsp;=&nbsp;(array)&nbsp;<span class="src-var">$words</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1489"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$words</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1490"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;empty&nbsp;word&nbsp;lists&nbsp;mess&nbsp;up&nbsp;highlighting</span></span></div></li>
+<li><div class="src-line"><a name="a1491"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1492"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1493"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1494"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Add&nbsp;the&nbsp;new&nbsp;keyword&nbsp;group&nbsp;internally</span></span></div></li>
+<li><div class="src-line"><a name="a1495"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$words</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1496"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1497"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$case_sensitive</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1498"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$styles</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1499"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1500"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//NEW&nbsp;in&nbsp;1.0.8,&nbsp;cache&nbsp;keyword&nbsp;regexp</span></span></div></li>
+<li><div class="src-line"><a name="a1501"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">parse_cache_built</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1502"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodoptimize_keyword_group">optimize_keyword_group</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1503"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1504"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1505"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1506"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1507"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Removes&nbsp;a&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1508"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1509"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;remove</span></div></li>
+<li><div class="src-line"><a name="a1510"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1511"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1512"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodremove_keyword_group">remove_keyword_group</a>&nbsp;<span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1513"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Remove&nbsp;the&nbsp;keyword&nbsp;group&nbsp;internally</span></span></div></li>
+<li><div class="src-line"><a name="a1514"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1515"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1516"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1517"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1518"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1519"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//NEW&nbsp;in&nbsp;1.0.8</span></span></div></li>
+<li><div class="src-line"><a name="a1520"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1521"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1522"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1523"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1524"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;compile&nbsp;optimized&nbsp;regexp&nbsp;list&nbsp;for&nbsp;keyword&nbsp;group</span></div></li>
+<li><div class="src-line"><a name="a1525"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1526"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">&nbsp;&nbsp;The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;compile&nbsp;&amp;&nbsp;optimize</span></div></li>
+<li><div class="src-line"><a name="a1527"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a1528"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1529"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodoptimize_keyword_group">optimize_keyword_group</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1530"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a1531"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">optimize_regexp_list</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1532"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1533"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1534"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1535"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;content&nbsp;of&nbsp;the&nbsp;header&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a1536"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1537"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;content&nbsp;of&nbsp;the&nbsp;header&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a1538"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1539"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1540"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_header_content">set_header_content</a><span class="src-sym">(</span><span class="src-var">$content</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1541"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">header_content</span>&nbsp;=&nbsp;<span class="src-var">$content</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1542"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1543"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1544"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1545"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;content&nbsp;of&nbsp;the&nbsp;footer&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a1546"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1547"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;content&nbsp;of&nbsp;the&nbsp;footer&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a1548"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1549"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1550"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_footer_content">set_footer_content</a><span class="src-sym">(</span><span class="src-var">$content</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1551"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">footer_content</span>&nbsp;=&nbsp;<span class="src-var">$content</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1552"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1553"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1554"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1555"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;style&nbsp;for&nbsp;the&nbsp;header&nbsp;content</span></div></li>
+<li><div class="src-line"><a name="a1556"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1557"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;style&nbsp;for&nbsp;the&nbsp;header&nbsp;content</span></div></li>
+<li><div class="src-line"><a name="a1558"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1559"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1560"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_header_content_style">set_header_content_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1561"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">header_content_style</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1562"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1563"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1564"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1565"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;style&nbsp;for&nbsp;the&nbsp;footer&nbsp;content</span></div></li>
+<li><div class="src-line"><a name="a1566"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1567"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;style&nbsp;for&nbsp;the&nbsp;footer&nbsp;content</span></div></li>
+<li><div class="src-line"><a name="a1568"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1569"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1570"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_footer_content_style">set_footer_content_style</a><span class="src-sym">(</span><span class="src-var">$style</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1571"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">footer_content_style</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1572"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1573"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1574"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1575"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;whether&nbsp;to&nbsp;force&nbsp;a&nbsp;surrounding&nbsp;block&nbsp;around</span></div></li>
+<li><div class="src-line"><a name="a1576"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;highlighted&nbsp;code&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a1577"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1578"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Tells&nbsp;whether&nbsp;to&nbsp;enable&nbsp;or&nbsp;disable&nbsp;this&nbsp;feature</span></div></li>
+<li><div class="src-line"><a name="a1579"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.7.20</span></div></li>
+<li><div class="src-line"><a name="a1580"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1581"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_inner_code_block">enable_inner_code_block</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1582"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">force_code_block</span>&nbsp;=&nbsp;(bool)<span class="src-var">$flag</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1583"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1584"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1585"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1586"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;base&nbsp;URL&nbsp;to&nbsp;be&nbsp;used&nbsp;for&nbsp;keywords</span></div></li>
+<li><div class="src-line"><a name="a1587"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1588"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">The&nbsp;key&nbsp;of&nbsp;the&nbsp;keyword&nbsp;group&nbsp;to&nbsp;set&nbsp;the&nbsp;URL&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a1589"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;URL&nbsp;to&nbsp;set&nbsp;for&nbsp;the&nbsp;group.&nbsp;If&nbsp;{FNAME}&nbsp;is&nbsp;in</span></div></li>
+<li><div class="src-line"><a name="a1590"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;url&nbsp;somewhere,&nbsp;it&nbsp;is&nbsp;replaced&nbsp;by&nbsp;the&nbsp;keyword</span></div></li>
+<li><div class="src-line"><a name="a1591"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;the&nbsp;URL&nbsp;is&nbsp;being&nbsp;made&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a1592"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1593"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1594"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_url_for_keyword_group">set_url_for_keyword_group</a><span class="src-sym">(</span><span class="src-var">$group</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$url</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1595"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'URLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$url</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1596"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1597"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1598"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1599"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;styles&nbsp;for&nbsp;links&nbsp;in&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a1600"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1601"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">A&nbsp;constant&nbsp;that&nbsp;specifies&nbsp;what&nbsp;state&nbsp;the&nbsp;style&nbsp;is&nbsp;being</span></div></li>
+<li><div class="src-line"><a name="a1602"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;for&nbsp;-&nbsp;e.g.&nbsp;:hover&nbsp;or&nbsp;:visited</span></div></li>
+<li><div class="src-line"><a name="a1603"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;styles&nbsp;to&nbsp;use&nbsp;for&nbsp;that&nbsp;state</span></div></li>
+<li><div class="src-line"><a name="a1604"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1605"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1606"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_link_styles">set_link_styles</a><span class="src-sym">(</span><span class="src-var">$type</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$styles</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1607"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">link_styles</span><span class="src-sym">[</span><span class="src-var">$type</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$styles</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1608"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1609"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1610"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1611"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;target&nbsp;for&nbsp;links&nbsp;in&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a1612"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1613"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;target&nbsp;for&nbsp;links&nbsp;in&nbsp;the&nbsp;code,&nbsp;e.g.&nbsp;_blank</span></div></li>
+<li><div class="src-line"><a name="a1614"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.3</span></div></li>
+<li><div class="src-line"><a name="a1615"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1616"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_link_target">set_link_target</a><span class="src-sym">(</span><span class="src-var">$target</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1617"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$target</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1618"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">link_target</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1619"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1620"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">link_target</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;target=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$target</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&nbsp;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1621"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1622"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1623"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1624"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1625"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;styles&nbsp;for&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a1626"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1627"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;styles&nbsp;to&nbsp;use&nbsp;on&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a1628"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1629"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1630"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_important_styles">set_important_styles</a><span class="src-sym">(</span><span class="src-var">$styles</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1631"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">important_styles</span>&nbsp;=&nbsp;<span class="src-var">$styles</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1632"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1633"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1634"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1635"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;whether&nbsp;context-important&nbsp;blocks&nbsp;are&nbsp;highlighted</span></div></li>
+<li><div class="src-line"><a name="a1636"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1637"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">Tells&nbsp;whether&nbsp;to&nbsp;enable&nbsp;or&nbsp;disable&nbsp;highlighting&nbsp;of&nbsp;important&nbsp;blocks</span></div></li>
+<li><div class="src-line"><a name="a1638"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;REMOVE&nbsp;THIS&nbsp;SHIZ&nbsp;FROM&nbsp;GESHI!</span></div></li>
+<li><div class="src-line"><a name="a1639"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@deprecated</span></div></li>
+<li><div class="src-line"><a name="a1640"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1641"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1642"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_important_blocks">enable_important_blocks</a><span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1643"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">enable_important_blocks</span>&nbsp;=&nbsp;<span class="src-sym">(</span>&nbsp;<span class="src-var">$flag</span>&nbsp;<span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1644"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1645"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1646"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1647"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Whether&nbsp;CSS&nbsp;IDs&nbsp;should&nbsp;be&nbsp;added&nbsp;to&nbsp;each&nbsp;line</span></div></li>
+<li><div class="src-line"><a name="a1648"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1649"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">If&nbsp;true,&nbsp;IDs&nbsp;will&nbsp;be&nbsp;added&nbsp;to&nbsp;each&nbsp;line.</span></div></li>
+<li><div class="src-line"><a name="a1650"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1651"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1652"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_ids">enable_ids</a><span class="src-sym">(</span><span class="src-var">$flag</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1653"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">add_ids</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-id">true</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1654"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1655"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1656"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1657"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Specifies&nbsp;which&nbsp;lines&nbsp;to&nbsp;highlight&nbsp;extra</span></div></li>
+<li><div class="src-line"><a name="a1658"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1659"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;extra&nbsp;style&nbsp;parameter&nbsp;was&nbsp;added&nbsp;in&nbsp;1.0.7.21.</span></div></li>
+<li><div class="src-line"><a name="a1660"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1661"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">mixed&nbsp;</span><span class="src-doc">An&nbsp;array&nbsp;of&nbsp;line&nbsp;numbers&nbsp;to&nbsp;highlight,&nbsp;or&nbsp;just&nbsp;a&nbsp;line</span></div></li>
+<li><div class="src-line"><a name="a1662"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number&nbsp;on&nbsp;its&nbsp;own.</span></div></li>
+<li><div class="src-line"><a name="a1663"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">A&nbsp;string&nbsp;specifying&nbsp;the&nbsp;style&nbsp;to&nbsp;use&nbsp;for&nbsp;this&nbsp;line.</span></div></li>
+<li><div class="src-line"><a name="a1664"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;null&nbsp;is&nbsp;specified,&nbsp;the&nbsp;default&nbsp;style&nbsp;is&nbsp;used.</span></div></li>
+<li><div class="src-line"><a name="a1665"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;false&nbsp;is&nbsp;specified,&nbsp;the&nbsp;line&nbsp;will&nbsp;be&nbsp;removed&nbsp;from</span></div></li>
+<li><div class="src-line"><a name="a1666"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;special&nbsp;highlighting</span></div></li>
+<li><div class="src-line"><a name="a1667"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1668"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;&nbsp;Some&nbsp;data&nbsp;replication&nbsp;here&nbsp;that&nbsp;could&nbsp;be&nbsp;cut&nbsp;down&nbsp;on</span></div></li>
+<li><div class="src-line"><a name="a1669"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1670"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodhighlight_lines_extra">highlight_lines_extra</a><span class="src-sym">(</span><span class="src-var">$lines</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style</span>&nbsp;=&nbsp;<span class="src-id">null</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1671"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$lines</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1672"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Split&nbsp;up&nbsp;the&nbsp;job&nbsp;using&nbsp;single&nbsp;lines&nbsp;at&nbsp;a&nbsp;time</span></span></div></li>
+<li><div class="src-line"><a name="a1673"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$lines</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$line</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1674"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodhighlight_lines_extra">highlight_lines_extra</a><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1675"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1676"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1677"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Mark&nbsp;the&nbsp;line&nbsp;as&nbsp;being&nbsp;highlighted&nbsp;specially</span></span></div></li>
+<li><div class="src-line"><a name="a1678"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span>&nbsp;=&nbsp;<a href="http://www.php.net/intval">intval</a><span class="src-sym">(</span><span class="src-var">$lines</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1679"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines</span><span class="src-sym">[</span><span class="src-var">$lines</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$lines</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1680"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1681"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Decide&nbsp;on&nbsp;which&nbsp;style&nbsp;to&nbsp;use</span></span></div></li>
+<li><div class="src-line"><a name="a1682"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$style</span>&nbsp;===&nbsp;<span class="src-id">null</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span>&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;we&nbsp;should&nbsp;use&nbsp;default&nbsp;style</span></span></div></li>
+<li><div class="src-line"><a name="a1683"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$lines</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1684"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$style</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span>&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;to&nbsp;remove&nbsp;this&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a1685"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines</span><span class="src-sym">[</span><span class="src-var">$lines</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1686"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$lines</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1687"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1688"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$lines</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$style</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1689"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1690"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1691"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1692"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1693"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1694"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;style&nbsp;for&nbsp;extra-highlighted&nbsp;lines</span></div></li>
+<li><div class="src-line"><a name="a1695"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1696"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;style&nbsp;for&nbsp;extra-highlighted&nbsp;lines</span></div></li>
+<li><div class="src-line"><a name="a1697"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1698"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1699"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_highlight_lines_extra_style">set_highlight_lines_extra_style</a><span class="src-sym">(</span><span class="src-var">$styles</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1700"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">highlight_extra_lines_style</span>&nbsp;=&nbsp;<span class="src-var">$styles</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1701"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1702"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1703"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1704"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;line-ending</span></div></li>
+<li><div class="src-line"><a name="a1705"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1706"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;new&nbsp;line-ending</span></div></li>
+<li><div class="src-line"><a name="a1707"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1708"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1709"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_line_ending">set_line_ending</a><span class="src-sym">(</span><span class="src-var">$line_ending</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1710"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_ending</span>&nbsp;=&nbsp;(string)<span class="src-var">$line_ending</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1711"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1712"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1713"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1714"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;what&nbsp;number&nbsp;line&nbsp;numbers&nbsp;should&nbsp;start&nbsp;at.&nbsp;Should</span></div></li>
+<li><div class="src-line"><a name="a1715"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;be&nbsp;a&nbsp;positive&nbsp;integer,&nbsp;and&nbsp;will&nbsp;be&nbsp;converted&nbsp;to&nbsp;one.</span></div></li>
+<li><div class="src-line"><a name="a1716"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1717"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;b&gt;Warning:&lt;/b&gt;&nbsp;Using&nbsp;this&nbsp;method&nbsp;will&nbsp;add&nbsp;the&nbsp;&quot;start&quot;</span></div></li>
+<li><div class="src-line"><a name="a1718"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;attribute&nbsp;to&nbsp;the&nbsp;&amp;lt;ol&amp;gt;&nbsp;that&nbsp;is&nbsp;used&nbsp;for&nbsp;line&nbsp;numbering.</span></div></li>
+<li><div class="src-line"><a name="a1719"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;is&nbsp;&lt;b&gt;not&lt;/b&gt;&nbsp;valid&nbsp;XHTML&nbsp;strict,&nbsp;so&nbsp;if&nbsp;that's&nbsp;what&nbsp;you</span></div></li>
+<li><div class="src-line"><a name="a1720"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;care&nbsp;about&nbsp;then&nbsp;don't&nbsp;use&nbsp;this&nbsp;method.&nbsp;Firefox&nbsp;is&nbsp;getting</span></div></li>
+<li><div class="src-line"><a name="a1721"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;support&nbsp;for&nbsp;the&nbsp;CSS&nbsp;method&nbsp;of&nbsp;doing&nbsp;this&nbsp;in&nbsp;1.1&nbsp;and&nbsp;Opera</span></div></li>
+<li><div class="src-line"><a name="a1722"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;has&nbsp;support&nbsp;for&nbsp;the&nbsp;CSS&nbsp;method,&nbsp;but&nbsp;(of&nbsp;course)&nbsp;IE&nbsp;doesn't</span></div></li>
+<li><div class="src-line"><a name="a1723"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;so&nbsp;it's&nbsp;not&nbsp;worth&nbsp;doing&nbsp;it&nbsp;the&nbsp;CSS&nbsp;way&nbsp;yet.</span></div></li>
+<li><div class="src-line"><a name="a1724"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1725"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">int&nbsp;</span><span class="src-doc">The&nbsp;number&nbsp;to&nbsp;start&nbsp;line&nbsp;numbers&nbsp;at</span></div></li>
+<li><div class="src-line"><a name="a1726"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1727"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1728"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodstart_line_numbers_at">start_line_numbers_at</a><span class="src-sym">(</span><span class="src-var">$number</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1729"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">line_numbers_start</span>&nbsp;=&nbsp;<a href="http://www.php.net/abs">abs</a><span class="src-sym">(</span><a href="http://www.php.net/intval">intval</a><span class="src-sym">(</span><span class="src-var">$number</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1730"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1731"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1732"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1733"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;encoding&nbsp;used&nbsp;for&nbsp;htmlspecialchars(),&nbsp;for&nbsp;international</span></div></li>
+<li><div class="src-line"><a name="a1734"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;support.</span></div></li>
+<li><div class="src-line"><a name="a1735"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1736"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;NOTE:&nbsp;This&nbsp;is&nbsp;not&nbsp;needed&nbsp;for&nbsp;now&nbsp;because&nbsp;htmlspecialchars()&nbsp;is&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a1737"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;being&nbsp;used&nbsp;(it&nbsp;has&nbsp;a&nbsp;security&nbsp;hole&nbsp;in&nbsp;PHP4&nbsp;that&nbsp;has&nbsp;not&nbsp;been&nbsp;patched).</span></div></li>
+<li><div class="src-line"><a name="a1738"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Maybe&nbsp;in&nbsp;a&nbsp;future&nbsp;version&nbsp;it&nbsp;may&nbsp;make&nbsp;a&nbsp;return&nbsp;for&nbsp;speed&nbsp;reasons,&nbsp;but</span></div></li>
+<li><div class="src-line"><a name="a1739"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;I&nbsp;doubt&nbsp;it.</span></div></li>
+<li><div class="src-line"><a name="a1740"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1741"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;encoding&nbsp;to&nbsp;use&nbsp;for&nbsp;the&nbsp;source</span></div></li>
+<li><div class="src-line"><a name="a1742"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.3</span></div></li>
+<li><div class="src-line"><a name="a1743"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1744"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodset_encoding">set_encoding</a><span class="src-sym">(</span><span class="src-var">$encoding</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1745"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$encoding</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1746"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">encoding</span>&nbsp;=&nbsp;<a href="http://www.php.net/strtolower">strtolower</a><span class="src-sym">(</span><span class="src-var">$encoding</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1747"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1748"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1749"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1750"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1751"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Turns&nbsp;linking&nbsp;of&nbsp;keywords&nbsp;on&nbsp;or&nbsp;off.</span></div></li>
+<li><div class="src-line"><a name="a1752"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1753"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">boolean&nbsp;</span><span class="src-doc">If&nbsp;true,&nbsp;links&nbsp;will&nbsp;be&nbsp;added&nbsp;to&nbsp;keywords</span></div></li>
+<li><div class="src-line"><a name="a1754"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a1755"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1756"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodenable_keyword_links">enable_keyword_links</a><span class="src-sym">(</span><span class="src-var">$enable</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1757"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">keyword_links</span>&nbsp;=&nbsp;(bool)&nbsp;<span class="src-var">$enable</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1758"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1759"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1760"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1761"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Setup&nbsp;caches&nbsp;needed&nbsp;for&nbsp;styling.&nbsp;This&nbsp;is&nbsp;automatically&nbsp;called&nbsp;in</span></div></li>
+<li><div class="src-line"><a name="a1762"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;parse_code()&nbsp;and&nbsp;get_stylesheet()&nbsp;when&nbsp;appropriate.&nbsp;This&nbsp;function&nbsp;helps</span></div></li>
+<li><div class="src-line"><a name="a1763"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;stylesheet&nbsp;generators&nbsp;as&nbsp;they&nbsp;rely&nbsp;on&nbsp;some&nbsp;style&nbsp;information&nbsp;being</span></div></li>
+<li><div class="src-line"><a name="a1764"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;preprocessed</span></div></li>
+<li><div class="src-line"><a name="a1765"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1766"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a1767"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a1768"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1769"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">build_style_cache</span><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1770"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Build&nbsp;the&nbsp;style&nbsp;cache&nbsp;needed&nbsp;to&nbsp;highlight&nbsp;numbers&nbsp;appropriate</span></span></div></li>
+<li><div class="src-line"><a name="a1771"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1772"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//First&nbsp;check&nbsp;what&nbsp;way&nbsp;highlighting&nbsp;information&nbsp;for&nbsp;numbers&nbsp;are&nbsp;given</span></span></div></li>
+<li><div class="src-line"><a name="a1773"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1774"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1775"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1776"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1777"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1778"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1779"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1780"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1781"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1782"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a1783"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_INT_BASIC</span>&nbsp;|</span></div></li>
+<li><div class="src-line"><a name="a1784"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_FLT_NONSCI</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1785"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1786"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1787"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span><span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$j</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$j</span>&nbsp;>&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$j</span>&gt;&gt;=<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1788"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Rearrange&nbsp;style&nbsp;indices&nbsp;if&nbsp;required&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a1789"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span>&lt;&lt;<span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1790"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a1791"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span>&lt;&lt;<span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1792"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span>&lt;&lt;<span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1793"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1794"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1795"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;this&nbsp;bit&nbsp;is&nbsp;set&nbsp;for&nbsp;highlighting</span></span></div></li>
+<li><div class="src-line"><a name="a1796"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-var">$j</span><span class="src-sym">&</span><span class="src-num">1</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1797"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//So&nbsp;this&nbsp;bit&nbsp;is&nbsp;set&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a1798"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;it&nbsp;belongs&nbsp;to&nbsp;group&nbsp;0&nbsp;or&nbsp;the&nbsp;actual&nbsp;stylegroup</span></span></div></li>
+<li><div class="src-line"><a name="a1799"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1800"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-num">1</span>&nbsp;&lt;&lt;&nbsp;<span class="src-var">$i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1801"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1802"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1803"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1804"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1805"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;|=&nbsp;<span class="src-num">1</span>&nbsp;&lt;&lt;&nbsp;<span class="src-var">$i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1806"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1807"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1808"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1809"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1810"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1811"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1812"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1813"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a1814"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Setup&nbsp;caches&nbsp;needed&nbsp;for&nbsp;parsing.&nbsp;This&nbsp;is&nbsp;automatically&nbsp;called&nbsp;in&nbsp;parse_code()&nbsp;when&nbsp;appropriate.</span></div></li>
+<li><div class="src-line"><a name="a1815"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;function&nbsp;makes&nbsp;stylesheet&nbsp;generators&nbsp;much&nbsp;faster&nbsp;as&nbsp;they&nbsp;do&nbsp;not&nbsp;need&nbsp;these&nbsp;caches.</span></div></li>
+<li><div class="src-line"><a name="a1816"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1817"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a1818"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a1819"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a1820"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">build_parse_cache</span><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1821"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;cache&nbsp;symbol&nbsp;regexp</span></span></div></li>
+<li><div class="src-line"><a name="a1822"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//As&nbsp;this&nbsp;is&nbsp;a&nbsp;costy&nbsp;operation,&nbsp;we&nbsp;avoid&nbsp;doing&nbsp;it&nbsp;for&nbsp;multiple&nbsp;groups&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a1823"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Instead&nbsp;we&nbsp;perform&nbsp;it&nbsp;for&nbsp;all&nbsp;symbols&nbsp;at&nbsp;once.</span></span></div></li>
+<li><div class="src-line"><a name="a1824"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a1825"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//For&nbsp;this&nbsp;to&nbsp;work,&nbsp;we&nbsp;need&nbsp;to&nbsp;reorganize&nbsp;the&nbsp;data&nbsp;arrays.</span></span></div></li>
+<li><div class="src-line"><a name="a1826"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1827"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'MULTIPLE_SYMBOL_GROUPS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;>&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1828"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1829"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1830"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_multi</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;multi&nbsp;char&nbsp;symbols</span></span></div></li>
+<li><div class="src-line"><a name="a1831"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_single</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;single&nbsp;char&nbsp;symbols</span></span></div></li>
+<li><div class="src-line"><a name="a1832"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$symbols</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1833"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$symbols</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1834"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$symbols</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$sym</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1835"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$sym</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$sym</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1836"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$sym</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1837"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$sym</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1838"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$sym</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span>&nbsp;<span class="src-comm">//&nbsp;multiple&nbsp;chars</span></span></div></li>
+<li><div class="src-line"><a name="a1839"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_multi</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$sym</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1840"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span>&nbsp;<span class="src-comm">//&nbsp;single&nbsp;char</span></span></div></li>
+<li><div class="src-line"><a name="a1841"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$sym</span>&nbsp;==&nbsp;<span class="src-str">'-'</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1842"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;don't&nbsp;trigger&nbsp;range&nbsp;out&nbsp;of&nbsp;order&nbsp;error</span></span></div></li>
+<li><div class="src-line"><a name="a1843"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_single</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'\-'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1844"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1845"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_single</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$sym</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1846"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1847"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1848"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1849"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1850"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1851"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbols</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$symbols</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1852"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$symbols</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1853"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$symbols</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1854"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$symbols</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span>&nbsp;<span class="src-comm">//&nbsp;multiple&nbsp;chars</span></span></div></li>
+<li><div class="src-line"><a name="a1855"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_multi</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$symbols</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1856"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$symbols</span>&nbsp;==&nbsp;<span class="src-str">'-'</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1857"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;don't&nbsp;trigger&nbsp;range&nbsp;out&nbsp;of&nbsp;order&nbsp;error</span></span></div></li>
+<li><div class="src-line"><a name="a1858"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_single</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'\-'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1859"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span>&nbsp;<span class="src-comm">//&nbsp;single&nbsp;char</span></span></div></li>
+<li><div class="src-line"><a name="a1860"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg_single</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><span class="src-var">$symbols</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1861"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1862"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1863"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1864"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1865"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1866"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Now&nbsp;we&nbsp;have&nbsp;an&nbsp;array&nbsp;with&nbsp;each&nbsp;possible&nbsp;symbol&nbsp;as&nbsp;the&nbsp;key&nbsp;and&nbsp;the&nbsp;style&nbsp;as&nbsp;the&nbsp;actual&nbsp;data.</span></span></div></li>
+<li><div class="src-line"><a name="a1867"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;way&nbsp;we&nbsp;can&nbsp;set&nbsp;the&nbsp;correct&nbsp;style&nbsp;just&nbsp;the&nbsp;moment&nbsp;we&nbsp;highlight&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a1868"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a1869"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Now&nbsp;we&nbsp;need&nbsp;to&nbsp;rewrite&nbsp;our&nbsp;array&nbsp;to&nbsp;get&nbsp;a&nbsp;search&nbsp;string&nbsp;that</span></span></div></li>
+<li><div class="src-line"><a name="a1870"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1871"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$symbol_preg_multi</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1872"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/rsort">rsort</a><span class="src-sym">(</span><span class="src-var">$symbol_preg_multi</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1873"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-str">'|'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_preg_multi</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1874"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1875"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$symbol_preg_single</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1876"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/rsort">rsort</a><span class="src-sym">(</span><span class="src-var">$symbol_preg_single</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1877"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_preg</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'['</span>&nbsp;.&nbsp;<a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-str">''</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_preg_single</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">']'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1878"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1879"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_SEARCH'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-str">&quot;|&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_preg</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1880"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1881"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1882"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;cache&nbsp;optimized&nbsp;regexp&nbsp;for&nbsp;keyword&nbsp;matching</span></span></div></li>
+<li><div class="src-line"><a name="a1883"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;remove&nbsp;old&nbsp;cache</span></span></div></li>
+<li><div class="src-line"><a name="a1884"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1885"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1886"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a1887"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1888"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodoptimize_keyword_group">optimize_keyword_group</a><span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1889"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1890"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1891"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1892"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;brackets</span></span></div></li>
+<li><div class="src-line"><a name="a1893"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1894"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHE_BRACKET_MATCH'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'['</span><span class="src-sym">,</span>&nbsp;<span class="src-str">']'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'('</span><span class="src-sym">,</span>&nbsp;<span class="src-str">')'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'{'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'}'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1895"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">use_classes</span>&nbsp;&amp;&amp;&nbsp;isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1896"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHE_BRACKET_REPLACE'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a1897"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;&amp;#91;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1898"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;&amp;#93;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1899"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;&amp;#40;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1900"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;&amp;#41;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1901"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;&amp;#123;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1902"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;&amp;#125;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1903"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1904"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1905"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1906"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHE_BRACKET_REPLACE'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a1907"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;br0&quot;&gt;&amp;#91;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1908"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;br0&quot;&gt;&amp;#93;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1909"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;br0&quot;&gt;&amp;#40;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1910"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;br0&quot;&gt;&amp;#41;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1911"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;br0&quot;&gt;&amp;#123;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1912"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;br0&quot;&gt;&amp;#125;|&gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1913"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1914"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1915"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1916"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1917"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Build&nbsp;the&nbsp;parse&nbsp;cache&nbsp;needed&nbsp;to&nbsp;highlight&nbsp;numbers&nbsp;appropriate</span></span></div></li>
+<li><div class="src-line"><a name="a1918"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1919"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;the&nbsp;style&nbsp;rearrangements&nbsp;have&nbsp;been&nbsp;processed&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a1920"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;also&nbsp;does&nbsp;some&nbsp;preprocessing&nbsp;to&nbsp;check&nbsp;which&nbsp;style&nbsp;groups&nbsp;are&nbsp;useable&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a1921"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1922"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">build_style_cache</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1923"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1924"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1925"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Number&nbsp;format&nbsp;specification</span></span></div></li>
+<li><div class="src-line"><a name="a1926"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//All&nbsp;this&nbsp;formats&nbsp;are&nbsp;matched&nbsp;case-insensitively!</span></span></div></li>
+<li><div class="src-line"><a name="a1927"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">static</span>&nbsp;<span class="src-var">$numbers_format</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a1928"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_INT_BASIC</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1929"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.%])(?&lt;![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1930"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_INT_CSTYLE</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1931"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.%])(?&lt;![\d\.]e[+\-])([1-9]\d*?|0)l(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1932"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_BIN_SUFFIX</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1933"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])[01]+?b(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1934"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_BIN_PREFIX_PERCENT</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1935"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.%])(?&lt;![\d\.]e[+\-])%[01]+?(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1936"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_BIN_PREFIX_0B</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1937"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.%])(?&lt;![\d\.]e[+\-])0b[01]+?(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1938"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_OCT_PREFIX</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1939"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])0[0-7]+?(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1940"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_OCT_SUFFIX</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1941"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])[0-7]+?o(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1942"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_HEX_PREFIX</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1943"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])0x[0-9a-f]+?(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1944"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_HEX_SUFFIX</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1945"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])\d[0-9a-f]*?h(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1946"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_FLT_NONSCI</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1947"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])\d+?\.\d+?(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1948"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_FLT_NONSCI_F</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1949"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)f(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1950"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_FLT_SCI_SHORT</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1951"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])\.\d+?(?:e[+\-]?\d+?)?(?![0-9a-z\.])'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a1952"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GESHI_NUMBER_FLT_SCI_ZERO</span>&nbsp;=&gt;</span></div></li>
+<li><div class="src-line"><a name="a1953"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'(?&lt;![0-9a-z_\.])(?&lt;![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)(?:e[+\-]?\d+?)?(?![0-9a-z\.])'</span></span></div></li>
+<li><div class="src-line"><a name="a1954"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1955"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1956"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//At&nbsp;this&nbsp;step&nbsp;we&nbsp;have&nbsp;an&nbsp;associative&nbsp;array&nbsp;with&nbsp;flag&nbsp;groups&nbsp;for&nbsp;a</span></span></div></li>
+<li><div class="src-line"><a name="a1957"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//specific&nbsp;style&nbsp;or&nbsp;an&nbsp;string&nbsp;denoting&nbsp;a&nbsp;regexp&nbsp;given&nbsp;its&nbsp;index.</span></span></div></li>
+<li><div class="src-line"><a name="a1958"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_RXCACHE'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1959"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$rxdata</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1960"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-id">is_string</span><span class="src-sym">(</span><span class="src-var">$rxdata</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1961"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp</span>&nbsp;=&nbsp;<span class="src-var">$rxdata</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1962"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1963"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;is&nbsp;a&nbsp;bitfield&nbsp;of&nbsp;number&nbsp;flags&nbsp;to&nbsp;highlight:</span></span></div></li>
+<li><div class="src-line"><a name="a1964"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Build&nbsp;an&nbsp;array,&nbsp;implode&nbsp;them&nbsp;together&nbsp;and&nbsp;make&nbsp;this&nbsp;the&nbsp;actual&nbsp;RX</span></span></div></li>
+<li><div class="src-line"><a name="a1965"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$rxuse</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1966"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span><span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">1</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;&lt;=&nbsp;<span class="src-var">$rxdata</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&lt;&lt;=<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1967"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-var">$rxdata</span>&nbsp;<span class="src-sym">&</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1968"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$rxuse</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$numbers_format</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1969"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1970"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1971"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp</span>&nbsp;=&nbsp;<a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-str">&quot;|&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$rxuse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1972"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1973"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1974"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_RXCACHE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a1975"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">"</span></span>/(?&lt;!&lt;\|\/NUM!)(?&lt;!\d\/&gt;)(<span class="src-var">$regexp</span>)(?!\|&gt;)/i<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1976"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1977"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1978"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1979"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">parse_cache_built</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1980"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a1981"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1982"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a1983"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;the&nbsp;code&nbsp;in&nbsp;$this-&gt;source,&nbsp;highlighted&nbsp;and&nbsp;surrounded&nbsp;by&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a1984"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;nessecary&nbsp;HTML.</span></div></li>
+<li><div class="src-line"><a name="a1985"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1986"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;should&nbsp;only&nbsp;be&nbsp;called&nbsp;ONCE,&nbsp;cos&nbsp;it's&nbsp;SLOW!&nbsp;If&nbsp;you&nbsp;want&nbsp;to&nbsp;highlight</span></div></li>
+<li><div class="src-line"><a name="a1987"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;same&nbsp;source&nbsp;multiple&nbsp;times,&nbsp;you're&nbsp;better&nbsp;off&nbsp;doing&nbsp;a&nbsp;whole&nbsp;lot&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a1988"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;str_replaces&nbsp;to&nbsp;replace&nbsp;the&nbsp;&amp;lt;span&amp;gt;s</span></div></li>
+<li><div class="src-line"><a name="a1989"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a1990"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a1991"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a1992"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">parse_code</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1993"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Start&nbsp;the&nbsp;timer</span></span></div></li>
+<li><div class="src-line"><a name="a1994"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start_time</span>&nbsp;=&nbsp;<span class="src-id">microtime</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a1995"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a1996"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Firstly,&nbsp;if&nbsp;there&nbsp;is&nbsp;an&nbsp;error,&nbsp;we&nbsp;won't&nbsp;highlight</span></span></div></li>
+<li><div class="src-line"><a name="a1997"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">error</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a1998"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Escape&nbsp;the&nbsp;source&nbsp;for&nbsp;output</span></span></div></li>
+<li><div class="src-line"><a name="a1999"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-var">source</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2000"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2001"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;fix&nbsp;is&nbsp;related&nbsp;to&nbsp;SF#1923020,&nbsp;but&nbsp;has&nbsp;to&nbsp;be&nbsp;applied&nbsp;regardless&nbsp;of</span></span></div></li>
+<li><div class="src-line"><a name="a2002"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//actually&nbsp;highlighting&nbsp;symbols.</span></span></div></li>
+<li><div class="src-line"><a name="a2003"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<span class="src-id">str_replace</span><span class="src-sym">(</span><span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'&lt;SEMI&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;PIPE&gt;'</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">';'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'|'</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2004"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2005"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Timing&nbsp;is&nbsp;irrelevant</span></span></div></li>
+<li><div class="src-line"><a name="a2006"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">set_time</span><span class="src-sym">(</span><span class="src-var">$start_time</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start_time</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2007"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">finalise</span><span class="src-sym">(</span><span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2008"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2009"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2010"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2011"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;make&nbsp;sure&nbsp;the&nbsp;parse&nbsp;cache&nbsp;is&nbsp;up2date</span></span></div></li>
+<li><div class="src-line"><a name="a2012"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_cache_built</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2013"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">build_parse_cache</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2014"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2015"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2016"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Replace&nbsp;all&nbsp;newlines&nbsp;to&nbsp;a&nbsp;common&nbsp;form.</span></span></div></li>
+<li><div class="src-line"><a name="a2017"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$code</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\r\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">source</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2018"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$code</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\r&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2019"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2020"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;spaces&nbsp;for&nbsp;regular&nbsp;expression&nbsp;matching&nbsp;and&nbsp;line&nbsp;numbers</span></span></div></li>
+<li><div class="src-line"><a name="a2021"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$code&nbsp;=&nbsp;&quot;\n&quot;&nbsp;.&nbsp;$code&nbsp;.&nbsp;&quot;\n&quot;;</span></span></div></li>
+<li><div class="src-line"><a name="a2022"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a2023"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Initialise&nbsp;various&nbsp;stuff</span></span></div></li>
+<li><div class="src-line"><a name="a2024"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$length</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2025"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$COMMENT_MATCHED</span>&nbsp;&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2026"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;&nbsp;&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2027"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$endresult</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2028"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2029"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&quot;Important&quot;&nbsp;selections&nbsp;are&nbsp;handled&nbsp;like&nbsp;multiline&nbsp;comments</span></span></div></li>
+<li><div class="src-line"><a name="a2030"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;@todo&nbsp;GET&nbsp;RID&nbsp;OF&nbsp;THIS&nbsp;SHIZ</span></span></div></li>
+<li><div class="src-line"><a name="a2031"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodenable_important_blocks">enable_important_blocks</a><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2032"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_MULTI'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT&quot;&gt;GESHI_START_IMPORTANT&lt;/a&gt;</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_END_IMPORTANT&quot;&gt;GESHI_END_IMPORTANT&lt;/a&gt;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2033"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2034"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2035"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">strict_mode</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2036"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Break&nbsp;the&nbsp;source&nbsp;into&nbsp;bits.&nbsp;Each&nbsp;bit&nbsp;will&nbsp;be&nbsp;a&nbsp;portion&nbsp;of&nbsp;the&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2037"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;within&nbsp;script&nbsp;delimiters&nbsp;-&nbsp;for&nbsp;example,&nbsp;HTML&nbsp;between&nbsp;&lt;&nbsp;and&nbsp;&gt;</span></span></div></li>
+<li><div class="src-line"><a name="a2038"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$k</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2039"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2040"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$matches</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2041"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_match_pointer</span>&nbsp;=&nbsp;<span class="src-id">null</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2042"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;use&nbsp;a&nbsp;copy&nbsp;to&nbsp;unset&nbsp;delimiters&nbsp;on&nbsp;demand&nbsp;(when&nbsp;they&nbsp;are&nbsp;not&nbsp;found)</span></span></div></li>
+<li><div class="src-line"><a name="a2043"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$delim_copy</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SCRIPT_DELIMITERS'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2044"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2045"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$length</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2046"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_match_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;never&nbsp;true</span></span></div></li>
+<li><div class="src-line"><a name="a2047"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$delim_copy</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$dk</span>&nbsp;=&gt;&nbsp;<span class="src-var">$delimiters</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2048"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$delimiters</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2049"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$delimiters</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$open</span>&nbsp;=&gt;&nbsp;<span class="src-var">$close</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2050"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;make&nbsp;sure&nbsp;the&nbsp;cache&nbsp;is&nbsp;setup&nbsp;properly</span></span></div></li>
+<li><div class="src-line"><a name="a2051"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2052"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2053"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'next_match'</span>&nbsp;=&gt;&nbsp;-<span class="src-num">1</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2054"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'dk'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$dk</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2055"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2056"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'open'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$open</span><span class="src-sym">,</span>&nbsp;<span class="src-comm">//&nbsp;needed&nbsp;for&nbsp;grouping&nbsp;of&nbsp;adjacent&nbsp;code&nbsp;blocks&nbsp;(see&nbsp;below)</span></span></div></li>
+<li><div class="src-line"><a name="a2057"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'open_strlen'</span>&nbsp;=&gt;&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$open</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2058"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2059"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'close'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$close</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2060"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'close_strlen'</span>&nbsp;=&gt;&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$close</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2061"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2062"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2063"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Get&nbsp;the&nbsp;next&nbsp;little&nbsp;bit&nbsp;for&nbsp;this&nbsp;opening&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2064"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span>&nbsp;<&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2065"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;only&nbsp;find&nbsp;the&nbsp;next&nbsp;pos&nbsp;if&nbsp;it&nbsp;was&nbsp;not&nbsp;already&nbsp;cached</span></span></div></li>
+<li><div class="src-line"><a name="a2066"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$open_pos</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$open</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2067"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$open_pos</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2068"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;no&nbsp;match&nbsp;for&nbsp;this&nbsp;delimiter&nbsp;ever</span></span></div></li>
+<li><div class="src-line"><a name="a2069"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$delim_copy</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2070"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2071"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2072"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$open_pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2073"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2074"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span>&nbsp;<&nbsp;<span class="src-var">$next_match_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2075"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//So&nbsp;we&nbsp;got&nbsp;a&nbsp;new&nbsp;match,&nbsp;update&nbsp;the&nbsp;close_pos</span></span></div></li>
+<li><div class="src-line"><a name="a2076"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'close_pos'</span><span class="src-sym">]</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a2077"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span>+<span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2078"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2079"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_match_pointer</span>&nbsp;=<span class="src-sym">&</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2080"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_match_pos</span>&nbsp;=&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2081"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2082"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2083"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2084"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//So&nbsp;we&nbsp;should&nbsp;match&nbsp;an&nbsp;RegExp&nbsp;as&nbsp;Strict&nbsp;Block&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2085"></a><span class="src-doc">/**</span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a2086"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;value&nbsp;in&nbsp;$delimiters&nbsp;is&nbsp;expected&nbsp;to&nbsp;be&nbsp;an&nbsp;RegExp</span></div></li>
+<li><div class="src-line"><a name="a2087"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;containing&nbsp;exactly&nbsp;2&nbsp;matching&nbsp;groups:</span></div></li>
+<li><div class="src-line"><a name="a2088"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;Group&nbsp;1&nbsp;is&nbsp;the&nbsp;opener</span></div></li>
+<li><div class="src-line"><a name="a2089"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;-&nbsp;Group&nbsp;2&nbsp;is&nbsp;the&nbsp;closer</span></div></li>
+<li><div class="src-line"><a name="a2090"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a2091"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-id">GESHI_PHP_PRE_433</span>&nbsp;&amp;&amp;&nbsp;<span class="src-comm">//Needs&nbsp;proper&nbsp;rewrite&nbsp;to&nbsp;work&nbsp;with&nbsp;PHP&nbsp;&gt;=4.3.0;&nbsp;4.3.3&nbsp;is&nbsp;guaranteed&nbsp;to&nbsp;work.</span></span></div></li>
+<li><div class="src-line"><a name="a2092"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-var">$delimiters</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches_rx</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2093"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//We&nbsp;got&nbsp;a&nbsp;match&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2094"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2095"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'next_match'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$matches_rx</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2096"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'dk'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$dk</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2097"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2098"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'close_strlen'</span>&nbsp;=&gt;&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$matches_rx</span><span class="src-sym">[</span><span class="src-num">2</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2099"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'close_pos'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$matches_rx</span><span class="src-sym">[</span><span class="src-num">2</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2100"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2101"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2102"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;no&nbsp;match&nbsp;for&nbsp;this&nbsp;delimiter&nbsp;ever</span></span></div></li>
+<li><div class="src-line"><a name="a2103"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$delim_copy</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2104"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2105"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2106"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2107"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span>&nbsp;&lt;=&nbsp;<span class="src-var">$next_match_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2108"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_match_pointer</span>&nbsp;=<span class="src-sym">&</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2109"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_match_pos</span>&nbsp;=&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-var">$dk</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2110"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2111"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2112"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2113"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;non-highlightable&nbsp;text</span></span></div></li>
+<li><div class="src-line"><a name="a2114"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2115"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pos</span>&nbsp;-&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a2116"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2117"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$k</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2118"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2119"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$next_match_pos</span>&nbsp;>&nbsp;<span class="src-var">$length</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2120"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;out&nbsp;of&nbsp;bounds&nbsp;means&nbsp;no&nbsp;next&nbsp;match&nbsp;was&nbsp;found</span></span></div></li>
+<li><div class="src-line"><a name="a2121"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2122"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2123"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2124"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;highlightable&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2125"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'dk'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2126"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2127"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Only&nbsp;combine&nbsp;for&nbsp;non-rx&nbsp;script&nbsp;blocks</span></span></div></li>
+<li><div class="src-line"><a name="a2128"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$delim_copy</span><span class="src-sym">[</span><span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'dk'</span><span class="src-sym">]]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2129"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;group&nbsp;adjacent&nbsp;script&nbsp;blocks,&nbsp;e.g.&nbsp;&lt;foobar&gt;&lt;asdf&gt;&nbsp;should&nbsp;be&nbsp;one&nbsp;block,&nbsp;not&nbsp;three!</span></span></div></li>
+<li><div class="src-line"><a name="a2130"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$next_match_pos</span>&nbsp;+&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'open_strlen'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2131"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while</span>&nbsp;<span class="src-sym">(</span><span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2132"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'close'</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2133"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close_pos</span>&nbsp;==&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2134"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2135"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2136"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span>&nbsp;+&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'close_strlen'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2137"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;==&nbsp;<span class="src-var">$length</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2138"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2139"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2140"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'open'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'open_strlen'</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-num">1</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2141"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'open_strlen'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;==&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'open'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2142"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;merge&nbsp;adjacent&nbsp;but&nbsp;make&nbsp;sure&nbsp;we&nbsp;don't&nbsp;merge&nbsp;things&nbsp;like&nbsp;&lt;tag&gt;&lt;!--&nbsp;comment&nbsp;--&gt;</span></span></div></li>
+<li><div class="src-line"><a name="a2143"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$matches</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$submatches</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2144"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$submatches</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$match</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2145"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match</span><span class="src-sym">[</span><span class="src-str">'next_match'</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2146"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;a&nbsp;different&nbsp;block&nbsp;already&nbsp;matches&nbsp;here!</span></span></div></li>
+<li><div class="src-line"><a name="a2147"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span>&nbsp;<span class="src-num">3</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2148"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2149"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2150"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2151"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2152"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2153"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2154"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2155"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2156"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'close_pos'</span><span class="src-sym">]</span>&nbsp;+&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">[</span><span class="src-str">'close_strlen'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2157"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2158"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2159"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2160"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close_pos</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2161"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;no&nbsp;closing&nbsp;delimiter&nbsp;found!</span></span></div></li>
+<li><div class="src-line"><a name="a2162"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pos</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2163"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$k</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2164"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2165"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2166"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pos</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;-&nbsp;<span class="src-var">$next_match_pos</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2167"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$k</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2168"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2169"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2170"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$delim_copy</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pointer</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$next_match_pos</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2171"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_parts</span>&nbsp;=&nbsp;<span class="src-var">$k</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2172"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2173"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$num_parts</span>&nbsp;==&nbsp;<span class="src-num">1</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">strict_mode</span>&nbsp;==&nbsp;<span class="src-id">GESHI_MAYBE</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2174"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;when&nbsp;we&nbsp;have&nbsp;only&nbsp;one&nbsp;part,&nbsp;we&nbsp;don't&nbsp;have&nbsp;anything&nbsp;to&nbsp;highlight&nbsp;at&nbsp;all.</span></span></div></li>
+<li><div class="src-line"><a name="a2175"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;if&nbsp;we&nbsp;have&nbsp;a&nbsp;&quot;maybe&quot;&nbsp;strict&nbsp;language,&nbsp;this&nbsp;should&nbsp;be&nbsp;handled&nbsp;as&nbsp;highlightable&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2176"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2177"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">0</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2178"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">0</span>&nbsp;=&gt;&nbsp;<span class="src-str">''</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2179"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<span class="src-str">''</span></span></div></li>
+<li><div class="src-line"><a name="a2180"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2181"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2182"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">0</span>&nbsp;=&gt;&nbsp;<span class="src-id">null</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2183"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span></span></div></li>
+<li><div class="src-line"><a name="a2184"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a2185"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2186"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_parts</span>&nbsp;=&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2187"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2188"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2189"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2190"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Not&nbsp;strict&nbsp;mode&nbsp;-&nbsp;simply&nbsp;dump&nbsp;the&nbsp;source&nbsp;into</span></span></div></li>
+<li><div class="src-line"><a name="a2191"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;array&nbsp;at&nbsp;index&nbsp;1&nbsp;(the&nbsp;first&nbsp;highlightable&nbsp;block)</span></span></div></li>
+<li><div class="src-line"><a name="a2192"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parts</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2193"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">0</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2194"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">0</span>&nbsp;=&gt;&nbsp;<span class="src-str">''</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2195"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<span class="src-str">''</span></span></div></li>
+<li><div class="src-line"><a name="a2196"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2197"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2198"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">0</span>&nbsp;=&gt;&nbsp;<span class="src-id">null</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2199"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-num">1</span>&nbsp;=&gt;&nbsp;<span class="src-var">$code</span></span></div></li>
+<li><div class="src-line"><a name="a2200"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a2201"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2202"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_parts</span>&nbsp;=&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2203"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2204"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2205"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Unset&nbsp;variables&nbsp;we&nbsp;won't&nbsp;need&nbsp;any&nbsp;longer</span></span></div></li>
+<li><div class="src-line"><a name="a2206"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2207"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2208"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Preload&nbsp;some&nbsp;repeatedly&nbsp;used&nbsp;values&nbsp;regarding&nbsp;hardquotes&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2209"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$hq</span>&nbsp;=&nbsp;isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'HARDQUOTE'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'HARDQUOTE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;:&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2210"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$hq_strlen</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$hq</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2211"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2212"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Preload&nbsp;if&nbsp;line&nbsp;numbers&nbsp;are&nbsp;to&nbsp;be&nbsp;generated&nbsp;afterwards</span></span></div></li>
+<li><div class="src-line"><a name="a2213"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Added&nbsp;a&nbsp;check&nbsp;if&nbsp;line&nbsp;breaks&nbsp;should&nbsp;be&nbsp;forced&nbsp;even&nbsp;without&nbsp;line&nbsp;numbers,&nbsp;fixes&nbsp;SF#1727398</span></span></div></li>
+<li><div class="src-line"><a name="a2214"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$check_linenumbers</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2215"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines</span><span class="src-sym">)</span>&nbsp;||&nbsp;<span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">allow_multiline_span</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2216"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2217"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//preload&nbsp;the&nbsp;escape&nbsp;char&nbsp;for&nbsp;faster&nbsp;checking&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2218"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escaped_escape_char</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2219"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2220"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;is&nbsp;used&nbsp;for&nbsp;single-line&nbsp;comments</span></span></div></li>
+<li><div class="src-line"><a name="a2221"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$sc_disallowed_before</span>&nbsp;=&nbsp;<span class="src-str">&quot;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2222"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$sc_disallowed_after</span>&nbsp;=&nbsp;<span class="src-str">&quot;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2223"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2224"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2225"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2226"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2227"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$sc_disallowed_before</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2228"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2229"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_AFTER'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2230"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$sc_disallowed_after</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_AFTER'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2231"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2232"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2233"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2234"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2235"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Fix&nbsp;for&nbsp;SF#1932083:&nbsp;Multichar&nbsp;Quotemarks&nbsp;unsupported</span></span></div></li>
+<li><div class="src-line"><a name="a2236"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$is_string_starter</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2237"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2238"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'QUOTEMARKS'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$quotemark</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2239"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$quotemark</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2240"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$quotemark</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]]</span>&nbsp;=&nbsp;(string)<span class="src-var">$quotemark</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2241"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_string">is_string</a><span class="src-sym">(</span><span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$quotemark</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2242"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$quotemark</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2243"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$quotemark</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]]</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2244"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$quotemark</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2245"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2246"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$quotemark</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$quotemark</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2247"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2248"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2249"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2250"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2251"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Now&nbsp;we&nbsp;go&nbsp;through&nbsp;each&nbsp;part.&nbsp;We&nbsp;know&nbsp;that&nbsp;even-indexed&nbsp;parts&nbsp;are</span></span></div></li>
+<li><div class="src-line"><a name="a2252"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;code&nbsp;that&nbsp;shouldn't&nbsp;be&nbsp;highlighted,&nbsp;and&nbsp;odd-indexed&nbsp;parts&nbsp;should</span></span></div></li>
+<li><div class="src-line"><a name="a2253"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;be&nbsp;highlighted</span></span></div></li>
+<li><div class="src-line"><a name="a2254"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$key</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$key</span>&nbsp;<&nbsp;<span class="src-var">$num_parts</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2255"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$STRICTATTRS</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2256"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2257"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;this&nbsp;block&nbsp;should&nbsp;be&nbsp;highlighted...</span></span></div></li>
+<li><div class="src-line"><a name="a2258"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-sym">(</span><span class="src-var">$key</span>&nbsp;<span class="src-sym">&</span>&nbsp;<span class="src-num">1</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2259"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Else&nbsp;not&nbsp;a&nbsp;block&nbsp;to&nbsp;highlight</span></span></div></li>
+<li><div class="src-line"><a name="a2260"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$endresult</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2261"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2262"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2263"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2264"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2265"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2266"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$part</span>&nbsp;=&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2267"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2268"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$highlight_part</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2269"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">strict_mode</span>&nbsp;&amp;&amp;&nbsp;<span class="src-sym">!</span><a href="http://www.php.net/is_null">is_null</a><span class="src-sym">(</span><span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2270"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;get&nbsp;the&nbsp;class&nbsp;key&nbsp;for&nbsp;this&nbsp;block&nbsp;of&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2271"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$script_key</span>&nbsp;=&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2272"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$highlight_part</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'HIGHLIGHT_STRICT_BLOCK'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$script_key</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2273"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SCRIPT'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$script_key</span><span class="src-sym">]</span>&nbsp;!=&nbsp;<span class="src-str">''</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2274"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'SCRIPT'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2275"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;a&nbsp;span&nbsp;element&nbsp;around&nbsp;the&nbsp;source&nbsp;to</span></span></div></li>
+<li><div class="src-line"><a name="a2276"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;highlight&nbsp;the&nbsp;overall&nbsp;source&nbsp;block</span></span></div></li>
+<li><div class="src-line"><a name="a2277"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2278"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SCRIPT'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$script_key</span><span class="src-sym">]</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2279"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SCRIPT'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$script_key</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2280"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2281"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;sc'</span>&nbsp;.&nbsp;<span class="src-var">$script_key</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2282"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2283"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2284"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$STRICTATTRS</span>&nbsp;=&nbsp;<span class="src-var">$attributes</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2285"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2286"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2287"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2288"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$highlight_part</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2289"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Now,&nbsp;highlight&nbsp;the&nbsp;code&nbsp;in&nbsp;this&nbsp;block.&nbsp;This&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2290"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;is&nbsp;really&nbsp;the&nbsp;engine&nbsp;of&nbsp;GeSHi&nbsp;(along&nbsp;with&nbsp;the&nbsp;method</span></span></div></li>
+<li><div class="src-line"><a name="a2291"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;parse_non_string_part).</span></span></div></li>
+<li><div class="src-line"><a name="a2292"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a2293"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;cache&nbsp;comment&nbsp;regexps&nbsp;incrementally</span></span></div></li>
+<li><div class="src-line"><a name="a2294"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_regexp_key</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2295"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_regexp_pos</span>&nbsp;=&nbsp;-<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2296"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_multi_pos</span>&nbsp;=&nbsp;-<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2297"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_single_pos</span>&nbsp;=&nbsp;-<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2298"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_regexp_cache_per_key</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2299"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_multi_cache_per_key</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2300"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_single_cache_per_key</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2301"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_open_comment_multi</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2302"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_single_key</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2303"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_regexp_cache_per_key</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2304"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_key</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2305"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;=&nbsp;-<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2306"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2307"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$length</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2308"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2309"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Get&nbsp;the&nbsp;next&nbsp;char</span></span></div></li>
+<li><div class="src-line"><a name="a2310"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char</span>&nbsp;=&nbsp;<span class="src-var">$part</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2311"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char_len</span>&nbsp;=&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2312"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2313"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;update&nbsp;regexp&nbsp;comment&nbsp;cache&nbsp;if&nbsp;needed</span></span></div></li>
+<li><div class="src-line"><a name="a2314"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_REGEXP'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$next_comment_regexp_pos</span>&nbsp;<&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2315"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_regexp_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2316"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_REGEXP'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$comment_key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$regexp</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2317"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2318"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2319"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;&gt;=&nbsp;<span class="src-var">$i</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2320"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2321"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;have&nbsp;already&nbsp;matched&nbsp;something</span></span></div></li>
+<li><div class="src-line"><a name="a2322"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2323"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;comment&nbsp;is&nbsp;never&nbsp;matched</span></span></div></li>
+<li><div class="src-line"><a name="a2324"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2325"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2326"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2327"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2328"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;is&nbsp;to&nbsp;allow&nbsp;use&nbsp;of&nbsp;the&nbsp;offset&nbsp;parameter&nbsp;in&nbsp;preg_match&nbsp;and&nbsp;stay&nbsp;as&nbsp;compatible&nbsp;with&nbsp;older&nbsp;PHP&nbsp;versions&nbsp;as&nbsp;possible</span></span></div></li>
+<li><div class="src-line"><a name="a2329"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_PHP_PRE_433</span>&nbsp;&amp;&amp;&nbsp;<a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-var">$regexp</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$match</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">))</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2330"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-id">GESHI_PHP_PRE_433</span>&nbsp;&amp;&amp;&nbsp;<a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-var">$regexp</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$match</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">))</span></span></div></li>
+<li><div class="src-line"><a name="a2331"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2332"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2333"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_PHP_PRE_433</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2334"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;+=&nbsp;<span class="src-var">$i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2335"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2336"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2337"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2338"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'key'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$comment_key</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2339"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'length'</span>&nbsp;=&gt;&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2340"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'pos'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$match_i</span></span></div></li>
+<li><div class="src-line"><a name="a2341"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2342"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2343"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2344"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2345"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2346"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2347"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;!==&nbsp;<span class="src-id">false</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$match_i</span>&nbsp;<&nbsp;<span class="src-var">$next_comment_regexp_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2348"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_regexp_pos</span>&nbsp;=&nbsp;<span class="src-var">$match_i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2349"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_regexp_key</span>&nbsp;=&nbsp;<span class="src-var">$comment_key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2350"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;===&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2351"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2352"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2353"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2354"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2355"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2356"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2357"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_started</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2358"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2359"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2360"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Possibly&nbsp;the&nbsp;start&nbsp;of&nbsp;a&nbsp;new&nbsp;string&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2361"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a2362"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;which&nbsp;starter&nbsp;it&nbsp;was&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2363"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Fix&nbsp;for&nbsp;SF#1932083:&nbsp;Multichar&nbsp;Quotemarks&nbsp;unsupported</span></span></div></li>
+<li><div class="src-line"><a name="a2364"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2365"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char_new</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2366"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$testchar</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2367"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$testchar</span>&nbsp;===&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$testchar</span><span class="src-sym">))</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2368"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$testchar</span><span class="src-sym">)</span>&nbsp;>&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$char_new</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2369"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char_new</span>&nbsp;=&nbsp;<span class="src-var">$testchar</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2370"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_started</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2371"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2372"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2373"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$string_started</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2374"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char</span>&nbsp;=&nbsp;<span class="src-var">$char_new</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2375"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2376"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2377"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$testchar</span>&nbsp;=&nbsp;<span class="src-var">$is_string_starter</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2378"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$testchar</span>&nbsp;===&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$testchar</span><span class="src-sym">)))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2379"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char</span>&nbsp;=&nbsp;<span class="src-var">$testchar</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2380"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_started</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2381"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2382"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2383"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char_len</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$char</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2384"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2385"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2386"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$string_started</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$i</span>&nbsp;!=&nbsp;<span class="src-var">$next_comment_regexp_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2387"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Hand&nbsp;out&nbsp;the&nbsp;correct&nbsp;style&nbsp;information&nbsp;for&nbsp;this&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2388"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_key</span>&nbsp;=&nbsp;<a href="http://www.php.net/array_search">array_search</a><span class="src-sym">(</span><span class="src-var">$char</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'QUOTEMARKS'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2389"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$string_key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2390"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$string_key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2391"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_key</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2392"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2393"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2394"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;parse&nbsp;the&nbsp;stuff&nbsp;before&nbsp;this</span></span></div></li>
+<li><div class="src-line"><a name="a2395"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2396"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2397"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2398"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2399"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$string_key</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2400"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2401"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;st'</span>.<span class="src-var">$string_key</span>.<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2402"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2403"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2404"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;now&nbsp;handle&nbsp;the&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2405"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$string_attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.&nbsp;<span class="src-id">GeSHi</span><span class="src-sym">::</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$char</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2406"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$char_len</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2407"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_open</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2408"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2409"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_REGEXP'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2410"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2411"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2412"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2413"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2414"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;regular&nbsp;ending&nbsp;pos&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2415"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$char</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2416"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<span class="src-var">$close_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2417"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2418"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2419"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2420"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2421"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;update&nbsp;escape&nbsp;regexp&nbsp;cache&nbsp;if&nbsp;needed</span></span></div></li>
+<li><div class="src-line"><a name="a2422"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_REGEXP'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;<&nbsp;<span class="src-var">$start</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2423"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2424"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_REGEXP'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$escape_key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$regexp</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2425"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2426"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2427"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;&gt;=&nbsp;<span class="src-var">$start</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2428"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2429"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;have&nbsp;already&nbsp;matched&nbsp;something</span></span></div></li>
+<li><div class="src-line"><a name="a2430"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2431"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;comment&nbsp;is&nbsp;never&nbsp;matched</span></span></div></li>
+<li><div class="src-line"><a name="a2432"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2433"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2434"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2435"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2436"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;is&nbsp;to&nbsp;allow&nbsp;use&nbsp;of&nbsp;the&nbsp;offset&nbsp;parameter&nbsp;in&nbsp;preg_match&nbsp;and&nbsp;stay&nbsp;as&nbsp;compatible&nbsp;with&nbsp;older&nbsp;PHP&nbsp;versions&nbsp;as&nbsp;possible</span></span></div></li>
+<li><div class="src-line"><a name="a2437"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_PHP_PRE_433</span>&nbsp;&amp;&amp;&nbsp;<a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-var">$regexp</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$match</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">))</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2438"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-id">GESHI_PHP_PRE_433</span>&nbsp;&amp;&amp;&nbsp;<a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-var">$regexp</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$match</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_OFFSET_CAPTURE</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span></span></div></li>
+<li><div class="src-line"><a name="a2439"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2440"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2441"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_PHP_PRE_433</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2442"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;+=&nbsp;<span class="src-var">$start</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2443"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2444"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2445"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2446"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'key'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$escape_key</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2447"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'length'</span>&nbsp;=&gt;&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2448"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'pos'</span>&nbsp;=&gt;&nbsp;<span class="src-var">$match_i</span></span></div></li>
+<li><div class="src-line"><a name="a2449"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2450"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2451"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'pos'</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2452"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2453"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2454"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2455"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;!==&nbsp;<span class="src-id">false</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$match_i</span>&nbsp;<&nbsp;<span class="src-var">$next_escape_regexp_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2456"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;=&nbsp;<span class="src-var">$match_i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2457"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_key</span>&nbsp;=&nbsp;<span class="src-var">$escape_key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2458"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;===&nbsp;<span class="src-var">$start</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2459"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2460"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2461"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2462"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2463"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2464"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2465"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Find&nbsp;the&nbsp;next&nbsp;simple&nbsp;escape&nbsp;position</span></span></div></li>
+<li><div class="src-line"><a name="a2466"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-str">''</span>&nbsp;!=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2467"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$simple_escape</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2468"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<span class="src-var">$simple_escape</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2469"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$simple_escape</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2470"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2471"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2472"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$simple_escape</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2473"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2474"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2475"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2476"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$simple_escape</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2477"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2478"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2479"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-var">$simple_escape</span>&nbsp;<&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2480"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$simple_escape</span>&nbsp;<&nbsp;<span class="src-var">$length</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2481"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$simple_escape</span>&nbsp;<&nbsp;<span class="src-var">$close_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2482"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//The&nbsp;nexxt&nbsp;escape&nbsp;sequence&nbsp;is&nbsp;a&nbsp;simple&nbsp;one&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2483"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_pos</span>&nbsp;=&nbsp;<span class="src-var">$simple_escape</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2484"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2485"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Add&nbsp;the&nbsp;stuff&nbsp;not&nbsp;in&nbsp;the&nbsp;string&nbsp;yet&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2486"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span>&nbsp;-&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2487"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2488"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;style&nbsp;for&nbsp;this&nbsp;escaped&nbsp;char&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2489"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2490"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2491"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2492"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;es0&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2493"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2494"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2495"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Add&nbsp;the&nbsp;style&nbsp;for&nbsp;the&nbsp;escape&nbsp;char&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2496"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$escape_char_attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a2497"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">GeSHi</span><span class="src-sym">::</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2498"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2499"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;byte&nbsp;AFTER&nbsp;the&nbsp;ESCAPE_CHAR&nbsp;we&nbsp;just&nbsp;found</span></span></div></li>
+<li><div class="src-line"><a name="a2500"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_char</span>&nbsp;=&nbsp;<span class="src-var">$part</span><span class="src-sym">[</span><span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2501"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$es_char</span>&nbsp;==&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2502"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;don't&nbsp;put&nbsp;a&nbsp;newline&nbsp;around&nbsp;newlines</span></span></div></li>
+<li><div class="src-line"><a name="a2503"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&lt;/span&gt;\n&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2504"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2505"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/ord">ord</a><span class="src-sym">(</span><span class="src-var">$es_char</span><span class="src-sym">)</span>&nbsp;&gt;=&nbsp;<span class="src-num">128</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2506"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;is&nbsp;an&nbsp;non-ASCII&nbsp;char&nbsp;(UTF8&nbsp;or&nbsp;single&nbsp;byte)</span></span></div></li>
+<li><div class="src-line"><a name="a2507"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;code&nbsp;tries&nbsp;to&nbsp;work&nbsp;around&nbsp;SF#2037598&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2508"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/function_exists">function_exists</a><span class="src-sym">(</span><span class="src-str">'mb_substr'</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2509"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_char_m</span>&nbsp;=&nbsp;<a href="http://www.php.net/mb_substr">mb_substr</a><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span>+<span class="src-num">1</span><span class="src-sym">,</span>&nbsp;<span class="src-num">16</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-num">1</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">encoding</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2510"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-var">$es_char_m</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2511"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-id">GESHI_PHP_PRE_433</span>&nbsp;&amp;&amp;&nbsp;<span class="src-str">'utf-8'</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">encoding</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2512"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-str">&quot;/[\xC2-\xDF][\x80-\xBF]&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a2513"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;|\xE0[\xA0-\xBF][\x80-\xBF]&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a2514"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a2515"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;|\xED[\x80-\x9F][\x80-\xBF]&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a2516"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;|\xF0[\x90-\xBF][\x80-\xBF]{2}&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a2517"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;|[\xF1-\xF3][\x80-\xBF]{3}&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a2518"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;|\xF4[\x80-\x8F][\x80-\xBF]{2}/s&quot;</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2519"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_char_m</span><span class="src-sym">,</span>&nbsp;<span class="src-id">null</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2520"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_char_m</span>&nbsp;=&nbsp;<span class="src-var">$es_char_m</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2521"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2522"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_char_m</span>&nbsp;=&nbsp;<span class="src-var">$es_char</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2523"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2524"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$es_char_m</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2525"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2526"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_char_m</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$es_char</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2527"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2528"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$es_char_m</span><span class="src-sym">)</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2529"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2530"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$es_char</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2531"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2532"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2533"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$next_escape_regexp_pos</span>&nbsp;<&nbsp;<span class="src-var">$length</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2534"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_escape_regexp_pos</span>&nbsp;<&nbsp;<span class="src-var">$close_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2535"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$es_pos</span>&nbsp;=&nbsp;<span class="src-var">$next_escape_regexp_pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2536"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Add&nbsp;the&nbsp;stuff&nbsp;not&nbsp;in&nbsp;the&nbsp;string&nbsp;yet&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2537"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span>&nbsp;-&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2538"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2539"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;key&nbsp;and&nbsp;length&nbsp;of&nbsp;this&nbsp;match&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2540"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape</span>&nbsp;=&nbsp;<span class="src-var">$escape_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$next_escape_regexp_key</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2541"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_str</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$escape</span><span class="src-sym">[</span><span class="src-str">'length'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2542"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_key</span>&nbsp;=&nbsp;<span class="src-var">$escape</span><span class="src-sym">[</span><span class="src-str">'key'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2543"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2544"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;style&nbsp;for&nbsp;this&nbsp;escaped&nbsp;char&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2545"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2546"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$escape_key</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2547"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2548"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;es'</span>&nbsp;.&nbsp;<span class="src-var">$escape_key</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2549"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2550"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2551"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Add&nbsp;the&nbsp;style&nbsp;for&nbsp;the&nbsp;escape&nbsp;char&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2552"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$escape_char_attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a2553"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$escape_str</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2554"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2555"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-var">$escape</span><span class="src-sym">[</span><span class="src-str">'length'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2556"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2557"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Copy&nbsp;the&nbsp;remainder&nbsp;of&nbsp;the&nbsp;string&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a2558"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-var">$start</span>&nbsp;+&nbsp;<span class="src-var">$char_len</span><span class="src-sym">))</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2559"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span>&nbsp;+&nbsp;<span class="src-var">$char_len</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2560"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_open</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2561"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2562"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">while</span><span class="src-sym">(</span><span class="src-var">$string_open</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2563"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2564"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$check_linenumbers</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2565"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Are&nbsp;line&nbsp;numbers&nbsp;used?&nbsp;If,&nbsp;we&nbsp;should&nbsp;end&nbsp;the&nbsp;string&nbsp;before</span></span></div></li>
+<li><div class="src-line"><a name="a2566"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;newline&nbsp;and&nbsp;begin&nbsp;it&nbsp;again&nbsp;(so&nbsp;when&nbsp;&lt;li&gt;s&nbsp;are&nbsp;put&nbsp;in&nbsp;the&nbsp;source</span></span></div></li>
+<li><div class="src-line"><a name="a2567"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;remains&nbsp;XHTML&nbsp;compliant)</span></span></div></li>
+<li><div class="src-line"><a name="a2568"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note&nbsp;to&nbsp;self:&nbsp;This&nbsp;opens&nbsp;up&nbsp;possibility&nbsp;of&nbsp;config&nbsp;files&nbsp;specifying</span></span></div></li>
+<li><div class="src-line"><a name="a2569"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;that&nbsp;languages&nbsp;can/cannot&nbsp;have&nbsp;multiline&nbsp;strings???</span></span></div></li>
+<li><div class="src-line"><a name="a2570"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;/span&gt;\n&lt;span<span class="src-var">$string_attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$string</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2571"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2572"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2573"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$string</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2574"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2575"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$start</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2576"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2577"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$hq</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$hq</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$char</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2578"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$hq_strlen</span><span class="src-sym">)</span>&nbsp;==&nbsp;<span class="src-var">$hq</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2579"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;The&nbsp;start&nbsp;of&nbsp;a&nbsp;hard&nbsp;quoted&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2580"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2581"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'HARD'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2582"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'HARD'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2583"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2584"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;st_h&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2585"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;es_h&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2586"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2587"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;parse&nbsp;the&nbsp;stuff&nbsp;before&nbsp;this</span></span></div></li>
+<li><div class="src-line"><a name="a2588"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2589"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2590"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2591"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;now&nbsp;handle&nbsp;the&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2592"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2593"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2594"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;look&nbsp;for&nbsp;closing&nbsp;quote</span></span></div></li>
+<li><div class="src-line"><a name="a2595"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$hq_strlen</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2596"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close_pos</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'HARDQUOTE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2597"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2598"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$part</span><span class="src-sym">[</span><span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2599"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;make&nbsp;sure&nbsp;this&nbsp;quote&nbsp;is&nbsp;not&nbsp;escaped</span></span></div></li>
+<li><div class="src-line"><a name="a2600"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'HARDESCAPE'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$hardescape</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2601"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$hardescape</span><span class="src-sym">))</span>&nbsp;==&nbsp;<span class="src-var">$hardescape</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2602"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;check&nbsp;wether&nbsp;this&nbsp;quote&nbsp;is&nbsp;escaped&nbsp;or&nbsp;if&nbsp;it&nbsp;is&nbsp;something&nbsp;like&nbsp;'\\'</span></span></div></li>
+<li><div class="src-line"><a name="a2603"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$escape_char_pos</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2604"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$escape_char_pos</span>&nbsp;>&nbsp;<span class="src-num">0</span></span></div></li>
+<li><div class="src-line"><a name="a2605"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span class="src-var">$part</span><span class="src-sym">[</span><span class="src-var">$escape_char_pos</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2606"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--<span class="src-var">$escape_char_pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2607"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2608"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">((</span><span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-var">$escape_char_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">&</span>&nbsp;<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2609"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;uneven&nbsp;number&nbsp;of&nbsp;escape&nbsp;chars&nbsp;=&gt;&nbsp;this&nbsp;quote&nbsp;is&nbsp;escaped</span></span></div></li>
+<li><div class="src-line"><a name="a2610"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span>&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2611"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2612"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2613"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2614"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2615"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2616"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;found&nbsp;closing&nbsp;quote</span></span></div></li>
+<li><div class="src-line"><a name="a2617"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2618"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2619"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2620"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Found&nbsp;the&nbsp;closing&nbsp;delimiter?</span></span></div></li>
+<li><div class="src-line"><a name="a2621"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$close_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2622"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;span&nbsp;till&nbsp;the&nbsp;end&nbsp;of&nbsp;this&nbsp;$part&nbsp;when&nbsp;no&nbsp;closing&nbsp;delimiter&nbsp;is&nbsp;found</span></span></div></li>
+<li><div class="src-line"><a name="a2623"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2624"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2625"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2626"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;actual&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2627"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2628"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2629"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2630"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;handle&nbsp;escape&nbsp;chars&nbsp;and&nbsp;encode&nbsp;html&nbsp;chars</span></span></div></li>
+<li><div class="src-line"><a name="a2631"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;(special&nbsp;because&nbsp;when&nbsp;we&nbsp;have&nbsp;escape&nbsp;chars&nbsp;within&nbsp;our&nbsp;string&nbsp;they&nbsp;may&nbsp;not&nbsp;be&nbsp;escaped)</span></span></div></li>
+<li><div class="src-line"><a name="a2632"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2633"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2634"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_string</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2635"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$es_pos</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2636"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;hmtl&nbsp;escape&nbsp;stuff&nbsp;before</span></span></div></li>
+<li><div class="src-line"><a name="a2637"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_string</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span>&nbsp;-&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2638"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;check&nbsp;if&nbsp;this&nbsp;is&nbsp;a&nbsp;hard&nbsp;escape</span></span></div></li>
+<li><div class="src-line"><a name="a2639"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'HARDESCAPE'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$hardescape</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2640"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$es_pos</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$hardescape</span><span class="src-sym">))</span>&nbsp;==&nbsp;<span class="src-var">$hardescape</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2641"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;indeed,&nbsp;this&nbsp;is&nbsp;a&nbsp;hardescape</span></span></div></li>
+<li><div class="src-line"><a name="a2642"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_string</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$escape_char_attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a2643"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$hardescape</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2644"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$hardescape</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2645"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span>&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2646"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2647"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2648"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;not&nbsp;a&nbsp;hard&nbsp;escape,&nbsp;but&nbsp;a&nbsp;normal&nbsp;escape</span></span></div></li>
+<li><div class="src-line"><a name="a2649"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;they&nbsp;come&nbsp;in&nbsp;pairs&nbsp;of&nbsp;two</span></span></div></li>
+<li><div class="src-line"><a name="a2650"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$c</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2651"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">[</span><span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-var">$c</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;isset<span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">[</span><span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-var">$c</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a2652"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span class="src-var">$string</span><span class="src-sym">[</span><span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-var">$c</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span></span></div></li>
+<li><div class="src-line"><a name="a2653"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span class="src-var">$string</span><span class="src-sym">[</span><span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-var">$c</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">]</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2654"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$c</span>&nbsp;+=&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2655"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2656"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$c</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2657"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_string</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$escape_char_attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a2658"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">str_repeat</span><span class="src-sym">(</span><span class="src-var">$escaped_escape_char</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$c</span><span class="src-sym">)</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a2659"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2660"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-var">$c</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2661"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2662"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;is&nbsp;just&nbsp;a&nbsp;single&nbsp;lonely&nbsp;escape&nbsp;char...</span></span></div></li>
+<li><div class="src-line"><a name="a2663"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_string</span>&nbsp;.=&nbsp;<span class="src-var">$escaped_escape_char</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2664"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-var">$es_pos</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2665"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2666"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2667"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<span class="src-var">$new_string</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2668"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2669"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2670"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2671"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2672"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$check_linenumbers</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2673"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Are&nbsp;line&nbsp;numbers&nbsp;used?&nbsp;If,&nbsp;we&nbsp;should&nbsp;end&nbsp;the&nbsp;string&nbsp;before</span></span></div></li>
+<li><div class="src-line"><a name="a2674"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;newline&nbsp;and&nbsp;begin&nbsp;it&nbsp;again&nbsp;(so&nbsp;when&nbsp;&lt;li&gt;s&nbsp;are&nbsp;put&nbsp;in&nbsp;the&nbsp;source</span></span></div></li>
+<li><div class="src-line"><a name="a2675"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;remains&nbsp;XHTML&nbsp;compliant)</span></span></div></li>
+<li><div class="src-line"><a name="a2676"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note&nbsp;to&nbsp;self:&nbsp;This&nbsp;opens&nbsp;up&nbsp;possibility&nbsp;of&nbsp;config&nbsp;files&nbsp;specifying</span></span></div></li>
+<li><div class="src-line"><a name="a2677"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;that&nbsp;languages&nbsp;can/cannot&nbsp;have&nbsp;multiline&nbsp;strings???</span></span></div></li>
+<li><div class="src-line"><a name="a2678"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;/span&gt;\n&lt;span<span class="src-var">$string_attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$string</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2679"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2680"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2681"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;</span><span class="src-str">&quot;</span>&lt;span<span class="src-var">$string_attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.&nbsp;<span class="src-var">$string</span>&nbsp;.&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2682"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$string</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2683"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2684"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2685"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Have&nbsp;a&nbsp;look&nbsp;for&nbsp;regexp&nbsp;comments</span></span></div></li>
+<li><div class="src-line"><a name="a2686"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;==&nbsp;<span class="src-var">$next_comment_regexp_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2687"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$COMMENT_MATCHED</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2688"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment</span>&nbsp;=&nbsp;<span class="src-var">$comment_regexp_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$next_comment_regexp_key</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2689"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$comment</span><span class="src-sym">[</span><span class="src-str">'length'</span><span class="src-sym">]</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2690"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2691"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//@todo&nbsp;If&nbsp;remove&nbsp;important&nbsp;do&nbsp;remove&nbsp;here</span></span></div></li>
+<li><div class="src-line"><a name="a2692"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MULTI'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2693"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2694"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$comment</span><span class="src-sym">[</span><span class="src-str">'key'</span><span class="src-sym">]]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2695"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2696"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;co'</span>&nbsp;.&nbsp;<span class="src-var">$comment</span><span class="src-sym">[</span><span class="src-str">'key'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2697"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2698"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2699"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.&nbsp;<span class="src-var">$test_str</span>&nbsp;.&nbsp;<span class="src-str">&quot;&lt;/span&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2700"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2701"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Short-cut&nbsp;through&nbsp;all&nbsp;the&nbsp;multiline&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2702"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$check_linenumbers</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2703"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;strreplace&nbsp;to&nbsp;put&nbsp;close&nbsp;span&nbsp;and&nbsp;open&nbsp;span&nbsp;around&nbsp;multiline&nbsp;newlines</span></span></div></li>
+<li><div class="src-line"><a name="a2704"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2705"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;/span&gt;\n&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2706"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">str_replace</span><span class="src-sym">(</span><span class="src-str">&quot;\n&nbsp;&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\n&amp;nbsp;&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$test_str</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a2707"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2708"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2709"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2710"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2711"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;+=&nbsp;<span class="src-var">$comment</span><span class="src-sym">[</span><span class="src-str">'length'</span><span class="src-sym">]</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2712"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2713"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;parse&nbsp;the&nbsp;rest</span></span></div></li>
+<li><div class="src-line"><a name="a2714"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2715"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2716"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2717"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2718"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;we&nbsp;haven't&nbsp;matched&nbsp;a&nbsp;regexp&nbsp;comment,&nbsp;try&nbsp;multi-line&nbsp;comments</span></span></div></li>
+<li><div class="src-line"><a name="a2719"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$COMMENT_MATCHED</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2720"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Is&nbsp;this&nbsp;a&nbsp;multiline&nbsp;comment?</span></span></div></li>
+<li><div class="src-line"><a name="a2721"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_MULTI'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$next_comment_multi_pos</span>&nbsp;<&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2722"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_multi_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2723"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_MULTI'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$open</span>&nbsp;=&gt;&nbsp;<span class="src-var">$close</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2724"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2725"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2726"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span>&nbsp;&gt;=&nbsp;<span class="src-var">$i</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2727"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2728"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;have&nbsp;already&nbsp;matched&nbsp;something</span></span></div></li>
+<li><div class="src-line"><a name="a2729"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2730"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;comment&nbsp;is&nbsp;never&nbsp;matched</span></span></div></li>
+<li><div class="src-line"><a name="a2731"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2732"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2733"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2734"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">((</span><span class="src-var">$match_i</span>&nbsp;=&nbsp;<a href="http://www.php.net/stripos">stripos</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$open</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">))</span>&nbsp;!==&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2735"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$match_i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2736"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2737"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_multi_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2738"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2739"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2740"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;!==&nbsp;<span class="src-id">false</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$match_i</span>&nbsp;<&nbsp;<span class="src-var">$next_comment_multi_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2741"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_multi_pos</span>&nbsp;=&nbsp;<span class="src-var">$match_i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2742"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_open_comment_multi</span>&nbsp;=&nbsp;<span class="src-var">$open</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2743"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;===&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2744"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2745"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2746"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2747"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2748"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2749"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;==&nbsp;<span class="src-var">$next_comment_multi_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2750"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$open</span>&nbsp;=&nbsp;<span class="src-var">$next_open_comment_multi</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2751"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_MULTI'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$open</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2752"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$open_strlen</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$open</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2753"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_strlen</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$close</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2754"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$COMMENT_MATCHED</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2755"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str_match</span>&nbsp;=&nbsp;<span class="src-var">$open</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2756"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//@todo&nbsp;If&nbsp;remove&nbsp;important&nbsp;do&nbsp;remove&nbsp;here</span></span></div></li>
+<li><div class="src-line"><a name="a2757"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MULTI'</span><span class="src-sym">]</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2758"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$open</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT&quot;&gt;GESHI_START_IMPORTANT&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2759"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$open</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT&quot;&gt;GESHI_START_IMPORTANT&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2760"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2761"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MULTI'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2762"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2763"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;coMULTI&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2764"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2765"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$open</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2766"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2767"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2768"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">important_styles</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2769"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2770"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;imp&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2771"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2772"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2773"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;We&nbsp;don't&nbsp;include&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;comment&nbsp;if&nbsp;it's&nbsp;an</span></span></div></li>
+<li><div class="src-line"><a name="a2774"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&quot;important&quot;&nbsp;part</span></span></div></li>
+<li><div class="src-line"><a name="a2775"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2776"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2777"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2778"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$open</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2779"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2780"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2781"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-id">strpos</span><span class="src-sym">(</span>&nbsp;<span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$open_strlen</span>&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2782"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2783"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close_pos</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2784"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2785"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2786"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2787"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Short-cut&nbsp;through&nbsp;all&nbsp;the&nbsp;multiline&nbsp;code</span></span></div></li>
+<li><div class="src-line"><a name="a2788"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$rest_of_comment</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-id">substr</span><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$open_strlen</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-var">$i</span>&nbsp;-&nbsp;<span class="src-var">$open_strlen</span>&nbsp;+&nbsp;<span class="src-var">$close_strlen</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2789"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">((</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MULTI'</span><span class="src-sym">]</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2790"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str_match</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT&quot;&gt;GESHI_START_IMPORTANT&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2791"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$check_linenumbers</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2792"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2793"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;strreplace&nbsp;to&nbsp;put&nbsp;close&nbsp;span&nbsp;and&nbsp;open&nbsp;span&nbsp;around&nbsp;multiline&nbsp;newlines</span></span></div></li>
+<li><div class="src-line"><a name="a2794"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;.=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2795"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;/span&gt;\n&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a2796"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-id">str_replace</span><span class="src-sym">(</span><span class="src-str">&quot;\n&nbsp;&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\n&amp;nbsp;&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$rest_of_comment</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a2797"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2798"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2799"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;.=&nbsp;<span class="src-var">$rest_of_comment</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2800"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2801"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2802"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MULTI'</span><span class="src-sym">]</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2803"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str_match</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT&quot;&gt;GESHI_START_IMPORTANT&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2804"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2805"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2806"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2807"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span>&nbsp;+&nbsp;<span class="src-var">$close_strlen</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2808"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2809"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;parse&nbsp;the&nbsp;rest</span></span></div></li>
+<li><div class="src-line"><a name="a2810"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2811"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2812"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2813"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2814"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2815"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;we&nbsp;haven't&nbsp;matched&nbsp;a&nbsp;multiline&nbsp;comment,&nbsp;try&nbsp;single-line&nbsp;comments</span></span></div></li>
+<li><div class="src-line"><a name="a2816"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$COMMENT_MATCHED</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2817"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;cache&nbsp;potential&nbsp;single&nbsp;line&nbsp;comment&nbsp;occurances</span></span></div></li>
+<li><div class="src-line"><a name="a2818"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_SINGLE'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$next_comment_single_pos</span>&nbsp;<&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2819"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_single_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2820"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_SINGLE'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$comment_key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$comment_mark</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2821"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2822"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2823"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;&gt;=&nbsp;<span class="src-var">$i</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2824"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2825"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;have&nbsp;already&nbsp;matched&nbsp;something</span></span></div></li>
+<li><div class="src-line"><a name="a2826"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2827"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;comment&nbsp;is&nbsp;never&nbsp;matched</span></span></div></li>
+<li><div class="src-line"><a name="a2828"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2829"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2830"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$match_i</span>&nbsp;=&nbsp;<span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2831"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a2832"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;case&nbsp;sensitive&nbsp;comments</span></span></div></li>
+<li><div class="src-line"><a name="a2833"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-id">GESHI_COMMENTS</span><span class="src-sym">]</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2834"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;=&nbsp;<a href="http://www.php.net/stripos">stripos</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$comment_mark</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">))</span>&nbsp;!==&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2835"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;non&nbsp;case&nbsp;sensitive</span></span></div></li>
+<li><div class="src-line"><a name="a2836"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-id">GESHI_COMMENTS</span><span class="src-sym">]</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2837"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">((</span><span class="src-var">$match_i</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$comment_mark</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">))</span>&nbsp;!==&nbsp;<span class="src-id">false</span><span class="src-sym">)))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2838"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$match_i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2839"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2840"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_single_cache_per_key</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2841"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2842"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2843"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;!==&nbsp;<span class="src-id">false</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$match_i</span>&nbsp;<&nbsp;<span class="src-var">$next_comment_single_pos</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2844"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_single_pos</span>&nbsp;=&nbsp;<span class="src-var">$match_i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2845"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$next_comment_single_key</span>&nbsp;=&nbsp;<span class="src-var">$comment_key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2846"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$match_i</span>&nbsp;===&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2847"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2848"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2849"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2850"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2851"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2852"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$next_comment_single_pos</span>&nbsp;==&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2853"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_key</span>&nbsp;=&nbsp;<span class="src-var">$next_comment_single_key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2854"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$comment_mark</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_SINGLE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2855"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$com_len</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$comment_mark</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2856"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2857"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;This&nbsp;check&nbsp;will&nbsp;find&nbsp;special&nbsp;variables&nbsp;like&nbsp;$#&nbsp;in&nbsp;bash</span></span></div></li>
+<li><div class="src-line"><a name="a2858"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;or&nbsp;compiler&nbsp;directives&nbsp;of&nbsp;Delphi&nbsp;beginning&nbsp;{$</span></span></div></li>
+<li><div class="src-line"><a name="a2859"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">((</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$sc_disallowed_before</span><span class="src-sym">)</span>&nbsp;||&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;==&nbsp;<span class="src-num">0</span><span class="src-sym">)</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2860"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$sc_disallowed_before</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$part</span><span class="src-sym">[</span><span class="src-var">$i</span>-<span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">)))</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a2861"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$sc_disallowed_after</span><span class="src-sym">)</span>&nbsp;||&nbsp;<span class="src-sym">(</span><span class="src-var">$length</span>&nbsp;&lt;=&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$com_len</span><span class="src-sym">)</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a2862"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$sc_disallowed_after</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$part</span><span class="src-sym">[</span><span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$com_len</span><span class="src-sym">]</span><span class="src-sym">))))</span></span></div></li>
+<li><div class="src-line"><a name="a2863"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2864"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;is&nbsp;a&nbsp;valid&nbsp;comment</span></span></div></li>
+<li><div class="src-line"><a name="a2865"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$COMMENT_MATCHED</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2866"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2867"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2868"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2869"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2870"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;co'</span>&nbsp;.&nbsp;<span class="src-var">$comment_key</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2871"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2872"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;span<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;&nbsp;</span><span class="src-str">.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">change_case</span><span class="src-sym">(</span><span class="src-var">$comment_mark</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2873"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2874"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$comment_mark</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2875"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2876"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2877"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;this&nbsp;comment&nbsp;is&nbsp;the&nbsp;last&nbsp;in&nbsp;the&nbsp;source</span></span></div></li>
+<li><div class="src-line"><a name="a2878"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-id">strpos</span><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2879"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oops</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2880"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close_pos</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2881"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_pos</span>&nbsp;=&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2882"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oops</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2883"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2884"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-var">$com_len</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close_pos</span>&nbsp;-&nbsp;<span class="src-var">$i</span>&nbsp;-&nbsp;<span class="src-var">$com_len</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2885"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$comment_key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2886"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&lt;/span&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2887"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2888"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2889"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Take&nbsp;into&nbsp;account&nbsp;that&nbsp;the&nbsp;comment&nbsp;might&nbsp;be&nbsp;the&nbsp;last&nbsp;in&nbsp;the&nbsp;source</span></span></div></li>
+<li><div class="src-line"><a name="a2890"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$oops</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2891"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$test_str</span>&nbsp;.=&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2892"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2893"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2894"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-var">$close_pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2895"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2896"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;parse&nbsp;the&nbsp;rest</span></span></div></li>
+<li><div class="src-line"><a name="a2897"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2898"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2899"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2900"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2901"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2902"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2903"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2904"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Where&nbsp;are&nbsp;we&nbsp;adding&nbsp;this&nbsp;char?</span></span></div></li>
+<li><div class="src-line"><a name="a2905"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$COMMENT_MATCHED</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2906"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;.=&nbsp;<span class="src-var">$char</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2907"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2908"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$test_str</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2909"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$test_str</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2910"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$COMMENT_MATCHED</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2911"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2912"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2913"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Parse&nbsp;the&nbsp;last&nbsp;bit</span></span></div></li>
+<li><div class="src-line"><a name="a2914"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2915"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2916"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2917"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2918"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2919"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Close&nbsp;the&nbsp;&lt;span&gt;&nbsp;that&nbsp;surrounds&nbsp;the&nbsp;block</span></span></div></li>
+<li><div class="src-line"><a name="a2920"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$STRICTATTRS</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2921"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;/span&gt;\n&lt;span<span class="src-var">$STRICTATTRS</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2922"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2923"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2924"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2925"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$endresult</span>&nbsp;.=&nbsp;<span class="src-var">$result</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2926"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$part</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$parts</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2927"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2928"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2929"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;fix&nbsp;is&nbsp;related&nbsp;to&nbsp;SF#1923020,&nbsp;but&nbsp;has&nbsp;to&nbsp;be&nbsp;applied&nbsp;regardless&nbsp;of</span></span></div></li>
+<li><div class="src-line"><a name="a2930"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//actually&nbsp;highlighting&nbsp;symbols.</span></span></div></li>
+<li><div class="src-line"><a name="a2931"></a><span class="src-doc">/**&nbsp;NOTE:&nbsp;memorypeak&nbsp;#3&nbsp;*/</span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a2932"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$endresult</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'&lt;SEMI&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;PIPE&gt;'</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">';'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'|'</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$endresult</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2933"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2934"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Parse&nbsp;the&nbsp;last&nbsp;stuff&nbsp;(redundant?)</span></span></div></li>
+<li><div class="src-line"><a name="a2935"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$result&nbsp;.=&nbsp;$this-&gt;parse_non_string_part($stuff_to_parse);</span></span></div></li>
+<li><div class="src-line"><a name="a2936"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a2937"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Lop&nbsp;off&nbsp;the&nbsp;very&nbsp;first&nbsp;and&nbsp;last&nbsp;spaces</span></span></div></li>
+<li><div class="src-line"><a name="a2938"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$result&nbsp;=&nbsp;substr($result,&nbsp;1,&nbsp;-1);</span></span></div></li>
+<li><div class="src-line"><a name="a2939"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a2940"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;We're&nbsp;finished:&nbsp;stop&nbsp;timing</span></span></div></li>
+<li><div class="src-line"><a name="a2941"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">set_time</span><span class="src-sym">(</span><span class="src-var">$start_time</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/microtime">microtime</a><span class="src-sym">(</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2942"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2943"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">finalise</span><span class="src-sym">(</span><span class="src-var">$endresult</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2944"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$endresult</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2945"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2946"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2947"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a2948"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Swaps&nbsp;out&nbsp;spaces&nbsp;and&nbsp;tabs&nbsp;for&nbsp;HTML&nbsp;indentation.&nbsp;Not&nbsp;needed&nbsp;if</span></div></li>
+<li><div class="src-line"><a name="a2949"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;code&nbsp;is&nbsp;in&nbsp;a&nbsp;pre&nbsp;block...</span></div></li>
+<li><div class="src-line"><a name="a2950"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a2951"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc">&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;source&nbsp;to&nbsp;indent&nbsp;(reference!)</span></div></li>
+<li><div class="src-line"><a name="a2952"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a2953"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a2954"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a2955"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">indent</span><span class="src-sym">(</span><span class="src-sym">&</span><span class="src-var">$result</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2956"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">///&nbsp;Replace&nbsp;tabs&nbsp;with&nbsp;the&nbsp;correct&nbsp;number&nbsp;of&nbsp;spaces</span></span></div></li>
+<li><div class="src-line"><a name="a2957"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;!==&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$result</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\t&quot;</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2958"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span>&nbsp;=&nbsp;<a href="http://www.php.net/explode">explode</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2959"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<span class="src-id">null</span><span class="src-sym">;</span><span class="src-comm">//Save&nbsp;memory&nbsp;while&nbsp;we&nbsp;process&nbsp;the&nbsp;lines&nbsp;individually</span></span></div></li>
+<li><div class="src-line"><a name="a2960"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$tab_width</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodget_real_tab_width">get_real_tab_width</a><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2961"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$tab_string</span>&nbsp;=&nbsp;<span class="src-str">'&amp;nbsp;'</span>&nbsp;.&nbsp;<a href="http://www.php.net/str_repeat">str_repeat</a><span class="src-sym">(</span><span class="src-str">'&nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$tab_width</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2962"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2963"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$key</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$n</span>&nbsp;=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$lines</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$key</span>&nbsp;<&nbsp;<span class="src-var">$n</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$key</span>++<span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2964"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$line</span>&nbsp;=&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2965"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\t&quot;</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2966"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2967"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2968"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a2969"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pos</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2970"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$length</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2971"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;reduce&nbsp;memory</span></span></div></li>
+<li><div class="src-line"><a name="a2972"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a2973"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$IN_TAG</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2974"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$length</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2975"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char</span>&nbsp;=&nbsp;<span class="src-var">$line</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2976"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Simple&nbsp;engine&nbsp;to&nbsp;work&nbsp;out&nbsp;whether&nbsp;we're&nbsp;in&nbsp;a&nbsp;tag.</span></span></div></li>
+<li><div class="src-line"><a name="a2977"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;we&nbsp;are&nbsp;we&nbsp;modify&nbsp;$pos.&nbsp;This&nbsp;is&nbsp;so&nbsp;we&nbsp;ignore&nbsp;HTML</span></span></div></li>
+<li><div class="src-line"><a name="a2978"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;in&nbsp;the&nbsp;line&nbsp;and&nbsp;only&nbsp;workout&nbsp;the&nbsp;tab&nbsp;replacement</span></span></div></li>
+<li><div class="src-line"><a name="a2979"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;via&nbsp;the&nbsp;actual&nbsp;content&nbsp;of&nbsp;the&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a2980"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;This&nbsp;test&nbsp;could&nbsp;be&nbsp;improved&nbsp;to&nbsp;include&nbsp;strings&nbsp;in&nbsp;the</span></span></div></li>
+<li><div class="src-line"><a name="a2981"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;html&nbsp;so&nbsp;that&nbsp;&lt;&nbsp;or&nbsp;&gt;&nbsp;would&nbsp;be&nbsp;allowed&nbsp;in&nbsp;user's&nbsp;styles</span></span></div></li>
+<li><div class="src-line"><a name="a2982"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;(e.g.&nbsp;quotes:&nbsp;'&lt;'&nbsp;'&gt;';&nbsp;or&nbsp;similar)</span></span></div></li>
+<li><div class="src-line"><a name="a2983"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$IN_TAG</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2984"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-str">'&gt;'</span>&nbsp;==&nbsp;<span class="src-var">$char</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2985"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$IN_TAG</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2986"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2987"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$char</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2988"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-str">'&lt;'</span>&nbsp;==&nbsp;<span class="src-var">$char</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2989"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$IN_TAG</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2990"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2991"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-str">'&amp;'</span>&nbsp;==&nbsp;<span class="src-var">$char</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2992"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$substr</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">3</span><span class="src-sym">,</span>&nbsp;<span class="src-num">5</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2993"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$posi</span>&nbsp;=&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$substr</span><span class="src-sym">,</span>&nbsp;<span class="src-str">';'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2994"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<span class="src-var">$posi</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2995"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2996"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a2997"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pos</span>&nbsp;-=&nbsp;<span class="src-var">$posi</span>+<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a2998"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a2999"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$char</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3000"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-str">&quot;\t&quot;</span>&nbsp;==&nbsp;<span class="src-var">$char</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3001"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$str</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3002"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;OPTIMISE&nbsp;-&nbsp;move&nbsp;$strs&nbsp;out.&nbsp;Make&nbsp;an&nbsp;array:</span></span></div></li>
+<li><div class="src-line"><a name="a3003"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;$tabs&nbsp;=&nbsp;array(</span></span></div></li>
+<li><div class="src-line"><a name="a3004"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;1&nbsp;=&gt;&nbsp;'&amp;nbsp;',</span></span></div></li>
+<li><div class="src-line"><a name="a3005"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;2&nbsp;=&gt;&nbsp;'&amp;nbsp;&nbsp;',</span></span></div></li>
+<li><div class="src-line"><a name="a3006"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;3&nbsp;=&gt;&nbsp;'&amp;nbsp;&nbsp;&amp;nbsp;'&nbsp;etc&nbsp;etc</span></span></div></li>
+<li><div class="src-line"><a name="a3007"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;to&nbsp;use&nbsp;instead&nbsp;of&nbsp;building&nbsp;a&nbsp;string&nbsp;every&nbsp;time</span></span></div></li>
+<li><div class="src-line"><a name="a3008"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$tab_end_width</span>&nbsp;=&nbsp;<span class="src-var">$tab_width</span>&nbsp;-&nbsp;<span class="src-sym">(</span><span class="src-var">$pos</span>&nbsp;%&nbsp;<span class="src-var">$tab_width</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//Moved&nbsp;out&nbsp;of&nbsp;the&nbsp;look&nbsp;as&nbsp;it&nbsp;doesn't&nbsp;change&nbsp;within&nbsp;the&nbsp;loop</span></span></div></li>
+<li><div class="src-line"><a name="a3009"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">((</span><span class="src-var">$pos</span>&nbsp;<span class="src-sym">&</span>&nbsp;<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;||&nbsp;<span class="src-num">1</span>&nbsp;==&nbsp;<span class="src-var">$tab_end_width</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3010"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$str</span>&nbsp;.=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$tab_string</span><span class="src-sym">,</span>&nbsp;<span class="src-num">6</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$tab_end_width</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3011"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3012"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$str</span>&nbsp;.=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$tab_string</span><span class="src-sym">,</span>&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$tab_end_width</span>+<span class="src-num">5</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3013"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3014"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$str</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3015"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pos</span>&nbsp;+=&nbsp;<span class="src-var">$tab_end_width</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3016"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3017"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;===&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;\t&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3018"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3019"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3020"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3021"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-num">0</span>&nbsp;==&nbsp;<span class="src-var">$pos</span>&nbsp;&amp;&amp;&nbsp;<span class="src-str">'&nbsp;'</span>&nbsp;==&nbsp;<span class="src-var">$char</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3022"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-str">'&amp;nbsp;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3023"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3024"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3025"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$lines</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.=&nbsp;<span class="src-var">$char</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3026"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$pos</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3027"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3028"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3029"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3030"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$lines</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3031"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$lines</span><span class="src-sym">)</span><span class="src-sym">;</span><span class="src-comm">//We&nbsp;don't&nbsp;need&nbsp;the&nbsp;lines&nbsp;separated&nbsp;beyond&nbsp;this&nbsp;---&nbsp;free&nbsp;them!</span></span></div></li>
+<li><div class="src-line"><a name="a3032"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3033"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Other&nbsp;whitespace</span></span></div></li>
+<li><div class="src-line"><a name="a3034"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;BenBE:&nbsp;Fix&nbsp;to&nbsp;reduce&nbsp;the&nbsp;number&nbsp;of&nbsp;replacements&nbsp;to&nbsp;be&nbsp;done</span></span></div></li>
+<li><div class="src-line"><a name="a3035"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span><span class="src-str">'/^&nbsp;/m'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&amp;nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3036"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'&nbsp;&nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&nbsp;&amp;nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3037"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3038"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3039"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_ending</span>&nbsp;===&nbsp;<span class="src-id">null</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3040"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<a href="http://www.php.net/nl2br">nl2br</a><span class="src-sym">(</span><span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3041"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3042"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$result</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_ending</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$result</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3043"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3044"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3045"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3046"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3047"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a3048"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Changes&nbsp;the&nbsp;case&nbsp;of&nbsp;a&nbsp;keyword&nbsp;for&nbsp;those&nbsp;languages&nbsp;where&nbsp;a&nbsp;change&nbsp;is&nbsp;asked&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a3049"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3050"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc">&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;keyword&nbsp;to&nbsp;change&nbsp;the&nbsp;case&nbsp;of</span></div></li>
+<li><div class="src-line"><a name="a3051"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;keyword&nbsp;with&nbsp;its&nbsp;case&nbsp;changed</span></div></li>
+<li><div class="src-line"><a name="a3052"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a3053"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3054"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a3055"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">change_case</span><span class="src-sym">(</span><span class="src-var">$instr</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3056"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">switch</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3057"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_CAPS_UPPER&quot;&gt;GESHI_CAPS_UPPER&lt;/a&gt;</span>:</span></div></li>
+<li><div class="src-line"><a name="a3058"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<a href="http://www.php.net/strtoupper">strtoupper</a><span class="src-sym">(</span><span class="src-var">$instr</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3059"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_CAPS_LOWER&quot;&gt;GESHI_CAPS_LOWER&lt;/a&gt;</span>:</span></div></li>
+<li><div class="src-line"><a name="a3060"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<a href="http://www.php.net/strtolower">strtolower</a><span class="src-sym">(</span><span class="src-var">$instr</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3061"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">default</span>:</span></div></li>
+<li><div class="src-line"><a name="a3062"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$instr</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3063"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3064"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3065"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3066"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a3067"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Handles&nbsp;replacements&nbsp;of&nbsp;keywords&nbsp;to&nbsp;include&nbsp;markup&nbsp;and&nbsp;links&nbsp;if&nbsp;requested</span></div></li>
+<li><div class="src-line"><a name="a3068"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3069"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc">&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;keyword&nbsp;to&nbsp;add&nbsp;the&nbsp;Markup&nbsp;to</span></div></li>
+<li><div class="src-line"><a name="a3070"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">The&nbsp;</span><span class="src-doc">HTML&nbsp;for&nbsp;the&nbsp;match&nbsp;found</span></div></li>
+<li><div class="src-line"><a name="a3071"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a3072"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3073"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3074"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;&nbsp;&nbsp;Get&nbsp;rid&nbsp;of&nbsp;ender&nbsp;in&nbsp;keyword&nbsp;links</span></div></li>
+<li><div class="src-line"><a name="a3075"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a3076"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">handle_keyword_replace</span><span class="src-sym">(</span><span class="src-var">$match</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3077"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$k</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_kw_replace_group</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3078"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keyword</span>&nbsp;=&nbsp;<span class="src-var">$match</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3079"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3080"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$before</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3081"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$after</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3082"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3083"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">keyword_links</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3084"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Keyword&nbsp;links&nbsp;have&nbsp;been&nbsp;ebabled</span></span></div></li>
+<li><div class="src-line"><a name="a3085"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a3086"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'URLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3087"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'URLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3088"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;There&nbsp;is&nbsp;a&nbsp;base&nbsp;group&nbsp;for&nbsp;this&nbsp;keyword</span></span></div></li>
+<li><div class="src-line"><a name="a3089"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a3090"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Old&nbsp;system:&nbsp;strtolower</span></span></div></li>
+<li><div class="src-line"><a name="a3091"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$keyword&nbsp;=&nbsp;(&nbsp;$this-&gt;language_data['CASE_SENSITIVE'][$group]&nbsp;)&nbsp;?&nbsp;$keyword&nbsp;:&nbsp;strtolower($keyword);</span></span></div></li>
+<li><div class="src-line"><a name="a3092"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;New&nbsp;system:&nbsp;get&nbsp;keyword&nbsp;from&nbsp;language&nbsp;file&nbsp;to&nbsp;get&nbsp;correct&nbsp;case</span></span></div></li>
+<li><div class="src-line"><a name="a3093"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3094"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'URLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'{FNAME}'</span><span class="src-sym">)</span>&nbsp;!==&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3095"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$word</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3096"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/strcasecmp">strcasecmp</a><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$keyword</span><span class="src-sym">)</span>&nbsp;==&nbsp;<span class="src-num">0</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3097"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3098"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3099"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3100"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3101"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$word</span>&nbsp;=&nbsp;<span class="src-var">$keyword</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3102"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3103"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3104"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$before</span>&nbsp;=&nbsp;<span class="src-str">'&lt;|UR1|&quot;'</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a3105"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a3106"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a3107"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'{FNAME}'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3108"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'{FNAMEL}'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3109"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'{FNAMEU}'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3110"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'.'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3111"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a3112"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'+'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'%20'</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/urlencode">urlencode</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">)))</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3113"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'+'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'%20'</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/urlencode">urlencode</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/strtolower">strtolower</a><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">))))</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3114"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'+'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'%20'</span><span class="src-sym">,</span>&nbsp;<a href="http://www.php.net/urlencode">urlencode</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><a href="http://www.php.net/strtoupper">strtoupper</a><span class="src-sym">(</span><span class="src-var">$word</span><span class="src-sym">))))</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3115"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;DOT&gt;'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3116"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'URLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span></span></div></li>
+<li><div class="src-line"><a name="a3117"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3118"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$after</span>&nbsp;=&nbsp;<span class="src-str">'&lt;/a&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3119"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3120"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3121"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3122"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$before</span>&nbsp;.&nbsp;<span class="src-str">'&lt;|/'</span>.&nbsp;<span class="src-var">$k</span>&nbsp;.<span class="src-str">'/&gt;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">change_case</span><span class="src-sym">(</span><span class="src-var">$keyword</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'|&gt;'</span>&nbsp;.&nbsp;<span class="src-var">$after</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3123"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3124"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3125"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a3126"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;handles&nbsp;regular&nbsp;expressions&nbsp;highlighting-definitions&nbsp;with&nbsp;callback&nbsp;functions</span></div></li>
+<li><div class="src-line"><a name="a3127"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3128"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-tag">@note</span><span class="src-doc">&nbsp;this&nbsp;is&nbsp;a&nbsp;callback,&nbsp;don't&nbsp;use&nbsp;it&nbsp;directly</span></div></li>
+<li><div class="src-line"><a name="a3129"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3130"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">array&nbsp;</span><span class="src-doc">the&nbsp;matches&nbsp;array</span></div></li>
+<li><div class="src-line"><a name="a3131"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">The&nbsp;</span><span class="src-doc">highlighted&nbsp;string</span></div></li>
+<li><div class="src-line"><a name="a3132"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a3133"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3134"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a3135"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">handle_regexps_callback</span><span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3136"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;before:&nbsp;&quot;'&nbsp;style=\&quot;'&nbsp;.&nbsp;call_user_func(\&quot;$func\&quot;,&nbsp;'\\1')&nbsp;.&nbsp;'\&quot;\\1|&gt;'&quot;,</span></span></div></li>
+<li><div class="src-line"><a name="a3137"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<a href="http://www.php.net/call_user_func">call_user_func</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_rx_key</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span>.&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'|&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3138"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3139"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3140"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a3141"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;handles&nbsp;newlines&nbsp;in&nbsp;REGEXPS&nbsp;matches.&nbsp;Set&nbsp;the&nbsp;_hmr_*&nbsp;vars&nbsp;before&nbsp;calling&nbsp;this</span></div></li>
+<li><div class="src-line"><a name="a3142"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3143"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-tag">@note</span><span class="src-doc">&nbsp;this&nbsp;is&nbsp;a&nbsp;callback,&nbsp;don't&nbsp;use&nbsp;it&nbsp;directly</span></div></li>
+<li><div class="src-line"><a name="a3144"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3145"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">array&nbsp;</span><span class="src-doc">the&nbsp;matches&nbsp;array</span></div></li>
+<li><div class="src-line"><a name="a3146"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@return&nbsp;</span><span class="src-doc-type">string&nbsp;</span></div></li>
+<li><div class="src-line"><a name="a3147"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a3148"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3149"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a3150"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">handle_multiline_regexps</span><span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3151"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$before</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_before</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3152"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$after</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_after</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3153"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_replace</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3154"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replace</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_replace</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3155"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$search</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3156"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3157"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$matches</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$k</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3158"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$search</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'\\'</span>&nbsp;.&nbsp;<span class="src-var">$k</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3159"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3160"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3161"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$before</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-var">$search</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$before</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3162"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$after</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-var">$search</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$after</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3163"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replace</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-var">$search</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$matches</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$replace</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3164"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3165"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replace</span>&nbsp;=&nbsp;<span class="src-var">$matches</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3166"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3167"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$before</span></span></div></li>
+<li><div class="src-line"><a name="a3168"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<span class="src-str">'&lt;|!REG3XP'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_key</span>&nbsp;.<span class="src-str">'!&gt;'</span></span></div></li>
+<li><div class="src-line"><a name="a3169"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">&quot;|&gt;\n&lt;|!REG3XP&quot;</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_key</span>&nbsp;.&nbsp;<span class="src-str">'!&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$replace</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a3170"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<span class="src-str">'|&gt;'</span></span></div></li>
+<li><div class="src-line"><a name="a3171"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<span class="src-var">$after</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3172"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3173"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3174"></a><span class="src-doc">/**</span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;</span></span></div></li>
+<li><div class="src-line"><a name="a3175"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Takes&nbsp;a&nbsp;string&nbsp;that&nbsp;has&nbsp;no&nbsp;strings&nbsp;or&nbsp;comments&nbsp;in&nbsp;it,&nbsp;and&nbsp;highlights</span></div></li>
+<li><div class="src-line"><a name="a3176"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;stuff&nbsp;like&nbsp;keywords,&nbsp;numbers&nbsp;and&nbsp;methods.</span></div></li>
+<li><div class="src-line"><a name="a3177"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3178"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@param&nbsp;</span><span class="src-doc-type">string&nbsp;</span><span class="src-doc">The&nbsp;string&nbsp;to&nbsp;parse&nbsp;for&nbsp;keyword,&nbsp;numbers&nbsp;etc.</span></div></li>
+<li><div class="src-line"><a name="a3179"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@since</span><span class="src-doc">&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a3180"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@access</span><span class="src-doc">&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3181"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span class="src-doc-coretag">@todo</span><span class="src-doc">&nbsp;BUGGY!&nbsp;Why?&nbsp;Why&nbsp;not&nbsp;build&nbsp;string&nbsp;and&nbsp;return?</span></div></li>
+<li><div class="src-line"><a name="a3182"></a><span class="src-doc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span class="src-str"></span></span></div></li>
+<li><div class="src-line"><a name="a3183"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">parse_non_string_part</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3184"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3185"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3186"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Regular&nbsp;expressions</span></span></div></li>
+<li><div class="src-line"><a name="a3187"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$regexp</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3188"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3189"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$regexp</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3190"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3191"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;produce&nbsp;valid&nbsp;HTML&nbsp;when&nbsp;we&nbsp;match&nbsp;multiple&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3192"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_replace</span>&nbsp;=&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_REPLACE</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3193"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_before</span>&nbsp;=&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_BEFORE</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3194"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_key</span>&nbsp;=&nbsp;<span class="src-var">$key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3195"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_after</span>&nbsp;=&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_AFTER</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3196"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace_callback">preg_replace_callback</a><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a3197"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;/&quot;</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_SEARCH</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">"</span></span>/{<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_MODIFIERS</span><span class="src-sym">]</span><span class="src-sym">}</span><span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3198"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'handle_multiline_regexps'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3199"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3200"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_replace</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3201"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_before</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3202"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_after</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3203"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3204"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a3205"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'/'</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_SEARCH</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'/'</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_MODIFIERS</span><span class="src-sym">]</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3206"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_BEFORE</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&lt;|!REG3XP'</span>.&nbsp;<span class="src-var">$key</span>&nbsp;.<span class="src-str">'!&gt;'</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_REPLACE</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'|&gt;'</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span><span class="src-sym">[</span><span class="src-id">GESHI_AFTER</span><span class="src-sym">]</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3207"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3208"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3209"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3210"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3211"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;produce&nbsp;valid&nbsp;HTML&nbsp;when&nbsp;we&nbsp;match&nbsp;multiple&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3212"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_key</span>&nbsp;=&nbsp;<span class="src-var">$key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3213"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace_callback">preg_replace_callback</a><span class="src-sym">(</span>&nbsp;<span class="src-str">&quot;/(&quot;</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span>&nbsp;.&nbsp;<span class="src-str">&quot;)/&quot;</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3214"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'handle_multiline_regexps'</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3215"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_hmr_key</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3216"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3217"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span>&nbsp;<span class="src-str">&quot;/(&quot;</span>&nbsp;.&nbsp;<span class="src-var">$regexp</span>&nbsp;.&nbsp;<span class="src-str">&quot;)/&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;|!REG3XP<span class="src-var">$key</span>!&gt;\\1|&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3218"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3219"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3220"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3221"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3222"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3223"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Highlight&nbsp;numbers.&nbsp;As&nbsp;of&nbsp;1.0.8&nbsp;we&nbsp;support&nbsp;diffent&nbsp;types&nbsp;of&nbsp;numbers</span></span></div></li>
+<li><div class="src-line"><a name="a3224"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$numbers_found</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3225"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<a href="http://www.php.net/preg_match">preg_match</a><span class="src-sym">(</span><span class="src-str">'#\d#'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;<span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3226"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$numbers_found</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3227"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3228"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//For&nbsp;each&nbsp;of&nbsp;the&nbsp;formats&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3229"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_RXCACHE'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$id</span>&nbsp;=&gt;&nbsp;<span class="src-var">$regexp</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3230"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;it&nbsp;should&nbsp;be&nbsp;highlighted&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3231"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span><span class="src-var">$regexp</span><span class="src-sym">,</span>&nbsp;<span class="src-str">"</span></span>&lt;|/NUM!<span class="src-var">$id</span>/&gt;\\1|&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3232"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3233"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3234"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3235"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Highlight&nbsp;keywords</span></span></div></li>
+<li><div class="src-line"><a name="a3236"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_before</span>&nbsp;=&nbsp;<span class="src-str">&quot;(?&lt;![a-zA-Z0-9\$_\|\#;&gt;|^&amp;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3237"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_after</span>&nbsp;=&nbsp;<span class="src-str">&quot;(?![a-zA-Z0-9_\|%\\-&amp;;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3238"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3239"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$quotemarks</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span><a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'QUOTEMARKS'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3240"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_before</span>&nbsp;.=&nbsp;<span class="src-var">$quotemarks</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3241"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_after</span>&nbsp;.=&nbsp;<span class="src-var">$quotemarks</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3242"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3243"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_before</span>&nbsp;.=&nbsp;<span class="src-str">&quot;])&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3244"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_after</span>&nbsp;.=&nbsp;<span class="src-str">&quot;])&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3245"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3246"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parser_control_pergroup</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3247"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3248"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3249"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$x</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;check&nbsp;wether&nbsp;per-keyword-group&nbsp;parser_control&nbsp;is&nbsp;enabled</span></span></div></li>
+<li><div class="src-line"><a name="a3250"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3251"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_before</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3252"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$x</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3253"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3254"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_AFTER'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3255"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_after</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_AFTER'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3256"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$x</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3257"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3258"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parser_control_pergroup</span>&nbsp;=&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;-&nbsp;<span class="src-var">$x</span><span class="src-sym">)</span>&nbsp;>&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3259"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3260"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3261"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3262"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;if&nbsp;this&nbsp;is&nbsp;changed,&nbsp;don't&nbsp;forget&nbsp;to&nbsp;change&nbsp;it&nbsp;below</span></span></div></li>
+<li><div class="src-line"><a name="a3263"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!empty($disallowed_before))&nbsp;{</span></span></div></li>
+<li><div class="src-line"><a name="a3264"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$disallowed_before&nbsp;=&nbsp;&quot;(?&lt;![$disallowed_before])&quot;;</span></span></div></li>
+<li><div class="src-line"><a name="a3265"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div></li>
+<li><div class="src-line"><a name="a3266"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!empty($disallowed_after))&nbsp;{</span></span></div></li>
+<li><div class="src-line"><a name="a3267"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$disallowed_after&nbsp;=&nbsp;&quot;(?![$disallowed_after])&quot;;</span></span></div></li>
+<li><div class="src-line"><a name="a3268"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div></li>
+<li><div class="src-line"><a name="a3269"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a3270"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$k</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3271"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a3272"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3273"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3274"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$case_sensitive</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CASE_SENSITIVE'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3275"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$modifiers</span>&nbsp;=&nbsp;<span class="src-var">$case_sensitive</span>&nbsp;?&nbsp;<span class="src-str">''</span>&nbsp;:&nbsp;<span class="src-str">'i'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3276"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3277"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;NEW&nbsp;in&nbsp;1.0.8&nbsp;-&nbsp;per-keyword-group&nbsp;parser&nbsp;control</span></span></div></li>
+<li><div class="src-line"><a name="a3278"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_before_local</span>&nbsp;=&nbsp;<span class="src-var">$disallowed_before</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3279"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_after_local</span>&nbsp;=&nbsp;<span class="src-var">$disallowed_after</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3280"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$parser_control_pergroup</span>&nbsp;&amp;&amp;&nbsp;isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3281"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3282"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_before_local</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a3283"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3284"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3285"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3286"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_AFTER'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3287"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$disallowed_after_local</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a3288"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'DISALLOWED_AFTER'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3289"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3290"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3291"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3292"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_kw_replace_group</span>&nbsp;=&nbsp;<span class="src-var">$k</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3293"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3294"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//NEW&nbsp;in&nbsp;1.0.8,&nbsp;the&nbsp;cached&nbsp;regexp&nbsp;list</span></span></div></li>
+<li><div class="src-line"><a name="a3295"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;since&nbsp;we&nbsp;don't&nbsp;want&nbsp;PHP&nbsp;/&nbsp;PCRE&nbsp;to&nbsp;crash&nbsp;due&nbsp;to&nbsp;too&nbsp;large&nbsp;patterns&nbsp;we&nbsp;split&nbsp;them&nbsp;into&nbsp;smaller&nbsp;chunks</span></span></div></li>
+<li><div class="src-line"><a name="a3296"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$set</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$set_length</span>&nbsp;=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$set</span>&nbsp;<&nbsp;&nbsp;<span class="src-var">$set_length</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$set</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3297"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywordset</span>&nbsp;=<span class="src-sym">&</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHED_KEYWORD_LISTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$set</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3298"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Might&nbsp;make&nbsp;a&nbsp;more&nbsp;unique&nbsp;string&nbsp;for&nbsp;putting&nbsp;the&nbsp;number&nbsp;in&nbsp;soon</span></span></div></li>
+<li><div class="src-line"><a name="a3299"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Basically,&nbsp;we&nbsp;don't&nbsp;put&nbsp;the&nbsp;styles&nbsp;in&nbsp;yet&nbsp;because&nbsp;then&nbsp;the&nbsp;styles&nbsp;themselves&nbsp;will</span></span></div></li>
+<li><div class="src-line"><a name="a3300"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;get&nbsp;highlighted&nbsp;if&nbsp;the&nbsp;language&nbsp;has&nbsp;a&nbsp;CSS&nbsp;keyword&nbsp;in&nbsp;it&nbsp;(like&nbsp;CSS,&nbsp;for&nbsp;example&nbsp;;))</span></span></div></li>
+<li><div class="src-line"><a name="a3301"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace_callback">preg_replace_callback</a><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a3302"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">"</span></span>/<span class="src-var">$disallowed_before_local</span>({<span class="src-var">$keywordset</span><span class="src-sym">}</span>)(?!\&lt;DOT\&gt;(?:htm|php))<span class="src-var">$disallowed_after_local</span>/<span class="src-var">$modifiers</span><span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3303"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'handle_keyword_replace'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3304"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span></span></div></li>
+<li><div class="src-line"><a name="a3305"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3306"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3307"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3308"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3309"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3310"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a3311"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Now&nbsp;that's&nbsp;all&nbsp;done,&nbsp;replace&nbsp;/[number]/&nbsp;with&nbsp;the&nbsp;correct&nbsp;styles</span></span></div></li>
+<li><div class="src-line"><a name="a3312"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a3313"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$k</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3314"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3315"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a3316"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;?</span></div></li>
+<li><div class="src-line"><a name="a3317"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$k</span><span class="src-sym">]</span>&nbsp;:&nbsp;<span class="src-str">&quot;&quot;</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3318"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3319"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;kw'</span>&nbsp;.&nbsp;<span class="src-var">$k</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3320"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3321"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">"</span></span>&lt;|/<span class="src-var">$k</span>/&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;</span><span class="src-str">&quot;</span>&lt;|<span class="src-var">$attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3322"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3323"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3324"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$numbers_found</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3325"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Put&nbsp;number&nbsp;styles&nbsp;in</span></span></div></li>
+<li><div class="src-line"><a name="a3326"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_RXCACHE'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$id</span>&nbsp;=&gt;&nbsp;<span class="src-var">$regexp</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3327"></a></span><span class="src-str"><span class="src-comm">//Commented&nbsp;out&nbsp;for&nbsp;now,&nbsp;as&nbsp;this&nbsp;needs&nbsp;some&nbsp;review&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3328"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;($numbers_permissions&nbsp;&amp;&nbsp;$id)&nbsp;{</span></span></div></li>
+<li><div class="src-line"><a name="a3329"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;the&nbsp;appropriate&nbsp;style&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3330"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Checking&nbsp;for&nbsp;unset&nbsp;styles&nbsp;is&nbsp;done&nbsp;by&nbsp;the&nbsp;style&nbsp;cache&nbsp;builder&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3331"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3332"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$id</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3333"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3334"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;nu'</span>.<span class="src-var">$id</span>.<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3335"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3336"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3337"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Set&nbsp;in&nbsp;the&nbsp;correct&nbsp;styles&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3338"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">"</span></span>/NUM!<span class="src-var">$id</span>/<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$attributes</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3339"></a></span><span class="src-str"><span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div></li>
+<li><div class="src-line"><a name="a3340"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3341"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3342"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3343"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Highlight&nbsp;methods&nbsp;and&nbsp;fields&nbsp;in&nbsp;objects</span></span></div></li>
+<li><div class="src-line"><a name="a3344"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3345"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oolang_spaces</span>&nbsp;=&nbsp;<span class="src-str">&quot;[\s]*&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3346"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oolang_before</span>&nbsp;=&nbsp;<span class="src-str">&quot;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3347"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oolang_after</span>&nbsp;=&nbsp;<span class="src-str">&quot;[a-zA-Z][a-zA-Z0-9_]*&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3348"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3349"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3350"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MATCH_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3351"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oolang_before</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MATCH_BEFORE'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3352"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3353"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MATCH_AFTER'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3354"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oolang_after</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MATCH_AFTER'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3355"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3356"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MATCH_SPACES'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3357"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$oolang_spaces</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'OOLANG'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'MATCH_SPACES'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3358"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3359"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3360"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3361"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3362"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'OBJECT_SPLITTERS'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$splitter</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3363"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">false</span>&nbsp;!==&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$splitter</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3364"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3365"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3366"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3367"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;me'</span>&nbsp;.&nbsp;<span class="src-var">$key</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3368"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3369"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span><span class="src-str">"</span></span>/(<span class="src-var">$oolang_before</span>)(<span class="src-str">&quot;&nbsp;</span><span class="src-str">.&nbsp;<span class="src-id">preg_quote</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'OBJECT_SPLITTERS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'/'</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">"</span></span>)(<span class="src-var">$oolang_spaces</span>)(<span class="src-var">$oolang_after</span>)/<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;</span><span class="src-str">&quot;</span>\\1\\2\\3&lt;|<span class="src-var">$attributes</span>&gt;\\4|&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3370"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3371"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3372"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3373"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3374"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a3375"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Highlight&nbsp;brackets.&nbsp;Yes,&nbsp;I've&nbsp;tried&nbsp;adding&nbsp;a&nbsp;semi-colon&nbsp;to&nbsp;this&nbsp;list.</span></span></div></li>
+<li><div class="src-line"><a name="a3376"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;You&nbsp;try&nbsp;it,&nbsp;and&nbsp;see&nbsp;what&nbsp;happens&nbsp;;)</span></span></div></li>
+<li><div class="src-line"><a name="a3377"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;TODO:&nbsp;Fix&nbsp;lexic&nbsp;permissions&nbsp;not&nbsp;converting&nbsp;entities&nbsp;if&nbsp;shouldn't</span></span></div></li>
+<li><div class="src-line"><a name="a3378"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;be&nbsp;highlighting&nbsp;regardless</span></span></div></li>
+<li><div class="src-line"><a name="a3379"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a3380"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3381"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHE_BRACKET_MATCH'</span><span class="src-sym">]</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3382"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'CACHE_BRACKET_REPLACE'</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3383"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3384"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3385"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3386"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//FIX&nbsp;for&nbsp;symbol&nbsp;highlighting&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3387"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span>&nbsp;&amp;&amp;&nbsp;<span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3388"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Get&nbsp;all&nbsp;matches&nbsp;and&nbsp;throw&nbsp;away&nbsp;those&nbsp;witin&nbsp;a&nbsp;block&nbsp;that&nbsp;is&nbsp;already&nbsp;highlighted...&nbsp;(i.e.&nbsp;matched&nbsp;by&nbsp;a&nbsp;regexp)</span></span></div></li>
+<li><div class="src-line"><a name="a3389"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$n_symbols</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_match_all">preg_match_all</a><span class="src-sym">(</span><span class="src-str">&quot;/&lt;\|(?:&lt;DOT&gt;|[^&gt;])+&gt;(?:(?!\|&gt;).*?)\|&gt;|&lt;\/a&gt;|(?:&quot;</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_SEARCH'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">&quot;)+/&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$pot_symbols</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_OFFSET_CAPTURE</span>&nbsp;|&nbsp;<span class="src-id">PREG_SET_ORDER</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3390"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$global_offset</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3391"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$s_id</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$s_id</span>&nbsp;<&nbsp;<span class="src-var">$n_symbols</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$s_id</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3392"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_match</span>&nbsp;=&nbsp;<span class="src-var">$pot_symbols</span><span class="src-sym">[</span><span class="src-var">$s_id</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3393"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$symbol_match</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;'</span><span class="src-sym">)</span>&nbsp;!==&nbsp;<span class="src-id">false</span>&nbsp;||&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$symbol_match</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&gt;'</span><span class="src-sym">)</span>&nbsp;!==&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3394"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;already&nbsp;highlighted&nbsp;blocks&nbsp;_must_&nbsp;include&nbsp;either&nbsp;&lt;&nbsp;or&nbsp;&gt;</span></span></div></li>
+<li><div class="src-line"><a name="a3395"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;so&nbsp;if&nbsp;this&nbsp;conditional&nbsp;applies,&nbsp;we&nbsp;have&nbsp;to&nbsp;skip&nbsp;this&nbsp;match</span></span></div></li>
+<li><div class="src-line"><a name="a3396"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;BenBE:&nbsp;UNLESS&nbsp;the&nbsp;block&nbsp;contains&nbsp;&lt;SEMI&gt;&nbsp;or&nbsp;&lt;PIPE&gt;</span></span></div></li>
+<li><div class="src-line"><a name="a3397"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$symbol_match</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;SEMI&gt;'</span><span class="src-sym">)</span>&nbsp;===&nbsp;<span class="src-id">false</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3398"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$symbol_match</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;PIPE&gt;'</span><span class="src-sym">)</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3399"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3400"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3401"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3402"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3403"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;if&nbsp;we&nbsp;reach&nbsp;this&nbsp;point,&nbsp;we&nbsp;have&nbsp;a&nbsp;valid&nbsp;match&nbsp;which&nbsp;needs&nbsp;to&nbsp;be&nbsp;highlighted</span></span></div></li>
+<li><div class="src-line"><a name="a3404"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a3405"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_length</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$symbol_match</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3406"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_offset</span>&nbsp;=&nbsp;<span class="src-var">$pot_symbols</span><span class="src-sym">[</span><span class="src-var">$s_id</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3407"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$pot_symbols</span><span class="src-sym">[</span><span class="src-var">$s_id</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3408"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_end</span>&nbsp;=&nbsp;<span class="src-var">$symbol_length</span>&nbsp;+&nbsp;<span class="src-var">$symbol_offset</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3409"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;=&nbsp;<span class="src-str">&quot;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3410"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3411"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;if&nbsp;we&nbsp;have&nbsp;multiple&nbsp;styles,&nbsp;we&nbsp;have&nbsp;to&nbsp;handle&nbsp;them&nbsp;properly</span></span></div></li>
+<li><div class="src-line"><a name="a3412"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'MULTIPLE_SYMBOL_GROUPS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3413"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$old_sym</span>&nbsp;=&nbsp;-<span class="src-num">1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3414"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Split&nbsp;the&nbsp;current&nbsp;stuff&nbsp;to&nbsp;replace&nbsp;into&nbsp;its&nbsp;atomic&nbsp;symbols&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3415"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/preg_match_all">preg_match_all</a><span class="src-sym">(</span><span class="src-str">&quot;/&quot;</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_SEARCH'</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">&quot;/&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_match</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$sym_match_syms</span><span class="src-sym">,</span>&nbsp;<span class="src-id">PREG_PATTERN_ORDER</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3416"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$sym_match_syms</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$sym_ms</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3417"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;consequtive&nbsp;symbols&nbsp;belong&nbsp;to&nbsp;the&nbsp;same&nbsp;group&nbsp;to&nbsp;save&nbsp;output&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3418"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$sym_ms</span><span class="src-sym">]</span><span class="src-sym">)</span></span></div></li>
+<li><div class="src-line"><a name="a3419"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$sym_ms</span><span class="src-sym">]</span>&nbsp;!=&nbsp;<span class="src-var">$old_sym</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3420"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>-<span class="src-num">1</span>&nbsp;!=&nbsp;<span class="src-var">$old_sym</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3421"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;.=&nbsp;<span class="src-str">&quot;|&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3422"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3423"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$old_sym</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'SYMBOL_DATA'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$sym_ms</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3424"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3425"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$old_sym</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3426"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3427"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;sy'</span>&nbsp;.&nbsp;<span class="src-var">$old_sym</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3428"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3429"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3430"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;.=&nbsp;<span class="src-var">$sym_ms</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3431"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3432"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$sym_match_syms</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3433"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3434"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Close&nbsp;remaining&nbsp;tags&nbsp;and&nbsp;insert&nbsp;the&nbsp;replacement&nbsp;at&nbsp;the&nbsp;right&nbsp;position&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3435"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Take&nbsp;caution&nbsp;if&nbsp;symbol_hl&nbsp;is&nbsp;empty&nbsp;to&nbsp;avoid&nbsp;doubled&nbsp;closing&nbsp;spans.</span></span></div></li>
+<li><div class="src-line"><a name="a3436"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>-<span class="src-num">1</span>&nbsp;!=&nbsp;<span class="src-var">$old_sym</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3437"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;.=&nbsp;<span class="src-str">&quot;|&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3438"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3439"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3440"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3441"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;=&nbsp;<span class="src-str">'&lt;|&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3442"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3443"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;=&nbsp;<span class="src-str">'&lt;|&nbsp;class=&quot;sy0&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3444"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3445"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$symbol_hl</span>&nbsp;.=&nbsp;<span class="src-var">$symbol_match</span>&nbsp;.&nbsp;<span class="src-str">'|&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3446"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3447"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3448"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr_replace">substr_replace</a><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_hl</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_offset</span>&nbsp;+&nbsp;<span class="src-var">$global_offset</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$symbol_length</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3449"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3450"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;since&nbsp;we&nbsp;replace&nbsp;old&nbsp;text&nbsp;with&nbsp;something&nbsp;of&nbsp;different&nbsp;size,</span></span></div></li>
+<li><div class="src-line"><a name="a3451"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we'll&nbsp;have&nbsp;to&nbsp;keep&nbsp;track&nbsp;of&nbsp;the&nbsp;differences</span></span></div></li>
+<li><div class="src-line"><a name="a3452"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$global_offset</span>&nbsp;+=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$symbol_hl</span><span class="src-sym">)</span>&nbsp;-&nbsp;<span class="src-var">$symbol_length</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3453"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3454"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3455"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//FIX&nbsp;for&nbsp;symbol&nbsp;highlighting&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3456"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a3457"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;class/style&nbsp;for&nbsp;regexps</span></span></div></li>
+<li><div class="src-line"><a name="a3458"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3459"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3460"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_callable">is_callable</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3461"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_rx_key</span>&nbsp;=&nbsp;<span class="src-var">$key</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3462"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace_callback">preg_replace_callback</a><span class="src-sym">(</span><span class="src-str">"</span></span>/!REG3XP<span class="src-var">$key</span>!(.*)\|&gt;/U<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3463"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'handle_regexps_callback'</span><span class="src-sym">)</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a3464"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3465"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3466"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3467"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3468"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3469"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3470"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_key_exists">array_key_exists</a><span class="src-sym">(</span><span class="src-id">GESHI_CLASS</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3471"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;'</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a3472"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-id">GESHI_CLASS</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3473"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3474"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;re'</span>&nbsp;.&nbsp;<span class="src-var">$key</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3475"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3476"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3477"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">"</span></span>!REG3XP<span class="src-var">$key</span>!<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;</span><span class="src-str">&quot;</span><span class="src-var">$attributes</span><span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3478"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3479"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3480"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3481"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3482"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Replace&nbsp;&lt;DOT&gt;&nbsp;with&nbsp;.&nbsp;for&nbsp;urls</span></span></div></li>
+<li><div class="src-line"><a name="a3483"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<span class="src-id">str_replace</span><span class="src-sym">(</span><span class="src-str">'&lt;DOT&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'.'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3484"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Replace&nbsp;&lt;|UR1|&nbsp;with&nbsp;&lt;a&nbsp;href=&nbsp;for&nbsp;urls&nbsp;also</span></span></div></li>
+<li><div class="src-line"><a name="a3485"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">link_styles</span><span class="src-sym">[</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_LINK&quot;&gt;GESHI_LINK&lt;/a&gt;</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3486"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3487"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'&lt;|UR1|'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;a'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">link_target</span>&nbsp;.&nbsp;<span class="src-str">'&nbsp;href='</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3488"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3489"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'&lt;|UR1|'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;a'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">link_target</span>&nbsp;.&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">link_styles</span><span class="src-sym">[</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_LINK&quot;&gt;GESHI_LINK&lt;/a&gt;</span><span class="src-sym">]</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&nbsp;href='</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3490"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3491"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3492"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'&lt;|UR1|'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;a'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">link_target</span>&nbsp;.&nbsp;<span class="src-str">'&nbsp;href='</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3493"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3494"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3495"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a3496"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;NOW&nbsp;we&nbsp;add&nbsp;the&nbsp;span&nbsp;thingy&nbsp;;)</span></span></div></li>
+<li><div class="src-line"><a name="a3497"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//</span></span></div></li>
+<li><div class="src-line"><a name="a3498"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a3499"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">'&lt;|'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;span'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3500"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a>&nbsp;<span class="src-sym">(</span>&nbsp;<span class="src-str">'|&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$stuff_to_parse</span>&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3501"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$stuff_to_parse</span><span class="src-sym">,</span>&nbsp;<span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3502"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3503"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3504"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3505"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;time&nbsp;taken&nbsp;to&nbsp;parse&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a3506"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3507"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;microtime&nbsp;The&nbsp;time&nbsp;when&nbsp;parsing&nbsp;started</span></div></li>
+<li><div class="src-line"><a name="a3508"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;microtime&nbsp;The&nbsp;time&nbsp;when&nbsp;parsing&nbsp;ended</span></div></li>
+<li><div class="src-line"><a name="a3509"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a3510"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3511"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3512"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">set_time</span><span class="src-sym">(</span><span class="src-var">$start_time</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$end_time</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3513"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<a href="http://www.php.net/explode">explode</a><span class="src-sym">(</span><span class="src-str">'&nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$start_time</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3514"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$end</span>&nbsp;=&nbsp;<a href="http://www.php.net/explode">explode</a><span class="src-sym">(</span><span class="src-str">'&nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$end_time</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3515"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="http://www.php.net/time">time</a>&nbsp;=&nbsp;<span class="src-var">$end</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;+&nbsp;<span class="src-var">$end</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span>&nbsp;-&nbsp;<span class="src-var">$start</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span>&nbsp;-&nbsp;<span class="src-var">$start</span><span class="src-sym">[</span><span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3516"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3517"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3518"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3519"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Gets&nbsp;the&nbsp;time&nbsp;taken&nbsp;to&nbsp;parse&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a3520"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3521"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;double&nbsp;The&nbsp;time&nbsp;taken&nbsp;to&nbsp;parse&nbsp;the&nbsp;code</span></div></li>
+<li><div class="src-line"><a name="a3522"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a3523"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3524"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodget_time">get_time</a><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3525"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="http://www.php.net/time">time</a><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3526"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3527"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3528"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3529"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Merges&nbsp;arrays&nbsp;recursively,&nbsp;overwriting&nbsp;values&nbsp;of&nbsp;the&nbsp;first&nbsp;array&nbsp;with&nbsp;values&nbsp;of&nbsp;later&nbsp;arrays</span></div></li>
+<li><div class="src-line"><a name="a3530"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3531"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.8</span></div></li>
+<li><div class="src-line"><a name="a3532"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3533"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3534"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">merge_arrays</span><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3535"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$arrays</span>&nbsp;=&nbsp;<a href="http://www.php.net/func_get_args">func_get_args</a><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3536"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$narrays</span>&nbsp;=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$arrays</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3537"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3538"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;check&nbsp;arguments</span></span></div></li>
+<li><div class="src-line"><a name="a3539"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;comment&nbsp;out&nbsp;if&nbsp;more&nbsp;performance&nbsp;is&nbsp;necessary&nbsp;(in&nbsp;this&nbsp;case&nbsp;the&nbsp;foreach&nbsp;loop&nbsp;will&nbsp;trigger&nbsp;a&nbsp;warning&nbsp;if&nbsp;the&nbsp;argument&nbsp;is&nbsp;not&nbsp;an&nbsp;array)</span></span></div></li>
+<li><div class="src-line"><a name="a3540"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$narrays</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;++<span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3541"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$arrays</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3542"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;also&nbsp;array_merge_recursive&nbsp;returns&nbsp;nothing&nbsp;in&nbsp;this&nbsp;case</span></span></div></li>
+<li><div class="src-line"><a name="a3543"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/trigger_error">trigger_error</a><span class="src-sym">(</span><span class="src-str">'Argument&nbsp;#'</span>&nbsp;.&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>+<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&nbsp;is&nbsp;not&nbsp;an&nbsp;array&nbsp;-&nbsp;trying&nbsp;to&nbsp;merge&nbsp;array&nbsp;with&nbsp;scalar!&nbsp;Returning&nbsp;false!'</span><span class="src-sym">,</span>&nbsp;<span class="src-id">E_USER_WARNING</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3544"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3545"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3546"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3547"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3548"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;first&nbsp;array&nbsp;is&nbsp;in&nbsp;the&nbsp;output&nbsp;set&nbsp;in&nbsp;every&nbsp;case</span></span></div></li>
+<li><div class="src-line"><a name="a3549"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$ret</span>&nbsp;=&nbsp;<span class="src-var">$arrays</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3550"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3551"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;merege&nbsp;$ret&nbsp;with&nbsp;the&nbsp;remaining&nbsp;arrays</span></span></div></li>
+<li><div class="src-line"><a name="a3552"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">1</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$narrays</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;++<span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3553"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$arrays</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$value</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3554"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$value</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;isset<span class="src-sym">(</span><span class="src-var">$ret</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3555"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;if&nbsp;$ret[$key]&nbsp;is&nbsp;not&nbsp;an&nbsp;array&nbsp;you&nbsp;try&nbsp;to&nbsp;merge&nbsp;an&nbsp;scalar&nbsp;value&nbsp;with&nbsp;an&nbsp;array&nbsp;-&nbsp;the&nbsp;result&nbsp;is&nbsp;not&nbsp;defined&nbsp;(incompatible&nbsp;arrays)</span></span></div></li>
+<li><div class="src-line"><a name="a3556"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;in&nbsp;this&nbsp;case&nbsp;the&nbsp;call&nbsp;will&nbsp;trigger&nbsp;an&nbsp;E_USER_WARNING&nbsp;and&nbsp;the&nbsp;$ret[$key]&nbsp;will&nbsp;be&nbsp;false.</span></span></div></li>
+<li><div class="src-line"><a name="a3557"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$ret</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">merge_arrays</span><span class="src-sym">(</span><span class="src-var">$ret</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$value</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3558"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3559"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$ret</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$value</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3560"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3561"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3562"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3563"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3564"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$ret</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3565"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3566"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3567"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3568"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Gets&nbsp;language&nbsp;information&nbsp;and&nbsp;stores&nbsp;it&nbsp;for&nbsp;later&nbsp;use</span></div></li>
+<li><div class="src-line"><a name="a3569"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3570"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;string&nbsp;The&nbsp;filename&nbsp;of&nbsp;the&nbsp;language&nbsp;file&nbsp;you&nbsp;want&nbsp;to&nbsp;load</span></div></li>
+<li><div class="src-line"><a name="a3571"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a3572"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3573"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@todo&nbsp;Needs&nbsp;to&nbsp;load&nbsp;keys&nbsp;for&nbsp;lexic&nbsp;permissions&nbsp;for&nbsp;keywords,&nbsp;regexps&nbsp;etc</span></div></li>
+<li><div class="src-line"><a name="a3574"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3575"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">load_language</span><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3576"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$file_name</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">loaded_language</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3577"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;file&nbsp;is&nbsp;already&nbsp;loaded!</span></span></div></li>
+<li><div class="src-line"><a name="a3578"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3579"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3580"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3581"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Prepare&nbsp;some&nbsp;stuff&nbsp;before&nbsp;actually&nbsp;loading&nbsp;the&nbsp;language&nbsp;file</span></span></div></li>
+<li><div class="src-line"><a name="a3582"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">loaded_language</span>&nbsp;=&nbsp;<span class="src-var">$file_name</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3583"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">parse_cache_built</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3584"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodenable_highlighting">enable_highlighting</a><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3585"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$language_data</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3586"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3587"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Load&nbsp;the&nbsp;language&nbsp;file</span></span></div></li>
+<li><div class="src-line"><a name="a3588"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require&nbsp;<span class="src-var">$file_name</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3589"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3590"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Perhaps&nbsp;some&nbsp;checking&nbsp;might&nbsp;be&nbsp;added&nbsp;here&nbsp;later&nbsp;to&nbsp;check&nbsp;that</span></span></div></li>
+<li><div class="src-line"><a name="a3591"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;$language&nbsp;data&nbsp;is&nbsp;a&nbsp;valid&nbsp;thing&nbsp;but&nbsp;maybe&nbsp;not</span></span></div></li>
+<li><div class="src-line"><a name="a3592"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span>&nbsp;=&nbsp;<span class="src-var">$language_data</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3593"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3594"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;strict&nbsp;mode&nbsp;if&nbsp;should&nbsp;be&nbsp;set</span></span></div></li>
+<li><div class="src-line"><a name="a3595"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">strict_mode</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STRICT_MODE_APPLIES'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3596"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3597"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;permissions&nbsp;for&nbsp;all&nbsp;lexics&nbsp;to&nbsp;true</span></span></div></li>
+<li><div class="src-line"><a name="a3598"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;so&nbsp;they'll&nbsp;be&nbsp;highlighted&nbsp;by&nbsp;default</span></span></div></li>
+<li><div class="src-line"><a name="a3599"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3600"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3601"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3602"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3603"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">false</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3604"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3605"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3606"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3607"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_SINGLE'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3608"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3609"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3610"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/array_keys">array_keys</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">)</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3611"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3612"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3613"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3614"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;for&nbsp;BenBE&nbsp;and&nbsp;future&nbsp;code&nbsp;reviews:</span></span></div></li>
+<li><div class="src-line"><a name="a3615"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;can&nbsp;use&nbsp;empty&nbsp;here&nbsp;since&nbsp;we&nbsp;only&nbsp;check&nbsp;for&nbsp;existance&nbsp;and&nbsp;emptiness&nbsp;of&nbsp;an&nbsp;array</span></span></div></li>
+<li><div class="src-line"><a name="a3616"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;if&nbsp;it&nbsp;is&nbsp;not&nbsp;an&nbsp;array&nbsp;at&nbsp;all&nbsp;but&nbsp;rather&nbsp;false&nbsp;or&nbsp;null&nbsp;this&nbsp;will&nbsp;work&nbsp;as&nbsp;intended&nbsp;as&nbsp;well</span></span></div></li>
+<li><div class="src-line"><a name="a3617"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;even&nbsp;if&nbsp;$this-&gt;language_data['PARSER_CONTROL']&nbsp;is&nbsp;undefined&nbsp;this&nbsp;won't&nbsp;trigger&nbsp;a&nbsp;notice</span></span></div></li>
+<li><div class="src-line"><a name="a3618"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ENABLE_FLAGS'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3619"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ENABLE_FLAGS'</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$flag</span>&nbsp;=&gt;&nbsp;<span class="src-var">$value</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3620"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;it's&nbsp;either&nbsp;true&nbsp;or&nbsp;false&nbsp;and&nbsp;maybe&nbsp;is&nbsp;true&nbsp;as&nbsp;well</span></span></div></li>
+<li><div class="src-line"><a name="a3621"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$perm</span>&nbsp;=&nbsp;<span class="src-var">$value</span>&nbsp;!==&nbsp;<span class="src-id">GESHI_NEVER</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3622"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$flag</span>&nbsp;==&nbsp;<span class="src-str">'ALL'</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3623"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodenable_highlighting">enable_highlighting</a><span class="src-sym">(</span><span class="src-var">$perm</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3624"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3625"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3626"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$flag</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3627"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;unknown&nbsp;lexic&nbsp;permission</span></span></div></li>
+<li><div class="src-line"><a name="a3628"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3629"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3630"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$flag</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3631"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$flag</span><span class="src-sym">]</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$val</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3632"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$flag</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$key</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$perm</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3633"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3634"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3635"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-var">$flag</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$perm</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3636"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3637"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3638"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'PARSER_CONTROL'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ENABLE_FLAGS'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3639"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3640"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3641"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//NEW&nbsp;in&nbsp;1.0.8:&nbsp;Allow&nbsp;styles&nbsp;to&nbsp;be&nbsp;loaded&nbsp;from&nbsp;a&nbsp;separate&nbsp;file&nbsp;to&nbsp;override&nbsp;defaults</span></span></div></li>
+<li><div class="src-line"><a name="a3642"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$style_filename</span>&nbsp;=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$file_name</span><span class="src-sym">,</span>&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;-<span class="src-num">4</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'.style.php'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3643"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/is_readable">is_readable</a><span class="src-sym">(</span><span class="src-var">$style_filename</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3644"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Clear&nbsp;any&nbsp;style_data&nbsp;that&nbsp;could&nbsp;have&nbsp;been&nbsp;set&nbsp;before&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3645"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$style_data</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3646"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$style_data</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3647"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3648"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3649"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Read&nbsp;the&nbsp;Style&nbsp;Information&nbsp;from&nbsp;the&nbsp;style&nbsp;file</span></span></div></li>
+<li><div class="src-line"><a name="a3650"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-inc">include</span>&nbsp;<span class="src-var">$style_filename</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3651"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3652"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Apply&nbsp;the&nbsp;new&nbsp;styles&nbsp;to&nbsp;our&nbsp;current&nbsp;language&nbsp;styles</span></span></div></li>
+<li><div class="src-line"><a name="a3653"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$style_data</span><span class="src-sym">)</span>&nbsp;&amp;&amp;&nbsp;<a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$style_data</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3654"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span>&nbsp;=</span></div></li>
+<li><div class="src-line"><a name="a3655"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">merge_arrays</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$style_data</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3656"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3657"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3658"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3659"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3660"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3661"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Takes&nbsp;the&nbsp;parsed&nbsp;code&nbsp;and&nbsp;various&nbsp;options,&nbsp;and&nbsp;creates&nbsp;the&nbsp;HTML</span></div></li>
+<li><div class="src-line"><a name="a3662"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;surrounding&nbsp;it&nbsp;to&nbsp;make&nbsp;it&nbsp;look&nbsp;nice.</span></div></li>
+<li><div class="src-line"><a name="a3663"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3664"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;string&nbsp;The&nbsp;code&nbsp;already&nbsp;parsed&nbsp;(reference!)</span></div></li>
+<li><div class="src-line"><a name="a3665"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a3666"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3667"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3668"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">finalise</span><span class="src-sym">(</span><span class="src-sym">&</span><span class="src-var">$parsed_code</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3669"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Remove&nbsp;end&nbsp;parts&nbsp;of&nbsp;important&nbsp;declarations</span></span></div></li>
+<li><div class="src-line"><a name="a3670"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;This&nbsp;is&nbsp;BUGGY!!&nbsp;My&nbsp;fault&nbsp;for&nbsp;bad&nbsp;code:&nbsp;fix&nbsp;coming&nbsp;in&nbsp;1.2</span></span></div></li>
+<li><div class="src-line"><a name="a3671"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;@todo&nbsp;Remove&nbsp;this&nbsp;crap</span></span></div></li>
+<li><div class="src-line"><a name="a3672"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodenable_important_blocks">enable_important_blocks</a>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3673"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/strpos">strpos</a><span class="src-sym">(</span><span class="src-var">$parsed_code</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT&quot;&gt;GESHI_START_IMPORTANT&lt;/a&gt;</span><span class="src-sym">))</span>&nbsp;===&nbsp;<span class="src-id">false</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3674"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_END_IMPORTANT&quot;&gt;GESHI_END_IMPORTANT&lt;/a&gt;</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-str">''</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$parsed_code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3675"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3676"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3677"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;HTML&nbsp;whitespace&nbsp;stuff&nbsp;if&nbsp;we're&nbsp;using&nbsp;the&nbsp;&lt;div&gt;&nbsp;header</span></span></div></li>
+<li><div class="src-line"><a name="a3678"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE&quot;&gt;GESHI_HEADER_PRE&lt;/a&gt;</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3679"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">indent</span><span class="src-sym">(</span><span class="src-var">$parsed_code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3680"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3681"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3682"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;purge&nbsp;some&nbsp;unnecessary&nbsp;stuff</span></span></div></li>
+<li><div class="src-line"><a name="a3683"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;NOTE:&nbsp;memorypeak&nbsp;#1&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3684"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span><span class="src-str">'#&lt;span[^&gt;]+&gt;(\s*)&lt;/span&gt;#'</span><span class="src-sym">,</span>&nbsp;<span class="src-str">'\\1'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$parsed_code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3685"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3686"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;we&nbsp;are&nbsp;using&nbsp;IDs&nbsp;for&nbsp;line&nbsp;numbers,&nbsp;there&nbsp;needs&nbsp;to&nbsp;be&nbsp;an&nbsp;overall</span></span></div></li>
+<li><div class="src-line"><a name="a3687"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;ID&nbsp;set&nbsp;to&nbsp;prevent&nbsp;collisions.</span></span></div></li>
+<li><div class="src-line"><a name="a3688"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">add_ids</span>&nbsp;&amp;&amp;&nbsp;<span class="src-sym">!</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3689"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span>&nbsp;=&nbsp;<span class="src-str">'geshi-'</span>&nbsp;.&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><a href="http://www.php.net/md5">md5</a><span class="src-sym">(</span><a href="http://www.php.net/microtime">microtime</a><span class="src-sym">(</span><span class="src-sym">))</span><span class="src-sym">,</span>&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-num">4</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3690"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3691"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3692"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Get&nbsp;code&nbsp;into&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3693"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;NOTE:&nbsp;memorypeak&nbsp;#2&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3694"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$code</span>&nbsp;=&nbsp;<a href="http://www.php.net/explode">explode</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$parsed_code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3695"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="http://www.php.net/header">header</a><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3696"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3697"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;we're&nbsp;using&nbsp;line&nbsp;numbers,&nbsp;we&nbsp;insert&nbsp;&lt;li&gt;s&nbsp;and&nbsp;appropriate</span></span></div></li>
+<li><div class="src-line"><a name="a3698"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;markup&nbsp;to&nbsp;style&nbsp;them&nbsp;(otherwise&nbsp;we&nbsp;don't&nbsp;need&nbsp;to&nbsp;do&nbsp;anything)</span></span></div></li>
+<li><div class="src-line"><a name="a3699"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE&quot;&gt;GESHI_HEADER_PRE_TABLE&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3700"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;we're&nbsp;using&nbsp;the&nbsp;&lt;pre&gt;&nbsp;header,&nbsp;we&nbsp;shouldn't&nbsp;add&nbsp;newlines&nbsp;because</span></span></div></li>
+<li><div class="src-line"><a name="a3701"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;&lt;pre&gt;&nbsp;will&nbsp;line-break&nbsp;them&nbsp;(and&nbsp;the&nbsp;&lt;li&gt;s&nbsp;already&nbsp;do&nbsp;this&nbsp;for&nbsp;us)</span></span></div></li>
+<li><div class="src-line"><a name="a3702"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$ls</span>&nbsp;=&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE&quot;&gt;GESHI_HEADER_PRE&lt;/a&gt;</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-str">&quot;\n&quot;</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3703"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3704"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;vars&nbsp;to&nbsp;defaults&nbsp;for&nbsp;following&nbsp;loop</span></span></div></li>
+<li><div class="src-line"><a name="a3705"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3706"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3707"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Foreach&nbsp;line...</span></span></div></li>
+<li><div class="src-line"><a name="a3708"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$n</span>&nbsp;=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$n</span><span class="src-sym">;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3709"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Reset&nbsp;the&nbsp;attributes&nbsp;for&nbsp;a&nbsp;new&nbsp;line&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a3710"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3711"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3712"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Make&nbsp;lines&nbsp;have&nbsp;at&nbsp;least&nbsp;one&nbsp;space&nbsp;in&nbsp;them&nbsp;if&nbsp;they're&nbsp;empty</span></span></div></li>
+<li><div class="src-line"><a name="a3713"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;BenBE:&nbsp;Checking&nbsp;emptiness&nbsp;using&nbsp;trim&nbsp;instead&nbsp;of&nbsp;relying&nbsp;on&nbsp;blanks</span></span></div></li>
+<li><div class="src-line"><a name="a3714"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-str">''</span>&nbsp;==&nbsp;<a href="http://www.php.net/trim">trim</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3715"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&amp;nbsp;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3716"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3717"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3718"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;this&nbsp;is&nbsp;a&nbsp;&quot;special&nbsp;line&quot;...</span></span></div></li>
+<li><div class="src-line"><a name="a3719"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS&quot;&gt;GESHI_FANCY_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3720"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;%&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_nth_row</span>&nbsp;==&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_nth_row</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3721"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;the&nbsp;attributes&nbsp;to&nbsp;style&nbsp;the&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3722"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3723"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$attr&nbsp;=&nbsp;'&nbsp;class=&quot;li2&quot;';</span></span></div></li>
+<li><div class="src-line"><a name="a3724"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'class'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'li2'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3725"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$def_attr</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;de2&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3726"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3727"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$attr&nbsp;=&nbsp;'&nbsp;style=&quot;'&nbsp;.&nbsp;$this-&gt;line_style2&nbsp;.&nbsp;'&quot;';</span></span></div></li>
+<li><div class="src-line"><a name="a3728"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'style'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_style2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3729"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;This&nbsp;style&nbsp;&quot;covers&nbsp;up&quot;&nbsp;the&nbsp;special&nbsp;styles&nbsp;set&nbsp;for&nbsp;special&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3730"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;so&nbsp;that&nbsp;styles&nbsp;applied&nbsp;to&nbsp;special&nbsp;lines&nbsp;don't&nbsp;apply&nbsp;to&nbsp;the&nbsp;actual</span></span></div></li>
+<li><div class="src-line"><a name="a3731"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;code&nbsp;on&nbsp;that&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3732"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$def_attr</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">code_style</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3733"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3734"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3735"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3736"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$attr&nbsp;=&nbsp;'&nbsp;class=&quot;li1&quot;';</span></span></div></li>
+<li><div class="src-line"><a name="a3737"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'class'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'li1'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3738"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$def_attr</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;de1&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3739"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3740"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$attr&nbsp;=&nbsp;'&nbsp;style=&quot;'&nbsp;.&nbsp;$this-&gt;line_style1&nbsp;.&nbsp;'&quot;';</span></span></div></li>
+<li><div class="src-line"><a name="a3741"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'style'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_style1</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3742"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$def_attr</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">code_style</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3743"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3744"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3745"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3746"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;which&nbsp;type&nbsp;of&nbsp;tag&nbsp;to&nbsp;insert&nbsp;for&nbsp;this&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3747"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3748"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;pre<span class="src-var">$def_attr</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3749"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$end</span>&nbsp;=&nbsp;<span class="src-str">'&lt;/pre&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3750"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3751"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Span&nbsp;or&nbsp;div?</span></span></div></li>
+<li><div class="src-line"><a name="a3752"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$start</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&lt;div<span class="src-var">$def_attr</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3753"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$end</span>&nbsp;=&nbsp;<span class="src-str">'&lt;/div&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3754"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3755"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3756"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3757"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3758"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Are&nbsp;we&nbsp;supposed&nbsp;to&nbsp;use&nbsp;ids?&nbsp;If&nbsp;so,&nbsp;add&nbsp;them</span></span></div></li>
+<li><div class="src-line"><a name="a3759"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">add_ids</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3760"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'id'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">"</span></span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span>-<span class="src-var">$i</span><span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3761"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3762"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3763"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Is&nbsp;this&nbsp;some&nbsp;line&nbsp;with&nbsp;extra&nbsp;styles???</span></span></div></li>
+<li><div class="src-line"><a name="a3764"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">in_array</span><span class="src-sym">(</span><span class="src-var">$i</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3765"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3766"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3767"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'class'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>lx<span class="src-var">$i</span><span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3768"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3769"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'class'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">&quot;ln-xtra&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3770"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3771"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3772"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_push">array_push</a><span class="src-sym">(</span><span class="src-var">$attrs</span><span class="src-sym">[</span><span class="src-str">'style'</span><span class="src-sym">]</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">get_line_style</span><span class="src-sym">(</span><span class="src-var">$i</span><span class="src-sym">))</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3773"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3774"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3775"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3776"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;in&nbsp;the&nbsp;line&nbsp;surrounded&nbsp;by&nbsp;appropriate&nbsp;list&nbsp;HTML</span></span></div></li>
+<li><div class="src-line"><a name="a3777"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attr_string</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3778"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$attrs</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$attr</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3779"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attr_string</span>&nbsp;.=&nbsp;<span class="src-str">'&nbsp;'</span>&nbsp;.&nbsp;<span class="src-var">$key</span>&nbsp;.&nbsp;<span class="src-str">'=&quot;'</span>&nbsp;.&nbsp;<a href="http://www.php.net/implode">implode</a><span class="src-sym">(</span><span class="src-str">'&nbsp;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$attr</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3780"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3781"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3782"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;li<span class="src-var">$attr_string</span>&gt;<span class="src-var">$start</span>{<span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span>-<span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">}</span><span class="src-var">$end</span>&lt;/li&gt;<span class="src-var">$ls</span><span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3783"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3784"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3785"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3786"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$n</span>&nbsp;=&nbsp;<span class="src-id">count</span><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3787"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3788"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;de1&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3789"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3790"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">code_style</span>&nbsp;.<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3791"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3792"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3793"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;pre'</span>.&nbsp;<span class="src-var">$attributes</span>&nbsp;.<span class="src-str">'&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3794"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">elseif</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE&quot;&gt;GESHI_HEADER_PRE_TABLE&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3795"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3796"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3797"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;ln&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3798"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3799"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attrs</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">table_linenumber_style</span>&nbsp;.<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3800"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3801"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;td'</span>.<span class="src-var">$attrs</span>.<span class="src-str">'&gt;&lt;pre'</span>.<span class="src-var">$attributes</span>.<span class="src-str">'&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3802"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;get&nbsp;linenumbers</span></span></div></li>
+<li><div class="src-line"><a name="a3803"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;don't&nbsp;merge&nbsp;it&nbsp;with&nbsp;the&nbsp;for&nbsp;below,&nbsp;since&nbsp;it&nbsp;should&nbsp;be&nbsp;better&nbsp;for</span></span></div></li>
+<li><div class="src-line"><a name="a3804"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;memory&nbsp;consumption&nbsp;this&nbsp;way</span></span></div></li>
+<li><div class="src-line"><a name="a3805"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;@todo:&nbsp;but...&nbsp;actually&nbsp;it&nbsp;would&nbsp;still&nbsp;be&nbsp;somewhat&nbsp;nice&nbsp;to&nbsp;merge&nbsp;the&nbsp;two&nbsp;loops</span></span></div></li>
+<li><div class="src-line"><a name="a3806"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;mem&nbsp;peaks&nbsp;are&nbsp;at&nbsp;different&nbsp;positions</span></span></div></li>
+<li><div class="src-line"><a name="a3807"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$n</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3808"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3809"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;fancy&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3810"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS&quot;&gt;GESHI_FANCY_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3811"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;%&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_nth_row</span>&nbsp;==&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_nth_row</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3812"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;the&nbsp;attributes&nbsp;to&nbsp;style&nbsp;the&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3813"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3814"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;span&nbsp;class=&quot;xtra&nbsp;li2&quot;&gt;&lt;span&nbsp;class=&quot;de2&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3815"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3816"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;This&nbsp;style&nbsp;&quot;covers&nbsp;up&quot;&nbsp;the&nbsp;special&nbsp;styles&nbsp;set&nbsp;for&nbsp;special&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3817"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;so&nbsp;that&nbsp;styles&nbsp;applied&nbsp;to&nbsp;special&nbsp;lines&nbsp;don't&nbsp;apply&nbsp;to&nbsp;the&nbsp;actual</span></span></div></li>
+<li><div class="src-line"><a name="a3818"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;code&nbsp;on&nbsp;that&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3819"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;span&nbsp;style=&quot;display:block;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_style2</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;'</span></span></div></li>
+<li><div class="src-line"><a name="a3820"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span class="src-str">'&lt;span&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">code_style</span>&nbsp;.<span class="src-str">'&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3821"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3822"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close</span>&nbsp;+=&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3823"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3824"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Is&nbsp;this&nbsp;some&nbsp;line&nbsp;with&nbsp;extra&nbsp;styles???</span></span></div></li>
+<li><div class="src-line"><a name="a3825"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3826"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3827"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3828"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span&nbsp;class=\&quot;xtra&nbsp;lx<span class="src-var">$i</span>\&quot;&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3829"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3830"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&lt;span&nbsp;class=\&quot;xtra&nbsp;ln-xtra\&quot;&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3831"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3832"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3833"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&lt;span&nbsp;style=\&quot;display:block;&quot;</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">get_line_style</span><span class="src-sym">(</span><span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">&quot;\&quot;&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3834"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3835"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$close</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3836"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3837"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers_start</span>&nbsp;+&nbsp;<span class="src-var">$i</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3838"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3839"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<a href="http://www.php.net/str_repeat">str_repeat</a><span class="src-sym">(</span><span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3840"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;!=&nbsp;<span class="src-var">$n</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3841"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3842"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3843"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3844"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;/pre&gt;&lt;/td&gt;&lt;td'</span>.<span class="src-var">$attributes</span>.<span class="src-str">'&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3845"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3846"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;pre'</span>.&nbsp;<span class="src-var">$attributes</span>&nbsp;.<span class="src-str">'&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3847"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3848"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;No&nbsp;line&nbsp;numbers,&nbsp;but&nbsp;still&nbsp;need&nbsp;to&nbsp;handle&nbsp;highlighting&nbsp;lines&nbsp;extra.</span></span></div></li>
+<li><div class="src-line"><a name="a3849"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Have&nbsp;to&nbsp;use&nbsp;divs&nbsp;so&nbsp;the&nbsp;full&nbsp;width&nbsp;of&nbsp;the&nbsp;code&nbsp;is&nbsp;highlighted</span></span></div></li>
+<li><div class="src-line"><a name="a3850"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3851"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span>&nbsp;<span class="src-var">$i</span>&nbsp;<&nbsp;<span class="src-var">$n</span><span class="src-sym">;</span>&nbsp;++<span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3852"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Make&nbsp;lines&nbsp;have&nbsp;at&nbsp;least&nbsp;one&nbsp;space&nbsp;in&nbsp;them&nbsp;if&nbsp;they're&nbsp;empty</span></span></div></li>
+<li><div class="src-line"><a name="a3853"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;BenBE:&nbsp;Checking&nbsp;emptiness&nbsp;using&nbsp;trim&nbsp;instead&nbsp;of&nbsp;relying&nbsp;on&nbsp;blanks</span></span></div></li>
+<li><div class="src-line"><a name="a3854"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-str">''</span>&nbsp;==&nbsp;<a href="http://www.php.net/trim">trim</a><span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3855"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&amp;nbsp;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3856"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3857"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;fancy&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3858"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS&quot;&gt;GESHI_FANCY_LINE_NUMBERS&lt;/a&gt;</span>&nbsp;&amp;&amp;</span></div></li>
+<li><div class="src-line"><a name="a3859"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$i</span>&nbsp;%&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_nth_row</span>&nbsp;==&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_nth_row</span>&nbsp;-&nbsp;<span class="src-num">1</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3860"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;the&nbsp;attributes&nbsp;to&nbsp;style&nbsp;the&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3861"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3862"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;span&nbsp;class=&quot;xtra&nbsp;li2&quot;&gt;&lt;span&nbsp;class=&quot;de2&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3863"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3864"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;This&nbsp;style&nbsp;&quot;covers&nbsp;up&quot;&nbsp;the&nbsp;special&nbsp;styles&nbsp;set&nbsp;for&nbsp;special&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a3865"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;so&nbsp;that&nbsp;styles&nbsp;applied&nbsp;to&nbsp;special&nbsp;lines&nbsp;don't&nbsp;apply&nbsp;to&nbsp;the&nbsp;actual</span></span></div></li>
+<li><div class="src-line"><a name="a3866"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;code&nbsp;on&nbsp;that&nbsp;line</span></span></div></li>
+<li><div class="src-line"><a name="a3867"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;span&nbsp;style=&quot;display:block;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_style2</span>&nbsp;.&nbsp;<span class="src-str">'&quot;&gt;'</span></span></div></li>
+<li><div class="src-line"><a name="a3868"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span class="src-str">'&lt;span&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">code_style</span>&nbsp;.<span class="src-str">'&quot;&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3869"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3870"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close</span>&nbsp;+=&nbsp;<span class="src-num">2</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3871"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3872"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Is&nbsp;this&nbsp;some&nbsp;line&nbsp;with&nbsp;extra&nbsp;styles???</span></span></div></li>
+<li><div class="src-line"><a name="a3873"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">1</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3874"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3875"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3876"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&lt;span&nbsp;class=\&quot;xtra&nbsp;lx<span class="src-var">$i</span>\&quot;&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3877"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3878"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&lt;span&nbsp;class=\&quot;xtra&nbsp;ln-xtra\&quot;&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3879"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3880"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3881"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&lt;span&nbsp;style=\&quot;display:block;&quot;</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">get_line_style</span><span class="src-sym">(</span><span class="src-var">$i</span><span class="src-sym">)</span>&nbsp;.&nbsp;<span class="src-str">&quot;\&quot;&gt;&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3882"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3883"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$close</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3884"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3885"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3886"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3887"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3888"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$close</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3889"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<a href="http://www.php.net/str_repeat">str_repeat</a><span class="src-sym">(</span><span class="src-str">'&lt;/span&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$close</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3890"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close</span>&nbsp;=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3891"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3892"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">elseif</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$i</span>&nbsp;+&nbsp;<span class="src-num">1</span>&nbsp;<&nbsp;<span class="src-var">$n</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3893"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">&quot;\n&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3894"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3895"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$code</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3896"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3897"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3898"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span>&nbsp;||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE&quot;&gt;GESHI_HEADER_PRE_TABLE&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3899"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;/pre&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3900"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3901"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE&quot;&gt;GESHI_HEADER_PRE_TABLE&lt;/a&gt;</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3902"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-str">'&lt;/td&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3903"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3904"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3905"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3906"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$parsed_code</span>&nbsp;.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">footer</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3907"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3908"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3909"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3910"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Creates&nbsp;the&nbsp;header&nbsp;for&nbsp;the&nbsp;code&nbsp;block&nbsp;(with&nbsp;correct&nbsp;attributes)</span></div></li>
+<li><div class="src-line"><a name="a3911"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3912"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;The&nbsp;header&nbsp;for&nbsp;the&nbsp;code&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a3913"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a3914"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3915"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3916"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="http://www.php.net/header">header</a><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3917"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Get&nbsp;attributes&nbsp;needed</span></span></div></li>
+<li><div class="src-line"><a name="a3918"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3919"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@todo&nbsp;&nbsp;&nbsp;Document&nbsp;behaviour&nbsp;change&nbsp;-&nbsp;class&nbsp;is&nbsp;outputted&nbsp;regardless&nbsp;of&nbsp;whether</span></div></li>
+<li><div class="src-line"><a name="a3920"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;we're&nbsp;using&nbsp;classes&nbsp;or&nbsp;not.&nbsp;Same&nbsp;with&nbsp;style</span></div></li>
+<li><div class="src-line"><a name="a3921"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3922"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3923"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_class</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3924"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;.=&nbsp;<span class="src-str">&quot;&nbsp;&quot;</span>.<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_class</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3925"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3926"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;.=&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3927"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3928"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3929"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span>&nbsp;id=\&quot;{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span><span class="src-sym">}</span>\&quot;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3930"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3931"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_style</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3932"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attributes</span>&nbsp;.=&nbsp;<span class="src-str">'&nbsp;style=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_style</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3933"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3934"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3935"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$ol_attributes</span>&nbsp;=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3936"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3937"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers_start</span>&nbsp;!=&nbsp;<span class="src-num">1</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3938"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$ol_attributes</span>&nbsp;.=&nbsp;<span class="src-str">'&nbsp;start=&quot;'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers_start</span>&nbsp;.&nbsp;<span class="src-str">'&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3939"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3940"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3941"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Get&nbsp;the&nbsp;header&nbsp;HTML</span></span></div></li>
+<li><div class="src-line"><a name="a3942"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$header</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_content</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3943"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$header</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3944"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE&quot;&gt;GESHI_HEADER_PRE&lt;/a&gt;</span>&nbsp;||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3945"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$header</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">''</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$header</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3946"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3947"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$header</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">replace_keywords</span><span class="src-sym">(</span><span class="src-var">$header</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3948"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3949"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3950"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attr</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;head&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3951"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3952"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attr</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&nbsp;style=\&quot;{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_content_style</span><span class="src-sym">}</span>\&quot;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3953"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3954"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_PRE_TABLE</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3955"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$header</span>&nbsp;=&nbsp;</span><span class="src-str">&quot;</span>&lt;thead&gt;&lt;tr&gt;&lt;td&nbsp;colspan=\&quot;2\&quot;&nbsp;<span class="src-var">$attr</span>&gt;<span class="src-var">$header</span>&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3956"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3957"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$header</span>&nbsp;=&nbsp;</span><span class="src-str">&quot;</span>&lt;div<span class="src-var">$attr</span>&gt;<span class="src-var">$header</span>&lt;/div&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3958"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3959"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3960"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3961"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_HEADER_NONE</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3962"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3963"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;</span><span class="src-str">&quot;</span><span class="src-var">$header</span>&lt;ol<span class="src-var">$attributes$ol_attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3964"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3965"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-var">$header</span>&nbsp;.&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">force_code_block</span>&nbsp;?&nbsp;<span class="src-str">'&lt;div&gt;'</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3966"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3967"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3968"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Work&nbsp;out&nbsp;what&nbsp;to&nbsp;return&nbsp;and&nbsp;do&nbsp;it</span></span></div></li>
+<li><div class="src-line"><a name="a3969"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3970"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE&quot;&gt;GESHI_HEADER_PRE&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3971"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-str">"</span></span>&lt;pre<span class="src-var">$attributes</span>&gt;<span class="src-var">$header</span>&lt;ol<span class="src-var">$ol_attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3972"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_DIV</span>&nbsp;||</span></div></li>
+<li><div class="src-line"><a name="a3973"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_PRE_VALID</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3974"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;</span><span class="src-str">&quot;</span>&lt;div<span class="src-var">$attributes</span>&gt;<span class="src-var">$header</span>&lt;ol<span class="src-var">$ol_attributes</span>&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3975"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_PRE_TABLE</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3976"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;</span><span class="src-str">&quot;</span>&lt;table<span class="src-var">$attributes</span>&gt;<span class="src-var">$header</span>&lt;tbody&gt;&lt;tr&nbsp;class=\&quot;li1\&quot;&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3977"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3978"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3979"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_PRE</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3980"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;</span><span class="src-str">&quot;</span>&lt;pre<span class="src-var">$attributes</span>&gt;<span class="src-var">$header</span><span class="src-str">&quot;&nbsp;&nbsp;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a3981"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">force_code_block</span>&nbsp;?&nbsp;<span class="src-str">'&lt;div&gt;'</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3982"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3983"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-str">"</span></span>&lt;div<span class="src-var">$attributes</span>&gt;<span class="src-var">$header</span><span class="src-str">&quot;&nbsp;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a3984"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">force_code_block</span>&nbsp;?&nbsp;<span class="src-str">'&lt;div&gt;'</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3985"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3986"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3987"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a3988"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a3989"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a3990"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;the&nbsp;footer&nbsp;for&nbsp;the&nbsp;code&nbsp;block.</span></div></li>
+<li><div class="src-line"><a name="a3991"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a3992"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;The&nbsp;footer&nbsp;for&nbsp;the&nbsp;code&nbsp;block</span></div></li>
+<li><div class="src-line"><a name="a3993"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a3994"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a3995"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a3996"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">footer</span><span class="src-sym">(</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3997"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$footer</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">footer_content</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a3998"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$footer</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a3999"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE&quot;&gt;GESHI_HEADER_PRE&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4000"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$footer</span>&nbsp;=&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-str">&quot;\n&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-str">''</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$footer</span><span class="src-sym">)</span><span class="src-sym">;;</span></span></div></li>
+<li><div class="src-line"><a name="a4001"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4002"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$footer</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">replace_keywords</span><span class="src-sym">(</span><span class="src-var">$footer</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4003"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4004"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">use_classes</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4005"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attr</span>&nbsp;=&nbsp;<span class="src-str">'&nbsp;class=&quot;foot&quot;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4006"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4007"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$attr</span>&nbsp;=&nbsp;<span class="src-str">"</span></span>&nbsp;style=\&quot;{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">footer_content_style</span><span class="src-sym">}</span>\&quot;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4008"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4009"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_PRE_TABLE</span>&nbsp;&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">linenumbers</span>&nbsp;!=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4010"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$footer</span>&nbsp;=&nbsp;</span><span class="src-str">&quot;</span>&lt;tfoot&gt;&lt;tr&gt;&lt;td&nbsp;colspan=\&quot;2\&quot;&gt;<span class="src-var">$footer</span>&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4011"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4012"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$footer</span>&nbsp;=&nbsp;</span><span class="src-str">&quot;</span>&lt;div<span class="src-var">$attr</span>&gt;<span class="src-var">$footer</span>&lt;/div&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4013"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4014"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4015"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4016"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-id">GESHI_HEADER_NONE</span>&nbsp;==&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4017"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">)</span>&nbsp;?&nbsp;<span class="src-str">'&lt;/ol&gt;'</span>&nbsp;.&nbsp;<span class="src-var">$footer</span>&nbsp;:&nbsp;<span class="src-var">$footer</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4018"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4019"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4020"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_DIV&quot;&gt;GESHI_HEADER_DIV&lt;/a&gt;</span>&nbsp;||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID&quot;&gt;GESHI_HEADER_PRE_VALID&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4021"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4022"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-str">"</span></span>&lt;/ol&gt;<span class="src-var">$footer</span>&lt;/div&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4023"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4024"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">force_code_block</span>&nbsp;?&nbsp;<span class="src-str">'&lt;/div&gt;'</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a4025"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">"</span></span><span class="src-var">$footer</span>&lt;/div&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4026"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4027"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">elseif</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_type</span>&nbsp;==&nbsp;<span class="src-id">GESHI_HEADER_PRE_TABLE</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4028"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4029"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;</span><span class="src-str">&quot;</span>&lt;/tr&gt;&lt;/tbody&gt;<span class="src-var">$footer</span>&lt;/table&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4030"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4031"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">force_code_block</span>&nbsp;?&nbsp;<span class="src-str">'&lt;/div&gt;'</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a4032"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">"</span></span><span class="src-var">$footer</span>&lt;/div&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4033"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4034"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4035"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">GESHI_NO_LINE_NUMBERS</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4036"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;</span><span class="src-str">&quot;</span>&lt;/ol&gt;<span class="src-var">$footer</span>&lt;/pre&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4037"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4038"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">force_code_block</span>&nbsp;?&nbsp;<span class="src-str">'&lt;/div&gt;'</span>&nbsp;:&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a4039"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">"</span></span><span class="src-var">$footer</span>&lt;/pre&gt;<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4040"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4041"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4042"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4043"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a4044"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Replaces&nbsp;certain&nbsp;keywords&nbsp;in&nbsp;the&nbsp;header&nbsp;and&nbsp;footer&nbsp;with</span></div></li>
+<li><div class="src-line"><a name="a4045"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;certain&nbsp;configuration&nbsp;values</span></div></li>
+<li><div class="src-line"><a name="a4046"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4047"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;string&nbsp;The&nbsp;header&nbsp;or&nbsp;footer&nbsp;content&nbsp;to&nbsp;do&nbsp;replacement&nbsp;on</span></div></li>
+<li><div class="src-line"><a name="a4048"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;The&nbsp;header&nbsp;or&nbsp;footer&nbsp;with&nbsp;replaced&nbsp;keywords</span></div></li>
+<li><div class="src-line"><a name="a4049"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.2</span></div></li>
+<li><div class="src-line"><a name="a4050"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a4051"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a4052"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">replace_keywords</span><span class="src-sym">(</span><span class="src-var">$instr</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4053"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span>&nbsp;=&nbsp;<span class="src-var">$replacements</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4054"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4055"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&lt;TIME&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4056"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'{TIME}'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4057"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<a href="http://www.php.net/number_format">number_format</a><span class="src-sym">(</span><span class="src-var">$time</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodget_time">get_time</a><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">,</span>&nbsp;<span class="src-num">3</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4058"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4059"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&lt;LANGUAGE&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4060"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'{LANGUAGE}'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4061"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'LANG_NAME'</span><span class="src-sym">]</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4062"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4063"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&lt;VERSION&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4064"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'{VERSION}'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4065"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_VERSION&quot;&gt;GESHI_VERSION&lt;/a&gt;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4066"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4067"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&lt;SPEED&gt;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4068"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$keywords</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'{SPEED}'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4069"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$time</span>&nbsp;&lt;=&nbsp;<span class="src-num">0</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4070"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$speed</span>&nbsp;=&nbsp;<span class="src-str">'N/A'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4071"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4072"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$speed</span>&nbsp;=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">source</span><span class="src-sym">)</span>&nbsp;/&nbsp;<span class="src-var">$time</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4073"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$speed</span>&nbsp;&gt;=&nbsp;<span class="src-num">1024</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4074"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$speed</span>&nbsp;=&nbsp;<a href="http://www.php.net/sprintf">sprintf</a><span class="src-sym">(</span><span class="src-str">&quot;%.2f&nbsp;KB/s&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$speed</span>&nbsp;/&nbsp;<span class="src-num">1024.0</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4075"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4076"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$speed</span>&nbsp;=&nbsp;<a href="http://www.php.net/sprintf">sprintf</a><span class="src-sym">(</span><span class="src-str">&quot;%.0f&nbsp;B/s&quot;</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$speed</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4077"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4078"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4079"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$replacements</span><span class="src-sym">[</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-var">$speed</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4080"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4081"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<a href="http://www.php.net/str_replace">str_replace</a><span class="src-sym">(</span><span class="src-var">$keywords</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$replacements</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$instr</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4082"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4083"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4084"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a4085"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Secure&nbsp;replacement&nbsp;for&nbsp;PHP&nbsp;built-in&nbsp;function&nbsp;htmlspecialchars().</span></div></li>
+<li><div class="src-line"><a name="a4086"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4087"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;See&nbsp;ticket&nbsp;#427&nbsp;(http://wush.net/trac/wikka/ticket/427)&nbsp;for&nbsp;the&nbsp;rationale</span></div></li>
+<li><div class="src-line"><a name="a4088"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;for&nbsp;this&nbsp;replacement&nbsp;function.</span></div></li>
+<li><div class="src-line"><a name="a4089"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4090"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;INTERFACE&nbsp;for&nbsp;this&nbsp;function&nbsp;is&nbsp;almost&nbsp;the&nbsp;same&nbsp;as&nbsp;that&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a4091"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;htmlspecialchars(),&nbsp;with&nbsp;the&nbsp;same&nbsp;default&nbsp;for&nbsp;quote&nbsp;style;&nbsp;however,&nbsp;there</span></div></li>
+<li><div class="src-line"><a name="a4092"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;is&nbsp;no&nbsp;'charset'&nbsp;parameter.&nbsp;The&nbsp;reason&nbsp;for&nbsp;this&nbsp;is&nbsp;as&nbsp;follows:</span></div></li>
+<li><div class="src-line"><a name="a4093"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4094"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;PHP&nbsp;docs&nbsp;say:</span></div></li>
+<li><div class="src-line"><a name="a4095"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;The&nbsp;third&nbsp;argument&nbsp;charset&nbsp;defines&nbsp;character&nbsp;set&nbsp;used&nbsp;in&nbsp;conversion.&quot;</span></div></li>
+<li><div class="src-line"><a name="a4096"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4097"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;I&nbsp;suspect&nbsp;PHP's&nbsp;htmlspecialchars()&nbsp;is&nbsp;working&nbsp;at&nbsp;the&nbsp;byte-value&nbsp;level&nbsp;and</span></div></li>
+<li><div class="src-line"><a name="a4098"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;thus&nbsp;_needs_&nbsp;to&nbsp;know&nbsp;(or&nbsp;asssume)&nbsp;a&nbsp;character&nbsp;set&nbsp;because&nbsp;the&nbsp;special</span></div></li>
+<li><div class="src-line"><a name="a4099"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;characters&nbsp;to&nbsp;be&nbsp;replaced&nbsp;could&nbsp;exist&nbsp;at&nbsp;different&nbsp;code&nbsp;points&nbsp;in</span></div></li>
+<li><div class="src-line"><a name="a4100"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;different&nbsp;character&nbsp;sets.&nbsp;(If&nbsp;indeed&nbsp;htmlspecialchars()&nbsp;works&nbsp;at</span></div></li>
+<li><div class="src-line"><a name="a4101"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;byte-value&nbsp;level&nbsp;that&nbsp;goes&nbsp;some&nbsp;&nbsp;way&nbsp;towards&nbsp;explaining&nbsp;why&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a4102"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;vulnerability&nbsp;would&nbsp;exist&nbsp;in&nbsp;this&nbsp;function,&nbsp;too,&nbsp;and&nbsp;not&nbsp;only&nbsp;in</span></div></li>
+<li><div class="src-line"><a name="a4103"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;htmlentities()&nbsp;which&nbsp;certainly&nbsp;is&nbsp;working&nbsp;at&nbsp;byte-value&nbsp;level.)</span></div></li>
+<li><div class="src-line"><a name="a4104"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4105"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;replacement&nbsp;function&nbsp;however&nbsp;works&nbsp;at&nbsp;character&nbsp;level&nbsp;and&nbsp;should</span></div></li>
+<li><div class="src-line"><a name="a4106"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;therefore&nbsp;be&nbsp;&quot;immune&quot;&nbsp;to&nbsp;character&nbsp;set&nbsp;differences&nbsp;-&nbsp;so&nbsp;no&nbsp;charset</span></div></li>
+<li><div class="src-line"><a name="a4107"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;parameter&nbsp;is&nbsp;needed&nbsp;or&nbsp;provided.&nbsp;If&nbsp;a&nbsp;third&nbsp;parameter&nbsp;is&nbsp;passed,&nbsp;it&nbsp;will</span></div></li>
+<li><div class="src-line"><a name="a4108"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;be&nbsp;silently&nbsp;ignored.</span></div></li>
+<li><div class="src-line"><a name="a4109"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4110"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;In&nbsp;the&nbsp;OUTPUT&nbsp;there&nbsp;is&nbsp;a&nbsp;minor&nbsp;difference&nbsp;in&nbsp;that&nbsp;we&nbsp;use&nbsp;'&amp;#39;'&nbsp;instead</span></div></li>
+<li><div class="src-line"><a name="a4111"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;of&nbsp;PHP's&nbsp;'&amp;#039;'&nbsp;for&nbsp;a&nbsp;single&nbsp;quote:&nbsp;this&nbsp;provides&nbsp;compatibility&nbsp;with</span></div></li>
+<li><div class="src-line"><a name="a4112"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get_html_translation_table(HTML_SPECIALCHARS,&nbsp;ENT_QUOTES)</span></div></li>
+<li><div class="src-line"><a name="a4113"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;(see&nbsp;comment&nbsp;by&nbsp;mikiwoz&nbsp;at&nbsp;yahoo&nbsp;dot&nbsp;co&nbsp;dot&nbsp;uk&nbsp;on</span></div></li>
+<li><div class="src-line"><a name="a4114"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;http://php.net/htmlspecialchars);&nbsp;it&nbsp;also&nbsp;matches&nbsp;the&nbsp;entity&nbsp;definition</span></div></li>
+<li><div class="src-line"><a name="a4115"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;for&nbsp;XML&nbsp;1.0</span></div></li>
+<li><div class="src-line"><a name="a4116"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;(http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters).</span></div></li>
+<li><div class="src-line"><a name="a4117"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Like&nbsp;PHP&nbsp;we&nbsp;use&nbsp;a&nbsp;numeric&nbsp;character&nbsp;reference&nbsp;instead&nbsp;of&nbsp;'&amp;apos;'&nbsp;for&nbsp;the</span></div></li>
+<li><div class="src-line"><a name="a4118"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;single&nbsp;quote.&nbsp;For&nbsp;the&nbsp;other&nbsp;special&nbsp;characters&nbsp;we&nbsp;use&nbsp;the&nbsp;named&nbsp;entity</span></div></li>
+<li><div class="src-line"><a name="a4119"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;references,&nbsp;as&nbsp;PHP&nbsp;is&nbsp;doing.</span></div></li>
+<li><div class="src-line"><a name="a4120"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4121"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{@link&nbsp;http://wikkawiki.org/JavaWoman&nbsp;Marjolein&nbsp;Katsma}</span></div></li>
+<li><div class="src-line"><a name="a4122"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4123"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@license&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.gnu.org/copyleft/lgpl.html</span></div></li>
+<li><div class="src-line"><a name="a4124"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GNU&nbsp;Lesser&nbsp;General&nbsp;Public&nbsp;License</span></div></li>
+<li><div class="src-line"><a name="a4125"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@copyright&nbsp;&nbsp;&nbsp;Copyright&nbsp;2007,&nbsp;{@link&nbsp;http://wikkawiki.org/CreditsPage</span></div></li>
+<li><div class="src-line"><a name="a4126"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wikka&nbsp;Development&nbsp;Team}</span></div></li>
+<li><div class="src-line"><a name="a4127"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4128"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private</span></div></li>
+<li><div class="src-line"><a name="a4129"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;&nbsp;$string&nbsp;string&nbsp;to&nbsp;be&nbsp;converted</span></div></li>
+<li><div class="src-line"><a name="a4130"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;integer&nbsp;$quote_style</span></div></li>
+<li><div class="src-line"><a name="a4131"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;ENT_COMPAT:&nbsp;&nbsp;&nbsp;escapes&nbsp;&amp;,&nbsp;&lt;,&nbsp;&gt;&nbsp;and&nbsp;double&nbsp;quote&nbsp;(default)</span></div></li>
+<li><div class="src-line"><a name="a4132"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;ENT_NOQUOTES:&nbsp;escapes&nbsp;only&nbsp;&amp;,&nbsp;&lt;&nbsp;and&nbsp;&gt;</span></div></li>
+<li><div class="src-line"><a name="a4133"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;ENT_QUOTES:&nbsp;&nbsp;&nbsp;escapes&nbsp;&amp;,&nbsp;&lt;,&nbsp;&gt;,&nbsp;double&nbsp;and&nbsp;single&nbsp;quotes</span></div></li>
+<li><div class="src-line"><a name="a4134"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;&nbsp;converted&nbsp;string</span></div></li>
+<li><div class="src-line"><a name="a4135"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.0.7.18</span></div></li>
+<li><div class="src-line"><a name="a4136"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a4137"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<span class="src-id">hsc</span><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$quote_style</span>&nbsp;=&nbsp;<span class="src-id">ENT_COMPAT</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4138"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;init</span></span></div></li>
+<li><div class="src-line"><a name="a4139"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">static</span>&nbsp;<span class="src-var">$aTransSpecchar</span>&nbsp;=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span></span></div></li>
+<li><div class="src-line"><a name="a4140"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&amp;'</span>&nbsp;=&gt;&nbsp;<span class="src-str">'&amp;amp;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a4141"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&quot;'</span>&nbsp;=&gt;&nbsp;<span class="src-str">'&amp;quot;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a4142"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&lt;'</span>&nbsp;=&gt;&nbsp;<span class="src-str">'&amp;lt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a4143"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'&gt;'</span>&nbsp;=&gt;&nbsp;<span class="src-str">'&amp;gt;'</span><span class="src-sym">,</span></span></div></li>
+<li><div class="src-line"><a name="a4144"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4145"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;fix&nbsp;is&nbsp;related&nbsp;to&nbsp;SF#1923020,&nbsp;but&nbsp;has&nbsp;to&nbsp;be&nbsp;applied</span></span></div></li>
+<li><div class="src-line"><a name="a4146"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//regardless&nbsp;of&nbsp;actually&nbsp;highlighting&nbsp;symbols.</span></span></div></li>
+<li><div class="src-line"><a name="a4147"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a4148"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Circumvent&nbsp;a&nbsp;bug&nbsp;with&nbsp;symbol&nbsp;highlighting</span></span></div></li>
+<li><div class="src-line"><a name="a4149"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;is&nbsp;required&nbsp;as&nbsp;;&nbsp;would&nbsp;produce&nbsp;undesirable&nbsp;side-effects&nbsp;if&nbsp;it</span></span></div></li>
+<li><div class="src-line"><a name="a4150"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//was&nbsp;not&nbsp;to&nbsp;be&nbsp;processed&nbsp;as&nbsp;an&nbsp;entity.</span></span></div></li>
+<li><div class="src-line"><a name="a4151"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">';'</span>&nbsp;=&gt;&nbsp;<span class="src-str">'&lt;SEMI&gt;'</span><span class="src-sym">,</span>&nbsp;<span class="src-comm">//&nbsp;Force&nbsp;;&nbsp;to&nbsp;be&nbsp;processed&nbsp;as&nbsp;entity</span></span></div></li>
+<li><div class="src-line"><a name="a4152"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'|'</span>&nbsp;=&gt;&nbsp;<span class="src-str">'&lt;PIPE&gt;'</span>&nbsp;<span class="src-comm">//&nbsp;Force&nbsp;|&nbsp;to&nbsp;be&nbsp;processed&nbsp;as&nbsp;entity</span></span></div></li>
+<li><div class="src-line"><a name="a4153"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">)</span><span class="src-sym">;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;ENT_COMPAT&nbsp;set</span></span></div></li>
+<li><div class="src-line"><a name="a4154"></a></span><span class="src-str"><span class="src-comm"></span></span></div></li>
+<li><div class="src-line"><a name="a4155"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">switch</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$quote_style</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4156"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case</span>&nbsp;<span class="src-id">ENT_NOQUOTES</span>:&nbsp;<span class="src-comm">//&nbsp;don't&nbsp;convert&nbsp;double&nbsp;quotes</span></span></div></li>
+<li><div class="src-line"><a name="a4157"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$aTransSpecchar</span><span class="src-sym">[</span><span class="src-str">'&quot;'</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4158"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4159"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case</span>&nbsp;<span class="src-id">ENT_QUOTES</span>:&nbsp;<span class="src-comm">//&nbsp;convert&nbsp;single&nbsp;quotes&nbsp;as&nbsp;well</span></span></div></li>
+<li><div class="src-line"><a name="a4160"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$aTransSpecchar</span><span class="src-sym">[</span><span class="src-str">&quot;'&quot;</span><span class="src-sym">]</span>&nbsp;=&nbsp;<span class="src-str">'&amp;#39;'</span><span class="src-sym">;</span>&nbsp;<span class="src-comm">//&nbsp;(apos)&nbsp;htmlspecialchars()&nbsp;uses&nbsp;'&amp;#039;'</span></span></div></li>
+<li><div class="src-line"><a name="a4161"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4162"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4163"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4164"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;return&nbsp;translated&nbsp;string</span></span></div></li>
+<li><div class="src-line"><a name="a4165"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<a href="http://www.php.net/strtr">strtr</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,</span>&nbsp;<span class="src-var">$aTransSpecchar</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4166"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4167"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4168"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;/**</span></div></li>
+<li><div class="src-line"><a name="a4169"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;a&nbsp;stylesheet&nbsp;for&nbsp;the&nbsp;highlighted&nbsp;code.&nbsp;If&nbsp;$economy&nbsp;mode</span></div></li>
+<li><div class="src-line"><a name="a4170"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;is&nbsp;true,&nbsp;we&nbsp;only&nbsp;return&nbsp;the&nbsp;stylesheet&nbsp;declarations&nbsp;that&nbsp;matter&nbsp;for</span></div></li>
+<li><div class="src-line"><a name="a4171"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;this&nbsp;code&nbsp;block&nbsp;instead&nbsp;of&nbsp;the&nbsp;whole&nbsp;thing</span></div></li>
+<li><div class="src-line"><a name="a4172"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</span></div></li>
+<li><div class="src-line"><a name="a4173"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&nbsp;boolean&nbsp;Whether&nbsp;to&nbsp;use&nbsp;economy&nbsp;mode&nbsp;or&nbsp;not</span></div></li>
+<li><div class="src-line"><a name="a4174"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;A&nbsp;stylesheet&nbsp;built&nbsp;on&nbsp;the&nbsp;data&nbsp;for&nbsp;the&nbsp;current&nbsp;language</span></div></li>
+<li><div class="src-line"><a name="a4175"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;&nbsp;1.0.0</span></div></li>
+<li><div class="src-line"><a name="a4176"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></div></li>
+<li><div class="src-line"><a name="a4177"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function</span>&nbsp;<a href="../geshi/core/GeSHi.html#methodget_stylesheet">get_stylesheet</a><span class="src-sym">(</span><span class="src-var">$economy_mode</span>&nbsp;=&nbsp;<span class="src-id">true</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4178"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;there's&nbsp;an&nbsp;error,&nbsp;chances&nbsp;are&nbsp;that&nbsp;the&nbsp;language&nbsp;file</span></span></div></li>
+<li><div class="src-line"><a name="a4179"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;won't&nbsp;have&nbsp;populated&nbsp;the&nbsp;language&nbsp;data&nbsp;file,&nbsp;so&nbsp;we&nbsp;can't</span></span></div></li>
+<li><div class="src-line"><a name="a4180"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;risk&nbsp;getting&nbsp;a&nbsp;stylesheet...</span></span></div></li>
+<li><div class="src-line"><a name="a4181"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methoderror">error</a><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4182"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return</span>&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4183"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4184"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4185"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//Check&nbsp;if&nbsp;the&nbsp;style&nbsp;rearrangements&nbsp;have&nbsp;been&nbsp;processed&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a4186"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//This&nbsp;also&nbsp;does&nbsp;some&nbsp;preprocessing&nbsp;to&nbsp;check&nbsp;which&nbsp;style&nbsp;groups&nbsp;are&nbsp;useable&nbsp;...</span></span></div></li>
+<li><div class="src-line"><a name="a4187"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span><span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'NUMBERS_CACHE'</span><span class="src-sym">]</span><span class="src-sym">))</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4188"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">build_style_cache</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4189"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4190"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4191"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;First,&nbsp;work&nbsp;out&nbsp;what&nbsp;the&nbsp;selector&nbsp;should&nbsp;be.&nbsp;If&nbsp;there's&nbsp;an&nbsp;ID,</span></span></div></li>
+<li><div class="src-line"><a name="a4192"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;that&nbsp;should&nbsp;be&nbsp;used,&nbsp;the&nbsp;same&nbsp;for&nbsp;a&nbsp;class.&nbsp;Otherwise,&nbsp;a&nbsp;selector</span></span></div></li>
+<li><div class="src-line"><a name="a4193"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;of&nbsp;''&nbsp;means&nbsp;that&nbsp;these&nbsp;styles&nbsp;will&nbsp;be&nbsp;applied&nbsp;anywhere</span></span></div></li>
+<li><div class="src-line"><a name="a4194"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4195"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$selector</span>&nbsp;=&nbsp;<span class="src-str">'#'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4196"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4197"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$selector</span>&nbsp;=&nbsp;<span class="src-str">'.'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4198"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_class</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4199"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$selector</span>&nbsp;.=&nbsp;<span class="src-str">'.'</span>&nbsp;.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_class</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4200"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4201"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4202"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$selector</span>&nbsp;.=&nbsp;<span class="src-str">'&nbsp;'</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4203"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4204"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Header&nbsp;of&nbsp;the&nbsp;stylesheet</span></span></div></li>
+<li><div class="src-line"><a name="a4205"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4206"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet</span>&nbsp;=&nbsp;<span class="src-str">&quot;/**\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4207"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;GeSHi&nbsp;Dynamically&nbsp;Generated&nbsp;Stylesheet\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4208"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;--------------------------------------\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4209"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">"</span></span>&nbsp;*&nbsp;Dynamically&nbsp;generated&nbsp;stylesheet&nbsp;for&nbsp;{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language</span><span class="src-sym">}</span>\n<span class="src-str">&quot;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a4210"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="src-str">&quot;</span>&nbsp;*&nbsp;CSS&nbsp;class:&nbsp;{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_class</span><span class="src-sym">}</span>,&nbsp;CSS&nbsp;id:&nbsp;{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_id</span><span class="src-sym">}</span>\n<span class="src-str">&quot;</span><span class="src-str">.</span></div></li>
+<li><div class="src-line"><a name="a4211"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;GeSHi&nbsp;(C)&nbsp;2004&nbsp;-&nbsp;2007&nbsp;Nigel&nbsp;McNie,&nbsp;2007&nbsp;-&nbsp;2008&nbsp;Benny&nbsp;Baumann\n&quot;</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a4212"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;(http://qbnz.com/highlighter/&nbsp;and&nbsp;http://geshi.org/)\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4213"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;--------------------------------------\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4214"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*/\n&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4215"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span>&nbsp;<span class="src-key">else</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4216"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet</span>&nbsp;=&nbsp;<span class="src-str">&quot;/**\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4217"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;GeSHi&nbsp;(C)&nbsp;2004&nbsp;-&nbsp;2007&nbsp;Nigel&nbsp;McNie,&nbsp;2007&nbsp;-&nbsp;2008&nbsp;Benny&nbsp;Baumann\n&quot;</span>&nbsp;.</span></div></li>
+<li><div class="src-line"><a name="a4218"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*&nbsp;(http://qbnz.com/highlighter/&nbsp;and&nbsp;http://geshi.org/)\n&quot;</span>.</span></div></li>
+<li><div class="src-line"><a name="a4219"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">&quot;&nbsp;*/\n&quot;</span><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4220"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4221"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4222"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Set&nbsp;the&nbsp;&lt;ol&gt;&nbsp;to&nbsp;have&nbsp;no&nbsp;effect&nbsp;at&nbsp;all&nbsp;if&nbsp;there&nbsp;are&nbsp;line&nbsp;numbers</span></span></div></li>
+<li><div class="src-line"><a name="a4223"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;(&lt;ol&gt;s&nbsp;have&nbsp;margins&nbsp;that&nbsp;should&nbsp;be&nbsp;destroyed&nbsp;so&nbsp;all&nbsp;layout&nbsp;is</span></span></div></li>
+<li><div class="src-line"><a name="a4224"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;controlled&nbsp;by&nbsp;the&nbsp;set_overall_style&nbsp;method,&nbsp;which&nbsp;works&nbsp;on&nbsp;the</span></span></div></li>
+<li><div class="src-line"><a name="a4225"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&lt;pre&gt;&nbsp;or&nbsp;&lt;div&gt;&nbsp;container).&nbsp;Additionally,&nbsp;set&nbsp;default&nbsp;styles&nbsp;for&nbsp;lines</span></span></div></li>
+<li><div class="src-line"><a name="a4226"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode</span>&nbsp;||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers</span>&nbsp;!=&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS&quot;&gt;GESHI_NO_LINE_NUMBERS&lt;/a&gt;</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4227"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$stylesheet&nbsp;.=&nbsp;&quot;$selector,&nbsp;{$selector}ol,&nbsp;{$selector}ol&nbsp;li&nbsp;{margin:&nbsp;0;}\n&quot;;</span></span></div></li>
+<li><div class="src-line"><a name="a4228"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span><span class="src-var">$selector</span>.de1,&nbsp;<span class="src-var">$selector</span>.de2&nbsp;{{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">code_style</span><span class="src-sym">}</span>}\n<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4229"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4230"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4231"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;overall&nbsp;styles</span></span></div></li>
+<li><div class="src-line"><a name="a4232"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note:&nbsp;neglect&nbsp;economy_mode,&nbsp;empty&nbsp;styles&nbsp;are&nbsp;meaningless</span></span></div></li>
+<li><div class="src-line"><a name="a4233"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_style</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4234"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet</span>&nbsp;.=&nbsp;<span class="src-str">"</span></span><span class="src-var">$selector</span>&nbsp;{{<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">overall_style</span><span class="src-sym">}</span>}\n<span class="src-str">&quot;</span><span class="src-str"><span class="src-sym">;</span></span></div></li>
+<li><div class="src-line"><a name="a4235"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></span></div></li>
+<li><div class="src-line"><a name="a4236"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4237"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Add&nbsp;styles&nbsp;for&nbsp;links</span></span></div></li>
+<li><div class="src-line"><a name="a4238"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note:&nbsp;economy&nbsp;mode&nbsp;does&nbsp;not&nbsp;make&nbsp;_any_&nbsp;sense&nbsp;here</span></span></div></li>
+<li><div class="src-line"><a name="a4239"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;either&nbsp;the&nbsp;style&nbsp;is&nbsp;empty&nbsp;and&nbsp;thus&nbsp;no&nbsp;selector&nbsp;is&nbsp;needed</span></span></div></li>
+<li><div class="src-line"><a name="a4240"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;the&nbsp;appropriate&nbsp;key&nbsp;is&nbsp;given.</span></span></div></li>
+<li><div class="src-line"><a name="a4241"></a></span><span class="src-str"><span class="src-comm"></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">link_styles</span>&nbsp;<span class="src-key">as</span>&nbsp;<span class="src-var">$key</span>&nbsp;=&gt;&nbsp;<span class="src-var">$style</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4242"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$style</span>&nbsp;!=&nbsp;<span class="src-str">''</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4243"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">switch</span>&nbsp;<span class="src-sym">(</span><span class="src-var">$key</span><span class="src-sym">)</span>&nbsp;<span class="src-sym">{</span></span></div></li>
+<li><div class="src-line"><a name="a4244"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case</span>&nbsp;<span class="src-id">&lt;a&nbsp;href=&quot;../geshi/core/_geshi.php.html#defineGESHI_LINK&quot;&gt;GESHI_LINK&lt;/a&gt;</span>:</span></div></li>
+<li><div class="src-line"><a name="a4245"></a></span><span class="src-str">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet</span>&nbsp;.=&nbsp;<span class="src-str">"</span>{<span class="src-var">$selector</span><span class="src-sym">}</span>a:link&nbsp;{{<span class="src-var">$style</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4246"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4247"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case&nbsp;</span><span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_HOVER">GESHI_HOVER</a></span>:</div></li>
+<li><div class="src-line"><a name="a4248"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>a:hover&nbsp;{{<span class="src-var">$style</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4249"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4250"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case&nbsp;</span><span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_ACTIVE">GESHI_ACTIVE</a></span>:</div></li>
+<li><div class="src-line"><a name="a4251"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>a:active&nbsp;{{<span class="src-var">$style</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4252"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4253"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">case&nbsp;</span><span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_VISITED">GESHI_VISITED</a></span>:</div></li>
+<li><div class="src-line"><a name="a4254"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>a:visited&nbsp;{{<span class="src-var">$style</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4255"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4256"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4257"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4258"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4259"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4260"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Header&nbsp;and&nbsp;footer</span></div></li>
+<li><div class="src-line"><a name="a4261"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note:&nbsp;neglect&nbsp;economy_mode,&nbsp;empty&nbsp;styles&nbsp;are&nbsp;meaningless</span></div></li>
+<li><div class="src-line"><a name="a4262"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">header_content_style&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4263"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.head&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">header_content_style</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4264"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4265"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">footer_content_style&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4266"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.foot&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">footer_content_style</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4267"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4268"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4269"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Styles&nbsp;for&nbsp;important&nbsp;stuff</span></div></li>
+<li><div class="src-line"><a name="a4270"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note:&nbsp;neglect&nbsp;economy_mode,&nbsp;empty&nbsp;styles&nbsp;are&nbsp;meaningless</span></div></li>
+<li><div class="src-line"><a name="a4271"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">important_styles&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4272"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.imp&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">important_styles</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4273"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4274"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4275"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Simple&nbsp;line&nbsp;number&nbsp;styles</span></div></li>
+<li><div class="src-line"><a name="a4276"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">((</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers&nbsp;</span>!=&nbsp;<span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS">GESHI_NO_LINE_NUMBERS</a></span><span class="src-sym">)&nbsp;</span>&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_style1&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4277"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>li,&nbsp;{<span class="src-var">$selector</span><span class="src-sym">}</span>.li1&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">line_style1</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4278"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4279"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">((</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers&nbsp;</span>!=&nbsp;<span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS">GESHI_NO_LINE_NUMBERS</a></span><span class="src-sym">)&nbsp;</span>&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">table_linenumber_style&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4280"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>.ln&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">table_linenumber_style</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4281"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4282"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;style&nbsp;set&nbsp;for&nbsp;fancy&nbsp;line&nbsp;numbers,&nbsp;echo&nbsp;it&nbsp;out</span></div></li>
+<li><div class="src-line"><a name="a4283"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">((</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_numbers&nbsp;</span>==&nbsp;<span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS">GESHI_FANCY_LINE_NUMBERS</a></span><span class="src-sym">)&nbsp;</span>&amp;&amp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">line_style2&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4284"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>.li2&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">line_style2</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4285"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4286"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4287"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note:&nbsp;empty&nbsp;styles&nbsp;are&nbsp;meaningless</span></div></li>
+<li><div class="src-line"><a name="a4288"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4289"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||</div></li>
+<li><div class="src-line"><a name="a4290"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>&amp;&amp;</div></li>
+<li><div class="src-line"><a name="a4291"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'KEYWORDS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4292"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.kw<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4293"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4294"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4295"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4296"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||</div></li>
+<li><div class="src-line"><a name="a4297"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>&amp;&amp;</div></li>
+<li><div class="src-line"><a name="a4298"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'COMMENTS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>||</div></li>
+<li><div class="src-line"><a name="a4299"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_REGEXP'</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>&amp;&amp;</div></li>
+<li><div class="src-line"><a name="a4300"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'COMMENT_REGEXP'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">))))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4301"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.co<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4302"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4303"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4304"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4305"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'ESCAPE_CHAR'</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4306"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;NEW:&nbsp;since&nbsp;1.0.8&nbsp;we&nbsp;have&nbsp;to&nbsp;handle&nbsp;hardescapes</span></div></li>
+<li><div class="src-line"><a name="a4307"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$group&nbsp;</span>===&nbsp;<span class="src-str">'HARD'</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4308"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$group&nbsp;</span>=&nbsp;<span class="src-str">'_h'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4309"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4310"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.es<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4311"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4312"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4313"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4314"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'BRACKETS'</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4315"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.br<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4316"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4317"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4318"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4319"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'SYMBOLS'</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4320"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.sy<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4321"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4322"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4323"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4324"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'STRINGS'</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4325"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;NEW:&nbsp;since&nbsp;1.0.8&nbsp;we&nbsp;have&nbsp;to&nbsp;handle&nbsp;hardquotes</span></div></li>
+<li><div class="src-line"><a name="a4326"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$group&nbsp;</span>===&nbsp;<span class="src-str">'HARD'</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4327"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$group&nbsp;</span>=&nbsp;<span class="src-str">'_h'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4328"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4329"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.st<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4330"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4331"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4332"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4333"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'NUMBERS'</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4334"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.nu<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4335"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4336"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4337"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4338"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'METHODS'</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4339"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.me<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4340"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4341"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4342"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;note:&nbsp;neglect&nbsp;economy_mode,&nbsp;empty&nbsp;styles&nbsp;are&nbsp;meaningless</span></div></li>
+<li><div class="src-line"><a name="a4343"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'SCRIPT'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4344"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4345"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.sc<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4346"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4347"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4348"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'STYLES'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$group&nbsp;</span>=&gt;&nbsp;<span class="src-var">$styles</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4349"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$styles&nbsp;</span>!=&nbsp;<span class="src-str">''&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||</div></li>
+<li><div class="src-line"><a name="a4350"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>&amp;&amp;</div></li>
+<li><div class="src-line"><a name="a4351"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">lexic_permissions</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4352"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><a href="http://www.php.net/is_array">is_array</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>&amp;&amp;</div></li>
+<li><div class="src-line"><a name="a4353"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_key_exists">array_key_exists</a><span class="src-sym">(</span><span class="src-id">GESHI_CLASS</span><span class="src-sym">,&nbsp;</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4354"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4355"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">language_data</span><span class="src-sym">[</span><span class="src-str">'REGEXPS'</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$group</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-id">GESHI_CLASS</span><span class="src-sym">]</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4356"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str">&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4357"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}&nbsp;</span><span class="src-key">else&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4358"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span><span class="src-str"><span class="src-var">$selector</span>.re<span class="src-var">$group</span>&nbsp;{{<span class="src-var">$styles</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4359"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4360"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4361"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4362"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;Styles&nbsp;for&nbsp;lines&nbsp;being&nbsp;highlighted&nbsp;extra</span></div></li>
+<li><div class="src-line"><a name="a4363"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$economy_mode&nbsp;</span>||&nbsp;<span class="src-sym">(</span><a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines</span><span class="src-sym">)</span>!=<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles</span><span class="src-sym">)))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4364"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>.ln-xtra,&nbsp;{<span class="src-var">$selector</span><span class="src-sym">}</span>li.ln-xtra,&nbsp;{<span class="src-var">$selector</span><span class="src-sym">}</span>div.ln-xtra&nbsp;{{<span class="src-var">$this</span></span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_style</span><span class="src-str"></span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4365"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4366"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>span.xtra&nbsp;{&nbsp;display:block;&nbsp;}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4367"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$lineid&nbsp;</span>=&gt;&nbsp;<span class="src-var">$linestyle</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4368"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$stylesheet&nbsp;</span>.=&nbsp;<span class="src-str">&quot;</span>{<span class="src-var">$selector</span><span class="src-str"></span><span class="src-sym">}</span>.lx<span class="src-var">$lineid</span>,&nbsp;{<span class="src-var">$selector</span><span class="src-sym">}</span>li.lx<span class="src-var">$lineid</span>,&nbsp;{<span class="src-var">$selector</span><span class="src-sym">}</span>div.lx<span class="src-var">$lineid</span>&nbsp;{{<span class="src-var">$linestyle</span><span class="src-sym">}</span>}\n</span><span class="src-str">&quot;</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4369"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4370"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4371"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-var">$stylesheet</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4372"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4373"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4374"></a>&nbsp;&nbsp;&nbsp;&nbsp;/**</div></li>
+<li><div class="src-line"><a name="a4375"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Get's&nbsp;the&nbsp;style&nbsp;that&nbsp;is&nbsp;used&nbsp;for&nbsp;the&nbsp;specified&nbsp;line</div></li>
+<li><div class="src-line"><a name="a4376"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</div></li>
+<li><div class="src-line"><a name="a4377"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;int&nbsp;The&nbsp;line&nbsp;number&nbsp;information&nbsp;is&nbsp;requested&nbsp;for</div></li>
+<li><div class="src-line"><a name="a4378"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</div></li>
+<li><div class="src-line"><a name="a4379"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.7.21</div></li>
+<li><div class="src-line"><a name="a4380"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</div></li>
+<li><div class="src-line"><a name="a4381"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><span class="src-id">get_line_style</span><span class="src-sym">(</span><span class="src-var">$line</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4382"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$style&nbsp;=&nbsp;null;</span></div></li>
+<li><div class="src-line"><a name="a4383"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$style&nbsp;</span>=&nbsp;<span class="src-id">null</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4384"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$line</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4385"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$style&nbsp;</span>=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_styles</span><span class="src-sym">[</span><span class="src-var">$line</span><span class="src-sym">]</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4386"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}&nbsp;</span><span class="src-key">else&nbsp;</span><span class="src-sym">{&nbsp;</span><span class="src-comm">//&nbsp;if&nbsp;no&nbsp;&quot;extra&quot;&nbsp;style&nbsp;assigned</span></div></li>
+<li><div class="src-line"><a name="a4387"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$style&nbsp;</span>=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">highlight_extra_lines_style</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4388"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4389"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4390"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-var">$style</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4391"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4392"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4393"></a>&nbsp;&nbsp;&nbsp;&nbsp;/**</div></li>
+<li><div class="src-line"><a name="a4394"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;this&nbsp;functions&nbsp;creates&nbsp;an&nbsp;optimized&nbsp;regular&nbsp;expression&nbsp;list</div></li>
+<li><div class="src-line"><a name="a4395"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;of&nbsp;an&nbsp;array&nbsp;of&nbsp;strings.</div></li>
+<li><div class="src-line"><a name="a4396"></a>&nbsp;&nbsp;&nbsp;&nbsp;*</div></li>
+<li><div class="src-line"><a name="a4397"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Example:</div></li>
+<li><div class="src-line"><a name="a4398"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;code&gt;$list&nbsp;=&nbsp;array('faa',&nbsp;'foo',&nbsp;'foobar');</div></li>
+<li><div class="src-line"><a name="a4399"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;string&nbsp;'f(aa|oo(bar)?)'&lt;/code&gt;</div></li>
+<li><div class="src-line"><a name="a4400"></a>&nbsp;&nbsp;&nbsp;&nbsp;*</div></li>
+<li><div class="src-line"><a name="a4401"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;$list&nbsp;array&nbsp;of&nbsp;(unquoted)&nbsp;strings</div></li>
+<li><div class="src-line"><a name="a4402"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;$regexp_delimiter&nbsp;your&nbsp;regular&nbsp;expression&nbsp;delimiter,&nbsp;@see&nbsp;preg_quote()</div></li>
+<li><div class="src-line"><a name="a4403"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;for&nbsp;regular&nbsp;expression</div></li>
+<li><div class="src-line"><a name="a4404"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;Milian&nbsp;Wolff&nbsp;&lt;mail@milianw.de&gt;</div></li>
+<li><div class="src-line"><a name="a4405"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.8</div></li>
+<li><div class="src-line"><a name="a4406"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</div></li>
+<li><div class="src-line"><a name="a4407"></a>&nbsp;&nbsp;&nbsp;&nbsp;*/</div></li>
+<li><div class="src-line"><a name="a4408"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><span class="src-id">optimize_regexp_list</span><span class="src-sym">(</span><span class="src-var">$list</span><span class="src-sym">,&nbsp;</span><span class="src-var">$regexp_delimiter&nbsp;</span>=&nbsp;<span class="src-str">'/'</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4409"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regex_chars&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">'.'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'\\'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'+'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'*'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'?'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'['</span><span class="src-sym">,&nbsp;</span><span class="src-str">'^'</span><span class="src-sym">,&nbsp;</span><span class="src-str">']'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'$'</span><span class="src-sym">,</span></div></li>
+<li><div class="src-line"><a name="a4410"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-str">'('</span><span class="src-sym">,&nbsp;</span><span class="src-str">')'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'{'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'}'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'='</span><span class="src-sym">,&nbsp;</span><span class="src-str">'!'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'&lt;'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'&gt;'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'|'</span><span class="src-sym">,&nbsp;</span><span class="src-str">':'</span><span class="src-sym">,&nbsp;</span><span class="src-var">$regexp_delimiter</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4411"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/sort">sort</a><span class="src-sym">(</span><span class="src-var">$list</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4412"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp_list&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">''</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4413"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_subpatterns&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4414"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list_key&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4415"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4416"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;the&nbsp;tokens&nbsp;which&nbsp;we&nbsp;will&nbsp;use&nbsp;to&nbsp;generate&nbsp;the&nbsp;regexp&nbsp;list</span></div></li>
+<li><div class="src-line"><a name="a4417"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$tokens&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4418"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$prev_keys&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4419"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;go&nbsp;through&nbsp;all&nbsp;entries&nbsp;of&nbsp;the&nbsp;list&nbsp;and&nbsp;generate&nbsp;the&nbsp;token&nbsp;list</span></div></li>
+<li><div class="src-line"><a name="a4420"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$cur_len&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4421"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">for&nbsp;</span><span class="src-sym">(</span><span class="src-var">$i&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">,&nbsp;</span><span class="src-var">$i_max&nbsp;</span>=&nbsp;<a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$list</span><span class="src-sym">)</span><span class="src-sym">;&nbsp;</span><span class="src-var">$i&nbsp;</span>&lt;&nbsp;<span class="src-var">$i_max</span><span class="src-sym">;&nbsp;</span>++<span class="src-var">$i</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4422"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$cur_len&nbsp;</span>&gt;&nbsp;<span class="src-id">GESHI_MAX_PCRE_LENGTH</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4423"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;seems&nbsp;like&nbsp;the&nbsp;length&nbsp;of&nbsp;this&nbsp;pcre&nbsp;is&nbsp;growing&nbsp;exorbitantly</span></div></li>
+<li><div class="src-line"><a name="a4424"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp_list</span><span class="src-sym">[</span>++<span class="src-var">$list_key</span><span class="src-sym">]&nbsp;</span>=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_optimize_regexp_list_tokens_to_string</span><span class="src-sym">(</span><span class="src-var">$tokens</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4425"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_subpatterns&nbsp;</span>=&nbsp;<a href="http://www.php.net/substr_count">substr_count</a><span class="src-sym">(</span><span class="src-var">$regexp_list</span><span class="src-sym">[</span><span class="src-var">$list_key</span><span class="src-sym">]</span><span class="src-sym">,&nbsp;</span><span class="src-str">'(?:'</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4426"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$tokens&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4427"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$cur_len&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4428"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4429"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$level&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4430"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$entry&nbsp;</span>=&nbsp;<a href="http://www.php.net/preg_quote">preg_quote</a><span class="src-sym">(</span>(string)&nbsp;<span class="src-var">$list</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">,&nbsp;</span><span class="src-var">$regexp_delimiter</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4431"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pointer&nbsp;</span>=&nbsp;<span class="src-sym">&amp;</span><span class="src-var">$tokens</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4432"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;properly&nbsp;assign&nbsp;the&nbsp;new&nbsp;entry&nbsp;to&nbsp;the&nbsp;correct&nbsp;position&nbsp;in&nbsp;the&nbsp;token&nbsp;array</span></div></li>
+<li><div class="src-line"><a name="a4433"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;possibly&nbsp;generate&nbsp;smaller&nbsp;common&nbsp;denominator&nbsp;keys</span></div></li>
+<li><div class="src-line"><a name="a4434"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while&nbsp;</span><span class="src-sym">(</span><span class="src-id">true</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4435"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;get&nbsp;the&nbsp;common&nbsp;denominator</span></div></li>
+<li><div class="src-line"><a name="a4436"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4437"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]&nbsp;</span>==&nbsp;<span class="src-var">$entry</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4438"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;is&nbsp;a&nbsp;duplicate&nbsp;entry,&nbsp;skip&nbsp;it</span></div></li>
+<li><div class="src-line"><a name="a4439"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue&nbsp;</span><span class="src-num">2</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4440"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4441"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$char&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4442"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">while&nbsp;</span><span class="src-sym">(</span>isset<span class="src-sym">(</span><span class="src-var">$entry</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span>&amp;&amp;&nbsp;isset<span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span><span class="src-sym">)</span></div></li>
+<li><div class="src-line"><a name="a4443"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span class="src-var">$entry</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]&nbsp;</span>==&nbsp;<span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]</span><span class="src-sym">[</span><span class="src-var">$char</span><span class="src-sym">]</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4444"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$char</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4445"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4446"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$char&nbsp;</span>&gt;&nbsp;<span class="src-num">0</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4447"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;entry&nbsp;has&nbsp;at&nbsp;least&nbsp;some&nbsp;chars&nbsp;in&nbsp;common&nbsp;with&nbsp;the&nbsp;current&nbsp;key</span></div></li>
+<li><div class="src-line"><a name="a4448"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$char&nbsp;</span>==&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4449"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;current&nbsp;key&nbsp;is&nbsp;totally&nbsp;matched,&nbsp;i.e.&nbsp;this&nbsp;entry&nbsp;has&nbsp;just&nbsp;some&nbsp;bits&nbsp;appended</span></div></li>
+<li><div class="src-line"><a name="a4450"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pointer&nbsp;</span>=&nbsp;<span class="src-sym">&amp;</span><span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]]</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4451"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}&nbsp;</span><span class="src-key">else&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4452"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;only&nbsp;part&nbsp;of&nbsp;the&nbsp;keys&nbsp;match</span></div></li>
+<li><div class="src-line"><a name="a4453"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_key_part1&nbsp;</span>=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">,&nbsp;</span><span class="src-var">$char</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4454"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_key_part2&nbsp;</span>=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]</span><span class="src-sym">,&nbsp;</span><span class="src-var">$char</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4455"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4456"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$new_key_part1</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">,&nbsp;</span><span class="src-var">$regex_chars</span><span class="src-sym">)</span></div></li>
+<li><div class="src-line"><a name="a4457"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;||&nbsp;<a href="http://www.php.net/in_array">in_array</a><span class="src-sym">(</span><span class="src-var">$new_key_part2</span><span class="src-sym">[</span><span class="src-num">0</span><span class="src-sym">]</span><span class="src-sym">,&nbsp;</span><span class="src-var">$regex_chars</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4458"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;this&nbsp;is&nbsp;bad,&nbsp;a&nbsp;regex&nbsp;char&nbsp;as&nbsp;first&nbsp;character</span></div></li>
+<li><div class="src-line"><a name="a4459"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$entry</span><span class="src-sym">]&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">''&nbsp;</span>=&gt;&nbsp;<span class="src-id">true</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4460"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_splice">array_splice</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">,&nbsp;</span><span class="src-var">$level</span><span class="src-sym">,&nbsp;</span><a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">)</span><span class="src-sym">,&nbsp;</span><span class="src-var">$entry</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4461"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$cur_len&nbsp;</span>+=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$entry</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4462"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4463"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}&nbsp;</span><span class="src-key">else&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4464"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;relocate&nbsp;previous&nbsp;tokens</span></div></li>
+<li><div class="src-line"><a name="a4465"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$new_key_part1</span><span class="src-sym">]&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-var">$new_key_part2&nbsp;</span>=&gt;&nbsp;<span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]]</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4466"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$prev_keys</span><span class="src-sym">[</span><span class="src-var">$level</span><span class="src-sym">]]</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4467"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pointer&nbsp;</span>=&nbsp;<span class="src-sym">&amp;</span><span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$new_key_part1</span><span class="src-sym">]</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4468"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;recreate&nbsp;key&nbsp;index</span></div></li>
+<li><div class="src-line"><a name="a4469"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_splice">array_splice</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">,&nbsp;</span><span class="src-var">$level</span><span class="src-sym">,&nbsp;</span><a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">)</span><span class="src-sym">,&nbsp;</span><span class="src-key">array</span><span class="src-sym">(</span><span class="src-var">$new_key_part1</span><span class="src-sym">,&nbsp;</span><span class="src-var">$new_key_part2</span><span class="src-sym">))</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4470"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$cur_len&nbsp;</span>+=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$new_key_part2</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4471"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4472"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4473"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++<span class="src-var">$level</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4474"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$entry&nbsp;</span>=&nbsp;<a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$entry</span><span class="src-sym">,&nbsp;</span><span class="src-var">$char</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4475"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">continue</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4476"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4477"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;else:&nbsp;fall&nbsp;trough,&nbsp;i.e.&nbsp;no&nbsp;common&nbsp;denominator&nbsp;was&nbsp;found</span></div></li>
+<li><div class="src-line"><a name="a4478"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4479"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$level&nbsp;</span>==&nbsp;<span class="src-num">0&nbsp;</span>&amp;&amp;&nbsp;<span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$tokens</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4480"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;we&nbsp;can&nbsp;dump&nbsp;current&nbsp;tokens&nbsp;into&nbsp;the&nbsp;string&nbsp;and&nbsp;throw&nbsp;them&nbsp;away&nbsp;afterwards</span></div></li>
+<li><div class="src-line"><a name="a4481"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_entry&nbsp;</span>=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_optimize_regexp_list_tokens_to_string</span><span class="src-sym">(</span><span class="src-var">$tokens</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4482"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_subpatterns&nbsp;</span>=&nbsp;<a href="http://www.php.net/substr_count">substr_count</a><span class="src-sym">(</span><span class="src-var">$new_entry</span><span class="src-sym">,&nbsp;</span><span class="src-str">'(?:'</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4483"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-id">GESHI_MAX_PCRE_SUBPATTERNS&nbsp;</span>&amp;&amp;&nbsp;<span class="src-var">$num_subpatterns&nbsp;</span>+&nbsp;<span class="src-var">$new_subpatterns&nbsp;</span>&gt;&nbsp;<span class="src-id">GESHI_MAX_PCRE_SUBPATTERNS</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4484"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp_list</span><span class="src-sym">[</span>++<span class="src-var">$list_key</span><span class="src-sym">]&nbsp;</span>=&nbsp;<span class="src-var">$new_entry</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4485"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_subpatterns&nbsp;</span>=&nbsp;<span class="src-var">$new_subpatterns</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4486"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}&nbsp;</span><span class="src-key">else&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4487"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$regexp_list</span><span class="src-sym">[</span><span class="src-var">$list_key</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4488"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_entry&nbsp;</span>=&nbsp;<span class="src-str">'|'&nbsp;</span>.&nbsp;<span class="src-var">$new_entry</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4489"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4490"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp_list</span><span class="src-sym">[</span><span class="src-var">$list_key</span><span class="src-sym">]&nbsp;</span>.=&nbsp;<span class="src-var">$new_entry</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4491"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$num_subpatterns&nbsp;</span>+=&nbsp;<span class="src-var">$new_subpatterns</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4492"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4493"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$tokens&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4494"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$cur_len&nbsp;</span>=&nbsp;<span class="src-num">0</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4495"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4496"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;no&nbsp;further&nbsp;common&nbsp;denominator&nbsp;found</span></div></li>
+<li><div class="src-line"><a name="a4497"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$pointer</span><span class="src-sym">[</span><span class="src-var">$entry</span><span class="src-sym">]&nbsp;</span>=&nbsp;<span class="src-key">array</span><span class="src-sym">(</span><span class="src-str">''&nbsp;</span>=&gt;&nbsp;<span class="src-id">true</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4498"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.php.net/array_splice">array_splice</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">,&nbsp;</span><span class="src-var">$level</span><span class="src-sym">,&nbsp;</span><a href="http://www.php.net/count">count</a><span class="src-sym">(</span><span class="src-var">$prev_keys</span><span class="src-sym">)</span><span class="src-sym">,&nbsp;</span><span class="src-var">$entry</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4499"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4500"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$cur_len&nbsp;</span>+=&nbsp;<a href="http://www.php.net/strlen">strlen</a><span class="src-sym">(</span><span class="src-var">$entry</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4501"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">break</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4502"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4503"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$list</span><span class="src-sym">[</span><span class="src-var">$i</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4504"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4505"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;make&nbsp;sure&nbsp;the&nbsp;last&nbsp;tokens&nbsp;get&nbsp;converted&nbsp;as&nbsp;well</span></div></li>
+<li><div class="src-line"><a name="a4506"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_entry&nbsp;</span>=&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_optimize_regexp_list_tokens_to_string</span><span class="src-sym">(</span><span class="src-var">$tokens</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4507"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-id">GESHI_MAX_PCRE_SUBPATTERNS&nbsp;</span>&amp;&amp;&nbsp;<span class="src-var">$num_subpatterns&nbsp;</span>+&nbsp;<a href="http://www.php.net/substr_count">substr_count</a><span class="src-sym">(</span><span class="src-var">$new_entry</span><span class="src-sym">,&nbsp;</span><span class="src-str">'(?:'</span><span class="src-sym">)&nbsp;</span>&gt;&nbsp;<span class="src-id">GESHI_MAX_PCRE_SUBPATTERNS</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4508"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp_list</span><span class="src-sym">[</span>++<span class="src-var">$list_key</span><span class="src-sym">]&nbsp;</span>=&nbsp;<span class="src-var">$new_entry</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4509"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}&nbsp;</span><span class="src-key">else&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4510"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$regexp_list</span><span class="src-sym">[</span><span class="src-var">$list_key</span><span class="src-sym">]</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4511"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$new_entry&nbsp;</span>=&nbsp;<span class="src-str">'|'&nbsp;</span>.&nbsp;<span class="src-var">$new_entry</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4512"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4513"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$regexp_list</span><span class="src-sym">[</span><span class="src-var">$list_key</span><span class="src-sym">]&nbsp;</span>.=&nbsp;<span class="src-var">$new_entry</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4514"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4515"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-var">$regexp_list</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4516"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4517"></a>&nbsp;&nbsp;&nbsp;&nbsp;/**</div></li>
+<li><div class="src-line"><a name="a4518"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;this&nbsp;function&nbsp;creates&nbsp;the&nbsp;appropriate&nbsp;regexp&nbsp;string&nbsp;of&nbsp;an&nbsp;token&nbsp;array</div></li>
+<li><div class="src-line"><a name="a4519"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;you&nbsp;should&nbsp;not&nbsp;call&nbsp;this&nbsp;function&nbsp;directly,&nbsp;@see&nbsp;$this-&gt;optimize_regexp_list().</div></li>
+<li><div class="src-line"><a name="a4520"></a>&nbsp;&nbsp;&nbsp;&nbsp;*</div></li>
+<li><div class="src-line"><a name="a4521"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;&amp;$tokens&nbsp;array&nbsp;of&nbsp;tokens</div></li>
+<li><div class="src-line"><a name="a4522"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;$recursed&nbsp;bool&nbsp;to&nbsp;know&nbsp;wether&nbsp;we&nbsp;recursed&nbsp;or&nbsp;not</div></li>
+<li><div class="src-line"><a name="a4523"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string</div></li>
+<li><div class="src-line"><a name="a4524"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;Milian&nbsp;Wolff&nbsp;&lt;mail@milianw.de&gt;</div></li>
+<li><div class="src-line"><a name="a4525"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.8</div></li>
+<li><div class="src-line"><a name="a4526"></a>&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@access&nbsp;private</div></li>
+<li><div class="src-line"><a name="a4527"></a>&nbsp;&nbsp;&nbsp;&nbsp;*/</div></li>
+<li><div class="src-line"><a name="a4528"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><span class="src-id">_optimize_regexp_list_tokens_to_string</span><span class="src-sym">(</span><span class="src-sym">&amp;</span><span class="src-var">$tokens</span><span class="src-sym">,&nbsp;</span><span class="src-var">$recursed&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4529"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>=&nbsp;<span class="src-str">''</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4530"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">foreach&nbsp;</span><span class="src-sym">(</span><span class="src-var">$tokens&nbsp;</span><span class="src-key">as&nbsp;</span><span class="src-var">$token&nbsp;</span>=&gt;&nbsp;<span class="src-var">$sub_tokens</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4531"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>.=&nbsp;<span class="src-var">$token</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4532"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$close_entry&nbsp;</span>=&nbsp;isset<span class="src-sym">(</span><span class="src-var">$sub_tokens</span><span class="src-sym">[</span><span class="src-str">''</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4533"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset<span class="src-sym">(</span><span class="src-var">$sub_tokens</span><span class="src-sym">[</span><span class="src-str">''</span><span class="src-sym">]</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4534"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-key">empty</span><span class="src-sym">(</span><span class="src-var">$sub_tokens</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4535"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>.=&nbsp;<span class="src-str">'(?:'&nbsp;</span>.&nbsp;<span class="src-var">$this</span><span class="src-sym">-&gt;</span><span class="src-id">_optimize_regexp_list_tokens_to_string</span><span class="src-sym">(</span><span class="src-var">$sub_tokens</span><span class="src-sym">,&nbsp;</span><span class="src-id">true</span><span class="src-sym">)&nbsp;</span>.&nbsp;<span class="src-str">')'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4536"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$close_entry</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4537"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;make&nbsp;sub_tokens&nbsp;optional</span></div></li>
+<li><div class="src-line"><a name="a4538"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>.=&nbsp;<span class="src-str">'?'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4539"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4540"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4541"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>.=&nbsp;<span class="src-str">'|'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4542"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4543"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><span class="src-var">$recursed</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4544"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;do&nbsp;some&nbsp;optimizations</span></div></li>
+<li><div class="src-line"><a name="a4545"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;common&nbsp;trailing&nbsp;strings</span></div></li>
+<li><div class="src-line"><a name="a4546"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;BUGGY!</span></div></li>
+<li><div class="src-line"><a name="a4547"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//$list&nbsp;=&nbsp;preg_replace_callback('#(?&lt;=^|\:|\|)\w+?(\w+)(?:\|.+\1)+(?=\|)#',&nbsp;create_function(</span></div></li>
+<li><div class="src-line"><a name="a4548"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;&nbsp;&nbsp;&nbsp;'$matches',&nbsp;'return&nbsp;&quot;(?:&quot;&nbsp;.&nbsp;preg_replace(&quot;#&quot;&nbsp;.&nbsp;preg_quote($matches[1],&nbsp;&quot;#&quot;)&nbsp;.&nbsp;&quot;(?=\||$)#&quot;,&nbsp;&quot;&quot;,&nbsp;$matches[0])&nbsp;.&nbsp;&quot;)&quot;&nbsp;.&nbsp;$matches[1];'),&nbsp;$list);</span></div></li>
+<li><div class="src-line"><a name="a4549"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;(?:p)?&nbsp;=&gt;&nbsp;p?</span></div></li>
+<li><div class="src-line"><a name="a4550"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>=&nbsp;<a href="http://www.php.net/preg_replace">preg_replace</a><span class="src-sym">(</span><span class="src-str">'#\(\?\:(.)\)\?#'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'\1?'</span><span class="src-sym">,&nbsp;</span><span class="src-var">$list</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4551"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;(?:a|b|c|d|...)?&nbsp;=&gt;&nbsp;[abcd...]?</span></div></li>
+<li><div class="src-line"><a name="a4552"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;TODO:&nbsp;a|bb|c&nbsp;=&gt;&nbsp;[ac]|bb</span></div></li>
+<li><div class="src-line"><a name="a4553"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">static&nbsp;</span><span class="src-var">$callback_2</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4554"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span>isset<span class="src-sym">(</span><span class="src-var">$callback_2</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4555"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$callback_2&nbsp;</span>=&nbsp;<a href="http://www.php.net/create_function">create_function</a><span class="src-sym">(</span><span class="src-str">'$matches'</span><span class="src-sym">,&nbsp;</span><span class="src-str">'return&nbsp;&quot;[&quot;&nbsp;.&nbsp;str_replace(&quot;|&quot;,&nbsp;&quot;&quot;,&nbsp;$matches[1])&nbsp;.&nbsp;&quot;]&quot;;'</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4556"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4557"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$list&nbsp;</span>=&nbsp;<a href="http://www.php.net/preg_replace_callback">preg_replace_callback</a><span class="src-sym">(</span><span class="src-str">'#\(\?\:((?:.\|)+.)\)#'</span><span class="src-sym">,&nbsp;</span><span class="src-var">$callback_2</span><span class="src-sym">,&nbsp;</span><span class="src-var">$list</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4558"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4559"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-comm">//&nbsp;return&nbsp;$list&nbsp;without&nbsp;trailing&nbsp;pipe</span></div></li>
+<li><div class="src-line"><a name="a4560"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><a href="http://www.php.net/substr">substr</a><span class="src-sym">(</span><span class="src-var">$list</span><span class="src-sym">,&nbsp;</span><span class="src-num">0</span><span class="src-sym">,&nbsp;</span>-<span class="src-num">1</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4561"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4562"></a><span class="src-sym">}&nbsp;</span><span class="src-comm">//&nbsp;End&nbsp;Class&nbsp;GeSHi</span></div></li>
+<li><div class="src-line"><a name="a4563"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4564"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4565"></a><span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-sym">!</span><a href="http://www.php.net/function_exists">function_exists</a><span class="src-sym">(</span><span class="src-str">'geshi_highlight'</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4566"></a>&nbsp;&nbsp;&nbsp;&nbsp;/**</div></li>
+<li><div class="src-line"><a name="a4567"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Easy&nbsp;way&nbsp;to&nbsp;highlight&nbsp;stuff.&nbsp;Behaves&nbsp;just&nbsp;like&nbsp;highlight_string</div></li>
+<li><div class="src-line"><a name="a4568"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*</div></li>
+<li><div class="src-line"><a name="a4569"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;string&nbsp;The&nbsp;code&nbsp;to&nbsp;highlight</div></li>
+<li><div class="src-line"><a name="a4570"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;string&nbsp;The&nbsp;language&nbsp;to&nbsp;highlight&nbsp;the&nbsp;code&nbsp;in</div></li>
+<li><div class="src-line"><a name="a4571"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;string&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;language&nbsp;files.&nbsp;You&nbsp;can&nbsp;leave&nbsp;this&nbsp;blank&nbsp;if&nbsp;you&nbsp;need</div></li>
+<li><div class="src-line"><a name="a4572"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;from&nbsp;version&nbsp;1.0.7&nbsp;the&nbsp;path&nbsp;should&nbsp;be&nbsp;automatically&nbsp;detected</div></li>
+<li><div class="src-line"><a name="a4573"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;boolean&nbsp;Whether&nbsp;to&nbsp;return&nbsp;the&nbsp;result&nbsp;or&nbsp;to&nbsp;echo</div></li>
+<li><div class="src-line"><a name="a4574"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;string&nbsp;The&nbsp;code&nbsp;highlighted&nbsp;(if&nbsp;$return&nbsp;is&nbsp;true)</div></li>
+<li><div class="src-line"><a name="a4575"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;1.0.2</div></li>
+<li><div class="src-line"><a name="a4576"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</div></li>
+<li><div class="src-line"><a name="a4577"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">function&nbsp;</span><a href="../geshi/core/_geshi.php.html#functiongeshi_highlight">geshi_highlight</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,&nbsp;</span><span class="src-var">$language</span><span class="src-sym">,&nbsp;</span><span class="src-var">$path&nbsp;</span>=&nbsp;<span class="src-id">null</span><span class="src-sym">,&nbsp;</span><span class="src-var">$return&nbsp;</span>=&nbsp;<span class="src-id">false</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4578"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$geshi&nbsp;</span>=&nbsp;<span class="src-key">new&nbsp;</span><a href="../geshi/core/GeSHi.html#methodGeSHi">GeSHi</a><span class="src-sym">(</span><span class="src-var">$string</span><span class="src-sym">,&nbsp;</span><span class="src-var">$language</span><span class="src-sym">,&nbsp;</span><span class="src-var">$path</span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4579"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-var">$geshi</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodset_header_type">set_header_type</a><span class="src-sym">(</span><span class="src-id"><a href="../geshi/core/_geshi.php.html#defineGESHI_HEADER_NONE">GESHI_HEADER_NONE</a></span><span class="src-sym">)</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4580"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4581"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$return</span><span class="src-sym">)&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4582"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-str">'&lt;code&gt;'&nbsp;</span>.&nbsp;<span class="src-var">$geshi</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodparse_code">parse_code</a><span class="src-sym">(</span><span class="src-sym">)&nbsp;</span>.&nbsp;<span class="src-str">'&lt;/code&gt;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4583"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4584"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4585"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;<span class="src-str">'&lt;code&gt;'&nbsp;</span>.&nbsp;<span class="src-var">$geshi</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methodparse_code">parse_code</a><span class="src-sym">(</span><span class="src-sym">)&nbsp;</span>.&nbsp;<span class="src-str">'&lt;/code&gt;'</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4586"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4587"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">if&nbsp;</span><span class="src-sym">(</span><span class="src-var">$geshi</span><span class="src-sym">-&gt;</span><a href="../geshi/core/GeSHi.html#methoderror">error</a><span class="src-sym">(</span><span class="src-sym">))&nbsp;</span><span class="src-sym">{</span></div></li>
+<li><div class="src-line"><a name="a4588"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-id">false</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4589"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4590"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-key">return&nbsp;</span><span class="src-id">true</span><span class="src-sym">;</span></div></li>
+<li><div class="src-line"><a name="a4591"></a>&nbsp;&nbsp;&nbsp;&nbsp;<span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4592"></a><span class="src-sym">}</span></div></li>
+<li><div class="src-line"><a name="a4593"></a>&nbsp;</div></li>
+<li><div class="src-line"><a name="a4594"></a><span class="src-php">?&gt;</span></div></li>
+</ol></div>
+</div>
+       <p class="notes" id="credit">
+               Documentation generated on Thu, 25 Dec 2008 14:34:52 +0100 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.4.2</a>
+       </p>
+       </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/blank.html b/examples/includes/geshi/docs/api/blank.html
new file mode 100644 (file)
index 0000000..d44ac46
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<head>
+       <title>GeSHi 1.0.8</title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+</head>
+<body>
+<div align="center"><h1>GeSHi 1.0.8</h1></div>
+<b>Welcome to geshi!</b><br />
+<br />
+This documentation was generated by <a href="http://www.phpdoc.org">phpDocumentor v1.4.2</a><br />
+</body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/classtrees_geshi.html b/examples/includes/geshi/docs/api/classtrees_geshi.html
new file mode 100644 (file)
index 0000000..e5c3868
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title></title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               
+<!-- Start of Class Data -->
+<H2>
+       
+</H2>
+<h2>Root class GeSHi</h2>
+<ul>
+<li><a href="geshi/core/GeSHi.html">GeSHi</a></li></ul>
+
+       <p class="notes" id="credit">
+               Documentation generated on Thu, 25 Dec 2008 14:34:34 +0100 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.4.2</a>
+       </p>
+       </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/elementindex.html b/examples/includes/geshi/docs/api/elementindex.html
new file mode 100644 (file)
index 0000000..970ebd1
--- /dev/null
@@ -0,0 +1,867 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title></title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               <a name="top"></a>
+<h2>Full index</h2>
+<h3>Package indexes</h3>
+<ul>
+       <li><a href="elementindex_geshi.html">geshi</a></li>
+</ul>
+<br />
+<div class="index-letter-menu">
+       <a class="index-letter" href="elementindex.html#a">a</a>
+       <a class="index-letter" href="elementindex.html#d">d</a>
+       <a class="index-letter" href="elementindex.html#e">e</a>
+       <a class="index-letter" href="elementindex.html#g">g</a>
+       <a class="index-letter" href="elementindex.html#h">h</a>
+       <a class="index-letter" href="elementindex.html#l">l</a>
+       <a class="index-letter" href="elementindex.html#o">o</a>
+       <a class="index-letter" href="elementindex.html#p">p</a>
+       <a class="index-letter" href="elementindex.html#r">r</a>
+       <a class="index-letter" href="elementindex.html#s">s</a>
+</div>
+
+       <a name="a"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">a</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">add_keyword</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodadd_keyword">GeSHi::add_keyword()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Adds a keyword to a keyword group for highlighting</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">add_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodadd_keyword_group">GeSHi::add_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Creates a new keyword group</div>
+                                       </dd>
+               </dl>
+       <a name="d"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">d</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">disable_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methoddisable_highlighting">GeSHi::disable_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Disables all highlighting</div>
+                                       </dd>
+               </dl>
+       <a name="e"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">e</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_classes</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_classes">GeSHi::enable_classes()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether CSS classes should be used to highlight the source. Default  is off, calling this method with no arguments will turn it on</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_highlighting">GeSHi::enable_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Enables all highlighting</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_ids</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_ids">GeSHi::enable_ids()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Whether CSS IDs should be added to each line</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_important_blocks</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_important_blocks">GeSHi::enable_important_blocks()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether context-important blocks are highlighted</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_inner_code_block</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_inner_code_block">GeSHi::enable_inner_code_block()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether to force a surrounding block around  the highlighted code or not</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_keyword_links</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_keyword_links">GeSHi::enable_keyword_links()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns linking of keywords on or off.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_line_numbers</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_line_numbers">GeSHi::enable_line_numbers()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether line numbers should be displayed.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_multiline_span</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_multiline_span">GeSHi::enable_multiline_span()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets wether spans and other HTML markup generated by GeSHi can  span over multiple lines or not. Defaults to true to reduce overhead.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_strict_mode</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_strict_mode">GeSHi::enable_strict_mode()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Enables/disables strict highlighting. Default is off, calling this  method without parameters will turn it on. See documentation  for more details on strict mode and where to use it.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">error</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methoderror">GeSHi::error()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns an error message associated with the last GeSHi operation,  or false if no error has occured</div>
+                                       </dd>
+               </dl>
+       <a name="g"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">g</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Constructor.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">GeSHi</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodGeSHi">GeSHi::GeSHi()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Creates a new GeSHi object, with source and language</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Class.png" alt="Class" title="Class" /></title>
+                       GeSHi
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html">GeSHi</a> in geshi.php</div>
+                                                       <div class="index-item-description">The GeSHi Class.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Page.png" alt="Page" title="Page" /></title>
+                       <span class="include-title">geshi.php</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html">geshi.php</a> in geshi.php</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_ACTIVE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_ACTIVE">GESHI_ACTIVE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :active state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_CAPS_LOWER</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_CAPS_LOWER">GESHI_CAPS_LOWER</a> in geshi.php</div>
+                                                       <div class="index-item-description">Leave keywords found as the case that they are</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_CAPS_NO_CHANGE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_CAPS_NO_CHANGE">GESHI_CAPS_NO_CHANGE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Lowercase keywords found</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_CAPS_UPPER</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_CAPS_UPPER">GESHI_CAPS_UPPER</a> in geshi.php</div>
+                                                       <div class="index-item-description">Uppercase keywords found</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_END_IMPORTANT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_END_IMPORTANT">GESHI_END_IMPORTANT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The ender for important parts of the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_FANCY_LINE_NUMBERS</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS">GESHI_FANCY_LINE_NUMBERS</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use fancy line numbers when building the result</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_DIV</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_DIV">GESHI_HEADER_DIV</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a &quot;div&quot; to surround the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_NONE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_NONE">GESHI_HEADER_NONE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use nothing to surround the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_PRE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE">GESHI_HEADER_PRE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a &quot;pre&quot; to surround the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_PRE_TABLE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE">GESHI_HEADER_PRE_TABLE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a &quot;table&quot; to surround the source:</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_PRE_VALID</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID">GESHI_HEADER_PRE_VALID</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a pre to wrap lines when line numbers are enabled or to wrap the whole code.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Function.png" alt="Function" title="Function" /></title>
+                       <span class="method-title">geshi_highlight</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#functiongeshi_highlight">geshi_highlight()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Easy way to highlight stuff. Behaves just like highlight_string</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HOVER</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HOVER">GESHI_HOVER</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :hover state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_LANG_ROOT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_LANG_ROOT">GESHI_LANG_ROOT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The language file directory for GeSHi</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_LINK</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_LINK">GESHI_LINK</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :link state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_NORMAL_LINE_NUMBERS</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_NORMAL_LINE_NUMBERS">GESHI_NORMAL_LINE_NUMBERS</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use normal line numbers when building the result</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_NO_LINE_NUMBERS</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS">GESHI_NO_LINE_NUMBERS</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use no line numbers when building the result</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_ROOT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_ROOT">GESHI_ROOT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The root directory for GeSHi</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_SECURITY_PARANOID</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_SECURITY_PARANOID">GESHI_SECURITY_PARANOID</a> in geshi.php</div>
+                                                       <div class="index-item-description">Tells GeSHi to be paranoid about security settings</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_START_IMPORTANT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT">GESHI_START_IMPORTANT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The starter for important parts of the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_VERSION</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_VERSION">GESHI_VERSION</a> in geshi.php</div>
+                                                       <div class="index-item-description">The version of this GeSHi file</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_VISITED</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_VISITED">GESHI_VISITED</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :visited state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_language_name</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_language_name">GeSHi::get_language_name()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Gets a human-readable language name (thanks to Simon Patterson  for the idea :))</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_language_name_from_extension</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_language_name_from_extension">GeSHi::get_language_name_from_extension()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Given a file extension, this method returns either a valid geshi language  name, or the empty string if it couldn't be found</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_multiline_span</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_multiline_span">GeSHi::get_multiline_span()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Get current setting for multiline spans, see GeSHi-&gt;enable_multiline_span().</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_real_tab_width</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_real_tab_width">GeSHi::get_real_tab_width()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns the tab width to use, based on the current language and user  preference</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_stylesheet</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_stylesheet">GeSHi::get_stylesheet()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns a stylesheet for the highlighted code. If $economy mode  is true, we only return the stylesheet declarations that matter for  this code block instead of the whole thing</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_time</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_time">GeSHi::get_time()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Gets the time taken to parse the code</div>
+                                       </dd>
+               </dl>
+       <a name="h"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">h</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">highlight_lines_extra</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodhighlight_lines_extra">GeSHi::highlight_lines_extra()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Specifies which lines to highlight extra</div>
+                                       </dd>
+               </dl>
+       <a name="l"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">l</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">load_from_file</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodload_from_file">GeSHi::load_from_file()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Given a file name, this method loads its contents in, and attempts</div>
+                                       </dd>
+               </dl>
+       <a name="o"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">o</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">optimize_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodoptimize_keyword_group">GeSHi::optimize_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">compile optimized regexp list for keyword group</div>
+                                       </dd>
+               </dl>
+       <a name="p"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">p</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">parse_code</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodparse_code">GeSHi::parse_code()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns the code in $this-&gt;source, highlighted and surrounded by the  nessecary HTML.</div>
+                                       </dd>
+               </dl>
+       <a name="r"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">r</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">remove_keyword</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodremove_keyword">GeSHi::remove_keyword()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Removes a keyword from a keyword group</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">remove_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodremove_keyword_group">GeSHi::remove_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Removes a keyword group</div>
+                                       </dd>
+               </dl>
+       <a name="s"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">s</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_brackets_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_brackets_highlighting">GeSHi::set_brackets_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for brackets</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_brackets_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_brackets_style">GeSHi::set_brackets_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for brackets. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_case_keywords</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_case_keywords">GeSHi::set_case_keywords()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the case that keywords should use when found. Use the constants:</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_case_sensitivity</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_case_sensitivity">GeSHi::set_case_sensitivity()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether a set of keywords are checked for in a case sensitive manner</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_code_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_code_style">GeSHi::set_code_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for the actual code. This should be a string</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_comments_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_comments_highlighting">GeSHi::set_comments_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for comment groups</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_comments_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_comments_style">GeSHi::set_comments_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for comment groups.  If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_encoding</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_encoding">GeSHi::set_encoding()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the encoding used for htmlspecialchars(), for international  support.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_escape_characters_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_escape_characters_highlighting">GeSHi::set_escape_characters_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for escaped characters</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_escape_characters_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_escape_characters_style">GeSHi::set_escape_characters_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for escaped characters. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_footer_content</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_footer_content">GeSHi::set_footer_content()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the content of the footer block</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_footer_content_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_footer_content_style">GeSHi::set_footer_content_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for the footer content</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_header_content</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_header_content">GeSHi::set_header_content()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the content of the header block</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_header_content_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_header_content_style">GeSHi::set_header_content_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for the header content</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_header_type</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_header_type">GeSHi::set_header_type()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the type of header to be used.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_highlight_lines_extra_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_highlight_lines_extra_style">GeSHi::set_highlight_lines_extra_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for extra-highlighted lines</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_important_styles</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_important_styles">GeSHi::set_important_styles()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets styles for important parts of the code</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_keyword_group_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_keyword_group_highlighting">GeSHi::set_keyword_group_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for a keyword group</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_keyword_group_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_keyword_group_style">GeSHi::set_keyword_group_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for a keyword group. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_language</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_language">GeSHi::set_language()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the language for this object</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_language_path</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_language_path">GeSHi::set_language_path()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the path to the directory containing the language files. Note  that this path is relative to the directory of the script that included  geshi.php, NOT geshi.php itself.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_line_ending</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_line_ending">GeSHi::set_line_ending()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the line-ending</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_line_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_line_style">GeSHi::set_line_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for the line numbers.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_link_styles</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_link_styles">GeSHi::set_link_styles()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets styles for links in code</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_link_target</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_link_target">GeSHi::set_link_target()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the target for links in code</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_methods_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_methods_highlighting">GeSHi::set_methods_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for methods</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_methods_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_methods_style">GeSHi::set_methods_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for methods. $key is a number that references the</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_numbers_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_numbers_highlighting">GeSHi::set_numbers_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for numbers</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_numbers_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_numbers_style">GeSHi::set_numbers_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for numbers. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_overall_class</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_overall_class">GeSHi::set_overall_class()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the overall classname for this block of code. This  class can then be used in a stylesheet to style this object's  output</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_overall_id</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_overall_id">GeSHi::set_overall_id()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the overall id for this block of code. This id can then  be used in a stylesheet to style this object's output</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_overall_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_overall_style">GeSHi::set_overall_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for the code that will be outputted  when this object is parsed. The style should be a  string of valid stylesheet declarations</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_regexps_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_regexps_highlighting">GeSHi::set_regexps_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for regexps</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_regexps_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_regexps_style">GeSHi::set_regexps_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for regexps. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_source</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_source">GeSHi::set_source()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the source code for this object</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_strings_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_strings_highlighting">GeSHi::set_strings_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for strings</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_strings_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_strings_style">GeSHi::set_strings_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for strings. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_symbols_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_symbols_highlighting">GeSHi::set_symbols_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for symbols</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_symbols_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_symbols_style">GeSHi::set_symbols_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for symbols. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_tab_width</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_tab_width">GeSHi::set_tab_width()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets how many spaces a tab is substituted for</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_url_for_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_url_for_keyword_group">GeSHi::set_url_for_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the base URL to be used for keywords</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_use_language_tab_width</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_use_language_tab_width">GeSHi::set_use_language_tab_width()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether or not to use tab-stop width specifed by language</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">start_line_numbers_at</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodstart_line_numbers_at">GeSHi::start_line_numbers_at()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets what number line numbers should start at. Should  be a positive integer, and will be converted to one.</div>
+                                       </dd>
+               </dl>
+
+<div class="index-letter-menu">
+       <a class="index-letter" href="elementindex.html#a">a</a>
+       <a class="index-letter" href="elementindex.html#d">d</a>
+       <a class="index-letter" href="elementindex.html#e">e</a>
+       <a class="index-letter" href="elementindex.html#g">g</a>
+       <a class="index-letter" href="elementindex.html#h">h</a>
+       <a class="index-letter" href="elementindex.html#l">l</a>
+       <a class="index-letter" href="elementindex.html#o">o</a>
+       <a class="index-letter" href="elementindex.html#p">p</a>
+       <a class="index-letter" href="elementindex.html#r">r</a>
+       <a class="index-letter" href="elementindex.html#s">s</a>
+</div> </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/elementindex_geshi.html b/examples/includes/geshi/docs/api/elementindex_geshi.html
new file mode 100644 (file)
index 0000000..f319396
--- /dev/null
@@ -0,0 +1,864 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title></title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               <a name="top"></a>
+<h2>[geshi] element index</h2>
+<a href="elementindex.html">All elements</a>
+<br />
+<div class="index-letter-menu">
+       <a class="index-letter" href="elementindex_geshi.html#a">a</a>
+       <a class="index-letter" href="elementindex_geshi.html#d">d</a>
+       <a class="index-letter" href="elementindex_geshi.html#e">e</a>
+       <a class="index-letter" href="elementindex_geshi.html#g">g</a>
+       <a class="index-letter" href="elementindex_geshi.html#h">h</a>
+       <a class="index-letter" href="elementindex_geshi.html#l">l</a>
+       <a class="index-letter" href="elementindex_geshi.html#o">o</a>
+       <a class="index-letter" href="elementindex_geshi.html#p">p</a>
+       <a class="index-letter" href="elementindex_geshi.html#r">r</a>
+       <a class="index-letter" href="elementindex_geshi.html#s">s</a>
+</div>
+
+       <a name="a"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">a</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">add_keyword</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodadd_keyword">GeSHi::add_keyword()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Adds a keyword to a keyword group for highlighting</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">add_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodadd_keyword_group">GeSHi::add_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Creates a new keyword group</div>
+                                       </dd>
+               </dl>
+       <a name="d"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">d</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">disable_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methoddisable_highlighting">GeSHi::disable_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Disables all highlighting</div>
+                                       </dd>
+               </dl>
+       <a name="e"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">e</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_classes</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_classes">GeSHi::enable_classes()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether CSS classes should be used to highlight the source. Default  is off, calling this method with no arguments will turn it on</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_highlighting">GeSHi::enable_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Enables all highlighting</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_ids</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_ids">GeSHi::enable_ids()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Whether CSS IDs should be added to each line</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_important_blocks</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_important_blocks">GeSHi::enable_important_blocks()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether context-important blocks are highlighted</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_inner_code_block</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_inner_code_block">GeSHi::enable_inner_code_block()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether to force a surrounding block around  the highlighted code or not</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_keyword_links</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_keyword_links">GeSHi::enable_keyword_links()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns linking of keywords on or off.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_line_numbers</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_line_numbers">GeSHi::enable_line_numbers()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether line numbers should be displayed.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_multiline_span</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_multiline_span">GeSHi::enable_multiline_span()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets wether spans and other HTML markup generated by GeSHi can  span over multiple lines or not. Defaults to true to reduce overhead.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">enable_strict_mode</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodenable_strict_mode">GeSHi::enable_strict_mode()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Enables/disables strict highlighting. Default is off, calling this  method without parameters will turn it on. See documentation  for more details on strict mode and where to use it.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">error</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methoderror">GeSHi::error()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns an error message associated with the last GeSHi operation,  or false if no error has occured</div>
+                                       </dd>
+               </dl>
+       <a name="g"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">g</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Constructor.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">GeSHi</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodGeSHi">GeSHi::GeSHi()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Creates a new GeSHi object, with source and language</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Class.png" alt="Class" title="Class" /></title>
+                       GeSHi
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html">GeSHi</a> in geshi.php</div>
+                                                       <div class="index-item-description">The GeSHi Class.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Page.png" alt="Page" title="Page" /></title>
+                       <span class="include-title">geshi.php</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html">geshi.php</a> in geshi.php</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_ACTIVE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_ACTIVE">GESHI_ACTIVE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :active state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_CAPS_LOWER</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_CAPS_LOWER">GESHI_CAPS_LOWER</a> in geshi.php</div>
+                                                       <div class="index-item-description">Leave keywords found as the case that they are</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_CAPS_NO_CHANGE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_CAPS_NO_CHANGE">GESHI_CAPS_NO_CHANGE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Lowercase keywords found</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_CAPS_UPPER</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_CAPS_UPPER">GESHI_CAPS_UPPER</a> in geshi.php</div>
+                                                       <div class="index-item-description">Uppercase keywords found</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_END_IMPORTANT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_END_IMPORTANT">GESHI_END_IMPORTANT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The ender for important parts of the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_FANCY_LINE_NUMBERS</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_FANCY_LINE_NUMBERS">GESHI_FANCY_LINE_NUMBERS</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use fancy line numbers when building the result</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_DIV</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_DIV">GESHI_HEADER_DIV</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a &quot;div&quot; to surround the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_NONE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_NONE">GESHI_HEADER_NONE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use nothing to surround the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_PRE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE">GESHI_HEADER_PRE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a &quot;pre&quot; to surround the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_PRE_TABLE</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_TABLE">GESHI_HEADER_PRE_TABLE</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a &quot;table&quot; to surround the source:</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HEADER_PRE_VALID</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HEADER_PRE_VALID">GESHI_HEADER_PRE_VALID</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use a pre to wrap lines when line numbers are enabled or to wrap the whole code.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Function.png" alt="Function" title="Function" /></title>
+                       <span class="method-title">geshi_highlight</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#functiongeshi_highlight">geshi_highlight()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Easy way to highlight stuff. Behaves just like highlight_string</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_HOVER</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_HOVER">GESHI_HOVER</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :hover state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_LANG_ROOT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_LANG_ROOT">GESHI_LANG_ROOT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The language file directory for GeSHi</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_LINK</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_LINK">GESHI_LINK</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :link state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_NORMAL_LINE_NUMBERS</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_NORMAL_LINE_NUMBERS">GESHI_NORMAL_LINE_NUMBERS</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use normal line numbers when building the result</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_NO_LINE_NUMBERS</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_NO_LINE_NUMBERS">GESHI_NO_LINE_NUMBERS</a> in geshi.php</div>
+                                                       <div class="index-item-description">Use no line numbers when building the result</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_ROOT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_ROOT">GESHI_ROOT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The root directory for GeSHi</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_SECURITY_PARANOID</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_SECURITY_PARANOID">GESHI_SECURITY_PARANOID</a> in geshi.php</div>
+                                                       <div class="index-item-description">Tells GeSHi to be paranoid about security settings</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_START_IMPORTANT</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_START_IMPORTANT">GESHI_START_IMPORTANT</a> in geshi.php</div>
+                                                       <div class="index-item-description">The starter for important parts of the source</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_VERSION</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_VERSION">GESHI_VERSION</a> in geshi.php</div>
+                                                       <div class="index-item-description">The version of this GeSHi file</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Constant.png" alt="Constant" title="Constant" /></title>
+                       <span class="const-title">GESHI_VISITED</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/_geshi.php.html#defineGESHI_VISITED">GESHI_VISITED</a> in geshi.php</div>
+                                                       <div class="index-item-description">Links in the source in the :visited state</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_language_name</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_language_name">GeSHi::get_language_name()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Gets a human-readable language name (thanks to Simon Patterson  for the idea :))</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_language_name_from_extension</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_language_name_from_extension">GeSHi::get_language_name_from_extension()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Given a file extension, this method returns either a valid geshi language  name, or the empty string if it couldn't be found</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_multiline_span</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_multiline_span">GeSHi::get_multiline_span()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Get current setting for multiline spans, see GeSHi-&gt;enable_multiline_span().</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_real_tab_width</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_real_tab_width">GeSHi::get_real_tab_width()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns the tab width to use, based on the current language and user  preference</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_stylesheet</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_stylesheet">GeSHi::get_stylesheet()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns a stylesheet for the highlighted code. If $economy mode  is true, we only return the stylesheet declarations that matter for  this code block instead of the whole thing</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">get_time</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodget_time">GeSHi::get_time()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Gets the time taken to parse the code</div>
+                                       </dd>
+               </dl>
+       <a name="h"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">h</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">highlight_lines_extra</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodhighlight_lines_extra">GeSHi::highlight_lines_extra()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Specifies which lines to highlight extra</div>
+                                       </dd>
+               </dl>
+       <a name="l"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">l</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">load_from_file</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodload_from_file">GeSHi::load_from_file()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Given a file name, this method loads its contents in, and attempts</div>
+                                       </dd>
+               </dl>
+       <a name="o"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">o</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">optimize_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodoptimize_keyword_group">GeSHi::optimize_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">compile optimized regexp list for keyword group</div>
+                                       </dd>
+               </dl>
+       <a name="p"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">p</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">parse_code</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodparse_code">GeSHi::parse_code()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Returns the code in $this-&gt;source, highlighted and surrounded by the  nessecary HTML.</div>
+                                       </dd>
+               </dl>
+       <a name="r"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">r</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">remove_keyword</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodremove_keyword">GeSHi::remove_keyword()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Removes a keyword from a keyword group</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">remove_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodremove_keyword_group">GeSHi::remove_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Removes a keyword group</div>
+                                       </dd>
+               </dl>
+       <a name="s"></a>
+       <div class="index-letter-section">
+               <div style="float: left" class="index-letter-title">s</div>
+               <div style="float: right"><a href="#top">top</a></div>
+               <div style="clear: both"></div>
+       </div>
+       <dl>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_brackets_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_brackets_highlighting">GeSHi::set_brackets_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for brackets</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_brackets_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_brackets_style">GeSHi::set_brackets_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for brackets. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_case_keywords</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_case_keywords">GeSHi::set_case_keywords()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the case that keywords should use when found. Use the constants:</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_case_sensitivity</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_case_sensitivity">GeSHi::set_case_sensitivity()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether a set of keywords are checked for in a case sensitive manner</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_code_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_code_style">GeSHi::set_code_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for the actual code. This should be a string</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_comments_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_comments_highlighting">GeSHi::set_comments_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for comment groups</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_comments_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_comments_style">GeSHi::set_comments_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for comment groups.  If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_encoding</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_encoding">GeSHi::set_encoding()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the encoding used for htmlspecialchars(), for international  support.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_escape_characters_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_escape_characters_highlighting">GeSHi::set_escape_characters_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for escaped characters</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_escape_characters_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_escape_characters_style">GeSHi::set_escape_characters_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for escaped characters. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_footer_content</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_footer_content">GeSHi::set_footer_content()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the content of the footer block</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_footer_content_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_footer_content_style">GeSHi::set_footer_content_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for the footer content</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_header_content</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_header_content">GeSHi::set_header_content()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the content of the header block</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_header_content_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_header_content_style">GeSHi::set_header_content_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for the header content</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_header_type</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_header_type">GeSHi::set_header_type()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the type of header to be used.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_highlight_lines_extra_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_highlight_lines_extra_style">GeSHi::set_highlight_lines_extra_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for extra-highlighted lines</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_important_styles</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_important_styles">GeSHi::set_important_styles()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets styles for important parts of the code</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_keyword_group_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_keyword_group_highlighting">GeSHi::set_keyword_group_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for a keyword group</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_keyword_group_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_keyword_group_style">GeSHi::set_keyword_group_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the style for a keyword group. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_language</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_language">GeSHi::set_language()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the language for this object</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_language_path</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_language_path">GeSHi::set_language_path()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the path to the directory containing the language files. Note  that this path is relative to the directory of the script that included  geshi.php, NOT geshi.php itself.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_line_ending</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_line_ending">GeSHi::set_line_ending()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the line-ending</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_line_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_line_style">GeSHi::set_line_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for the line numbers.</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_link_styles</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_link_styles">GeSHi::set_link_styles()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets styles for links in code</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_link_target</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_link_target">GeSHi::set_link_target()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the target for links in code</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_methods_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_methods_highlighting">GeSHi::set_methods_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for methods</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_methods_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_methods_style">GeSHi::set_methods_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for methods. $key is a number that references the</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_numbers_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_numbers_highlighting">GeSHi::set_numbers_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for numbers</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_numbers_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_numbers_style">GeSHi::set_numbers_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for numbers. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_overall_class</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_overall_class">GeSHi::set_overall_class()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the overall classname for this block of code. This  class can then be used in a stylesheet to style this object's  output</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_overall_id</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_overall_id">GeSHi::set_overall_id()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the overall id for this block of code. This id can then  be used in a stylesheet to style this object's output</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_overall_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_overall_style">GeSHi::set_overall_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for the code that will be outputted  when this object is parsed. The style should be a  string of valid stylesheet declarations</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_regexps_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_regexps_highlighting">GeSHi::set_regexps_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for regexps</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_regexps_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_regexps_style">GeSHi::set_regexps_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for regexps. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_source</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_source">GeSHi::set_source()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the source code for this object</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_strings_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_strings_highlighting">GeSHi::set_strings_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for strings</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_strings_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_strings_style">GeSHi::set_strings_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for strings. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_symbols_highlighting</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_symbols_highlighting">GeSHi::set_symbols_highlighting()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Turns highlighting on/off for symbols</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_symbols_style</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_symbols_style">GeSHi::set_symbols_style()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the styles for symbols. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_tab_width</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_tab_width">GeSHi::set_tab_width()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets how many spaces a tab is substituted for</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_url_for_keyword_group</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_url_for_keyword_group">GeSHi::set_url_for_keyword_group()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets the base URL to be used for keywords</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">set_use_language_tab_width</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodset_use_language_tab_width">GeSHi::set_use_language_tab_width()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets whether or not to use tab-stop width specifed by language</div>
+                                       </dd>
+                       <dt class="field">
+                                               <img src="media/images/Method.png" alt="Method" title="Method" /></title>
+                       <span class="method-title">start_line_numbers_at</span>
+                                       </dt>
+               <dd class="index-item-body">
+                       <div class="index-item-details"><a href="geshi/core/GeSHi.html#methodstart_line_numbers_at">GeSHi::start_line_numbers_at()</a> in geshi.php</div>
+                                                       <div class="index-item-description">Sets what number line numbers should start at. Should  be a positive integer, and will be converted to one.</div>
+                                       </dd>
+               </dl>
+
+<div class="index-letter-menu">
+       <a class="index-letter" href="elementindex_geshi.html#a">a</a>
+       <a class="index-letter" href="elementindex_geshi.html#d">d</a>
+       <a class="index-letter" href="elementindex_geshi.html#e">e</a>
+       <a class="index-letter" href="elementindex_geshi.html#g">g</a>
+       <a class="index-letter" href="elementindex_geshi.html#h">h</a>
+       <a class="index-letter" href="elementindex_geshi.html#l">l</a>
+       <a class="index-letter" href="elementindex_geshi.html#o">o</a>
+       <a class="index-letter" href="elementindex_geshi.html#p">p</a>
+       <a class="index-letter" href="elementindex_geshi.html#r">r</a>
+       <a class="index-letter" href="elementindex_geshi.html#s">s</a>
+</div> </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/errors.html b/examples/includes/geshi/docs/api/errors.html
new file mode 100644 (file)
index 0000000..c917f03
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title>phpDocumentor Parser Errors and Warnings</title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               <a href="#Post-parsing">Post-parsing</a><br>
+<a name="geshi.php"></a>
+<h1>geshi.php</h1>
+<h2>Errors:</h2><br>
+<b>Error on line 569</b> - DocBlock has multiple @access tags, illegal. ignoring additional tag "@access private"<br>
+       <p class="notes" id="credit">
+               Documentation generated on Thu, 25 Dec 2008 14:34:53 +0100 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.4.2</a>
+       </p>
+       </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/geshi/core/GeSHi.html b/examples/includes/geshi/docs/api/geshi/core/GeSHi.html
new file mode 100644 (file)
index 0000000..a8ccc7d
--- /dev/null
@@ -0,0 +1,2676 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title>Docs For Class GeSHi</title>
+                       <link rel="stylesheet" href="../../media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                       <div class="page-body">                 
+<h2 class="class-name"><img src="../../media/images/Class_logo.png"
+                                                                                                               alt=" Class"
+                                                                                                               title=" Class"
+                                                                                                               style="vertical-align: middle"> GeSHi</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+       <div class="info-box-title">Description</div>
+       <div class="nav-bar">
+                                       <span class="disabled">Description</span> |
+                                                                                                                       <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+                                               
+                                       </div>
+       <div class="info-box-body">
+                       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The GeSHi Class.</p>
+<p class="description"><p>Please refer to the documentation for GeSHi 1.0.X that is available  at http://qbnz.com/highlighter/documentation.php for more information  about how to use this class.</p></p>
+       <ul class="tags">
+                               <li><span class="field">author:</span> Nigel McNie &lt;<a href="mailto:nigel@geshi.org">nigel@geshi.org</a>&gt;, Benny Baumann &lt;BenBE@omorphia.de&gt;</li>
+                               <li><span class="field">copyright:</span> (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann</li>
+                       </ul>
+               <p class="notes">
+                       Located in <a class="field" href="_geshi.php.html">/geshi.php</a> (line <span class="field"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a253">253</a></span>)
+               </p>
+               
+                               
+               <pre></pre>
+       
+                       </div>
+</div>
+
+
+
+
+       <a name="sec-method-summary"></a>
+       <div class="info-box">
+               <div class="info-box-title">Method Summary</span></div>
+               <div class="nav-bar">
+                       <a href="#sec-description">Description</a> |
+                                                                                               <span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+               </div>
+               <div class="info-box-body">                     
+                       <div class="method-summary">
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Constructor.png" alt=" "/>
+                                                                                       <span class="method-result">GeSHi</span>
+                                                                               <a href="#GeSHi" title="details" class="method-name">GeSHi</a>
+                                                                                       ([<span class="var-type">string</span>&nbsp;<span class="var-name">$source</span> = <span class="var-default">''</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$language</span> = <span class="var-default">''</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span> = <span class="var-default">''</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#add_keyword" title="details" class="method-name">add_keyword</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$word</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#add_keyword_group" title="details" class="method-name">add_keyword_group</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$case_sensitive</span> = <span class="var-default">true</span>], [<span class="var-type">array</span>&nbsp;<span class="var-name">$words</span> = <span class="var-default">array()</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#disable_highlighting" title="details" class="method-name">disable_highlighting</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_classes" title="details" class="method-name">enable_classes</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_highlighting" title="details" class="method-name">enable_highlighting</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_ids" title="details" class="method-name">enable_ids</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_important_blocks" title="details" class="method-name">enable_important_blocks</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_inner_code_block" title="details" class="method-name">enable_inner_code_block</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_keyword_links" title="details" class="method-name">enable_keyword_links</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$enable</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_line_numbers" title="details" class="method-name">enable_line_numbers</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$flag</span>, [<span class="var-type">int</span>&nbsp;<span class="var-name">$nth_row</span> = <span class="var-default">5</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_multiline_span" title="details" class="method-name">enable_multiline_span</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#enable_strict_mode" title="details" class="method-name">enable_strict_mode</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$mode</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">string|false</span>
+                                                                               <a href="#error" title="details" class="method-name">error</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">string</span>
+                                                                               <a href="#get_language_name" title="details" class="method-name">get_language_name</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#get_language_name_from_extension" title="details" class="method-name">get_language_name_from_extension</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$extension</span>, [<span class="var-type">array</span>&nbsp;<span class="var-name">$lookup</span> = <span class="var-default">array()</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">bool</span>
+                                                                               <a href="#get_multiline_span" title="details" class="method-name">get_multiline_span</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">int</span>
+                                                                               <a href="#get_real_tab_width" title="details" class="method-name">get_real_tab_width</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">string</span>
+                                                                               <a href="#get_stylesheet" title="details" class="method-name">get_stylesheet</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$economy_mode</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">double</span>
+                                                                               <a href="#get_time" title="details" class="method-name">get_time</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#highlight_lines_extra" title="details" class="method-name">highlight_lines_extra</a>
+                                                                                       (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$lines</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span> = <span class="var-default">null</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#load_from_file" title="details" class="method-name">load_from_file</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$file_name</span>, [<span class="var-type">array</span>&nbsp;<span class="var-name">$lookup</span> = <span class="var-default">array()</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#optimize_keyword_group" title="details" class="method-name">optimize_keyword_group</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#parse_code" title="details" class="method-name">parse_code</a>
+                                                                               ()
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#remove_keyword" title="details" class="method-name">remove_keyword</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$word</span>, [<span class="var-type">bool</span>&nbsp;<span class="var-name">$recompile</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#remove_keyword_group" title="details" class="method-name">remove_keyword_group</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_brackets_highlighting" title="details" class="method-name">set_brackets_highlighting</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_brackets_style" title="details" class="method-name">set_brackets_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_case_keywords" title="details" class="method-name">set_case_keywords</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$case</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_case_sensitivity" title="details" class="method-name">set_case_sensitivity</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">boolean</span>&nbsp;<span class="var-name">$case</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_code_style" title="details" class="method-name">set_code_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_comments_highlighting" title="details" class="method-name">set_comments_highlighting</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_comments_style" title="details" class="method-name">set_comments_style</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_encoding" title="details" class="method-name">set_encoding</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_escape_characters_highlighting" title="details" class="method-name">set_escape_characters_highlighting</a>
+                                                                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_escape_characters_style" title="details" class="method-name">set_escape_characters_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_footer_content" title="details" class="method-name">set_footer_content</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$content</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_footer_content_style" title="details" class="method-name">set_footer_content_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_header_content" title="details" class="method-name">set_header_content</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$content</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_header_content_style" title="details" class="method-name">set_header_content_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_header_type" title="details" class="method-name">set_header_type</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$type</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_highlight_lines_extra_style" title="details" class="method-name">set_highlight_lines_extra_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_important_styles" title="details" class="method-name">set_important_styles</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_keyword_group_highlighting" title="details" class="method-name">set_keyword_group_highlighting</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_keyword_group_style" title="details" class="method-name">set_keyword_group_style</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_language" title="details" class="method-name">set_language</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$language</span>, [<span class="var-type"></span>&nbsp;<span class="var-name">$force_reset</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_language_path" title="details" class="method-name">set_language_path</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_line_ending" title="details" class="method-name">set_line_ending</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$line_ending</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_line_style" title="details" class="method-name">set_line_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style1</span>, [<span class="var-type">string|boolean</span>&nbsp;<span class="var-name">$style2</span> = <span class="var-default">''</span>], [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_link_styles" title="details" class="method-name">set_link_styles</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$type</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_link_target" title="details" class="method-name">set_link_target</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$target</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_methods_highlighting" title="details" class="method-name">set_methods_highlighting</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_methods_style" title="details" class="method-name">set_methods_style</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_numbers_highlighting" title="details" class="method-name">set_numbers_highlighting</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_numbers_style" title="details" class="method-name">set_numbers_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_overall_class" title="details" class="method-name">set_overall_class</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$class</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_overall_id" title="details" class="method-name">set_overall_id</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$id</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_overall_style" title="details" class="method-name">set_overall_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_regexps_highlighting" title="details" class="method-name">set_regexps_highlighting</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_regexps_style" title="details" class="method-name">set_regexps_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">boolean</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type"></span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_source" title="details" class="method-name">set_source</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$source</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_strings_highlighting" title="details" class="method-name">set_strings_highlighting</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_strings_style" title="details" class="method-name">set_strings_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_symbols_highlighting" title="details" class="method-name">set_symbols_highlighting</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_symbols_style" title="details" class="method-name">set_symbols_style</a>
+                                                                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>], [<span class="var-type">int</span>&nbsp;<span class="var-name">$group</span> = <span class="var-default">0</span>])
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_tab_width" title="details" class="method-name">set_tab_width</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$width</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_url_for_keyword_group" title="details" class="method-name">set_url_for_keyword_group</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$group</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$url</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#set_use_language_tab_width" title="details" class="method-name">set_use_language_tab_width</a>
+                                                                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$use</span>)
+                                                                       </div>
+                                                                                                                               <div class="method-definition">
+                                       <img src="../../media/images/Method.png" alt=" "/>
+                                                                                       <span class="method-result">void</span>
+                                                                               <a href="#start_line_numbers_at" title="details" class="method-name">start_line_numbers_at</a>
+                                                                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$number</span>)
+                                                                       </div>
+                                                                                       </div>
+               </div>
+       </div>          
+
+       
+       <a name="sec-methods"></a>
+       <div class="info-box">
+               <div class="info-box-title">Methods</div>
+               <div class="nav-bar">
+                       <a href="#sec-description">Description</a> |
+                                                                                                       <a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+                                               
+               </div>
+               <div class="info-box-body">
+                       <A NAME='method_detail'></A>
+<a name="methodGeSHi" id="GeSHi"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Constructor.png" />
+               <span class="method-title">Constructor GeSHi</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a591">591</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Creates a new GeSHi object, with source and language</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">GeSHi</span>
+               <span class="method-name">
+                       GeSHi
+               </span>
+                                       ([<span class="var-type">string</span>&nbsp;<span class="var-name">$source</span> = <span class="var-default">''</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$language</span> = <span class="var-default">''</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span> = <span class="var-default">''</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$source</span><span class="var-description">: The source code to highlight</span>                        </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$language</span><span class="var-description">: The language to highlight the source with</span>                 </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$path</span><span class="var-description">: The path to the language file directory. <strong>This
+               is deprecated!</strong> I've backported the auto path                detection from the 1.1.X dev branch, so now it                should be automatically set correctly. If you have                renamed the language directory however, you will                still need to set the path using this parameter or                GeSHi->set_language_path()</span>                        </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodadd_keyword" id="add_keyword"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">add_keyword</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1441">1441</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a keyword to a keyword group for highlighting</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       add_keyword
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$word</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to add the keyword to</span>                     </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$word</span><span class="var-description">: The word to add to the keyword group</span>                  </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodadd_keyword_group" id="add_keyword_group"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">add_keyword_group</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1487">1487</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Creates a new keyword group</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       add_keyword_group
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$case_sensitive</span> = <span class="var-default">true</span>], [<span class="var-type">array</span>&nbsp;<span class="var-name">$words</span> = <span class="var-default">array()</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to create</span>                 </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$styles</span><span class="var-description">: The styles for the keyword group</span>                    </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$case_sensitive</span><span class="var-description">: Whether the keyword group is case sensitive ornot</span>                   </li>
+                                       <li>
+                               <span class="var-type">array</span>
+                               <span class="var-name">$words</span><span class="var-description">: The words to use for the keyword group</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methoddisable_highlighting" id="disable_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">disable_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1288">1288</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Disables all highlighting</p>
+       <ul class="tags">
+                               <li><span class="field">deprecated:</span> In favour of enable_highlighting</li>
+                               <li><span class="field">todo:</span> Rewrite with array traversal</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       disable_highlighting
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodenable_classes" id="enable_classes"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_classes</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a805">805</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether CSS classes should be used to highlight the source. Default  is off, calling this method with no arguments will turn it on</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_classes
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn classes on or not</span>                     </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_highlighting" id="enable_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1302">1302</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Enables all highlighting</p>
+<p class="description"><p>The optional flag parameter was added in version 1.0.7.21 and can be used  to enable (true) or disable (false) all highlighting.</p></p>
+       <ul class="tags">
+                               <li><span class="field">todo:</span> Rewrite with array traversal</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_highlighting
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: A flag specifying whether to enable or disable all highlighting</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_ids" id="enable_ids"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_ids</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1652">1652</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Whether CSS IDs should be added to each line</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_ids
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: If true, IDs will be added to each line.</span>                      </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_important_blocks" id="enable_important_blocks"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_important_blocks</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1642">1642</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether context-important blocks are highlighted</p>
+       <ul class="tags">
+                               <li><span class="field">deprecated:</span> </li>
+                               <li><span class="field">todo:</span> REMOVE THIS SHIZ FROM GESHI!</li>
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_important_blocks
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Tells whether to enable or disable highlighting of important blocks</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_inner_code_block" id="enable_inner_code_block"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_inner_code_block</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1581">1581</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether to force a surrounding block around  the highlighted code or not</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.7.20</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_inner_code_block
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Tells whether to enable or disable this feature</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_keyword_links" id="enable_keyword_links"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_keyword_links</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1756">1756</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns linking of keywords on or off.</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_keyword_links
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$enable</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$enable</span><span class="var-description">: If true, links will be added to keywords</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_line_numbers" id="enable_line_numbers"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_line_numbers</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a878">878</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether line numbers should be displayed.</p>
+<p class="description"><p>Valid values for the first parameter are:</p><p><ul><li>GESHI_NO_LINE_NUMBERS: Line numbers will not be displayed</li><li>GESHI_NORMAL_LINE_NUMBERS: Line numbers will be displayed</li><li>GESHI_FANCY_LINE_NUMBERS: Fancy line numbers will be displayed</li></ul>  For fancy line numbers, the second parameter is used to signal which lines  are to be fancy. For example, if the value of this parameter is 5 then every  5th line will be fancy.</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_line_numbers
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$flag</span>, [<span class="var-type">int</span>&nbsp;<span class="var-name">$nth_row</span> = <span class="var-default">5</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$flag</span><span class="var-description">: How line numbers should be displayed</span>                  </li>
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$nth_row</span><span class="var-description">: Defines which lines are fancy</span>                      </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_multiline_span" id="enable_multiline_span"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_multiline_span</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a896">896</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets wether spans and other HTML markup generated by GeSHi can  span over multiple lines or not. Defaults to true to reduce overhead.</p>
+<p class="description"><p>Set it to false if you want to manipulate the output or manually display  the code in an ordered list.</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.7.22</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_multiline_span
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Wether multiline spans are allowed or not</span>                     </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodenable_strict_mode" id="enable_strict_mode"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">enable_strict_mode</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1275">1275</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Enables/disables strict highlighting. Default is off, calling this  method without parameters will turn it on. See documentation  for more details on strict mode and where to use it.</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       enable_strict_mode
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$mode</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$mode</span><span class="var-description">: Whether to enable strict mode or not</span>                  </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methoderror" id="error"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">error</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a608">608</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Returns an error message associated with the last GeSHi operation,  or false if no error has occured</p>
+       <ul class="tags">
+                               <li><span class="field">return:</span> An error message if there has been an error, else false</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">string|false</span>
+               <span class="method-name">
+                       error
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodget_language_name" id="get_language_name"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">get_language_name</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a632">632</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Gets a human-readable language name (thanks to Simon Patterson  for the idea :))</p>
+       <ul class="tags">
+                               <li><span class="field">return:</span> The name for the current language</li>
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">string</span>
+               <span class="method-name">
+                       get_language_name
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodget_language_name_from_extension" id="get_language_name_from_extension"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">get_language_name_from_extension</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1329">1329</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Given a file extension, this method returns either a valid geshi language  name, or the empty string if it couldn't be found</p>
+       <ul class="tags">
+                               <li><span class="field">todo:</span> Re-think about how this method works (maybe make it private and/or make it        a extension-&gt;lang lookup?)</li>
+                               <li><span class="field">todo:</span> static?</li>
+                               <li><span class="field">since:</span> 1.0.5</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       get_language_name_from_extension
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$extension</span>, [<span class="var-type">array</span>&nbsp;<span class="var-name">$lookup</span> = <span class="var-default">array()</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$extension</span><span class="var-description">: The extension to get a language name for</span>                 </li>
+                                       <li>
+                               <span class="var-type">array</span>
+                               <span class="var-name">$lookup</span><span class="var-description">: A lookup array to use instead of the default one</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodget_multiline_span" id="get_multiline_span"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">get_multiline_span</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a906">906</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Get current setting for multiline spans, see GeSHi-&gt;enable_multiline_span().</p>
+       <ul class="tags">
+                               <li><span class="field">see:</span> <a href="../../geshi/core/GeSHi.html#methodenable_multiline_span">GeSHi::enable_multiline_span()</a></li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">bool</span>
+               <span class="method-name">
+                       get_multiline_span
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodget_real_tab_width" id="get_real_tab_width"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">get_real_tab_width</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1258">1258</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Returns the tab width to use, based on the current language and user  preference</p>
+       <ul class="tags">
+                               <li><span class="field">return:</span> Tab width</li>
+                               <li><span class="field">since:</span> 1.0.7.20</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">int</span>
+               <span class="method-name">
+                       get_real_tab_width
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodget_stylesheet" id="get_stylesheet"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">get_stylesheet</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a4177">4177</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Returns a stylesheet for the highlighted code. If $economy mode  is true, we only return the stylesheet declarations that matter for  this code block instead of the whole thing</p>
+       <ul class="tags">
+                               <li><span class="field">return:</span> A stylesheet built on the data for the current language</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">string</span>
+               <span class="method-name">
+                       get_stylesheet
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$economy_mode</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$economy_mode</span><span class="var-description">: Whether to use economy mode or not</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodget_time" id="get_time"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">get_time</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a3524">3524</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Gets the time taken to parse the code</p>
+       <ul class="tags">
+                               <li><span class="field">return:</span> The time taken to parse the code</li>
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">double</span>
+               <span class="method-name">
+                       get_time
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodhighlight_lines_extra" id="highlight_lines_extra"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">highlight_lines_extra</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1670">1670</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Specifies which lines to highlight extra</p>
+<p class="description"><p>The extra style parameter was added in 1.0.7.21.</p></p>
+       <ul class="tags">
+                               <li><span class="field">todo:</span> Some data replication here that could be cut down on</li>
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       highlight_lines_extra
+               </span>
+                                       (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$lines</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span> = <span class="var-default">null</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">mixed</span>
+                               <span class="var-name">$lines</span><span class="var-description">: An array of line numbers to highlight, or just a line               number on its own.</span>                       </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: A string specifying the style to use for this line.               If null is specified, the default style is used.               If false is specified, the line will be removed from               special highlighting</span>                     </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodload_from_file" id="load_from_file"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">load_from_file</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1425">1425</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Given a file name, this method loads its contents in, and attempts</p>
+<p class="description"><p>to set the language automatically. An optional lookup table can be  passed for looking up the language name. If not specified a default  table is used</p><p>The language table is in the form  <pre>array(
+   'lang_name' => array('extension', 'extension', ...),
+   'lang_name' ...
+ );</pre></p></p>
+       <ul class="tags">
+                               <li><span class="field">todo:</span> Complete rethink of this and above method</li>
+                               <li><span class="field">since:</span> 1.0.5</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       load_from_file
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$file_name</span>, [<span class="var-type">array</span>&nbsp;<span class="var-name">$lookup</span> = <span class="var-default">array()</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$file_name</span><span class="var-description">: The filename to load the source from</span>                     </li>
+                                       <li>
+                               <span class="var-type">array</span>
+                               <span class="var-name">$lookup</span><span class="var-description">: A lookup array to use instead of the default one</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodoptimize_keyword_group" id="optimize_keyword_group"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">optimize_keyword_group</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1529">1529</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">compile optimized regexp list for keyword group</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.8</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       optimize_keyword_group
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to compile &amp; optimize</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodparse_code" id="parse_code"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">parse_code</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1992">1992</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Returns the code in $this-&gt;source, highlighted and surrounded by the  nessecary HTML.</p>
+<p class="description"><p>This should only be called ONCE, cos it's SLOW! If you want to highlight  the same source multiple times, you're better off doing a whole lot of  str_replaces to replace the &amp;lt;span&amp;gt;s</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       parse_code
+               </span>
+                               ()
+                       </div>
+       
+               
+                       
+       </div>
+<a name="methodremove_keyword" id="remove_keyword"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">remove_keyword</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1466">1466</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Removes a keyword from a keyword group</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       remove_keyword
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$word</span>, [<span class="var-type">bool</span>&nbsp;<span class="var-name">$recompile</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to remove the keyword from</span>                        </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$word</span><span class="var-description">: The word to remove from the keyword group</span>                     </li>
+                                       <li>
+                               <span class="var-type">bool</span>
+                               <span class="var-name">$recompile</span><span class="var-description">: Wether to automatically recompile the optimized regexp list or not.                Note: if you set this to false and @see GeSHi-&gt;parse_code() was already called once,                for the current language, you have to manually call @see GeSHi-&gt;optimize_keyword_group()                or the removed keyword will stay in cache and still be highlighted! On the other hand                it might be too expensive to recompile the regexp list for every removal if you want to                remove a lot of keywords.</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodremove_keyword_group" id="remove_keyword_group"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">remove_keyword_group</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1512">1512</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Removes a keyword group</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       remove_keyword_group
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to remove</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_brackets_highlighting" id="set_brackets_highlighting"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_brackets_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1036">1036</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for brackets</p>
+<p class="description"><p>This method is DEPRECATED: use set_symbols_highlighting instead.  This method will be remove in 1.2.X</p></p>
+       <ul class="tags">
+                               <li><span class="field">deprecated:</span> In favour of set_symbols_highlighting</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_brackets_highlighting
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for brackets on or off</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_brackets_style" id="set_brackets_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_brackets_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1018">1018</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for brackets. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+<p class="description"><p>This method is DEPRECATED: use set_symbols_style instead.  This method will be removed in 1.2.X</p></p>
+       <ul class="tags">
+                               <li><span class="field">deprecated:</span> In favour of set_symbols_style</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_brackets_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the brackets</span>                       </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_case_keywords" id="set_case_keywords"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_case_keywords</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1216">1216</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the case that keywords should use when found. Use the constants:</p>
+<p class="description"><p><ul><li>GESHI_CAPS_NO_CHANGE: leave keywords as-is</li><li>GESHI_CAPS_UPPER: convert all keywords to uppercase where found</li><li>GESHI_CAPS_LOWER: convert all keywords to lowercase where found</li></ul></p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.1</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_case_keywords
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$case</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$case</span><span class="var-description">: A constant specifying what to do with matched keywords</span>                        </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_case_sensitivity" id="set_case_sensitivity"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_case_sensitivity</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1202">1202</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether a set of keywords are checked for in a case sensitive manner</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_case_sensitivity
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">boolean</span>&nbsp;<span class="var-name">$case</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to change the case sensitivity of</span>                 </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$case</span><span class="var-description">: Whether to check in a case sensitive manner or not</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_code_style" id="set_code_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_code_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a824">824</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the style for the actual code. This should be a string</p>
+<p class="description"><p>containing valid stylesheet declarations. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p><p>Note: Use this method to override any style changes you made to  the line numbers if you are using line numbers, else the line of  code will have the same style as the line number! Consult the  GeSHi documentation for more information about this.</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_code_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to use for actual code</span>                     </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the current styles with the new styles</span>                  </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_comments_highlighting" id="set_comments_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_comments_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a972">972</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for comment groups</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_comments_highlighting
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the comment group to turn on or off</span>                 </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for that group on or off</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_comments_style" id="set_comments_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_comments_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a957">957</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for comment groups.  If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_comments_style
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the comment group to change the styles of</span>                   </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the comments</span>                       </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_encoding" id="set_encoding"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_encoding</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1744">1744</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the encoding used for htmlspecialchars(), for international  support.</p>
+<p class="description"><p>NOTE: This is not needed for now because htmlspecialchars() is not  being used (it has a security hole in PHP4 that has not been patched).  Maybe in a future version it may make a return for speed reasons, but  I doubt it.</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.3</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_encoding
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$encoding</span><span class="var-description">: The encoding to use for the source</span>                        </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_escape_characters_highlighting" id="set_escape_characters_highlighting"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_escape_characters_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1000">1000</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for escaped characters</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_escape_characters_highlighting
+               </span>
+                                       ([<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for escape characters on or off</span>                  </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_escape_characters_style" id="set_escape_characters_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_escape_characters_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a986">986</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for escaped characters. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_escape_characters_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the escape characters</span>                      </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_footer_content" id="set_footer_content"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_footer_content</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1550">1550</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the content of the footer block</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_footer_content
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$content</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$content</span><span class="var-description">: The content of the footer block</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_footer_content_style" id="set_footer_content_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_footer_content_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1570">1570</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the style for the footer content</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_footer_content_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style for the footer content</span>                     </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_header_content" id="set_header_content"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_header_content</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1540">1540</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the content of the header block</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_header_content
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$content</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$content</span><span class="var-description">: The content of the header block</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_header_content_style" id="set_header_content_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_header_content_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1560">1560</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the style for the header content</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_header_content_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style for the header content</span>                     </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_header_type" id="set_header_type"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_header_type</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a746">746</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the type of header to be used.</p>
+<p class="description"><p>If GESHI_HEADER_DIV is used, the code is surrounded in a &quot;div&quot;.This  means more source code but more control over tab width and line-wrapping.  GESHI_HEADER_PRE means that a &quot;pre&quot; is used - less source, but less  control. Default is GESHI_HEADER_PRE.</p><p>From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code  should be outputted.</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_header_type
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$type</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$type</span><span class="var-description">: The type of header to be used</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_highlight_lines_extra_style" id="set_highlight_lines_extra_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_highlight_lines_extra_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1699">1699</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the style for extra-highlighted lines</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_highlight_lines_extra_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$styles</span><span class="var-description">: The style for extra-highlighted lines</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_important_styles" id="set_important_styles"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_important_styles</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1630">1630</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets styles for important parts of the code</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_important_styles
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$styles</span><span class="var-description">: The styles to use on important parts of the code</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_keyword_group_highlighting" id="set_keyword_group_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_keyword_group_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a942">942</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for a keyword group</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_keyword_group_highlighting
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span> = <span class="var-default">true</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to turn on or off</span>                 </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for that group on or off</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_keyword_group_style" id="set_keyword_group_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_keyword_group_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a921">921</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the style for a keyword group. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_keyword_group_style
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the keyword group to change the styles of</span>                   </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the keywords</span>                       </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_language" id="set_language"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_language</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a659">659</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the language for this object</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                               <li><span class="field">note:</span> since 1.0.8 this function won't reset language-settings by default anymore!        if you need this set $force_reset = true</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_language
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$language</span>, [<span class="var-type"></span>&nbsp;<span class="var-name">$force_reset</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$language</span><span class="var-description">: The name of the language to use</span>                   </li>
+                                       <li>
+                               <span class="var-type"></span>
+                               <span class="var-name">$force_reset</span>                      </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_language_path" id="set_language_path"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_language_path</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a703">703</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the path to the directory containing the language files. Note  that this path is relative to the directory of the script that included  geshi.php, NOT geshi.php itself.</p>
+       <ul class="tags">
+                               <li><span class="field">deprecated:</span> The path to the language files should now be automatically              detected, so this method should no longer be needed. The              1.1.X branch handles manual setting of the path differently              so this method will disappear in 1.2.0.</li>
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_language_path
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$path</span><span class="var-description">: The path to the language directory</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_line_ending" id="set_line_ending"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_line_ending</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1709">1709</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the line-ending</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_line_ending
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$line_ending</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$line_ending</span><span class="var-description">: The new line-ending</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_line_style" id="set_line_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_line_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a844">844</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for the line numbers.</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_line_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style1</span>, [<span class="var-type">string|boolean</span>&nbsp;<span class="var-name">$style2</span> = <span class="var-default">''</span>], [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style1</span><span class="var-description">: The style for the line numbers that are &quot;normal&quot;</span>                  </li>
+                                       <li>
+                               <span class="var-type">string|boolean</span>
+                               <span class="var-name">$style2</span><span class="var-description">: If a string, this is the style of the line         numbers that are &quot;fancy&quot;, otherwise if boolean then this         defines whether the normal styles should be merged with the         new normal styles or not</span>                  </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: If set, is the flag for whether to merge the &quot;fancy&quot;         styles with the current styles or not</span>                     </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_link_styles" id="set_link_styles"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_link_styles</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1606">1606</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets styles for links in code</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_link_styles
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$type</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$styles</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$type</span><span class="var-description">: A constant that specifies what state the style is being             set for - e.g. :hover or :visited</span>                 </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$styles</span><span class="var-description">: The styles to use for that state</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_link_target" id="set_link_target"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_link_target</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1616">1616</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the target for links in code</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.3</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_link_target
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$target</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$target</span><span class="var-description">: The target for links in the code, e.g. _blank</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_methods_highlighting" id="set_methods_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_methods_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1162">1162</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for methods</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_methods_highlighting
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for methods on or off</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_methods_style" id="set_methods_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_methods_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1148">1148</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for methods. $key is a number that references the</p>
+<p class="description"><p>appropriate &quot;object splitter&quot; - see the language file for the language  you are highlighting to get this number. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_methods_style
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the object splitter to change the styles of</span>                 </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the methods</span>                        </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_numbers_highlighting" id="set_numbers_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_numbers_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1131">1131</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for numbers</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_numbers_highlighting
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for numbers on or off</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_numbers_style" id="set_numbers_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_numbers_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1117">1117</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for numbers. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_numbers_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the numbers</span>                        </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_overall_class" id="set_overall_class"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_overall_class</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a783">783</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the overall classname for this block of code. This  class can then be used in a stylesheet to style this object's  output</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_overall_class
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$class</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$class</span><span class="var-description">: The class name to use for this block of code</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_overall_id" id="set_overall_id"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_overall_id</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a794">794</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the overall id for this block of code. This id can then  be used in a stylesheet to style this object's output</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_overall_id
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$id</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$id</span><span class="var-description">: The ID to use for this block of code</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_overall_style" id="set_overall_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_overall_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a767">767</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for the code that will be outputted  when this object is parsed. The style should be a  string of valid stylesheet declarations</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_overall_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The overall style for the outputted code block</span>                       </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the styles with the current styles or not</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_regexps_highlighting" id="set_regexps_highlighting"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_regexps_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1191">1191</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for regexps</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_regexps_highlighting
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$key</span><span class="var-description">: The key of the regular expression group to turn on or off</span>                      </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for the regular expression group on or off</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_regexps_style" id="set_regexps_style"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_regexps_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1176">1176</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for regexps. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_regexps_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$key</span>, <span class="var-type">boolean</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type"></span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$key</span><span class="var-description">: The style to make the regular expression matches</span>                       </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$style</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                       </li>
+                                       <li>
+                               <span class="var-type"></span>
+                               <span class="var-name">$preserve_defaults</span>                        </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_source" id="set_source"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_source</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a645">645</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the source code for this object</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_source
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$source</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$source</span><span class="var-description">: The source code to highlight</span>                        </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_strings_highlighting" id="set_strings_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_strings_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1103">1103</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for strings</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_strings_highlighting
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for strings on or off</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_strings_style" id="set_strings_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_strings_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1089">1089</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for strings. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_strings_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the escape characters</span>                      </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_symbols_highlighting" id="set_symbols_highlighting"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_symbols_highlighting</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1071">1071</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Turns highlighting on/off for symbols</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_symbols_highlighting
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$flag</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$flag</span><span class="var-description">: Whether to turn highlighting for symbols on or off</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_symbols_style" id="set_symbols_style"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_symbols_style</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1051">1051</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the styles for symbols. If $preserve_defaults is  true, then styles are merged with the default styles, with the  user defined styles having priority</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.1</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_symbols_style
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$style</span>, [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$preserve_defaults</span> = <span class="var-default">false</span>], [<span class="var-type">int</span>&nbsp;<span class="var-name">$group</span> = <span class="var-default">0</span>])
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$style</span><span class="var-description">: The style to make the symbols</span>                        </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$preserve_defaults</span><span class="var-description">: Whether to merge the new styles with the old or just                 to overwrite them</span>                   </li>
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$group</span><span class="var-description">: Tells the group of symbols for which style should be set.</span>                    </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_tab_width" id="set_tab_width"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_tab_width</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1231">1231</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets how many spaces a tab is substituted for</p>
+<p class="description"><p>Widths below zero are ignored</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.0</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_tab_width
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$width</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$width</span><span class="var-description">: The tab width</span>                        </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_url_for_keyword_group" id="set_url_for_keyword_group"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_url_for_keyword_group</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1594">1594</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the base URL to be used for keywords</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_url_for_keyword_group
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$group</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$url</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$group</span><span class="var-description">: The key of the keyword group to set the URL for</span>                      </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$url</span><span class="var-description">: The URL to set for the group. If {FNAME} is in                the url somewhere, it is replaced by the keyword                that the URL is being made for</span>                   </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodset_use_language_tab_width" id="set_use_language_tab_width"><!-- --></a>
+<div class="oddrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">set_use_language_tab_width</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1247">1247</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether or not to use tab-stop width specifed by language</p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.7.20</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       set_use_language_tab_width
+               </span>
+                                       (<span class="var-type">boolean</span>&nbsp;<span class="var-name">$use</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$use</span><span class="var-description">: Whether to use language-specific tab-stop widths</span>                       </li>
+                               </ul>
+               
+                       
+       </div>
+<a name="methodstart_line_numbers_at" id="start_line_numbers_at"><!-- --></a>
+<div class="evenrow">
+       
+       <div class="method-header">
+               <img src="../../media/images/Method.png" />
+               <span class="method-title">start_line_numbers_at</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a1728">1728</a></span>)
+       </div> 
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets what number line numbers should start at. Should  be a positive integer, and will be converted to one.</p>
+<p class="description"><p><strong>Warning:</strong> Using this method will add the &quot;start&quot;  attribute to the &amp;lt;ol&amp;gt; that is used for line numbering.  This is <strong>not</strong> valid XHTML strict, so if that's what you  care about then don't use this method. Firefox is getting  support for the CSS method of doing this in 1.1 and Opera  has support for the CSS method, but (of course) IE doesn't  so it's not worth doing it the CSS way yet.</p></p>
+       <ul class="tags">
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       
+       <div class="method-signature">
+               <span class="method-result">void</span>
+               <span class="method-name">
+                       start_line_numbers_at
+               </span>
+                                       (<span class="var-type">int</span>&nbsp;<span class="var-name">$number</span>)
+                       </div>
+       
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">int</span>
+                               <span class="var-name">$number</span><span class="var-description">: The number to start line numbers at</span>                 </li>
+                               </ul>
+               
+                       
+       </div>
+                                               
+               </div>
+       </div>
+
+       
+       <p class="notes" id="credit">
+               Documentation generated on Thu, 25 Dec 2008 14:34:52 +0100 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.4.2</a>
+       </p>
+       </div></body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/geshi/core/_geshi.php.html b/examples/includes/geshi/docs/api/geshi/core/_geshi.php.html
new file mode 100644 (file)
index 0000000..798f68f
--- /dev/null
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title>Docs for page geshi.php</title>
+                       <link rel="stylesheet" href="../../media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                       <div class="page-body">                 
+<h2 class="file-name"><img src="../../media/images/Page_logo.png" alt="File" style="vertical-align: middle">/geshi.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+       <div class="info-box-title">Description</div>
+       <div class="nav-bar">
+                                       <span class="disabled">Description</span> |
+                                                       <a href="#sec-classes">Classes</a>
+                       |                                                                       <a href="#sec-constants">Constants</a>
+                       |                                                                       <a href="#sec-functions">Functions</a>
+                       </div>
+       <div class="info-box-body">     
+               <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">GeSHi - Generic Syntax Highlighter</p>
+<p class="description"><p>The GeSHi class for Generic Syntax Highlighting. Please refer to the  documentation at http://qbnz.com/highlighter/documentation.php for more  information about how to use this class.</p><p>For changes, release notes, TODOs etc, see the relevant files in the docs/  directory.</p><p>This file is part of GeSHi.</p><p>GeSHi is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.</p><p>GeSHi is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.</p><p>You should have received a copy of the GNU General Public License   along with GeSHi; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</p></p>
+       <ul class="tags">
+                               <li><span class="field">author:</span> Nigel McNie &lt;<a href="mailto:nigel@geshi.org">nigel@geshi.org</a>&gt;, Benny Baumann &lt;BenBE@omorphia.de&gt;</li>
+                               <li><span class="field">copyright:</span> (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann</li>
+                               <li><span class="field">filesource:</span> <a href="../../__filesource/fsource_geshi_core_geshi.php.html">Source Code for this file</a></li>
+                               <li><span class="field">license:</span> <a href="http://gnu.org/copyleft/gpl.html">GNU GPL</a></li>
+                       </ul>
+               
+                       </div>
+</div>
+               
+       <a name="sec-classes"></a>      
+       <div class="info-box">
+               <div class="info-box-title">Classes</div>
+               <div class="nav-bar">
+                       <a href="#sec-description">Description</a> |
+                       <span class="disabled">Classes</span>
+                       |                                                                               <a href="#sec-constants">Constants</a>
+                               |                                                                                                       <a href="#sec-functions">Functions</a>
+                                       </div>
+               <div class="info-box-body">     
+                       <table cellpadding="2" cellspacing="0" class="class-table">
+                               <tr>
+                                       <th class="class-table-header">Class</th>
+                                       <th class="class-table-header">Description</th>
+                               </tr>
+                                                               <tr>
+                                       <td style="padding-right: 2em; vertical-align: top; white-space: nowrap">
+                                               <img src="../../media/images/Class.png"
+                                                                alt=" class"
+                                                                title=" class"/>
+                                               <a href="../../geshi/core/GeSHi.html">GeSHi</a>
+                                       </td>
+                                       <td>
+                                                                                       The GeSHi Class.
+                                                                               </td>
+                               </tr>
+                                                       </table>
+               </div>
+       </div>
+
+       
+       <a name="sec-constants"></a>    
+       <div class="info-box">
+               <div class="info-box-title">Constants</div>
+               <div class="nav-bar">
+                       <a href="#sec-description">Description</a> |
+                                                       <a href="#sec-classes">Classes</a>
+                               |                                                                       <span class="disabled">Constants</span>
+                       |                                                                               <a href="#sec-functions">Functions</a>
+                                       </div>
+               <div class="info-box-body">     
+                       <a name="defineGESHI_ACTIVE"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_ACTIVE</span> = 2
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a107">107</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Links in the source in the :active state</p>
+       
+               
+</div>
+<a name="defineGESHI_CAPS_LOWER"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_CAPS_LOWER</span> = 2
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a99">99</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Leave keywords found as the case that they are</p>
+       
+               
+</div>
+<a name="defineGESHI_CAPS_NO_CHANGE"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_CAPS_NO_CHANGE</span> = 0
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a95">95</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Lowercase keywords found</p>
+       
+               
+</div>
+<a name="defineGESHI_CAPS_UPPER"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_CAPS_UPPER</span> = 1
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a97">97</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Uppercase keywords found</p>
+       
+               
+</div>
+<a name="defineGESHI_END_IMPORTANT"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_END_IMPORTANT</span> = '&lt;END GeSHi&gt;'
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a117">117</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The ender for important parts of the source</p>
+       
+               
+</div>
+<a name="defineGESHI_FANCY_LINE_NUMBERS"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_FANCY_LINE_NUMBERS</span> = 2
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a67">67</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use fancy line numbers when building the result</p>
+       
+               
+</div>
+<a name="defineGESHI_HEADER_DIV"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_HEADER_DIV</span> = 1
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a73">73</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use a &quot;div&quot; to surround the source</p>
+       
+               
+</div>
+<a name="defineGESHI_HEADER_NONE"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_HEADER_NONE</span> = 0
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a71">71</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use nothing to surround the source</p>
+       
+               
+</div>
+<a name="defineGESHI_HEADER_PRE"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_HEADER_PRE</span> = 2
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a75">75</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use a &quot;pre&quot; to surround the source</p>
+       
+               
+</div>
+<a name="defineGESHI_HEADER_PRE_TABLE"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_HEADER_PRE_TABLE</span> = 4
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a91">91</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use a &quot;table&quot; to surround the source:</p>
+<p class="description"><p>&lt;table&gt;     &lt;thead&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;$header&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;     &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;<pre>$linenumbers</pre>&lt;/td&gt;&lt;td&gt;<pre>$code></pre>&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;     &lt;tfooter&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;$footer&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;   &lt;/table&gt;</p><p>this is essentially only a workaround for Firefox, see sf#1651996 or take a look at  https://bugzilla.mozilla.org/show_bug.cgi?id=365805</p></p>
+       <ul class="tags">
+                               <li><span class="field">note:</span> when linenumbers are disabled this is essentially the same as GESHI_HEADER_PRE</li>
+                       </ul>
+       
+               
+</div>
+<a name="defineGESHI_HEADER_PRE_VALID"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_HEADER_PRE_VALID</span> = 3
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a77">77</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use a pre to wrap lines when line numbers are enabled or to wrap the whole code.</p>
+       
+               
+</div>
+<a name="defineGESHI_HOVER"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_HOVER</span> = 1
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a105">105</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Links in the source in the :hover state</p>
+       
+               
+</div>
+<a name="defineGESHI_LANG_ROOT"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_LANG_ROOT</span> = GESHI_ROOT.'geshi'.DIRECTORY_SEPARATOR
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a53">53</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The language file directory for GeSHi</p>
+       
+               
+</div>
+<a name="defineGESHI_LINK"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_LINK</span> = 0
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a103">103</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Links in the source in the :link state</p>
+       
+               
+</div>
+<a name="defineGESHI_NORMAL_LINE_NUMBERS"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_NORMAL_LINE_NUMBERS</span> = 1
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a65">65</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use normal line numbers when building the result</p>
+       
+               
+</div>
+<a name="defineGESHI_NO_LINE_NUMBERS"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_NO_LINE_NUMBERS</span> = 0
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a63">63</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Use no line numbers when building the result</p>
+       
+               
+</div>
+<a name="defineGESHI_ROOT"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_ROOT</span> = dirname(__FILE__).DIRECTORY_SEPARATOR
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a49">49</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The root directory for GeSHi</p>
+       
+               
+</div>
+<a name="defineGESHI_SECURITY_PARANOID"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_SECURITY_PARANOID</span> = false
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a58">58</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Tells GeSHi to be paranoid about security settings</p>
+       
+               
+</div>
+<a name="defineGESHI_START_IMPORTANT"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_START_IMPORTANT</span> = '&lt;BEGIN GeSHi&gt;'
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a115">115</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The starter for important parts of the source</p>
+       
+               
+</div>
+<a name="defineGESHI_VERSION"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_VERSION</span> = '1.0.8.2',
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a44">44</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">The version of this GeSHi file</p>
+       
+               
+</div>
+<a name="defineGESHI_VISITED"><!-- --></a>
+<div class="oddrow">
+       
+       <div>
+               <img src="../../media/images/Constant.png" />
+               <span class="const-title">
+                       <span class="const-name">GESHI_VISITED</span> = 3
+                       (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a109">109</a></span>)
+               </span>
+       </div>
+       
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Links in the source in the :visited state</p>
+       
+               
+</div>
+               </div>
+       </div>
+       
+       
+       <a name="sec-functions"></a>    
+       <div class="info-box">
+               <div class="info-box-title">Functions</div>
+               <div class="nav-bar">
+                       <a href="#sec-description">Description</a> |
+                                                       <a href="#sec-classes">Classes</a>
+                               |                                                                                                       <a href="#sec-constants">Constants</a>
+                               |                                                                       <span class="disabled">Functions</span>
+               </div>
+               <div class="info-box-body">     
+                       <a name="functiongeshi_highlight" id="functiongeshi_highlight"><!-- --></a>
+<div class="evenrow">
+       
+       <div>
+               <img src="../../media/images/Function.png" />
+               <span class="method-title">geshi_highlight</span> (line <span class="line-number"><a href="../../__filesource/fsource_geshi_core_geshi.php.html#a4577">4577</a></span>)
+       </div> 
+
+       <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Easy way to highlight stuff. Behaves just like highlight_string</p>
+       <ul class="tags">
+                               <li><span class="field">return:</span> The code highlighted (if $return is true)</li>
+                               <li><span class="field">since:</span> 1.0.2</li>
+                       </ul>
+       <div class="method-signature">
+               <span class="method-result">string</span>
+               <span class="method-name">
+                       geshi_highlight
+               </span>
+                                       (<span class="var-type">string</span>&nbsp;<span class="var-name">$string</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$language</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span> = <span class="var-default">null</span>], [<span class="var-type">boolean</span>&nbsp;<span class="var-name">$return</span> = <span class="var-default">false</span>])
+                       </div>
+
+                       <ul class="parameters">
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$string</span><span class="var-description">: The code to highlight</span>                       </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$language</span><span class="var-description">: The language to highlight the code in</span>                     </li>
+                                       <li>
+                               <span class="var-type">string</span>
+                               <span class="var-name">$path</span><span class="var-description">: The path to the language files. You can leave this blank if you need                as from version 1.0.7 the path should be automatically detected</span>                   </li>
+                                       <li>
+                               <span class="var-type">boolean</span>
+                               <span class="var-name">$return</span><span class="var-description">: Whether to return the result or to echo</span>                     </li>
+                               </ul>
+               
+       
+</div>
+               </div>
+       </div>
+       
+       <p class="notes" id="credit">
+               Documentation generated on Thu, 25 Dec 2008 14:34:34 +0100 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.4.2</a>
+       </p>
+       </div></body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/index.html b/examples/includes/geshi/docs/api/index.html
new file mode 100644 (file)
index 0000000..f499a8f
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html 
+     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//FR"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+   <html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+       <!-- Generated by phpDocumentor on Thu, 25 Dec 2008 14:34:34 +0100  -->
+  <title>GeSHi 1.0.8</title>
+  <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+</head>
+
+<FRAMESET rows='120,*'>
+       <FRAME src='packages.html' name='left_top' frameborder="1" bordercolor="#999999">
+       <FRAMESET cols='25%,*'>
+               <FRAME src='li_geshi.html' name='left_bottom' frameborder="1" bordercolor="#999999">
+               <FRAME src='blank.html' name='right' frameborder="1" bordercolor="#999999">
+       </FRAMESET>
+       <NOFRAMES>
+               <H2>Frame Alert</H2>
+               <P>This document is designed to be viewed using the frames feature.
+               If you see this message, you are using a non-frame-capable web client.</P>
+       </NOFRAMES>
+</FRAMESET>
+</HTML>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/li_geshi.html b/examples/includes/geshi/docs/api/li_geshi.html
new file mode 100644 (file)
index 0000000..f074e37
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title></title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               <div class="package-title">geshi</div>
+<div class="package-details">
+                       
+       <dl class="tree">
+               
+               <dt class="folder-title">Description</dt>
+               <dd>
+                       <a href='classtrees_geshi.html' target='right'>Class trees</a><br />
+                       <a href='elementindex_geshi.html' target='right'>Index of elements</a><br />
+                                                       <a href="todolist.html" target="right">Todo List</a><br />
+                                       </dd>
+       
+                                                       
+                                                       
+                                                                                                                                                                                                                               
+                                               
+                                                       
+                                                                                       
+                               <dt class="sub-package"><img class="tree-icon" src="media/images/package.png" alt="Sub-package">core</dt>
+                               <dd>
+                                       <dl class="tree">
+                                                                                                                                                       <dt class="folder-title"><img class="tree-icon" src="media/images/class_folder.png" alt=" ">Classes</dt>
+                                                                                                                       <dd><img class="tree-icon" src="media/images/Class.png" alt="Class"><a href='geshi/core/GeSHi.html' target='right'>GeSHi</a></dd>
+                                                                                                                                                                                                               <dt class="folder-title"><img class="tree-icon" src="media/images/function_folder.png" alt=" ">Functions</dt>
+                                                                                                                       <dd><img class="tree-icon" src="media/images/Function.png" alt="Function"><a href='geshi/core/_geshi.php.html#functiongeshi_highlight' target='right'>geshi_highlight</a></dd>
+                                                                                                                                                                                                               <dt class="folder-title"><img class="tree-icon" src="media/images/folder.png" alt=" ">Files</dt>
+                                                                                                                       <dd><img class="tree-icon" src="media/images/Page.png" alt="File"><a href='geshi/core/_geshi.php.html' target='right'>geshi.php</a></dd>
+                                                                                                                                               </dl>
+                               </dd>
+                                                               
+                                               
+                       </dl>
+</div>
+<p class="notes"><a href="http://www.phpdoc.org" target="_blank">phpDocumentor v <span class="field">1.4.2</span></a></p>
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/media/banner.css b/examples/includes/geshi/docs/api/media/banner.css
new file mode 100644 (file)
index 0000000..032b037
--- /dev/null
@@ -0,0 +1,33 @@
+body 
+{ 
+       background-color: #EEEEEE; 
+       margin: 0px; 
+       padding: 0px;
+}
+
+/* Banner (top bar) classes */
+
+.banner {  }
+
+.banner-menu 
+{
+       text-align: right;
+       clear: both;
+       padding: .5em;
+       border-top: 2px solid #AAAAAA;  
+}
+
+.banner-title 
+{ 
+       text-align: right; 
+       font-size: 20pt; 
+       font-weight: bold; 
+       margin: .2em;
+}
+
+.package-selector 
+{ 
+       background-color: #DDDDDD; 
+       border: 1px solid #AAAAAA; 
+       color: #000090;
+}
diff --git a/examples/includes/geshi/docs/api/media/images/AbstractClass.png b/examples/includes/geshi/docs/api/media/images/AbstractClass.png
new file mode 100644 (file)
index 0000000..afa9d1d
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/AbstractClass.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/AbstractClass_logo.png b/examples/includes/geshi/docs/api/media/images/AbstractClass_logo.png
new file mode 100644 (file)
index 0000000..8f65c39
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/AbstractClass_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/AbstractMethod.png b/examples/includes/geshi/docs/api/media/images/AbstractMethod.png
new file mode 100644 (file)
index 0000000..605ccbe
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/AbstractMethod.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/AbstractPrivateClass.png b/examples/includes/geshi/docs/api/media/images/AbstractPrivateClass.png
new file mode 100644 (file)
index 0000000..53d76c6
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/AbstractPrivateClass.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/AbstractPrivateClass_logo.png b/examples/includes/geshi/docs/api/media/images/AbstractPrivateClass_logo.png
new file mode 100644 (file)
index 0000000..4e68f57
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/AbstractPrivateClass_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/AbstractPrivateMethod.png b/examples/includes/geshi/docs/api/media/images/AbstractPrivateMethod.png
new file mode 100644 (file)
index 0000000..41cc9f0
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/AbstractPrivateMethod.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Class.png b/examples/includes/geshi/docs/api/media/images/Class.png
new file mode 100644 (file)
index 0000000..cf548d2
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Class.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Class_logo.png b/examples/includes/geshi/docs/api/media/images/Class_logo.png
new file mode 100644 (file)
index 0000000..6f223c4
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Class_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Constant.png b/examples/includes/geshi/docs/api/media/images/Constant.png
new file mode 100644 (file)
index 0000000..a9c6f28
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Constant.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Constructor.png b/examples/includes/geshi/docs/api/media/images/Constructor.png
new file mode 100644 (file)
index 0000000..3f16222
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Constructor.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Destructor.png b/examples/includes/geshi/docs/api/media/images/Destructor.png
new file mode 100644 (file)
index 0000000..f28528f
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Destructor.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Function.png b/examples/includes/geshi/docs/api/media/images/Function.png
new file mode 100644 (file)
index 0000000..902fe25
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Function.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Global.png b/examples/includes/geshi/docs/api/media/images/Global.png
new file mode 100644 (file)
index 0000000..7281bd2
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Global.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/I.png b/examples/includes/geshi/docs/api/media/images/I.png
new file mode 100644 (file)
index 0000000..e8512fb
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/I.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Index.png b/examples/includes/geshi/docs/api/media/images/Index.png
new file mode 100644 (file)
index 0000000..6558ec3
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Index.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Interface.png b/examples/includes/geshi/docs/api/media/images/Interface.png
new file mode 100644 (file)
index 0000000..e6cd51e
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Interface.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Interface_logo.png b/examples/includes/geshi/docs/api/media/images/Interface_logo.png
new file mode 100644 (file)
index 0000000..6f223c4
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Interface_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/L.png b/examples/includes/geshi/docs/api/media/images/L.png
new file mode 100644 (file)
index 0000000..eb334ed
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/L.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Lminus.png b/examples/includes/geshi/docs/api/media/images/Lminus.png
new file mode 100644 (file)
index 0000000..f7c43c0
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Lminus.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Lplus.png b/examples/includes/geshi/docs/api/media/images/Lplus.png
new file mode 100644 (file)
index 0000000..848ec2f
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Lplus.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Method.png b/examples/includes/geshi/docs/api/media/images/Method.png
new file mode 100644 (file)
index 0000000..9b21578
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Method.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Page.png b/examples/includes/geshi/docs/api/media/images/Page.png
new file mode 100644 (file)
index 0000000..ffe7986
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Page.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Page_logo.png b/examples/includes/geshi/docs/api/media/images/Page_logo.png
new file mode 100644 (file)
index 0000000..44ce0b3
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Page_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/PrivateClass.png b/examples/includes/geshi/docs/api/media/images/PrivateClass.png
new file mode 100644 (file)
index 0000000..470e6d5
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/PrivateClass.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/PrivateClass_logo.png b/examples/includes/geshi/docs/api/media/images/PrivateClass_logo.png
new file mode 100644 (file)
index 0000000..590e006
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/PrivateClass_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/PrivateMethod.png b/examples/includes/geshi/docs/api/media/images/PrivateMethod.png
new file mode 100644 (file)
index 0000000..d01f2b3
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/PrivateMethod.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/PrivateVariable.png b/examples/includes/geshi/docs/api/media/images/PrivateVariable.png
new file mode 100644 (file)
index 0000000..d76b21d
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/PrivateVariable.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/StaticMethod.png b/examples/includes/geshi/docs/api/media/images/StaticMethod.png
new file mode 100644 (file)
index 0000000..9b21578
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/StaticMethod.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/StaticVariable.png b/examples/includes/geshi/docs/api/media/images/StaticVariable.png
new file mode 100644 (file)
index 0000000..8e82019
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/StaticVariable.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/T.png b/examples/includes/geshi/docs/api/media/images/T.png
new file mode 100644 (file)
index 0000000..3017325
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/T.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Tminus.png b/examples/includes/geshi/docs/api/media/images/Tminus.png
new file mode 100644 (file)
index 0000000..2260e42
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Tminus.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Tplus.png b/examples/includes/geshi/docs/api/media/images/Tplus.png
new file mode 100644 (file)
index 0000000..2c8d8f4
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Tplus.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/Variable.png b/examples/includes/geshi/docs/api/media/images/Variable.png
new file mode 100644 (file)
index 0000000..8e82019
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/Variable.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/blank.png b/examples/includes/geshi/docs/api/media/images/blank.png
new file mode 100644 (file)
index 0000000..cee9cd3
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/blank.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/class_folder.png b/examples/includes/geshi/docs/api/media/images/class_folder.png
new file mode 100644 (file)
index 0000000..84e9587
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/class_folder.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/empty.png b/examples/includes/geshi/docs/api/media/images/empty.png
new file mode 100644 (file)
index 0000000..d568386
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/empty.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/file.png b/examples/includes/geshi/docs/api/media/images/file.png
new file mode 100644 (file)
index 0000000..0bb2427
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/file.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/folder.png b/examples/includes/geshi/docs/api/media/images/folder.png
new file mode 100644 (file)
index 0000000..a2d79f8
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/folder.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/function_folder.png b/examples/includes/geshi/docs/api/media/images/function_folder.png
new file mode 100644 (file)
index 0000000..8b3d6e3
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/function_folder.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/next_button.png b/examples/includes/geshi/docs/api/media/images/next_button.png
new file mode 100644 (file)
index 0000000..cdbc615
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/next_button.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/next_button_disabled.png b/examples/includes/geshi/docs/api/media/images/next_button_disabled.png
new file mode 100644 (file)
index 0000000..4a11780
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/next_button_disabled.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/package.png b/examples/includes/geshi/docs/api/media/images/package.png
new file mode 100644 (file)
index 0000000..b04cf56
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/package.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/package_folder.png b/examples/includes/geshi/docs/api/media/images/package_folder.png
new file mode 100644 (file)
index 0000000..6162baf
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/package_folder.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/previous_button.png b/examples/includes/geshi/docs/api/media/images/previous_button.png
new file mode 100644 (file)
index 0000000..327fdbc
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/previous_button.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/previous_button_disabled.png b/examples/includes/geshi/docs/api/media/images/previous_button_disabled.png
new file mode 100644 (file)
index 0000000..c02ff64
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/previous_button_disabled.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/private_class_logo.png b/examples/includes/geshi/docs/api/media/images/private_class_logo.png
new file mode 100644 (file)
index 0000000..590e006
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/private_class_logo.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/tutorial.png b/examples/includes/geshi/docs/api/media/images/tutorial.png
new file mode 100644 (file)
index 0000000..bc19737
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/tutorial.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/tutorial_folder.png b/examples/includes/geshi/docs/api/media/images/tutorial_folder.png
new file mode 100644 (file)
index 0000000..2a468b2
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/tutorial_folder.png differ
diff --git a/examples/includes/geshi/docs/api/media/images/up_button.png b/examples/includes/geshi/docs/api/media/images/up_button.png
new file mode 100644 (file)
index 0000000..ff36c59
Binary files /dev/null and b/examples/includes/geshi/docs/api/media/images/up_button.png differ
diff --git a/examples/includes/geshi/docs/api/media/stylesheet.css b/examples/includes/geshi/docs/api/media/stylesheet.css
new file mode 100644 (file)
index 0000000..ed3f0b2
--- /dev/null
@@ -0,0 +1,145 @@
+a { color: #000090; text-decoration: none; }
+a:hover, a:active, a:focus { color: highlighttext; background-color: highlight; text-decoration: none; }
+
+body { background: #FFFFFF; }
+body, table { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; }
+
+a img { border: 0px; }
+
+/* Page layout/boxes */
+
+.info-box {  }
+.info-box-title { margin: 1em 0em 0em 0em; font-weight: normal; font-size: 14pt; color: #999999; border-bottom: 2px solid #999999; }
+.info-box-body { border: 1px solid #999999; padding: .5em; }
+.nav-bar { font-size: 8pt; white-space: nowrap; text-align: right; padding: .2em; margin: 0em 0em 1em 0em; }
+
+.oddrow { background-color: #F8F8F8; border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em}
+.evenrow { border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em}
+
+.page-body { max-width: 800px; margin: auto; }
+.tree { white-space: nowrap; font: icon }
+.tree dd { margin-left: 19px }
+.tree dl { margin: 0px }
+.tree-icon {   vertical-align: middle; border: 0px; margin-right: 3px }
+
+/* Index formatting classes */
+
+.index-item-body { margin-top: .5em; margin-bottom: .5em}
+.index-item-description { margin-top: .25em }
+.index-item-details { font-weight: normal; font-style: italic; font-size: 8pt }
+.index-letter-section { background-color: #EEEEEE; border: 1px dotted #999999; padding: .5em; margin-bottom: 1em}
+.index-letter-title { font-size: 12pt; font-weight: bold }
+.index-letter-menu { text-align: center; margin: 1em }
+.index-letter { font-size: 12pt }
+
+/* Docbook classes */
+
+.description {}
+.short-description { font-weight: bold; color: #666666; }
+.tags {        padding-left: 0em; margin-left: 3em; color: #666666; list-style-type: square; }
+.parameters {  padding-left: 0em; margin-left: 3em; color: #014fbe; list-style-type: square; }
+.redefinitions { font-size: 8pt; padding-left: 0em; margin-left: 2em; }
+.package { font-weight: bold; }
+.package-title { font-weight: bold; font-size: 14pt; border-bottom: 1px solid black }
+.package-details { font-size: 85%; }
+.sub-package { font-weight: bold; }
+.tutorial { border-width: thin; border-color: #0066ff; }
+.tutorial-nav-box { width: 100%; border: 1px solid #999999; background-color: #F8F8F8; }
+.folder-title { font-style: italic; font-family: Verdana, Arial, Helvetica, sans-serif }
+
+/* Generic formatting */
+
+.field { font-weight: bold; }
+.detail { font-size: 8pt; }
+.notes { font-style: italic; font-size: 8pt; }
+.separator { background-color: #999999; height: 2px; }
+.warning {  color: #FF6600; }
+.disabled { font-style: italic; color: #999999; }
+
+/* Code elements */
+
+.line-number {  }
+
+.class-table { width: 100%; }
+.class-table-header { border-bottom: 1px dotted #666666; text-align: left}
+.class-name { color: #0000AA; font-weight: bold; }
+
+.method-summary { color: #009000; padding-left: 1em; font-size: 8pt; }
+.method-header { }
+.method-definition { margin-bottom: .2em }
+.method-title { color: #009000; font-weight: bold; }
+.method-name { font-weight: bold; }
+.method-signature { font-size: 85%; color: #666666; margin: .5em 0em }
+.method-result { font-style: italic; }
+
+.var-summary { padding-left: 1em; font-size: 8pt; }
+.var-header { }
+.var-title { color: #014fbe; margin-bottom: .3em }
+.var-type { font-style: italic; }
+.var-name { font-weight: bold; }
+.var-default {}
+.var-description { font-weight: normal; color: #000000; }
+
+.include-title { color: #014fbe;}
+.include-type { font-style: italic; }
+.include-name { font-weight: bold; }
+
+.const-title { color: #FF6600; }
+.const-name { font-weight: bold; }
+
+/* Syntax highlighting */
+
+.src-code { font-family: 'Courier New', Courier, monospace; font-weight: normal; }
+.src-line { font-family: 'Courier New', Courier, monospace; font-weight: normal; }
+
+.src-code a:link { padding: 1px; text-decoration: underline; color: #0000DD; }
+.src-code a:visited { text-decoration: underline; color: #0000DD; }
+.src-code a:active { background-color: #FFFF66; color: #008000; }
+.src-code a:hover { background-color: #FFFF66; text-decoration: overline underline; color: #008000; }
+
+.src-comm { color: #666666; }
+.src-id { color: #FF6600; font-style: italic; }
+.src-inc { color: #0000AA; font-weight: bold; }
+.src-key { color: #0000AA; font-weight: bold; }
+.src-num { color: #CC0000; }
+.src-str { color: #CC0000; }
+.src-sym { }
+.src-var { }
+
+.src-php { font-weight: bold; }
+
+.src-doc { color: #666666; }
+.src-doc-close-template { color: #666666 }
+.src-doc-coretag { color: #008000; }
+.src-doc-inlinetag {}
+.src-doc-internal {}
+.src-doc-tag { color: #0080CC; }
+.src-doc-template { color: #666666 }
+.src-doc-type { font-style: italic; color: #444444 }
+.src-doc-var { color: #444444 }
+
+.tute-tag { color: #009999 }
+.tute-attribute-name { color: #0000FF }
+.tute-attribute-value { color: #0099FF }
+.tute-entity { font-weight: bold; }
+.tute-comment { font-style: italic }
+.tute-inline-tag { color: #636311; font-weight: bold }
+
+/* tutorial */
+
+.authors {  }
+.author { font-style: italic; font-weight: bold }
+.author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal }
+.example { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; }
+*[class="example"] { line-height : 1.0em; }
+.listing { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; white-space: nowrap; }
+*[class="listing"] { line-height : 1.0em; }
+.release-info { font-size: 85%; font-style: italic; margin: 1em 0em }
+.ref-title-box {  }
+.ref-title {  }
+.ref-purpose { font-style: italic; color: #666666 }
+.ref-synopsis {  }
+.title { font-weight: bold; border-bottom: 1px solid #999999; color: #999999;  }
+.cmd-synopsis { margin: 1em 0em }
+.cmd-title { font-weight: bold }
+.toc { margin-left: 2em; padding-left: 0em }
diff --git a/examples/includes/geshi/docs/api/packages.html b/examples/includes/geshi/docs/api/packages.html
new file mode 100644 (file)
index 0000000..d8c4c04
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title></title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <link rel="stylesheet" href="media/banner.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                       <div class="banner">
+                               <div class="banner-title">geshi</div>
+                               <div class="banner-menu">
+                                       <form>
+                                               <table cellpadding="0" cellspacing="0" style="width: 100%">
+                                                       <tr>
+                                                               <td>
+                                                                                                                                       </td>
+                                                               <td style="width: 2em">&nbsp;</td>
+                                                               <td style="text-align: right">
+                                                                                                                                       </td>
+                                                       </tr>
+                                               </table>
+                                       </form>
+                               </div>
+                       </div>
+               </body>
+       </html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/api/todolist.html b/examples/includes/geshi/docs/api/todolist.html
new file mode 100644 (file)
index 0000000..95177c1
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+  <html xmlns="http://www.w3.org/1999/xhtml">
+               <head>
+                       <!-- template designed by Marco Von Ballmoos -->
+                       <title>Todo List</title>
+                       <link rel="stylesheet" href="media/stylesheet.css" />
+                       <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+               </head>
+               <body>
+                                               <div align="center"><h1>Todo List</h1></div>
+<h2>geshi</h2>
+<h3><a href="geshi/core/GeSHi.html#methoddisable_highlighting">GeSHi::disable_highlighting()</a></h3>
+<ul>
+    <li>Rewrite with array traversal</li>
+</ul>
+<h3><a href="geshi/core/GeSHi.html#methodenable_highlighting">GeSHi::enable_highlighting()</a></h3>
+<ul>
+    <li>Rewrite with array traversal</li>
+</ul>
+<h3><a href="geshi/core/GeSHi.html#methodenable_important_blocks">GeSHi::enable_important_blocks()</a></h3>
+<ul>
+    <li>REMOVE THIS SHIZ FROM GESHI!</li>
+</ul>
+<h3><a href="geshi/core/GeSHi.html#methodget_language_name_from_extension">GeSHi::get_language_name_from_extension()</a></h3>
+<ul>
+    <li>Re-think about how this method works (maybe make it private and/or make it        a extension-&gt;lang lookup?)</li>
+    <li>static?</li>
+</ul>
+<h3><a href="geshi/core/GeSHi.html#methodhighlight_lines_extra">GeSHi::highlight_lines_extra()</a></h3>
+<ul>
+    <li>Some data replication here that could be cut down on</li>
+</ul>
+<h3><a href="geshi/core/GeSHi.html#methodload_from_file">GeSHi::load_from_file()</a></h3>
+<ul>
+    <li>Complete rethink of this and above method</li>
+</ul>
+       <p class="notes" id="credit">
+               Documentation generated on Thu, 25 Dec 2008 14:34:53 +0100 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.4.2</a>
+       </p>
+       </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/geshi-doc.html b/examples/includes/geshi/docs/geshi-doc.html
new file mode 100644 (file)
index 0000000..fff5347
--- /dev/null
@@ -0,0 +1,4051 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+    <head>
+        <title>GeSHi Documentation 1.0.8.3</title>
+
+       <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+       <meta name="keywords" content="GeSHi, syntax, highlighter, colorizer, beautifier, code, generic, php, sql, css, html, syntax, highlighting, documentation" />
+       <meta name="description" content="GeSHi - Generic Syntax Highlighter for PHP. Highlight many languages, including PHP, CSS, HTML, SQL, Java and C for XHTML compliant output using this easy PHP Class. Every aspect of the highlighting is customisable, from colours and other styles to case-sensitivity checking and more. GeSHi - the best syntax highlighter in the world!" />
+
+        <style type="text/css">
+            html {
+                background-color: #e6e6e6;
+            }
+            body {
+                font-family: Verdana, Arial, sans-serif;
+                margin: 10px;
+                border: 2px solid #d0d0d0;
+                background-color: #f6f6f6;
+                padding: 10px;
+            }
+            p, ul, ol, div, blockquote, dt, dd {
+                font-size: 80%;
+                line-height: 140%;
+                letter-spacing: 1px;
+                color: #002;
+            }
+            dt {
+                font-weight: bold;
+            }
+            acronym {
+                border-bottom: 1px dotted #303030;
+                cursor: help;
+            }
+            blockquote {
+                font-weight: bold;
+            }
+            pre, .geshicode {
+                border: 1px solid #c0e6ff;
+                background-color: #e0e8ef;
+                color: #002;
+                margin:0;
+                font-size: 12px;
+                width:100%;
+            }
+            table {
+                border-collapse:collapse;
+            }
+            .geshicode pre {
+                border:none;
+                background-color:inherit;
+                font-weight:bold;
+            }
+            .geshicode .li2 td {
+                background-color:#eee;
+            }
+            .geshicode .li1 td {
+                background-color:#fff;
+            }
+            .geshicode td td {
+                padding:0 2px;
+            }
+            .geshicode td, .geshicode table {
+                width: 100%;
+            }
+            .geshicode td.ln {
+                border-right:2px solid #e0e8ef;
+            }
+            .geshicode .head {
+                text-align:center;
+                font-weight:bold;
+            }
+            code, tt, kbd {
+                font-size: 125%;
+                font-weight:normal;
+            }
+            hr {
+                height: 0;
+                border: none;
+                border-top: 1px dotted #404040;
+                width: 75%;
+            }
+            var {
+                color: blue; font-style: normal; font-family: monospace;
+            }
+            li {
+                padding-top: 2px;
+            }
+            ul ul, ol ol, div ul, div ol {
+                font-size:100%;
+            }
+            .note {
+                border: 1px solid yellow;
+                background-color: #ffc;
+                color: #220;
+                padding: 5px;
+                margin: 1em 0 0 .75em;
+            }
+            .caution {
+                border: 6px double red;
+                background-color: #fcc;
+                color: #200;
+                padding: 5px;
+                margin: 1em 0 0 .75em;
+            }
+            .caution p:first-child, .note p:first-child {
+                margin-top: 0;
+            }
+            .caution-header {
+                border: 1px solid red;
+                border-width: 1px 2px 2px 1px;
+                margin-top: -1.6em;
+                background-color: #fcc;
+                width: 10%;
+                font-weight: bold;
+                text-align: center;
+                color: #600;
+            }
+            .note-header {
+                border: 1px solid #ff0;
+                border-width: 1px 2px 2px 1px;
+                margin-top: -1.2em;
+                background-color: #ffc;
+                width: 10%;
+                font-weight: bold;
+                text-align: center;
+                color: #660;
+            }
+            .nav {
+                font-size: 70%;
+            }
+            .nav a {
+                color: #707070;
+                border: 1px solid #a0a0a0;
+                border-width: 0 1px 1px 1px;
+                border-top: 1px dotted #c0c0c0;
+                text-decoration: none;
+                padding: 1px 2px;
+                background-color: #e0e0e0;
+                -moz-border-radius-bottomleft: 3px;
+                -moz-border-radius-bottomright: 3px;
+            }
+            h1, #contents {
+                margin-top: 0;
+                margin-bottom: 0;
+                text-align: center;
+                color: #404060;
+            }
+            #contents {
+                text-align:left;
+                background:none;
+                border:none;
+            }
+            h2 {
+                border-bottom: 1px dotted #b0b0b0;
+                margin-top: 2em;
+                border-top: 1px dotted #b0b0b0;
+                background-color: #ddd;
+                margin-bottom: 0;
+            }
+            h3 {
+                margin-top: 1.6em;
+                border-bottom: 1px dotted #c0c0c0;
+                margin-bottom: 0;
+            }
+            h4 {
+                border-bottom: 1px dotted #d0d0d0;
+                margin-top: 1.2em;
+                margin-bottom: 0;
+            }
+            h2, h3, h4 {
+                color: #707070;
+                font-weight: normal;
+            }
+            a {
+                color: #7777ff;
+            }
+            sup a {
+                text-decoration: none;
+            }
+            abbr {
+                cursor: help;
+            }
+            .header p {
+                text-align: center;
+                border-bottom: 1px dotted #d0d0d0;
+            }
+
+            .header dl {
+                background-color: #e0e8ef;
+                color: #002;
+                padding: 5px;
+            }
+
+            .header img {
+                float: right;
+                margin:2.5em 1em 0 0;
+            }
+
+            /**
+ * GeSHi Dynamically Generated Stylesheet
+ * --------------------------------------
+ * Dynamically generated stylesheet for bash
+ * CSS class: , CSS id:
+ * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+ * (http://qbnz.com/highlighter/ and http://geshi.org/)
+ * --------------------------------------
+ */
+.bash .de1, .bash .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
+.bash  {font-family:monospace;}
+.bash .imp {font-weight: bold; color: red;}
+.bash li, .bash .li1 {font-weight: normal; vertical-align:top;}
+.bash .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
+.bash .li2 {font-weight: bold; vertical-align:top;}
+.bash .kw1 {color: #000000; font-weight: bold;}
+.bash .kw2 {color: #c20cb9; font-weight: bold;}
+.bash .kw3 {color: #7a0874; font-weight: bold;}
+.bash .co0 {color: #666666; font-style: italic;}
+.bash .co1 {color: #800000;}
+.bash .co2 {color: #cc0000; font-style: italic;}
+.bash .co3 {color: #000000; font-weight: bold;}
+.bash .es1 {color: #000099; font-weight: bold;}
+.bash .es2 {color: #007800;}
+.bash .es3 {color: #007800;}
+.bash .es4 {color: #007800;}
+.bash .es5 {color: #780078;}
+.bash .es_h {color: #000099; font-weight: bold;}
+.bash .br0 {color: #7a0874; font-weight: bold;}
+.bash .sy0 {color: #000000; font-weight: bold;}
+.bash .st0 {color: #ff0000;}
+.bash .st_h {color: #ff0000;}
+.bash .nu0 {color: #000000;}
+.bash .re0 {color: #007800;}
+.bash .re1 {color: #007800;}
+.bash .re2 {color: #007800;}
+.bash .re4 {color: #007800;}
+.bash .re5 {color: #660033;}
+.bash .ln-xtra, .bash li.ln-xtra, .bash div.ln-xtra {background-color: #ffc;}
+.bash span.xtra { display:block; }
+
+/**
+ * GeSHi Dynamically Generated Stylesheet
+ * --------------------------------------
+ * Dynamically generated stylesheet for php
+ * CSS class: , CSS id:
+ * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+ * (http://qbnz.com/highlighter/ and http://geshi.org/)
+ * --------------------------------------
+ */
+.php .de1, .php .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
+.php  {font-family:monospace;}
+.php .imp {font-weight: bold; color: red;}
+.php li, .php .li1 {font-weight: normal; vertical-align:top;}
+.php .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
+.php .li2 {font-weight: bold; vertical-align:top;}
+.php .kw1 {color: #b1b100;}
+.php .kw2 {color: #000000; font-weight: bold;}
+.php .kw3 {color: #990000;}
+.php .kw4 {color: #009900; font-weight: bold;}
+.php .co1 {color: #666666; font-style: italic;}
+.php .co2 {color: #666666; font-style: italic;}
+.php .co3 {color: #0000cc; font-style: italic;}
+.php .co4 {color: #009933; font-style: italic;}
+.php .coMULTI {color: #666666; font-style: italic;}
+.php .es0 {color: #000099; font-weight: bold;}
+.php .es1 {color: #000099; font-weight: bold;}
+.php .es2 {color: #660099; font-weight: bold;}
+.php .es3 {color: #660099; font-weight: bold;}
+.php .es4 {color: #006699; font-weight: bold;}
+.php .es5 {color: #006699; font-weight: bold; font-style: italic;}
+.php .es6 {color: #009933; font-weight: bold;}
+.php .es_h {color: #000099; font-weight: bold;}
+.php .br0 {color: #009900;}
+.php .sy0 {color: #339933;}
+.php .sy1 {color: #000000; font-weight: bold;}
+.php .st0 {color: #0000ff;}
+.php .st_h {color: #0000ff;}
+.php .nu0 {color: #cc66cc;}
+.php .nu8 {color: #208080;}
+.php .nu12 {color: #208080;}
+.php .nu19 {color:#800080;}
+.php .me1 {color: #004000;}
+.php .me2 {color: #004000;}
+.php .re0 {color: #000088;}
+.php .ln-xtra, .php li.ln-xtra, .php div.ln-xtra {background-color: #ffc;}
+.php span.xtra { display:block; }
+
+/**
+ * GeSHi Dynamically Generated Stylesheet
+ * --------------------------------------
+ * Dynamically generated stylesheet for html4strict
+ * CSS class: , CSS id:
+ * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+ * (http://qbnz.com/highlighter/ and http://geshi.org/)
+ * --------------------------------------
+ */
+.html4strict .de1, .html4strict .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
+.html4strict  {font-family:monospace;}
+.html4strict .imp {font-weight: bold; color: red;}
+.html4strict li, .html4strict .li1 {font-weight: normal; vertical-align:top;}
+.html4strict .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
+.html4strict .li2 {font-weight: bold; vertical-align:top;}
+.html4strict .kw2 {color: #000000; font-weight: bold;}
+.html4strict .kw3 {color: #000066;}
+.html4strict .es0 {color: #000099; font-weight: bold;}
+.html4strict .br0 {color: #66cc66;}
+.html4strict .sy0 {color: #66cc66;}
+.html4strict .st0 {color: #ff0000;}
+.html4strict .nu0 {color: #cc66cc;}
+.html4strict .sc-1 {color: #808080; font-style: italic;}
+.html4strict .sc0 {color: #00bbdd;}
+.html4strict .sc1 {color: #ddbb00;}
+.html4strict .sc2 {color: #009900;}
+.html4strict .ln-xtra, .html4strict li.ln-xtra, .html4strict div.ln-xtra {background-color: #ffc;}
+.html4strict span.xtra { display:block; }
+
+/**
+ * GeSHi Dynamically Generated Stylesheet
+ * --------------------------------------
+ * Dynamically generated stylesheet for css
+ * CSS class: , CSS id:
+ * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+ * (http://qbnz.com/highlighter/ and http://geshi.org/)
+ * --------------------------------------
+ */
+.css .de1, .css .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
+.css  {font-family:monospace;}
+.css .imp {font-weight: bold; color: red;}
+.css li, .css .li1 {font-weight: normal; vertical-align:top;}
+.css .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
+.css .li2 {font-weight: bold; vertical-align:top;}
+.css .kw1 {color: #000000; font-weight: bold;}
+.css .kw2 {color: #993333;}
+.css .co1 {color: #a1a100;}
+.css .co2 {color: #ff0000; font-style: italic;}
+.css .coMULTI {color: #808080; font-style: italic;}
+.css .es0 {color: #000099; font-weight: bold;}
+.css .br0 {color: #00AA00;}
+.css .sy0 {color: #00AA00;}
+.css .st0 {color: #ff0000;}
+.css .nu0 {color: #cc66cc;}
+.css .re0 {color: #cc00cc;}
+.css .re1 {color: #6666ff;}
+.css .re2 {color: #3333ff;}
+.css .re3 {color: #933;}
+.css .ln-xtra, .css li.ln-xtra, .css div.ln-xtra {background-color: #ffc;}
+.css span.xtra { display:block; }
+
+/**
+ * GeSHi Dynamically Generated Stylesheet
+ * --------------------------------------
+ * Dynamically generated stylesheet for java
+ * CSS class: , CSS id:
+ * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+ * (http://qbnz.com/highlighter/ and http://geshi.org/)
+ * --------------------------------------
+ */
+.java .de1, .java .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
+.java  {font-family:monospace;}
+.java .imp {font-weight: bold; color: red;}
+.java li, .java .li1 {font-weight: normal; vertical-align:top;}
+.java .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
+.java .li2 {font-weight: bold; vertical-align:top;}
+.java .kw1 {color: #000000; font-weight: bold;}
+.java .kw2 {color: #000066; font-weight: bold;}
+.java .kw3 {color: #003399;}
+.java .kw4 {color: #000066; font-weight: bold;}
+.java .co1 {color: #666666; font-style: italic;}
+.java .co2 {color: #006699;}
+.java .co3 {color: #008000; font-style: italic; font-weight: bold;}
+.java .coMULTI {color: #666666; font-style: italic;}
+.java .es0 {color: #000099; font-weight: bold;}
+.java .br0 {color: #009900;}
+.java .sy0 {color: #339933;}
+.java .st0 {color: #0000ff;}
+.java .nu0 {color: #cc66cc;}
+.java .me1 {color: #006633;}
+.java .me2 {color: #006633;}
+.java .ln-xtra, .java li.ln-xtra, .java div.ln-xtra {background-color: #ffc;}
+.java span.xtra { display:block; }
+
+
+        </style>
+    </head>
+    <body>
+    <h1 id="top"><abbr title="Generic Syntax Highlighter">GeSHi</abbr> Documentation</h1>
+
+<div class="header">
+
+<p>Version 1.0.8.3</p>
+
+<p><img src="http://qbnz.com/highlighter/images/geshi.png" alt="The GeSHi Logo" /></p>
+
+<dl>
+<dt>Authors:</dt>
+<dd>&copy; 2004 - 2007&#160;<a href="mailto:nigel@geshi.org">Nigel McNie</a></dd>
+
+<dd>&copy; 2007 - 2009&#160;<a href="mailto:BenBE@omorphia.de">Benny Baumann</a></dd>
+
+<dd>&copy; 2008 - 2009&#160;<a href="mailto:mail@milianw.de">Milian Wolff</a></dd>
+
+<dt><abbr title="Generic Syntax Highlighter">GeSHi</abbr> Website:</dt>
+<dd><a href="http://qbnz.com/highlighter">http://qbnz.com/highlighter</a></dd>
+</dl>
+
+</div>
+
+<p>This is the documentation for <abbr title="Generic Syntax Highlighter">GeSHi</abbr> - Generic Syntax Highlighter.</p>
+
+<p>The most modern version of this document is available on the web -
+go to <a href="http://qbnz.com/highlighter/documentation.php">http://qbnz.com/highlighter/documentation.php</a> to view it.</p>
+
+<p>Any comments, questions, confusing points? Please <a href="#feedback">get in contact</a> with the developers! We
+need all the information we can get to make the use of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> and everything related to it (including this documentation)
+a breeze.</p>
+
+<h2 id="contents">Contents</h2>
+
+<div id="toc"><ul>
+<li><a href="#introduction">1 Introduction</a><ul>
+<li><a href="#features">1.1 Features</a></li>
+<li><a href="#about-geshi">1.2 About <abbr title="Generic Syntax Highlighter">GeSHi</abbr></a></li>
+<li><a href="#credits">1.3 Credits</a></li>
+<li><a href="#feedback">1.4 Feedback</a></li>
+</ul></li>
+<li><a href="#the-basics">2 The Basics</a><ul>
+<li><a href="#getting-geshi">2.1 Getting <abbr title="Generic Syntax Highlighter">GeSHi</abbr> work</a><ul>
+<li><a href="#requirements">2.1.1 Requirements</a></li>
+<li><a href="#downloading-geshi">2.1.2 Downloading <abbr title="Generic Syntax Highlighter">GeSHi</abbr></a></li>
+<li><a href="#extracting-geshi">2.1.3 Extracting <abbr title="Generic Syntax Highlighter">GeSHi</abbr></a></li>
+<li><a href="#installing-geshi">2.1.4 Installing <abbr title="Generic Syntax Highlighter">GeSHi</abbr></a></li>
+</ul></li>
+<li><a href="#basic-usage">2.2 Basic Usage</a></li>
+</ul></li>
+<li><a href="#advanced-features">3 Advanced Features</a><ul>
+<li><a href="#the-code-container">3.1 The Code Container</a></li>
+<li><a href="#line-numbers">3.2 Line Numbers</a><ul>
+<li><a href="#enabling-line-numbers">3.2.1 Enabling Line Numbers</a></li>
+<li><a href="#styling-line-numbers">3.2.2 Styling Line Numbers</a></li>
+<li><a href="#starting-line-numbers">3.2.3 Choosing a Start Number</a></li>
+</ul></li>
+<li><a href="#using-css-classes">3.3 Using <abbr title="Cascading Style Sheets">CSS</abbr> Classes</a><ul>
+<li><a href="#enabling-css-classes">3.3.1 Enabling <abbr title="Cascading Style Sheets">CSS</abbr> Classes</a></li>
+<li><a href="#setting-css-class-id">3.3.2 Setting the <abbr title="Cascading Style Sheets">CSS</abbr> class and ID</a></li>
+<li><a href="#getting-stylesheet">3.3.3 Getting the stylesheet for your code</a></li>
+<li><a href="#using-an-external-stylesheet">3.3.4 Using an External Stylesheet</a></li>
+</ul></li>
+<li><a href="#changing-styles">3.4 Changing Styles</a><ul>
+<li><a href="#the-overall-styles">3.4.1 The Overall Styles</a></li>
+<li><a href="#line-number-styles">3.4.2 Line Number Styles</a></li>
+<li><a href="#setting-keyword-styles">3.4.3 Setting Keyword Styles</a></li>
+<li><a href="#setting-comment-styles">3.4.4 Setting Comment Styles</a></li>
+<li><a href="#setting-other-styles">3.4.5 Setting Other Styles</a></li>
+</ul></li>
+<li><a href="#case-caps">3.5 Case Sensitivity and Auto Casing</a><ul>
+<li><a href="#auto-caps-nocaps">3.5.1 Auto-Caps/NoCaps</a></li>
+<li><a href="#setting-case-sensitivity">3.5.2 Setting Case Sensitivity</a></li>
+</ul></li>
+<li><a href="#changing-config">3.6 Changing the Source, Language, Config Options</a><ul>
+<li><a href="#changing-the-source">3.6.1 Changing the Source Code</a></li>
+<li><a href="#changing-the-language">3.6.2 Changing the Language</a></li>
+<li><a href="#changing-the-path">3.6.3 Changing the Language Path</a></li>
+<li><a href="#changing-the-charset">3.6.4 Changing the Character Set</a></li>
+</ul></li>
+<li><a href="#error-handling">3.7 Error Handling</a></li>
+<li><a href="#disabling-lexics">3.8 Disabling styling of some Lexics</a></li>
+<li><a href="#setting-tab-width">3.9 Setting the Tab Width</a></li>
+<li><a href="#using-strict-mode">3.10 Using Strict Mode</a></li>
+<li><a href="#adding-removing-keywords">3.11 Adding/Removing Keywords</a><ul>
+<li><a href="#adding-a-keyword">3.11.1 Adding a Keyword</a></li>
+<li><a href="#removing-a-keyword">3.11.2 Removing a Keyword</a></li>
+<li><a href="#adding-a-keyword-group">3.11.3 Adding a Keyword Group</a></li>
+<li><a href="#removing-a-keyword-group">3.11.4 Removing a Keyword Group</a></li>
+</ul></li>
+<li><a href="#headers-and-footers">3.12 Headers and Footers for Your Code</a><ul>
+<li><a href="#keyword-substitution">3.12.1 Keyword Substitution</a></li>
+<li><a href="#setting-header-content">3.12.2 Setting Header Content</a></li>
+<li><a href="#setting-footer-content">3.12.3 Setting Footer Content</a></li>
+<li><a href="#styling-header-content">3.12.4 Styling Header Content</a></li>
+<li><a href="#styling-footer-content">3.12.5 Styling Footer Content</a></li>
+</ul></li>
+<li><a href="#keyword-urls">3.13 Keyword URLs</a><ul>
+<li><a href="#setting-a-url">3.13.1 Setting a URL for a Keyword Group</a></li>
+<li><a href="#disabling-urls">3.13.2 Disabling a URL for a Keyword Group</a></li>
+<li><a href="#disabling-all-urls">3.13.3 Disabling all URLs for Keywords</a></li>
+<li><a href="#styling-links">3.13.4 Styling Links</a></li>
+<li><a href="#using-targets">3.13.5 Setting the Link Target</a></li>
+</ul></li>
+<li><a href="#using-contextual-importance">3.14 Using Contextual Importance</a></li>
+<li><a href="#highlighting-special-lines-extra">3.15 Highlighting Special Lines &#8220;Extra&#8221;</a><ul>
+<li><a href="#specifying-lines-to-highlight-extra">3.15.1 Specifying the Lines to Highlight Extra</a></li>
+<li><a href="#styles-for-highlighted-lines">3.15.2 Styles for the Highlighted Lines</a></li>
+</ul></li>
+<li><a href="#adding-ids-to-each-line">3.16 Adding IDs to Each Line</a></li>
+<li><a href="#getting-the-time-of-styling">3.17 Getting the Time of Styling</a></li>
+</ul></li>
+<li><a href="#language-files">4 Language Files</a><ul>
+<li><a href="#language-file-example">4.1 An Example Language File</a></li>
+<li><a href="#language-file-conventions">4.2 Language File Conventions</a></li>
+<li><a href="#language-file-sections">4.3 Language File Sections</a><ul>
+<li><a href="#language-file-header">4.3.1 The Header</a></li>
+<li><a href="#language-file-start-indices">4.3.2 The First Indices</a></li>
+<li><a href="#language-file-keywords">4.3.3 Keywords</a></li>
+<li><a href="#language-file-symbols-case">4.3.4 Symbols and Case Sensitivity</a></li>
+<li><a href="#language-file-styles">4.3.5 Styles for your Language File</a></li>
+<li><a href="#language-file-urls">4.3.6 URLs for Functions</a></li>
+<li><a href="#language-file-numbers-support">4.3.7 Number Highlighting Support</a></li>
+<li><a href="#language-file-oo-support">4.3.8 Object Orientation Support</a></li>
+<li><a href="#language-file-regexps">4.3.9 Using Regular Expressions</a></li>
+<li><a href="#language-file-strict-mode">4.3.10 Contextual Highlighting and Strict Mode</a></li>
+<li><a href="#language-file-parser-control">4.3.11 Special Parser Settings (Experimental)</a></li>
+<li><a href="#language-file-tidying-up">4.3.12 Tidying Up</a></li>
+</ul></li>
+<li><a href="#lang-validation">4.4 Validating your language file</a></li>
+</ul></li>
+<li><a href="#method-constant-reference">5 Method/Constant Reference</a></li>
+</ul>
+</div>
+
+<h2 id="introduction">1 Introduction</h2><div class="nav"><a href="#features">Next</a></div>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> is exactly what the acronym stands for: a <strong>Generic Syntax Highlighter</strong>. As long
+as you have a language file for almost any computer language - whether it be a
+scripting language, object orientated, markup or anything in between - <abbr title="Generic Syntax Highlighter">GeSHi</abbr> can
+highlight it! <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is extremely customisable - the same source can be highlighted
+multiple times in multiple ways - the same source even with a different language.
+<abbr title="Generic Syntax Highlighter">GeSHi</abbr> outputs XHTML strict compliant code<sup id="fnref:xhtml-strict"><a href="#fn:xhtml-strict" rel="footnote">1</a></sup>, and can
+make use of <abbr title="Cascading Style Sheets">CSS</abbr> to save on the amount of output. And what is the cost for all of this? You need
+<a href="http://php.net"><abbr title="PHP: HTML Preprocessor">PHP</abbr></a>. That&#8217;s all!</p>
+
+<h3 id="features">1.1 Features</h3><div class="nav"><a href="#introduction">Previous</a> | <a href="#introduction">Top</a> | <a href="#about-geshi">Next</a></div>
+
+<p>Here are some of the standout features of <abbr title="Generic Syntax Highlighter">GeSHi</abbr>:</p>
+
+<dl>
+<dt>Programmed in <abbr title="PHP: HTML Preprocessor">PHP</abbr>:</dt>
+<dd><abbr title="Generic Syntax Highlighter">GeSHi</abbr> is coded entirely in <abbr title="PHP: HTML Preprocessor">PHP</abbr>. This means that where ever you have <abbr title="PHP: HTML Preprocessor">PHP</abbr>, you
+can have <abbr title="Generic Syntax Highlighter">GeSHi</abbr>! Almost any free webhost supports <abbr title="PHP: HTML Preprocessor">PHP</abbr>, and <abbr title="Generic Syntax Highlighter">GeSHi</abbr> works fine with <abbr title="PHP: HTML Preprocessor">PHP</abbr> > 4.3.0<sup id="fnref:php-version-note"><a href="#fn:php-version-note" rel="footnote">2</a></sup>.</dd>
+
+<dt>Support for many languages:</dt>
+<dd><abbr title="Generic Syntax Highlighter">GeSHi</abbr> comes with more than <em>100</em> languages, including <abbr title="PHP: HTML Preprocessor">PHP</abbr>, <abbr title="Hypertext Markup Language">HTML</abbr>, <abbr title="Cascading Style Sheets">CSS</abbr>, Java, C, Lisp, <abbr title="Extensible Markup Language">XML</abbr>, Perl, Python,
+<abbr title="Assembly language">ASM</abbr> and many more!</dd>
+
+<dt>XHTML compliant output:</dt>
+<dd><abbr title="Generic Syntax Highlighter">GeSHi</abbr> produces XHTML compliant output, using stylesheets, so you need not worry about
+<abbr title="Generic Syntax Highlighter">GeSHi</abbr> ruining your claims to perfection in the standards department ;)</dd>
+
+<dt>Highly customisable:</dt>
+<dd><abbr title="Generic Syntax Highlighter">GeSHi</abbr> allows you to change the style of the output on the fly, use <abbr title="Cascading Style Sheets">CSS</abbr> classes or not, use an external
+stylesheet or not, use line numbering, change the case of output keywords&#8230; the list goes on and on!</dd>
+
+<dt>Flexible:</dt>
+<dd>Unfortunately, <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is quite load/time intensive for large blocks of code. However, you want speed?
+Turn off any features you don&#8217;t like, pre-make a stylesheet and use <abbr title="Cascading Style Sheets">CSS</abbr> classes to reduce the amount of output and more -
+it&#8217;s easy to strike a balance that suits you.</dd>
+</dl>
+
+<p>This is just a taste of what you get with <abbr title="Generic Syntax Highlighter">GeSHi</abbr> - the best syntax highlighter for the web in the world!</p>
+
+<h3 id="about-geshi">1.2 About <abbr title="Generic Syntax Highlighter">GeSHi</abbr></h3><div class="nav"><a href="#features">Previous</a> | <a href="#introduction">Top</a> | <a href="#credits">Next</a></div>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> started as a mod for the <a href="http://phpbb.net"><abbr title="PHP Burning Board">phpBB</abbr></a> forum system, to enable highlighting of more
+languages than the available (which can be roughly estimated to exactly 0 ;)). However, it quickly spawned into an
+entire project on its own. But now it has been released, work continues on a mod
+for phpBB<sup id="fnref:phpbb-note"><a href="#fn:phpbb-note" rel="footnote">3</a></sup> - and hopefully for many forum systems, blogs and other web-based systems.</p>
+
+<p>Several systems are using <abbr title="Generic Syntax Highlighter">GeSHi</abbr> now, including:</p>
+
+<ul>
+<li><a href="http://www.splitbrain.org/docuwiki/">Dokuwiki</a> - An advanced wiki engine</li>
+<li><a href="http://gtk.php.net/">gtk.php.net</a> - Their manual uses <abbr title="Generic Syntax Highlighter">GeSHi</abbr> for syntax highlighting</li>
+<li><a href="http://www.wordpress.org/">WordPress</a> - A powerful blogging system<sup id="fnref:plugin-only"><a href="#fn:plugin-only" rel="footnote">4</a></sup></li>
+<li><a href="http://www.php-fusion.co.uk/"><abbr title="PHP: HTML Preprocessor">PHP</abbr>-Fusion</a> - A constantly evolving CMS</li>
+<li><a href="http://cypreess.dione.cc/sqlm">SQL Manager</a> - A Postgres DBAL</li>
+<li><a href="http://www.mamboserver.com/">Mambo</a> - A popular open source CMS</li>
+<li><a href="http://www.mediawiki.org/">MediaWiki</a> - A leader in Wikis[^plugin-only]</li>
+<li><a href="http://www.tikiwiki.org/">TikiWiki</a> - A megapowerful Wiki/CMS</li>
+<li><a href="http://www.tikipro.org/">TikiPro</a> - Another powerful Wiki based on TikiWiki</li>
+<li><a href="http://www.wikkawiki.org/">WikkaWiki</a> - A flexible and lightweight Wiki engine</li>
+<li><a href="http://robloach.net/projects/phpscripts/rweb/">RWeb</a> - A site-building tool</li>
+</ul>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> is the original work of <a href="mailto:nigel@geshi.org">Nigel McNie</a>. The project was later handed over to <a href="mailto:BenBE@omorphia.de">Benny Baumann</a>.
+Others have helped with aspects of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> also, they&#8217;re mentioned in the <a href="THANKS"><code>THANKS</code></a> file.</p>
+
+<h3 id="credits">1.3 Credits</h3><div class="nav"><a href="#about-geshi">Previous</a> | <a href="#introduction">Top</a> | <a href="#feedback">Next</a></div>
+
+<p>Many people have helped out with <abbr title="Generic Syntax Highlighter">GeSHi</abbr>, whether by creating language files, submitting bug
+reports, suggesting new ideas or simply pointing out a new idea or something I&#8217;d missed. All
+of these people have helped to build a better <abbr title="Generic Syntax Highlighter">GeSHi</abbr>, you can see them in the <a href="THANKS"><code>THANKS</code></a>
+file.</p>
+
+<p>Do you want your name on this list? Why not make a language file, or submit a valid bug? Or perhaps help me with an
+added feature I can&#8217;t get my head around, or suggest a new feature, or even port
+<abbr title="Generic Syntax Highlighter">GeSHi</abbr> to anothe language? There&#8217;s lots you can do to help out, and I need it all :)</p>
+
+<h3 id="feedback">1.4 Feedback</h3><div class="nav"><a href="#credits">Previous</a> | <a href="#introduction">Top</a> | <a href="#the-basics">Next</a></div>
+
+<p>I need your feedback! <em>ANY</em>thing you have to say is fine, whether it be a query,
+congratulations, a bug report or complaint, I don&#8217;t care! I want to make this software
+the best it can be, and I need your help! You can contact me in the following ways:</p>
+
+<ul>
+<li><strong>E-mail:</strong>  <a href="mailto:nigel@geshi.org">Nigel McNie</a>, <a href="mailto:BenBE@omorphia.de">Benny Baumann</a> or better yet: use the <a href="http://lists.sourceforge.net/mailman/listinfo/geshi-users">geshi-users</a> mailinglist</li>
+<li><strong>Forums:</strong>  <a href="http://sourceforge.net/forum?group_id=114997">Sourceforge.net Forums</a></li>
+<li><strong>IRC:</strong> <a href="irc://irc.freenode.net/geshi">#geshi</a> on <a href="http://freenode.net">Freenode</a></li>
+</ul>
+
+<p>Remember, any help I am grateful for :)</p>
+
+<h2 id="the-basics">2 The Basics</h2><div class="nav"><a href="#feedback">Previous</a> | <a href="#getting-geshi">Next</a></div>
+
+<p>In this section, you&#8217;ll learn a bit about <abbr title="Generic Syntax Highlighter">GeSHi</abbr>, how it works and what it uses, how to install it and how to use
+it to perform basic highlighting.</p>
+
+<h3 id="getting-geshi">2.1 Getting <abbr title="Generic Syntax Highlighter">GeSHi</abbr> work</h3><div class="nav"><a href="#the-basics">Previous</a> | <a href="#the-basics">Top</a> | <a href="#requirements">Next</a></div>
+
+<p>If you&#8217;re reading this and don&#8217;t have <abbr title="Generic Syntax Highlighter">GeSHi</abbr>, that&#8217;s a problem ;). So, how do you get your hands on it?</p>
+
+<h4 id="requirements">2.1.1 Requirements</h4><div class="nav"><a href="#getting-geshi">Previous</a> | <a href="#getting-geshi">Top</a> | <a href="#downloading-geshi">Next</a></div>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> requires the following to be installable:</p>
+
+<ul>
+<li><strong><a href="http://php.net"><abbr title="PHP: HTML Preprocessor">PHP</abbr></a></strong>. It&#8217;s untested with anything other below 4.4.X. I hope to extend this range soon. I see no reason why
+it won&#8217;t work with any version of <abbr title="PHP: HTML Preprocessor">PHP</abbr> above 4.3.0.</li>
+<li><strong>Approximately 2 megabytes of space</strong>. The actual script is small - around 150K - but most of the size comes
+from the large number of language files (over 100!). If you&#8217;re pushed for space, make sure you don&#8217;t upload to
+your server the <code>docs/</code> or <code>contrib/</code> directory, and you may want to leave out any language files that don&#8217;t
+take your fancy either.</li>
+</ul>
+
+<p>As you can see, the requirements are very small. If <abbr title="Generic Syntax Highlighter">GeSHi</abbr> does NOT work for you in a particular version of <abbr title="PHP: HTML Preprocessor">PHP</abbr>, let
+me know why and I&#8217;ll fix it.</p>
+
+<h4 id="downloading-geshi">2.1.2 Downloading <abbr title="Generic Syntax Highlighter">GeSHi</abbr></h4><div class="nav"><a href="#requirements">Previous</a> | <a href="#getting-geshi">Top</a> | <a href="#extracting-geshi">Next</a></div>
+
+<p>There are several ways to get a copy of <abbr title="Generic Syntax Highlighter">GeSHi</abbr>. The first and easiest way of all is
+visiting <a href="http://qbnz.com/highlighter/downloads.php">http://qbnz.com/highlighter/downloads.php</a> to obtain the latest version.
+This is suitable especially when you plan on using <abbr title="Generic Syntax Highlighter">GeSHi</abbr> on an production website
+or otherwise need a stable copy for flawless operation.</p>
+
+<p>If you are somewhat more sophisticated or need a feature just recently implemented
+you might consider getting <abbr title="Generic Syntax Highlighter">GeSHi</abbr> by downloading via SVN. There are multiple ways
+for doing so and each one has its own advantages and disadvantages. Let&#8217;s cover
+the various locations in the SVN you might download from:</p>
+
+<ul>
+<li><a href="https://geshi.svn.sourceforge.net/svnroot/geshi/tags/">https://geshi.svn.sourceforge.net/svnroot/geshi/tags/</a>:<br />
+This directory holds all previous releases of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> each as a subdirectory. By downloading from here you can test your code with various old versions
+in case something has been broken recently.</li>
+<li><a href="https://geshi.svn.sourceforge.net/svnroot/geshi/branches/RELEASE_1_0_X_STABLE/geshi-1.0.X/src/">https://geshi.svn.sourceforge.net/svnroot/geshi/branches/RELEASE_1_0_X_STABLE/geshi-1.0.X/src/</a>:<br />
+This directory is the right place for you if you want to have reasonably current versions of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> but need something that is stable. This directory
+is updated once in a while between updates whenever there&#8217;s something new but which is already reasonably stable. This branch is used to form the
+actual release once the work is done.</li>
+<li><a href="https://geshi.svn.sourceforge.net/svnroot/geshi/trunk/geshi-1.0.X/src/">https://geshi.svn.sourceforge.net/svnroot/geshi/trunk/geshi-1.0.X/src/</a>:<br />
+This directory is the working directory where every new feature, patch or improvement is committed to. This directory is updated regularly, but is not
+guaranteed to be tested and stable at all times. With this version you&#8217;ll always get the latest version of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> out there, but beware of bugs! There
+will be loads of them here! So this is absolutely <strong>not recommended</strong> for productive use!</li>
+</ul>
+
+<p>If you have choosen the right SVN directory for you do a quick
+<code class="highlighted bash"><span class="kw2">svn</span> <span class="kw2">co</span> <span class="re1">$SVNPATH</span> geshi</code> where <code class="highlighted bash"><span class="re1">$SVNPATH</span></code> is one of the above paths and your desired version of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> will be
+downloaded into an subdirectory called &#8220;geshi&#8221;. If you got a version of <abbr title="Generic Syntax Highlighter">GeSHi</abbr>
+you can go on installing as shown below.</p>
+
+<h4 id="extracting-geshi">2.1.3 Extracting <abbr title="Generic Syntax Highlighter">GeSHi</abbr></h4><div class="nav"><a href="#downloading-geshi">Previous</a> | <a href="#getting-geshi">Top</a> | <a href="#installing-geshi">Next</a></div>
+
+<p>Packages come in <code>.zip</code>, <code>.tar.gz</code> and <code>.tar.bz2</code> format, so there&#8217;s no complaining about whether it&#8217;s available for
+you. *nix users probably want <code>.tar.gz</code> or <code>.tar.bz2</code> and windows users probably want <code>.zip</code>.
+And those lucky to download it directly from SVN don&#8217;t even need to bother extracting <abbr title="Generic Syntax Highlighter">GeSHi</abbr>.</p>
+
+<p>To extract <abbr title="Generic Syntax Highlighter">GeSHi</abbr> in Linux (<code>.tar.gz</code>):</p>
+
+<ol>
+<li>Open a shell</li>
+<li><code class="highlighted bash"><span class="kw3">cd</span></code> to the directory where the archive lies</li>
+<li>Type <code class="highlighted bash"><span class="kw2">tar</span> <span class="re5">-xzvf</span> <span class="br0">&#91;</span>filename<span class="br0">&#93;</span></code> where <code>[filename]</code> is the name of the archive (typically <code>GeSHi-1.X.X.tar.gz</code>)</li>
+<li><abbr title="Generic Syntax Highlighter">GeSHi</abbr> will be extracted to its own directory</li>
+</ol>
+
+<p>To extract <abbr title="Generic Syntax Highlighter">GeSHi</abbr> in Windows (<code>.zip</code>):</p>
+
+<ol>
+<li>Open Explorer</li>
+<li>Navigate to the directory where the archive lies</li>
+<li>Extract the archive. The method you use will depend on your configuration. Some people can right-click upon
+the archive and select &#8220;Extract&#8221; from there, others may have to drag the archive and drop it upon an extraction program.</li>
+</ol>
+
+<p>To extract from <code>.zip</code> you&#8217;ll need an unzipping program - <code class="highlighted bash"><span class="kw2">unzip</span></code> in Linux, or 7-Zip, WinZip, WinRAR or similar for Windows.</p>
+
+<h4 id="installing-geshi">2.1.4 Installing <abbr title="Generic Syntax Highlighter">GeSHi</abbr></h4><div class="nav"><a href="#extracting-geshi">Previous</a> | <a href="#getting-geshi">Top</a> | <a href="#basic-usage">Next</a></div>
+
+<p>Installing <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is a snap, even for those most new to <abbr title="PHP: HTML Preprocessor">PHP</abbr>. There&#8217;s no tricks involved. Honest!</p>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> is nothing more than a <abbr title="PHP: HTML Preprocessor">PHP</abbr> class with related language support files. Those of you familiar with <abbr title="PHP: HTML Preprocessor">PHP</abbr> can then
+guess how easy the installation will be: simply copy it into your include path somewhere. You can put it wherever you
+like in this include path. I recommend that you put the language files in a subdirectory of your include path too -
+perhaps the same subdirectory that geshi.php is in. <strong>Remember this path</strong> for later.</p>
+
+<p>If you don&#8217;t know what an include path is, don&#8217;t worry. Simply copy <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to your webserver. So for example, say your
+site is at <code>http://mysite.com/myfolder</code>, you can copy <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to your site so the directory structure is like this:</p>
+
+<pre><code>http://mysite.com/myfolder/geshi/[language files]
+http://mysite.com/myfolder/geshi.php
+</code></pre>
+
+<p>Or you can put it in any subdirectory you like:</p>
+
+<pre><code>http://mysite.com/myfolder/includes/geshi/[language files]
+http://mysite.com/myfolder/includes/geshi.php
+</code></pre>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>When using <abbr title="Generic Syntax Highlighter">GeSHi</abbr> on a live site, the only directory required is the <code>geshi/</code> subdirectory. Both <code>contrib/</code> and <code>docs/</code> are
+worthless, and furthermore, as some people discovered, one of the files in contrib had a security hole (fixed as of 1.0.7.3).
+I suggest you delete these directories from any live site they are on.</p>
+
+</div>
+
+<h3 id="basic-usage">2.2 Basic Usage</h3><div class="nav"><a href="#installing-geshi">Previous</a> | <a href="#the-basics">Top</a> | <a href="#advanced-features">Next</a></div>
+
+<p>Use of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is very easy. Here&#8217;s a simple example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+<span class="xtra li2"><span class="de2">28</span></span></pre></td><td class="de1"><pre class="de1"><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// Include the GeSHi library</span></span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">include_once</span> <span class="st_h">'geshi.php'</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="co1">//</span></span></span><span class="co1">// Define some source to highlight, a language to use</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// and the path to the language files</span></span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$source</span> <span class="sy0">=</span> <span class="st_h">'$foo = 45;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">for ( $i = 1; $i &lt; $foo; $i++ )</span></span></span><span class="st_h">{</span>
+<span class="xtra li2"><span class="de2"><span class="st_h"> &nbsp;echo &quot;$foo\n&quot;;</span></span></span><span class="st_h"> &nbsp;--$foo;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">}'</span><span class="sy0">;</span></span></span><span class="re0">$language</span> <span class="sy0">=</span> <span class="st_h">'php'</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// Create a GeSHi object</span></span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="re0">$language</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// And echo the result!</span></span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<p>As you can see, there&#8217;s only three really important lines:</p>
+
+<p><code class="highlighted php"><span class="kw1">include_once</span><span class="br0">&#40;</span><span class="st_h">'geshi.php'</span><span class="br0">&#41;</span></code></p>
+
+<p>This line includes the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> class for use</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="re0">$language</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>This line creates a new <abbr title="Generic Syntax Highlighter">GeSHi</abbr> object, holding the source and the language you want to use for highlighting.</p>
+
+<p><code class="highlighted php"><span class="kw1">echo</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>This line spits out the result :)</p>
+
+<p>So as you can see, simple usage of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is really easy. Just create a new <abbr title="Generic Syntax Highlighter">GeSHi</abbr> object and get the code!</p>
+
+<p>Since version 1.0.2, there is a function included with <abbr title="Generic Syntax Highlighter">GeSHi</abbr> called <code>geshi_highlight</code>. This behaves exactly as the php
+function <code class="highlighted php"><span class="kw3">highlight_string</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code> behaves - all you do is pass it the language you want to use to highlight and the
+path to the language files as well as the source. Here are some examples:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+</pre></td><td class="de1"><pre class="de1"><span class="co1">// Simply echo the highlighted code</span>
+<span class="xtra li2"><span class="de2">geshi_highlight<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'php'</span><span class="sy0">,</span> <span class="re0">$path</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="co1">// Get the code back, for use later</span></span></span><span class="re0">$code</span> <span class="sy0">=</span> geshi_highlight<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'java'</span><span class="sy0">,</span> <span class="re0">$path</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// Check if there is an error with parsing this code</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><a href="http://www.php.net/ob_start"><span class="kw3">ob_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$result</span> <span class="sy0">=</span> geshi_highlight<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'perl'</span><span class="sy0">,</span> <span class="re0">$path</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span><span class="re0">$code</span> <span class="sy0">=</span> <a href="http://www.php.net/ob_get_contents"><span class="kw3">ob_get_contents</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><a href="http://www.php.net/ob_end_clean"><span class="kw3">ob_end_clean</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy0">!</span><span class="re0">$result</span> <span class="br0">&#41;</span></span></span><span class="br0">&#123;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// There was an error with highlighting...</span></span></span><span class="br0">&#125;</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">else</span></span></span><span class="br0">&#123;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// All OK :)</span></span></span><span class="br0">&#125;</span></pre></td></tr></tbody></table>
+
+<p>However, these are really simple examples and doesn&#8217;t even begin to cover all the advanced features of <abbr title="Generic Syntax Highlighter">GeSHi</abbr>.
+If you want to learn more, continue on to section 3: Advanced Features.</p>
+
+<h2 id="advanced-features">3 Advanced Features</h2><div class="nav"><a href="#basic-usage">Previous</a> | <a href="#the-code-container">Next</a></div>
+
+<p>This section documents the advanced features of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> - strict mode, using <abbr title="Cascading Style Sheets">CSS</abbr> classes, changing styles on the fly,
+disabling highlighting of some things and more.</p>
+
+<p>In this section there are many code snippets. For all of these, you should assume that the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> library has been
+included, and a <abbr title="Generic Syntax Highlighter">GeSHi</abbr> object has been created and is referenced by the variable <code class="highlighted php"><span class="re0">$geshi</span></code>. Normally, the
+source, language and path used are arbitary.</p>
+
+<h3 id="the-code-container">3.1 The Code Container</h3><div class="nav"><a href="#advanced-features">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#line-numbers">Next</a></div>
+
+<p>The <strong>Code Container</strong> has a fundamental effect on the layout of your code before you even begin to style. What is the
+Code Container? It&#8217;s the bit of markup that goes around your code to contain it. By default your code is surrounded
+by a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code>, but you can also specify a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>.</p>
+
+<p>The <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> header is the default. If you&#8217;re familiar with <abbr title="Hypertext Markup Language">HTML</abbr> you&#8217;ll know that whitespace is rendered
+&#8220;as is&#8221; by a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> element. The advantage for you is that if you use <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> the whitespace
+you use will appear pretty much exactly how it is in the source, and what&#8217;s more <abbr title="Generic Syntax Highlighter">GeSHi</abbr> won&#8217;t have to add a whole
+lot of <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">br</span> <span class="sy0">/</span>&gt;</span></code>&#8217;s and non-breaking spaces (<code class="highlighted html4strict"><span class="sc1">&amp;nbsp;</span></code>) to your code to indent it. This saves
+you source code (and your valuable visitors waiting time and your bandwidth).</p>
+
+<p>But if you don&#8217;t like <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> or it looks stupid in your browser no matter what styles you try to
+apply to it or something similar, you might want to use a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> instead. A <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> will
+result in more source - <abbr title="Generic Syntax Highlighter">GeSHi</abbr> will have to insert whitespace markup - but in return you can wrap long lines of code
+that would otherwise have your browser&#8217;s horizontal scrollbar appear. Of course with <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> you can
+<em>not</em> wrap lines if you please. The highlighter demo at the <a href="http://qbnz.com/highlighter"><abbr title="Generic Syntax Highlighter">GeSHi</abbr> home page</a> uses the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>
+approach for this reason.</p>
+
+<p>At this stage there isn&#8217;t an option to wrap the code in <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">code</span>&gt;</span></code> tags (unless you use the function
+<code>geshi_highlight</code>), partly because of the inconsistent and unexpected ways stuff in <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">code</span>&gt;</span></code> tags is
+highlighted. Besides, <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">code</span>&gt;</span></code> is an inline element. But this may become an option in future versions.</p>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.7.2 there is a new header type, that specifies that the code should not be wrapped in anything at all.</p>
+
+<p>Another requested addition has been made in <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.7.20 to force <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to create a block around the highlighted
+source even if this wasn&#8217;t necessary, thus styles that are applied to the output of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> can directly influence
+the code only even if headers and footers are present.</p>
+
+<p>To change/set the header to use, you call the <strong><code class="highlighted php">set_header_type<span class="br0">&#40;</span><span class="br0">&#41;</span></code></strong> method. It has one required argument which
+defines the container type. Available are:</p>
+
+<dl>
+<dt><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_type</span><span class="br0">&#40;</span>GESHI_HEADER_DIV<span class="br0">&#41;</span><span class="sy0">;</span></code></dt>
+<dd>
+<p>Puts a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> around both, code and linenumbers. Whitespace is converted to <code class="highlighted html4strict"><span class="sc1">&amp;nbsp;</span></code>
+sequences (i.e. one whitespace and the html entity of a non-breaking whitespace) to keep your indendation level
+in tact. Tabs are converted as well and you can manually <a href="#setting-tab-width">define the tab-width</a>. Lines are automatically wrapped.
+Linenumbers are created using an ordered list.</p>
+</dd>
+
+<dt><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_type</span><span class="br0">&#40;</span>GESHI_HEADER_PRE<span class="br0">&#41;</span><span class="sy0">;</span></code></dt>
+<dd>
+<p>Wraps code and linenumbers in a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> container. This way whitespace is kept as-is and thus
+this header produces less overhead then the <code>GESHI_HEADER_DIV</code> header type. Since linenumbers are still
+created using an ordered list this header type produces <strong>invalid <abbr title="Hypertext Markup Language">HTML</abbr></strong>.</p>
+</dd>
+
+<dt><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_type</span><span class="br0">&#40;</span>GESHI_HEADER_PRE_VALID<span class="br0">&#41;</span><span class="sy0">;</span></code></dt>
+<dd><em><small>Available since 1.0.8</small></em></dd>
+
+<dd>
+<p>When linenumbers are disabled, this behaves just like <code>GESHI_HEADER_PRE</code>. In the other case though, a
+<code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> is used to wrap the code and linenumbers and the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> is put inside the list
+items (<code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">li</span>&gt;</span></code>). This means slightly larger <abbr title="Hypertext Markup Language">HTML</abbr> output compared to <code>GESHI_HEADER_PRE</code>, but the
+output is <strong>valid <abbr title="Hypertext Markup Language">HTML</abbr></strong>.</p>
+</dd>
+
+<dt><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_type</span><span class="br0">&#40;</span>GESHI_HEADER_PRE_TABLE<span class="br0">&#41;</span><span class="sy0">;</span></code></dt>
+<dd><em><small>Available since 1.0.8</small></em></dd>
+
+<dd>
+<p>Once again a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> tag wraps the output. This time though no ordered list is used to create an ordered list,
+but instead we use a table with two cells in a single row. The left cell contains a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> tag which holds all
+linenumbers. The second cell holds the highlighted code, also wrapped in a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> tag, just like with
+<code>GESHI_HEADER_PRE</code>.</p>
+</dd>
+
+<dd>
+<p>This produces <strong>valid <abbr title="Hypertext Markup Language">HTML</abbr></strong> and works around the nasty selection behaviour of Firefox and other Gecko based
+browsers, see <a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1651996&amp;group_id=114997&amp;atid=670231">SF#1651996</a> for more information.</p>
+</dd>
+
+<dt><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_type</span><span class="br0">&#40;</span>GESHI_HEADER_NONE<span class="br0">&#41;</span><span class="sy0">;</span></code></dt>
+<dd><em><small>Available since 1.0.7.2</small></em></dd>
+
+<dd>
+<p>No wrapper is added.</p>
+</dd>
+</dl>
+
+<p>Those are the only arguments you should pass to <code class="highlighted php">set_header_type</code>. Passing anything else may cause inconsistencies
+in what is used as the Code Container (although it <em>should</em> simply use a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code>). Better not to risk it.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>GESHI_HEADER_DIV, GESHI_HEADER_PRE, etc. are <em>constants</em>, so don&#8217;t put them in strings!</p>
+
+</div>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>The default styles for the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> and <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> <em>will be different</em>, especially if you use
+  line numbers!</p>
+
+<p>I have found that a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> results in code that is smaller than for that of a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>, you
+  should rectify this difference by using <strong><code class="highlighted php">set_overall_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code></strong> if you need to. But be aware of this
+  difference for if you are changing the header type!</p>
+
+</div>
+
+<h3 id="line-numbers">3.2 Line Numbers</h3><div class="nav"><a href="#the-code-container">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#enabling-line-numbers">Next</a></div>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> has the ability to add line numbers to your code (see the demo available at <a href="http://qbnz.com/highlighter/demo.php">http://qbnz.com/highlighter/demo.php</a>
+to see what can be achieved). Line numbers are a great way to make your code look professional, especially if you use the
+fancy line numbers feature.</p>
+
+<p>There are multiple methods for highlighting line numbers, but none of them is perfect. Of the various ways to highlight
+line numbers <abbr title="Generic Syntax Highlighter">GeSHi</abbr> itself implements 2 different approaches, but allows you
+by the way it generates the code to do the line numbers yourself if necessary - but more on this case later.</p>
+
+<p>The easiest approach is using the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">ol</span>&gt;</span></code>-tag for generating the line numbers, but
+even though this is the easiest one there&#8217;s a big drawback with this one when
+using Gecko-engine based browsers like Firefox or Konqueror. In these browsers
+this approach will select the line numbers along with the code or will include extra markup in the selection.</p>
+
+<p>The other approach has been implemented in the 1.0.8 release of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> with the <code class="highlighted php">GESHI_HEADER_PRE_TABLE</code> header type.
+When using this header type the line numbers are rendered apart from the source
+in a table cell while the actual source is formatted as if the <code class="highlighted php">GESHI_HEADER_PRE</code> header had been used.
+This approach works with Firefox and other Gecko-based browsers so far although extreme care
+has to be taken when applying styles to your source as Windows has some fonts
+where bold font is of different height than normal or italic text of the same fontface.</p>
+
+<h4 id="enabling-line-numbers">3.2.1 Enabling Line Numbers</h4><div class="nav"><a href="#line-numbers">Previous</a> | <a href="#line-numbers">Top</a> | <a href="#styling-line-numbers">Next</a></div>
+
+<p>To highlight a source with line numbers, you call the <code class="highlighted php">enable_line_numbers<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_line_numbers</span><span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span><span class="sy0">;</span></code>
+Where <code class="highlighted php"><span class="re0">$flag</span></code> is one of the following:</p>
+
+<ul>
+<li><code>GESHI_NORMAL_LINE_NUMBERS</code> - Use normal line numbering</li>
+<li><code>GESHI_FANCY_LINE_NUMBERS</code> - Use fancy line numbering</li>
+<li><code>GESHI_NO_LINE_NUMBERS</code> - Disable line numbers (default)</li>
+</ul>
+
+<p>Normal line numbers means you specify a style for them, and that style gets applied to all of them. Fancy line numbers
+means that you can specify a different style for each n<sup>th</sup> line number. You change the value of n (default 5):</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_line_numbers</span><span class="br0">&#40;</span>GESHI_FANCY_LINE_NUMBERS<span class="sy0">,</span> <span class="nu0">37</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>The second parameter is not used in any other mode. Setting it to <code>0</code> is the same as simply using normal line numbers.
+Setting it to <code>1</code> applies the fancy style to every line number.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>The values above are CONSTANTS - so don&#8217;t put them in strings!</p>
+
+</div>
+
+<h4 id="styling-line-numbers">3.2.2 Styling Line Numbers</h4><div class="nav"><a href="#enabling-line-numbers">Previous</a> | <a href="#line-numbers">Top</a> | <a href="#starting-line-numbers">Next</a></div>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.2, line numbers are added by the use of ordered lists. This solves the old issues of line number
+styles inheriting from styles meant for the code. Also, this solves an important issue about selecting code. For
+example, line numbers look nice, but when you go to select the code in your browser to copy it? You got the line
+numbers too! Not such a good thing, but thankfully this issue is now solved. What is the price? Unfortunately the
+whole way that styles are inherited/used has changed for those of you who were familiar with 1.0.1, and there is
+quite a bit more <abbr title="Hypertext Markup Language">HTML</abbr> involved. So think carefully about these things before you enable line numbers.</p>
+
+<p>Now, onto how to style line numbers:</p>
+
+<p>Styles are set for line numbers using the <code class="highlighted php">set_line_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="st_h">'background: #fcfcfc;'</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>If you&#8217;re using Fancy Line Numbers mode, you pass a second string for the style of the n<sup>th</sup> line number:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="st_h">'background: #fcfcfc;'</span><span class="sy0">,</span> <span class="st_h">'background: #f0f0f0;'</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>The second style will have no effect if you&#8217;re not using Fancy Line Numbers mode.</p>
+
+<p>By default, the styles you pass overwrite the current styles. Add a boolean &#8220;true&#8221; after the styles you specify to combine them with the current styles:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="st_h">'background: red;'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// or, for fancy line numbers</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="st_h">'background: red;'</span><span class="sy0">,</span> <span class="st_h">'background: blue;'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Due to a bug with Firefox the issue that should have been fixed with 1.0.2 has reappeared in another form as Firefox
+  includes extra text\markup into plaintext versions of webpage copies. This can sometimes be useful (actually it&#8217;s
+  used to get the plaintext version of this documentation), but more often is quite annoying. Best practice so far is
+  to either not use line numbers, or offer the visitor of your page a plaintext version of your source. To learn more
+  have a look at the <a href="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1651996&amp;group_id=114997&amp;atid=670231">SF.net BugTracker Issue #1651996</a>. This will hopefully be fixed in <abbr title="Generic Syntax Highlighter">GeSHi</abbr> version 1.2
+  or as soon as Firefox provides webdevelopers with adequate ways to control this feature - whichever comes first!</p>
+
+</div>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>When you set line number styles, the code will inherit those styles! This is the main issue to come out of the 1.0.2
+  release. If you want your code to be styled in a predictable manner, you&#8217;ll have to call the <code class="highlighted php">set_code_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code>
+  method to rectify this problem.</p>
+
+<p>Note also that you cannot apply background colours to line numbers unless you use <code class="highlighted php">set_overall_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code>.
+  Here&#8217;s how you&#8217;d style:</p>
+
+<ol>
+<li><p>Use <code class="highlighted php">set_overall_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to style the overall code block. For example, you can set the border
+style/colour, any margins and padding etc. using this method. <strong>In addition:</strong> set the background colour for
+all the line numbers using this method.</p></li>
+<li><p>Use <code class="highlighted php">set_line_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to style the foreground of the line numbers. For example, you can set the colour,
+weight, font, padding etc. of the line numbers using this method.</p></li>
+<li><p>Use <code class="highlighted php">set_code_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to explicitly override the styles you set for line numbers using
+<code class="highlighted php">set_line_style</code>. For example, if you&#8217;d set the line numbers to be bold (or even if you&#8217;d only set
+the fancy line number style to be bold), and you didn&#8217;t actually want your code to be bold, you&#8217;d make sure
+that <code class="highlighted css"><span class="kw1">font-weight</span><span class="sy0">:</span> <span class="kw2">normal</span><span class="sy0">;</span></code> was in the stylesheet rule you passed to <code class="highlighted php">set_code_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code>.</p>
+
+<p>This is the one major change from <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.1 - make sure you become familiar with this, and make sure that you check
+any code you have already styled with 1.0.1 when you upgrade to make sure nothing bad happens to it.</p></li>
+</ol>
+
+</div>
+
+<h4 id="starting-line-numbers">3.2.3 Choosing a Start Number</h4><div class="nav"><a href="#styling-line-numbers">Previous</a> | <a href="#line-numbers">Top</a> | <a href="#using-css-classes">Next</a></div>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.2, you can now make the line numbers start at any number, rather than just 1. This feature is useful
+if you&#8217;re highlighting code from a file from around a certain line number in that file, as an additional guide to
+those who will view the code. You set the line numbers by calling the <code class="highlighted php">start_line_numbers_at<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">start_line_numbers_at</span><span class="br0">&#40;</span><span class="re0">$number</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p><code class="highlighted php"><span class="re0">$number</span></code> must be a positive integer (or zero). If it is not, <abbr title="Generic Syntax Highlighter">GeSHi</abbr> will convert it anyway.</p>
+
+<p>If you have not enabled line numbers, this will have no effect.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>Although I&#8217;d like <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to have XHTML strict compliance, this feature will break compliancy (however transitional
+  compliancy remains). This is because the only widely supported way to change the start value for line numbers is
+  by using the <strong>start=&#8221;number&#8221;</strong> attribute of the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">ol</span>&gt;</span></code> tag. Although <abbr title="Cascading Style Sheets">CSS</abbr> does provide a mechanism for
+  doing this, it is only supported in Opera versions 7.5 and above (not even Firefox supports this).</p>
+
+</div>
+
+<h3 id="using-css-classes">3.3 Using <abbr title="Cascading Style Sheets">CSS</abbr> Classes</h3><div class="nav"><a href="#starting-line-numbers">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#enabling-css-classes">Next</a></div>
+
+<p>Using <abbr title="Cascading Style Sheets">CSS</abbr> to highlight your code instead of in-lining the styles is a definate bonus. Not only is it more compliant
+(the w3c is deprecating the style attribute in XHTML 2.0) but it results in far less outputted code - up to a whopping
+90% saving - which makes a &#42;huge&#42; difference to those unlucky of us on modems!</p>
+
+<h4 id="enabling-css-classes">3.3.1 Enabling <abbr title="Cascading Style Sheets">CSS</abbr> Classes</h4><div class="nav"><a href="#using-css-classes">Previous</a> | <a href="#using-css-classes">Top</a> | <a href="#setting-css-class-id">Next</a></div>
+
+<p>By default, <abbr title="Generic Syntax Highlighter">GeSHi</abbr> doesn&#8217;t use the classes, so it&#8217;s easy just to whack out some highlighted code if you need without
+worrying about stylesheets. However, if you&#8217;re a bit more organised about it, you should use the classes ;). To turn
+the use of classes on, you call the <code class="highlighted php">enable_classes<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>If you want to turn classes OFF for some reason later:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>If classes are enabled when <code class="highlighted php">parse_code<span class="br0">&#40;</span><span class="br0">&#41;</span></code> is called, then the resultant source will use <abbr title="Cascading Style Sheets">CSS</abbr> classes in the
+output, otherwise it will in-line the styles. The advantages of using classes are great - the reduction in source will
+be very noticeable, and what&#8217;s more you can use one stylesheet for several different highlights on the same page. In
+fact, you can even use an external stylesheet and link to that, saving even more time and source (because stylesheets
+are cached by browsers).</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>There have been problems with inline styles and the Symbol Highlighting added in 1.0.7.21. If you can you should
+  therefore turn <abbr title="Cascading Style Sheets">CSS</abbr> classes ON to avoid those issues. Although latest reworks in 1.0.8 should fix most of those issues.</p>
+
+</div>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>This should be the very first method you call after creating a new <abbr title="Generic Syntax Highlighter">GeSHi</abbr> object! That way, various other methods
+  can act upon your choice to use classes correctly. In theory, you could call this method just before parsing the
+  code, but this may result in unexpected behaviour.</p>
+
+</div>
+
+<h4 id="setting-css-class-id">3.3.2 Setting the <abbr title="Cascading Style Sheets">CSS</abbr> class and ID</h4><div class="nav"><a href="#enabling-css-classes">Previous</a> | <a href="#using-css-classes">Top</a> | <a href="#getting-stylesheet">Next</a></div>
+
+<p>You can set an overall <abbr title="Cascading Style Sheets">CSS</abbr> class and id for the code. This is a good feature that allows you to use the same
+stylesheet for many different snippets of code. You call <code class="highlighted php">set_overall_class<span class="br0">&#40;</span><span class="br0">&#41;</span></code> and <code class="highlighted php">set_overall_id</code>
+to accomplish this:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_overall_class</span><span class="br0">&#40;</span><span class="st_h">'mycode'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_overall_id</span><span class="br0">&#40;</span><span class="st_h">'dk48ck'</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<p>The default classname is the name of the language being used. This means you can use just the one stylesheet for all
+sources that use the same language, and incidentally means that you probably won&#8217;t have to call these methods too often.</p>
+
+<p><abbr title="Cascading Style Sheets">CSS</abbr> IDs are supposed to be unique, and you should use them as such. Basically, you can specify an ID for your code
+and then use that ID to highlight that code in a unique way. You&#8217;d do this for a block of code that you expressly
+wanted to be highlighted in a different way (see the section below on gettting the stylesheet for your code for an example).</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 the class name will always include the language name used for highlighting.</p>
+
+</div>
+
+<h4 id="getting-stylesheet">3.3.3 Getting the stylesheet for your code</h4><div class="nav"><a href="#setting-css-class-id">Previous</a> | <a href="#using-css-classes">Top</a> | <a href="#using-an-external-stylesheet">Next</a></div>
+
+<p>The other half of using <abbr title="Cascading Style Sheets">CSS</abbr> classes is getting the stylesheet for use with the classes. <abbr title="Generic Syntax Highlighter">GeSHi</abbr> makes it very easy to
+get a stylesheet for your code, with one easy method call:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+</pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// Here we have code that will spit out a header for</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// a stylesheet. For example:</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="st_h">'&lt;html&gt;</span></span></span><span class="st_h">&lt;head&gt;&lt;title&gt;Code&lt;/title&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">&lt;style type=&quot;text/css&quot;&gt;</span></span></span><span class="st_h">&lt;!--'</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// Echo out the stylesheet for this code block</span></span></span><span class="kw1">echo</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">get_stylesheet</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// And continue echoing the page</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="kw1">echo</span> <span class="st_h">'--&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">&lt;/style&gt;&lt;/head&gt;</span></span></span><span class="st_h">&lt;body&gt;'</span><span class="sy0">;</span></pre></td></tr></tbody></table>
+
+<p>The <code class="highlighted php">get_stylesheet<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method gets the stylesheet for your code in one easy call. All you need to do
+is output it in the correct place. As you can also see, you don&#8217;t even have to enable class usage to get the
+stylesheet nessecary either - however not enabling classes but using the stylesheet may result in problems later.</p>
+
+<p>By default, <code class="highlighted php">get_stylesheet<span class="br0">&#40;</span><span class="br0">&#41;</span></code> tries to echo the least amount of code possible. Although currently it doesn&#8217;t
+check to see if a certain lexic is even in the source, you can expect this feature in the future. At least for the
+present however, if you explicitly disable the highlighting of a certain lexic, or disable line numbers, the related
+<abbr title="Cascading Style Sheets">CSS</abbr> will not be outputted. This may be a bad thing for you perhaps you&#8217;re going to use the stylesheet for many blocks
+of code, some with line numbers, others with some lexic enabled where this source has it disabled. Or perhaps you&#8217;re
+building an external stylesheet and want all lexics included. So to get around this problem, you do this:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">get_stylesheet</span><span class="br0">&#40;</span><span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>This turns economy mode off, and all of the stylesheet will be outputted regardless.</p>
+
+<p>Now lets say you have several snippets of code, using the same language. In most of them you don&#8217;t mind if they&#8217;re
+highlighted the same way (in fact, that&#8217;s exactly what you want) but in one of them you&#8217;d like the source to be
+highlighted differently. Here&#8217;s how you can do that:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+<span class="xtra li2"><span class="de2">28</span></span>29
+<span class="xtra li2"><span class="de2">30</span></span>31
+<span class="xtra li2"><span class="de2">32</span></span>33
+<span class="xtra li2"><span class="de2">34</span></span>35
+<span class="xtra li2"><span class="de2">36</span></span>37
+<span class="xtra li2"><span class="de2">38</span></span>39
+<span class="xtra li2"><span class="de2">40</span></span>41
+<span class="xtra li2"><span class="de2">42</span></span>43
+<span class="xtra li2"><span class="de2">44</span></span>45
+<span class="xtra li2"><span class="de2">46</span></span>47
+<span class="xtra li2"><span class="de2">48</span></span></pre></td><td class="de1"><pre class="de1"><span class="co1">// assume path is the default &quot;geshi/&quot; relative to the current directory</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$geshi1</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source1</span><span class="sy0">,</span> <span class="re0">$lang</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi2</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source2</span><span class="sy0">,</span> <span class="re0">$lang</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi3</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source3</span><span class="sy0">,</span> <span class="re0">$lang</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="co1">// Turn classes on for all sources</span></span></span><span class="re0">$geshi1</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$geshi2</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi3</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="co1">// Make $geshi3 unique</span></span></span><span class="re0">$geshi3</span><span class="sy0">-&gt;</span><span class="me1">set_overall_id</span><span class="br0">&#40;</span><span class="st_h">'different'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="co1">//</span></span></span><span class="co1">// Methods are called on $geshi3 to change styles...</span>
+<span class="xtra li2"><span class="de2"><span class="co1">//</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="st_h">'&lt;html&gt;</span></span></span><span class="st_h">&lt;head&gt;&lt;title&gt;Code&lt;/title&gt;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="st_h">&lt;style type=&quot;text/css&quot;&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">&lt;!--</span></span></span><span class="st_h">'</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// Get the nessecary stylesheets</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="re0">$geshi1</span><span class="sy0">-&gt;</span><span class="me1">get_stylesheet</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="re0">$geshi3</span><span class="sy0">-&gt;</span><span class="me1">get_stylesheet</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="st_h">'--&gt;</span></span></span><span class="st_h">&lt;/style&gt;&lt;/head&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">&lt;body&gt;'</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="kw1">echo</span> <span class="st_h">'Code snippet 1:'</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="re0">$geshi1</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span><span class="kw1">echo</span> <span class="st_h">'Code snippet 2 (same highlighting as 1):'</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="kw1">echo</span> <span class="re0">$geshi2</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="st_h">'Code snippet 3 (DIFFERENT highlighting):'</span><span class="sy0">;</span></span></span><span class="kw1">echo</span> <span class="re0">$geshi3</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="st_h">'&lt;/body&gt;&lt;/html&gt;'</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<p>Before version 1.0.2, you needed to set the class of the code you wanted to be unique to the empty string. This
+limitation has been removed in version 1.0.2 - if you set the ID of a block of code, all styling will be done based
+on that ID alone.</p>
+
+<h4 id="using-an-external-stylesheet">3.3.4 Using an External Stylesheet</h4><div class="nav"><a href="#getting-stylesheet">Previous</a> | <a href="#using-css-classes">Top</a> | <a href="#changing-styles">Next</a></div>
+
+<p>An external stylesheet can reduce even more the amount of code needed to highlight some source. However there are some
+drawbacks with this. To use an external stylesheet, it&#8217;s up to you to link it in to your document, normally with
+the following <abbr title="Hypertext Markup Language">HTML</abbr>:</p>
+
+<table class="html4strict geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">HTML code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+</pre></td><td class="de1"><pre class="de1"><span class="sc2">&lt;<a href="http://december.com/html/4/element/html.html"><span class="kw2">html</span></a>&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="sc2">&lt;<a href="http://december.com/html/4/element/head.html"><span class="kw2">head</span></a>&gt;</span></span></span><span class="sc2">&lt;<a href="http://december.com/html/4/element/link.html"><span class="kw2">link</span></a> <span class="kw3">rel</span><span class="sy0">=</span><span class="st0">&quot;stylesheet&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;text/css&quot;</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;url_to_stylesheet.css&quot;</span> <span class="sy0">/</span>&gt;</span></pre></td></tr></tbody></table>
+
+<p>In your external stylesheet you put <abbr title="Cascading Style Sheets">CSS</abbr> declarations for your code. Then just make sure you&#8217;re using the correct class (use
+<code class="highlighted php">set_overall_class<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to ensure this) and this should work fine.</p>
+
+<p>This method is great if you don&#8217;t mind the source always being highlighted the same (in particular, if you&#8217;re making a
+plugin for a forum/wiki/other system, using an external stylesheet is a good idea!). It saves a small amount of code and
+your bandwidth, and it&#8217;s relatively easy to just change the stylesheet should you need to. However, using this will render
+the methods that change the styles of the code useless, because of course the stylesheet is no longer being dynamically
+generated. You can still disable highlighting of certain lexics dynamically, however.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>As of version 1.0.2, <abbr title="Generic Syntax Highlighter">GeSHi</abbr> comes with a <code>contrib/</code> directory, which in it contains a &#8220;wizard&#8221; script for creating
+  a stylesheet. Although this script is by no means a complete solution, it will create the necessary rules for the
+  basic lexics - comments, strings for example. Things not included in the wizard include regular expressions for any
+  language that uses them (<abbr title="PHP: HTML Preprocessor">PHP</abbr> and <abbr title="Extensible Markup Language">XML</abbr> are two languages that use them), and keyword-link styles. However, this script
+  should take some of the tedium out of the job of making an external stylesheet. Expect a much better version of this
+  script in version 1.2!</p>
+
+</div>
+
+<h3 id="changing-styles">3.4 Changing Styles</h3><div class="nav"><a href="#using-an-external-stylesheet">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#the-overall-styles">Next</a></div>
+
+<p>One of the more powerful features of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is the ability to change the style of the output dynamically. Why be chained
+to the boring styles the language authors make up? You can change almost every single aspect of highlighted code - and
+can even say whether something is to be highlighted at all.</p>
+
+<p>If you&#8217;re confused about &#8220;styles&#8221;, you probably want to have a quick tutorial in them so you know what you can do with
+them. Checkout the homepage of <abbr title="Cascading Style Sheets">CSS</abbr> at <a href="http://www.w3.org/Style/CSS">http://www.w3.org/Style/CSS</a>.</p>
+
+<h4 id="the-overall-styles">3.4.1 The Overall Styles</h4><div class="nav"><a href="#changing-styles">Previous</a> | <a href="#changing-styles">Top</a> | <a href="#line-number-styles">Next</a></div>
+
+<p>The code outputted by <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is either in a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> or a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> (see the section entitled &#8220;The
+Code Container&#8221;), and this can be styled.</p>
+
+<p><code>$geshi-&gt;set_overall_style('... styles ...');</code>
+Where styles is a string containing valid <abbr title="Cascading Style Sheets">CSS</abbr> declarations. By default, these styles overwrite the current styles, but you can change this by adding a second parameter:</p>
+
+<p><code>$geshi-&gt;set_overall_style('color: blue;', true);</code>
+The default styles &#8220;shine through&#8221; wherever anything isn&#8217;t highlighted. Also, you can apply more advanced styles, like position: (fixed|relative) etc, because a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>/<code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> is a block level element.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Remember that a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> will by default have a larger font size than a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code>, as discussed in the section <a href="#the-code-container">&#8220;The Code Container&#8221;</a>.</p>
+
+</div>
+
+<h4 id="line-number-styles">3.4.2 Line Number Styles</h4><div class="nav"><a href="#the-overall-styles">Previous</a> | <a href="#changing-styles">Top</a> | <a href="#setting-keyword-styles">Next</a></div>
+
+<p>You may wish to refer to the section [Styling Line Numbers][1] before reading this section.</p>
+
+<p>As of version 1.0.2, the way line numbers are generated is different, so therefore the way that they are styled is
+different. In particular, now you cannot set the background style of the fancy line numbers to be different from that
+of the normal line numbers.</p>
+
+<p>Line number styles are set by using the method <code class="highlighted php">set_line_style</code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="re0">$style1</span><span class="sy0">,</span> <span class="re0">$style2</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p><code class="highlighted php"><span class="re0">$style1</span></code> is the style of the line numbers by default, and <code class="highlighted php"><span class="re0">$style2</span></code> is the style of the fancy line numbers.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>Things have changed since 1.0.1! This note is <strong>very</strong> important - please make sure you check this twice before
+  complaining about line numbers!</p>
+
+<p>Because of the way that ordered lists are done in <abbr title="Hypertext Markup Language">HTML</abbr>, there really isn&#8217;t normally a way to style the actual
+  <em>numbers</em> in the list. I&#8217;ve cheated somewhat with <abbr title="Generic Syntax Highlighter">GeSHi</abbr> - I&#8217;ve made it possible to use <abbr title="Cascading Style Sheets">CSS</abbr> to style the <em>foreground</em> of
+  the line numbers. So therefore, you can change the color, font size and type, and padding on them. If you want to
+  have a pretty background, you <strong>must</strong> use <code class="highlighted php">set_overall_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to do this, and use <code class="highlighted php">set_code_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code>
+  to style the actual code! This is explained in the section above: <a href="#styling-line-numbers">Styling Line Numbers</a>.</p>
+
+<p>In addition, the styles for fancy line numbers <em>is now the difference between the normal styles and the styles you want
+  to achieve</em>. For example, in <abbr title="Generic Syntax Highlighter">GeSHi</abbr> prior to 1.0.2 you may have done this to style line numbers:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="st_h">'color: red; font-weight: bold;'</span><span class="sy0">,</span> <span class="st_h">'color: green; font-weight: bold'</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Now you instead can do this:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_line_style</span><span class="br0">&#40;</span><span class="st_h">'color: red; font-weight: bold;'</span><span class="sy0">,</span> <span class="st_h">'color: green;'</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>The <code class="highlighted css"><span class="kw1">font-weight</span><span class="sy0">:</span> <span class="kw2">bold</span><span class="sy0">;</span></code> will automatically carry through to the fancy styles. This is actually a small
+  saving in code - but the difference may be confusing for anyone using 1.0.1 at first.</p>
+
+</div>
+
+<h4 id="setting-keyword-styles">3.4.3 Setting Keyword Styles</h4><div class="nav"><a href="#line-number-styles">Previous</a> | <a href="#changing-styles">Top</a> | <a href="#setting-comment-styles">Next</a></div>
+
+<p>Perhaps the most regular change you will make will be to the styles of a keyword set. In order to change the styles for
+a particular set, you&#8217;ll have to know what the set is called first. Sets are numbered from 1 up. Typically, set 1
+contains keywords like <code>if</code>, <code>while</code>, <code>do</code>, <code>for</code>, <code>switch</code> etc, set 2 contains <code>null</code>, <code>false</code>, <code>true</code> etc, set 3
+contains function inbuilt into the language (<code>echo</code>, <code>htmlspecialchars</code> etc. in <abbr title="PHP: HTML Preprocessor">PHP</abbr>) and set 4 contains data types and
+similar variable modifiers: <code>int</code>, <code>double</code>, <code>real</code>, <code>static</code> etc. However these things are not fixed, and you should
+check the language file to see what key you want. Having a familiarity with a language file is definately a plus for
+using it.</p>
+
+<p>To change the styles for a keyword set, call the <code class="highlighted php">set_keyword_group_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_keyword_group_style</span><span class="br0">&#40;</span><span class="re0">$group</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$group</span></code> is the group to change the styles for and <code class="highlighted php"><span class="re0">$styles</span></code> is a string containing the styles
+to apply to that group.</p>
+
+<p>By default, the styles you pass overwrite the current styles. Add a boolean <code class="highlighted php"><span class="kw4">true</span></code> after the styles you specify to
+combine them with the current styles:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_keyword_group_style</span><span class="br0">&#40;</span><span class="nu0">3</span><span class="sy0">,</span> <span class="st_h">'color: white;'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<h4 id="setting-comment-styles">3.4.4 Setting Comment Styles</h4><div class="nav"><a href="#setting-keyword-styles">Previous</a> | <a href="#changing-styles">Top</a> | <a href="#setting-other-styles">Next</a></div>
+
+<p>To change the styles for a comment group, call the <code class="highlighted php">set_comments_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_comments_style</span><span class="br0">&#40;</span><span class="re0">$group</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$group</span></code> is either a number corresponding to a single-line comment, or the string <code class="highlighted php"><span class="st_h">'MULTI'</span></code> to
+specify multiline comments:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_comments_style</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="st_h">'font-style: italic;'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_comments_style</span><span class="br0">&#40;</span><span class="st_h">'MULTI'</span><span class="sy0">,</span> <span class="st_h">'display: hidden;'</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<p>By default, the styles you pass overwrite the current styles. Add a boolean <code class="highlighted php"><span class="kw4">true</span></code> after the styles you specify to
+combine them with the current styles:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_comments_style</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="st_h">'font-weight: 100;'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>In 1.0.7.22 a new kind of Comments called &#8220;COMMENT_REGEXP&#8221; has been added. Those are handled by setting single
+  line comment styles.</p>
+
+</div>
+
+<h4 id="setting-other-styles">3.4.5 Setting Other Styles</h4><div class="nav"><a href="#setting-comment-styles">Previous</a> | <a href="#changing-styles">Top</a> | <a href="#case-caps">Next</a></div>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> can highlight many other aspects of your source other than just keywords and comments. Strings, Numbers, Methods
+and Brackets among other things can all also be highlighted. Here are the related methods:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+</pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_escape_characters_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_symbols_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_strings_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_numbers_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_methods_style</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_regexps_style</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></tbody></table>
+
+<p><code class="highlighted php"><span class="re0">$styles</span></code> is a string containing valid stylesheet declarations, while <code class="highlighted php"><span class="re0">$preserve_defaults</span></code> should be set
+to <code class="highlighted php"><span class="kw4">true</span></code> if you want your styles to be merged with the previous styles. In the case of <code class="highlighted php">set_methods_style<span class="br0">&#40;</span><span class="br0">&#41;</span></code>,
+you should select a group to set the styles of, check the language files for the number used for each &#8220;object splitter&#8221;.</p>
+
+<p>Like this was possible for <code class="highlighted php">set_method_style</code> a new parameter has been introduced for
+<code class="highlighted php">set_symbols_style</code> too which allows you to select the group of symbols for which you&#8217;d like to change your
+style. <code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_symbols_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$preserve_defaults</span><span class="br0">&#91;</span><span class="sy0">,</span> <span class="re0">$group</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></code> If the third parameter is not
+given, group 0 is assumed. Furthermore you should note that any changes to group 0 are also reflected in the bracket
+style, i.e. a pass-through call to <code class="highlighted php">set_bracket_style</code> is made.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Since <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 multiple styles for strings and numbers are supported, though the API doesn&#8217;t provide full access yet.</p>
+
+</div>
+
+<h3 id="case-caps">3.5 Case Sensitivity and Auto Casing</h3><div class="nav"><a href="#setting-other-styles">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#auto-caps-nocaps">Next</a></div>
+
+<p>Controlling the case of the outputted source is an easy job with <abbr title="Generic Syntax Highlighter">GeSHi</abbr>. You can control which keywords are converted in
+case, and also control whether keywords are checked in a case sensitive manner.</p>
+
+<h4 id="auto-caps-nocaps">3.5.1 Auto-Caps/NoCaps</h4><div class="nav"><a href="#case-caps">Previous</a> | <a href="#case-caps">Top</a> | <a href="#setting-case-sensitivity">Next</a></div>
+
+<p>Auto-Caps/NoCaps is a nifty little feature that capitalises or lowercases automatically certain lexics when they are
+styled. I dabble in QuickBASIC, a dialect of BASIC which is well known for it&#8217;s capatalisation, and SQL is another
+language well known for using caps for readability.</p>
+
+<p>To change what case lexics are rendered in, you call the <code class="highlighted php">set_case_keywords<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_case_keywords</span><span class="br0">&#40;</span><span class="re0">$caps_modifier</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>The valid values to pass to this method are:</p>
+
+<ul>
+<li><code>GESHI_CAPS_NO_CHANGE</code> - Don&#8217;t change the case of any lexics, leave as they are found</li>
+<li><code>GESHI_CAPS_UPPER</code> - Uppercase all lexics found</li>
+<li><code>GESHI_CAPS_LOWER</code> - Lowercase all lexics found</li>
+</ul>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>When I say &#8220;lexic&#8221;, I mean &#8220;keywords&#8221;. <strong>Any</strong> keyword in <strong>any</strong> keyword array will be modified using this option!
+  This is one small area of inflexibility I hope to fix in 1.2.X.</p>
+
+</div>
+
+<p>I suspect this will only be used to specify <code>GESHI_CAPS_NO_CHANGE</code> to turn off autocaps for languages like SQL
+and BASIC variants, like so:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'sql'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_case_keywords</span><span class="br0">&#40;</span>GESHI_CAPS_NO_CHANGE<span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// don't want keywords capatalised</span></span></span></pre></td></tr></tbody></table>
+
+<p>All the same, it can be used for some interesting effects:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'java'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// Anyone who's used java knows how picky it is about CapitalLetters...</span></span></span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_case_keywords</span><span class="br0">&#40;</span>GESHI_CAPS_LOWER<span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// No *way* the source will look right now ;)</span></span></span></pre></td></tr></tbody></table>
+
+<h4 id="setting-case-sensitivity">3.5.2 Setting Case Sensitivity</h4><div class="nav"><a href="#auto-caps-nocaps">Previous</a> | <a href="#case-caps">Top</a> | <a href="#changing-config">Next</a></div>
+
+<p>Some languages, like <abbr title="PHP: HTML Preprocessor">PHP</abbr>, don&#8217;t mind what case function names and keywords are in, while others, like Java, depend on
+such pickiness to maintain their bad reputations ;). In any event, you can use the <code class="highlighted php">set_case_sensitivity<span class="br0">&#40;</span><span class="br0">&#41;</span></code>
+to change the case sensitiveness of a particular keyword group from the default:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_case_sensitivity</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$sensitivity</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$key</span></code> is the key of the group for which you wish to change case sensitivness for (see the language file
+for that language), and <code class="highlighted php"><span class="re0">$sensitivity</span></code> is a boolean value - <code class="highlighted php"><span class="kw4">true</span></code> if the keyword is case sensitive, and
+<code class="highlighted php"><span class="kw4">false</span></code> if not.</p>
+
+<h3 id="changing-config">3.6 Changing the Source, Language, Config Options</h3><div class="nav"><a href="#setting-case-sensitivity">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#changing-the-source">Next</a></div>
+
+<p>What happens if you want to change the source to be highlighted on the fly, or the language. Or if you want to specify
+any of those basic fields after you&#8217;ve created a <abbr title="Generic Syntax Highlighter">GeSHi</abbr> object? Well, that&#8217;s where these methods come in.</p>
+
+<h4 id="changing-the-source">3.6.1 Changing the Source Code</h4><div class="nav"><a href="#changing-config">Previous</a> | <a href="#changing-config">Top</a> | <a href="#changing-the-language">Next</a></div>
+
+<p>To change the source code, you call the <code class="highlighted php">set_source<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_source</span><span class="br0">&#40;</span><span class="re0">$newsource</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source1</span><span class="sy0">,</span> <span class="st_h">'php'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// Method calls to specify various options...</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$code1</span> <span class="sy0">=</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_source</span><span class="br0">&#40;</span><span class="re0">$source2</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$code2</span> <span class="sy0">=</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<h4 id="changing-the-language">3.6.2 Changing the Language</h4><div class="nav"><a href="#changing-the-source">Previous</a> | <a href="#changing-config">Top</a> | <a href="#changing-the-path">Next</a></div>
+
+<p>What happens if you want to change the language used for highlighting? Just call <code class="highlighted php">set_language<span class="br0">&#40;</span><span class="br0">&#41;</span></code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_language</span><span class="br0">&#40;</span><span class="st_h">'newlanguage'</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span></pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'php'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$code</span> <span class="sy0">=</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="co1">// Highlight GeSHi's output</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_source</span><span class="br0">&#40;</span><span class="re0">$code</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_language</span><span class="br0">&#40;</span><span class="st_h">'html4strict'</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_classes</span><span class="br0">&#40;</span><span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="kw1">echo</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.5, you can use the method <code class="highlighted php">load_from_file<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to load the source code and language from a file.
+Simply pass this method a file name and it will attempt to load the source and set the language.</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">load_from_file</span><span class="br0">&#40;</span><span class="re0">$file_name</span><span class="sy0">,</span> <span class="re0">$lookup</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p><code class="highlighted php"><span class="re0">$file_name</span></code> is the file name to use, and <code class="highlighted php"><span class="re0">$lookup</span></code> is an optional parameter that contains a lookup
+array to use for deciding which language to choose. You can use this to override <abbr title="Generic Syntax Highlighter">GeSHi</abbr>&#8217;s default lookup array, which
+may not contain the extension of the file you&#8217;re after, or perhaps does have your extension but under a different
+language. The lookup array is of the form:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span></pre></td><td class="de1"><pre class="de1"><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp;<span class="st_h">'lang_name'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'extension'</span><span class="sy0">,</span> <span class="st_h">'extension'</span><span class="sy0">,</span> <span class="sy0">...</span><span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp;<span class="st_h">'lang_name'</span> <span class="sy0">...</span>
+<span class="xtra li2"><span class="de2"><span class="br0">&#41;</span><span class="sy0">;</span></span></span></pre></td></tr></tbody></table>
+
+<p>Also, you can use the method <code class="highlighted php">get_language_name_from_extension<span class="br0">&#40;</span><span class="br0">&#41;</span></code> if you need to convert a file extension
+to a valid language name. This method will return the empty string if it could not find a match in the lookup, and
+like <code class="highlighted php">load_from_file</code> it accepts an optional second parameter that contains a lookup array.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Names are case-insensitive - they will be converted to lower case to match a language file however. So if you&#8217;re
+  making a language file, remember it should have a name in lower case.</p>
+
+</div>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>What you pass to this method is the name of a language file, minus the .php extension. If you&#8217;re writing a plugin
+  for a particular application, it&#8217;s up to you to somehow convert user input into a valid language name.</p>
+
+</div>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Since <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 this function does not reset language settings for an already loaded language. If you want
+  to highlight code in the same language with different settings add the optional
+  <code class="highlighted php"><span class="re0">$force_reset</span> parameter</code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_language</span><span class="br0">&#40;</span><span class="st_h">'language'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+</div>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> <code class="highlighted php"><span class="kw1">include</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code>s the language file, so be careful to make sure that users can&#8217;t pass some wierd
+  language name to include any old script! <abbr title="Generic Syntax Highlighter">GeSHi</abbr> tries to strip non-valid characters out of a language name, but
+  you should always do this your self anyway. In particular, language files are always lower-case, with either
+  alphanumeric characters, dashes or underscores in their name.</p>
+
+<p>At the very least, strip &#8220;/&#8221; characters out of a language name.</p>
+
+</div>
+
+<h4 id="changing-the-path">3.6.3 Changing the Language Path</h4><div class="nav"><a href="#changing-the-language">Previous</a> | <a href="#changing-config">Top</a> | <a href="#changing-the-charset">Next</a></div>
+
+<p>What happens if all of a sudden you want to use language files from a different directory from the current
+language file location? You call the <code class="highlighted php">set_language_path<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_language_path</span><span class="br0">&#40;</span><span class="re0">$newpath</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>It doesn&#8217;t matter whether the path has a trailing slash after it or not - only that it points to a valid folder.
+If it doesn&#8217;t, that&#8217;s your tough luck ;)</p>
+
+<h4 id="changing-the-charset">3.6.4 Changing the Character Set</h4><div class="nav"><a href="#changing-the-path">Previous</a> | <a href="#changing-config">Top</a> | <a href="#error-handling">Next</a></div>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Although <abbr title="Generic Syntax Highlighter">GeSHi</abbr> itself does not require to know the exact charset of your source you
+  will need to set this option when processing sources where multi-byte characters can occur.
+  As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.7.18 internally a rewrite of <code class="highlighted php"><span class="kw3">htmlspecialchars</span></code> is used
+  due to a security flaw in that function that is unpatched in even the most recent PHP4 versions and in PHP5 &lt; 5.2.
+  Although this does no longer explicitely require the charset it is required again
+  as of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 to properly handle multi-byte characters (e.g. after an escape char).</p>
+
+</div>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 the default charset has been changed to UTF-8.</p>
+
+</div>
+
+<p>As of version 1.0.3, you can use the method <code class="highlighted php">set_encoding<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to specify the character set that your source
+is in. Valid names are those names that are valid for the <abbr title="PHP: HTML Preprocessor">PHP</abbr> mbstring library:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_encoding</span><span class="br0">&#40;</span><span class="re0">$encoding</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>There is a table of valid strings for <code class="highlighted php"><span class="re0">$encoding</span></code> at the php.net manual linked to above. If you do not
+specify an encoding, or specify an invalid encoding, the character set used is ISO-8859-1.</p>
+
+<h3 id="error-handling">3.7 Error Handling</h3><div class="nav"><a href="#changing-the-charset">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#disabling-lexics">Next</a></div>
+
+<p>What happens if you try to highlight using a language that doesn&#8217;t exist? Or if <abbr title="Generic Syntax Highlighter">GeSHi</abbr> can&#8217;t read a required file?
+The results you get may be confusing. You may check your code over and over, and never find anything wrong. <abbr title="Generic Syntax Highlighter">GeSHi</abbr>
+provides ways of finding out if <abbr title="Generic Syntax Highlighter">GeSHi</abbr> itself found anything wrong with what you tried to do. After highlighting,
+you can call the <code class="highlighted php">error<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="st_h">'hi'</span><span class="sy0">,</span> <span class="st_h">'thisLangIsNotSupported'</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p><code class="highlighted php"><span class="kw1">echo</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">error</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// echoes error message</span></code></p>
+
+<p>The error message you will get will look like this:</p>
+
+<blockquote>
+  <p><abbr title="Generic Syntax Highlighter">GeSHi</abbr> Error: <abbr title="Generic Syntax Highlighter">GeSHi</abbr> could not find the language thisLangIsNotSupported (using path geshi/) (code 2)</p>
+</blockquote>
+
+<p>The error outputted will be the last error <abbr title="Generic Syntax Highlighter">GeSHi</abbr> came across, just like how <code class="highlighted php"><span class="kw3">mysql_error</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code> works.</p>
+
+<h3 id="disabling-lexics">3.8 Disabling styling of some Lexics</h3><div class="nav"><a href="#error-handling">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#setting-tab-width">Next</a></div>
+
+<p>One disadvantage of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> is that for large source files using complex languages, it can be quite slow with
+every option turned on. Although future releases will concentrate on the speed/resource side of highlighting,
+you can gain speed by disabling some of the highlighting options. This is done by using a
+series of <code class="highlighted php">set_<span class="sy0">*</span>_highlighting</code> methods:</p>
+
+<dl>
+<dt><code class="highlighted php">set_keyword_group_highlighting<span class="br0">&#40;</span><span class="re0">$group</span><span class="sy0">,</span> <span class="re0">$flag</span><span class="br0">&#41;</span><span class="sy0">:</span></code></dt>
+<dd>Sets whether a particular <code class="highlighted php"><span class="re0">$group</span></code> of keywords is to be highlighted or not. Consult the necessary
+language file(s) to see what <code class="highlighted php"><span class="re0">$group</span></code> should be for each group (typically a positive integer).
+<code class="highlighted php"><span class="re0">$flag</span></code> is <code class="highlighted php"><span class="kw4">false</span></code> if you want to disable highlighting of this group, and <code class="highlighted php"><span class="kw4">true</span></code> if you want
+to re-enable higlighting of this group. If you disable a keyword group then even if the keyword group has a
+related URL one will not be generated for that keyword.</dd>
+
+<dt><code class="highlighted php">set_comments_highlighting<span class="br0">&#40;</span><span class="re0">$group</span><span class="sy0">,</span> <span class="re0">$flag</span><span class="br0">&#41;</span><span class="sy0">:</span></code></dt>
+<dd>Sets whether a particular <code class="highlighted php"><span class="re0">$group</span></code> of comments is to be highlighted or not. Consult the necessary
+language file(s) to see what <code class="highlighted php"><span class="re0">$group</span></code> should be for each group (typically a positive integer, or th
+string <code class="highlighted php"><span class="st_h">'MULTI'</span></code> for multiline comments. <code class="highlighted php"><span class="re0">$flag</span></code> is <code class="highlighted php"><span class="kw4">false</span></code> if you want to disable
+highlighting of this group, and <code class="highlighted php"><span class="kw4">true</span></code> if you want to re-enable highlighting of this group.</dd>
+
+<dt><code class="highlighted php">set_regexps_highlighting<span class="br0">&#40;</span><span class="re0">$regexp</span><span class="sy0">,</span> <span class="re0">$flag</span><span class="br0">&#41;</span><span class="sy0">:</span></code></dt>
+<dd>Sets whether a particular <code class="highlighted php"><span class="re0">$regexp</span></code> is to be highlighted or not. Consult the necessary language file(s)
+to see what <code class="highlighted php"><span class="re0">$regexp</span></code> should be for each regexp (typically a positive integer, or the string <code class="highlighted php"><span class="st_h">'MULTI'</span></code>
+for multiline comments. <code class="highlighted php"><span class="re0">$flag</span></code> is <code class="highlighted php"><span class="kw4">false</span></code> if you want to disable highlighting of this group,
+and <code class="highlighted php"><span class="kw4">true</span></code> if you want to re-enable highlighting of this group.</dd>
+</dl>
+
+<p>The following methods:</p>
+
+<ul>
+<li><code class="highlighted php">set_escape_characters_highlighting<span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span></code></li>
+<li><code class="highlighted php">set_symbols_highlighting<span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span></code></li>
+<li><code class="highlighted php">set_strings_highlighting<span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span></code></li>
+<li><code class="highlighted php">set_numbers_highlighting<span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span></code></li>
+<li><code class="highlighted php">set_methods_highlighting<span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span></code></li>
+</ul>
+
+<p>Work on their respective lexics (e.g. <code class="highlighted php">set_methods_highlighting<span class="br0">&#40;</span><span class="br0">&#41;</span></code> will disable/enable highlighting of methods).
+For each method, if <code class="highlighted php"><span class="re0">$flag</span></code> is <code class="highlighted php"><span class="kw4">false</span></code> then the related lexics will not be highlighted at all (this
+means no <abbr title="Hypertext Markup Language">HTML</abbr> will surround the lexic like usual, saving on time and bandwidth.</p>
+
+<p>In case all highlighting should be disabled or reenabled <abbr title="Generic Syntax Highlighter">GeSHi</abbr> provides two methods called <code class="highlighted php">disable_highlighting<span class="br0">&#40;</span><span class="br0">&#41;</span></code>
+and <code class="highlighted php">enable_highlighting<span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span></code>. The optional paramter <code class="highlighted php"><span class="re0">$flag</span></code> has been added in 1.0.7.21 and specifies
+the desired state, i.e. <code class="highlighted php"><span class="kw4">true</span></code> (default) to turn all highlighting on, or <code class="highlighted php"><span class="kw4">false</span></code> to turn all
+highlighting off. Since 1.0.7.21 the method <code class="highlighted php">disnable_highlighting<span class="br0">&#40;</span><span class="br0">&#41;</span></code> has become deprecated.</p>
+
+<h3 id="setting-tab-width">3.9 Setting the Tab Width</h3><div class="nav"><a href="#disabling-lexics">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#using-strict-mode">Next</a></div>
+
+<p>If you&#8217;re using the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">pre</span>&gt;</span></code> header, tabs are handled automatically by your browser, and in general you can
+count on good results. However, if you&#8217;re using the <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code> header, you may want to specify a tab
+width explicitly.</p>
+
+<p>Note that tabs created in this fashion won&#8217;t be like normal tabs - there won&#8217;t be &#8220;tab-stops&#8221; as such, instead
+tabs will be replaced with the specified number of spaces - just like most editors do.</p>
+
+<p>To change the tab width, you call the <code class="highlighted php">set_tab_width<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_tab_width</span><span class="br0">&#40;</span><span class="re0">$width</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$width</span></code> is the width in spaces that you&#8217;d like tabs to be.</p>
+
+<h3 id="using-strict-mode">3.10 Using Strict Mode</h3><div class="nav"><a href="#setting-tab-width">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#adding-removing-keywords">Next</a></div>
+
+<p>Some languages like to get tricky, and jump in and out of the file that they&#8217;re in. For example, the vast
+majority of you reading this will have used a <abbr title="PHP: HTML Preprocessor">PHP</abbr> file. And you know that <abbr title="PHP: HTML Preprocessor">PHP</abbr> code is only executed if it&#8217;s
+within delimiters like <code class="highlighted php"><span class="kw2">&lt;?php</span></code> and <code class="highlighted php"><span class="sy1">?&gt;</span></code> (there are others of course&#8230;). So what happens if you do the
+following in a php file?</p>
+
+<p><code class="highlighted php">&lt;img src=&quot;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="kw3">rand</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">100</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>&quot; /&gt;</code></p>
+
+<p>When using <abbr title="Generic Syntax Highlighter">GeSHi</abbr> without strict mode, or using a bad highlighter, you&#8217;ll end up with scrambled crap,
+especially if you&#8217;re being slack about where you&#8217;re putting your quotes, you could end up with the rest
+of your file as bright blue. Fortunately, you can tell <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to be &#8220;strict&#8221; about just when it highlights
+and when it does not, using the <code class="highlighted php">enable_strict_mode<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_strict_mode</span><span class="br0">&#40;</span><span class="re0">$mode</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$mode</span></code> is <code class="highlighted php"><span class="kw4">true</span></code> or not specified to enable strict mode, or <code class="highlighted php"><span class="kw4">false</span></code> to disable
+strict mode if you&#8217;ve already turned it and don&#8217;t want it now.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 there is a new way to tell <abbr title="Generic Syntax Highlighter">GeSHi</abbr> when to use Strict Mode
+  which is somewhat more intelligent than in previous releases. <abbr title="Generic Syntax Highlighter">GeSHi</abbr> now also
+  allows <code class="highlighted php">GESHI_MAYBE</code>, <code class="highlighted php">GESHI_NEVER</code> and <code class="highlighted php">GESHI_ALWAYS</code> instead of <code class="highlighted php"><span class="kw4">true</span></code> and <code class="highlighted php"><span class="kw4">false</span></code>.
+  Basically <code class="highlighted php">GESHI_ALWAYS</code> (<code class="highlighted php"><span class="kw4">true</span></code>) always enables strict mode,
+  whereas <code class="highlighted php">GESHI_NEVER</code> (<code class="highlighted php"><span class="kw4">false</span></code>) completely disables strict mode. The new thing is
+  <code class="highlighted php">GESHI_MAYBE</code> which enables strict mode if it finds any sequences of code
+  that look like strict block delimiters.</p>
+
+<p>By the way: That&#8217;s why this section had to be changed, as the new documentation
+  tool we now use, applies this feature and thus auto-detects when strict mode has to be used&#8230;</p>
+
+</div>
+
+<h3 id="adding-removing-keywords">3.11 Adding/Removing Keywords</h3><div class="nav"><a href="#using-strict-mode">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#adding-a-keyword">Next</a></div>
+
+<p>Lets say that you&#8217;re working on a large project, with many files, many classes and many functions. Perhaps also you
+have the source code on the web and highlighted by <abbr title="Generic Syntax Highlighter">GeSHi</abbr>, perhaps as a front end to CVS, as a learning tool, something
+to refer to, whatever. Well, why not highlight the names of the functions and classes <em>your</em> project uses, as well
+as the standard functions and classes? Or perhaps you&#8217;re not interested in highlighting certain functions, and would
+like to remove them? Or maybe you don&#8217;t mind if an entire function group goes west in the interest of speed? <abbr title="Generic Syntax Highlighter">GeSHi</abbr>
+can handle all of this!</p>
+
+<h4 id="adding-a-keyword">3.11.1 Adding a Keyword</h4><div class="nav"><a href="#adding-removing-keywords">Previous</a> | <a href="#adding-removing-keywords">Top</a> | <a href="#removing-a-keyword">Next</a></div>
+
+<p>If you want to add a keyword to an existing keyword group, you use the <code class="highlighted php">add_keyword</code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">add_keyword</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$word</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$key</span></code> is the index of the group of keywords you want to add this keyword to, and <code class="highlighted php"><span class="re0">$word</span></code> is
+the word to add.</p>
+
+<p>This implies knowledge of the language file to know the correct index.</p>
+
+<h4 id="removing-a-keyword">3.11.2 Removing a Keyword</h4><div class="nav"><a href="#adding-a-keyword">Previous</a> | <a href="#adding-removing-keywords">Top</a> | <a href="#adding-a-keyword-group">Next</a></div>
+
+<p>Perhaps you want to remove a keyword from an existing group. Maybe you don&#8217;t use it and want to save yourself some time. Whatever the reason, you can remove it using the <code class="highlighted php">remove_keyword</code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">remove_keyword</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$word</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$key</span></code> is the index of the group of keywords that you want to remove this keyword from, and
+<code class="highlighted php"><span class="re0">$word</span></code> is the word to remove.</p>
+
+<p>This implies knowledge of the language file to know the correct index - most of the time the keywords you&#8217;ll
+want to remove will be in group 3, but this is not guaranteed and you should check the language file first.</p>
+
+<p>This function is silent - if the keyword is not in the group you specified, nothing awful will happen ;)</p>
+
+<h4 id="adding-a-keyword-group">3.11.3 Adding a Keyword Group</h4><div class="nav"><a href="#removing-a-keyword">Previous</a> | <a href="#adding-removing-keywords">Top</a> | <a href="#removing-a-keyword-group">Next</a></div>
+
+<p>Lets say for your big project you have several main functions and classes that you&#8217;d like highlighted. Why not
+add them as their own group instead of having them highlighted the same way as other keywords? Then you can make
+them stand out, and people can instantly see which functions and classes are user defined or inbuilt. Furthermore,
+you could set the URL for this group to point at the API documentation of your project.</p>
+
+<p>You add a keyword group by using the <code class="highlighted php">add_keyword_group</code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">add_keyword_group</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="sy0">,</span> <span class="re0">$case_sensitive</span><span class="sy0">,</span> <span class="re0">$words</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$key</span></code> is the key that you want to use to refer to this group, <code class="highlighted php"><span class="re0">$styles</span></code> is the styles that
+you want to use to style this group, <code class="highlighted php"><span class="re0">$case_sensitive</span></code> is <strong>true</strong> or <strong>false</strong> depending on whether you want
+this group of keywords to be case sensitive or not and <code class="highlighted php"><span class="re0">$words</span></code> is an array of words (or a string) of which
+words to add to this group. For example:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">add_keyword_group</span><span class="br0">&#40;</span><span class="nu0">10</span><span class="sy0">,</span> <span class="st_h">'color: #600000;'</span><span class="sy0">,</span> <span class="kw4">false</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'myfunc_1'</span><span class="sy0">,</span> <span class="st_h">'myfunc_2'</span><span class="sy0">,</span> <span class="st_h">'myfunc_3'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Adds a keyword group referenced by index 10, of which all keywords in the group will be dark red, each keyword
+can be in any case and which contains the keywords &#8220;myfunc_1&#8221;, &#8220;myfunc_2&#8221; and &#8220;myfunc_3&#8221;.</p>
+
+<p>After creating such a keyword group, you may call other <abbr title="Generic Syntax Highlighter">GeSHi</abbr> methods on it, just as you would for any other keyword group.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>If you specify a <code class="highlighted php"><span class="re0">$key</span></code> for which there is already a keyword group, the old keyword group will be
+  overwritten! Most language files don&#8217;t use numbers larger than 5, so I recommend you play it safe and use a number
+  like 10 or 42.</p>
+
+</div>
+
+<h4 id="removing-a-keyword-group">3.11.4 Removing a Keyword Group</h4><div class="nav"><a href="#adding-a-keyword-group">Previous</a> | <a href="#adding-removing-keywords">Top</a> | <a href="#headers-and-footers">Next</a></div>
+
+<p>Perhaps you <em>really</em> need speed? Why not just remove an entire keyword group? <abbr title="Generic Syntax Highlighter">GeSHi</abbr> won&#8217;t have to loop through
+each keyword checking for its existance, saving much time. You remove a keyword group by using the
+<code class="highlighted php">remove_keyword_group</code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">remove_keyword_group</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$key</span></code> is the key of the group you wish to remove. This implies knowleged of the language file.</p>
+
+<h3 id="headers-and-footers">3.12 Headers and Footers for Your Code</h3><div class="nav"><a href="#removing-a-keyword-group">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#keyword-substitution">Next</a></div>
+
+<p>So you want to add some special information to the highlighted source? <abbr title="Generic Syntax Highlighter">GeSHi</abbr> can do that too! You can specify headers
+and footers for your code, style them, and insert information from the highlighted source into your header or footer.</p>
+
+<h4 id="keyword-substitution">3.12.1 Keyword Substitution</h4><div class="nav"><a href="#headers-and-footers">Previous</a> | <a href="#headers-and-footers">Top</a> | <a href="#setting-header-content">Next</a></div>
+
+<p>In your header and footer, you can put special keywords that will be replaced with actual configuration values for
+this <abbr title="Generic Syntax Highlighter">GeSHi</abbr> object. The keywords you can use are:</p>
+
+<ul>
+<li><strong><code>&lt;TIME&gt;</code></strong> or <strong><code>{TIME}</code></strong>: Is replaced by the time it took for the <code class="highlighted php">parse_code<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method - i.e.,
+how long it took for your code to be highlighted. The time is returned to three decimal places.</li>
+<li><strong><code>&lt;LANGUAGE&gt;</code></strong> or <strong><code>{LANGUAGE}</code></strong>: Is replaced by a nice, friendly version of the language name used to
+highlight this code.</li>
+<li><strong><code>&lt;SPEED&gt;</code></strong> or <strong><code>{SPEED}</code></strong>: Is replaced by the speed at which your source has been processed.</li>
+<li><strong><code>&lt;VERSION&gt;</code></strong> or <strong><code>{VERSION}</code></strong>: The <abbr title="Generic Syntax Highlighter">GeSHi</abbr> version used to highlight the code.</li>
+</ul>
+
+<h4 id="setting-header-content">3.12.2 Setting Header Content</h4><div class="nav"><a href="#keyword-substitution">Previous</a> | <a href="#headers-and-footers">Top</a> | <a href="#setting-footer-content">Next</a></div>
+
+<p>The header for your code is a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>, which is inside the containing block. Therefore, it is affected by
+the method <code class="highlighted php">set_overall_style</code>, and should contain the sort of <abbr title="Hypertext Markup Language">HTML</abbr> that belongs in a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>.
+You may use any <abbr title="Hypertext Markup Language">HTML</abbr> you like, and format it as an <abbr title="Hypertext Markup Language">HTML</abbr> document. You should use valid <abbr title="Hypertext Markup Language">HTML</abbr> - convert to entities
+any quotemarks or angle brackets you want displayed. You set the header content using the method
+<code class="highlighted php">set_header_content<span class="br0">&#40;</span><span class="br0">&#41;</span></code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_content</span><span class="br0">&#40;</span><span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$content</span></code> is the <abbr title="Hypertext Markup Language">HTML</abbr> you want to use for the header.</p>
+
+<h4 id="setting-footer-content">3.12.3 Setting Footer Content</h4><div class="nav"><a href="#setting-header-content">Previous</a> | <a href="#headers-and-footers">Top</a> | <a href="#styling-header-content">Next</a></div>
+
+<p>The footer for your code is a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>, which is inside the containing block. Therefore, it is affected by
+the method <code class="highlighted php">set_overall_style</code>, and should contain the sort of <abbr title="Hypertext Markup Language">HTML</abbr> that belongs in a <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">div</span>&gt;</span></code>.
+You may use any <abbr title="Hypertext Markup Language">HTML</abbr> you like, and format it as an <abbr title="Hypertext Markup Language">HTML</abbr> document. You should use valid <abbr title="Hypertext Markup Language">HTML</abbr> - convert to entities
+any quotemarks or angle brackets you want displayed. You set the footer content using the method
+<code class="highlighted php">set_footer_content<span class="br0">&#40;</span><span class="br0">&#41;</span></code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_footer_content</span><span class="br0">&#40;</span><span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$content</span></code> is the <abbr title="Hypertext Markup Language">HTML</abbr> you want to use for the footer.</p>
+
+<h4 id="styling-header-content">3.12.4 Styling Header Content</h4><div class="nav"><a href="#setting-footer-content">Previous</a> | <a href="#headers-and-footers">Top</a> | <a href="#styling-footer-content">Next</a></div>
+
+<p>You can apply styles to the header content you have set with the <code class="highlighted php">set_header_content_style</code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_header_content_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$styles</span></code> is the stylesheet declarations you want to use to style the header content.</p>
+
+<h4 id="styling-footer-content">3.12.5 Styling Footer Content</h4><div class="nav"><a href="#styling-header-content">Previous</a> | <a href="#headers-and-footers">Top</a> | <a href="#keyword-urls">Next</a></div>
+
+<p>You can apply styles to the footer content you have set with the <code class="highlighted php">set_footer_content_style</code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_footer_content_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$styles</span></code> is the stylesheet declarations you want to use to style the footer content.</p>
+
+<h3 id="keyword-urls">3.13 Keyword URLs</h3><div class="nav"><a href="#styling-footer-content">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#setting-a-url">Next</a></div>
+
+<p>As of version 1.0.2, <abbr title="Generic Syntax Highlighter">GeSHi</abbr> allows you to specify a URL for keyword groups. This URL is used by <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to convert
+the keywords in that group into URLs to appropriate documentation. And using <code class="highlighted php">add_keyword_group</code> you
+can add functions and classes from your own projects and use the URL functionality to provide a link to your
+own API documentation.</p>
+
+<h4 id="setting-a-url">3.13.1 Setting a URL for a Keyword Group</h4><div class="nav"><a href="#keyword-urls">Previous</a> | <a href="#keyword-urls">Top</a> | <a href="#disabling-urls">Next</a></div>
+
+<p>To set the URL to be used for a keyword group, you use the <code class="highlighted php">set_url_for_keyword_group<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_url_for_keyword_group</span><span class="br0">&#40;</span><span class="re0">$group</span><span class="sy0">,</span> <span class="re0">$url</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$group</span></code> is the keyword group you want to assign the URL for, and <code class="highlighted php"><span class="re0">$url</span></code> is the URL for
+this group of keywords.</p>
+
+<p>You may be wondering how to make each keyword in the group point to the correct URL. You do this by putting
+<code>{FNAME}</code> in the URL at the correct place. For example, <abbr title="PHP: HTML Preprocessor">PHP</abbr> makes it easy by linking <code>www.php.net/function-name</code>
+to the documentation for that function, so the URL used is <code>http://www.php.net/{FNAME}</code>.</p>
+
+<p>Of course, when you get to a language like Java, that puts its class documentation in related folders, it gets a
+little trickier to work out an appropriate URL (see the Java language file!). I hope to provide some kind of
+redirection service at the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> website in the future.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>As of Version 1.0.7.21 there have been added two more symbols you can use to link to functions. <code>{FNAMEL}</code>
+  will generate the lowercase version of the keyword, <code>{FNAMEU}</code> will generate the uppercase version. <code>{FNAME}</code>
+  will provide the keyword as specified in the language file. <strong>Use one of these more specific placeholders
+  if possible</strong>, as they result in less overhead while linking for case insensitive languages.</p>
+
+</div>
+
+<h4 id="disabling-urls">3.13.2 Disabling a URL for a Keyword Group</h4><div class="nav"><a href="#setting-a-url">Previous</a> | <a href="#keyword-urls">Top</a> | <a href="#disabling-all-urls">Next</a></div>
+
+<p>It&#8217;s easy to disable a URL for a keyword group: Simply use the method <code class="highlighted php">set_url_for_keyword_group<span class="br0">&#40;</span><span class="br0">&#41;</span></code> to pass
+an empty string as the URL:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_url_for_keyword_group</span><span class="br0">&#40;</span><span class="re0">$group</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<h4 id="disabling-all-urls">3.13.3 Disabling all URLs for Keywords</h4><div class="nav"><a href="#disabling-urls">Previous</a> | <a href="#keyword-urls">Top</a> | <a href="#styling-links">Next</a></div>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.7.18, you can disable all URL linking for keywords:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_keyword_links</span><span class="br0">&#40;</span><span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<h4 id="styling-links">3.13.4 Styling Links</h4><div class="nav"><a href="#disabling-all-urls">Previous</a> | <a href="#keyword-urls">Top</a> | <a href="#using-targets">Next</a></div>
+
+<p>You can also style the function links. You can style their default status, hovered, active and visited status.
+All of this is controlled by one method, <code class="highlighted php">set_link_styles<span class="br0">&#40;</span><span class="br0">&#41;</span></code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_link_styles</span><span class="br0">&#40;</span><span class="re0">$mode</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$mode</span></code> is one of four values:</p>
+
+<ul>
+<li><strong><code class="highlighted php">GESHI_LINK</code>:</strong> The default style of the links.</li>
+<li><strong><code class="highlighted php">GESHI_HOVER</code>:</strong> The style of the links when they have focus (the mouse is hovering over them).</li>
+<li><strong><code class="highlighted php">GESHI_ACTIVE</code>:</strong> The style of the links when they are being clicked.</li>
+<li><strong><code class="highlighted php">GESHI_VISITED</code>:</strong> The style of links that the user has already visited.</li>
+</ul>
+
+<p>And <code class="highlighted php"><span class="re0">$styles</span></code> is the stylesheet declarations to apply to the links.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>The names <code class="highlighted php">GESHI_LINK</code>, <code class="highlighted php">GESHI_HOVER</code> &#8230; are constants. Don&#8217;t put them in quotes!</p>
+
+</div>
+
+<h4 id="using-targets">3.13.5 Setting the Link Target</h4><div class="nav"><a href="#styling-links">Previous</a> | <a href="#keyword-urls">Top</a> | <a href="#using-contextual-importance">Next</a></div>
+
+<p>Perhaps you want to set the target of link attributes, so the manual pages open in a new window? Use the
+<code class="highlighted php">set_link_target<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_link_target</span><span class="br0">&#40;</span><span class="re0">$target</span><span class="sy0">,</span> <span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$target</span></code> is any valid (X)<abbr title="Hypertext Markup Language">HTML</abbr> target value - <code>_blank</code> or <code>_top</code> for example.</p>
+
+<h3 id="using-contextual-importance">3.14 Using Contextual Importance</h3><div class="nav"><a href="#using-targets">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#highlighting-special-lines-extra">Next</a></div>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>This functionality is not only buggy, but is proving very hard to implement in 1.1.X. Therefore, this
+  functionality may well be <strong>removed</strong> in 1.2.0. You are hereby warned!</p>
+
+</div>
+
+<p>This feature allows you to mark a part of your source as important. But as the
+implementation its use is deprecated and you should consider using
+the &#8220;Highlight Lines Extra&#8221; feature described below.</p>
+
+<h3 id="highlighting-special-lines-extra">3.15 Highlighting Special Lines &#8220;Extra&#8221;</h3><div class="nav"><a href="#using-contextual-importance">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#specifying-lines-to-highlight-extra">Next</a></div>
+
+<p>An alternative (and more stable) method of highlighting code that is important
+is to use extra highlighting by line. Although you may not know what line numbers
+contain the important lines, if you do this method is a much more flexible way of
+making important lines stand out.</p>
+
+<h4 id="specifying-lines-to-highlight-extra">3.15.1 Specifying the Lines to Highlight Extra</h4><div class="nav"><a href="#highlighting-special-lines-extra">Previous</a> | <a href="#highlighting-special-lines-extra">Top</a> | <a href="#styles-for-highlighted-lines">Next</a></div>
+
+<p>To specify which lines to highlight extra, you pass an array containing the line numbers to <code class="highlighted php">highlight_lines_extra<span class="br0">&#40;</span><span class="br0">&#41;</span></code>:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">highlight_lines_extra</span><span class="br0">&#40;</span><span class="re0">$array</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>The array could be in the form <code class="highlighted php"><span class="kw3">array</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="nu0">4</span><span class="sy0">,</span> <span class="nu0">7</span><span class="sy0">,</span> <span class="nu0">12</span><span class="sy0">,</span> <span class="nu0">344</span><span class="sy0">,</span> <span class="nu0">4242</span><span class="br0">&#41;</span></code>, made from a DB query, generated
+from looking through the source for certain important things and working out what line those things are&#8230;
+However you get the line numbers, the array should simply be an array of integers.</p>
+
+<p>Here&#8217;s an example, using the same source as before:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+</pre></td><td class="de1"><pre class="de1"><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="co1">// Here we go again! This time we'll simply highlight the 8th line</span></span></span><span class="co1">//</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$source</span> <span class="sy0">=</span> <span class="st_h">'public int[][] product ( n, m )</span></span></span><span class="st_h">{</span>
+<span class="xtra li2"><span class="de2"><span class="st_h"> &nbsp;int [][] ans = new int[n][m];</span></span></span><span class="st_h"> &nbsp;for ( int i = 0; i &lt; n; i++ )</span>
+<span class="xtra li2"><span class="de2"><span class="st_h"> &nbsp;{</span></span></span><span class="st_h"> &nbsp; &nbsp;for ( int j = 0; i &lt; m; j++ )</span>
+<span class="xtra li2"><span class="de2"><span class="st_h"> &nbsp; &nbsp;{</span></span></span><span class="st_h"> &nbsp; &nbsp; &nbsp;ans[i][j] = i * j;</span>
+<span class="xtra li2"><span class="de2"><span class="st_h"> &nbsp; &nbsp;}</span></span></span><span class="st_h"> &nbsp;}</span>
+<span class="xtra li2"><span class="de2"><span class="st_h"> &nbsp;return ans;</span></span></span><span class="st_h">}'</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="st_h">'java'</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">highlight_lines_extra</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="nu0">8</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="kw1">echo</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></tbody></table>
+
+<p>Which produces:</p>
+
+<table class="java geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">Java code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2"><span class="xtra ln-xtra">8</span></span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span></pre></td><td class="de1"><pre class="de1"><span class="kw1">public</span> <span class="kw4">int</span><span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="br0">&#93;</span> product <span class="br0">&#40;</span> n, m <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2"><span class="br0">&#123;</span></span></span>&nbsp; <span class="kw4">int</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="br0">&#93;</span> ans <span class="sy0">=</span> <span class="kw1">new</span> <span class="kw4">int</span><span class="br0">&#91;</span>n<span class="br0">&#93;</span><span class="br0">&#91;</span>m<span class="br0">&#93;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> n<span class="sy0">;</span> i<span class="sy0">++</span> <span class="br0">&#41;</span></span></span>&nbsp; <span class="br0">&#123;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw4">int</span> j <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> m<span class="sy0">;</span> j<span class="sy0">++</span> <span class="br0">&#41;</span></span></span>&nbsp; &nbsp; <span class="br0">&#123;</span>
+<span class="xtra li2"><span class="de2"><span class="xtra ln-xtra">&nbsp; &nbsp; &nbsp; ans<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span>j<span class="br0">&#93;</span> <span class="sy0">=</span> i <span class="sy0">*</span> j<span class="sy0">;</span></span></span></span>&nbsp; &nbsp; <span class="br0">&#125;</span>
+<span class="xtra li2"><span class="de2">&nbsp; <span class="br0">&#125;</span></span></span>&nbsp; <span class="kw1">return</span> ans<span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="br0">&#125;</span></span></span></pre></td></tr></tbody></table>
+
+<p>What&#8217;s more, as you can see the code on a highlighted line is still actually highlighted itself.</p>
+
+<h4 id="styles-for-highlighted-lines">3.15.2 Styles for the Highlighted Lines</h4><div class="nav"><a href="#specifying-lines-to-highlight-extra">Previous</a> | <a href="#highlighting-special-lines-extra">Top</a> | <a href="#adding-ids-to-each-line">Next</a></div>
+
+<p>Again as with contextual importance, you&#8217;re not chained to the yellow theme that is the default. You can
+use the <code class="highlighted php">set_highlight_lines_extra_style</code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">set_highlight_lines_extra_style</span><span class="br0">&#40;</span><span class="re0">$styles</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$styles</span></code> is the stylesheet declarations that you want to apply to highlighted lines.</p>
+
+<h3 id="adding-ids-to-each-line">3.16 Adding IDs to Each Line</h3><div class="nav"><a href="#styles-for-highlighted-lines">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#getting-the-time-of-styling">Next</a></div>
+
+<p>Perhaps you&#8217;re a javascript junkie? <abbr title="Generic Syntax Highlighter">GeSHi</abbr> provides a way to give each line an ID so you can access that line with
+javascript, or perhaps just by plain <abbr title="Cascading Style Sheets">CSS</abbr> (though if you want to access lines by <abbr title="Cascading Style Sheets">CSS</abbr> you should use the method
+in the previous section). To enable IDs you call the <code class="highlighted php">enable_ids<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<p><code class="highlighted php"><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">enable_ids</span><span class="br0">&#40;</span><span class="re0">$flag</span><span class="br0">&#41;</span><span class="sy0">;</span></code></p>
+
+<p>Where <code class="highlighted php"><span class="re0">$flag</span></code> is <code class="highlighted php"><span class="kw4">true</span></code> or not present to enable IDs, and <code class="highlighted php"><span class="kw4">false</span></code> to disable them again if you need.</p>
+
+<p>The ID generated is in the form <code>{overall-css-id}-{line-number}</code>. So for example, if you set the overall <abbr title="Cascading Style Sheets">CSS</abbr> id to
+be &#8220;mycode&#8221;, then the IDs for each line would by &#8220;mycode-1&#8221;, &#8220;mycode-2&#8221; etc. If there is no <abbr title="Cascading Style Sheets">CSS</abbr> ID set, then one is
+made up in the form <code>geshi-[4 random characters]</code>, but this is not so useful for if you want to do javascript manipulation.</p>
+
+<h3 id="getting-the-time-of-styling">3.17 Getting the Time of Styling</h3><div class="nav"><a href="#adding-ids-to-each-line">Previous</a> | <a href="#advanced-features">Top</a> | <a href="#language-files">Next</a></div>
+
+<p>Once you&#8217;ve called <code class="highlighted php">parse_code<span class="br0">&#40;</span><span class="br0">&#41;</span></code>, you can get the time it took to run the highlighting by calling the
+<code class="highlighted php">get_time<span class="br0">&#40;</span><span class="br0">&#41;</span></code> method:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+</pre></td><td class="de1"><pre class="de1"><span class="re0">$geshi</span> <span class="sy0">=</span> <span class="kw2">new</span> GeSHi<span class="br0">&#40;</span><span class="re0">$source</span><span class="sy0">,</span> <span class="re0">$language</span><span class="sy0">,</span> <span class="re0">$path</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$code</span> <span class="sy0">=</span> <a href="http://www.php.net/mysql_real_escape_string"><span class="kw3">mysql_real_escape_string</span></a><span class="br0">&#40;</span><span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">parse_code</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2"><span class="re0">$time</span> <span class="sy0">=</span> <span class="re0">$geshi</span><span class="sy0">-&gt;</span><span class="me1">get_time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="co1">// do something with it</span></span></span><a href="http://www.php.net/mysql_query"><span class="kw3">mysql_query</span></a><span class="br0">&#40;</span><span class="st0">&quot;INSERT INTO code VALUES ('<span class="es4">$code</span>', '<span class="es4">$time</span>')&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></td></tr></tbody></table>
+
+<h2 id="language-files">4 Language Files</h2><div class="nav"><a href="#getting-the-time-of-styling">Previous</a> | <a href="#language-file-example">Next</a></div>
+
+<p>So now you know what features <abbr title="Generic Syntax Highlighter">GeSHi</abbr> offers, and perhaps you&#8217;ve even meddled with the source. Or perhaps
+you&#8217;d like a language file for language X but it doesn&#8217;t seem to be supported? Rubbish! <abbr title="Generic Syntax Highlighter">GeSHi</abbr> will highlight
+anything, what do you think I coded this for? ^_^ You&#8217;ll just have to learn how to make a language file
+yourself. And I promise it&#8217;s not too hard - and if you&#8217;re here you&#8217;re in the right place!</p>
+
+<h3 id="language-file-example">4.1 An Example Language File</h3><div class="nav"><a href="#language-files">Previous</a> | <a href="#language-files">Top</a> | <a href="#language-file-conventions">Next</a></div>
+
+<p>Let&#8217;s begin by looking at an example language file - the language file for the first language ever supported,
+<abbr title="PHP: HTML Preprocessor">PHP</abbr>:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+<span class="xtra li2"><span class="de2">28</span></span>29
+<span class="xtra li2"><span class="de2">30</span></span>31
+<span class="xtra li2"><span class="de2">32</span></span>33
+<span class="xtra li2"><span class="de2">34</span></span>35
+<span class="xtra li2"><span class="de2">36</span></span>37
+<span class="xtra li2"><span class="de2">38</span></span>39
+<span class="xtra li2"><span class="de2">40</span></span>41
+<span class="xtra li2"><span class="de2">42</span></span>43
+<span class="xtra li2"><span class="de2">44</span></span>45
+<span class="xtra li2"><span class="de2">46</span></span>47
+<span class="xtra li2"><span class="de2">48</span></span>49
+<span class="xtra li2"><span class="de2">50</span></span>51
+<span class="xtra li2"><span class="de2">52</span></span>53
+<span class="xtra li2"><span class="de2">54</span></span>55
+<span class="xtra li2"><span class="de2">56</span></span>57
+<span class="xtra li2"><span class="de2">58</span></span>59
+<span class="xtra li2"><span class="de2">60</span></span>61
+<span class="xtra li2"><span class="de2">62</span></span>63
+<span class="xtra li2"><span class="de2">64</span></span>65
+<span class="xtra li2"><span class="de2">66</span></span>67
+<span class="xtra li2"><span class="de2">68</span></span>69
+<span class="xtra li2"><span class="de2">70</span></span>71
+<span class="xtra li2"><span class="de2">72</span></span>73
+<span class="xtra li2"><span class="de2">74</span></span>75
+<span class="xtra li2"><span class="de2">76</span></span>77
+<span class="xtra li2"><span class="de2">78</span></span>79
+<span class="xtra li2"><span class="de2">80</span></span>81
+<span class="xtra li2"><span class="de2">82</span></span>83
+<span class="xtra li2"><span class="de2">84</span></span>85
+<span class="xtra li2"><span class="de2">86</span></span>87
+<span class="xtra li2"><span class="de2">88</span></span>89
+<span class="xtra li2"><span class="de2">90</span></span>91
+<span class="xtra li2"><span class="de2">92</span></span>93
+<span class="xtra li2"><span class="de2">94</span></span>95
+<span class="xtra li2"><span class="de2">96</span></span>97
+<span class="xtra li2"><span class="de2">98</span></span>99
+<span class="xtra li2"><span class="de2">100</span></span>101
+<span class="xtra li2"><span class="de2">102</span></span>103
+<span class="xtra li2"><span class="de2">104</span></span>105
+<span class="xtra li2"><span class="de2">106</span></span>107
+<span class="xtra li2"><span class="de2">108</span></span>109
+<span class="xtra li2"><span class="de2">110</span></span>111
+<span class="xtra li2"><span class="de2">112</span></span>113
+<span class="xtra li2"><span class="de2">114</span></span>115
+<span class="xtra li2"><span class="de2">116</span></span>117
+<span class="xtra li2"><span class="de2">118</span></span>119
+<span class="xtra li2"><span class="de2">120</span></span>121
+<span class="xtra li2"><span class="de2">122</span></span>123
+<span class="xtra li2"><span class="de2">124</span></span>125
+<span class="xtra li2"><span class="de2">126</span></span>127
+<span class="xtra li2"><span class="de2">128</span></span>129
+<span class="xtra li2"><span class="de2">130</span></span>131
+<span class="xtra li2"><span class="de2">132</span></span>133
+<span class="xtra li2"><span class="de2">134</span></span>135
+<span class="xtra li2"><span class="de2">136</span></span>137
+<span class="xtra li2"><span class="de2">138</span></span>139
+<span class="xtra li2"><span class="de2">140</span></span>141
+<span class="xtra li2"><span class="de2">142</span></span>143
+<span class="xtra li2"><span class="de2">144</span></span>145
+<span class="xtra li2"><span class="de2">146</span></span>147
+<span class="xtra li2"><span class="de2">148</span></span>149
+<span class="xtra li2"><span class="de2">150</span></span>151
+<span class="xtra li2"><span class="de2">152</span></span>153
+<span class="xtra li2"><span class="de2">154</span></span>155
+<span class="xtra li2"><span class="de2">156</span></span>157
+<span class="xtra li2"><span class="de2">158</span></span>159
+<span class="xtra li2"><span class="de2">160</span></span>161
+<span class="xtra li2"><span class="de2">162</span></span>163
+<span class="xtra li2"><span class="de2">164</span></span>165
+<span class="xtra li2"><span class="de2">166</span></span>167
+<span class="xtra li2"><span class="de2">168</span></span>169
+<span class="xtra li2"><span class="de2">170</span></span>171
+<span class="xtra li2"><span class="de2">172</span></span>173
+<span class="xtra li2"><span class="de2">174</span></span>175
+<span class="xtra li2"><span class="de2">176</span></span>177
+<span class="xtra li2"><span class="de2">178</span></span>179
+<span class="xtra li2"><span class="de2">180</span></span>181
+<span class="xtra li2"><span class="de2">182</span></span>183
+<span class="xtra li2"><span class="de2">184</span></span>185
+<span class="xtra li2"><span class="de2">186</span></span>187
+<span class="xtra li2"><span class="de2">188</span></span>189
+<span class="xtra li2"><span class="de2">190</span></span>191
+<span class="xtra li2"><span class="de2">192</span></span>193
+<span class="xtra li2"><span class="de2">194</span></span>195
+<span class="xtra li2"><span class="de2">196</span></span>197
+<span class="xtra li2"><span class="de2">198</span></span>199
+<span class="xtra li2"><span class="de2">200</span></span>201
+<span class="xtra li2"><span class="de2">202</span></span>203
+<span class="xtra li2"><span class="de2">204</span></span>205
+<span class="xtra li2"><span class="de2">206</span></span>207
+<span class="xtra li2"><span class="de2">208</span></span>209
+<span class="xtra li2"><span class="de2">210</span></span>211
+<span class="xtra li2"><span class="de2">212</span></span>213
+<span class="xtra li2"><span class="de2">214</span></span>215
+<span class="xtra li2"><span class="de2">216</span></span>217
+<span class="xtra li2"><span class="de2">218</span></span>219
+<span class="xtra li2"><span class="de2">220</span></span>221
+<span class="xtra li2"><span class="de2">222</span></span>223
+<span class="xtra li2"><span class="de2">224</span></span>225
+<span class="xtra li2"><span class="de2">226</span></span>227
+<span class="xtra li2"><span class="de2">228</span></span>229
+<span class="xtra li2"><span class="de2">230</span></span>231
+<span class="xtra li2"><span class="de2">232</span></span>233
+<span class="xtra li2"><span class="de2">234</span></span>235
+<span class="xtra li2"><span class="de2">236</span></span>237
+<span class="xtra li2"><span class="de2">238</span></span>239
+<span class="xtra li2"><span class="de2">240</span></span>241
+<span class="xtra li2"><span class="de2">242</span></span>243
+<span class="xtra li2"><span class="de2">244</span></span>245
+<span class="xtra li2"><span class="de2">246</span></span>247
+<span class="xtra li2"><span class="de2">248</span></span>249
+<span class="xtra li2"><span class="de2">250</span></span>251
+<span class="xtra li2"><span class="de2">252</span></span>253
+<span class="xtra li2"><span class="de2">254</span></span>255
+<span class="xtra li2"><span class="de2">256</span></span>257
+<span class="xtra li2"><span class="de2">258</span></span>259
+<span class="xtra li2"><span class="de2">260</span></span>261
+<span class="xtra li2"><span class="de2">262</span></span>263
+<span class="xtra li2"><span class="de2">264</span></span>265
+<span class="xtra li2"><span class="de2">266</span></span>267
+<span class="xtra li2"><span class="de2">268</span></span>269
+<span class="xtra li2"><span class="de2">270</span></span>271
+<span class="xtra li2"><span class="de2">272</span></span>273
+<span class="xtra li2"><span class="de2">274</span></span>275
+<span class="xtra li2"><span class="de2">276</span></span>277
+<span class="xtra li2"><span class="de2">278</span></span>279
+<span class="xtra li2"><span class="de2">280</span></span>281
+<span class="xtra li2"><span class="de2">282</span></span>283
+<span class="xtra li2"><span class="de2">284</span></span>285
+<span class="xtra li2"><span class="de2">286</span></span>287
+<span class="xtra li2"><span class="de2">288</span></span>289
+<span class="xtra li2"><span class="de2">290</span></span>291
+<span class="xtra li2"><span class="de2">292</span></span>293
+<span class="xtra li2"><span class="de2">294</span></span>295
+<span class="xtra li2"><span class="de2">296</span></span>297
+<span class="xtra li2"><span class="de2">298</span></span>299
+<span class="xtra li2"><span class="de2">300</span></span>301
+<span class="xtra li2"><span class="de2">302</span></span>303
+<span class="xtra li2"><span class="de2">304</span></span>305
+<span class="xtra li2"><span class="de2">306</span></span>307
+<span class="xtra li2"><span class="de2">308</span></span>309
+<span class="xtra li2"><span class="de2">310</span></span>311
+<span class="xtra li2"><span class="de2">312</span></span>313
+<span class="xtra li2"><span class="de2">314</span></span>315
+<span class="xtra li2"><span class="de2">316</span></span>317
+<span class="xtra li2"><span class="de2">318</span></span>319
+<span class="xtra li2"><span class="de2">320</span></span>321
+<span class="xtra li2"><span class="de2">322</span></span>323
+<span class="xtra li2"><span class="de2">324</span></span>325
+<span class="xtra li2"><span class="de2">326</span></span>327
+<span class="xtra li2"><span class="de2">328</span></span>329
+<span class="xtra li2"><span class="de2">330</span></span>331
+<span class="xtra li2"><span class="de2">332</span></span>333
+<span class="xtra li2"><span class="de2">334</span></span>335
+<span class="xtra li2"><span class="de2">336</span></span>337
+<span class="xtra li2"><span class="de2">338</span></span>339
+<span class="xtra li2"><span class="de2">340</span></span>341
+<span class="xtra li2"><span class="de2">342</span></span>343
+<span class="xtra li2"><span class="de2">344</span></span>345
+<span class="xtra li2"><span class="de2">346</span></span>347
+<span class="xtra li2"><span class="de2">348</span></span>349
+<span class="xtra li2"><span class="de2">350</span></span>351
+<span class="xtra li2"><span class="de2">352</span></span>353
+<span class="xtra li2"><span class="de2">354</span></span>355
+<span class="xtra li2"><span class="de2">356</span></span>357
+<span class="xtra li2"><span class="de2">358</span></span>359
+<span class="xtra li2"><span class="de2">360</span></span>361
+<span class="xtra li2"><span class="de2">362</span></span>363
+<span class="xtra li2"><span class="de2">364</span></span>365
+<span class="xtra li2"><span class="de2">366</span></span>367
+<span class="xtra li2"><span class="de2">368</span></span>369
+<span class="xtra li2"><span class="de2">370</span></span>371
+<span class="xtra li2"><span class="de2">372</span></span>373
+<span class="xtra li2"><span class="de2">374</span></span>375
+<span class="xtra li2"><span class="de2">376</span></span>377
+<span class="xtra li2"><span class="de2">378</span></span>379
+<span class="xtra li2"><span class="de2">380</span></span>381
+<span class="xtra li2"><span class="de2">382</span></span>383
+<span class="xtra li2"><span class="de2">384</span></span>385
+<span class="xtra li2"><span class="de2">386</span></span>387
+<span class="xtra li2"><span class="de2">388</span></span>389
+<span class="xtra li2"><span class="de2">390</span></span>391
+<span class="xtra li2"><span class="de2">392</span></span>393
+<span class="xtra li2"><span class="de2">394</span></span>395
+<span class="xtra li2"><span class="de2">396</span></span>397
+<span class="xtra li2"><span class="de2">398</span></span>399
+<span class="xtra li2"><span class="de2">400</span></span>401
+<span class="xtra li2"><span class="de2">402</span></span>403
+<span class="xtra li2"><span class="de2">404</span></span>405
+<span class="xtra li2"><span class="de2">406</span></span>407
+<span class="xtra li2"><span class="de2">408</span></span>409
+<span class="xtra li2"><span class="de2">410</span></span>411
+<span class="xtra li2"><span class="de2">412</span></span>413
+<span class="xtra li2"><span class="de2">414</span></span>415
+<span class="xtra li2"><span class="de2">416</span></span>417
+<span class="xtra li2"><span class="de2">418</span></span>419
+<span class="xtra li2"><span class="de2">420</span></span>421
+<span class="xtra li2"><span class="de2">422</span></span>423
+<span class="xtra li2"><span class="de2">424</span></span>425
+<span class="xtra li2"><span class="de2">426</span></span>427
+<span class="xtra li2"><span class="de2">428</span></span>429
+<span class="xtra li2"><span class="de2">430</span></span>431
+<span class="xtra li2"><span class="de2">432</span></span>433
+<span class="xtra li2"><span class="de2">434</span></span>435
+<span class="xtra li2"><span class="de2">436</span></span>437
+<span class="xtra li2"><span class="de2">438</span></span>439
+<span class="xtra li2"><span class="de2">440</span></span>441
+<span class="xtra li2"><span class="de2">442</span></span>443
+<span class="xtra li2"><span class="de2">444</span></span>445
+<span class="xtra li2"><span class="de2">446</span></span>447
+<span class="xtra li2"><span class="de2">448</span></span>449
+<span class="xtra li2"><span class="de2">450</span></span>451
+<span class="xtra li2"><span class="de2">452</span></span>453
+<span class="xtra li2"><span class="de2">454</span></span>455
+<span class="xtra li2"><span class="de2">456</span></span>457
+<span class="xtra li2"><span class="de2">458</span></span>459
+<span class="xtra li2"><span class="de2">460</span></span>461
+<span class="xtra li2"><span class="de2">462</span></span>463
+<span class="xtra li2"><span class="de2">464</span></span>465
+<span class="xtra li2"><span class="de2">466</span></span>467
+<span class="xtra li2"><span class="de2">468</span></span>469
+<span class="xtra li2"><span class="de2">470</span></span>471
+<span class="xtra li2"><span class="de2">472</span></span>473
+<span class="xtra li2"><span class="de2">474</span></span>475
+<span class="xtra li2"><span class="de2">476</span></span>477
+<span class="xtra li2"><span class="de2">478</span></span>479
+<span class="xtra li2"><span class="de2">480</span></span>481
+<span class="xtra li2"><span class="de2">482</span></span>483
+<span class="xtra li2"><span class="de2">484</span></span>485
+<span class="xtra li2"><span class="de2">486</span></span>487
+<span class="xtra li2"><span class="de2">488</span></span>489
+<span class="xtra li2"><span class="de2">490</span></span>491
+<span class="xtra li2"><span class="de2">492</span></span>493
+<span class="xtra li2"><span class="de2">494</span></span>495
+<span class="xtra li2"><span class="de2">496</span></span>497
+<span class="xtra li2"><span class="de2">498</span></span>499
+<span class="xtra li2"><span class="de2">500</span></span>501
+<span class="xtra li2"><span class="de2">502</span></span>503
+<span class="xtra li2"><span class="de2">504</span></span>505
+<span class="xtra li2"><span class="de2">506</span></span>507
+<span class="xtra li2"><span class="de2">508</span></span>509
+<span class="xtra li2"><span class="de2">510</span></span>511
+<span class="xtra li2"><span class="de2">512</span></span>513
+<span class="xtra li2"><span class="de2">514</span></span>515
+<span class="xtra li2"><span class="de2">516</span></span>517
+<span class="xtra li2"><span class="de2">518</span></span>519
+<span class="xtra li2"><span class="de2">520</span></span>521
+<span class="xtra li2"><span class="de2">522</span></span>523
+<span class="xtra li2"><span class="de2">524</span></span>525
+<span class="xtra li2"><span class="de2">526</span></span>527
+<span class="xtra li2"><span class="de2">528</span></span>529
+<span class="xtra li2"><span class="de2">530</span></span>531
+<span class="xtra li2"><span class="de2">532</span></span>533
+<span class="xtra li2"><span class="de2">534</span></span>535
+<span class="xtra li2"><span class="de2">536</span></span>537
+<span class="xtra li2"><span class="de2">538</span></span>539
+<span class="xtra li2"><span class="de2">540</span></span>541
+<span class="xtra li2"><span class="de2">542</span></span>543
+<span class="xtra li2"><span class="de2">544</span></span>545
+<span class="xtra li2"><span class="de2">546</span></span>547
+<span class="xtra li2"><span class="de2">548</span></span>549
+<span class="xtra li2"><span class="de2">550</span></span>551
+<span class="xtra li2"><span class="de2">552</span></span>553
+<span class="xtra li2"><span class="de2">554</span></span>555
+<span class="xtra li2"><span class="de2">556</span></span>557
+<span class="xtra li2"><span class="de2">558</span></span>559
+<span class="xtra li2"><span class="de2">560</span></span>561
+<span class="xtra li2"><span class="de2">562</span></span>563
+<span class="xtra li2"><span class="de2">564</span></span>565
+<span class="xtra li2"><span class="de2">566</span></span>567
+<span class="xtra li2"><span class="de2">568</span></span>569
+<span class="xtra li2"><span class="de2">570</span></span>571
+<span class="xtra li2"><span class="de2">572</span></span>573
+<span class="xtra li2"><span class="de2">574</span></span>575
+<span class="xtra li2"><span class="de2">576</span></span>577
+<span class="xtra li2"><span class="de2">578</span></span>579
+<span class="xtra li2"><span class="de2">580</span></span>581
+<span class="xtra li2"><span class="de2">582</span></span>583
+<span class="xtra li2"><span class="de2">584</span></span>585
+<span class="xtra li2"><span class="de2">586</span></span>587
+<span class="xtra li2"><span class="de2">588</span></span>589
+<span class="xtra li2"><span class="de2">590</span></span>591
+<span class="xtra li2"><span class="de2">592</span></span>593
+<span class="xtra li2"><span class="de2">594</span></span>595
+<span class="xtra li2"><span class="de2">596</span></span>597
+<span class="xtra li2"><span class="de2">598</span></span>599
+<span class="xtra li2"><span class="de2">600</span></span>601
+<span class="xtra li2"><span class="de2">602</span></span>603
+<span class="xtra li2"><span class="de2">604</span></span>605
+<span class="xtra li2"><span class="de2">606</span></span>607
+<span class="xtra li2"><span class="de2">608</span></span>609
+<span class="xtra li2"><span class="de2">610</span></span>611
+<span class="xtra li2"><span class="de2">612</span></span>613
+<span class="xtra li2"><span class="de2">614</span></span>615
+<span class="xtra li2"><span class="de2">616</span></span>617
+<span class="xtra li2"><span class="de2">618</span></span>619
+<span class="xtra li2"><span class="de2">620</span></span>621
+<span class="xtra li2"><span class="de2">622</span></span>623
+<span class="xtra li2"><span class="de2">624</span></span>625
+<span class="xtra li2"><span class="de2">626</span></span>627
+<span class="xtra li2"><span class="de2">628</span></span>629
+<span class="xtra li2"><span class="de2">630</span></span>631
+<span class="xtra li2"><span class="de2">632</span></span>633
+<span class="xtra li2"><span class="de2">634</span></span>635
+<span class="xtra li2"><span class="de2">636</span></span>637
+<span class="xtra li2"><span class="de2">638</span></span>639
+<span class="xtra li2"><span class="de2">640</span></span>641
+<span class="xtra li2"><span class="de2">642</span></span>643
+<span class="xtra li2"><span class="de2">644</span></span>645
+<span class="xtra li2"><span class="de2">646</span></span>647
+<span class="xtra li2"><span class="de2">648</span></span>649
+<span class="xtra li2"><span class="de2">650</span></span>651
+<span class="xtra li2"><span class="de2">652</span></span>653
+<span class="xtra li2"><span class="de2">654</span></span>655
+<span class="xtra li2"><span class="de2">656</span></span>657
+<span class="xtra li2"><span class="de2">658</span></span>659
+<span class="xtra li2"><span class="de2">660</span></span>661
+<span class="xtra li2"><span class="de2">662</span></span>663
+<span class="xtra li2"><span class="de2">664</span></span>665
+<span class="xtra li2"><span class="de2">666</span></span>667
+<span class="xtra li2"><span class="de2">668</span></span>669
+<span class="xtra li2"><span class="de2">670</span></span>671
+<span class="xtra li2"><span class="de2">672</span></span>673
+<span class="xtra li2"><span class="de2">674</span></span>675
+<span class="xtra li2"><span class="de2">676</span></span>677
+<span class="xtra li2"><span class="de2">678</span></span>679
+<span class="xtra li2"><span class="de2">680</span></span>681
+<span class="xtra li2"><span class="de2">682</span></span>683
+<span class="xtra li2"><span class="de2">684</span></span>685
+<span class="xtra li2"><span class="de2">686</span></span>687
+<span class="xtra li2"><span class="de2">688</span></span>689
+<span class="xtra li2"><span class="de2">690</span></span>691
+<span class="xtra li2"><span class="de2">692</span></span>693
+<span class="xtra li2"><span class="de2">694</span></span>695
+<span class="xtra li2"><span class="de2">696</span></span>697
+<span class="xtra li2"><span class="de2">698</span></span>699
+<span class="xtra li2"><span class="de2">700</span></span>701
+<span class="xtra li2"><span class="de2">702</span></span>703
+<span class="xtra li2"><span class="de2">704</span></span>705
+<span class="xtra li2"><span class="de2">706</span></span>707
+<span class="xtra li2"><span class="de2">708</span></span>709
+<span class="xtra li2"><span class="de2">710</span></span>711
+<span class="xtra li2"><span class="de2">712</span></span>713
+<span class="xtra li2"><span class="de2">714</span></span>715
+<span class="xtra li2"><span class="de2">716</span></span>717
+<span class="xtra li2"><span class="de2">718</span></span>719
+<span class="xtra li2"><span class="de2">720</span></span>721
+<span class="xtra li2"><span class="de2">722</span></span>723
+<span class="xtra li2"><span class="de2">724</span></span>725
+<span class="xtra li2"><span class="de2">726</span></span>727
+<span class="xtra li2"><span class="de2">728</span></span>729
+<span class="xtra li2"><span class="de2">730</span></span>731
+<span class="xtra li2"><span class="de2">732</span></span>733
+<span class="xtra li2"><span class="de2">734</span></span>735
+<span class="xtra li2"><span class="de2">736</span></span>737
+<span class="xtra li2"><span class="de2">738</span></span>739
+<span class="xtra li2"><span class="de2">740</span></span>741
+<span class="xtra li2"><span class="de2">742</span></span>743
+<span class="xtra li2"><span class="de2">744</span></span>745
+<span class="xtra li2"><span class="de2">746</span></span>747
+<span class="xtra li2"><span class="de2">748</span></span>749
+<span class="xtra li2"><span class="de2">750</span></span>751
+<span class="xtra li2"><span class="de2">752</span></span>753
+<span class="xtra li2"><span class="de2">754</span></span>755
+<span class="xtra li2"><span class="de2">756</span></span>757
+<span class="xtra li2"><span class="de2">758</span></span>759
+<span class="xtra li2"><span class="de2">760</span></span>761
+<span class="xtra li2"><span class="de2">762</span></span>763
+<span class="xtra li2"><span class="de2">764</span></span>765
+<span class="xtra li2"><span class="de2">766</span></span>767
+<span class="xtra li2"><span class="de2">768</span></span>769
+<span class="xtra li2"><span class="de2">770</span></span>771
+<span class="xtra li2"><span class="de2">772</span></span>773
+<span class="xtra li2"><span class="de2">774</span></span>775
+<span class="xtra li2"><span class="de2">776</span></span>777
+<span class="xtra li2"><span class="de2">778</span></span>779
+<span class="xtra li2"><span class="de2">780</span></span>781
+<span class="xtra li2"><span class="de2">782</span></span>783
+<span class="xtra li2"><span class="de2">784</span></span>785
+<span class="xtra li2"><span class="de2">786</span></span>787
+<span class="xtra li2"><span class="de2">788</span></span>789
+<span class="xtra li2"><span class="de2">790</span></span>791
+<span class="xtra li2"><span class="de2">792</span></span>793
+<span class="xtra li2"><span class="de2">794</span></span>795
+<span class="xtra li2"><span class="de2">796</span></span>797
+<span class="xtra li2"><span class="de2">798</span></span>799
+<span class="xtra li2"><span class="de2">800</span></span>801
+<span class="xtra li2"><span class="de2">802</span></span>803
+<span class="xtra li2"><span class="de2">804</span></span>805
+<span class="xtra li2"><span class="de2">806</span></span>807
+<span class="xtra li2"><span class="de2">808</span></span>809
+<span class="xtra li2"><span class="de2">810</span></span>811
+<span class="xtra li2"><span class="de2">812</span></span>813
+<span class="xtra li2"><span class="de2">814</span></span>815
+<span class="xtra li2"><span class="de2">816</span></span>817
+<span class="xtra li2"><span class="de2">818</span></span>819
+<span class="xtra li2"><span class="de2">820</span></span>821
+<span class="xtra li2"><span class="de2">822</span></span>823
+<span class="xtra li2"><span class="de2">824</span></span>825
+<span class="xtra li2"><span class="de2">826</span></span>827
+<span class="xtra li2"><span class="de2">828</span></span>829
+<span class="xtra li2"><span class="de2">830</span></span>831
+<span class="xtra li2"><span class="de2">832</span></span>833
+<span class="xtra li2"><span class="de2">834</span></span>835
+<span class="xtra li2"><span class="de2">836</span></span>837
+<span class="xtra li2"><span class="de2">838</span></span>839
+<span class="xtra li2"><span class="de2">840</span></span>841
+<span class="xtra li2"><span class="de2">842</span></span>843
+<span class="xtra li2"><span class="de2">844</span></span>845
+<span class="xtra li2"><span class="de2">846</span></span>847
+<span class="xtra li2"><span class="de2">848</span></span>849
+<span class="xtra li2"><span class="de2">850</span></span>851
+<span class="xtra li2"><span class="de2">852</span></span>853
+<span class="xtra li2"><span class="de2">854</span></span>855
+<span class="xtra li2"><span class="de2">856</span></span>857
+<span class="xtra li2"><span class="de2">858</span></span>859
+<span class="xtra li2"><span class="de2">860</span></span>861
+<span class="xtra li2"><span class="de2">862</span></span>863
+<span class="xtra li2"><span class="de2">864</span></span>865
+<span class="xtra li2"><span class="de2">866</span></span>867
+<span class="xtra li2"><span class="de2">868</span></span>869
+<span class="xtra li2"><span class="de2">870</span></span>871
+<span class="xtra li2"><span class="de2">872</span></span>873
+<span class="xtra li2"><span class="de2">874</span></span>875
+<span class="xtra li2"><span class="de2">876</span></span>877
+<span class="xtra li2"><span class="de2">878</span></span>879
+<span class="xtra li2"><span class="de2">880</span></span>881
+<span class="xtra li2"><span class="de2">882</span></span>883
+<span class="xtra li2"><span class="de2">884</span></span>885
+<span class="xtra li2"><span class="de2">886</span></span>887
+<span class="xtra li2"><span class="de2">888</span></span>889
+<span class="xtra li2"><span class="de2">890</span></span>891
+<span class="xtra li2"><span class="de2">892</span></span>893
+<span class="xtra li2"><span class="de2">894</span></span>895
+<span class="xtra li2"><span class="de2">896</span></span>897
+<span class="xtra li2"><span class="de2">898</span></span>899
+<span class="xtra li2"><span class="de2">900</span></span>901
+<span class="xtra li2"><span class="de2">902</span></span>903
+<span class="xtra li2"><span class="de2">904</span></span>905
+<span class="xtra li2"><span class="de2">906</span></span>907
+<span class="xtra li2"><span class="de2">908</span></span>909
+<span class="xtra li2"><span class="de2">910</span></span>911
+<span class="xtra li2"><span class="de2">912</span></span>913
+<span class="xtra li2"><span class="de2">914</span></span>915
+<span class="xtra li2"><span class="de2">916</span></span>917
+<span class="xtra li2"><span class="de2">918</span></span>919
+<span class="xtra li2"><span class="de2">920</span></span>921
+<span class="xtra li2"><span class="de2">922</span></span>923
+<span class="xtra li2"><span class="de2">924</span></span>925
+<span class="xtra li2"><span class="de2">926</span></span>927
+<span class="xtra li2"><span class="de2">928</span></span>929
+<span class="xtra li2"><span class="de2">930</span></span>931
+<span class="xtra li2"><span class="de2">932</span></span>933
+<span class="xtra li2"><span class="de2">934</span></span>935
+<span class="xtra li2"><span class="de2">936</span></span>937
+<span class="xtra li2"><span class="de2">938</span></span>939
+<span class="xtra li2"><span class="de2">940</span></span>941
+<span class="xtra li2"><span class="de2">942</span></span>943
+<span class="xtra li2"><span class="de2">944</span></span>945
+<span class="xtra li2"><span class="de2">946</span></span>947
+<span class="xtra li2"><span class="de2">948</span></span>949
+<span class="xtra li2"><span class="de2">950</span></span>951
+<span class="xtra li2"><span class="de2">952</span></span>953
+<span class="xtra li2"><span class="de2">954</span></span>955
+<span class="xtra li2"><span class="de2">956</span></span>957
+<span class="xtra li2"><span class="de2">958</span></span>959
+<span class="xtra li2"><span class="de2">960</span></span>961
+<span class="xtra li2"><span class="de2">962</span></span>963
+<span class="xtra li2"><span class="de2">964</span></span>965
+<span class="xtra li2"><span class="de2">966</span></span>967
+<span class="xtra li2"><span class="de2">968</span></span>969
+<span class="xtra li2"><span class="de2">970</span></span>971
+<span class="xtra li2"><span class="de2">972</span></span>973
+<span class="xtra li2"><span class="de2">974</span></span>975
+<span class="xtra li2"><span class="de2">976</span></span>977
+<span class="xtra li2"><span class="de2">978</span></span>979
+<span class="xtra li2"><span class="de2">980</span></span>981
+<span class="xtra li2"><span class="de2">982</span></span>983
+<span class="xtra li2"><span class="de2">984</span></span>985
+<span class="xtra li2"><span class="de2">986</span></span>987
+<span class="xtra li2"><span class="de2">988</span></span>989
+<span class="xtra li2"><span class="de2">990</span></span>991
+<span class="xtra li2"><span class="de2">992</span></span>993
+<span class="xtra li2"><span class="de2">994</span></span>995
+<span class="xtra li2"><span class="de2">996</span></span>997
+<span class="xtra li2"><span class="de2">998</span></span>999
+<span class="xtra li2"><span class="de2">1000</span></span>1001
+<span class="xtra li2"><span class="de2">1002</span></span>1003
+<span class="xtra li2"><span class="de2">1004</span></span>1005
+<span class="xtra li2"><span class="de2">1006</span></span>1007
+<span class="xtra li2"><span class="de2">1008</span></span>1009
+<span class="xtra li2"><span class="de2">1010</span></span>1011
+<span class="xtra li2"><span class="de2">1012</span></span>1013
+<span class="xtra li2"><span class="de2">1014</span></span>1015
+<span class="xtra li2"><span class="de2">1016</span></span>1017
+<span class="xtra li2"><span class="de2">1018</span></span>1019
+<span class="xtra li2"><span class="de2">1020</span></span>1021
+<span class="xtra li2"><span class="de2">1022</span></span>1023
+<span class="xtra li2"><span class="de2">1024</span></span>1025
+<span class="xtra li2"><span class="de2">1026</span></span>1027
+<span class="xtra li2"><span class="de2">1028</span></span>1029
+<span class="xtra li2"><span class="de2">1030</span></span>1031
+<span class="xtra li2"><span class="de2">1032</span></span>1033
+<span class="xtra li2"><span class="de2">1034</span></span>1035
+<span class="xtra li2"><span class="de2">1036</span></span>1037
+<span class="xtra li2"><span class="de2">1038</span></span>1039
+<span class="xtra li2"><span class="de2">1040</span></span>1041
+<span class="xtra li2"><span class="de2">1042</span></span>1043
+<span class="xtra li2"><span class="de2">1044</span></span>1045
+<span class="xtra li2"><span class="de2">1046</span></span>1047
+<span class="xtra li2"><span class="de2">1048</span></span>1049
+<span class="xtra li2"><span class="de2">1050</span></span>1051
+<span class="xtra li2"><span class="de2">1052</span></span>1053
+<span class="xtra li2"><span class="de2">1054</span></span>1055
+<span class="xtra li2"><span class="de2">1056</span></span>1057
+<span class="xtra li2"><span class="de2">1058</span></span>1059
+<span class="xtra li2"><span class="de2">1060</span></span>1061
+<span class="xtra li2"><span class="de2">1062</span></span>1063
+<span class="xtra li2"><span class="de2">1064</span></span>1065
+<span class="xtra li2"><span class="de2">1066</span></span>1067
+<span class="xtra li2"><span class="de2">1068</span></span>1069
+<span class="xtra li2"><span class="de2">1070</span></span>1071
+<span class="xtra li2"><span class="de2">1072</span></span>1073
+<span class="xtra li2"><span class="de2">1074</span></span>1075
+<span class="xtra li2"><span class="de2">1076</span></span>1077
+<span class="xtra li2"><span class="de2">1078</span></span>1079
+<span class="xtra li2"><span class="de2">1080</span></span>1081
+<span class="xtra li2"><span class="de2">1082</span></span>1083
+<span class="xtra li2"><span class="de2">1084</span></span>1085
+<span class="xtra li2"><span class="de2">1086</span></span>1087
+<span class="xtra li2"><span class="de2">1088</span></span>1089
+<span class="xtra li2"><span class="de2">1090</span></span>1091
+<span class="xtra li2"><span class="de2">1092</span></span>1093
+<span class="xtra li2"><span class="de2">1094</span></span></pre></td><td class="de1"><pre class="de1"><span class="kw2">&lt;?php</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">/*************************************************************************************</span></span></span><span class="coMULTI">&nbsp;* php.php</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* --------</span></span></span><span class="coMULTI">&nbsp;* Author: Nigel McNie (nigel@geshi.org)</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)</span></span></span><span class="coMULTI">&nbsp;* Release Version: 1.0.8.3</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* Date Started: 2004/06/20</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* PHP language file for GeSHi.</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* CHANGES</span></span></span><span class="coMULTI">&nbsp;* -------</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* 2008/05/23 (1.0.7.22)</span></span></span><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;Added description of extra language features (SF#1970248)</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* 2004/11/25 (1.0.3)</span></span></span><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;Added support for multiple object splitters</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;Fixed &amp;new problem</span></span></span><span class="coMULTI">&nbsp;* 2004/10/27 (1.0.2)</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;Added URL support</span></span></span><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;Added extra constants</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* 2004/08/05 (1.0.1)</span></span></span><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;Added support for symbols</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* 2004/07/14 (1.0.0)</span></span></span><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;First Release</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* TODO (updated 2004/07/14)</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* -------------------------</span></span></span><span class="coMULTI">&nbsp;* * Make sure the last few function I may have missed</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; (like eval()) are included for highlighting</span></span></span><span class="coMULTI">&nbsp;* * Split to several files - php4, php5 etc</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;*************************************************************************************</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* &nbsp; &nbsp; This file is part of GeSHi.</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* &nbsp; GeSHi is free software; you can redistribute it and/or modify</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; it under the terms of the GNU General Public License as published by</span></span></span><span class="coMULTI">&nbsp;* &nbsp; the Free Software Foundation; either version 2 of the License, or</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; (at your option) any later version.</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; GeSHi is distributed in the hope that it will be useful,</span></span></span><span class="coMULTI">&nbsp;* &nbsp; but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. &nbsp;See the</span></span></span><span class="coMULTI">&nbsp;* &nbsp; GNU General Public License for more details.</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* &nbsp; You should have received a copy of the GNU General Public License</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; along with GeSHi; if not, write to the Free Software</span></span></span><span class="coMULTI">&nbsp;* &nbsp; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA &nbsp;02111-1307 &nbsp;USA</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;************************************************************************************/</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$language_data</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'LANG_NAME'</span> <span class="sy0">=&gt;</span> <span class="st_h">'PHP'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'COMMENT_SINGLE'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'//'</span><span class="sy0">,</span> <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'#'</span><span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'COMMENT_MULTI'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'/*'</span> <span class="sy0">=&gt;</span> <span class="st_h">'*/'</span><span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'HARDQUOTE'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&quot;'&quot;</span><span class="sy0">,</span> <span class="st0">&quot;'&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'HARDESCAPE'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&quot;'&quot;</span><span class="sy0">,</span> <span class="st0">&quot;<span class="es1">\\</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'HARDCHAR'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;<span class="es1">\\</span>&quot;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'COMMENT_REGEXP'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Heredoc and Nowdoc syntax</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'/&lt;&lt;&lt;\s*?(\'?)([a-zA-Z0-9]+?)\1[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// phpdoc comments</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">'#/\*\*(?![\*\/]).*\*/#sU'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Advanced # handling</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;/#.*?(?:(?=\?\&gt;)|^)/smi&quot;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'CASE_KEYWORDS'</span> <span class="sy0">=&gt;</span> GESHI_CAPS_NO_CHANGE<span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'QUOTEMARKS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'&quot;'</span><span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'ESCAPE_CHAR'</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'ESCAPE_REGEXP'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Simple Single Char Escapes</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;#<span class="es1">\\</span><span class="es1">\\</span>[nfrtv<span class="es1">\$</span><span class="es1">\&quot;</span><span class="es1">\n</span><span class="es1">\\</span><span class="es1">\\</span>]#i&quot;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Hexadecimal Char Specs</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;#<span class="es1">\\</span><span class="es1">\\</span>x[\da-fA-F]{1,2}#i&quot;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Octal Char Specs</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;#<span class="es1">\\</span><span class="es1">\\</span>[0-7]{1,3}#&quot;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//String Parsing of Variable Names</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;#<span class="es1">\\</span>$[a-z0-9_]+(?:<span class="es1">\\</span>[[a-z0-9_]+<span class="es1">\\</span>]|-&gt;[a-z0-9_]+)?|(?:<span class="es1">\\</span>{<span class="es1">\\</span>$|<span class="es1">\\</span>$<span class="es1">\\</span>{)[a-z0-9_]+(?:<span class="es1">\\</span>[('?)[a-z0-9_]*<span class="es1">\\</span>1<span class="es1">\\</span>]|-&gt;[a-z0-9_]+)*<span class="es1">\\</span>}#i&quot;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Experimental extension supporting cascaded {${$var}} syntax</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;#<span class="es1">\$</span>[a-z0-9_]+(?:\[[a-z0-9_]+\]|-&gt;[a-z0-9_]+)?|(?:\{<span class="es1">\$</span>|<span class="es1">\$</span>\{)[a-z0-9_]+(?:\[('?)[a-z0-9_]*<span class="es1">\\</span>1\]|-&gt;[a-z0-9_]+)*\}|\{<span class="es1">\$</span>(?R)\}#i&quot;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Format String support in &quot;&quot;-Strings</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">6</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;#%(?:%|(?:\d+<span class="es1">\\</span><span class="es1">\\</span><span class="es1">\\</span><span class="es1">\$</span>)?<span class="es1">\\</span>+?(?:<span class="es2">\x20</span>|0|'.)?-?(?:\d+|<span class="es1">\\</span>*)?(?:\.\d+)?[bcdefFosuxX])#&quot;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'NUMBERS'</span> <span class="sy0">=&gt;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_INT_BASIC <span class="sy0">|</span> &nbsp;GESHI_NUMBER_OCT_PREFIX <span class="sy0">|</span> GESHI_NUMBER_HEX_PREFIX <span class="sy0">|</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_FLT_SCI_ZERO<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'KEYWORDS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'as'</span><span class="sy0">,</span><span class="st_h">'break'</span><span class="sy0">,</span><span class="st_h">'case'</span><span class="sy0">,</span><span class="st_h">'continue'</span><span class="sy0">,</span><span class="st_h">'default'</span><span class="sy0">,</span><span class="st_h">'do'</span><span class="sy0">,</span><span class="st_h">'else'</span><span class="sy0">,</span><span class="st_h">'elseif'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'endfor'</span><span class="sy0">,</span><span class="st_h">'endforeach'</span><span class="sy0">,</span><span class="st_h">'endif'</span><span class="sy0">,</span><span class="st_h">'endswitch'</span><span class="sy0">,</span><span class="st_h">'endwhile'</span><span class="sy0">,</span><span class="st_h">'for'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'foreach'</span><span class="sy0">,</span><span class="st_h">'if'</span><span class="sy0">,</span><span class="st_h">'include'</span><span class="sy0">,</span><span class="st_h">'include_once'</span><span class="sy0">,</span><span class="st_h">'require'</span><span class="sy0">,</span><span class="st_h">'require_once'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'return'</span><span class="sy0">,</span><span class="st_h">'switch'</span><span class="sy0">,</span><span class="st_h">'while'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'echo'</span><span class="sy0">,</span><span class="st_h">'print'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&amp;amp;new'</span><span class="sy0">,</span><span class="st_h">'&amp;lt;/script&amp;gt;'</span><span class="sy0">,</span><span class="st_h">'&amp;lt;?php'</span><span class="sy0">,</span><span class="st_h">'&amp;lt;script language'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'class'</span><span class="sy0">,</span><span class="st_h">'const'</span><span class="sy0">,</span><span class="st_h">'declare'</span><span class="sy0">,</span><span class="st_h">'extends'</span><span class="sy0">,</span><span class="st_h">'function'</span><span class="sy0">,</span><span class="st_h">'global'</span><span class="sy0">,</span><span class="st_h">'interface'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'namespace'</span><span class="sy0">,</span><span class="st_h">'new'</span><span class="sy0">,</span><span class="st_h">'private'</span><span class="sy0">,</span><span class="st_h">'public'</span><span class="sy0">,</span><span class="st_h">'self'</span><span class="sy0">,</span><span class="st_h">'var'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'abs'</span><span class="sy0">,</span><span class="st_h">'acos'</span><span class="sy0">,</span><span class="st_h">'acosh'</span><span class="sy0">,</span><span class="st_h">'addcslashes'</span><span class="sy0">,</span><span class="st_h">'addslashes'</span><span class="sy0">,</span><span class="st_h">'aggregate'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'aggregate_methods'</span><span class="sy0">,</span><span class="st_h">'aggregate_methods_by_list'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'aggregate_methods_by_regexp'</span><span class="sy0">,</span><span class="st_h">'aggregate_properties'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'aggregate_properties_by_list'</span><span class="sy0">,</span><span class="st_h">'aggregate_properties_by_regexp'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'aggregation_info'</span><span class="sy0">,</span><span class="st_h">'apache_child_terminate'</span><span class="sy0">,</span><span class="st_h">'apache_get_modules'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'apache_get_version'</span><span class="sy0">,</span><span class="st_h">'apache_getenv'</span><span class="sy0">,</span><span class="st_h">'apache_lookup_uri'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'apache_note'</span><span class="sy0">,</span><span class="st_h">'apache_request_headers'</span><span class="sy0">,</span><span class="st_h">'apache_response_headers'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'apache_setenv'</span><span class="sy0">,</span><span class="st_h">'array'</span><span class="sy0">,</span><span class="st_h">'array_change_key_case'</span><span class="sy0">,</span><span class="st_h">'array_chunk'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_combine'</span><span class="sy0">,</span><span class="st_h">'array_count_values'</span><span class="sy0">,</span><span class="st_h">'array_diff'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_diff_assoc'</span><span class="sy0">,</span><span class="st_h">'array_diff_key'</span><span class="sy0">,</span><span class="st_h">'array_diff_uassoc'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_diff_ukey'</span><span class="sy0">,</span><span class="st_h">'array_fill'</span><span class="sy0">,</span><span class="st_h">'array_fill_keys'</span><span class="sy0">,</span><span class="st_h">'array_filter'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_flip'</span><span class="sy0">,</span><span class="st_h">'array_intersect'</span><span class="sy0">,</span><span class="st_h">'array_intersect_assoc'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_intersect_key'</span><span class="sy0">,</span><span class="st_h">'array_intersect_uassoc'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_intersect_ukey'</span><span class="sy0">,</span><span class="st_h">'array_key_exists'</span><span class="sy0">,</span><span class="st_h">'array_keys'</span><span class="sy0">,</span><span class="st_h">'array_map'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_merge'</span><span class="sy0">,</span><span class="st_h">'array_merge_recursive'</span><span class="sy0">,</span><span class="st_h">'array_multisort'</span><span class="sy0">,</span><span class="st_h">'array_pad'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_pop'</span><span class="sy0">,</span><span class="st_h">'array_product'</span><span class="sy0">,</span><span class="st_h">'array_push'</span><span class="sy0">,</span><span class="st_h">'array_rand'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_reduce'</span><span class="sy0">,</span><span class="st_h">'array_reverse'</span><span class="sy0">,</span><span class="st_h">'array_search'</span><span class="sy0">,</span><span class="st_h">'array_shift'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_slice'</span><span class="sy0">,</span><span class="st_h">'array_splice'</span><span class="sy0">,</span><span class="st_h">'array_sum'</span><span class="sy0">,</span><span class="st_h">'array_udiff'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_udiff_assoc'</span><span class="sy0">,</span><span class="st_h">'array_udiff_uassoc'</span><span class="sy0">,</span><span class="st_h">'array_uintersect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_uintersect_assoc'</span><span class="sy0">,</span><span class="st_h">'array_uintersect_uassoc'</span><span class="sy0">,</span><span class="st_h">'array_unique'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'array_unshift'</span><span class="sy0">,</span><span class="st_h">'array_values'</span><span class="sy0">,</span><span class="st_h">'array_walk'</span><span class="sy0">,</span><span class="st_h">'array_walk_recursive'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'arsort'</span><span class="sy0">,</span><span class="st_h">'asin'</span><span class="sy0">,</span><span class="st_h">'asinh'</span><span class="sy0">,</span><span class="st_h">'asort'</span><span class="sy0">,</span><span class="st_h">'assert'</span><span class="sy0">,</span><span class="st_h">'assert_options'</span><span class="sy0">,</span><span class="st_h">'atan'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'atan2'</span><span class="sy0">,</span><span class="st_h">'atanh'</span><span class="sy0">,</span><span class="st_h">'base_convert'</span><span class="sy0">,</span><span class="st_h">'base64_decode'</span><span class="sy0">,</span><span class="st_h">'base64_encode'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'basename'</span><span class="sy0">,</span><span class="st_h">'bcadd'</span><span class="sy0">,</span><span class="st_h">'bccomp'</span><span class="sy0">,</span><span class="st_h">'bcdiv'</span><span class="sy0">,</span><span class="st_h">'bcmod'</span><span class="sy0">,</span><span class="st_h">'bcmul'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcompiler_load'</span><span class="sy0">,</span><span class="st_h">'bcompiler_load_exe'</span><span class="sy0">,</span><span class="st_h">'bcompiler_parse_class'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcompiler_read'</span><span class="sy0">,</span><span class="st_h">'bcompiler_write_class'</span><span class="sy0">,</span><span class="st_h">'bcompiler_write_constant'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcompiler_write_exe_footer'</span><span class="sy0">,</span><span class="st_h">'bcompiler_write_file'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcompiler_write_footer'</span><span class="sy0">,</span><span class="st_h">'bcompiler_write_function'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcompiler_write_functions_from_file'</span><span class="sy0">,</span><span class="st_h">'bcompiler_write_header'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcompiler_write_included_filename'</span><span class="sy0">,</span><span class="st_h">'bcpow'</span><span class="sy0">,</span><span class="st_h">'bcpowmod'</span><span class="sy0">,</span><span class="st_h">'bcscale'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bcsqrt'</span><span class="sy0">,</span><span class="st_h">'bcsub'</span><span class="sy0">,</span><span class="st_h">'bin2hex'</span><span class="sy0">,</span><span class="st_h">'bindec'</span><span class="sy0">,</span><span class="st_h">'bindtextdomain'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bind_textdomain_codeset'</span><span class="sy0">,</span><span class="st_h">'bitset_empty'</span><span class="sy0">,</span><span class="st_h">'bitset_equal'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bitset_excl'</span><span class="sy0">,</span><span class="st_h">'bitset_fill'</span><span class="sy0">,</span><span class="st_h">'bitset_from_array'</span><span class="sy0">,</span><span class="st_h">'bitset_from_hash'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bitset_from_string'</span><span class="sy0">,</span><span class="st_h">'bitset_in'</span><span class="sy0">,</span><span class="st_h">'bitset_incl'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bitset_intersection'</span><span class="sy0">,</span><span class="st_h">'bitset_invert'</span><span class="sy0">,</span><span class="st_h">'bitset_is_empty'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bitset_subset'</span><span class="sy0">,</span><span class="st_h">'bitset_to_array'</span><span class="sy0">,</span><span class="st_h">'bitset_to_hash'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bitset_to_string'</span><span class="sy0">,</span><span class="st_h">'bitset_union'</span><span class="sy0">,</span><span class="st_h">'blenc_encrypt'</span><span class="sy0">,</span><span class="st_h">'bzclose'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bzcompress'</span><span class="sy0">,</span><span class="st_h">'bzdecompress'</span><span class="sy0">,</span><span class="st_h">'bzerrno'</span><span class="sy0">,</span><span class="st_h">'bzerror'</span><span class="sy0">,</span><span class="st_h">'bzerrstr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'bzflush'</span><span class="sy0">,</span><span class="st_h">'bzopen'</span><span class="sy0">,</span><span class="st_h">'bzread'</span><span class="sy0">,</span><span class="st_h">'bzwrite'</span><span class="sy0">,</span><span class="st_h">'cal_days_in_month'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cal_from_jd'</span><span class="sy0">,</span><span class="st_h">'cal_info'</span><span class="sy0">,</span><span class="st_h">'cal_to_jd'</span><span class="sy0">,</span><span class="st_h">'call_user_func'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'call_user_func_array'</span><span class="sy0">,</span><span class="st_h">'call_user_method'</span><span class="sy0">,</span><span class="st_h">'call_user_method_array'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ceil'</span><span class="sy0">,</span><span class="st_h">'chdir'</span><span class="sy0">,</span><span class="st_h">'checkdate'</span><span class="sy0">,</span><span class="st_h">'checkdnsrr'</span><span class="sy0">,</span><span class="st_h">'chgrp'</span><span class="sy0">,</span><span class="st_h">'chmod'</span><span class="sy0">,</span><span class="st_h">'chop'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'chown'</span><span class="sy0">,</span><span class="st_h">'chr'</span><span class="sy0">,</span><span class="st_h">'chunk_split'</span><span class="sy0">,</span><span class="st_h">'class_exists'</span><span class="sy0">,</span><span class="st_h">'class_implements'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'class_parents'</span><span class="sy0">,</span><span class="st_h">'classkit_aggregate_methods'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'classkit_doc_comments'</span><span class="sy0">,</span><span class="st_h">'classkit_import'</span><span class="sy0">,</span><span class="st_h">'classkit_method_add'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'classkit_method_copy'</span><span class="sy0">,</span><span class="st_h">'classkit_method_redefine'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'classkit_method_remove'</span><span class="sy0">,</span><span class="st_h">'classkit_method_rename'</span><span class="sy0">,</span><span class="st_h">'clearstatcache'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'closedir'</span><span class="sy0">,</span><span class="st_h">'closelog'</span><span class="sy0">,</span><span class="st_h">'com_create_guid'</span><span class="sy0">,</span><span class="st_h">'com_event_sink'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'com_get_active_object'</span><span class="sy0">,</span><span class="st_h">'com_load_typelib'</span><span class="sy0">,</span><span class="st_h">'com_message_pump'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'com_print_typeinfo'</span><span class="sy0">,</span><span class="st_h">'compact'</span><span class="sy0">,</span><span class="st_h">'confirm_phpdoc_compiled'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'connection_aborted'</span><span class="sy0">,</span><span class="st_h">'connection_status'</span><span class="sy0">,</span><span class="st_h">'constant'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'convert_cyr_string'</span><span class="sy0">,</span><span class="st_h">'convert_uudecode'</span><span class="sy0">,</span><span class="st_h">'convert_uuencode'</span><span class="sy0">,</span><span class="st_h">'copy'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cos'</span><span class="sy0">,</span><span class="st_h">'cosh'</span><span class="sy0">,</span><span class="st_h">'count'</span><span class="sy0">,</span><span class="st_h">'count_chars'</span><span class="sy0">,</span><span class="st_h">'cpdf_add_annotation'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_add_outline'</span><span class="sy0">,</span><span class="st_h">'cpdf_arc'</span><span class="sy0">,</span><span class="st_h">'cpdf_begin_text'</span><span class="sy0">,</span><span class="st_h">'cpdf_circle'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_clip'</span><span class="sy0">,</span><span class="st_h">'cpdf_close'</span><span class="sy0">,</span><span class="st_h">'cpdf_closepath'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_closepath_fill_stroke'</span><span class="sy0">,</span><span class="st_h">'cpdf_closepath_stroke'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_continue_text'</span><span class="sy0">,</span><span class="st_h">'cpdf_curveto'</span><span class="sy0">,</span><span class="st_h">'cpdf_end_text'</span><span class="sy0">,</span><span class="st_h">'cpdf_fill'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_fill_stroke'</span><span class="sy0">,</span><span class="st_h">'cpdf_finalize'</span><span class="sy0">,</span><span class="st_h">'cpdf_finalize_page'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_global_set_document_limits'</span><span class="sy0">,</span><span class="st_h">'cpdf_import_jpeg'</span><span class="sy0">,</span><span class="st_h">'cpdf_lineto'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_moveto'</span><span class="sy0">,</span><span class="st_h">'cpdf_newpath'</span><span class="sy0">,</span><span class="st_h">'cpdf_open'</span><span class="sy0">,</span><span class="st_h">'cpdf_output_buffer'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_page_init'</span><span class="sy0">,</span><span class="st_h">'cpdf_rect'</span><span class="sy0">,</span><span class="st_h">'cpdf_restore'</span><span class="sy0">,</span><span class="st_h">'cpdf_rlineto'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_rmoveto'</span><span class="sy0">,</span><span class="st_h">'cpdf_rotate'</span><span class="sy0">,</span><span class="st_h">'cpdf_rotate_text'</span><span class="sy0">,</span><span class="st_h">'cpdf_save'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_save_to_file'</span><span class="sy0">,</span><span class="st_h">'cpdf_scale'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_action_url'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_char_spacing'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_creator'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_current_page'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_font'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_font_directories'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_font_map_file'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_horiz_scaling'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_keywords'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_leading'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_page_animation'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_subject'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_text_matrix'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_text_pos'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_text_rendering'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_text_rise'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_title'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_set_viewer_preferences'</span><span class="sy0">,</span><span class="st_h">'cpdf_set_word_spacing'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_setdash'</span><span class="sy0">,</span><span class="st_h">'cpdf_setflat'</span><span class="sy0">,</span><span class="st_h">'cpdf_setgray'</span><span class="sy0">,</span><span class="st_h">'cpdf_setgray_fill'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_setgray_stroke'</span><span class="sy0">,</span><span class="st_h">'cpdf_setlinecap'</span><span class="sy0">,</span><span class="st_h">'cpdf_setlinejoin'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_setlinewidth'</span><span class="sy0">,</span><span class="st_h">'cpdf_setmiterlimit'</span><span class="sy0">,</span><span class="st_h">'cpdf_setrgbcolor'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_setrgbcolor_fill'</span><span class="sy0">,</span><span class="st_h">'cpdf_setrgbcolor_stroke'</span><span class="sy0">,</span><span class="st_h">'cpdf_show'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_show_xy'</span><span class="sy0">,</span><span class="st_h">'cpdf_stringwidth'</span><span class="sy0">,</span><span class="st_h">'cpdf_stroke'</span><span class="sy0">,</span><span class="st_h">'cpdf_text'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cpdf_translate'</span><span class="sy0">,</span><span class="st_h">'crack_check'</span><span class="sy0">,</span><span class="st_h">'crack_closedict'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'crack_getlastmessage'</span><span class="sy0">,</span><span class="st_h">'crack_opendict'</span><span class="sy0">,</span><span class="st_h">'crc32'</span><span class="sy0">,</span><span class="st_h">'create_function'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'crypt'</span><span class="sy0">,</span><span class="st_h">'ctype_alnum'</span><span class="sy0">,</span><span class="st_h">'ctype_alpha'</span><span class="sy0">,</span><span class="st_h">'ctype_cntrl'</span><span class="sy0">,</span><span class="st_h">'ctype_digit'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ctype_graph'</span><span class="sy0">,</span><span class="st_h">'ctype_lower'</span><span class="sy0">,</span><span class="st_h">'ctype_print'</span><span class="sy0">,</span><span class="st_h">'ctype_punct'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ctype_space'</span><span class="sy0">,</span><span class="st_h">'ctype_upper'</span><span class="sy0">,</span><span class="st_h">'ctype_xdigit'</span><span class="sy0">,</span><span class="st_h">'curl_close'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'curl_copy_handle'</span><span class="sy0">,</span><span class="st_h">'curl_errno'</span><span class="sy0">,</span><span class="st_h">'curl_error'</span><span class="sy0">,</span><span class="st_h">'curl_exec'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'curl_getinfo'</span><span class="sy0">,</span><span class="st_h">'curl_init'</span><span class="sy0">,</span><span class="st_h">'curl_multi_add_handle'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'curl_multi_close'</span><span class="sy0">,</span><span class="st_h">'curl_multi_exec'</span><span class="sy0">,</span><span class="st_h">'curl_multi_getcontent'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'curl_multi_info_read'</span><span class="sy0">,</span><span class="st_h">'curl_multi_init'</span><span class="sy0">,</span><span class="st_h">'curl_multi_remove_handle'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'curl_multi_select'</span><span class="sy0">,</span><span class="st_h">'curl_setopt'</span><span class="sy0">,</span><span class="st_h">'curl_setopt_array'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'curl_version'</span><span class="sy0">,</span><span class="st_h">'current'</span><span class="sy0">,</span><span class="st_h">'cvsclient_connect'</span><span class="sy0">,</span><span class="st_h">'cvsclient_log'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'cvsclient_login'</span><span class="sy0">,</span><span class="st_h">'cvsclient_retrieve'</span><span class="sy0">,</span><span class="st_h">'date'</span><span class="sy0">,</span><span class="st_h">'date_create'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'date_date_set'</span><span class="sy0">,</span><span class="st_h">'date_default_timezone_get'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'date_default_timezone_set'</span><span class="sy0">,</span><span class="st_h">'date_format'</span><span class="sy0">,</span><span class="st_h">'date_isodate_set'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'date_modify'</span><span class="sy0">,</span><span class="st_h">'date_offset_get'</span><span class="sy0">,</span><span class="st_h">'date_parse'</span><span class="sy0">,</span><span class="st_h">'date_sun_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'date_sunrise'</span><span class="sy0">,</span><span class="st_h">'date_sunset'</span><span class="sy0">,</span><span class="st_h">'date_time_set'</span><span class="sy0">,</span><span class="st_h">'date_timezone_get'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'date_timezone_set'</span><span class="sy0">,</span><span class="st_h">'db_id_list'</span><span class="sy0">,</span><span class="st_h">'dba_close'</span><span class="sy0">,</span><span class="st_h">'dba_delete'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dba_exists'</span><span class="sy0">,</span><span class="st_h">'dba_fetch'</span><span class="sy0">,</span><span class="st_h">'dba_firstkey'</span><span class="sy0">,</span><span class="st_h">'dba_handlers'</span><span class="sy0">,</span><span class="st_h">'dba_insert'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dba_key_split'</span><span class="sy0">,</span><span class="st_h">'dba_list'</span><span class="sy0">,</span><span class="st_h">'dba_nextkey'</span><span class="sy0">,</span><span class="st_h">'dba_open'</span><span class="sy0">,</span><span class="st_h">'dba_optimize'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dba_popen'</span><span class="sy0">,</span><span class="st_h">'dba_replace'</span><span class="sy0">,</span><span class="st_h">'dba_sync'</span><span class="sy0">,</span><span class="st_h">'dbase_add_record'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbase_close'</span><span class="sy0">,</span><span class="st_h">'dbase_create'</span><span class="sy0">,</span><span class="st_h">'dbase_delete_record'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbase_get_header_info'</span><span class="sy0">,</span><span class="st_h">'dbase_get_record'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbase_get_record_with_names'</span><span class="sy0">,</span><span class="st_h">'dbase_numfields'</span><span class="sy0">,</span><span class="st_h">'dbase_numrecords'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbase_open'</span><span class="sy0">,</span><span class="st_h">'dbase_pack'</span><span class="sy0">,</span><span class="st_h">'dbase_replace_record'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbg_get_all_contexts'</span><span class="sy0">,</span><span class="st_h">'dbg_get_all_module_names'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbg_get_all_source_lines'</span><span class="sy0">,</span><span class="st_h">'dbg_get_context_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbg_get_module_name'</span><span class="sy0">,</span><span class="st_h">'dbg_get_profiler_results'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbg_get_source_context'</span><span class="sy0">,</span><span class="st_h">'dblist'</span><span class="sy0">,</span><span class="st_h">'dbmclose'</span><span class="sy0">,</span><span class="st_h">'dbmdelete'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbmexists'</span><span class="sy0">,</span><span class="st_h">'dbmfetch'</span><span class="sy0">,</span><span class="st_h">'dbmfirstkey'</span><span class="sy0">,</span><span class="st_h">'dbminsert'</span><span class="sy0">,</span><span class="st_h">'dbmnextkey'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbmopen'</span><span class="sy0">,</span><span class="st_h">'dbmreplace'</span><span class="sy0">,</span><span class="st_h">'dbx_close'</span><span class="sy0">,</span><span class="st_h">'dbx_compare'</span><span class="sy0">,</span><span class="st_h">'dbx_connect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbx_error'</span><span class="sy0">,</span><span class="st_h">'dbx_escape_string'</span><span class="sy0">,</span><span class="st_h">'dbx_fetch_row'</span><span class="sy0">,</span><span class="st_h">'dbx_query'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dbx_sort'</span><span class="sy0">,</span><span class="st_h">'dcgettext'</span><span class="sy0">,</span><span class="st_h">'dcngettext'</span><span class="sy0">,</span><span class="st_h">'deaggregate'</span><span class="sy0">,</span><span class="st_h">'debug_backtrace'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'debug_zval_dump'</span><span class="sy0">,</span><span class="st_h">'debugbreak'</span><span class="sy0">,</span><span class="st_h">'decbin'</span><span class="sy0">,</span><span class="st_h">'dechex'</span><span class="sy0">,</span><span class="st_h">'decoct'</span><span class="sy0">,</span><span class="st_h">'define'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'defined'</span><span class="sy0">,</span><span class="st_h">'define_syslog_variables'</span><span class="sy0">,</span><span class="st_h">'deg2rad'</span><span class="sy0">,</span><span class="st_h">'dgettext'</span><span class="sy0">,</span><span class="st_h">'die'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dio_close'</span><span class="sy0">,</span><span class="st_h">'dio_open'</span><span class="sy0">,</span><span class="st_h">'dio_read'</span><span class="sy0">,</span><span class="st_h">'dio_seek'</span><span class="sy0">,</span><span class="st_h">'dio_stat'</span><span class="sy0">,</span><span class="st_h">'dio_write'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'dir'</span><span class="sy0">,</span><span class="st_h">'dirname'</span><span class="sy0">,</span><span class="st_h">'disk_free_space'</span><span class="sy0">,</span><span class="st_h">'disk_total_space'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'diskfreespace'</span><span class="sy0">,</span><span class="st_h">'dl'</span><span class="sy0">,</span><span class="st_h">'dngettext'</span><span class="sy0">,</span><span class="st_h">'docblock_token_name'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'docblock_tokenize'</span><span class="sy0">,</span><span class="st_h">'dom_import_simplexml'</span><span class="sy0">,</span><span class="st_h">'domxml_add_root'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_attributes'</span><span class="sy0">,</span><span class="st_h">'domxml_children'</span><span class="sy0">,</span><span class="st_h">'domxml_doc_add_root'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_doc_document_element'</span><span class="sy0">,</span><span class="st_h">'domxml_doc_get_element_by_id'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_doc_get_elements_by_tagname'</span><span class="sy0">,</span><span class="st_h">'domxml_doc_get_root'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_doc_set_root'</span><span class="sy0">,</span><span class="st_h">'domxml_doc_validate'</span><span class="sy0">,</span><span class="st_h">'domxml_doc_xinclude'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_dump_mem'</span><span class="sy0">,</span><span class="st_h">'domxml_dump_mem_file'</span><span class="sy0">,</span><span class="st_h">'domxml_dump_node'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_dumpmem'</span><span class="sy0">,</span><span class="st_h">'domxml_elem_get_attribute'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_elem_set_attribute'</span><span class="sy0">,</span><span class="st_h">'domxml_get_attribute'</span><span class="sy0">,</span><span class="st_h">'domxml_getattr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_html_dump_mem'</span><span class="sy0">,</span><span class="st_h">'domxml_new_child'</span><span class="sy0">,</span><span class="st_h">'domxml_new_doc'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_new_xmldoc'</span><span class="sy0">,</span><span class="st_h">'domxml_node'</span><span class="sy0">,</span><span class="st_h">'domxml_node_add_namespace'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_node_attributes'</span><span class="sy0">,</span><span class="st_h">'domxml_node_children'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_node_get_content'</span><span class="sy0">,</span><span class="st_h">'domxml_node_has_attributes'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_node_new_child'</span><span class="sy0">,</span><span class="st_h">'domxml_node_set_content'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_node_set_namespace'</span><span class="sy0">,</span><span class="st_h">'domxml_node_unlink_node'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_open_file'</span><span class="sy0">,</span><span class="st_h">'domxml_open_mem'</span><span class="sy0">,</span><span class="st_h">'domxml_parser'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_add_chunk'</span><span class="sy0">,</span><span class="st_h">'domxml_parser_cdata_section'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_characters'</span><span class="sy0">,</span><span class="st_h">'domxml_parser_comment'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_end'</span><span class="sy0">,</span><span class="st_h">'domxml_parser_end_document'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_end_element'</span><span class="sy0">,</span><span class="st_h">'domxml_parser_entity_reference'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_get_document'</span><span class="sy0">,</span><span class="st_h">'domxml_parser_namespace_decl'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_processing_instruction'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_parser_start_document'</span><span class="sy0">,</span><span class="st_h">'domxml_parser_start_element'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_root'</span><span class="sy0">,</span><span class="st_h">'domxml_set_attribute'</span><span class="sy0">,</span><span class="st_h">'domxml_setattr'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_substitute_entities_default'</span><span class="sy0">,</span><span class="st_h">'domxml_unlink_node'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'domxml_version'</span><span class="sy0">,</span><span class="st_h">'domxml_xmltree'</span><span class="sy0">,</span><span class="st_h">'doubleval'</span><span class="sy0">,</span><span class="st_h">'each'</span><span class="sy0">,</span><span class="st_h">'easter_date'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'easter_days'</span><span class="sy0">,</span><span class="st_h">'empty'</span><span class="sy0">,</span><span class="st_h">'end'</span><span class="sy0">,</span><span class="st_h">'ereg'</span><span class="sy0">,</span><span class="st_h">'ereg_replace'</span><span class="sy0">,</span><span class="st_h">'eregi'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'eregi_replace'</span><span class="sy0">,</span><span class="st_h">'error_get_last'</span><span class="sy0">,</span><span class="st_h">'error_log'</span><span class="sy0">,</span><span class="st_h">'error_reporting'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'escapeshellarg'</span><span class="sy0">,</span><span class="st_h">'escapeshellcmd'</span><span class="sy0">,</span><span class="st_h">'eval'</span><span class="sy0">,</span><span class="st_h">'event_deschedule'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'event_dispatch'</span><span class="sy0">,</span><span class="st_h">'event_free'</span><span class="sy0">,</span><span class="st_h">'event_handle_signal'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'event_have_events'</span><span class="sy0">,</span><span class="st_h">'event_init'</span><span class="sy0">,</span><span class="st_h">'event_new'</span><span class="sy0">,</span><span class="st_h">'event_pending'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'event_priority_set'</span><span class="sy0">,</span><span class="st_h">'event_schedule'</span><span class="sy0">,</span><span class="st_h">'event_set'</span><span class="sy0">,</span><span class="st_h">'event_timeout'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'exec'</span><span class="sy0">,</span><span class="st_h">'exif_imagetype'</span><span class="sy0">,</span><span class="st_h">'exif_read_data'</span><span class="sy0">,</span><span class="st_h">'exif_tagname'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'exif_thumbnail'</span><span class="sy0">,</span><span class="st_h">'exit'</span><span class="sy0">,</span><span class="st_h">'exp'</span><span class="sy0">,</span><span class="st_h">'explode'</span><span class="sy0">,</span><span class="st_h">'expm1'</span><span class="sy0">,</span><span class="st_h">'extension_loaded'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'extract'</span><span class="sy0">,</span><span class="st_h">'ezmlm_hash'</span><span class="sy0">,</span><span class="st_h">'fbird_add_user'</span><span class="sy0">,</span><span class="st_h">'fbird_affected_rows'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_backup'</span><span class="sy0">,</span><span class="st_h">'fbird_blob_add'</span><span class="sy0">,</span><span class="st_h">'fbird_blob_cancel'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_blob_close'</span><span class="sy0">,</span><span class="st_h">'fbird_blob_create'</span><span class="sy0">,</span><span class="st_h">'fbird_blob_echo'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_blob_get'</span><span class="sy0">,</span><span class="st_h">'fbird_blob_import'</span><span class="sy0">,</span><span class="st_h">'fbird_blob_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_blob_open'</span><span class="sy0">,</span><span class="st_h">'fbird_close'</span><span class="sy0">,</span><span class="st_h">'fbird_commit'</span><span class="sy0">,</span><span class="st_h">'fbird_commit_ret'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_connect'</span><span class="sy0">,</span><span class="st_h">'fbird_db_info'</span><span class="sy0">,</span><span class="st_h">'fbird_delete_user'</span><span class="sy0">,</span><span class="st_h">'fbird_drop_db'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_errcode'</span><span class="sy0">,</span><span class="st_h">'fbird_errmsg'</span><span class="sy0">,</span><span class="st_h">'fbird_execute'</span><span class="sy0">,</span><span class="st_h">'fbird_fetch_assoc'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_fetch_object'</span><span class="sy0">,</span><span class="st_h">'fbird_fetch_row'</span><span class="sy0">,</span><span class="st_h">'fbird_field_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_free_event_handler'</span><span class="sy0">,</span><span class="st_h">'fbird_free_query'</span><span class="sy0">,</span><span class="st_h">'fbird_free_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_gen_id'</span><span class="sy0">,</span><span class="st_h">'fbird_maintain_db'</span><span class="sy0">,</span><span class="st_h">'fbird_modify_user'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_name_result'</span><span class="sy0">,</span><span class="st_h">'fbird_num_fields'</span><span class="sy0">,</span><span class="st_h">'fbird_num_params'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_param_info'</span><span class="sy0">,</span><span class="st_h">'fbird_pconnect'</span><span class="sy0">,</span><span class="st_h">'fbird_prepare'</span><span class="sy0">,</span><span class="st_h">'fbird_query'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_restore'</span><span class="sy0">,</span><span class="st_h">'fbird_rollback'</span><span class="sy0">,</span><span class="st_h">'fbird_rollback_ret'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_server_info'</span><span class="sy0">,</span><span class="st_h">'fbird_service_attach'</span><span class="sy0">,</span><span class="st_h">'fbird_service_detach'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fbird_set_event_handler'</span><span class="sy0">,</span><span class="st_h">'fbird_trans'</span><span class="sy0">,</span><span class="st_h">'fbird_wait_event'</span><span class="sy0">,</span><span class="st_h">'fclose'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_add_doc_javascript'</span><span class="sy0">,</span><span class="st_h">'fdf_add_template'</span><span class="sy0">,</span><span class="st_h">'fdf_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_create'</span><span class="sy0">,</span><span class="st_h">'fdf_enum_values'</span><span class="sy0">,</span><span class="st_h">'fdf_errno'</span><span class="sy0">,</span><span class="st_h">'fdf_error'</span><span class="sy0">,</span><span class="st_h">'fdf_get_ap'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_get_attachment'</span><span class="sy0">,</span><span class="st_h">'fdf_get_encoding'</span><span class="sy0">,</span><span class="st_h">'fdf_get_file'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_get_flags'</span><span class="sy0">,</span><span class="st_h">'fdf_get_opt'</span><span class="sy0">,</span><span class="st_h">'fdf_get_status'</span><span class="sy0">,</span><span class="st_h">'fdf_get_value'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_get_version'</span><span class="sy0">,</span><span class="st_h">'fdf_header'</span><span class="sy0">,</span><span class="st_h">'fdf_next_field_name'</span><span class="sy0">,</span><span class="st_h">'fdf_open'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_open_string'</span><span class="sy0">,</span><span class="st_h">'fdf_remove_item'</span><span class="sy0">,</span><span class="st_h">'fdf_save'</span><span class="sy0">,</span><span class="st_h">'fdf_save_string'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_set_ap'</span><span class="sy0">,</span><span class="st_h">'fdf_set_encoding'</span><span class="sy0">,</span><span class="st_h">'fdf_set_file'</span><span class="sy0">,</span><span class="st_h">'fdf_set_flags'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_set_javascript_action'</span><span class="sy0">,</span><span class="st_h">'fdf_set_on_import_javascript'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_set_opt'</span><span class="sy0">,</span><span class="st_h">'fdf_set_status'</span><span class="sy0">,</span><span class="st_h">'fdf_set_submit_form_action'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fdf_set_target_frame'</span><span class="sy0">,</span><span class="st_h">'fdf_set_value'</span><span class="sy0">,</span><span class="st_h">'fdf_set_version'</span><span class="sy0">,</span><span class="st_h">'feof'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fflush'</span><span class="sy0">,</span><span class="st_h">'fgetc'</span><span class="sy0">,</span><span class="st_h">'fgetcsv'</span><span class="sy0">,</span><span class="st_h">'fgets'</span><span class="sy0">,</span><span class="st_h">'fgetss'</span><span class="sy0">,</span><span class="st_h">'file'</span><span class="sy0">,</span><span class="st_h">'file_exists'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'file_get_contents'</span><span class="sy0">,</span><span class="st_h">'file_put_contents'</span><span class="sy0">,</span><span class="st_h">'fileatime'</span><span class="sy0">,</span><span class="st_h">'filectime'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'filegroup'</span><span class="sy0">,</span><span class="st_h">'fileinode'</span><span class="sy0">,</span><span class="st_h">'filemtime'</span><span class="sy0">,</span><span class="st_h">'fileowner'</span><span class="sy0">,</span><span class="st_h">'fileperms'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'filepro'</span><span class="sy0">,</span><span class="st_h">'filepro_fieldcount'</span><span class="sy0">,</span><span class="st_h">'filepro_fieldname'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'filepro_fieldtype'</span><span class="sy0">,</span><span class="st_h">'filepro_fieldwidth'</span><span class="sy0">,</span><span class="st_h">'filepro_retrieve'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'filepro_rowcount'</span><span class="sy0">,</span><span class="st_h">'filesize'</span><span class="sy0">,</span><span class="st_h">'filetype'</span><span class="sy0">,</span><span class="st_h">'filter_has_var'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'filter_id'</span><span class="sy0">,</span><span class="st_h">'filter_input'</span><span class="sy0">,</span><span class="st_h">'filter_input_array'</span><span class="sy0">,</span><span class="st_h">'filter_list'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'filter_var'</span><span class="sy0">,</span><span class="st_h">'filter_var_array'</span><span class="sy0">,</span><span class="st_h">'finfo_buffer'</span><span class="sy0">,</span><span class="st_h">'finfo_close'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'finfo_file'</span><span class="sy0">,</span><span class="st_h">'finfo_open'</span><span class="sy0">,</span><span class="st_h">'finfo_set_flags'</span><span class="sy0">,</span><span class="st_h">'floatval'</span><span class="sy0">,</span><span class="st_h">'flock'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'floor'</span><span class="sy0">,</span><span class="st_h">'flush'</span><span class="sy0">,</span><span class="st_h">'fmod'</span><span class="sy0">,</span><span class="st_h">'fnmatch'</span><span class="sy0">,</span><span class="st_h">'fopen'</span><span class="sy0">,</span><span class="st_h">'fpassthru'</span><span class="sy0">,</span><span class="st_h">'fprintf'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fputcsv'</span><span class="sy0">,</span><span class="st_h">'fputs'</span><span class="sy0">,</span><span class="st_h">'fread'</span><span class="sy0">,</span><span class="st_h">'frenchtojd'</span><span class="sy0">,</span><span class="st_h">'fribidi_charset_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fribidi_get_charsets'</span><span class="sy0">,</span><span class="st_h">'fribidi_log2vis'</span><span class="sy0">,</span><span class="st_h">'fscanf'</span><span class="sy0">,</span><span class="st_h">'fseek'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'fsockopen'</span><span class="sy0">,</span><span class="st_h">'fstat'</span><span class="sy0">,</span><span class="st_h">'ftell'</span><span class="sy0">,</span><span class="st_h">'ftok'</span><span class="sy0">,</span><span class="st_h">'ftp_alloc'</span><span class="sy0">,</span><span class="st_h">'ftp_cdup'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_chdir'</span><span class="sy0">,</span><span class="st_h">'ftp_chmod'</span><span class="sy0">,</span><span class="st_h">'ftp_close'</span><span class="sy0">,</span><span class="st_h">'ftp_connect'</span><span class="sy0">,</span><span class="st_h">'ftp_delete'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_exec'</span><span class="sy0">,</span><span class="st_h">'ftp_fget'</span><span class="sy0">,</span><span class="st_h">'ftp_fput'</span><span class="sy0">,</span><span class="st_h">'ftp_get'</span><span class="sy0">,</span><span class="st_h">'ftp_get_option'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_login'</span><span class="sy0">,</span><span class="st_h">'ftp_mdtm'</span><span class="sy0">,</span><span class="st_h">'ftp_mkdir'</span><span class="sy0">,</span><span class="st_h">'ftp_nb_continue'</span><span class="sy0">,</span><span class="st_h">'ftp_nb_fget'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_nb_fput'</span><span class="sy0">,</span><span class="st_h">'ftp_nb_get'</span><span class="sy0">,</span><span class="st_h">'ftp_nb_put'</span><span class="sy0">,</span><span class="st_h">'ftp_nlist'</span><span class="sy0">,</span><span class="st_h">'ftp_pasv'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_put'</span><span class="sy0">,</span><span class="st_h">'ftp_pwd'</span><span class="sy0">,</span><span class="st_h">'ftp_quit'</span><span class="sy0">,</span><span class="st_h">'ftp_raw'</span><span class="sy0">,</span><span class="st_h">'ftp_rawlist'</span><span class="sy0">,</span><span class="st_h">'ftp_rename'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_rmdir'</span><span class="sy0">,</span><span class="st_h">'ftp_set_option'</span><span class="sy0">,</span><span class="st_h">'ftp_site'</span><span class="sy0">,</span><span class="st_h">'ftp_size'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ftp_ssl_connect'</span><span class="sy0">,</span><span class="st_h">'ftp_systype'</span><span class="sy0">,</span><span class="st_h">'ftruncate'</span><span class="sy0">,</span><span class="st_h">'function_exists'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'func_get_arg'</span><span class="sy0">,</span><span class="st_h">'func_get_args'</span><span class="sy0">,</span><span class="st_h">'func_num_args'</span><span class="sy0">,</span><span class="st_h">'fwrite'</span><span class="sy0">,</span><span class="st_h">'gd_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'getallheaders'</span><span class="sy0">,</span><span class="st_h">'getcwd'</span><span class="sy0">,</span><span class="st_h">'getdate'</span><span class="sy0">,</span><span class="st_h">'getenv'</span><span class="sy0">,</span><span class="st_h">'gethostbyaddr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gethostbyname'</span><span class="sy0">,</span><span class="st_h">'gethostbynamel'</span><span class="sy0">,</span><span class="st_h">'getimagesize'</span><span class="sy0">,</span><span class="st_h">'getlastmod'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'getmxrr'</span><span class="sy0">,</span><span class="st_h">'getmygid'</span><span class="sy0">,</span><span class="st_h">'getmyinode'</span><span class="sy0">,</span><span class="st_h">'getmypid'</span><span class="sy0">,</span><span class="st_h">'getmyuid'</span><span class="sy0">,</span><span class="st_h">'getopt'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'getprotobyname'</span><span class="sy0">,</span><span class="st_h">'getprotobynumber'</span><span class="sy0">,</span><span class="st_h">'getrandmax'</span><span class="sy0">,</span><span class="st_h">'getrusage'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'getservbyname'</span><span class="sy0">,</span><span class="st_h">'getservbyport'</span><span class="sy0">,</span><span class="st_h">'gettext'</span><span class="sy0">,</span><span class="st_h">'gettimeofday'</span><span class="sy0">,</span><span class="st_h">'gettype'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_browser'</span><span class="sy0">,</span><span class="st_h">'get_cfg_var'</span><span class="sy0">,</span><span class="st_h">'get_class'</span><span class="sy0">,</span><span class="st_h">'get_class_methods'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_class_vars'</span><span class="sy0">,</span><span class="st_h">'get_current_user'</span><span class="sy0">,</span><span class="st_h">'get_declared_classes'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_defined_constants'</span><span class="sy0">,</span><span class="st_h">'get_defined_functions'</span><span class="sy0">,</span><span class="st_h">'get_defined_vars'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_extension_funcs'</span><span class="sy0">,</span><span class="st_h">'get_headers'</span><span class="sy0">,</span><span class="st_h">'get_html_translation_table'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_included_files'</span><span class="sy0">,</span><span class="st_h">'get_include_path'</span><span class="sy0">,</span><span class="st_h">'get_loaded_extensions'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_magic_quotes_gpc'</span><span class="sy0">,</span><span class="st_h">'get_magic_quotes_runtime'</span><span class="sy0">,</span><span class="st_h">'get_meta_tags'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_object_vars'</span><span class="sy0">,</span><span class="st_h">'get_parent_class'</span><span class="sy0">,</span><span class="st_h">'get_required_files'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'get_resource_type'</span><span class="sy0">,</span><span class="st_h">'glob'</span><span class="sy0">,</span><span class="st_h">'gmdate'</span><span class="sy0">,</span><span class="st_h">'gmmktime'</span><span class="sy0">,</span><span class="st_h">'gmp_abs'</span><span class="sy0">,</span><span class="st_h">'gmp_add'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_and'</span><span class="sy0">,</span><span class="st_h">'gmp_clrbit'</span><span class="sy0">,</span><span class="st_h">'gmp_cmp'</span><span class="sy0">,</span><span class="st_h">'gmp_com'</span><span class="sy0">,</span><span class="st_h">'gmp_div'</span><span class="sy0">,</span><span class="st_h">'gmp_div_q'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_div_qr'</span><span class="sy0">,</span><span class="st_h">'gmp_div_r'</span><span class="sy0">,</span><span class="st_h">'gmp_divexact'</span><span class="sy0">,</span><span class="st_h">'gmp_fact'</span><span class="sy0">,</span><span class="st_h">'gmp_gcd'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_gcdext'</span><span class="sy0">,</span><span class="st_h">'gmp_hamdist'</span><span class="sy0">,</span><span class="st_h">'gmp_init'</span><span class="sy0">,</span><span class="st_h">'gmp_intval'</span><span class="sy0">,</span><span class="st_h">'gmp_invert'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_jacobi'</span><span class="sy0">,</span><span class="st_h">'gmp_legendre'</span><span class="sy0">,</span><span class="st_h">'gmp_mod'</span><span class="sy0">,</span><span class="st_h">'gmp_mul'</span><span class="sy0">,</span><span class="st_h">'gmp_neg'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_nextprime'</span><span class="sy0">,</span><span class="st_h">'gmp_or'</span><span class="sy0">,</span><span class="st_h">'gmp_perfect_square'</span><span class="sy0">,</span><span class="st_h">'gmp_popcount'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_pow'</span><span class="sy0">,</span><span class="st_h">'gmp_powm'</span><span class="sy0">,</span><span class="st_h">'gmp_prob_prime'</span><span class="sy0">,</span><span class="st_h">'gmp_random'</span><span class="sy0">,</span><span class="st_h">'gmp_scan0'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_scan1'</span><span class="sy0">,</span><span class="st_h">'gmp_setbit'</span><span class="sy0">,</span><span class="st_h">'gmp_sign'</span><span class="sy0">,</span><span class="st_h">'gmp_sqrt'</span><span class="sy0">,</span><span class="st_h">'gmp_sqrtrem'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gmp_strval'</span><span class="sy0">,</span><span class="st_h">'gmp_sub'</span><span class="sy0">,</span><span class="st_h">'gmp_xor'</span><span class="sy0">,</span><span class="st_h">'gmstrftime'</span><span class="sy0">,</span><span class="st_h">'gopher_parsedir'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gregoriantojd'</span><span class="sy0">,</span><span class="st_h">'gzclose'</span><span class="sy0">,</span><span class="st_h">'gzcompress'</span><span class="sy0">,</span><span class="st_h">'gzdeflate'</span><span class="sy0">,</span><span class="st_h">'gzencode'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gzeof'</span><span class="sy0">,</span><span class="st_h">'gzfile'</span><span class="sy0">,</span><span class="st_h">'gzgetc'</span><span class="sy0">,</span><span class="st_h">'gzgets'</span><span class="sy0">,</span><span class="st_h">'gzgetss'</span><span class="sy0">,</span><span class="st_h">'gzinflate'</span><span class="sy0">,</span><span class="st_h">'gzopen'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gzpassthru'</span><span class="sy0">,</span><span class="st_h">'gzputs'</span><span class="sy0">,</span><span class="st_h">'gzread'</span><span class="sy0">,</span><span class="st_h">'gzrewind'</span><span class="sy0">,</span><span class="st_h">'gzseek'</span><span class="sy0">,</span><span class="st_h">'gztell'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'gzuncompress'</span><span class="sy0">,</span><span class="st_h">'gzwrite'</span><span class="sy0">,</span><span class="st_h">'hash'</span><span class="sy0">,</span><span class="st_h">'hash_algos'</span><span class="sy0">,</span><span class="st_h">'hash_file'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'hash_final'</span><span class="sy0">,</span><span class="st_h">'hash_hmac'</span><span class="sy0">,</span><span class="st_h">'hash_hmac_file'</span><span class="sy0">,</span><span class="st_h">'hash_init'</span><span class="sy0">,</span><span class="st_h">'hash_update'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'hash_update_file'</span><span class="sy0">,</span><span class="st_h">'hash_update_stream'</span><span class="sy0">,</span><span class="st_h">'header'</span><span class="sy0">,</span><span class="st_h">'headers_list'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'headers_sent'</span><span class="sy0">,</span><span class="st_h">'hebrev'</span><span class="sy0">,</span><span class="st_h">'hebrevc'</span><span class="sy0">,</span><span class="st_h">'hexdec'</span><span class="sy0">,</span><span class="st_h">'highlight_file'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'highlight_string'</span><span class="sy0">,</span><span class="st_h">'html_doc'</span><span class="sy0">,</span><span class="st_h">'html_doc_file'</span><span class="sy0">,</span><span class="st_h">'html_entity_decode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'htmlentities'</span><span class="sy0">,</span><span class="st_h">'htmlspecialchars'</span><span class="sy0">,</span><span class="st_h">'htmlspecialchars_decode'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_build_cookie'</span><span class="sy0">,</span><span class="st_h">'http_build_query'</span><span class="sy0">,</span><span class="st_h">'http_build_str'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_build_url'</span><span class="sy0">,</span><span class="st_h">'http_cache_etag'</span><span class="sy0">,</span><span class="st_h">'http_cache_last_modified'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_chunked_decode'</span><span class="sy0">,</span><span class="st_h">'http_date'</span><span class="sy0">,</span><span class="st_h">'http_deflate'</span><span class="sy0">,</span><span class="st_h">'http_get'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_get_request_body'</span><span class="sy0">,</span><span class="st_h">'http_get_request_body_stream'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_get_request_headers'</span><span class="sy0">,</span><span class="st_h">'http_head'</span><span class="sy0">,</span><span class="st_h">'http_inflate'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_match_etag'</span><span class="sy0">,</span><span class="st_h">'http_match_modified'</span><span class="sy0">,</span><span class="st_h">'http_match_request_header'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_negotiate_charset'</span><span class="sy0">,</span><span class="st_h">'http_negotiate_content_type'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_negotiate_language'</span><span class="sy0">,</span><span class="st_h">'http_parse_cookie'</span><span class="sy0">,</span><span class="st_h">'http_parse_headers'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_parse_message'</span><span class="sy0">,</span><span class="st_h">'http_parse_params'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_persistent_handles_clean'</span><span class="sy0">,</span><span class="st_h">'http_persistent_handles_count'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_persistent_handles_ident'</span><span class="sy0">,</span><span class="st_h">'http_post_data'</span><span class="sy0">,</span><span class="st_h">'http_post_fields'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_put_data'</span><span class="sy0">,</span><span class="st_h">'http_put_file'</span><span class="sy0">,</span><span class="st_h">'http_put_stream'</span><span class="sy0">,</span><span class="st_h">'http_redirect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_request'</span><span class="sy0">,</span><span class="st_h">'http_request_body_encode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_request_method_exists'</span><span class="sy0">,</span><span class="st_h">'http_request_method_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_request_method_register'</span><span class="sy0">,</span><span class="st_h">'http_request_method_unregister'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_send_content_disposition'</span><span class="sy0">,</span><span class="st_h">'http_send_content_type'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_send_data'</span><span class="sy0">,</span><span class="st_h">'http_send_file'</span><span class="sy0">,</span><span class="st_h">'http_send_last_modified'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_send_status'</span><span class="sy0">,</span><span class="st_h">'http_send_stream'</span><span class="sy0">,</span><span class="st_h">'http_support'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'http_throttle'</span><span class="sy0">,</span><span class="st_h">'hypot'</span><span class="sy0">,</span><span class="st_h">'i18n_convert'</span><span class="sy0">,</span><span class="st_h">'i18n_discover_encoding'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'i18n_http_input'</span><span class="sy0">,</span><span class="st_h">'i18n_http_output'</span><span class="sy0">,</span><span class="st_h">'i18n_internal_encoding'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'i18n_ja_jp_hantozen'</span><span class="sy0">,</span><span class="st_h">'i18n_mime_header_decode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'i18n_mime_header_encode'</span><span class="sy0">,</span><span class="st_h">'ibase_add_user'</span><span class="sy0">,</span><span class="st_h">'ibase_affected_rows'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_backup'</span><span class="sy0">,</span><span class="st_h">'ibase_blob_add'</span><span class="sy0">,</span><span class="st_h">'ibase_blob_cancel'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_blob_close'</span><span class="sy0">,</span><span class="st_h">'ibase_blob_create'</span><span class="sy0">,</span><span class="st_h">'ibase_blob_echo'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_blob_get'</span><span class="sy0">,</span><span class="st_h">'ibase_blob_import'</span><span class="sy0">,</span><span class="st_h">'ibase_blob_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_blob_open'</span><span class="sy0">,</span><span class="st_h">'ibase_close'</span><span class="sy0">,</span><span class="st_h">'ibase_commit'</span><span class="sy0">,</span><span class="st_h">'ibase_commit_ret'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_connect'</span><span class="sy0">,</span><span class="st_h">'ibase_db_info'</span><span class="sy0">,</span><span class="st_h">'ibase_delete_user'</span><span class="sy0">,</span><span class="st_h">'ibase_drop_db'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_errcode'</span><span class="sy0">,</span><span class="st_h">'ibase_errmsg'</span><span class="sy0">,</span><span class="st_h">'ibase_execute'</span><span class="sy0">,</span><span class="st_h">'ibase_fetch_assoc'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_fetch_object'</span><span class="sy0">,</span><span class="st_h">'ibase_fetch_row'</span><span class="sy0">,</span><span class="st_h">'ibase_field_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_free_event_handler'</span><span class="sy0">,</span><span class="st_h">'ibase_free_query'</span><span class="sy0">,</span><span class="st_h">'ibase_free_result'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_gen_id'</span><span class="sy0">,</span><span class="st_h">'ibase_maintain_db'</span><span class="sy0">,</span><span class="st_h">'ibase_modify_user'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_name_result'</span><span class="sy0">,</span><span class="st_h">'ibase_num_fields'</span><span class="sy0">,</span><span class="st_h">'ibase_num_params'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_param_info'</span><span class="sy0">,</span><span class="st_h">'ibase_pconnect'</span><span class="sy0">,</span><span class="st_h">'ibase_prepare'</span><span class="sy0">,</span><span class="st_h">'ibase_query'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_restore'</span><span class="sy0">,</span><span class="st_h">'ibase_rollback'</span><span class="sy0">,</span><span class="st_h">'ibase_rollback_ret'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_server_info'</span><span class="sy0">,</span><span class="st_h">'ibase_service_attach'</span><span class="sy0">,</span><span class="st_h">'ibase_service_detach'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ibase_set_event_handler'</span><span class="sy0">,</span><span class="st_h">'ibase_trans'</span><span class="sy0">,</span><span class="st_h">'ibase_wait_event'</span><span class="sy0">,</span><span class="st_h">'iconv'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'iconv_get_encoding'</span><span class="sy0">,</span><span class="st_h">'iconv_mime_decode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'iconv_mime_decode_headers'</span><span class="sy0">,</span><span class="st_h">'iconv_mime_encode'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'iconv_set_encoding'</span><span class="sy0">,</span><span class="st_h">'iconv_strlen'</span><span class="sy0">,</span><span class="st_h">'iconv_strpos'</span><span class="sy0">,</span><span class="st_h">'iconv_strrpos'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'iconv_substr'</span><span class="sy0">,</span><span class="st_h">'id3_get_frame_long_name'</span><span class="sy0">,</span><span class="st_h">'id3_get_frame_short_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'id3_get_genre_id'</span><span class="sy0">,</span><span class="st_h">'id3_get_genre_list'</span><span class="sy0">,</span><span class="st_h">'id3_get_genre_name'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'id3_get_tag'</span><span class="sy0">,</span><span class="st_h">'id3_get_version'</span><span class="sy0">,</span><span class="st_h">'id3_remove_tag'</span><span class="sy0">,</span><span class="st_h">'id3_set_tag'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'idate'</span><span class="sy0">,</span><span class="st_h">'ignore_user_abort'</span><span class="sy0">,</span><span class="st_h">'image_type_to_extension'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'image_type_to_mime_type'</span><span class="sy0">,</span><span class="st_h">'image2wbmp'</span><span class="sy0">,</span><span class="st_h">'imagealphablending'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imageantialias'</span><span class="sy0">,</span><span class="st_h">'imagearc'</span><span class="sy0">,</span><span class="st_h">'imagechar'</span><span class="sy0">,</span><span class="st_h">'imagecharup'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecolorallocate'</span><span class="sy0">,</span><span class="st_h">'imagecolorallocatealpha'</span><span class="sy0">,</span><span class="st_h">'imagecolorat'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecolorclosest'</span><span class="sy0">,</span><span class="st_h">'imagecolorclosestalpha'</span><span class="sy0">,</span><span class="st_h">'imagecolordeallocate'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecolorexact'</span><span class="sy0">,</span><span class="st_h">'imagecolorexactalpha'</span><span class="sy0">,</span><span class="st_h">'imagecolormatch'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecolorresolve'</span><span class="sy0">,</span><span class="st_h">'imagecolorresolvealpha'</span><span class="sy0">,</span><span class="st_h">'imagecolorset'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecolorsforindex'</span><span class="sy0">,</span><span class="st_h">'imagecolorstotal'</span><span class="sy0">,</span><span class="st_h">'imagecolortransparent'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imageconvolution'</span><span class="sy0">,</span><span class="st_h">'imagecopy'</span><span class="sy0">,</span><span class="st_h">'imagecopymerge'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecopymergegray'</span><span class="sy0">,</span><span class="st_h">'imagecopyresampled'</span><span class="sy0">,</span><span class="st_h">'imagecopyresized'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecreate'</span><span class="sy0">,</span><span class="st_h">'imagecreatefromgd'</span><span class="sy0">,</span><span class="st_h">'imagecreatefromgd2'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecreatefromgd2part'</span><span class="sy0">,</span><span class="st_h">'imagecreatefromgif'</span><span class="sy0">,</span><span class="st_h">'imagecreatefromjpeg'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecreatefrompng'</span><span class="sy0">,</span><span class="st_h">'imagecreatefromstring'</span><span class="sy0">,</span><span class="st_h">'imagecreatefromwbmp'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagecreatefromxbm'</span><span class="sy0">,</span><span class="st_h">'imagecreatetruecolor'</span><span class="sy0">,</span><span class="st_h">'imagedashedline'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagedestroy'</span><span class="sy0">,</span><span class="st_h">'imageellipse'</span><span class="sy0">,</span><span class="st_h">'imagefill'</span><span class="sy0">,</span><span class="st_h">'imagefilledarc'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagefilledellipse'</span><span class="sy0">,</span><span class="st_h">'imagefilledpolygon'</span><span class="sy0">,</span><span class="st_h">'imagefilledrectangle'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagefilltoborder'</span><span class="sy0">,</span><span class="st_h">'imagefilter'</span><span class="sy0">,</span><span class="st_h">'imagefontheight'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagefontwidth'</span><span class="sy0">,</span><span class="st_h">'imageftbbox'</span><span class="sy0">,</span><span class="st_h">'imagefttext'</span><span class="sy0">,</span><span class="st_h">'imagegammacorrect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagegd'</span><span class="sy0">,</span><span class="st_h">'imagegd2'</span><span class="sy0">,</span><span class="st_h">'imagegif'</span><span class="sy0">,</span><span class="st_h">'imagegrabscreen'</span><span class="sy0">,</span><span class="st_h">'imagegrabwindow'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imageinterlace'</span><span class="sy0">,</span><span class="st_h">'imageistruecolor'</span><span class="sy0">,</span><span class="st_h">'imagejpeg'</span><span class="sy0">,</span><span class="st_h">'imagelayereffect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imageline'</span><span class="sy0">,</span><span class="st_h">'imageloadfont'</span><span class="sy0">,</span><span class="st_h">'imagepalettecopy'</span><span class="sy0">,</span><span class="st_h">'imagepng'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagepolygon'</span><span class="sy0">,</span><span class="st_h">'imagepsbbox'</span><span class="sy0">,</span><span class="st_h">'imagepsencodefont'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagepsextendfont'</span><span class="sy0">,</span><span class="st_h">'imagepsfreefont'</span><span class="sy0">,</span><span class="st_h">'imagepsloadfont'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagepsslantfont'</span><span class="sy0">,</span><span class="st_h">'imagepstext'</span><span class="sy0">,</span><span class="st_h">'imagerectangle'</span><span class="sy0">,</span><span class="st_h">'imagerotate'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagesavealpha'</span><span class="sy0">,</span><span class="st_h">'imagesetbrush'</span><span class="sy0">,</span><span class="st_h">'imagesetpixel'</span><span class="sy0">,</span><span class="st_h">'imagesetstyle'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagesetthickness'</span><span class="sy0">,</span><span class="st_h">'imagesettile'</span><span class="sy0">,</span><span class="st_h">'imagestring'</span><span class="sy0">,</span><span class="st_h">'imagestringup'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagesx'</span><span class="sy0">,</span><span class="st_h">'imagesy'</span><span class="sy0">,</span><span class="st_h">'imagetruecolortopalette'</span><span class="sy0">,</span><span class="st_h">'imagettfbbox'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imagettftext'</span><span class="sy0">,</span><span class="st_h">'imagetypes'</span><span class="sy0">,</span><span class="st_h">'imagewbmp'</span><span class="sy0">,</span><span class="st_h">'imagexbm'</span><span class="sy0">,</span><span class="st_h">'imap_8bit'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_alerts'</span><span class="sy0">,</span><span class="st_h">'imap_append'</span><span class="sy0">,</span><span class="st_h">'imap_base64'</span><span class="sy0">,</span><span class="st_h">'imap_binary'</span><span class="sy0">,</span><span class="st_h">'imap_body'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_bodystruct'</span><span class="sy0">,</span><span class="st_h">'imap_check'</span><span class="sy0">,</span><span class="st_h">'imap_clearflag_full'</span><span class="sy0">,</span><span class="st_h">'imap_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_create'</span><span class="sy0">,</span><span class="st_h">'imap_createmailbox'</span><span class="sy0">,</span><span class="st_h">'imap_delete'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_deletemailbox'</span><span class="sy0">,</span><span class="st_h">'imap_errors'</span><span class="sy0">,</span><span class="st_h">'imap_expunge'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_fetch_overview'</span><span class="sy0">,</span><span class="st_h">'imap_fetchbody'</span><span class="sy0">,</span><span class="st_h">'imap_fetchheader'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_fetchstructure'</span><span class="sy0">,</span><span class="st_h">'imap_fetchtext'</span><span class="sy0">,</span><span class="st_h">'imap_get_quota'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_get_quotaroot'</span><span class="sy0">,</span><span class="st_h">'imap_getacl'</span><span class="sy0">,</span><span class="st_h">'imap_getmailboxes'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_getsubscribed'</span><span class="sy0">,</span><span class="st_h">'imap_header'</span><span class="sy0">,</span><span class="st_h">'imap_headerinfo'</span><span class="sy0">,</span><span class="st_h">'imap_headers'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_last_error'</span><span class="sy0">,</span><span class="st_h">'imap_list'</span><span class="sy0">,</span><span class="st_h">'imap_listmailbox'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_listsubscribed'</span><span class="sy0">,</span><span class="st_h">'imap_lsub'</span><span class="sy0">,</span><span class="st_h">'imap_mail'</span><span class="sy0">,</span><span class="st_h">'imap_mail_compose'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_mail_copy'</span><span class="sy0">,</span><span class="st_h">'imap_mail_move'</span><span class="sy0">,</span><span class="st_h">'imap_mailboxmsginfo'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_mime_header_decode'</span><span class="sy0">,</span><span class="st_h">'imap_msgno'</span><span class="sy0">,</span><span class="st_h">'imap_num_msg'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_num_recent'</span><span class="sy0">,</span><span class="st_h">'imap_open'</span><span class="sy0">,</span><span class="st_h">'imap_ping'</span><span class="sy0">,</span><span class="st_h">'imap_qprint'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_rename'</span><span class="sy0">,</span><span class="st_h">'imap_renamemailbox'</span><span class="sy0">,</span><span class="st_h">'imap_reopen'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_rfc822_parse_adrlist'</span><span class="sy0">,</span><span class="st_h">'imap_rfc822_parse_headers'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_rfc822_write_address'</span><span class="sy0">,</span><span class="st_h">'imap_savebody'</span><span class="sy0">,</span><span class="st_h">'imap_scan'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_scanmailbox'</span><span class="sy0">,</span><span class="st_h">'imap_search'</span><span class="sy0">,</span><span class="st_h">'imap_set_quota'</span><span class="sy0">,</span><span class="st_h">'imap_setacl'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_setflag_full'</span><span class="sy0">,</span><span class="st_h">'imap_sort'</span><span class="sy0">,</span><span class="st_h">'imap_status'</span><span class="sy0">,</span><span class="st_h">'imap_subscribe'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_thread'</span><span class="sy0">,</span><span class="st_h">'imap_timeout'</span><span class="sy0">,</span><span class="st_h">'imap_uid'</span><span class="sy0">,</span><span class="st_h">'imap_undelete'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_unsubscribe'</span><span class="sy0">,</span><span class="st_h">'imap_utf7_decode'</span><span class="sy0">,</span><span class="st_h">'imap_utf7_encode'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'imap_utf8'</span><span class="sy0">,</span><span class="st_h">'implode'</span><span class="sy0">,</span><span class="st_h">'import_request_variables'</span><span class="sy0">,</span><span class="st_h">'in_array'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ini_alter'</span><span class="sy0">,</span><span class="st_h">'ini_get'</span><span class="sy0">,</span><span class="st_h">'ini_get_all'</span><span class="sy0">,</span><span class="st_h">'ini_restore'</span><span class="sy0">,</span><span class="st_h">'ini_set'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'intval'</span><span class="sy0">,</span><span class="st_h">'ip2long'</span><span class="sy0">,</span><span class="st_h">'iptcembed'</span><span class="sy0">,</span><span class="st_h">'iptcparse'</span><span class="sy0">,</span><span class="st_h">'isset'</span><span class="sy0">,</span><span class="st_h">'is_a'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'is_array'</span><span class="sy0">,</span><span class="st_h">'is_bool'</span><span class="sy0">,</span><span class="st_h">'is_callable'</span><span class="sy0">,</span><span class="st_h">'is_dir'</span><span class="sy0">,</span><span class="st_h">'is_double'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'is_executable'</span><span class="sy0">,</span><span class="st_h">'is_file'</span><span class="sy0">,</span><span class="st_h">'is_finite'</span><span class="sy0">,</span><span class="st_h">'is_float'</span><span class="sy0">,</span><span class="st_h">'is_infinite'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'is_int'</span><span class="sy0">,</span><span class="st_h">'is_integer'</span><span class="sy0">,</span><span class="st_h">'is_link'</span><span class="sy0">,</span><span class="st_h">'is_long'</span><span class="sy0">,</span><span class="st_h">'is_nan'</span><span class="sy0">,</span><span class="st_h">'is_null'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'is_numeric'</span><span class="sy0">,</span><span class="st_h">'is_object'</span><span class="sy0">,</span><span class="st_h">'is_readable'</span><span class="sy0">,</span><span class="st_h">'is_real'</span><span class="sy0">,</span><span class="st_h">'is_resource'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'is_scalar'</span><span class="sy0">,</span><span class="st_h">'is_soap_fault'</span><span class="sy0">,</span><span class="st_h">'is_string'</span><span class="sy0">,</span><span class="st_h">'is_subclass_of'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'is_uploaded_file'</span><span class="sy0">,</span><span class="st_h">'is_writable'</span><span class="sy0">,</span><span class="st_h">'is_writeable'</span><span class="sy0">,</span><span class="st_h">'iterator_apply'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'iterator_count'</span><span class="sy0">,</span><span class="st_h">'iterator_to_array'</span><span class="sy0">,</span><span class="st_h">'java_last_exception_clear'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'java_last_exception_get'</span><span class="sy0">,</span><span class="st_h">'jddayofweek'</span><span class="sy0">,</span><span class="st_h">'jdmonthname'</span><span class="sy0">,</span><span class="st_h">'jdtofrench'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'jdtogregorian'</span><span class="sy0">,</span><span class="st_h">'jdtojewish'</span><span class="sy0">,</span><span class="st_h">'jdtojulian'</span><span class="sy0">,</span><span class="st_h">'jdtounix'</span><span class="sy0">,</span><span class="st_h">'jewishtojd'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'join'</span><span class="sy0">,</span><span class="st_h">'jpeg2wbmp'</span><span class="sy0">,</span><span class="st_h">'json_decode'</span><span class="sy0">,</span><span class="st_h">'json_encode'</span><span class="sy0">,</span><span class="st_h">'juliantojd'</span><span class="sy0">,</span><span class="st_h">'key'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'key_exists'</span><span class="sy0">,</span><span class="st_h">'krsort'</span><span class="sy0">,</span><span class="st_h">'ksort'</span><span class="sy0">,</span><span class="st_h">'lcg_value'</span><span class="sy0">,</span><span class="st_h">'ldap_add'</span><span class="sy0">,</span><span class="st_h">'ldap_bind'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_close'</span><span class="sy0">,</span><span class="st_h">'ldap_compare'</span><span class="sy0">,</span><span class="st_h">'ldap_connect'</span><span class="sy0">,</span><span class="st_h">'ldap_count_entries'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_delete'</span><span class="sy0">,</span><span class="st_h">'ldap_dn2ufn'</span><span class="sy0">,</span><span class="st_h">'ldap_err2str'</span><span class="sy0">,</span><span class="st_h">'ldap_errno'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_error'</span><span class="sy0">,</span><span class="st_h">'ldap_explode_dn'</span><span class="sy0">,</span><span class="st_h">'ldap_first_attribute'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_first_entry'</span><span class="sy0">,</span><span class="st_h">'ldap_first_reference'</span><span class="sy0">,</span><span class="st_h">'ldap_free_result'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_get_attributes'</span><span class="sy0">,</span><span class="st_h">'ldap_get_dn'</span><span class="sy0">,</span><span class="st_h">'ldap_get_entries'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_get_option'</span><span class="sy0">,</span><span class="st_h">'ldap_get_values'</span><span class="sy0">,</span><span class="st_h">'ldap_get_values_len'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_list'</span><span class="sy0">,</span><span class="st_h">'ldap_mod_add'</span><span class="sy0">,</span><span class="st_h">'ldap_mod_del'</span><span class="sy0">,</span><span class="st_h">'ldap_mod_replace'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_modify'</span><span class="sy0">,</span><span class="st_h">'ldap_next_attribute'</span><span class="sy0">,</span><span class="st_h">'ldap_next_entry'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_next_reference'</span><span class="sy0">,</span><span class="st_h">'ldap_parse_reference'</span><span class="sy0">,</span><span class="st_h">'ldap_parse_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_read'</span><span class="sy0">,</span><span class="st_h">'ldap_rename'</span><span class="sy0">,</span><span class="st_h">'ldap_search'</span><span class="sy0">,</span><span class="st_h">'ldap_set_option'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ldap_sort'</span><span class="sy0">,</span><span class="st_h">'ldap_start_tls'</span><span class="sy0">,</span><span class="st_h">'ldap_unbind'</span><span class="sy0">,</span><span class="st_h">'levenshtein'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'libxml_clear_errors'</span><span class="sy0">,</span><span class="st_h">'libxml_get_errors'</span><span class="sy0">,</span><span class="st_h">'libxml_get_last_error'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'libxml_set_streams_context'</span><span class="sy0">,</span><span class="st_h">'libxml_use_internal_errors'</span><span class="sy0">,</span><span class="st_h">'link'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'linkinfo'</span><span class="sy0">,</span><span class="st_h">'list'</span><span class="sy0">,</span><span class="st_h">'localeconv'</span><span class="sy0">,</span><span class="st_h">'localtime'</span><span class="sy0">,</span><span class="st_h">'log'</span><span class="sy0">,</span><span class="st_h">'log1p'</span><span class="sy0">,</span><span class="st_h">'log10'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'long2ip'</span><span class="sy0">,</span><span class="st_h">'lstat'</span><span class="sy0">,</span><span class="st_h">'ltrim'</span><span class="sy0">,</span><span class="st_h">'lzf_compress'</span><span class="sy0">,</span><span class="st_h">'lzf_decompress'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'lzf_optimized_for'</span><span class="sy0">,</span><span class="st_h">'magic_quotes_runtime'</span><span class="sy0">,</span><span class="st_h">'mail'</span><span class="sy0">,</span><span class="st_h">'max'</span><span class="sy0">,</span><span class="st_h">'mbereg'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mberegi'</span><span class="sy0">,</span><span class="st_h">'mberegi_replace'</span><span class="sy0">,</span><span class="st_h">'mbereg_match'</span><span class="sy0">,</span><span class="st_h">'mbereg_replace'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mbereg_search'</span><span class="sy0">,</span><span class="st_h">'mbereg_search_getpos'</span><span class="sy0">,</span><span class="st_h">'mbereg_search_getregs'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mbereg_search_init'</span><span class="sy0">,</span><span class="st_h">'mbereg_search_pos'</span><span class="sy0">,</span><span class="st_h">'mbereg_search_regs'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mbereg_search_setpos'</span><span class="sy0">,</span><span class="st_h">'mbregex_encoding'</span><span class="sy0">,</span><span class="st_h">'mbsplit'</span><span class="sy0">,</span><span class="st_h">'mbstrcut'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mbstrlen'</span><span class="sy0">,</span><span class="st_h">'mbstrpos'</span><span class="sy0">,</span><span class="st_h">'mbstrrpos'</span><span class="sy0">,</span><span class="st_h">'mbsubstr'</span><span class="sy0">,</span><span class="st_h">'mb_check_encoding'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_convert_case'</span><span class="sy0">,</span><span class="st_h">'mb_convert_encoding'</span><span class="sy0">,</span><span class="st_h">'mb_convert_kana'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_convert_variables'</span><span class="sy0">,</span><span class="st_h">'mb_decode_mimeheader'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_decode_numericentity'</span><span class="sy0">,</span><span class="st_h">'mb_detect_encoding'</span><span class="sy0">,</span><span class="st_h">'mb_detect_order'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_encode_mimeheader'</span><span class="sy0">,</span><span class="st_h">'mb_encode_numericentity'</span><span class="sy0">,</span><span class="st_h">'mb_ereg'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_eregi'</span><span class="sy0">,</span><span class="st_h">'mb_eregi_replace'</span><span class="sy0">,</span><span class="st_h">'mb_ereg_match'</span><span class="sy0">,</span><span class="st_h">'mb_ereg_replace'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_ereg_search'</span><span class="sy0">,</span><span class="st_h">'mb_ereg_search_getpos'</span><span class="sy0">,</span><span class="st_h">'mb_ereg_search_getregs'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_ereg_search_init'</span><span class="sy0">,</span><span class="st_h">'mb_ereg_search_pos'</span><span class="sy0">,</span><span class="st_h">'mb_ereg_search_regs'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_ereg_search_setpos'</span><span class="sy0">,</span><span class="st_h">'mb_get_info'</span><span class="sy0">,</span><span class="st_h">'mb_http_input'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_http_output'</span><span class="sy0">,</span><span class="st_h">'mb_internal_encoding'</span><span class="sy0">,</span><span class="st_h">'mb_language'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_list_encodings'</span><span class="sy0">,</span><span class="st_h">'mb_output_handler'</span><span class="sy0">,</span><span class="st_h">'mb_parse_str'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_preferred_mime_name'</span><span class="sy0">,</span><span class="st_h">'mb_regex_encoding'</span><span class="sy0">,</span><span class="st_h">'mb_regex_set_options'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_send_mail'</span><span class="sy0">,</span><span class="st_h">'mb_split'</span><span class="sy0">,</span><span class="st_h">'mb_strcut'</span><span class="sy0">,</span><span class="st_h">'mb_strimwidth'</span><span class="sy0">,</span><span class="st_h">'mb_stripos'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_stristr'</span><span class="sy0">,</span><span class="st_h">'mb_strlen'</span><span class="sy0">,</span><span class="st_h">'mb_strpos'</span><span class="sy0">,</span><span class="st_h">'mb_strrchr'</span><span class="sy0">,</span><span class="st_h">'mb_strrichr'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_strripos'</span><span class="sy0">,</span><span class="st_h">'mb_strrpos'</span><span class="sy0">,</span><span class="st_h">'mb_strstr'</span><span class="sy0">,</span><span class="st_h">'mb_strtolower'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_strtoupper'</span><span class="sy0">,</span><span class="st_h">'mb_strwidth'</span><span class="sy0">,</span><span class="st_h">'mb_substitute_character'</span><span class="sy0">,</span><span class="st_h">'mb_substr'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mb_substr_count'</span><span class="sy0">,</span><span class="st_h">'mcrypt_cbc'</span><span class="sy0">,</span><span class="st_h">'mcrypt_cfb'</span><span class="sy0">,</span><span class="st_h">'mcrypt_create_iv'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_decrypt'</span><span class="sy0">,</span><span class="st_h">'mcrypt_ecb'</span><span class="sy0">,</span><span class="st_h">'mcrypt_enc_get_algorithms_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_enc_get_block_size'</span><span class="sy0">,</span><span class="st_h">'mcrypt_enc_get_iv_size'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_enc_get_key_size'</span><span class="sy0">,</span><span class="st_h">'mcrypt_enc_get_modes_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_enc_get_supported_key_sizes'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_enc_is_block_algorithm'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_enc_is_block_algorithm_mode'</span><span class="sy0">,</span><span class="st_h">'mcrypt_enc_is_block_mode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_enc_self_test'</span><span class="sy0">,</span><span class="st_h">'mcrypt_encrypt'</span><span class="sy0">,</span><span class="st_h">'mcrypt_generic'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_generic_deinit'</span><span class="sy0">,</span><span class="st_h">'mcrypt_generic_end'</span><span class="sy0">,</span><span class="st_h">'mcrypt_generic_init'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_get_block_size'</span><span class="sy0">,</span><span class="st_h">'mcrypt_get_cipher_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_get_iv_size'</span><span class="sy0">,</span><span class="st_h">'mcrypt_get_key_size'</span><span class="sy0">,</span><span class="st_h">'mcrypt_list_algorithms'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_list_modes'</span><span class="sy0">,</span><span class="st_h">'mcrypt_module_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_get_algo_block_size'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_get_algo_key_size'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_get_supported_key_sizes'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_is_block_algorithm'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_is_block_algorithm_mode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_is_block_mode'</span><span class="sy0">,</span><span class="st_h">'mcrypt_module_open'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mcrypt_module_self_test'</span><span class="sy0">,</span><span class="st_h">'mcrypt_ofb'</span><span class="sy0">,</span><span class="st_h">'md5'</span><span class="sy0">,</span><span class="st_h">'md5_file'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mdecrypt_generic'</span><span class="sy0">,</span><span class="st_h">'memcache_add'</span><span class="sy0">,</span><span class="st_h">'memcache_add_server'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_close'</span><span class="sy0">,</span><span class="st_h">'memcache_connect'</span><span class="sy0">,</span><span class="st_h">'memcache_debug'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_decrement'</span><span class="sy0">,</span><span class="st_h">'memcache_delete'</span><span class="sy0">,</span><span class="st_h">'memcache_flush'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_get'</span><span class="sy0">,</span><span class="st_h">'memcache_get_extended_stats'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_get_server_status'</span><span class="sy0">,</span><span class="st_h">'memcache_get_stats'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_get_version'</span><span class="sy0">,</span><span class="st_h">'memcache_increment'</span><span class="sy0">,</span><span class="st_h">'memcache_pconnect'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_replace'</span><span class="sy0">,</span><span class="st_h">'memcache_set'</span><span class="sy0">,</span><span class="st_h">'memcache_set_compress_threshold'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memcache_set_server_params'</span><span class="sy0">,</span><span class="st_h">'memory_get_peak_usage'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'memory_get_usage'</span><span class="sy0">,</span><span class="st_h">'metaphone'</span><span class="sy0">,</span><span class="st_h">'mhash'</span><span class="sy0">,</span><span class="st_h">'mhash_count'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mhash_get_block_size'</span><span class="sy0">,</span><span class="st_h">'mhash_get_hash_name'</span><span class="sy0">,</span><span class="st_h">'mhash_keygen_s2k'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'method_exists'</span><span class="sy0">,</span><span class="st_h">'microtime'</span><span class="sy0">,</span><span class="st_h">'mime_content_type'</span><span class="sy0">,</span><span class="st_h">'min'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ming_keypress'</span><span class="sy0">,</span><span class="st_h">'ming_setcubicthreshold'</span><span class="sy0">,</span><span class="st_h">'ming_setscale'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ming_useconstants'</span><span class="sy0">,</span><span class="st_h">'ming_useswfversion'</span><span class="sy0">,</span><span class="st_h">'mkdir'</span><span class="sy0">,</span><span class="st_h">'mktime'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'money_format'</span><span class="sy0">,</span><span class="st_h">'move_uploaded_file'</span><span class="sy0">,</span><span class="st_h">'msql'</span><span class="sy0">,</span><span class="st_h">'msql_affected_rows'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_close'</span><span class="sy0">,</span><span class="st_h">'msql_connect'</span><span class="sy0">,</span><span class="st_h">'msql_create_db'</span><span class="sy0">,</span><span class="st_h">'msql_createdb'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_data_seek'</span><span class="sy0">,</span><span class="st_h">'msql_db_query'</span><span class="sy0">,</span><span class="st_h">'msql_dbname'</span><span class="sy0">,</span><span class="st_h">'msql_drop_db'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_dropdb'</span><span class="sy0">,</span><span class="st_h">'msql_error'</span><span class="sy0">,</span><span class="st_h">'msql_fetch_array'</span><span class="sy0">,</span><span class="st_h">'msql_fetch_field'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_fetch_object'</span><span class="sy0">,</span><span class="st_h">'msql_fetch_row'</span><span class="sy0">,</span><span class="st_h">'msql_field_flags'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_field_len'</span><span class="sy0">,</span><span class="st_h">'msql_field_name'</span><span class="sy0">,</span><span class="st_h">'msql_field_seek'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_field_table'</span><span class="sy0">,</span><span class="st_h">'msql_field_type'</span><span class="sy0">,</span><span class="st_h">'msql_fieldflags'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_fieldlen'</span><span class="sy0">,</span><span class="st_h">'msql_fieldname'</span><span class="sy0">,</span><span class="st_h">'msql_fieldtable'</span><span class="sy0">,</span><span class="st_h">'msql_fieldtype'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_free_result'</span><span class="sy0">,</span><span class="st_h">'msql_freeresult'</span><span class="sy0">,</span><span class="st_h">'msql_list_dbs'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_list_fields'</span><span class="sy0">,</span><span class="st_h">'msql_list_tables'</span><span class="sy0">,</span><span class="st_h">'msql_listdbs'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_listfields'</span><span class="sy0">,</span><span class="st_h">'msql_listtables'</span><span class="sy0">,</span><span class="st_h">'msql_num_fields'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_num_rows'</span><span class="sy0">,</span><span class="st_h">'msql_numfields'</span><span class="sy0">,</span><span class="st_h">'msql_numrows'</span><span class="sy0">,</span><span class="st_h">'msql_pconnect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_query'</span><span class="sy0">,</span><span class="st_h">'msql_regcase'</span><span class="sy0">,</span><span class="st_h">'msql_result'</span><span class="sy0">,</span><span class="st_h">'msql_select_db'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'msql_selectdb'</span><span class="sy0">,</span><span class="st_h">'msql_tablename'</span><span class="sy0">,</span><span class="st_h">'mssql_bind'</span><span class="sy0">,</span><span class="st_h">'mssql_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_connect'</span><span class="sy0">,</span><span class="st_h">'mssql_data_seek'</span><span class="sy0">,</span><span class="st_h">'mssql_execute'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_fetch_array'</span><span class="sy0">,</span><span class="st_h">'mssql_fetch_assoc'</span><span class="sy0">,</span><span class="st_h">'mssql_fetch_batch'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_fetch_field'</span><span class="sy0">,</span><span class="st_h">'mssql_fetch_object'</span><span class="sy0">,</span><span class="st_h">'mssql_fetch_row'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_field_length'</span><span class="sy0">,</span><span class="st_h">'mssql_field_name'</span><span class="sy0">,</span><span class="st_h">'mssql_field_seek'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_field_type'</span><span class="sy0">,</span><span class="st_h">'mssql_free_result'</span><span class="sy0">,</span><span class="st_h">'mssql_free_statement'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_get_last_message'</span><span class="sy0">,</span><span class="st_h">'mssql_guid_string'</span><span class="sy0">,</span><span class="st_h">'mssql_init'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_min_error_severity'</span><span class="sy0">,</span><span class="st_h">'mssql_min_message_severity'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_next_result'</span><span class="sy0">,</span><span class="st_h">'mssql_num_fields'</span><span class="sy0">,</span><span class="st_h">'mssql_num_rows'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_pconnect'</span><span class="sy0">,</span><span class="st_h">'mssql_query'</span><span class="sy0">,</span><span class="st_h">'mssql_result'</span><span class="sy0">,</span><span class="st_h">'mssql_rows_affected'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mssql_select_db'</span><span class="sy0">,</span><span class="st_h">'mt_getrandmax'</span><span class="sy0">,</span><span class="st_h">'mt_rand'</span><span class="sy0">,</span><span class="st_h">'mt_srand'</span><span class="sy0">,</span><span class="st_h">'mysql'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_affected_rows'</span><span class="sy0">,</span><span class="st_h">'mysql_client_encoding'</span><span class="sy0">,</span><span class="st_h">'mysql_close'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_connect'</span><span class="sy0">,</span><span class="st_h">'mysql_createdb'</span><span class="sy0">,</span><span class="st_h">'mysql_create_db'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_data_seek'</span><span class="sy0">,</span><span class="st_h">'mysql_dbname'</span><span class="sy0">,</span><span class="st_h">'mysql_db_name'</span><span class="sy0">,</span><span class="st_h">'mysql_db_query'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_dropdb'</span><span class="sy0">,</span><span class="st_h">'mysql_drop_db'</span><span class="sy0">,</span><span class="st_h">'mysql_errno'</span><span class="sy0">,</span><span class="st_h">'mysql_error'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_escape_string'</span><span class="sy0">,</span><span class="st_h">'mysql_fetch_array'</span><span class="sy0">,</span><span class="st_h">'mysql_fetch_assoc'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_fetch_field'</span><span class="sy0">,</span><span class="st_h">'mysql_fetch_lengths'</span><span class="sy0">,</span><span class="st_h">'mysql_fetch_object'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_fetch_row'</span><span class="sy0">,</span><span class="st_h">'mysql_fieldflags'</span><span class="sy0">,</span><span class="st_h">'mysql_fieldlen'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_fieldname'</span><span class="sy0">,</span><span class="st_h">'mysql_fieldtable'</span><span class="sy0">,</span><span class="st_h">'mysql_fieldtype'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_field_flags'</span><span class="sy0">,</span><span class="st_h">'mysql_field_len'</span><span class="sy0">,</span><span class="st_h">'mysql_field_name'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_field_seek'</span><span class="sy0">,</span><span class="st_h">'mysql_field_table'</span><span class="sy0">,</span><span class="st_h">'mysql_field_type'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_freeresult'</span><span class="sy0">,</span><span class="st_h">'mysql_free_result'</span><span class="sy0">,</span><span class="st_h">'mysql_get_client_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_get_host_info'</span><span class="sy0">,</span><span class="st_h">'mysql_get_proto_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_get_server_info'</span><span class="sy0">,</span><span class="st_h">'mysql_info'</span><span class="sy0">,</span><span class="st_h">'mysql_insert_id'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_listdbs'</span><span class="sy0">,</span><span class="st_h">'mysql_listfields'</span><span class="sy0">,</span><span class="st_h">'mysql_listtables'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_list_dbs'</span><span class="sy0">,</span><span class="st_h">'mysql_list_fields'</span><span class="sy0">,</span><span class="st_h">'mysql_list_processes'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_list_tables'</span><span class="sy0">,</span><span class="st_h">'mysql_numfields'</span><span class="sy0">,</span><span class="st_h">'mysql_numrows'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_num_fields'</span><span class="sy0">,</span><span class="st_h">'mysql_num_rows'</span><span class="sy0">,</span><span class="st_h">'mysql_pconnect'</span><span class="sy0">,</span><span class="st_h">'mysql_ping'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_query'</span><span class="sy0">,</span><span class="st_h">'mysql_real_escape_string'</span><span class="sy0">,</span><span class="st_h">'mysql_result'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_selectdb'</span><span class="sy0">,</span><span class="st_h">'mysql_select_db'</span><span class="sy0">,</span><span class="st_h">'mysql_set_charset'</span><span class="sy0">,</span><span class="st_h">'mysql_stat'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_tablename'</span><span class="sy0">,</span><span class="st_h">'mysql_table_name'</span><span class="sy0">,</span><span class="st_h">'mysql_thread_id'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysql_unbuffered_query'</span><span class="sy0">,</span><span class="st_h">'mysqli_affected_rows'</span><span class="sy0">,</span><span class="st_h">'mysqli_autocommit'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_bind_param'</span><span class="sy0">,</span><span class="st_h">'mysqli_bind_result'</span><span class="sy0">,</span><span class="st_h">'mysqli_change_user'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_character_set_name'</span><span class="sy0">,</span><span class="st_h">'mysqli_client_encoding'</span><span class="sy0">,</span><span class="st_h">'mysqli_close'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_commit'</span><span class="sy0">,</span><span class="st_h">'mysqli_connect'</span><span class="sy0">,</span><span class="st_h">'mysqli_connect_errno'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_connect_error'</span><span class="sy0">,</span><span class="st_h">'mysqli_data_seek'</span><span class="sy0">,</span><span class="st_h">'mysqli_debug'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_disable_reads_from_master'</span><span class="sy0">,</span><span class="st_h">'mysqli_disable_rpl_parse'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_dump_debug_info'</span><span class="sy0">,</span><span class="st_h">'mysqli_embedded_server_end'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_embedded_server_start'</span><span class="sy0">,</span><span class="st_h">'mysqli_enable_reads_from_master'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_enable_rpl_parse'</span><span class="sy0">,</span><span class="st_h">'mysqli_errno'</span><span class="sy0">,</span><span class="st_h">'mysqli_error'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_escape_string'</span><span class="sy0">,</span><span class="st_h">'mysqli_execute'</span><span class="sy0">,</span><span class="st_h">'mysqli_fetch'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_fetch_array'</span><span class="sy0">,</span><span class="st_h">'mysqli_fetch_assoc'</span><span class="sy0">,</span><span class="st_h">'mysqli_fetch_field'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_fetch_field_direct'</span><span class="sy0">,</span><span class="st_h">'mysqli_fetch_fields'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_fetch_lengths'</span><span class="sy0">,</span><span class="st_h">'mysqli_fetch_object'</span><span class="sy0">,</span><span class="st_h">'mysqli_fetch_row'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_field_count'</span><span class="sy0">,</span><span class="st_h">'mysqli_field_seek'</span><span class="sy0">,</span><span class="st_h">'mysqli_field_tell'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_free_result'</span><span class="sy0">,</span><span class="st_h">'mysqli_get_charset'</span><span class="sy0">,</span><span class="st_h">'mysqli_get_client_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_get_client_version'</span><span class="sy0">,</span><span class="st_h">'mysqli_get_host_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_get_metadata'</span><span class="sy0">,</span><span class="st_h">'mysqli_get_proto_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_get_server_info'</span><span class="sy0">,</span><span class="st_h">'mysqli_get_server_version'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_get_warnings'</span><span class="sy0">,</span><span class="st_h">'mysqli_info'</span><span class="sy0">,</span><span class="st_h">'mysqli_init'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_insert_id'</span><span class="sy0">,</span><span class="st_h">'mysqli_kill'</span><span class="sy0">,</span><span class="st_h">'mysqli_master_query'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_more_results'</span><span class="sy0">,</span><span class="st_h">'mysqli_multi_query'</span><span class="sy0">,</span><span class="st_h">'mysqli_next_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_num_fields'</span><span class="sy0">,</span><span class="st_h">'mysqli_num_rows'</span><span class="sy0">,</span><span class="st_h">'mysqli_options'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_param_count'</span><span class="sy0">,</span><span class="st_h">'mysqli_ping'</span><span class="sy0">,</span><span class="st_h">'mysqli_prepare'</span><span class="sy0">,</span><span class="st_h">'mysqli_query'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_real_connect'</span><span class="sy0">,</span><span class="st_h">'mysqli_real_escape_string'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_real_query'</span><span class="sy0">,</span><span class="st_h">'mysqli_report'</span><span class="sy0">,</span><span class="st_h">'mysqli_rollback'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_rpl_parse_enabled'</span><span class="sy0">,</span><span class="st_h">'mysqli_rpl_probe'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_rpl_query_type'</span><span class="sy0">,</span><span class="st_h">'mysqli_select_db'</span><span class="sy0">,</span><span class="st_h">'mysqli_send_long_data'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_send_query'</span><span class="sy0">,</span><span class="st_h">'mysqli_set_charset'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_set_local_infile_default'</span><span class="sy0">,</span><span class="st_h">'mysqli_set_local_infile_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_set_opt'</span><span class="sy0">,</span><span class="st_h">'mysqli_slave_query'</span><span class="sy0">,</span><span class="st_h">'mysqli_sqlstate'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_ssl_set'</span><span class="sy0">,</span><span class="st_h">'mysqli_stat'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_affected_rows'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_attr_get'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_attr_set'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_bind_param'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_bind_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_close'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_data_seek'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_errno'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_error'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_execute'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_fetch'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_field_count'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_free_result'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_get_warnings'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_init'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_insert_id'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_num_rows'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_param_count'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_prepare'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_reset'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_result_metadata'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_send_long_data'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_stmt_sqlstate'</span><span class="sy0">,</span><span class="st_h">'mysqli_stmt_store_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_store_result'</span><span class="sy0">,</span><span class="st_h">'mysqli_thread_id'</span><span class="sy0">,</span><span class="st_h">'mysqli_thread_safe'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'mysqli_use_result'</span><span class="sy0">,</span><span class="st_h">'mysqli_warning_count'</span><span class="sy0">,</span><span class="st_h">'natcasesort'</span><span class="sy0">,</span><span class="st_h">'natsort'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'new_xmldoc'</span><span class="sy0">,</span><span class="st_h">'next'</span><span class="sy0">,</span><span class="st_h">'ngettext'</span><span class="sy0">,</span><span class="st_h">'nl2br'</span><span class="sy0">,</span><span class="st_h">'nl_langinfo'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ntuser_getdomaincontroller'</span><span class="sy0">,</span><span class="st_h">'ntuser_getusergroups'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ntuser_getuserinfo'</span><span class="sy0">,</span><span class="st_h">'ntuser_getuserlist'</span><span class="sy0">,</span><span class="st_h">'number_format'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ob_clean'</span><span class="sy0">,</span><span class="st_h">'ob_deflatehandler'</span><span class="sy0">,</span><span class="st_h">'ob_end_clean'</span><span class="sy0">,</span><span class="st_h">'ob_end_flush'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ob_etaghandler'</span><span class="sy0">,</span><span class="st_h">'ob_flush'</span><span class="sy0">,</span><span class="st_h">'ob_get_clean'</span><span class="sy0">,</span><span class="st_h">'ob_get_contents'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ob_get_flush'</span><span class="sy0">,</span><span class="st_h">'ob_get_length'</span><span class="sy0">,</span><span class="st_h">'ob_get_level'</span><span class="sy0">,</span><span class="st_h">'ob_get_status'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ob_gzhandler'</span><span class="sy0">,</span><span class="st_h">'ob_iconv_handler'</span><span class="sy0">,</span><span class="st_h">'ob_implicit_flush'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ob_inflatehandler'</span><span class="sy0">,</span><span class="st_h">'ob_list_handlers'</span><span class="sy0">,</span><span class="st_h">'ob_start'</span><span class="sy0">,</span><span class="st_h">'ob_tidyhandler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'octdec'</span><span class="sy0">,</span><span class="st_h">'odbc_autocommit'</span><span class="sy0">,</span><span class="st_h">'odbc_binmode'</span><span class="sy0">,</span><span class="st_h">'odbc_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_close_all'</span><span class="sy0">,</span><span class="st_h">'odbc_columnprivileges'</span><span class="sy0">,</span><span class="st_h">'odbc_columns'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_commit'</span><span class="sy0">,</span><span class="st_h">'odbc_connect'</span><span class="sy0">,</span><span class="st_h">'odbc_cursor'</span><span class="sy0">,</span><span class="st_h">'odbc_data_source'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_do'</span><span class="sy0">,</span><span class="st_h">'odbc_error'</span><span class="sy0">,</span><span class="st_h">'odbc_errormsg'</span><span class="sy0">,</span><span class="st_h">'odbc_exec'</span><span class="sy0">,</span><span class="st_h">'odbc_execute'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_fetch_array'</span><span class="sy0">,</span><span class="st_h">'odbc_fetch_into'</span><span class="sy0">,</span><span class="st_h">'odbc_fetch_object'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_fetch_row'</span><span class="sy0">,</span><span class="st_h">'odbc_field_len'</span><span class="sy0">,</span><span class="st_h">'odbc_field_name'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_field_num'</span><span class="sy0">,</span><span class="st_h">'odbc_field_precision'</span><span class="sy0">,</span><span class="st_h">'odbc_field_scale'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_field_type'</span><span class="sy0">,</span><span class="st_h">'odbc_foreignkeys'</span><span class="sy0">,</span><span class="st_h">'odbc_free_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_gettypeinfo'</span><span class="sy0">,</span><span class="st_h">'odbc_longreadlen'</span><span class="sy0">,</span><span class="st_h">'odbc_next_result'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_num_fields'</span><span class="sy0">,</span><span class="st_h">'odbc_num_rows'</span><span class="sy0">,</span><span class="st_h">'odbc_pconnect'</span><span class="sy0">,</span><span class="st_h">'odbc_prepare'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_primarykeys'</span><span class="sy0">,</span><span class="st_h">'odbc_procedurecolumns'</span><span class="sy0">,</span><span class="st_h">'odbc_procedures'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_result'</span><span class="sy0">,</span><span class="st_h">'odbc_result_all'</span><span class="sy0">,</span><span class="st_h">'odbc_rollback'</span><span class="sy0">,</span><span class="st_h">'odbc_setoption'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_specialcolumns'</span><span class="sy0">,</span><span class="st_h">'odbc_statistics'</span><span class="sy0">,</span><span class="st_h">'odbc_tableprivileges'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'odbc_tables'</span><span class="sy0">,</span><span class="st_h">'opendir'</span><span class="sy0">,</span><span class="st_h">'openlog'</span><span class="sy0">,</span><span class="st_h">'openssl_csr_export'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_csr_export_to_file'</span><span class="sy0">,</span><span class="st_h">'openssl_csr_get_public_key'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_csr_get_subject'</span><span class="sy0">,</span><span class="st_h">'openssl_csr_new'</span><span class="sy0">,</span><span class="st_h">'openssl_csr_sign'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_error_string'</span><span class="sy0">,</span><span class="st_h">'openssl_free_key'</span><span class="sy0">,</span><span class="st_h">'openssl_get_privatekey'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_get_publickey'</span><span class="sy0">,</span><span class="st_h">'openssl_open'</span><span class="sy0">,</span><span class="st_h">'openssl_pkcs12_export'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_pkcs12_export_to_file'</span><span class="sy0">,</span><span class="st_h">'openssl_pkcs12_read'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_pkcs7_decrypt'</span><span class="sy0">,</span><span class="st_h">'openssl_pkcs7_encrypt'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_pkcs7_sign'</span><span class="sy0">,</span><span class="st_h">'openssl_pkcs7_verify'</span><span class="sy0">,</span><span class="st_h">'openssl_pkey_export'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_pkey_export_to_file'</span><span class="sy0">,</span><span class="st_h">'openssl_pkey_free'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_pkey_get_details'</span><span class="sy0">,</span><span class="st_h">'openssl_pkey_get_private'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_pkey_get_public'</span><span class="sy0">,</span><span class="st_h">'openssl_pkey_new'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_private_decrypt'</span><span class="sy0">,</span><span class="st_h">'openssl_private_encrypt'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_public_decrypt'</span><span class="sy0">,</span><span class="st_h">'openssl_public_encrypt'</span><span class="sy0">,</span><span class="st_h">'openssl_seal'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_sign'</span><span class="sy0">,</span><span class="st_h">'openssl_verify'</span><span class="sy0">,</span><span class="st_h">'openssl_x509_checkpurpose'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_x509_check_private_key'</span><span class="sy0">,</span><span class="st_h">'openssl_x509_export'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_x509_export_to_file'</span><span class="sy0">,</span><span class="st_h">'openssl_x509_free'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'openssl_x509_parse'</span><span class="sy0">,</span><span class="st_h">'openssl_x509_read'</span><span class="sy0">,</span><span class="st_h">'ord'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'output_add_rewrite_var'</span><span class="sy0">,</span><span class="st_h">'output_reset_rewrite_vars'</span><span class="sy0">,</span><span class="st_h">'overload'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'outputdebugstring'</span><span class="sy0">,</span><span class="st_h">'pack'</span><span class="sy0">,</span><span class="st_h">'parse_ini_file'</span><span class="sy0">,</span><span class="st_h">'parse_str'</span><span class="sy0">,</span><span class="st_h">'parse_url'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'parsekit_compile_file'</span><span class="sy0">,</span><span class="st_h">'parsekit_compile_string'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'parsekit_func_arginfo'</span><span class="sy0">,</span><span class="st_h">'parsekit_opcode_flags'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'parsekit_opcode_name'</span><span class="sy0">,</span><span class="st_h">'passthru'</span><span class="sy0">,</span><span class="st_h">'pathinfo'</span><span class="sy0">,</span><span class="st_h">'pclose'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_add_bookmark'</span><span class="sy0">,</span><span class="st_h">'pdf_add_launchlink'</span><span class="sy0">,</span><span class="st_h">'pdf_add_locallink'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_add_nameddest'</span><span class="sy0">,</span><span class="st_h">'pdf_add_note'</span><span class="sy0">,</span><span class="st_h">'pdf_add_pdflink'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_add_thumbnail'</span><span class="sy0">,</span><span class="st_h">'pdf_add_weblink'</span><span class="sy0">,</span><span class="st_h">'pdf_arc'</span><span class="sy0">,</span><span class="st_h">'pdf_arcn'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_attach_file'</span><span class="sy0">,</span><span class="st_h">'pdf_begin_font'</span><span class="sy0">,</span><span class="st_h">'pdf_begin_glyph'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_begin_page'</span><span class="sy0">,</span><span class="st_h">'pdf_begin_pattern'</span><span class="sy0">,</span><span class="st_h">'pdf_begin_template'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_circle'</span><span class="sy0">,</span><span class="st_h">'pdf_clip'</span><span class="sy0">,</span><span class="st_h">'pdf_close'</span><span class="sy0">,</span><span class="st_h">'pdf_close_image'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_close_pdi'</span><span class="sy0">,</span><span class="st_h">'pdf_close_pdi_page'</span><span class="sy0">,</span><span class="st_h">'pdf_closepath'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_closepath_fill_stroke'</span><span class="sy0">,</span><span class="st_h">'pdf_closepath_stroke'</span><span class="sy0">,</span><span class="st_h">'pdf_concat'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_continue_text'</span><span class="sy0">,</span><span class="st_h">'pdf_create_gstate'</span><span class="sy0">,</span><span class="st_h">'pdf_create_pvf'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_curveto'</span><span class="sy0">,</span><span class="st_h">'pdf_delete'</span><span class="sy0">,</span><span class="st_h">'pdf_delete_pvf'</span><span class="sy0">,</span><span class="st_h">'pdf_encoding_set_char'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_end_font'</span><span class="sy0">,</span><span class="st_h">'pdf_end_glyph'</span><span class="sy0">,</span><span class="st_h">'pdf_end_page'</span><span class="sy0">,</span><span class="st_h">'pdf_end_pattern'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_end_template'</span><span class="sy0">,</span><span class="st_h">'pdf_endpath'</span><span class="sy0">,</span><span class="st_h">'pdf_fill'</span><span class="sy0">,</span><span class="st_h">'pdf_fill_imageblock'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_fill_pdfblock'</span><span class="sy0">,</span><span class="st_h">'pdf_fill_stroke'</span><span class="sy0">,</span><span class="st_h">'pdf_fill_textblock'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_findfont'</span><span class="sy0">,</span><span class="st_h">'pdf_fit_image'</span><span class="sy0">,</span><span class="st_h">'pdf_fit_pdi_page'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_fit_textline'</span><span class="sy0">,</span><span class="st_h">'pdf_get_apiname'</span><span class="sy0">,</span><span class="st_h">'pdf_get_buffer'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_get_errmsg'</span><span class="sy0">,</span><span class="st_h">'pdf_get_errnum'</span><span class="sy0">,</span><span class="st_h">'pdf_get_parameter'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_get_pdi_parameter'</span><span class="sy0">,</span><span class="st_h">'pdf_get_pdi_value'</span><span class="sy0">,</span><span class="st_h">'pdf_get_value'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_initgraphics'</span><span class="sy0">,</span><span class="st_h">'pdf_lineto'</span><span class="sy0">,</span><span class="st_h">'pdf_load_font'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_load_iccprofile'</span><span class="sy0">,</span><span class="st_h">'pdf_load_image'</span><span class="sy0">,</span><span class="st_h">'pdf_makespotcolor'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_moveto'</span><span class="sy0">,</span><span class="st_h">'pdf_new'</span><span class="sy0">,</span><span class="st_h">'pdf_open_ccitt'</span><span class="sy0">,</span><span class="st_h">'pdf_open_file'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_open_image'</span><span class="sy0">,</span><span class="st_h">'pdf_open_image_file'</span><span class="sy0">,</span><span class="st_h">'pdf_open_pdi'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_open_pdi_page'</span><span class="sy0">,</span><span class="st_h">'pdf_place_image'</span><span class="sy0">,</span><span class="st_h">'pdf_place_pdi_page'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_process_pdi'</span><span class="sy0">,</span><span class="st_h">'pdf_rect'</span><span class="sy0">,</span><span class="st_h">'pdf_restore'</span><span class="sy0">,</span><span class="st_h">'pdf_rotate'</span><span class="sy0">,</span><span class="st_h">'pdf_save'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_scale'</span><span class="sy0">,</span><span class="st_h">'pdf_set_border_color'</span><span class="sy0">,</span><span class="st_h">'pdf_set_border_dash'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_set_border_style'</span><span class="sy0">,</span><span class="st_h">'pdf_set_gstate'</span><span class="sy0">,</span><span class="st_h">'pdf_set_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_set_parameter'</span><span class="sy0">,</span><span class="st_h">'pdf_set_text_pos'</span><span class="sy0">,</span><span class="st_h">'pdf_set_value'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_setcolor'</span><span class="sy0">,</span><span class="st_h">'pdf_setdash'</span><span class="sy0">,</span><span class="st_h">'pdf_setdashpattern'</span><span class="sy0">,</span><span class="st_h">'pdf_setflat'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_setfont'</span><span class="sy0">,</span><span class="st_h">'pdf_setlinecap'</span><span class="sy0">,</span><span class="st_h">'pdf_setlinejoin'</span><span class="sy0">,</span><span class="st_h">'pdf_setlinewidth'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_setmatrix'</span><span class="sy0">,</span><span class="st_h">'pdf_setmiterlimit'</span><span class="sy0">,</span><span class="st_h">'pdf_setpolydash'</span><span class="sy0">,</span><span class="st_h">'pdf_shading'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_shading_pattern'</span><span class="sy0">,</span><span class="st_h">'pdf_shfill'</span><span class="sy0">,</span><span class="st_h">'pdf_show'</span><span class="sy0">,</span><span class="st_h">'pdf_show_boxed'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_show_xy'</span><span class="sy0">,</span><span class="st_h">'pdf_skew'</span><span class="sy0">,</span><span class="st_h">'pdf_stringwidth'</span><span class="sy0">,</span><span class="st_h">'pdf_stroke'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pdf_translate'</span><span class="sy0">,</span><span class="st_h">'pdo_drivers'</span><span class="sy0">,</span><span class="st_h">'pfsockopen'</span><span class="sy0">,</span><span class="st_h">'pg_affected_rows'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_cancel_query'</span><span class="sy0">,</span><span class="st_h">'pg_clientencoding'</span><span class="sy0">,</span><span class="st_h">'pg_client_encoding'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_close'</span><span class="sy0">,</span><span class="st_h">'pg_cmdtuples'</span><span class="sy0">,</span><span class="st_h">'pg_connect'</span><span class="sy0">,</span><span class="st_h">'pg_connection_busy'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_connection_reset'</span><span class="sy0">,</span><span class="st_h">'pg_connection_status'</span><span class="sy0">,</span><span class="st_h">'pg_convert'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_copy_from'</span><span class="sy0">,</span><span class="st_h">'pg_copy_to'</span><span class="sy0">,</span><span class="st_h">'pg_dbname'</span><span class="sy0">,</span><span class="st_h">'pg_delete'</span><span class="sy0">,</span><span class="st_h">'pg_end_copy'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_errormessage'</span><span class="sy0">,</span><span class="st_h">'pg_escape_bytea'</span><span class="sy0">,</span><span class="st_h">'pg_escape_string'</span><span class="sy0">,</span><span class="st_h">'pg_exec'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_execute'</span><span class="sy0">,</span><span class="st_h">'pg_fetch_all'</span><span class="sy0">,</span><span class="st_h">'pg_fetch_all_columns'</span><span class="sy0">,</span><span class="st_h">'pg_fetch_array'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_fetch_assoc'</span><span class="sy0">,</span><span class="st_h">'pg_fetch_object'</span><span class="sy0">,</span><span class="st_h">'pg_fetch_result'</span><span class="sy0">,</span><span class="st_h">'pg_fetch_row'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_fieldisnull'</span><span class="sy0">,</span><span class="st_h">'pg_fieldname'</span><span class="sy0">,</span><span class="st_h">'pg_fieldnum'</span><span class="sy0">,</span><span class="st_h">'pg_fieldprtlen'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_fieldsize'</span><span class="sy0">,</span><span class="st_h">'pg_fieldtype'</span><span class="sy0">,</span><span class="st_h">'pg_field_is_null'</span><span class="sy0">,</span><span class="st_h">'pg_field_name'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_field_num'</span><span class="sy0">,</span><span class="st_h">'pg_field_prtlen'</span><span class="sy0">,</span><span class="st_h">'pg_field_size'</span><span class="sy0">,</span><span class="st_h">'pg_field_table'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_field_type'</span><span class="sy0">,</span><span class="st_h">'pg_field_type_oid'</span><span class="sy0">,</span><span class="st_h">'pg_free_result'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_freeresult'</span><span class="sy0">,</span><span class="st_h">'pg_get_notify'</span><span class="sy0">,</span><span class="st_h">'pg_get_pid'</span><span class="sy0">,</span><span class="st_h">'pg_get_result'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_getlastoid'</span><span class="sy0">,</span><span class="st_h">'pg_host'</span><span class="sy0">,</span><span class="st_h">'pg_insert'</span><span class="sy0">,</span><span class="st_h">'pg_last_error'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_last_notice'</span><span class="sy0">,</span><span class="st_h">'pg_last_oid'</span><span class="sy0">,</span><span class="st_h">'pg_loclose'</span><span class="sy0">,</span><span class="st_h">'pg_locreate'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_loexport'</span><span class="sy0">,</span><span class="st_h">'pg_loimport'</span><span class="sy0">,</span><span class="st_h">'pg_loopen'</span><span class="sy0">,</span><span class="st_h">'pg_loread'</span><span class="sy0">,</span><span class="st_h">'pg_loreadall'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_lounlink'</span><span class="sy0">,</span><span class="st_h">'pg_lowrite'</span><span class="sy0">,</span><span class="st_h">'pg_lo_close'</span><span class="sy0">,</span><span class="st_h">'pg_lo_create'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_lo_export'</span><span class="sy0">,</span><span class="st_h">'pg_lo_import'</span><span class="sy0">,</span><span class="st_h">'pg_lo_open'</span><span class="sy0">,</span><span class="st_h">'pg_lo_read'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_lo_read_all'</span><span class="sy0">,</span><span class="st_h">'pg_lo_seek'</span><span class="sy0">,</span><span class="st_h">'pg_lo_tell'</span><span class="sy0">,</span><span class="st_h">'pg_lo_unlink'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_lo_write'</span><span class="sy0">,</span><span class="st_h">'pg_meta_data'</span><span class="sy0">,</span><span class="st_h">'pg_numfields'</span><span class="sy0">,</span><span class="st_h">'pg_numrows'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_num_fields'</span><span class="sy0">,</span><span class="st_h">'pg_num_rows'</span><span class="sy0">,</span><span class="st_h">'pg_options'</span><span class="sy0">,</span><span class="st_h">'pg_parameter_status'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_pconnect'</span><span class="sy0">,</span><span class="st_h">'pg_ping'</span><span class="sy0">,</span><span class="st_h">'pg_port'</span><span class="sy0">,</span><span class="st_h">'pg_prepare'</span><span class="sy0">,</span><span class="st_h">'pg_put_line'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_query'</span><span class="sy0">,</span><span class="st_h">'pg_query_params'</span><span class="sy0">,</span><span class="st_h">'pg_result'</span><span class="sy0">,</span><span class="st_h">'pg_result_error'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_result_error_field'</span><span class="sy0">,</span><span class="st_h">'pg_result_seek'</span><span class="sy0">,</span><span class="st_h">'pg_result_status'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_select'</span><span class="sy0">,</span><span class="st_h">'pg_send_execute'</span><span class="sy0">,</span><span class="st_h">'pg_send_prepare'</span><span class="sy0">,</span><span class="st_h">'pg_send_query'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_send_query_params'</span><span class="sy0">,</span><span class="st_h">'pg_set_client_encoding'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_set_error_verbosity'</span><span class="sy0">,</span><span class="st_h">'pg_setclientencoding'</span><span class="sy0">,</span><span class="st_h">'pg_trace'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_transaction_status'</span><span class="sy0">,</span><span class="st_h">'pg_tty'</span><span class="sy0">,</span><span class="st_h">'pg_unescape_bytea'</span><span class="sy0">,</span><span class="st_h">'pg_untrace'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pg_update'</span><span class="sy0">,</span><span class="st_h">'pg_version'</span><span class="sy0">,</span><span class="st_h">'php_egg_logo_guid'</span><span class="sy0">,</span><span class="st_h">'php_ini_loaded_file'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'php_ini_scanned_files'</span><span class="sy0">,</span><span class="st_h">'php_logo_guid'</span><span class="sy0">,</span><span class="st_h">'php_real_logo_guid'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'php_sapi_name'</span><span class="sy0">,</span><span class="st_h">'php_strip_whitespace'</span><span class="sy0">,</span><span class="st_h">'php_uname'</span><span class="sy0">,</span><span class="st_h">'phpcredits'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'phpdoc_xml_from_string'</span><span class="sy0">,</span><span class="st_h">'phpinfo'</span><span class="sy0">,</span><span class="st_h">'phpversion'</span><span class="sy0">,</span><span class="st_h">'pi'</span><span class="sy0">,</span><span class="st_h">'png2wbmp'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pop3_close'</span><span class="sy0">,</span><span class="st_h">'pop3_delete_message'</span><span class="sy0">,</span><span class="st_h">'pop3_get_account_size'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pop3_get_message'</span><span class="sy0">,</span><span class="st_h">'pop3_get_message_count'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pop3_get_message_header'</span><span class="sy0">,</span><span class="st_h">'pop3_get_message_ids'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pop3_get_message_size'</span><span class="sy0">,</span><span class="st_h">'pop3_get_message_sizes'</span><span class="sy0">,</span><span class="st_h">'pop3_open'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'pop3_undelete'</span><span class="sy0">,</span><span class="st_h">'popen'</span><span class="sy0">,</span><span class="st_h">'pos'</span><span class="sy0">,</span><span class="st_h">'posix_ctermid'</span><span class="sy0">,</span><span class="st_h">'posix_errno'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_getcwd'</span><span class="sy0">,</span><span class="st_h">'posix_getegid'</span><span class="sy0">,</span><span class="st_h">'posix_geteuid'</span><span class="sy0">,</span><span class="st_h">'posix_getgid'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_getgrgid'</span><span class="sy0">,</span><span class="st_h">'posix_getgrnam'</span><span class="sy0">,</span><span class="st_h">'posix_getgroups'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_getlogin'</span><span class="sy0">,</span><span class="st_h">'posix_getpgid'</span><span class="sy0">,</span><span class="st_h">'posix_getpgrp'</span><span class="sy0">,</span><span class="st_h">'posix_getpid'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_getppid'</span><span class="sy0">,</span><span class="st_h">'posix_getpwnam'</span><span class="sy0">,</span><span class="st_h">'posix_getpwuid'</span><span class="sy0">,</span><span class="st_h">'posix_getrlimit'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_getsid'</span><span class="sy0">,</span><span class="st_h">'posix_getuid'</span><span class="sy0">,</span><span class="st_h">'posix_get_last_error'</span><span class="sy0">,</span><span class="st_h">'posix_isatty'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_kill'</span><span class="sy0">,</span><span class="st_h">'posix_mkfifo'</span><span class="sy0">,</span><span class="st_h">'posix_setegid'</span><span class="sy0">,</span><span class="st_h">'posix_seteuid'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_setgid'</span><span class="sy0">,</span><span class="st_h">'posix_setpgid'</span><span class="sy0">,</span><span class="st_h">'posix_setsid'</span><span class="sy0">,</span><span class="st_h">'posix_setuid'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'posix_strerror'</span><span class="sy0">,</span><span class="st_h">'posix_times'</span><span class="sy0">,</span><span class="st_h">'posix_ttyname'</span><span class="sy0">,</span><span class="st_h">'posix_uname'</span><span class="sy0">,</span><span class="st_h">'pow'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'preg_grep'</span><span class="sy0">,</span><span class="st_h">'preg_last_error'</span><span class="sy0">,</span><span class="st_h">'preg_match'</span><span class="sy0">,</span><span class="st_h">'preg_match_all'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'preg_quote'</span><span class="sy0">,</span><span class="st_h">'preg_replace'</span><span class="sy0">,</span><span class="st_h">'preg_replace_callback'</span><span class="sy0">,</span><span class="st_h">'preg_split'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'prev'</span><span class="sy0">,</span><span class="st_h">'print_r'</span><span class="sy0">,</span><span class="st_h">'printf'</span><span class="sy0">,</span><span class="st_h">'proc_close'</span><span class="sy0">,</span><span class="st_h">'proc_get_status'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'proc_open'</span><span class="sy0">,</span><span class="st_h">'proc_terminate'</span><span class="sy0">,</span><span class="st_h">'putenv'</span><span class="sy0">,</span><span class="st_h">'quoted_printable_decode'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'quotemeta'</span><span class="sy0">,</span><span class="st_h">'rad2deg'</span><span class="sy0">,</span><span class="st_h">'radius_acct_open'</span><span class="sy0">,</span><span class="st_h">'radius_add_server'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_auth_open'</span><span class="sy0">,</span><span class="st_h">'radius_close'</span><span class="sy0">,</span><span class="st_h">'radius_config'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_create_request'</span><span class="sy0">,</span><span class="st_h">'radius_cvt_addr'</span><span class="sy0">,</span><span class="st_h">'radius_cvt_int'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_cvt_string'</span><span class="sy0">,</span><span class="st_h">'radius_demangle'</span><span class="sy0">,</span><span class="st_h">'radius_demangle_mppe_key'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_get_attr'</span><span class="sy0">,</span><span class="st_h">'radius_get_vendor_attr'</span><span class="sy0">,</span><span class="st_h">'radius_put_addr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_put_attr'</span><span class="sy0">,</span><span class="st_h">'radius_put_int'</span><span class="sy0">,</span><span class="st_h">'radius_put_string'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_put_vendor_addr'</span><span class="sy0">,</span><span class="st_h">'radius_put_vendor_attr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_put_vendor_int'</span><span class="sy0">,</span><span class="st_h">'radius_put_vendor_string'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_request_authenticator'</span><span class="sy0">,</span><span class="st_h">'radius_send_request'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'radius_server_secret'</span><span class="sy0">,</span><span class="st_h">'radius_strerror'</span><span class="sy0">,</span><span class="st_h">'rand'</span><span class="sy0">,</span><span class="st_h">'range'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'rawurldecode'</span><span class="sy0">,</span><span class="st_h">'rawurlencode'</span><span class="sy0">,</span><span class="st_h">'read_exif_data'</span><span class="sy0">,</span><span class="st_h">'readdir'</span><span class="sy0">,</span><span class="st_h">'readfile'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'readgzfile'</span><span class="sy0">,</span><span class="st_h">'readlink'</span><span class="sy0">,</span><span class="st_h">'realpath'</span><span class="sy0">,</span><span class="st_h">'reg_close_key'</span><span class="sy0">,</span><span class="st_h">'reg_create_key'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'reg_enum_key'</span><span class="sy0">,</span><span class="st_h">'reg_enum_value'</span><span class="sy0">,</span><span class="st_h">'reg_get_value'</span><span class="sy0">,</span><span class="st_h">'reg_open_key'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'reg_set_value'</span><span class="sy0">,</span><span class="st_h">'register_shutdown_function'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'register_tick_function'</span><span class="sy0">,</span><span class="st_h">'rename'</span><span class="sy0">,</span><span class="st_h">'res_close'</span><span class="sy0">,</span><span class="st_h">'res_get'</span><span class="sy0">,</span><span class="st_h">'res_list'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'res_list_type'</span><span class="sy0">,</span><span class="st_h">'res_open'</span><span class="sy0">,</span><span class="st_h">'res_set'</span><span class="sy0">,</span><span class="st_h">'reset'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'restore_error_handler'</span><span class="sy0">,</span><span class="st_h">'restore_include_path'</span><span class="sy0">,</span><span class="st_h">'rewind'</span><span class="sy0">,</span><span class="st_h">'rewinddir'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'rmdir'</span><span class="sy0">,</span><span class="st_h">'round'</span><span class="sy0">,</span><span class="st_h">'rsort'</span><span class="sy0">,</span><span class="st_h">'rtrim'</span><span class="sy0">,</span><span class="st_h">'runkit_class_adopt'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_class_emancipate'</span><span class="sy0">,</span><span class="st_h">'runkit_constant_add'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_constant_redefine'</span><span class="sy0">,</span><span class="st_h">'runkit_constant_remove'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_default_property_add'</span><span class="sy0">,</span><span class="st_h">'runkit_function_add'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_function_copy'</span><span class="sy0">,</span><span class="st_h">'runkit_function_redefine'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_function_remove'</span><span class="sy0">,</span><span class="st_h">'runkit_function_rename'</span><span class="sy0">,</span><span class="st_h">'runkit_import'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_lint'</span><span class="sy0">,</span><span class="st_h">'runkit_lint_file'</span><span class="sy0">,</span><span class="st_h">'runkit_method_add'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_method_copy'</span><span class="sy0">,</span><span class="st_h">'runkit_method_redefine'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_method_remove'</span><span class="sy0">,</span><span class="st_h">'runkit_method_rename'</span><span class="sy0">,</span><span class="st_h">'runkit_object_id'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_return_value_used'</span><span class="sy0">,</span><span class="st_h">'runkit_sandbox_output_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'runkit_superglobals'</span><span class="sy0">,</span><span class="st_h">'runkit_zval_inspect'</span><span class="sy0">,</span><span class="st_h">'scandir'</span><span class="sy0">,</span><span class="st_h">'sem_acquire'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sem_get'</span><span class="sy0">,</span><span class="st_h">'sem_release'</span><span class="sy0">,</span><span class="st_h">'sem_remove'</span><span class="sy0">,</span><span class="st_h">'serialize'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_cache_expire'</span><span class="sy0">,</span><span class="st_h">'session_cache_limiter'</span><span class="sy0">,</span><span class="st_h">'session_commit'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_decode'</span><span class="sy0">,</span><span class="st_h">'session_destroy'</span><span class="sy0">,</span><span class="st_h">'session_encode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_get_cookie_params'</span><span class="sy0">,</span><span class="st_h">'session_id'</span><span class="sy0">,</span><span class="st_h">'session_is_registered'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_module_name'</span><span class="sy0">,</span><span class="st_h">'session_name'</span><span class="sy0">,</span><span class="st_h">'session_regenerate_id'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_register'</span><span class="sy0">,</span><span class="st_h">'session_save_path'</span><span class="sy0">,</span><span class="st_h">'session_set_cookie_params'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_set_save_handler'</span><span class="sy0">,</span><span class="st_h">'session_start'</span><span class="sy0">,</span><span class="st_h">'session_unregister'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'session_unset'</span><span class="sy0">,</span><span class="st_h">'session_write_close'</span><span class="sy0">,</span><span class="st_h">'set_content'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'set_error_handler'</span><span class="sy0">,</span><span class="st_h">'set_file_buffer'</span><span class="sy0">,</span><span class="st_h">'set_include_path'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'set_magic_quotes_runtime'</span><span class="sy0">,</span><span class="st_h">'set_socket_blocking'</span><span class="sy0">,</span><span class="st_h">'set_time_limit'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'setcookie'</span><span class="sy0">,</span><span class="st_h">'setlocale'</span><span class="sy0">,</span><span class="st_h">'setrawcookie'</span><span class="sy0">,</span><span class="st_h">'settype'</span><span class="sy0">,</span><span class="st_h">'sha1'</span><span class="sy0">,</span><span class="st_h">'sha1_file'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'shell_exec'</span><span class="sy0">,</span><span class="st_h">'shmop_close'</span><span class="sy0">,</span><span class="st_h">'shmop_delete'</span><span class="sy0">,</span><span class="st_h">'shmop_open'</span><span class="sy0">,</span><span class="st_h">'shmop_read'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'shmop_size'</span><span class="sy0">,</span><span class="st_h">'shmop_write'</span><span class="sy0">,</span><span class="st_h">'shm_attach'</span><span class="sy0">,</span><span class="st_h">'shm_detach'</span><span class="sy0">,</span><span class="st_h">'shm_get_var'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'shm_put_var'</span><span class="sy0">,</span><span class="st_h">'shm_remove'</span><span class="sy0">,</span><span class="st_h">'shm_remove_var'</span><span class="sy0">,</span><span class="st_h">'show_source'</span><span class="sy0">,</span><span class="st_h">'shuffle'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'similar_text'</span><span class="sy0">,</span><span class="st_h">'simplexml_import_dom'</span><span class="sy0">,</span><span class="st_h">'simplexml_load_file'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'simplexml_load_string'</span><span class="sy0">,</span><span class="st_h">'sin'</span><span class="sy0">,</span><span class="st_h">'sinh'</span><span class="sy0">,</span><span class="st_h">'sizeof'</span><span class="sy0">,</span><span class="st_h">'sleep'</span><span class="sy0">,</span><span class="st_h">'smtp_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'smtp_cmd_data'</span><span class="sy0">,</span><span class="st_h">'smtp_cmd_mail'</span><span class="sy0">,</span><span class="st_h">'smtp_cmd_rcpt'</span><span class="sy0">,</span><span class="st_h">'smtp_connect'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'snmp_get_quick_print'</span><span class="sy0">,</span><span class="st_h">'snmp_get_valueretrieval'</span><span class="sy0">,</span><span class="st_h">'snmp_read_mib'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'snmp_set_quick_print'</span><span class="sy0">,</span><span class="st_h">'snmp_set_valueretrieval'</span><span class="sy0">,</span><span class="st_h">'snmp2_get'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'snmp2_getnext'</span><span class="sy0">,</span><span class="st_h">'snmp2_real_walk'</span><span class="sy0">,</span><span class="st_h">'snmp2_set'</span><span class="sy0">,</span><span class="st_h">'snmp2_walk'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'snmp3_get'</span><span class="sy0">,</span><span class="st_h">'snmp3_getnext'</span><span class="sy0">,</span><span class="st_h">'snmp3_real_walk'</span><span class="sy0">,</span><span class="st_h">'snmp3_set'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'snmp3_walk'</span><span class="sy0">,</span><span class="st_h">'snmpget'</span><span class="sy0">,</span><span class="st_h">'snmpgetnext'</span><span class="sy0">,</span><span class="st_h">'snmprealwalk'</span><span class="sy0">,</span><span class="st_h">'snmpset'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'snmpwalk'</span><span class="sy0">,</span><span class="st_h">'snmpwalkoid'</span><span class="sy0">,</span><span class="st_h">'socket_accept'</span><span class="sy0">,</span><span class="st_h">'socket_bind'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_clear_error'</span><span class="sy0">,</span><span class="st_h">'socket_close'</span><span class="sy0">,</span><span class="st_h">'socket_connect'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_create'</span><span class="sy0">,</span><span class="st_h">'socket_create_listen'</span><span class="sy0">,</span><span class="st_h">'socket_create_pair'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_getopt'</span><span class="sy0">,</span><span class="st_h">'socket_getpeername'</span><span class="sy0">,</span><span class="st_h">'socket_getsockname'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_get_option'</span><span class="sy0">,</span><span class="st_h">'socket_get_status'</span><span class="sy0">,</span><span class="st_h">'socket_iovec_add'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_iovec_alloc'</span><span class="sy0">,</span><span class="st_h">'socket_iovec_delete'</span><span class="sy0">,</span><span class="st_h">'socket_iovec_fetch'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_iovec_free'</span><span class="sy0">,</span><span class="st_h">'socket_iovec_set'</span><span class="sy0">,</span><span class="st_h">'socket_last_error'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_listen'</span><span class="sy0">,</span><span class="st_h">'socket_read'</span><span class="sy0">,</span><span class="st_h">'socket_readv'</span><span class="sy0">,</span><span class="st_h">'socket_recv'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_recvfrom'</span><span class="sy0">,</span><span class="st_h">'socket_recvmsg'</span><span class="sy0">,</span><span class="st_h">'socket_select'</span><span class="sy0">,</span><span class="st_h">'socket_send'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_sendmsg'</span><span class="sy0">,</span><span class="st_h">'socket_sendto'</span><span class="sy0">,</span><span class="st_h">'socket_setopt'</span><span class="sy0">,</span><span class="st_h">'socket_set_block'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_set_blocking'</span><span class="sy0">,</span><span class="st_h">'socket_set_nonblock'</span><span class="sy0">,</span><span class="st_h">'socket_set_option'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_set_timeout'</span><span class="sy0">,</span><span class="st_h">'socket_shutdown'</span><span class="sy0">,</span><span class="st_h">'socket_strerror'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'socket_write'</span><span class="sy0">,</span><span class="st_h">'socket_writev'</span><span class="sy0">,</span><span class="st_h">'sort'</span><span class="sy0">,</span><span class="st_h">'soundex'</span><span class="sy0">,</span><span class="st_h">'spl_autoload'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'spl_autoload_call'</span><span class="sy0">,</span><span class="st_h">'spl_autoload_extensions'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'spl_autoload_functions'</span><span class="sy0">,</span><span class="st_h">'spl_autoload_register'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'spl_autoload_unregister'</span><span class="sy0">,</span><span class="st_h">'spl_classes'</span><span class="sy0">,</span><span class="st_h">'spl_object_hash'</span><span class="sy0">,</span><span class="st_h">'split'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'spliti'</span><span class="sy0">,</span><span class="st_h">'sprintf'</span><span class="sy0">,</span><span class="st_h">'sql_regcase'</span><span class="sy0">,</span><span class="st_h">'sqlite_array_query'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_busy_timeout'</span><span class="sy0">,</span><span class="st_h">'sqlite_changes'</span><span class="sy0">,</span><span class="st_h">'sqlite_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_column'</span><span class="sy0">,</span><span class="st_h">'sqlite_create_aggregate'</span><span class="sy0">,</span><span class="st_h">'sqlite_create_function'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_current'</span><span class="sy0">,</span><span class="st_h">'sqlite_error_string'</span><span class="sy0">,</span><span class="st_h">'sqlite_escape_string'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_exec'</span><span class="sy0">,</span><span class="st_h">'sqlite_factory'</span><span class="sy0">,</span><span class="st_h">'sqlite_fetch_all'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_fetch_array'</span><span class="sy0">,</span><span class="st_h">'sqlite_fetch_column_types'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_fetch_object'</span><span class="sy0">,</span><span class="st_h">'sqlite_fetch_single'</span><span class="sy0">,</span><span class="st_h">'sqlite_fetch_string'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_field_name'</span><span class="sy0">,</span><span class="st_h">'sqlite_has_more'</span><span class="sy0">,</span><span class="st_h">'sqlite_has_prev'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_last_error'</span><span class="sy0">,</span><span class="st_h">'sqlite_last_insert_rowid'</span><span class="sy0">,</span><span class="st_h">'sqlite_libencoding'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_libversion'</span><span class="sy0">,</span><span class="st_h">'sqlite_next'</span><span class="sy0">,</span><span class="st_h">'sqlite_num_fields'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_num_rows'</span><span class="sy0">,</span><span class="st_h">'sqlite_open'</span><span class="sy0">,</span><span class="st_h">'sqlite_popen'</span><span class="sy0">,</span><span class="st_h">'sqlite_prev'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_query'</span><span class="sy0">,</span><span class="st_h">'sqlite_rewind'</span><span class="sy0">,</span><span class="st_h">'sqlite_seek'</span><span class="sy0">,</span><span class="st_h">'sqlite_single_query'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_udf_decode_binary'</span><span class="sy0">,</span><span class="st_h">'sqlite_udf_encode_binary'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sqlite_unbuffered_query'</span><span class="sy0">,</span><span class="st_h">'sqlite_valid'</span><span class="sy0">,</span><span class="st_h">'sqrt'</span><span class="sy0">,</span><span class="st_h">'srand'</span><span class="sy0">,</span><span class="st_h">'sscanf'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_auth_hostbased_file'</span><span class="sy0">,</span><span class="st_h">'ssh2_auth_none'</span><span class="sy0">,</span><span class="st_h">'ssh2_auth_password'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_auth_pubkey_file'</span><span class="sy0">,</span><span class="st_h">'ssh2_connect'</span><span class="sy0">,</span><span class="st_h">'ssh2_exec'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_fetch_stream'</span><span class="sy0">,</span><span class="st_h">'ssh2_fingerprint'</span><span class="sy0">,</span><span class="st_h">'ssh2_forward_accept'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_forward_listen'</span><span class="sy0">,</span><span class="st_h">'ssh2_methods_negotiated'</span><span class="sy0">,</span><span class="st_h">'ssh2_poll'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_publickey_add'</span><span class="sy0">,</span><span class="st_h">'ssh2_publickey_init'</span><span class="sy0">,</span><span class="st_h">'ssh2_publickey_list'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_publickey_remove'</span><span class="sy0">,</span><span class="st_h">'ssh2_scp_recv'</span><span class="sy0">,</span><span class="st_h">'ssh2_scp_send'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_sftp_lstat'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp_mkdir'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp_readlink'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_sftp_realpath'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp_rename'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp_rmdir'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_sftp_stat'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp_symlink'</span><span class="sy0">,</span><span class="st_h">'ssh2_sftp_unlink'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ssh2_shell'</span><span class="sy0">,</span><span class="st_h">'ssh2_tunnel'</span><span class="sy0">,</span><span class="st_h">'stat'</span><span class="sy0">,</span><span class="st_h">'stats_absolute_deviation'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_beta'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_binomial'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_cauchy'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_chisquare'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_exponential'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_f'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_gamma'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_laplace'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_logistic'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_negative_binomial'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_noncentral_chisquare'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_noncentral_f'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_noncentral_t'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_normal'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_poisson'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_t'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_cdf_uniform'</span><span class="sy0">,</span><span class="st_h">'stats_cdf_weibull'</span><span class="sy0">,</span><span class="st_h">'stats_covariance'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_dens_beta'</span><span class="sy0">,</span><span class="st_h">'stats_dens_cauchy'</span><span class="sy0">,</span><span class="st_h">'stats_dens_chisquare'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_dens_exponential'</span><span class="sy0">,</span><span class="st_h">'stats_dens_f'</span><span class="sy0">,</span><span class="st_h">'stats_dens_gamma'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_dens_laplace'</span><span class="sy0">,</span><span class="st_h">'stats_dens_logistic'</span><span class="sy0">,</span><span class="st_h">'stats_dens_normal'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_dens_pmf_binomial'</span><span class="sy0">,</span><span class="st_h">'stats_dens_pmf_hypergeometric'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_dens_pmf_negative_binomial'</span><span class="sy0">,</span><span class="st_h">'stats_dens_pmf_poisson'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_dens_t'</span><span class="sy0">,</span><span class="st_h">'stats_dens_uniform'</span><span class="sy0">,</span><span class="st_h">'stats_dens_weibull'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_harmonic_mean'</span><span class="sy0">,</span><span class="st_h">'stats_kurtosis'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_beta'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_gen_chisquare'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_exponential'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_gen_f'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_funiform'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_gamma'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_gen_ipoisson'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_iuniform'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_gen_noncenral_f'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_noncentral_chisquare'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_gen_noncentral_t'</span><span class="sy0">,</span><span class="st_h">'stats_rand_gen_normal'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_gen_t'</span><span class="sy0">,</span><span class="st_h">'stats_rand_getsd'</span><span class="sy0">,</span><span class="st_h">'stats_rand_ibinomial'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_ibinomial_negative'</span><span class="sy0">,</span><span class="st_h">'stats_rand_ignlgi'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_rand_phrase_to_seeds'</span><span class="sy0">,</span><span class="st_h">'stats_rand_ranf'</span><span class="sy0">,</span><span class="st_h">'stats_rand_setall'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_skew'</span><span class="sy0">,</span><span class="st_h">'stats_standard_deviation'</span><span class="sy0">,</span><span class="st_h">'stats_stat_binomial_coef'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_stat_correlation'</span><span class="sy0">,</span><span class="st_h">'stats_stat_factorial'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_stat_independent_t'</span><span class="sy0">,</span><span class="st_h">'stats_stat_innerproduct'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_stat_paired_t'</span><span class="sy0">,</span><span class="st_h">'stats_stat_percentile'</span><span class="sy0">,</span><span class="st_h">'stats_stat_powersum'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stats_variance'</span><span class="sy0">,</span><span class="st_h">'strcasecmp'</span><span class="sy0">,</span><span class="st_h">'strchr'</span><span class="sy0">,</span><span class="st_h">'strcmp'</span><span class="sy0">,</span><span class="st_h">'strcoll'</span><span class="sy0">,</span><span class="st_h">'strcspn'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_bucket_append'</span><span class="sy0">,</span><span class="st_h">'stream_bucket_make_writeable'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_bucket_new'</span><span class="sy0">,</span><span class="st_h">'stream_bucket_prepend'</span><span class="sy0">,</span><span class="st_h">'stream_context_create'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_context_get_default'</span><span class="sy0">,</span><span class="st_h">'stream_context_get_options'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_context_set_default'</span><span class="sy0">,</span><span class="st_h">'stream_context_set_option'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_context_set_params'</span><span class="sy0">,</span><span class="st_h">'stream_copy_to_stream'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_encoding'</span><span class="sy0">,</span><span class="st_h">'stream_filter_append'</span><span class="sy0">,</span><span class="st_h">'stream_filter_prepend'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_filter_register'</span><span class="sy0">,</span><span class="st_h">'stream_filter_remove'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_get_contents'</span><span class="sy0">,</span><span class="st_h">'stream_get_filters'</span><span class="sy0">,</span><span class="st_h">'stream_get_line'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_get_meta_data'</span><span class="sy0">,</span><span class="st_h">'stream_get_transports'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_get_wrappers'</span><span class="sy0">,</span><span class="st_h">'stream_is_local'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_notification_callback'</span><span class="sy0">,</span><span class="st_h">'stream_register_wrapper'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_resolve_include_path'</span><span class="sy0">,</span><span class="st_h">'stream_select'</span><span class="sy0">,</span><span class="st_h">'stream_set_blocking'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_set_timeout'</span><span class="sy0">,</span><span class="st_h">'stream_set_write_buffer'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_socket_accept'</span><span class="sy0">,</span><span class="st_h">'stream_socket_client'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_socket_enable_crypto'</span><span class="sy0">,</span><span class="st_h">'stream_socket_get_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_socket_pair'</span><span class="sy0">,</span><span class="st_h">'stream_socket_recvfrom'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_socket_sendto'</span><span class="sy0">,</span><span class="st_h">'stream_socket_server'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_socket_shutdown'</span><span class="sy0">,</span><span class="st_h">'stream_supports_lock'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_wrapper_register'</span><span class="sy0">,</span><span class="st_h">'stream_wrapper_restore'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stream_wrapper_unregister'</span><span class="sy0">,</span><span class="st_h">'strftime'</span><span class="sy0">,</span><span class="st_h">'stripcslashes'</span><span class="sy0">,</span><span class="st_h">'stripos'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'stripslashes'</span><span class="sy0">,</span><span class="st_h">'strip_tags'</span><span class="sy0">,</span><span class="st_h">'stristr'</span><span class="sy0">,</span><span class="st_h">'strlen'</span><span class="sy0">,</span><span class="st_h">'strnatcasecmp'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'strnatcmp'</span><span class="sy0">,</span><span class="st_h">'strpbrk'</span><span class="sy0">,</span><span class="st_h">'strncasecmp'</span><span class="sy0">,</span><span class="st_h">'strncmp'</span><span class="sy0">,</span><span class="st_h">'strpos'</span><span class="sy0">,</span><span class="st_h">'strrchr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'strrev'</span><span class="sy0">,</span><span class="st_h">'strripos'</span><span class="sy0">,</span><span class="st_h">'strrpos'</span><span class="sy0">,</span><span class="st_h">'strspn'</span><span class="sy0">,</span><span class="st_h">'strstr'</span><span class="sy0">,</span><span class="st_h">'strtok'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'strtolower'</span><span class="sy0">,</span><span class="st_h">'strtotime'</span><span class="sy0">,</span><span class="st_h">'strtoupper'</span><span class="sy0">,</span><span class="st_h">'strtr'</span><span class="sy0">,</span><span class="st_h">'strval'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'str_ireplace'</span><span class="sy0">,</span><span class="st_h">'str_pad'</span><span class="sy0">,</span><span class="st_h">'str_repeat'</span><span class="sy0">,</span><span class="st_h">'str_replace'</span><span class="sy0">,</span><span class="st_h">'str_rot13'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'str_split'</span><span class="sy0">,</span><span class="st_h">'str_shuffle'</span><span class="sy0">,</span><span class="st_h">'str_word_count'</span><span class="sy0">,</span><span class="st_h">'substr'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'substr_compare'</span><span class="sy0">,</span><span class="st_h">'substr_count'</span><span class="sy0">,</span><span class="st_h">'substr_replace'</span><span class="sy0">,</span><span class="st_h">'svn_add'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_auth_get_parameter'</span><span class="sy0">,</span><span class="st_h">'svn_auth_set_parameter'</span><span class="sy0">,</span><span class="st_h">'svn_cat'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_checkout'</span><span class="sy0">,</span><span class="st_h">'svn_cleanup'</span><span class="sy0">,</span><span class="st_h">'svn_client_version'</span><span class="sy0">,</span><span class="st_h">'svn_commit'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_diff'</span><span class="sy0">,</span><span class="st_h">'svn_export'</span><span class="sy0">,</span><span class="st_h">'svn_fs_abort_txn'</span><span class="sy0">,</span><span class="st_h">'svn_fs_apply_text'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_begin_txn2'</span><span class="sy0">,</span><span class="st_h">'svn_fs_change_node_prop'</span><span class="sy0">,</span><span class="st_h">'svn_fs_check_path'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_contents_changed'</span><span class="sy0">,</span><span class="st_h">'svn_fs_copy'</span><span class="sy0">,</span><span class="st_h">'svn_fs_delete'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_dir_entries'</span><span class="sy0">,</span><span class="st_h">'svn_fs_file_contents'</span><span class="sy0">,</span><span class="st_h">'svn_fs_file_length'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_is_dir'</span><span class="sy0">,</span><span class="st_h">'svn_fs_is_file'</span><span class="sy0">,</span><span class="st_h">'svn_fs_make_dir'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_make_file'</span><span class="sy0">,</span><span class="st_h">'svn_fs_node_created_rev'</span><span class="sy0">,</span><span class="st_h">'svn_fs_node_prop'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_props_changed'</span><span class="sy0">,</span><span class="st_h">'svn_fs_revision_prop'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_fs_revision_root'</span><span class="sy0">,</span><span class="st_h">'svn_fs_txn_root'</span><span class="sy0">,</span><span class="st_h">'svn_fs_youngest_rev'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_import'</span><span class="sy0">,</span><span class="st_h">'svn_info'</span><span class="sy0">,</span><span class="st_h">'svn_log'</span><span class="sy0">,</span><span class="st_h">'svn_ls'</span><span class="sy0">,</span><span class="st_h">'svn_repos_create'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_repos_fs'</span><span class="sy0">,</span><span class="st_h">'svn_repos_fs_begin_txn_for_commit'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_repos_fs_commit_txn'</span><span class="sy0">,</span><span class="st_h">'svn_repos_hotcopy'</span><span class="sy0">,</span><span class="st_h">'svn_repos_open'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'svn_repos_recover'</span><span class="sy0">,</span><span class="st_h">'svn_status'</span><span class="sy0">,</span><span class="st_h">'svn_update'</span><span class="sy0">,</span><span class="st_h">'symlink'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'sys_get_temp_dir'</span><span class="sy0">,</span><span class="st_h">'syslog'</span><span class="sy0">,</span><span class="st_h">'system'</span><span class="sy0">,</span><span class="st_h">'tan'</span><span class="sy0">,</span><span class="st_h">'tanh'</span><span class="sy0">,</span><span class="st_h">'tempnam'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'textdomain'</span><span class="sy0">,</span><span class="st_h">'thread_get'</span><span class="sy0">,</span><span class="st_h">'thread_include'</span><span class="sy0">,</span><span class="st_h">'thread_lock'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'thread_lock_try'</span><span class="sy0">,</span><span class="st_h">'thread_mutex_destroy'</span><span class="sy0">,</span><span class="st_h">'thread_mutex_init'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'thread_set'</span><span class="sy0">,</span><span class="st_h">'thread_start'</span><span class="sy0">,</span><span class="st_h">'thread_unlock'</span><span class="sy0">,</span><span class="st_h">'tidy_access_count'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_clean_repair'</span><span class="sy0">,</span><span class="st_h">'tidy_config_count'</span><span class="sy0">,</span><span class="st_h">'tidy_diagnose'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_error_count'</span><span class="sy0">,</span><span class="st_h">'tidy_get_body'</span><span class="sy0">,</span><span class="st_h">'tidy_get_config'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_get_error_buffer'</span><span class="sy0">,</span><span class="st_h">'tidy_get_head'</span><span class="sy0">,</span><span class="st_h">'tidy_get_html'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_get_html_ver'</span><span class="sy0">,</span><span class="st_h">'tidy_get_output'</span><span class="sy0">,</span><span class="st_h">'tidy_get_release'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_get_root'</span><span class="sy0">,</span><span class="st_h">'tidy_get_status'</span><span class="sy0">,</span><span class="st_h">'tidy_getopt'</span><span class="sy0">,</span><span class="st_h">'tidy_is_xhtml'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_is_xml'</span><span class="sy0">,</span><span class="st_h">'tidy_parse_file'</span><span class="sy0">,</span><span class="st_h">'tidy_parse_string'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'tidy_repair_file'</span><span class="sy0">,</span><span class="st_h">'tidy_repair_string'</span><span class="sy0">,</span><span class="st_h">'tidy_warning_count'</span><span class="sy0">,</span><span class="st_h">'time'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'timezone_abbreviations_list'</span><span class="sy0">,</span><span class="st_h">'timezone_identifiers_list'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'timezone_name_from_abbr'</span><span class="sy0">,</span><span class="st_h">'timezone_name_get'</span><span class="sy0">,</span><span class="st_h">'timezone_offset_get'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'timezone_open'</span><span class="sy0">,</span><span class="st_h">'timezone_transitions_get'</span><span class="sy0">,</span><span class="st_h">'tmpfile'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'token_get_all'</span><span class="sy0">,</span><span class="st_h">'token_name'</span><span class="sy0">,</span><span class="st_h">'touch'</span><span class="sy0">,</span><span class="st_h">'trigger_error'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'transliterate'</span><span class="sy0">,</span><span class="st_h">'transliterate_filters_get'</span><span class="sy0">,</span><span class="st_h">'trim'</span><span class="sy0">,</span><span class="st_h">'uasort'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ucfirst'</span><span class="sy0">,</span><span class="st_h">'ucwords'</span><span class="sy0">,</span><span class="st_h">'uksort'</span><span class="sy0">,</span><span class="st_h">'umask'</span><span class="sy0">,</span><span class="st_h">'uniqid'</span><span class="sy0">,</span><span class="st_h">'unixtojd'</span><span class="sy0">,</span><span class="st_h">'unlink'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'unpack'</span><span class="sy0">,</span><span class="st_h">'unregister_tick_function'</span><span class="sy0">,</span><span class="st_h">'unserialize'</span><span class="sy0">,</span><span class="st_h">'unset'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'urldecode'</span><span class="sy0">,</span><span class="st_h">'urlencode'</span><span class="sy0">,</span><span class="st_h">'user_error'</span><span class="sy0">,</span><span class="st_h">'use_soap_error_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'usleep'</span><span class="sy0">,</span><span class="st_h">'usort'</span><span class="sy0">,</span><span class="st_h">'utf8_decode'</span><span class="sy0">,</span><span class="st_h">'utf8_encode'</span><span class="sy0">,</span><span class="st_h">'var_dump'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'var_export'</span><span class="sy0">,</span><span class="st_h">'variant_abs'</span><span class="sy0">,</span><span class="st_h">'variant_add'</span><span class="sy0">,</span><span class="st_h">'variant_and'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_cast'</span><span class="sy0">,</span><span class="st_h">'variant_cat'</span><span class="sy0">,</span><span class="st_h">'variant_cmp'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_date_from_timestamp'</span><span class="sy0">,</span><span class="st_h">'variant_date_to_timestamp'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_div'</span><span class="sy0">,</span><span class="st_h">'variant_eqv'</span><span class="sy0">,</span><span class="st_h">'variant_fix'</span><span class="sy0">,</span><span class="st_h">'variant_get_type'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_idiv'</span><span class="sy0">,</span><span class="st_h">'variant_imp'</span><span class="sy0">,</span><span class="st_h">'variant_int'</span><span class="sy0">,</span><span class="st_h">'variant_mod'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_mul'</span><span class="sy0">,</span><span class="st_h">'variant_neg'</span><span class="sy0">,</span><span class="st_h">'variant_not'</span><span class="sy0">,</span><span class="st_h">'variant_or'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_pow'</span><span class="sy0">,</span><span class="st_h">'variant_round'</span><span class="sy0">,</span><span class="st_h">'variant_set'</span><span class="sy0">,</span><span class="st_h">'variant_set_type'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'variant_sub'</span><span class="sy0">,</span><span class="st_h">'variant_xor'</span><span class="sy0">,</span><span class="st_h">'version_compare'</span><span class="sy0">,</span><span class="st_h">'virtual'</span><span class="sy0">,</span><span class="st_h">'vfprintf'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'vprintf'</span><span class="sy0">,</span><span class="st_h">'vsprintf'</span><span class="sy0">,</span><span class="st_h">'wddx_add_vars'</span><span class="sy0">,</span><span class="st_h">'wddx_deserialize'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'wddx_packet_end'</span><span class="sy0">,</span><span class="st_h">'wddx_packet_start'</span><span class="sy0">,</span><span class="st_h">'wddx_serialize_value'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'wddx_serialize_vars'</span><span class="sy0">,</span><span class="st_h">'win_beep'</span><span class="sy0">,</span><span class="st_h">'win_browse_file'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win_browse_folder'</span><span class="sy0">,</span><span class="st_h">'win_create_link'</span><span class="sy0">,</span><span class="st_h">'win_message_box'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win_play_wav'</span><span class="sy0">,</span><span class="st_h">'win_shell_execute'</span><span class="sy0">,</span><span class="st_h">'win32_create_service'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_delete_service'</span><span class="sy0">,</span><span class="st_h">'win32_get_last_control_message'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_ps_list_procs'</span><span class="sy0">,</span><span class="st_h">'win32_ps_stat_mem'</span><span class="sy0">,</span><span class="st_h">'win32_ps_stat_proc'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_query_service_status'</span><span class="sy0">,</span><span class="st_h">'win32_scheduler_delete_task'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_scheduler_enum_tasks'</span><span class="sy0">,</span><span class="st_h">'win32_scheduler_get_task_info'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_scheduler_run'</span><span class="sy0">,</span><span class="st_h">'win32_scheduler_set_task_info'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_set_service_status'</span><span class="sy0">,</span><span class="st_h">'win32_start_service'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'win32_start_service_ctrl_dispatcher'</span><span class="sy0">,</span><span class="st_h">'win32_stop_service'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'wordwrap'</span><span class="sy0">,</span><span class="st_h">'xml_error_string'</span><span class="sy0">,</span><span class="st_h">'xml_get_current_byte_index'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_get_current_column_number'</span><span class="sy0">,</span><span class="st_h">'xml_get_current_line_number'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_get_error_code'</span><span class="sy0">,</span><span class="st_h">'xml_parse'</span><span class="sy0">,</span><span class="st_h">'xml_parser_create'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_parser_create_ns'</span><span class="sy0">,</span><span class="st_h">'xml_parser_free'</span><span class="sy0">,</span><span class="st_h">'xml_parser_get_option'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_parser_set_option'</span><span class="sy0">,</span><span class="st_h">'xml_parse_into_struct'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_character_data_handler'</span><span class="sy0">,</span><span class="st_h">'xml_set_default_handler'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_element_handler'</span><span class="sy0">,</span><span class="st_h">'xml_set_end_namespace_decl_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_external_entity_ref_handler'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_notation_decl_handler'</span><span class="sy0">,</span><span class="st_h">'xml_set_object'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_processing_instruction_handler'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_start_namespace_decl_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_unparsed_entity_decl_handler'</span><span class="sy0">,</span><span class="st_h">'xmldoc'</span><span class="sy0">,</span><span class="st_h">'xmldocfile'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_decode'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_decode_request'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_encode'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_encode_request'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_get_type'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_is_fault'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_parse_method_descriptions'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_server_add_introspection_data'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_server_call_method'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_server_create'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_server_destroy'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_server_register_introspection_callback'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlrpc_server_register_method'</span><span class="sy0">,</span><span class="st_h">'xmlrpc_set_type'</span><span class="sy0">,</span><span class="st_h">'xmltree'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_end_attribute'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_end_cdata'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_end_comment'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_end_document'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_end_dtd'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_end_dtd_attlist'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_end_dtd_element'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_end_dtd_entity'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_end_element'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_end_pi'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_flush'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_full_end_element'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_open_memory'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_open_uri'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_output_memory'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_set_indent'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_set_indent_string'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_start_attribute'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_start_attribute_ns'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_start_cdata'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_start_comment'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_start_document'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_start_dtd'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_start_dtd_attlist'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_start_dtd_element'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_start_dtd_entity'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_start_element'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_start_element_ns'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_start_pi'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_text'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_write_attribute'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_write_attribute_ns'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_write_cdata'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_write_comment'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_write_dtd'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_write_dtd_attlist'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_write_dtd_element'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_write_dtd_entity'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_write_element'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_write_element_ns'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xmlwriter_write_pi'</span><span class="sy0">,</span><span class="st_h">'xmlwriter_write_raw'</span><span class="sy0">,</span><span class="st_h">'xpath_eval'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xpath_eval_expression'</span><span class="sy0">,</span><span class="st_h">'xpath_new_context'</span><span class="sy0">,</span><span class="st_h">'xpath_register_ns'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xpath_register_ns_auto'</span><span class="sy0">,</span><span class="st_h">'xptr_eval'</span><span class="sy0">,</span><span class="st_h">'xptr_new_context'</span><span class="sy0">,</span><span class="st_h">'yp_all'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'yp_cat'</span><span class="sy0">,</span><span class="st_h">'yp_errno'</span><span class="sy0">,</span><span class="st_h">'yp_err_string'</span><span class="sy0">,</span><span class="st_h">'yp_first'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'yp_get_default_domain'</span><span class="sy0">,</span><span class="st_h">'yp_master'</span><span class="sy0">,</span><span class="st_h">'yp_match'</span><span class="sy0">,</span><span class="st_h">'yp_next'</span><span class="sy0">,</span><span class="st_h">'yp_order'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_current_obfuscation_level'</span><span class="sy0">,</span><span class="st_h">'zend_get_cfg_var'</span><span class="sy0">,</span><span class="st_h">'zend_get_id'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_loader_current_file'</span><span class="sy0">,</span><span class="st_h">'zend_loader_enabled'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_loader_file_encoded'</span><span class="sy0">,</span><span class="st_h">'zend_loader_file_licensed'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_loader_install_license'</span><span class="sy0">,</span><span class="st_h">'zend_loader_version'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_logo_guid'</span><span class="sy0">,</span><span class="st_h">'zend_match_hostmasks'</span><span class="sy0">,</span><span class="st_h">'zend_obfuscate_class_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_obfuscate_function_name'</span><span class="sy0">,</span><span class="st_h">'zend_optimizer_version'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zend_runtime_obfuscate'</span><span class="sy0">,</span><span class="st_h">'zend_version'</span><span class="sy0">,</span><span class="st_h">'zip_close'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zip_entry_close'</span><span class="sy0">,</span><span class="st_h">'zip_entry_compressedsize'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zip_entry_compressionmethod'</span><span class="sy0">,</span><span class="st_h">'zip_entry_filesize'</span><span class="sy0">,</span><span class="st_h">'zip_entry_name'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zip_entry_open'</span><span class="sy0">,</span><span class="st_h">'zip_entry_read'</span><span class="sy0">,</span><span class="st_h">'zip_open'</span><span class="sy0">,</span><span class="st_h">'zip_read'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zlib_get_coding_type'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'DEFAULT_INCLUDE_PATH'</span><span class="sy0">,</span> <span class="st_h">'DIRECTORY_SEPARATOR'</span><span class="sy0">,</span> <span class="st_h">'E_ALL'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_COMPILE_ERROR'</span><span class="sy0">,</span> <span class="st_h">'E_COMPILE_WARNING'</span><span class="sy0">,</span> <span class="st_h">'E_CORE_ERROR'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_CORE_WARNING'</span><span class="sy0">,</span> <span class="st_h">'E_ERROR'</span><span class="sy0">,</span> <span class="st_h">'E_NOTICE'</span><span class="sy0">,</span> <span class="st_h">'E_PARSE'</span><span class="sy0">,</span> <span class="st_h">'E_STRICT'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_USER_ERROR'</span><span class="sy0">,</span> <span class="st_h">'E_USER_NOTICE'</span><span class="sy0">,</span> <span class="st_h">'E_USER_WARNING'</span><span class="sy0">,</span> <span class="st_h">'E_WARNING'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ENT_COMPAT'</span><span class="sy0">,</span><span class="st_h">'ENT_QUOTES'</span><span class="sy0">,</span><span class="st_h">'ENT_NOQUOTES'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'false'</span><span class="sy0">,</span> <span class="st_h">'null'</span><span class="sy0">,</span> <span class="st_h">'PEAR_EXTENSION_DIR'</span><span class="sy0">,</span> <span class="st_h">'PEAR_INSTALL_DIR'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_BINDIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_CONFIG_FILE_PATH'</span><span class="sy0">,</span> <span class="st_h">'PHP_DATADIR'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_EXTENSION_DIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_LIBDIR'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_LOCALSTATEDIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_OS'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_OUTPUT_HANDLER_CONT'</span><span class="sy0">,</span> <span class="st_h">'PHP_OUTPUT_HANDLER_END'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_OUTPUT_HANDLER_START'</span><span class="sy0">,</span> <span class="st_h">'PHP_SYSCONFDIR'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_VERSION'</span><span class="sy0">,</span> <span class="st_h">'true'</span><span class="sy0">,</span> <span class="st_h">'__CLASS__'</span><span class="sy0">,</span> <span class="st_h">'__FILE__'</span><span class="sy0">,</span> <span class="st_h">'__FUNCTION__'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'__LINE__'</span><span class="sy0">,</span> <span class="st_h">'__METHOD__'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'SYMBOLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;%'</span><span class="sy0">,</span> <span class="st_h">'&lt;%='</span><span class="sy0">,</span> <span class="st_h">'%&gt;'</span><span class="sy0">,</span> <span class="st_h">'&lt;?'</span><span class="sy0">,</span> <span class="st_h">'&lt;?='</span><span class="sy0">,</span> <span class="st_h">'?&gt;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'('</span><span class="sy0">,</span> <span class="st_h">')'</span><span class="sy0">,</span> <span class="st_h">'['</span><span class="sy0">,</span> <span class="st_h">']'</span><span class="sy0">,</span> <span class="st_h">'{'</span><span class="sy0">,</span> <span class="st_h">'}'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'!'</span><span class="sy0">,</span> <span class="st_h">'@'</span><span class="sy0">,</span> <span class="st_h">'%'</span><span class="sy0">,</span> <span class="st_h">'&amp;'</span><span class="sy0">,</span> <span class="st_h">'|'</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;'</span><span class="sy0">,</span> <span class="st_h">'&gt;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'='</span><span class="sy0">,</span> <span class="st_h">'-'</span><span class="sy0">,</span> <span class="st_h">'+'</span><span class="sy0">,</span> <span class="st_h">'*'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'.'</span><span class="sy0">,</span> <span class="st_h">':'</span><span class="sy0">,</span> <span class="st_h">','</span><span class="sy0">,</span> <span class="st_h">';'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'CASE_SENSITIVE'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; GESHI_COMMENTS <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'STYLES'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'KEYWORDS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #b1b100;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000000; font-weight: bold;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #990000;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #009900; font-weight: bold;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'COMMENTS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #666666; font-style: italic;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #666666; font-style: italic;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #0000cc; font-style: italic;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #009933; font-style: italic;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'MULTI'</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #666666; font-style: italic;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ESCAPE_CHAR'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000099; font-weight: bold;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000099; font-weight: bold;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #660099; font-weight: bold;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #660099; font-weight: bold;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #006699; font-weight: bold;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #006699; font-weight: bold; font-style: italic;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">6</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #009933; font-weight: bold;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'HARD'</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000099; font-weight: bold;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'BRACKETS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #009900;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'STRINGS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #0000ff;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'HARD'</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #0000ff;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'NUMBERS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #cc66cc;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_OCT_PREFIX <span class="sy0">=&gt;</span> <span class="st_h">'color: #208080;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_HEX_PREFIX <span class="sy0">=&gt;</span> <span class="st_h">'color: #208080;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_FLT_SCI_ZERO <span class="sy0">=&gt;</span> <span class="st_h">'color:#800080;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'METHODS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #004000;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #004000;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'SYMBOLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #339933;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000000; font-weight: bold;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'REGEXPS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000088;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'SCRIPT'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'URLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'http://www.php.net/{FNAMEL}'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'OOLANG'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'OBJECT_SPLITTERS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'-&amp;gt;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'::'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'REGEXPS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//Variables</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;[<span class="es1">\\</span>$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*&quot;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'STRICT_MODE_APPLIES'</span> <span class="sy0">=&gt;</span> GESHI_MAYBE<span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'SCRIPT_DELIMITERS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;?php'</span> <span class="sy0">=&gt;</span> <span class="st_h">'?&gt;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;?'</span> <span class="sy0">=&gt;</span> <span class="st_h">'?&gt;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;%'</span> <span class="sy0">=&gt;</span> <span class="st_h">'%&gt;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;script language=&quot;php&quot;&gt;'</span> <span class="sy0">=&gt;</span> <span class="st_h">'&lt;/script&gt;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;/(&lt;\?(?:php)?)(?:'(?:[^'<span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?'|<span class="es1">\&quot;</span>(?:[^<span class="es1">\&quot;</span><span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?<span class="es1">\&quot;</span>|\/\*(?!\*\/).*?\*\/|.)*?(\?&gt;|\Z)/sm&quot;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;/(&lt;%)(?:'(?:[^'<span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?'|<span class="es1">\&quot;</span>(?:[^<span class="es1">\&quot;</span><span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?<span class="es1">\&quot;</span>|\/\*(?!\*\/).*?\*\/|.)*?(%&gt;|\Z)/sm&quot;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'HIGHLIGHT_STRICT_BLOCK'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'TAB_WIDTH'</span> <span class="sy0">=&gt;</span> <span class="nu0">4</span>
+<span class="xtra li2"><span class="de2"><span class="br0">&#41;</span><span class="sy0">;</span></span></span>&nbsp;
+<span class="xtra li2"><span class="de2"><span class="sy1">?&gt;</span></span></span></pre></td></tr></tbody></table>
+
+<p>If you&#8217;re remotely familiar with <abbr title="PHP: HTML Preprocessor">PHP</abbr> (or even if you&#8217;re not), you can see that all that a language file consists of is
+a glorified variable assignment. Easy! All a language file does is assign a variable <code class="highlighted php"><span class="re0">$language_data</span></code>. Though
+still, there&#8217;s a lot of indices to that array&#8230; but this section is here to break each index down and explain it to you.</p>
+
+<h3 id="language-file-conventions">4.2 Language File Conventions</h3><div class="nav"><a href="#language-file-example">Previous</a> | <a href="#language-files">Top</a> | <a href="#language-file-sections">Next</a></div>
+
+<p>There are several conventions that are used in language files. For ease of use and readability, your language
+files should obey the following rules:</p>
+
+<ul>
+<li><strong>Indentation is <em>4 spaces</em>, not tabs:</strong> Use spaces! as editors continiously screw up tabs there should be
+no tabs in your documents since it would look differently on every computer otherwise.</li>
+<li><strong>Strings are in single quotes:</strong> Every string in a language file should be in single quotes (&#8216;), unless you are
+specifying a single quote as a quotemark or escape character, in which case they can be in double quotes for
+readability; or if you are specifying a REGEXP (see below). This ensures that the language file can be loaded
+as fast as possible by <abbr title="PHP: HTML Preprocessor">PHP</abbr> as unnecessary parsing can be avoided.</li>
+<li><strong>Large arrays are multi-lined:</strong> An array with more than three or four values should be broken into multiple
+lines. In any case, lines should not be wider than a full-screen window (about 100 chars per line max).
+Don&#8217;t break the keywords arrays after every keyword.</li>
+<li><strong>Ending brackets for multi-lined arrays on a new line:</strong> Also with a comma after them, unless the array is
+the last one in a parent array. See the <abbr title="PHP: HTML Preprocessor">PHP</abbr> language file for examples of where to use commas.</li>
+<li><strong>Use <abbr title="Generic Syntax Highlighter">GeSHi</abbr>&#8217;s constants:</strong> For capatalisation, regular expressions etc. use the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> constants, <em>not</em>
+their actual values.</li>
+<li><strong>Verbatim header format:</strong> Copy the file header verbatim from other language files and modify the values
+afterwards. Don&#8217;t try to invent own header formats, as your languages else will fail validation!</li>
+</ul>
+
+<p>There are more notes on each convention where it may appear in the language file sections below.</p>
+
+<h3 id="language-file-sections">4.3 Language File Sections</h3><div class="nav"><a href="#language-file-conventions">Previous</a> | <a href="#language-files">Top</a> | <a href="#language-file-header">Next</a></div>
+
+<p>This section will look at all the sections of a language file, and how they relate to the final highlighting result.</p>
+
+<h4 id="language-file-header">4.3.1 The Header</h4><div class="nav"><a href="#language-file-sections">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-start-indices">Next</a></div>
+
+<p>The <em>header</em> of a language file is the first lines with the big comment and the start of the variable
+<code class="highlighted php"><span class="re0">$language_data</span></code>:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+<span class="xtra li2"><span class="de2">28</span></span>29
+<span class="xtra li2"><span class="de2">30</span></span>31
+<span class="xtra li2"><span class="de2">32</span></span>33
+<span class="xtra li2"><span class="de2">34</span></span>35
+<span class="xtra li2"><span class="de2">36</span></span>37
+<span class="xtra li2"><span class="de2">38</span></span>39
+<span class="xtra li2"><span class="de2">40</span></span>41
+<span class="xtra li2"><span class="de2">42</span></span>43
+</pre></td><td class="de1"><pre class="de1"><span class="kw2">&lt;?php</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">/*************************************************************************************</span></span></span><span class="coMULTI">&nbsp;* &lt;name-of-language-file.php&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* ---------------------------------</span></span></span><span class="coMULTI">&nbsp;* Author: &lt;name&gt; (&lt;e-mail address&gt;)</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* Copyright: (c) 2008 &lt;name&gt; (&lt;website URL&gt;)</span></span></span><span class="coMULTI">&nbsp;* Release Version: &lt;GeSHi release&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* Date Started: &lt;date started&gt;</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &lt;name-of-language&gt; language file for GeSHi.</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &lt;any-comments...&gt;</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* CHANGES</span></span></span><span class="coMULTI">&nbsp;* -------</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &lt;date-of-release&gt; (&lt;GeSHi release&gt;)</span></span></span><span class="coMULTI">&nbsp;* &nbsp;- &nbsp;First Release</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* TODO (updated &lt;date-of-release&gt;)</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* -------------------------</span></span></span><span class="coMULTI">&nbsp;* &lt;things-to-do&gt;</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;*************************************************************************************</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* &nbsp; &nbsp; This file is part of GeSHi.</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* &nbsp; GeSHi is free software; you can redistribute it and/or modify</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; it under the terms of the GNU General Public License as published by</span></span></span><span class="coMULTI">&nbsp;* &nbsp; the Free Software Foundation; either version 2 of the License, or</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; (at your option) any later version.</span></span></span><span class="coMULTI">&nbsp;*</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; GeSHi is distributed in the hope that it will be useful,</span></span></span><span class="coMULTI">&nbsp;* &nbsp; but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. &nbsp;See the</span></span></span><span class="coMULTI">&nbsp;* &nbsp; GNU General Public License for more details.</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;* &nbsp; You should have received a copy of the GNU General Public License</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;* &nbsp; along with GeSHi; if not, write to the Free Software</span></span></span><span class="coMULTI">&nbsp;* &nbsp; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA &nbsp;02111-1307 &nbsp;USA</span>
+<span class="xtra li2"><span class="de2"><span class="coMULTI">&nbsp;*</span></span></span><span class="coMULTI">&nbsp;************************************************************************************/</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="re0">$language_data</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span></pre></td></tr></tbody></table>
+
+<p>The parts in angle brackets are the parts that you change for your language file. <strong>Everything else <em>must</em> remain the same!</strong></p>
+
+<p>Here are the parts you should change:</p>
+
+<ul>
+<li><code>&lt;name-of-language-file.php&gt;</code> - This should become the name of your language file. Language file names are in
+lower case and contain only alphanumeric characters, dashes and underscores. Language files end with .php (which
+you should put with the name of your language file, eg language.php)</li>
+<li><code>&lt;name&gt;</code> - Your name, or alias.</li>
+<li><code>&lt;e-mail address&gt;</code> - Your e-mail address. If you want your language file included with <abbr title="Generic Syntax Highlighter">GeSHi</abbr> you <em>must</em>
+include an e-mail address that refers to an inbox controlled by you.</li>
+<li><code>&lt;website&gt;</code> - A URL of a website of yours (perhaps to a page that deals with your contribution to <abbr title="Generic Syntax Highlighter">GeSHi</abbr>, or
+your home page/blog)</li>
+<li><code>&lt;date-started&gt;</code> - The date you started working on the language file. If you can&#8217;t remember, guestimate.</li>
+<li><code>&lt;name-of-language&gt;</code> - The name of the language you made this language file for (probably similar to
+the language file name).</li>
+<li><code>&lt;any-comments&gt;</code> - Any comments you have to make about this language file, perhaps on where you got the keywords for,
+what dialect of the language this language file is for etc etc. If you don&#8217;t have any comments, remove the space for them.</li>
+<li><code>&lt;date-of-release</code> - The date you released the language file to the public. If you simply send it to me for inclusion
+in a new <abbr title="Generic Syntax Highlighter">GeSHi</abbr> and don&#8217;t release it, leave this blank, and I&#8217;ll replace it with the date of the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> release that
+it is first added to.</li>
+<li><code>&lt;GeSHi release&gt;</code> - This is the version of the release that will contain the changes you made.
+So if you have version 1.0.8 of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> running this will be the next version to be released, e.g. 1.0.8.1.</li>
+</ul>
+
+<p>Everything should remain the same.</p>
+
+<p><strong>Also:</strong> I&#8217;m not sure about the copyright on a new language file. I&#8217;m not a lawyer, could someone contact me about
+whether the copyright for a new language file should be exclusivly the authors, or joint with me (if included in a
+<abbr title="Generic Syntax Highlighter">GeSHi</abbr> release)?</p>
+
+<h4 id="language-file-start-indices">4.3.2 The First Indices</h4><div class="nav"><a href="#language-file-header">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-keywords">Next</a></div>
+
+<p>Here is an example from the php language file of the first indices:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span></pre></td><td class="de1"><pre class="de1"><span class="st_h">'LANG_NAME'</span> <span class="sy0">=&gt;</span> <span class="st_h">'PHP'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">'COMMENT_SINGLE'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'//'</span><span class="sy0">,</span> <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'#'</span><span class="br0">&#41;</span><span class="sy0">,</span></span></span><span class="st_h">'COMMENT_MULTI'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'/*'</span> <span class="sy0">=&gt;</span> <span class="st_h">'*/'</span><span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">'CASE_KEYWORDS'</span> <span class="sy0">=&gt;</span> GESHI_CAPS_NO_CHANGE<span class="sy0">,</span></span></span><span class="st_h">'QUOTEMARKS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&quot;'&quot;</span><span class="sy0">,</span> <span class="st_h">'&quot;'</span><span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">'ESCAPE_CHAR'</span> <span class="sy0">=&gt;</span> <span class="st_h">'\\'</span><span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<p>The first indices are the first few lines of a language file before the KEYWORDS index. These indices specify:</p>
+
+<ul>
+<li><strong>&#8216;LANG_NAME&#8217;</strong>: The name of the language. This name should be a human-readable version of the name
+(e.g. <abbr title="Hypertext Markup Language">HTML</abbr> 4 (transitional) instead of html4trans)</li>
+<li><strong>&#8216;COMMENT_SINGLE&#8217;:</strong> An array of single-line comments in your language, indexed by integers starting
+from 1. A single line comment is a comment that starts at the marker and goes until the end of the line. These
+comments may be any length > 0, and since they can be styled individually, can be used for other things than comments
+(for example the Java language file defines &#8220;import&#8221; as a single line comment). If you are making a language that
+uses a &#8217; (apostrophe) as a comment (or in the comment marker somewhere), use double quotes. e.g.: &#8220;&#8217;&#8221;</li>
+<li><strong>&#8216;COMMENT_MULTI&#8217;:</strong> Used to specify multiline comments, an array in the form &#8216;OPEN&#8217; => &#8216;CLOSE&#8217;. Unfortunately,
+all of these comments you add here will be styled the same way (an area of improvement for <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.2.X).
+These comment markers may be any length > 0.</li>
+<li><strong>&#8216;CASE_KEYWORDS&#8217;:</strong> Used to set whether the case of keywords should be changed automatically as they are found.
+For example, in an SQL or BASIC dialect you may want all keywords to be upper case. The accepted values for this are:</li>
+<li><code>GESHI_CAPS_UPPER</code>: Convert the case of all keywords to upper case.</li>
+<li><code>GESHI_CAPS_LOWER</code>: Convert the case of all keywords to lower case.</li>
+<li><code>GESHI_CAPS_NO_CHANGE</code>: Don&#8217;t change the case of any keyword.</li>
+<li><strong>&#8216;QUOTEMARKS&#8217;:</strong> Specifies the characters that mark the beginning and end of a string. This is another example
+where if your language includes the &#8217; string delimiter you should use double quotes around it.</li>
+<li><strong>&#8216;ESCAPE_CHAR&#8217;:</strong> Specifies the escape character used in all strings. If your language does not have an escape
+character then make this the empty string (<code>''</code>). This is not an array! If found, any character after an
+escape character and the escape character itself will be highlighted differently, and the character after the
+escape character cannot end a string.</li>
+</ul>
+
+<p>In some language files you might see here other indices too, but those are dealt with later on.</p>
+
+<h4 id="language-file-keywords">4.3.3 Keywords</h4><div class="nav"><a href="#language-file-start-indices">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-symbols-case">Next</a></div>
+
+<p>Keywords will make up the bulk of a language file. In this part you add keywords for your language, including
+inbuilt functions, data types, predefined constants etc etc.</p>
+
+<p>Here&#8217;s a (shortened) example from the php language file:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+<span class="xtra li2"><span class="de2">28</span></span>29
+<span class="xtra li2"><span class="de2">30</span></span>31
+<span class="xtra li2"><span class="de2">32</span></span>33
+<span class="xtra li2"><span class="de2">34</span></span>35
+<span class="xtra li2"><span class="de2">36</span></span>37
+<span class="xtra li2"><span class="de2">38</span></span>39
+<span class="xtra li2"><span class="de2">40</span></span></pre></td><td class="de1"><pre class="de1"><span class="st_h">'KEYWORDS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'as'</span><span class="sy0">,</span> <span class="st_h">'break'</span><span class="sy0">,</span> <span class="st_h">'case'</span><span class="sy0">,</span> <span class="st_h">'do'</span><span class="sy0">,</span> <span class="st_h">'else'</span><span class="sy0">,</span> <span class="st_h">'elseif'</span><span class="sy0">,</span> <span class="st_h">'endif'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'endswitch'</span><span class="sy0">,</span> <span class="st_h">'endwhile'</span><span class="sy0">,</span> <span class="st_h">'for'</span><span class="sy0">,</span> <span class="st_h">'foreach'</span><span class="sy0">,</span> <span class="st_h">'if'</span><span class="sy0">,</span> <span class="st_h">'include'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'include_once'</span><span class="sy0">,</span> <span class="st_h">'require'</span><span class="sy0">,</span> <span class="st_h">'require_once'</span><span class="sy0">,</span> <span class="st_h">'return'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'switch'</span><span class="sy0">,</span> <span class="st_h">'while'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&amp;lt;/script&gt;'</span><span class="sy0">,</span> <span class="st_h">'&amp;lt;?'</span><span class="sy0">,</span> <span class="st_h">'&amp;lt;?php'</span><span class="sy0">,</span> <span class="st_h">'&amp;lt;script language='</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'?&gt;'</span><span class="sy0">,</span> <span class="st_h">'class'</span><span class="sy0">,</span> <span class="st_h">'default'</span><span class="sy0">,</span> <span class="st_h">'DEFAULT_INCLUDE_PATH'</span><span class="sy0">,</span> <span class="st_h">'E_ALL'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_COMPILE_ERROR'</span><span class="sy0">,</span> <span class="st_h">'E_COMPILE_WARNING'</span><span class="sy0">,</span> <span class="st_h">'E_CORE_ERROR'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_CORE_WARNING'</span><span class="sy0">,</span> <span class="st_h">'E_ERROR'</span><span class="sy0">,</span> <span class="st_h">'E_NOTICE'</span><span class="sy0">,</span> <span class="st_h">'E_PARSE'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_USER_ERROR'</span><span class="sy0">,</span> <span class="st_h">'E_USER_NOTICE'</span><span class="sy0">,</span> <span class="st_h">'E_USER_WARNING'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'E_WARNING'</span><span class="sy0">,</span> <span class="st_h">'false'</span><span class="sy0">,</span> <span class="st_h">'function'</span><span class="sy0">,</span> <span class="st_h">'new'</span><span class="sy0">,</span> <span class="st_h">'null'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PEAR_EXTENSION_DIR'</span><span class="sy0">,</span> <span class="st_h">'PEAR_INSTALL_DIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_BINDIR'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_CONFIG_FILE_PATH'</span><span class="sy0">,</span> <span class="st_h">'PHP_DATADIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_EXTENSION_DIR'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_LIBDIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_LOCALSTATEDIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_OS'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_OUTPUT_HANDLER_CONT'</span><span class="sy0">,</span> <span class="st_h">'PHP_OUTPUT_HANDLER_END'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'PHP_OUTPUT_HANDLER_START'</span><span class="sy0">,</span> <span class="st_h">'PHP_SYSCONFDIR'</span><span class="sy0">,</span> <span class="st_h">'PHP_VERSION'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'true'</span><span class="sy0">,</span> <span class="st_h">'var'</span><span class="sy0">,</span> <span class="st_h">'__CLASS__'</span><span class="sy0">,</span> <span class="st_h">'__FILE__'</span><span class="sy0">,</span> <span class="st_h">'__FUNCTION__'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'__LINE__'</span><span class="sy0">,</span> <span class="st_h">'__METHOD__'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_parser_create'</span><span class="sy0">,</span> <span class="st_h">'xml_parser_create_ns'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_parser_free'</span><span class="sy0">,</span> <span class="st_h">'xml_parser_get_option'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_parser_set_option'</span><span class="sy0">,</span> <span class="st_h">'xml_parse_into_struct'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_character_data_handler'</span><span class="sy0">,</span> <span class="st_h">'xml_set_default_handler'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_element_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_end_namespace_decl_handler'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_external_entity_ref_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_notation_decl_handler'</span><span class="sy0">,</span> <span class="st_h">'xml_set_object'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_processing_instruction_handler'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_start_namespace_decl_handler'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'xml_set_unparsed_entity_decl_handler'</span><span class="sy0">,</span> <span class="st_h">'yp_all'</span><span class="sy0">,</span> <span class="st_h">'yp_cat'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'yp_errno'</span><span class="sy0">,</span> <span class="st_h">'yp_err_string'</span><span class="sy0">,</span> <span class="st_h">'yp_first'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'yp_get_default_domain'</span><span class="sy0">,</span> <span class="st_h">'yp_master'</span><span class="sy0">,</span> <span class="st_h">'yp_match'</span><span class="sy0">,</span> <span class="st_h">'yp_next'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'yp_order'</span><span class="sy0">,</span> <span class="st_h">'zend_logo_guid'</span><span class="sy0">,</span> <span class="st_h">'zend_version'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'zlib_get_coding_type'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<p>You can see that the index &#8216;KEYWORDS&#8217; refers to an array of arrays, indexed by positive integers. In each array,
+there are some keywords (in the actual php language file there is in fact many more keywords in the array indexed by 3).
+Here are some points to note about these keywords:</p>
+
+<ul>
+<li><strong>Indexed by positive integers:</strong> Use nothing else! I may change this in 1.2.X, but for the 1.0.X series,
+use positive integers only. Using strings here results in unnecessary overhead degrading performance when
+highlighting code with your language file!</li>
+<li><strong>Keywords sorted ascending:</strong> Keywords <em>should</em> be sorted in <em>ascending</em> order. This is mainly for
+readability. An issue with versions before 1.0.8 has been solved, so the reverse sorting order
+is no longer required and should thus be avoided. <abbr title="Generic Syntax Highlighter">GeSHi</abbr> itself sorts the keywords internally when
+building some of its caches, so the order doesn&#8217;t matter, but makes things easier to read and maintain.</li>
+<li><strong>Keywords are case sensitive (sometimes):</strong> If your language is case-sensitive, the correct casing of the
+keywords is defined as the case of the keywords in these keyword arrays. If you check the java language file you
+will see that everything is in exact casing. So if any of these keyword arrays are case sensitive, put the
+keywords in as their correct case! (note that which groups are case sensitive and which are not is configurable,
+see later on). If a keyword group is case insensitive, put the lowercase version of the keyword here
+<strong>OR</strong> in case documentation links require a special casing (other than all lowercase or all uppercase)
+the casing required for them use their casing.</li>
+<li><strong>Keywords must be in <code class="highlighted php"><span class="kw3">htmlentities</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code> form:</strong> All keywords should be written as if they had been
+run through the php function <code class="highlighted php"><span class="kw3">htmlentities</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code>. E.g, the keyword is <code class="highlighted html4strict"><span class="sc1">&amp;lt;</span>foo<span class="sc1">&amp;gt;</span></code>, not
+<code class="highlighted html4strict"><span class="sc2">&lt;foo&gt;</span></code></li>
+<li><strong>Don&#8217;t use keywords to highlight symbols:</strong> Just don&#8217;t!!! It doesn&#8217;t work, and there is seperate support
+for symbols since <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.7.21.</li>
+<li><strong>Markup Languages are special cases:</strong> Check the html4strict language file for an example: You need to tweak
+the Parser control here to tell the surroundings of tagnames. In case of doubt, feel free to ask.</li>
+</ul>
+
+<h4 id="language-file-symbols-case">4.3.4 Symbols and Case Sensitivity</h4><div class="nav"><a href="#language-file-keywords">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-styles">Next</a></div>
+
+<p>So you&#8217;ve put all the keywords for your language in? Now for a breather before we style them :). Symbols define
+what symbols your language uses. These are things like colons, brackets/braces, and other such general punctuation.
+No alphanumeric stuff belongs here, just the same as no symbols belong into the keywords section.</p>
+
+<p>As of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> version 1.0.7.21 the symbols section can be used in two ways:</p>
+
+<dl>
+<dt>Flat usage:</dt>
+<dd>This mode is the suggested way for existing language files and languages that only need few symbols where no
+further differentiation is needed or desired. You simply put all the characters in an array under symbols as shown
+in the first example below. All symbols in flat usage belong to symbol style group 0.</dd>
+
+<dt>Group usage:</dt>
+<dd>This is a slightly more enhanced way to provide <abbr title="Generic Syntax Highlighter">GeSHi</abbr> symbol information. To use group you create several subarrays
+each containing only a subset of the symbols to highlight. Every array will need to have an unique index thus
+you can assign the appropriate styles later.</dd>
+</dl>
+
+<p>Here&#8217;s an example for flat symbol usage</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+</pre></td><td class="de1"><pre class="de1"><span class="st_h">'SYMBOLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; <span class="st_h">'('</span><span class="sy0">,</span> <span class="st_h">')'</span><span class="sy0">,</span> <span class="st_h">'['</span><span class="sy0">,</span> <span class="st_h">']'</span><span class="sy0">,</span> <span class="st_h">'{'</span><span class="sy0">,</span> <span class="st_h">'}'</span><span class="sy0">,</span> <span class="st_h">'!'</span><span class="sy0">,</span> <span class="st_h">'@'</span><span class="sy0">,</span> <span class="st_h">'|'</span><span class="sy0">,</span> <span class="st_h">'&amp;'</span><span class="sy0">,</span> <span class="st_h">'+'</span><span class="sy0">,</span> <span class="st_h">'-'</span><span class="sy0">,</span> <span class="st_h">'*'</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="sy0">,</span> <span class="st_h">'%'</span><span class="sy0">,</span> <span class="st_h">'='</span><span class="sy0">,</span> <span class="st_h">'&lt;'</span><span class="sy0">,</span> <span class="st_h">'&gt;'</span></span></span><span class="br0">&#41;</span><span class="sy0">,</span></pre></td></tr></tbody></table>
+
+<p>which is not too different from the newly introduced group usage shown below:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span></pre></td><td class="de1"><pre class="de1"><span class="st_h">'SYMBOLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'('</span><span class="sy0">,</span> <span class="st_h">')'</span><span class="sy0">,</span> <span class="st_h">'['</span><span class="sy0">,</span> <span class="st_h">']'</span><span class="sy0">,</span> <span class="st_h">'{'</span><span class="sy0">,</span> <span class="st_h">'}'</span><span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'!'</span><span class="sy0">,</span> <span class="st_h">'@'</span><span class="sy0">,</span> <span class="st_h">'|'</span><span class="sy0">,</span> <span class="st_h">'&amp;'</span><span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'+'</span><span class="sy0">,</span> <span class="st_h">'-'</span><span class="sy0">,</span> <span class="st_h">'*'</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="sy0">,</span> <span class="st_h">'%'</span><span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'='</span><span class="sy0">,</span> <span class="st_h">'&amp;lt;'</span><span class="sy0">,</span> <span class="st_h">'&gt;'</span><span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2"><span class="br0">&#41;</span><span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>Please note that versions before 1.0.7.21 will silently ignore this setting.</p>
+
+<p>Also note that <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.7.21 itself had some bugs in Symbol highlighting that could cause
+  heavily scrambled code output.</p>
+
+</div>
+
+<p>The following case sensitivity group alludes to the keywords section: here you can set which keyword groups are case sensitive.</p>
+
+<p>In the <strong>&#8216;CASE_SENSITIVE&#8217;</strong> group there&#8217;s a special key <code>GESHI_COMMENTS</code> which is used to set whether comments are
+case sensitive or not (for example, BASIC has the REM statement which while not being case sensitive is still alphanumeric, and
+as in the example given before about the Java language file using &#8220;import&#8221; as a single line comment, this can be
+useful sometimes. <strong>true</strong> if comments are case sensitive, <strong>false</strong> otherwise. All of the other indices
+correspond to indices in the <code>'KEYWORDS'</code> section (see above).</p>
+
+<h4 id="language-file-styles">4.3.5 Styles for your Language File</h4><div class="nav"><a href="#language-file-symbols-case">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-urls">Next</a></div>
+
+<p>This is the fun part! Here you get to choose the colours, fonts, backgrounds and anything else you&#8217;d like for your
+language file.</p>
+
+<p>Here&#8217;s an example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+<span class="xtra li2"><span class="de2">28</span></span>29
+<span class="xtra li2"><span class="de2">30</span></span>31
+<span class="xtra li2"><span class="de2">32</span></span>33
+<span class="xtra li2"><span class="de2">34</span></span>35
+<span class="xtra li2"><span class="de2">36</span></span>37
+<span class="xtra li2"><span class="de2">38</span></span>39
+</pre></td><td class="de1"><pre class="de1"><span class="st_h">'STYLES'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'KEYWORDS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #b1b100;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000000; font-weight: bold;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000066;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'COMMENTS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #808080; font-style: italic;'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #808080; font-style: italic;'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'MULTI'</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #808080; font-style: italic;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'ESCAPE_CHAR'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #000099; font-weight: bold;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'BRACKETS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #66cc66;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'STRINGS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #ff0000;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'NUMBERS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #cc66cc;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'METHODS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #006600;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'SYMBOLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #66cc66;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="st_h">'REGEXPS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'color: #0000ff;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="st_h">'SCRIPT'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></span></span>&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></pre></td></tr></tbody></table>
+
+<p>Note that all style rules should end with a semi-colon! This is important: <abbr title="Generic Syntax Highlighter">GeSHi</abbr> may add extra rules to the rules you
+specify (and will do so if a user tries to change your styles on the fly), so the last semi-colon in any stylesheet
+rule is important!</p>
+
+<p>All strings here should contain valid stylesheet declarations (it&#8217;s also fine to have the empty string).</p>
+
+<ul>
+<li><strong>&#8216;KEYWORDS&#8217;:</strong> This is an array, from keyword index to style. The index you use is the index you used in
+the keywords section to specify the keywords belonging to that group.</li>
+<li><strong>&#8216;COMMENTS&#8217;:</strong> This is an array, from single-line comment index to style for that index. The index &#8216;MULTI&#8217; is
+used for multiline comments (and cannot be an array). COMMENT_REGEXP use the style given for their key as
+if they were single-line comments.</li>
+<li><strong>&#8216;ESCAPE_CHAR&#8217;, &#8216;BRACKETS&#8217; and &#8216;METHODS&#8217;:</strong> These are arrays with only one index: 0. You cannot add other indices to
+these arrays.</li>
+<li><strong>&#8216;STRINGS&#8217;:</strong> This defines the various styles for the Quotemarks you defined earlier. If you don&#8217;t use
+multiple styles for strings there&#8217;s only one index: 0. Please also add this index in case no strings are present.</li>
+<li><strong>&#8216;NUMBERS&#8217;:</strong> This sets the styles used to highlight numbers. The format used here depends on the format used to
+set the formats of numbers to highlight. If you just used an integer (bitmask) for numbers, you have to either
+specify one key with the respective constant, and\or include a key 0 as a default style. If you used an
+array for the number markup, copy the keys used there and assign the styles accordingly.</li>
+<li><strong>&#8216;SYMBOLS&#8217;:</strong> This provides one key for each symbol group you defined above. If you used the flat usage
+make sure you include a key for symbols group 0.</li>
+<li><strong>&#8216;REGEXPS&#8217;:</strong> This is an array with a style for each matching regex. Also, since 1.0.7.21, you can specify the
+name of a function to be called, that will be given the text matched by the regex, each time a match is found.
+Note that my testing found that <code>create_function</code> would not work with this due to a <abbr title="PHP: HTML Preprocessor">PHP</abbr> bug, so you have to
+put the function definition at the top of the language file. Be sure to prefix the function name
+with <code>geshi_[languagename]_</code> as to not conflict with other functions!</li>
+<li><strong>&#8216;SCRIPT&#8217;:</strong> For languages that use script delimiters, this is where you can style each block of script. For
+example, <abbr title="Hypertext Markup Language">HTML</abbr> and <abbr title="Extensible Markup Language">XML</abbr> have blocks that begin with &lt; and end with > (i.e. tags) and blocks that begin with &amp; and
+end with&#160;; (i.e. character entities), and you can set a style to apply to each whole block. You specify the
+delimiters for the blocks below. Note that many languages will not need this feature.</li>
+</ul>
+
+<h4 id="language-file-urls">4.3.6 URLs for Functions</h4><div class="nav"><a href="#language-file-styles">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-numbers-support">Next</a></div>
+
+<p>This section lets you specify a url to visit for each keyword group. Useful for pointing functions at their online
+manual entries.</p>
+
+<p>Here is an example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span></pre></td><td class="de1"><pre class="de1"><span class="st_h">'URLS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'http://www.php.net/{FNAME}'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<p>The indices of this array correspond to the keyword groups you specified in the keywords section. The string <code>{FNAME}</code>
+marks where the name of the function is substituted in. So for the example above, if the keyword being highlighted is
+&#8220;echo&#8221;, then the keyword will be a URL pointing to <code>http://www.php.net/echo</code>. Because some languages (Java!) don&#8217;t
+keep a uniform URL for functions/classes, you may have trouble in creating a URL for that language (though look in the
+java language file for a novel solution to it&#8217;s problem)</p>
+
+<h4 id="language-file-numbers-support">4.3.7 Number Highlighting Support</h4><div class="nav"><a href="#language-file-urls">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-oo-support">Next</a></div>
+
+<p>If your language supports different formats of numbers (e.g. integers and float representations) and you want
+<abbr title="Generic Syntax Highlighter">GeSHi</abbr> to handle them differently you can select from a set of predefined formats.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span></pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'NUMBERS'</span> <span class="sy0">=&gt;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_INT_BASIC <span class="sy0">|</span> GESHI_NUMBER_INT_CSTYLE <span class="sy0">|</span> GESHI_NUMBER_BIN_PREFIX_0B <span class="sy0">|</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_OCT_PREFIX <span class="sy0">|</span> GESHI_NUMBER_HEX_PREFIX <span class="sy0">|</span> GESHI_NUMBER_FLT_NONSCI <span class="sy0">|</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; GESHI_NUMBER_FLT_NONSCI_F <span class="sy0">|</span> GESHI_NUMBER_FLT_SCI_SHORT <span class="sy0">|</span> GESHI_NUMBER_FLT_SCI_ZERO<span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<p>All the formats you want <abbr title="Generic Syntax Highlighter">GeSHi</abbr> to recognize are selected via a bitmask that is built by bitwise OR-ing the format constants.
+When styling you use these constants to assign the proper styles. A style not assigned will automatically fallback to style group 0.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>For a complete list of formats supported by <abbr title="Generic Syntax Highlighter">GeSHi</abbr> have a look into the sources of geshi.php.</p>
+
+</div>
+
+<p>If you want to define your own formats for numbers or when you want to group the style for two or more formats you can use the array syntax.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'NUMBERS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> GESHI_NUMBER_INT_BASIC <span class="sy0">|</span> GESHI_NUMBER_INT_CSTYLE<span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> GESHI_NUMBER_BIN_PREFIX_0B<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> GESHI_NUMBER_OCT_PREFIX<span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> GESHI_NUMBER_HEX_PREFIX<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> GESHI_NUMBER_FLT_NONSCI <span class="sy0">|</span> GESHI_NUMBER_FLT_NONSCI_F <span class="sy0">|</span> GESHI_NUMBER_FLT_SCI_SHORT <span class="sy0">|</span> GESHI_NUMBER_FLT_SCI_ZERO</span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></pre></td></tr></tbody></table>
+
+<p>This creates 5 style groups 1..5 that will highlight each of the formats specified for each group.
+Styling of these groups doesn&#8217;t use the constants but uses the indices you just defined.</p>
+
+<p>Instead of using those predefined constants you also can assign a PCRE that matches a number when using this advanced format.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>The extended format hasn&#8217;t been exhaustively been tested. So beware of bugs there.</p>
+
+</div>
+
+<h4 id="language-file-oo-support">4.3.8 Object Orientation Support</h4><div class="nav"><a href="#language-file-numbers-support">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-regexps">Next</a></div>
+
+<p>Now we&#8217;re reaching the most little-used section of a language file, which includes such goodies as object orientation
+support and context support. <abbr title="Generic Syntax Highlighter">GeSHi</abbr> can highlight methods and data fields of objects easily, all you need to do is to
+tell it to do so and what the &#8220;splitter&#8221; is between object/method etc.</p>
+
+<p>Here&#8217;s an example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span></pre></td><td class="de1"><pre class="de1"><span class="st_h">'OOLANG'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">'OBJECT_SPLITTER'</span> <span class="sy0">=&gt;</span> <span class="st_h">'-&amp;gt;'</span><span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<p>If your language has object orientation, the value of <code>'OOLANG'</code> is true, otherwise it is false. If it is object
+orientated, in the <code>'OBJECT_SPLITTER'</code> value you put the <code>htmlentities()</code> version of the &#8220;splitter&#8221; between
+objects and methods/fields. If it is not, then make this the empty string.</p>
+
+<h4 id="language-file-regexps">4.3.9 Using Regular Expressions</h4><div class="nav"><a href="#language-file-oo-support">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-strict-mode">Next</a></div>
+
+<p>Regular expressions are a good way to catch any other lexic that fits certain rules but can&#8217;t be listed as a keyword.
+A good example is variables in <abbr title="PHP: HTML Preprocessor">PHP</abbr>: variables always start with either one or two &#8220;$&#8221; signs, then alphanumeric
+characters (a simplification). This is easy to catch with regular expressions.</p>
+
+<p>And new to version 1.0.2, there is an advanced way of using regular expressions to catch certain things but highlight
+only part of those things. This is particularly useful for languages like <abbr title="Extensible Markup Language">XML</abbr>.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>Regular expressions use the PCRE syntax (perl-style), <em>not</em> the <code class="highlighted php"><span class="kw3">ereg</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code> style!</p>
+
+</div>
+
+<p>Here is an example (this time the <abbr title="PHP: HTML Preprocessor">PHP</abbr> file merged with the <abbr title="Extensible Markup Language">XML</abbr> file):</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+</pre></td><td class="de1"><pre class="de1"><span class="nu0">0</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; GESHI_SEARCH <span class="sy0">=&gt;</span> <span class="st_h">'(((xml:)?[a-z\-]+))(=)'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; GESHI_REPLACE <span class="sy0">=&gt;</span> <span class="st_h">'\\1'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; GESHI_MODIFIERS <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; GESHI_BEFORE <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; GESHI_AFTER <span class="sy0">=&gt;</span> <span class="st_h">'\\4'</span></span></span>&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2"><span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; GESHI_SEARCH <span class="sy0">=&gt;</span> <span class="st_h">'(&gt;/?[a-z0-9]*(&gt;)?)'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; GESHI_REPLACE <span class="sy0">=&gt;</span> <span class="st_h">'\\1'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; GESHI_MODIFIERS <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; GESHI_BEFORE <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; GESHI_AFTER <span class="sy0">=&gt;</span> <span class="st_h">''</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span><span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;[<span class="es1">\\</span>$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*&quot;</span></pre></td></tr></tbody></table>
+
+<p>As you can see there are two formats. One is the &#8220;simple&#8221; format used in <abbr title="Generic Syntax Highlighter">GeSHi</abbr> &lt; 1.0.2, and the other is a more
+advanced syntax. Firstly, the simple syntax:</p>
+
+<ul>
+<li><strong>May be in double quotes:</strong> To make it easier for those who always place their regular expressions in double quotes,
+you may place any regular expression here in double quotes if you wish.</li>
+<li><strong>Don&#8217;t use curly brackets where possible:</strong> If you want to use curly brackets (<code>()</code>) then by all means give it a try,
+but I&#8217;m not sure whether under some circumstances <abbr title="Generic Syntax Highlighter">GeSHi</abbr> may throw a wobbly. You have been warned! If you want to
+use brackets, it would be better to use the advanced syntax.</li>
+<li><strong>Don&#8217;t use the &#8220;everything&#8221; regex:</strong> (That&#8217;s the <code>.*?</code> regex). Use advanced syntax instead.</li>
+</ul>
+
+<p>And now for advanced syntax, which gives you much more control over exactly what is highlighted:</p>
+
+<ul>
+<li><strong>GESHI_SEARCH:</strong> This element specifies the regular expression to search for. If you plan to capture the output,
+use brackets (<code>()</code>). See how in the first example above, most of the regular expression is in one set of brackets
+(with the equals sign in other brackets). You should make sure that the part of the regular expression that is
+supposed to match what is highlighted is in brackets.</li>
+<li><strong>GESHI_REPLACE:</strong> This is what the stuff matched by the regular expression will be replaced with. If you&#8217;ve
+grouped the stuff you want highlighted into brackets in the GESHI_SEARCH element, then you can use <code>\\number</code>
+to match that group, where <code>number</code> is a number corresponding to how many open brackets are between the open
+bracket of the group you want highlighted and the start of the GESHI_SEARCH string + 1. This may sound confusing,
+and it probably is, but if you&#8217;re familiar with how <abbr title="PHP: HTML Preprocessor">PHP</abbr>&#8217;s regular expressions work you should understand. In the
+example above, the opening bracket for the stuff we want highlighted is the very first bracket in the string, so
+the number of brackets before that bracket and the start of the string is 0. So we add 1 and get our replacement
+string of <code>\\1</code> <small>(whew!)</small>.</li>
+</ul>
+
+<p>If you didn&#8217;t understand a word of that, make sure that there are brackets around the string in <code>GESHI_SEARCH</code>
+and use <code>\\1</code> for <code>GESHI_REPLACE</code> ;)</p>
+
+<ul>
+<li><strong>GESHI_MODIFIERS:</strong> Specify modifiers for your regular expression. If your regular expression includes the
+everything matcher (<code>.*?</code>), then your modifiers should include &#8220;s&#8221; and &#8220;i&#8221; (e.g. use &#8216;si&#8217; for this).</li>
+<li><strong>GESHI_BEFORE:</strong>Specifies a bracket group that should appear before the highlighted match (this bracketed group will
+not be highlighted). Use this if you had to match what you wanted by matching part of your regexp string to something
+before what you wanted to highlight, and you don&#8217;t want that part to disappear in the highlighted result.</li>
+<li><strong>GESHI_AFTER:</strong>Specifies a bracket group that should appear after the highlighted match (this bracketed group will
+not be highlighted). Use this if you had to match what you wanted by matching part of your regexp string to something
+after what you wanted to highlight, and you don&#8217;t want that part to disappear in the highlighted result.</li>
+</ul>
+
+<p>Is that totally confusing? Here&#8217;s the test for if you&#8217;re an android or not: If you found that perfectly understandable
+then you&#8217;re an android ;). Here&#8217;s a better example:</p>
+
+<p>Let&#8217;s say that I&#8217;m making a language, and variables in this language always start with a dollar sign ($), are always
+written in lowercase letters and always end with an ampersand (&amp;). eg:</p>
+
+<p><code class="highlighted php"><span class="re0">$foo</span><span class="sy0">&amp;</span> <span class="sy0">=</span> <span class="st_h">'bar'</span></code></p>
+
+<p>I want to highlight <em>only the text between the $ and the &amp;</em>. How do I do that? With simple regular expressions I can&#8217;t,
+but with advanced, it&#8217;s relatively easy:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span></pre></td><td class="de1"><pre class="de1"><span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// search for a dollar sign, then one or more of the characters a-z, then an ampersand</span></span></span>&nbsp; &nbsp; GESHI_SEARCH <span class="sy0">=&gt;</span> <span class="st_h">'(\$)([a-z]+)(&amp;)'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// we wanna highlight the characters, which are in the second bracketed group</span></span></span>&nbsp; &nbsp; GESHI_REPLACE <span class="sy0">=&gt;</span> <span class="st_h">'\\2'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// no modifiers, since we're not matching the &quot;anything&quot; regex</span></span></span>&nbsp; &nbsp; GESHI_MODIFIERS <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// before the highlighted characters should be the first</span></span></span>&nbsp; &nbsp; <span class="co1">// bracketed group (always a dollar sign in this example)</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; GESHI_BEFORE <span class="sy0">=&gt;</span> <span class="st_h">'\\1'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="co1">// after the highlighted characters should be the third</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="co1">// bracketed group (always an ampersand in this example)</span></span></span>&nbsp; &nbsp; GESHI_AFTER <span class="sy0">=&gt;</span> <span class="st_h">'\\3'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span></pre></td></tr></tbody></table>
+
+<p>So if someone tried to highlight using my language, all cases of <code>$foo&amp;</code> would turn into:</p>
+
+<p><code class="highlighted html4strict">$<span class="sc2">&lt;<span class="kw2">span</span> <span class="kw3">style</span><span class="sy0">=</span><span class="st0">&quot;color: blue;&quot;</span>&gt;</span>foo<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">span</span>&gt;&lt;<span class="kw2">span</span> <span class="kw3">style</span><span class="sy0">=</span><span class="st0">&quot;color: green;&quot;</span>&gt;</span><span class="sc1">&amp;amp;</span><span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">span</span>&gt;</span></code></p>
+
+<p>(which would of course be viewed in a browser to get something like <code class="highlighted php"><span class="re0">$foo</span><span class="sy0">&amp;</span></code>)</p>
+
+<h4 id="language-file-strict-mode">4.3.10 Contextual Highlighting and Strict Mode</h4><div class="nav"><a href="#language-file-regexps">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-parser-control">Next</a></div>
+
+<p>For languages like <abbr title="Hypertext Markup Language">HTML</abbr>, it&#8217;s good if we can highlight a tag (like <code class="highlighted html4strict"><span class="sc2">&lt;<span class="kw2">a</span>&gt;</span></code> for example). But how do we stop
+every single &#8220;a&#8221; in the source getting highlighted? What about for attributes? If I&#8217;ve got the word &#8220;colspan&#8221; in my
+text I don&#8217;t want that highlighted! So how do you tell <abbr title="Generic Syntax Highlighter">GeSHi</abbr> not to highlight in that case? You do it with &#8220;Strict Blocks&#8221;.</p>
+
+<p>Here is an example:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span>13
+<span class="xtra li2"><span class="de2">14</span></span>15
+<span class="xtra li2"><span class="de2">16</span></span>17
+<span class="xtra li2"><span class="de2">18</span></span>19
+<span class="xtra li2"><span class="de2">20</span></span>21
+<span class="xtra li2"><span class="de2">22</span></span>23
+<span class="xtra li2"><span class="de2">24</span></span>25
+<span class="xtra li2"><span class="de2">26</span></span>27
+</pre></td><td class="de1"><pre class="de1"><span class="sy1">&lt;?</span> <span class="coMULTI">/* ... */</span>
+<span class="xtra li2"><span class="de2"><span class="st_h">'STRICT_MODE_APPLIES'</span> <span class="sy0">=&gt;</span> GESHI_MAYBE<span class="sy0">,</span></span></span><span class="st_h">'SCRIPT_DELIMITERS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;?php'</span> <span class="sy0">=&gt;</span> <span class="st_h">'?&gt;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;?'</span> <span class="sy0">=&gt;</span> <span class="st_h">'?&gt;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;%'</span> <span class="sy0">=&gt;</span> <span class="st_h">'%&gt;'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'&lt;script language=&quot;php&quot;&gt;'</span> <span class="sy0">=&gt;</span> <span class="st_h">'&lt;/script&gt;'</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;/(&lt;\?(?:php)?)(?:'(?:[^'<span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?'|<span class="es1">\&quot;</span>(?:[^<span class="es1">\&quot;</span><span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?<span class="es1">\&quot;</span>|\/\*(?!\*\/).*?\*\/|.)*?(\?&gt;|\Z)/sm&quot;</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;/(&lt;%)(?:'(?:[^'<span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?'|<span class="es1">\&quot;</span>(?:[^<span class="es1">\&quot;</span><span class="es1">\\</span><span class="es1">\\</span>]|<span class="es1">\\</span><span class="es1">\\</span>.)*?<span class="es1">\&quot;</span>|\/\*(?!\*\/).*?\*\/|.)*?(%&gt;|\Z)/sm&quot;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></span></span><span class="st_h">'HIGHLIGHT_STRICT_BLOCK'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; <span class="nu0">5</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span></span></span><span class="coMULTI">/* ... */</span> <span class="sy1">?&gt;</span></pre></td></tr></tbody></table>
+
+<p>What is strict mode? Strict mode says that highlighting only occurs inside the blocks you specify. You can see from
+the example above that highlighting will only occur if the source is inside <code class="highlighted php"><span class="kw2">&lt;?php</span> <span class="sy0">...</span> <span class="sy1">?&gt;</span></code> (though note the
+<code>GESHI_MAYBE</code>!). Here are some points about strict highlighting:</p>
+
+<ul>
+<li><strong>&#8216;STRICT_MODE_APPLIES&#8217;:</strong> This takes three values (all constants):
+
+<ul>
+<li><code>GESHI_ALWAYS</code>: Strict mode always applies for all of the blocks you specify. Users of your language
+file cannot turn strict mode off. This should be used for markup languages.</li>
+<li><code>GESHI_NEVER</code>: Strict mode is never used. Users of your language file cannot turn strict mode on. Use this
+value if there is no such thing as a block of code that would not be highlighted in your language
+(most languages, like C, Java etc. use this because anything in a C file should be highlighted).</li>
+<li><code>GESHI_MAYBE</code>: Strict mode &#42;sometimes&#42; applies. It defaults to &#8220;off&#8221;. Users can turn strict mode on if
+they please. If strict mode is off then everything in the source will be highlighted, even things outside
+the strict block markers. If strict mode is on the nothing outside strict block markers will be highlighted.</li>
+</ul></li>
+<li><strong>&#8216;SCRIPT_DELIMITERS&#8217;:</strong> This is an array of script delimiters, in the format of the above. The indices are use in the
+&#8216;SCRIPT&#8217; part of the styles section for highlighting everything in a strict block in a certain way.
+For example, you could set up your language file to make the background yellow of any code inside a strict
+block this way. The delimiters are in the form <code class="highlighted php"><span class="st_h">'OPEN'</span> <span class="sy0">=&gt;</span> <span class="st_h">'CLOSE'</span></code>. Delimiters can be of any
+length > 0. Delimiters are <em>not</em> formatted as if they were run through <code class="highlighted php"><span class="kw3">htmlentities</span><span class="br0">&#40;</span><span class="br0">&#41;</span></code>!</li>
+<li><strong>&#8216;HIGHLIGHT_STRICT_BLOCK&#8217;:</strong> specifies whether any highlighting should go on inside each block. Most of
+the time this should be true, but for example, in the <abbr title="Extensible Markup Language">XML</abbr> language file highlighting is turned off for
+blocks beginning with <code class="highlighted html4strict"><span class="sc0">&lt;!DOCTYPE</span></code> and ending with <code class="highlighted html4strict">&gt;</code>. However, you can still
+style the overall block using the method described above, and the <abbr title="Extensible Markup Language">XML</abbr> language file does just that.</li>
+</ul>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>The delimiters should be in <em>reverse alphabetical order</em>. Note that in the above example, <code class="highlighted php"><span class="kw2">&lt;?php</span></code>
+  comes before <code class="highlighted php"><span class="sy1">&lt;?</span></code>.</p>
+
+</div>
+
+<p>Since <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 instead of specifying an array with starter and ender you may also provide a regular expression
+that matches <em>the full block</em> you wish to highlight. If the regular expression match starts at the same position
+as a previous array declaration the Regexp match is taken. This is to allow for a fall-back when a preg_match
+doesn&#8217;t quite work as expected so you still get reasonably well results.</p>
+
+<p>If you didn&#8217;t get this, you might want to look into the <abbr title="PHP: HTML Preprocessor">PHP</abbr> or <abbr title="Hypertext Markup Language">HTML</abbr> language files as this feature is used there
+to fix some issues that have been there for about 3 years.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>For <abbr title="PHP: HTML Preprocessor">PHP</abbr> versions &lt;4.3.3 Strict Block Regexps are completely ignored due to problems in those version
+  that would cause loads of warning messages otherwise.</p>
+
+</div>
+
+<h4 id="language-file-parser-control">4.3.11 Special Parser Settings (Experimental)</h4><div class="nav"><a href="#language-file-strict-mode">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#language-file-tidying-up">Next</a></div>
+
+<p>Sometimes it is necessary for a language to render correctly to tweak some of the assumptions <abbr title="Generic Syntax Highlighter">GeSHi</abbr> usually makes to match the behaviour your language expects.
+To achieve this there is an experimental section called <code class="highlighted php"><span class="st_h">'PARSER_CONTROL'</span></code> which is optional and should be used only if necessary.
+With the help of this section some internal parameters of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> can be set which are not overrideable by the API and thus their use should be limited as much as possible.</p>
+
+<p>The syntax of the <strong>PARSER_CONTROL</strong> basically resembles an array structure simular to the one found in the rest of the language file. All subsections of the <strong>PARSER_CONTROL</strong> are optional.
+If a given setting isn&#8217;t present the usual default values of <abbr title="Generic Syntax Highlighter">GeSHi</abbr> are used.
+No validation of settings is performed for these settings. Also note that unknown settings are silently ignored.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>All <strong>PARSER_CONTROL</strong> settings are experimental and subject to change.
+  So if you need a special setting in a public language file you should consider requesting it upstream.
+  This is also the reason why documentation on these settings will only cover broad usage information as the underlying implementation might change without further notice.</p>
+
+</div>
+
+<p>One of the most common reasons why you might want to use the <strong>PARSER_CONTROL</strong> settings is to tweak what characters are allowed to surround a keyword.
+Usually <abbr title="Generic Syntax Highlighter">GeSHi</abbr> checks for a fixed set of characters like brackets and common symbols that denote the word boundary for a keyword.
+If this set conflicts with your language (e.g. - is allowed inside a keyword) or you want to limit the usage of a keyword to certain areas (e.g. for <abbr title="Hypertext Markup Language">HTML</abbr> tag names only match after &lt;) you can change those conditions here.</p>
+
+<p>Keyword boundary rules can either be set globally (directly within the PARSER_CONTROL&#8217;s KEYWORDS section or on a per-group basis.
+E.g. the following sample from the <abbr title="Hypertext Markup Language">HTML</abbr> language file sets different settings for keyword matching only for Keyword Group 2 and leaves the other groups alone.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span></pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'PARSER_CONTROL'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'KEYWORDS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">2</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'DISALLOWED_BEFORE'</span> <span class="sy0">=&gt;</span> <span class="st_h">'(?&lt;=&amp;lt;|&amp;lt;\/)'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'DISALLOWED_AFTER'</span> <span class="sy0">=&gt;</span> <span class="st_h">'(?=\s|\/|&amp;gt;)'</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span></span></span></pre></td></tr></tbody></table>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>The name <code class="highlighted php"><span class="st_h">'DISALLOWED_BEFORE'</span></code> and <code class="highlighted php"><span class="st_h">'DISALLOWED_AFTER'</span></code> might sound confusing at first, since they don&#8217;t define what to prevent, but what to match in order to find a keyword.
+  The reason for this strange naming is based in the original implementation of this feature when Nigel implemented this in the old parser statically.
+  When this implementation was brought out via the <strong>PARSER_CONTROL</strong> settings the original naming wasn&#8217;t altered since at that time this really was a blacklist of characters.
+  Later on this implementation was changed from a blacklist of characters to a part of a PCRE regexp, but leaving the name.
+  The naming might be subject to change though.</p>
+
+</div>
+
+<p>Another option you can change since <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8.3 is whether to treat spaces within keywords as literals (only a single space as given) or if the space should match any whitespace at that location.
+The following code will enable this behaviour for the whole keyword set. As said above you can choose to enable this for single keyword groups only though.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'PARSER_CONTROL'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'KEYWORDS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'SPACE_AS_WHITESPACE'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></span></span>&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">,</span></pre></td></tr></tbody></table>
+
+<p>Another option of interest might be disabling certain features for a given language.
+This might come in handy if the language file you are working on doesn&#8217;t support a given function or highlighting certain aspects won&#8217;t work properly or would interfere with custom implementations using regular expressions.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+<span class="xtra li2"><span class="de2">8</span></span>9
+<span class="xtra li2"><span class="de2">10</span></span>11
+<span class="xtra li2"><span class="de2">12</span></span></pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'PARSER_CONTROL'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ENABLE_FLAGS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ALL'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'NUMBERS'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'METHODS'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'SCRIPT'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'SYMBOLS'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'ESCAPE_CHAR'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'BRACKETS'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'STRINGS'</span> <span class="sy0">=&gt;</span> GESHI_NEVER<span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; <span class="br0">&#41;</span></span></span></pre></td></tr></tbody></table>
+
+<p>Inside the <code class="highlighted php"><span class="st_h">'ENABLE_FLAGS'</span></code> section follows an array of <code class="highlighted php"><span class="st_h">'name'</span><span class="sy0">=&gt;</span>value</code> pairs.
+Valid names are the sections below the <code class="highlighted php"><span class="st_h">'STYLES'</span></code> section (well, not exactly, but you can look there for what the features are called inside <abbr title="Generic Syntax Highlighter">GeSHi</abbr>).
+Valid values are the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> constants <code class="highlighted php">GESHI_NEVER</code> (don&#8217;t process this feature), <code class="highlighted php">GESHI_ALWAYS</code> (always process this feature, ignore the user) and <code class="highlighted php">GESHI_MAYBE</code> (listen to the user if he want&#8217;s this highlighted).
+The value <code class="highlighted php">GESHI_MAYBE</code> is the default one and thus needs not to be set explicitely.</p>
+
+<p>Another setting available through the <strong>PARSER_CONTROL</strong> settings is the possibility to limit the allowed characters before an single line comment.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'PARSER_CONTROL'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'COMMENTS'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'DISALLOWED_BEFORE'</span> <span class="sy0">=&gt;</span> <span class="st_h">'$'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></span></span>&nbsp; &nbsp; <span class="br0">&#41;</span></pre></td></tr></tbody></table>
+
+<p>With the current implementation the DISALLOWED_BEFORE COMMENT-specific setting is a list of characters. But this is subject to change.</p>
+
+<div class="note">
+
+<div class="note-header">Note:</div>
+
+<p>There is no <code class="highlighted php"><span class="st_h">'DISALLOWED_AFTER'</span></code> setting with the <code class="highlighted php"><span class="st_h">'COMMENTS'</span></code>-<strong>PARSER_CONTROL</strong>.</p>
+
+</div>
+
+<p>Another <strong>PARSER_CONTROL</strong> setting for the environment around certain syntactic constructs refers to the handling of object-oriented languages.</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+<span class="xtra li2"><span class="de2">4</span></span>5
+<span class="xtra li2"><span class="de2">6</span></span>7
+</pre></td><td class="de1"><pre class="de1">&nbsp; &nbsp; <span class="st_h">'PARSER_CONTROL'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'OOLANG'</span> <span class="sy0">=&gt;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'MATCH_BEFORE'</span> <span class="sy0">=&gt;</span> <span class="st_h">''</span><span class="sy0">,</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'MATCH_AFTER'</span> <span class="sy0">=&gt;</span> <span class="st_h">'[a-zA-Z_][a-zA-Z0-9_]*'</span><span class="sy0">,</span></span></span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st_h">'MATCH_SPACES'</span> <span class="sy0">=&gt;</span> <span class="st_h">'[\s]*'</span>
+<span class="xtra li2"><span class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span></span></span>&nbsp; &nbsp; <span class="br0">&#41;</span></pre></td></tr></tbody></table>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>Please note that the settings discussed in this section are experimental and might be changed, removed or altered in their meaning at any time.</p>
+
+</div>
+
+<h4 id="language-file-tidying-up">4.3.12 Tidying Up</h4><div class="nav"><a href="#language-file-parser-control">Previous</a> | <a href="#language-file-sections">Top</a> | <a href="#lang-validation">Next</a></div>
+
+<p>All language files should end with:</p>
+
+<table class="php geshicode" style="font-family:monospace;"><thead><tr><td colspan="2"  class="head">PHP code</td></tr></thead><tbody><tr class="li1"><td class="ln"><pre class="de1">1
+<span class="xtra li2"><span class="de2">2</span></span>3
+</pre></td><td class="de1"><pre class="de1"><span class="br0">&#41;</span><span class="sy0">;</span>
+<span class="xtra li2"><span class="de2">&nbsp;</span></span><span class="sy1">?&gt;</span></pre></td></tr></tbody></table>
+
+<p>That is the string content <code class="highlighted php"><span class="st0">&quot;<span class="es1">\n</span>);<span class="es1">\n</span>?&gt;<span class="es1">\n</span>&quot;</span></code>.</p>
+
+<div class="caution">
+
+<div class="caution-header">Caution:</div>
+
+<p>Make sure that there is EXACTLY one linebreak character at the end. If you accidentially include more
+  you might end up with messages like &#8220;Headers already sent&#8221;.</p>
+
+</div>
+
+<h3 id="lang-validation">4.4 Validating your language file</h3><div class="nav"><a href="#language-file-tidying-up">Previous</a> | <a href="#language-files">Top</a> | <a href="#method-constant-reference">Next</a></div>
+
+<p>Since <abbr title="Generic Syntax Highlighter">GeSHi</abbr> 1.0.8 there is a new script <code>langcheck.php</code> in the contrib directory that scans all
+language files it finds in the geshi/ subdirectory of the <abbr title="Generic Syntax Highlighter">GeSHi</abbr> installation for mistakes.</p>
+
+<p>Please make sure that your language does not contain any mistakes that this script shows you when sending in
+your language file for inclusion into the official release as this saves work for us when including your file.
+Also you can be sure your language file will work as expected once your language file validates correctly.</p>
+
+<p>Please note that not all of the language files shipped with <abbr title="Generic Syntax Highlighter">GeSHi</abbr> are fully valid yet, but we&#8217;re working on it
+and are happy about every patch we get!</p>
+
+<h2 id="method-constant-reference">5 Method/Constant Reference</h2><div class="nav"><a href="#lang-validation">Previous</a></div>
+
+<p>I&#8217;m afraid I have been lying for a little while about this now! Since 1.0.7 I have been including a phpdoc API for
+the sourcecode in the <a href="api/index.html">api</a> directory, but have forgot to update the documentation! However, it is available,
+and may assist you in coding, especially for plugin coders.</p>
+
+<hr />
+
+<p>That&#8217;s all, folks!</p>
+
+<p>I&#8217;ve improved the documentation greatly from version 1.0.1, but there may still be problems with it, or it may still
+be confusing for you. Or perhaps I was just plain wrong about one point! If so, contact me and I&#8217;ll do my best to sort it out.</p>
+
+<p>In case you were wondering, I&#8217;ve finished development of the 1.0.X thread of <abbr title="Generic Syntax Highlighter">GeSHi</abbr>. The only releases I&#8217;ll make in this
+thread will be of the bug-fix/add language files type. In particular, version 1.0.2 was a &#8220;concept&#8221; release - testing
+how far I could take the highlighting idea (as well as ideas from others).</p>
+
+<p>I&#8217;m planning a code rewrite for 1.2.X, which will be based on a new engine - a &#8220;psuedo-tokenizer&#8221; engine. Hopefully
+it will massively reduce the server load and time taken (by almost eliminating regexps), while providing
+superior highlighting. But fear not! The interface and method names should all remain the same ^_^ (though I can&#8217;t
+say the same for language files!)</p>
+
+<p>And finally, a couple of people have been asking me: how did you generate that documentation? The amazing answer is: my
+brain. And yes, it took a long time, and I don&#8217;t recommend doing it this way. And yes, you can borrow the styles if
+you like, though flick me an e-mail if you do.</p>
+
+<p>Anyway, enough blather from me. Get <abbr title="Generic Syntax Highlighter">GeSHi</abbr> working for you already! :D</p>
+
+<div class="header">
+
+<dl>
+<dt>Authors:</dt>
+<dd>&copy; 2004 - 2007&#160;<a href="mailto:nigel@geshi.org">Nigel McNie</a></dd>
+
+<dd>&copy; 2007 - 2008&#160;<a href="mailto:BenBE@omorphia.de">Benny Baumann</a></dd>
+
+<dd>&copy; 2008&#160;<a href="mailto:mail@milianw.de">Milian Wolff</a></dd>
+
+<dt><abbr title="Generic Syntax Highlighter">GeSHi</abbr> Website:</dt>
+<dd><a href="http://qbnz.com/highlighter">http://qbnz.com/highlighter</a></dd>
+</dl>
+
+</div>
+
+<div class="footnotes">
+<hr />
+<ol>
+
+<li id="fn:xhtml-strict">
+<p>The PRE header (see <a href="#the-code-container">The Code Container</a>) is not valid <abbr title="Hypertext Markup Language">HTML</abbr>, you might want
+to use one of the other header types instead.&#160;<a href="#fnref:xhtml-strict" rev="footnote">&#8617;</a></p>
+</li>
+
+<li id="fn:php-version-note">
+<p>Support is granted for <abbr title="PHP: HTML Preprocessor">PHP</abbr> 4.3.0 and above, but especially 4.3.x cannot be guaranteed to
+work due to a lack of test systems. If you are forced to use such old <abbr title="PHP: HTML Preprocessor">PHP</abbr> versions complain at your hoster or
+contact us if you find compatibility issues so we can try to resolve them. It&#8217;s only <abbr title="PHP: HTML Preprocessor">PHP</abbr> 4.4.X and above that
+is verified to work.&#160;<a href="#fnref:php-version-note" rev="footnote">&#8617;</a></p>
+</li>
+
+<li id="fn:phpbb-note">
+<p>I am no longer working on this MOD, however if someone else wants to they can contact me for more
+information.&#160;<a href="#fnref:phpbb-note" rev="footnote">&#8617;</a></p>
+</li>
+
+<li id="fn:plugin-only">
+<p>Available as plugin only. In addition, some of the other entries mentioned
+here may only have <abbr title="Generic Syntax Highlighter">GeSHi</abbr> available as a plugin.&#160;<a href="#fnref:plugin-only" rev="footnote">&#8617;</a></p>
+</li>
+
+</ol>
+</div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/examples/includes/geshi/docs/geshi-doc.txt b/examples/includes/geshi/docs/geshi-doc.txt
new file mode 100644 (file)
index 0000000..4aae137
--- /dev/null
@@ -0,0 +1,1740 @@
+[NOTE: This documentation has simply been copy-pasted from the HTML form and is NOT up to date, I recommend you
+read that instead]
+
+GeSHi Documentation
+Version 1.0.7.22
+
+Author:          Nigel McNie, Benny Baumann
+Copyright:       © 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
+Email:           nigel@geshi.org, BenBE@omorphia.de
+GeSHi Website:   http://qbnz.com/highlighter
+
+This is the documentation for GeSHi - Generic Syntax Highlighter. The most modern version of this document is available on the web - go to http://qbnz.com/highlighter/documentation.php to view it.
+
+Any comments, questions, confusing points? Please contact me! I need all the information I can get to make the use of GeSHi and everything related to it (including this documentation) a breeze.
+Contents
+
+    * 1. Introduction
+          o 1.1 Features
+          o 1.2 About GeSHi
+          o 1.3 Credits
+          o 1.4 Feedback
+    * 2. The Basics
+          o 2.1 Getting GeSHi
+          o 2.2 Installing GeSHi
+                + 2.2.1 Requirements
+                + 2.2.2 Extracting GeSHi
+                + 2.2.3 Installation
+          o 2.3 Basic Usage
+    * 3. Advanced Features
+          o 3.1 The Code Container
+          o 3.2 Line Numbers
+                + 3.2.1 Enabling Line Numbers
+                + 3.2.2 Styling Line Numbers
+                + 3.2.3 Choosing a Start Number
+          o 3.3 Using CSS Classes
+                + 3.3.1 Enabling CSS Classes
+                + 3.3.2 Setting the CSS Class/ID
+                + 3.3.3 Getting the Stylesheet
+                + 3.3.4 Using an External Stylesheet
+          o 3.4 Changing Styles
+                + 3.4.1 The Overall Styles
+                + 3.4.2 Line Number Styles
+                + 3.4.3 Setting Keyword Styles
+                + 3.4.4 Setting Comment Styles
+                + 3.4.5 Setting Other Styles
+          o 3.5 Case Sensitivity and Auto Casing
+                + 3.5.1 Auto Caps/Nocaps
+                + 3.5.2 Setting Case Sensitivity
+          o 3.6 Changing the Source/Language/Path/Charset
+                + 3.6.1 Changing the Source Code
+                + 3.6.2 Changing the Language
+                + 3.6.3 Changing the Path
+                + 3.6.4 Changing the Character Set
+                + 3.6.5 Using load_from_file to change the language and source code
+          o 3.7 Error Handling
+          o 3.8 Disabling Styling of Some Lexics
+          o 3.9 Setting the Tab Width
+          o 3.10 Using Strict Mode
+          o 3.11 Adding/Removing Keywords
+                + 3.11.1 Adding a Keyword
+                + 3.11.2 Removing a Keyword
+                + 3.11.3 Adding a Keyword Group
+                + 3.11.4 Removing a Keyword Group
+          o 3.12 Headers and Footers for your code
+                + 3.12.1 Keyword Substitution
+                + 3.12.2 Setting Header Content
+                + 3.12.3 Setting Footer Content
+                + 3.12.4 Styling Header Content
+                + 3.12.5 Styling Footer Content
+          o 3.13 Keyword URLs
+                + 3.13.1 Setting a URL for a Keyword Group
+                + 3.13.2 Disabling URLs for a Keyword Group
+                + 3.13.3 Disabling all URLs for Keywords
+                + 3.13.4 Styling Links
+                + 3.13.5 Setting the Link Target
+          o 3.14 Using Contextual Importance
+          o 3.15 Highlighting Special Lines "Extra"
+                + Specifying the Lines to Highlight Extra
+                + Styles for the Highlighted Lines
+          o 3.16 Adding IDs to Each Line
+          o 3.17 Getting the Time of Styling
+    * 4 Language Files
+          o 4.1 An Example Language File
+          o 4.2 Language File Conventions
+          o 4.3 Language File Sections
+                + 4.3.1 The Header
+                + 4.3.2 The First Indices
+                + 4.3.3 Keywords
+                + 4.3.4 Symbols and Case Sensitivity
+                + 4.3.5 Styles for your Language Files
+                + 4.3.6 URLs for Functions
+                + 4.3.7 Object Orientation Support
+                + 4.3.8 Using Regular Expressions
+                + 4.3.9 Contextual Highlighting and Strict Mode
+                + 4.3.10 Tidying Up
+    * 5 Method/Constant Reference
+
+1: Introduction
+Top | Contents | Next | Previous
+
+GeSHi is exactly what the acronym stands for: a Generic Syntax Highlighter. As long as you have a language file for almost any computer language - whether it be a scripting language, object orientated, markup or anything in between - GeSHi can highlight it! GeSHi is extremely customisable - the same source can be highlighted multiple times in multiple ways - the same source even with a different language. GeSHi outputs XHTML strict compliant code*, and can make use of CSS to save on the amount of output. And what is the cost for all of this? You need PHP. That's all!
+
+*Most of the time. Some languages do not output XHTML strict code, and using line numbers with the PRE header is not legal either. These problems will be fixed in 1.2.
+1.1: Features
+Top | Contents | Next | Previous
+
+Here are some of the standout features of GeSHi:
+
+    * Programmed in PHP: GeSHi is coded entirely in PHP. This means that where ever you have PHP, you can have GeSHi! Almost any free webhost supports PHP, and GeSHi works fine with PHP > 4.3.0*.
+    * Support for many languages: GeSHi comes with about 100 languages, including PHP, HTML, CSS, Java, C, Lisp, XML, Perl, Python, ASM and many more!
+    * XHTML compliant output: GeSHi produces XHTML compliant output, using stylesheets, so you need not worry about GeSHi ruining your claims to perfection in the standards department ;)
+    * Highly customisable: GeSHi allows you to change the style of the output on the fly, use CSS classes or not, use an external stylesheet or not, use line numbering, change the case of output keywords... the list goes on and on!
+    * Flexible: Unfortunately, GeSHi is quite load/time intensive for large blocks of code. However, you want speed? Turn off any features you don't like, pre-make a stylesheet and use CSS classes to reduce the amount of output and more - it's easy to strike a balance that suits you.
+
+This is just a taste of what you get with GeSHi - the best syntax highlighter for the web in the world!
+
+*Support is granted for PHP 4.3.0 and above, but especially 4.3.x cannot be guaranteed to work due to a lack of test systems. If you are forced to use such old PHP versions complain at your hoster or contact us if you find compatibility issues so we can try to resolve them. It's only PHP 4.4.X and above that is verified to work.
+1.2: About GeSHi
+Top | Contents | Next | Previous
+
+GeSHi started as a mod for the phpBB forum system, to enable highlighting of more languages than the available (which can be roughly estimated to exactly 0 ;)). However, it quickly spawned into an entire project on its own. But now it has been released, work continues on a mod for phpBB* - and hopefully for many forum systems, blogs and other web-based systems.
+
+*I am no longer working on this MOD, however if someone else wants to they can contact me for more information.
+
+Several systems are using GeSHi now, including:
+
+    * Dokuwiki - An advanced wiki engine
+    * gtk.php.net - Their manual uses GeSHi for syntax highlighting
+    * WordPress - A powerful blogging system*
+    * PHP-Fusion - A constantly evovling CMS
+    * SQL Manager - A Postgres DBAL
+    * Mambo - A popular open source CMS
+    * MediaWiki - A leader in Wikis*
+    * TikiWiki - A megapowerful Wiki/CMS
+    * TikiPro - Another powerful Wiki based on Tikiwiki
+    * RWeb - A site-building tool
+
+* Available as plugin only. In addition, some of the other entries mentioned here may only have GeSHi available as a plugin.
+
+GeSHi is the original work of Nigel McNie. The project was later handed over to Benny Baumann. Others have helped with aspects of GeSHi also, they're mentioned in the THANKS file.
+1.3: Credits
+Top | Contents | Next | Previous
+
+Many people have helped out with GeSHi, whether by creating language files, submitting bug reports, suggesting new ideas or simply pointing out a new idea or something I'd missed. All of these people have helped to build a better GeSHi, you can see them in the THANKS file.
+
+Do you want your name on this list? Why not make a language file, or submit a valid bug? Or perhaps help me with an added feature I can't get my head around, or suggest a new feature, or even port GeSHi to anothe language? There's lots you can do to help out, and I need it all :)
+1.4: Feedback
+Top | Contents | Next | Previous
+
+I need your feedback! ANYthing you have to say is fine, whether it be a query, congratulations, a bug report or complaint, I don't care! I want to make this software the best it can be, and I need your help! You can contact me in the following ways:
+
+    * E-mail: nigel@geshi.org
+    * Forums: Sourceforge.net Forums or GeSHi home forums
+
+Remember, any help I am grateful for :)
+2: The Basics
+Top | Contents | Next | Previous
+
+In this section, you'll learn a bit about GeSHi, how it works and what it uses, how to install it and how to use it to perform basic highlighting.
+2.1: Getting GeSHi
+Top | Contents | Next | Previous
+
+If you're reading this and don't have GeSHi, that's a problem ;). So, how do you get your hands on it? Visit http://qbnz.com/highlighter/downloads.php to obtain the latest version.
+2.2: Installing GeSHi
+Top | Contents | Next | Previous
+
+Installing GeSHi is a snap, even for those most new to PHP. There's no tricks involved. Honest!
+2.2.1: Requirements
+Top | Contents | Next | Previous
+
+GeSHi requires the following to be installable:
+
+    * PHP. It's untested with anything other below 4.4.X. I hope to extend this range soon. I see no reason why it won't work with any version of PHP above 4.3.0.
+    * Approximately 2 megabytes of space. The actual script is small - around 150K - but most of the size comes from the large number of language files (over 100!). If you're pushed for space, make sure you don't upload to your server the docs/ or contrib/ directory, and you may want to leave out any language files that don't take your fancy either.
+
+As you can see, the requirements are very small. If GeSHi does NOT work for you in a particular version of PHP, let me know why and I'll fix it.
+
+Packages come in .zip, .tar.gz and .tar.bz2 format, so there's no complaining about whether it's available for you. *nix users probably want .tar.gz or .tar.bz2 and windows users probably want .zip.
+2.2.2: Extracting GeSHi
+Top | Contents | Next | Previous
+
+To extract GeSHi in Linux (.tar.gz):
+
+   1. Open a shell
+   2. cd to the directory where the archive lies
+   3. Type tar -xzvf [filename] where [filename] is the name of the archive (typically GeSHi-1.X.X.tar.gz)
+   4. GeSHi will be extracted to its own directory
+
+To extract GeSHi in Windows (.zip):
+
+   1. Open Explorer
+   2. Navigate to the directory where the archive lies
+   3. Extract the archive. The method you use will depend on your configuration. Some people can right-click upon the archive and select "Extract" from there, others may have to drag the archive and drop it upon an extraction program.
+
+To extract from .zip you'll need an unzipping program - unzip in Linux, or Winzip, Winrar or similar for Windows.
+2.2.3: Installation
+Top | Contents | Next | Previous
+
+GeSHi is nothing more than a PHP class with related language support files. Those of you familiar with PHP can then guess how easy the installation will be: simply copy it into your include path somewhere. You can put it wherever you like in this include path. I recommend that you put the language files in a subdirectory of your include path too - perhaps the same subdirectory that geshi.php is in. Remember this path for later.
+
+If you don't know what an include path is, don't worry. Simply copy GeSHi to your webserver. So for example, say your site is at http://mysite.com/myfolder, you can copy GeSHi to your site so the directory structure is like this:
+
+http://mysite.com/myfolder/geshi/[language files]
+http://mysite.com/myfolder/geshi.php
+
+Or you can put it in any subdirectory you like:
+
+http://mysite.com/myfolder/includes/geshi/[language files]
+http://mysite.com/myfolder/includes/geshi.php
+
+Caution:
+
+When using GeSHi on a live site, the only directory required is the geshi/ subdirectory. Both contrib/ and docs/ are worthless, and furthermore, as some people discovered, one of the files in contrib had a security hole (fixed as of 1.0.7.3). I suggest you delete these directories from any live site they are on.
+2.3: Basic Usage
+Top | Contents | Next | Previous
+
+Use of GeSHi is very easy. Here's a simple example:
+//
+// Include the GeSHi library
+//
+include_once('geshi.php');
+
+//
+// Define some source to highlight, a language to use
+// and the path to the language files
+//
+$source = '$foo = 45;
+for ( $i = 1; $i < $foo; $i++ )
+{
+  echo "$foo<br />\n";
+  --$foo;
+}';
+$language = 'php';
+//
+// Create a GeSHi object
+//
+$geshi =& new GeSHi($source, $language);
+
+//
+// And echo the result!
+//
+echo $geshi->parse_code();
+
+As you can see, there's only three really important lines:
+include_once('geshi.php');
+
+This line includes the GeSHi class for use
+$geshi = new GeSHi($source, $language);
+
+This line creates a new GeSHi object, holding the source and the language you want to use for highlighting.
+echo $geshi->parse_code();
+
+This line spits out the result :)
+
+So as you can see, simple usage of GeSHi is really easy. Just create a new GeSHi object and get the code!
+
+Since version 1.0.2, there is a function included with GeSHi called geshi_highlight. This behaves exactly as the php function highlight_string behaves - all you do is pass it the language you want to use to highlight and the path to the language files as well as the source. Here are some examples:
+// Simply echo the highlighted code
+geshi_highlight($source, 'php', $path);
+
+// Get the code back, for use later
+$code = geshi_highlight($source, 'java', $path, true)
+
+// Check if there is an error with parsing this code
+ob_start();
+$result = geshi_highlight($source, 'perl', $path);
+$code = ob_get_contents();
+ob_end_clean();
+if ( !$result )
+{
+        // There was an error with highlighting...
+}
+else
+{
+        // All OK :)
+}
+
+However, these are really simple examples and doesn't even begin to cover all the advanced features of GeSHi. If you want to learn more, continue on to section 3: Advanced Features.
+3: Advanced Features
+Top | Contents | Next | Previous
+
+This section documents the advanced features of GeSHi - strict mode, using CSS classes, changing styles on the fly, disabling highlighting of some things and more.
+
+In this section there are many code snippets. For all of these, you should assume that the GeSHi library has been included, and a GeSHi object has been created and is referenced by the variable $geshi. Normally, the source, language and path used are arbitary.
+3.1 The Code Container
+Top | Contents | Next | Previous
+
+The Code Container has a fundamental effect on the layout of your code before you even begin to style. What is the Code Container? It's the bit of markup that goes around your code to contain it. By default your code is surrounded by a <pre>, but you can also specify a <div>.
+
+The <pre> header is the default. If you're familiar with HTML you'll know that whitespace is rendered "as is" by a <pre> element. The advantage for you is that if you use <pre> the whitespace you use will appear pretty much exactly how it is in the source, and what's more GeSHi won't have to add a whole lot of <br />'s and non-breaking spaces (&nbsp;) to your code to indent it. This saves you source code (and your valuable visitors waiting time and your bandwidth).
+
+But if you don't like <pre> or it looks stupid in your browser no matter what styles you try to apply to it or something similar, you might want to use a <div> instead. A <div> will result in more source - GeSHi will have to insert whitespace markup - but in return you can wrap long lines of code that would otherwise have your browser's horizontal scrollbar appear. Of course with <div> you can *not* wrap lines if you please. The highlighter demo at the GeSHi home page uses the <div> approach for this reason.
+
+At this stage there isn't an option to wrap the code in <code> tags (unless you use the function geshi_highlight), partly because of the inconsistent and unexpected ways stuff in <code> tags is highlighted. Besides, <code> is an inline element. But this may become an option in future versions.
+
+As of GeSHi 1.0.7.2 there is a new header type, that specifies that the code should not be wrapped in anything at all.
+
+Another requested addition has been made in GeSHi 1.0.7.20 to force GeSHi to create a block around the highlighted source even if this wasn't necessary, thus styles that are applied to the output of GeSHi can directly influence the code only even if headers and footers are present.
+
+To change/set the header to use, you call the set_header_type() method:
+$geshi->set_header_type(GESHI_HEADER_DIV);
+// or...
+$geshi->set_header_type(GESHI_HEADER_PRE); // or...
+$geshi->set_header_type(GESHI_HEADER_NONE);
+
+Those are the only three arguments you should pass to set_header_type. Passing anything else may cause inconsistencies in what is used as the Code Container (although it *should* simply use a <pre>). Better not to risk it.
+Note:
+
+GESHI_HEADER_DIV, GESHI_HEADER_PRE and GESHI_HEADER_NONE are constants, so don't put them in strings!
+Caution:
+
+The default styles for the <pre> and <div> will be different, especially if you use line numbers!. I have found that a <pre> results in code that is smaller than for that of a <div>, you should rectify this difference by using set_overall_style() if you need to. But be aware of this difference for if you are changing the header type!
+3.2: Line Numbers
+Top | Contents | Next | Previous
+
+GeSHi has the ability to add line numbers to your code (see the demo available at http://qbnz.com/highlighter/demo.php to see what can be achieved). Line numbers are a great way to make your code look professional, especially if you use the fancy line numbers feature.
+3.2.1: Enabling Line Numbers
+Top | Contents | Next | Previous
+
+To highlight a source with line numbers, you call the enable_line_numbers() method:
+$geshi->enable_line_numbers($flag);
+
+Where $flag is one of the following:
+
+    * GESHI_NORMAL_LINE_NUMBERS - Use normal line numbering
+    * GESHI_FANCY_LINE_NUMBERS - Use fancy line numbering
+    * GESHI_NO_LINE_NUMBERS - Disable line numbers (default)
+
+Normal line numbers means you specify a style for them, and that style gets applied to all of them. Fancy line numbers means that you can specify a different style for each nth line number. You change the value of n (default 5):
+$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 37);
+
+The second parameter is not used in any other mode. Setting it to 0 is the same as simply using normal line numbers. Setting it to 1 applies the fancy style to every line number.
+Note:
+
+The values above are CONSTANTS - so don't put them in strings!
+3.2.2 Styling Line Numbers
+Top | Contents | Next | Previous
+
+As of GeSHi 1.0.2, line numbers are added by the use of ordered lists. This solves the old issues of line number styles inheriting from styles meant for the code. Also, this solves an important issue about selecting code. For example, line numbers look nice, but when you go to select the code in your browser to copy it? You got the line numbers too! Not such a good thing, but thankfully this issue is now solved. What is the price? Unfortunately the whole way that styles are inherited/used has changed for those of you who were familiar with 1.0.1, and there is quite a bit more HTML involved. So think carefully about these things before you enable line numbers.
+
+Now, onto how to style line numbers:
+
+Styles are set for line numbers using the set_line_style() method:
+$geshi->set_line_style('background: #fcfcfc;');
+
+If you're using Fancy Line Numbers mode, you pass a second string for the style of the nth line number:
+$geshi->set_line_style('background: #fcfcfc;', 'background: #f0f0f0;');
+
+The second style will have no effect if you're not using Fancy Line Numbers mode.
+
+By default, the styles you pass overwrite the current styles. Add a boolean "true" after the styles you specify to combine them with the current styles:
+$geshi->set_line_style('background: red;', true);
+// or, for fancy line numbers
+$geshi->set_line_style('background: red;', 'background: blue;', true);
+Note:
+
+Due to a bug with Firefox the issue that should have been fixed with 1.0.2 has reappeared in another form as Firefox includes extra text\markup into plaintext versions of webpage copies. This can sometimes be useful (actually it's used to get the plaintext version of this documentation), but more often is quite annoying. Best practice so far is to either not use line numbers, or offer the visitor of your page a plaintext version of your source. To learn more have a look at the SF.net BugTracker Issue #1651996. This will hopefully be fixed in GeSHi version 1.2 or as soon as Firefox provides webdevelopers with adequate ways to control this feature - whichever comes first!
+Caution:
+
+When you set line number styles, the code will inherit those styles! This is the main issue to come out of the 1.0.2 release. If you want your code to be styled in a predictable manner, you'll have to call the set_code_style() method to rectify this problem.
+
+Note also that you cannot apply background colours to line numbers unless you use set_overall_style(). Here's how you'd style:
+
+   1. Use set_overall_style() to style the overall code block. For example, you can set the border style/colour, any margins and padding etc. using this method. In addition: set the background colour for all the line numbers using this method.
+   2. Use set_line_style() to style the foreground of the line numbers. For example, you can set the colour, weight, font, padding etc. of the line numbers using this method.
+   3. Use set_code_style() to explicitly override the styles you set for line numbers using set_line_style. For example, if you'd set the line numbers to be bold (or even if you'd only set the fancy line number style to be bold), and you didn't actually want your code to be bold, you'd make sure that font-weight: normal; was in the stylesheet rule you passed to set_code_style
+
+This is the one major change from GeSHi 1.0.1 - make sure you become familiar with this, and make sure that you check any code you have already styled with 1.0.1 when you upgrade to make sure nothing bad happens to it.
+3.2.3: Choosing a Start Number
+Top | Contents | Next | Previous
+
+As of GeSHi 1.0.2, you can now make the line numbers start at any number, rather than just 1. This feature is useful if you're highlighting code from a file from around a certain line number in that file, as an additional guide to those who will view the code. You set the line numbers by calling the start_line_numbers_at() method:
+$geshi->start_line_numbers_at($number);
+
+$number must be a positive integer (or zero). If it is not, GeSHi will convert it anyway.
+
+If you have not enabled line numbers, this will have no effect.
+Caution:
+
+Although I'd like GeSHi to have XHTML strict compliance, this feature will break compliancy (however transitional compliancy remains). This is because the only widely supported way to change the start value for line numbers is by using the start="number" attribute of the <ol> tag. Although CSS does provide a mechanism for doing this, it is only supported in Opera versions 7.5 and above (not even Firefox supports this).
+3.3: Using CSS Classes
+Top | Contents | Next | Previous
+
+Using CSS to highlight your code instead of in-lining the styles is a definate bonus. Not only is it more compliant (the w3c is deprecating the style attribute in XHTML 2.0) but it results in far less outputted code - up to a whopping 90% saving - which makes a *huge* difference to those unlucky of us on modems!
+3.3.1: Enabling CSS Classes
+Top | Contents | Next | Previous
+
+By default, GeSHi doesn't use the classes, so it's easy just to whack out some highlighted code if you need without worrying about stylesheets. However, if you're a bit more organised about it, you should use the classes ;). To turn the use of classes on, you call the enable_classes() method:
+$geshi->enable_classes();
+
+If you want to turn classes OFF for some reason later:
+$geshi->enable_classes(false);
+
+If classes are enabled when parse_code() is called, then the resultant source will use CSS classes in the output, otherwise it will in-line the styles. The advantages of using classes are great - the reduction in source will be very noticeable, and what's more you can use one stylesheet for several different highlights on the same page. In fact, you can even use an external stylesheet and link to that, saving even more time and source (because stylesheets are cached by browsers).
+Note:
+
+There have been problems with inline styles and the Symbol Highlighting added in 1.0.7.21. If you can you should therefore turn CSS classes ON to avoid those issues.
+Caution:
+
+This should be the very first method you call after creating a new GeSHi object! That way, various other methods can act upon your choice to use classes correctly. In theory, you could call this method just before parsing the code, but this may result in unexpected behaviour.
+3.3.2: Setting the CSS class and ID
+Top | Contents | Next | Previous
+
+You can set an overall CSS class and id for the code. This is a good feature that allows you to use the same stylesheet for many different snippets of code. You call set_overall_class() and set_overall_id to accomplish this:
+$geshi->set_overall_class('mycode');
+$geshi->set_overall_id('dk48ck');
+
+The default classname is the name of the language being used. This means you can use just the one stylesheet for all sources that use the same language, and incidentally means that you probably won't have to call these methods too often.
+
+CSS IDs are supposed to be unique, and you should use them as such. Basically, you can specify an ID for your code and then use that ID to highlight that code in a unique way. You'd do this for a block of code that you expressly wanted to be highlighted in a different way (see the section below on gettting the stylesheet for your code for an example).
+3.3.3: Getting the stylesheet for your code
+Top | Contents | Next | Previous
+
+The other half of using CSS classes is getting the stylesheet for use with the classes. GeSHi makes it very easy to get a stylesheet for your code, with one easy method call:
+$geshi->enable_classes();
+
+// Here we have code that will spit out a header for
+// a stylesheet. For example:
+
+echo '<html>
+<head><title>Code</title>
+<style type="text/css">
+<!--';
+
+// Echo out the stylesheet for this code block
+
+echo $geshi->get_stylesheet();
+
+// And continue echoing the page
+
+echo '-->
+</style></head>
+<body>';
+
+The get_stylesheet() method gets the stylesheet for your code in one easy call. All you need to do is output it in the correct place. As you can also see, you don't even have to enable class usage to get the stylesheet nessecary either - however not enabling classes but using the stylesheet may result in problems later.
+
+By default, get_stylesheet() tries to echo the least amount of code possible. Although currently it doesn't check to see if a certain lexic is even in the source, you can expect this feature in the future. At least for the present however, if you explicitly disable the highlighting of a certain lexic, or disable line numbers, the related CSS will not be outputted. This may be a bad thing for you perhaps you're going to use the stylesheet for many blocks of code, some with line numbers, others with some lexic enabled where this source has it disabled. Or perhaps you're building an external stylesheet and want all lexics included. So to get around this problem, you do this:
+$geshi->get_stylesheet(false);
+
+This turns economy mode off, and all of the stylesheet will be outputted regardless.
+
+Now lets say you have several snippets of code, using the same language. In most of them you don't mind if they're highlighted the same way (in fact, that's exactly what you want) but in one of them you'd like the source to be highlighted differently. Here's how you can do that:
+// assume path is the default "geshi/" relative to the current directory
+$geshi1 = new GeSHi($source1, $lang);
+$geshi2 = new GeSHi($source2, $lang);
+$geshi3 = new GeSHi($source3, $lang);
+
+// Turn classes on for all sources
+$geshi1->enable_classes();
+$geshi2->enable_classes();
+$geshi3->enable_classes();
+
+// Make $geshi3 unique
+$geshi3->set_overall_id('different');
+
+//
+// Methods are called on $geshi3 to change styles...
+//
+
+echo '<html>
+<head><title>Code</title>
+<style type="text/css">
+<!--
+';
+
+// Get the nessecary stylesheets
+echo $geshi1->get_stylesheet();
+echo $geshi3->get_stylesheet();
+
+echo '-->
+</style></head>
+<body>';
+
+
+echo 'Code snippet 1:';
+echo $geshi1->parse_code();
+echo 'Code snippet 2 (same highlighting as 1):';
+echo $geshi2->parse_code();
+echo 'Code snippet 3 (DIFFERENT highlighting):';
+echo $geshi3->parse_code();
+
+echo '</body></html>';
+
+Before version 1.0.2, you needed to set the class of the code you wanted to be unique to the empty string. This limitation has been removed in version 1.0.2 - if you set the ID of a block of code, all styling will be done based on that ID alone.
+3.3.4: Using an External Stylesheet
+Top | Contents | Next | Previous
+
+An external stylesheet can reduce even more the amount of code needed to highlight some source. However there are some drawbacks with this. To use an external stylesheet, it's up to you to link it in to your document, normally with the following HTML:
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="url_to_stylesheet.css" />
+
+In your external stylesheet you put CSS declarations for your code. Then just make sure you're using the correct class (use set_overall_class() to ensure this) and this should work fine.
+
+This method is great if you don't mind the source always being highlighted the same (in particular, if you're making a plugin for a forum/wiki/other system, using an external stylesheet is a good idea!). It saves a small amount of code and your bandwidth, and it's relatively easy to just change the stylesheet should you need to. However, using this will render the methods that change the styles of the code useless, because of course the stylesheet is no longer being dynamically generated. You can still disable highlighting of certain lexics dynamically, however.
+Note:
+
+As of version 1.0.2, GeSHi comes with a contrib/ directory, which in it contains a "wizard" script for creating a stylesheet. Although this script is by no means a complete solution, it will create the necessary rules for the basic lexics - comments, strings for example. Things not included in the wizard include regular expressions for any language that uses them (PHP and XML are two languages that use them), and keyword-link styles. However, this script should take some of the tedium out of the job of making an external stylesheet. Expect a much better version of this script in version 1.2!
+3.4: Changing Styles
+Top | Contents | Next | Previous
+
+One of the more powerful features of GeSHi is the ability to change the style of the output dynamically. Why be chained to the boring styles the language authors make up? You can change almost every single aspect of highlighted code - and can even say whether something is to be highlighted at all.
+
+If you're confused about "styles", you probably want to have a quick tutorial in them so you know what you can do with them. Checkout the homepage of CSS at http://www.w3.org/Style/CSS.
+3.4.1: The Overall Styles
+Top | Contents | Next | Previous
+
+The code outputted by GeSHi is either in a <div> or a <pre> (see the section entitled "The Code Container"), and this can be styled.
+$geshi->set_overall_style('... styles ...');
+
+Where styles is a string containing valid CSS declarations. By default, these styles overwrite the current styles, but you can change this by adding a second parameter:
+$geshi->set_overall_style('color: blue;', true);
+
+The default styles "shine through" wherever anything isn't highlighted. Also, you can apply more advanced styles, like position: (fixed|relative) etc, because a <div>/<pre> is a block level element.
+Note:
+
+Remember that a <div> will by default have a larger font size than a <pre>, as discussed in the section "The Code Container".
+3.4.2: Line Number Styles
+Top | Contents | Next | Previous
+
+You may wish to refer to the section Styling Line Numbers before reading this section.
+
+As of version 1.0.2, the way line numbers are generated is different, so therefore the way that they are styled is different. In particular, now you cannot set the background style of the fancy line numbers to be different from that of the normal line numbers.
+
+Line number styles are set by using the method set_line_style:
+$geshi->set_line_style($style1, $style2);
+
+$style1 is the style of the line numbers by default, and $style2 is the style of the fancy line numbers.
+Caution:
+
+Things have changed since 1.0.1! This note is very important - please make sure you check this twice before complaining about line numbers!
+
+Because of the way that ordered lists are done in HTML, there really isn't normally a way to style the actual numbers in the list. I've cheated somewhat with GeSHi - I've made it possible to use CSS to style the foreground of the line numbers. So therefore, you can change the color, font size and type, and padding on them. If you want to have a pretty background, you must use set_overall_style() to do this, and use set_code_style() to style the actual code! This is explained in the section above: Styling Line Numbers.
+
+In addition, the styles for fancy line numbers is now the difference between the normal styles and the styles you want to achieve. For example, in GeSHi prior to 1.0.2 you may have done this to style line numbers:
+$geshi->set_line_style('color: red; font-weight: bold;', 'color: green; font-weight: bold');
+
+Now you instead can do this:
+$geshi->set_line_style('color: red; font-weight: bold;', 'color: green;');
+
+The font-weight: bold; will automatically carry through to the fancy styles. This is actually a small saving in code - but the difference may be confusing for anyone using 1.0.1 at first.
+3.4.3: Setting Keyword Styles
+Top | Contents | Next | Previous
+
+Perhaps the most regular change you will make will be to the styles of a keyword set. In order to change the styles for a particular set, you'll have to know what the set is called first. Sets are numbered from 1 up. Typically, set 1 contains keywords like if, while, do, for, switch etc, set 2 contains null, false, true etc, set 3 contains function inbuilt into the language (echo, htmlspecialchars etc. in PHP) and set 4 contains data types and similar variable modifiers: int, double, real, static etc. However these things are not fixed, and you should check the language file to see what key you want. Having a familiarity with a language file is definately a plus for using it.
+
+To change the styles for a keyword set, call the set_keyword_group_style() method:
+$geshi->set_keyword_group_style($group, $styles);
+
+Where $group is the group to change the styles for and $styles is a string containing the styles to apply to that group.
+
+By default, the styles you pass overwrite the current styles. Add a boolean true after the styles you specify to combine them with the current styles:
+$geshi->set_keyword_group_style(3, 'color: white;', true);
+3.4.4: Setting Comment Styles
+Top | Contents | Next | Previous
+
+To change the styles for a comment group, call the set_comments_style() method:
+$geshi->set_comments_style($group, $styles);
+
+Where $group is either a number corresponding to a single-line comment, or the string 'MULTI' to specify multiline comments:
+$geshi->set_comments_style(1, 'font-style: italic;');
+$geshi->set_comments_style('MULTI', 'display: hidden;');
+
+By default, the styles you pass overwrite the current styles. Add a boolean true after the styles you specify to combine them with the current styles:
+$geshi->set_comments_style(1, 'font-weight: 100;', true);
+Note:
+
+In 1.0.7.22 a new kind of Comments called "COMMENT_REGEXP" has been added. Those are handled by setting single line comment styles.
+3.4.5: Setting Other Styles
+Top | Contents | Next | Previous
+
+GeSHi can highlight many other aspects of your source other than just keywords and comments. Strings, Numbers, Methods and Brackets among other things can all also be highlighted. Here are the related methods:
+$geshi->set_escape_characters_style($styles[, $preserve_defaults]);
+$geshi->set_symbols_style($styles[, $preserve_defaults]);
+$geshi->set_strings_style($styles[, $preserve_defaults]);
+$geshi->set_numbers_style($styles[, $preserve_defaults]);
+$geshi->set_methods_style($key, $styles[, $preserve_defaults]);
+$geshi->set_regexps_style($key, $styles[, $preserve_defaults]);
+
+$styles is a string containing valid stylesheet declarations, while $preserve_defaults should be set to true if you want your styles to be merged with the previous styles. In the case of set_methods_style, you should select a group to set the styles of, check the language files for the number used for each "object splitter".
+
+Like this was possible for set_method_style a new parameter has been introduced for set_symbols_style too which allows you to select the group of symbols for which you'd like to change your style. $geshi->set_symbols_style($styles[, $preserve_defaults[, $group]]);
+If the third parameter is not given, group 0 is assumed. Furthermore you should note that any changes to group 0 are also reflected in the bracket style, i.e. a pass-through call to set_bracket_style is made.
+3.5: Case Sensitivity and Auto Casing
+Top | Contents | Next | Previous
+
+Controlling the case of the outputted source is an easy job with GeSHi. You can control which keywords are converted in case, and also control whether keywords are checked in a case sensitive manner.
+3.5.1: Auto-Caps/Nocaps
+Top | Contents | Next | Previous
+
+Auto-Caps/Nocaps is a nifty little feature that capitalises or lowercases automatically certain lexics when they are styled. I dabble in QuickBASIC, a dialect of BASIC which is well known for it's capatalisation, and SQL is another language well known for using caps for readability.
+
+To change what case lexics are rendered in, you call the set_case_keywords() method:
+$geshi->set_case_keywords($caps_modifier);
+
+The valid values to pass to this method are:
+
+    * GESHI_CAPS_NO_CHANGE - Don't change the case of any lexics, leave as they are found
+    * GESHI_CAPS_UPPER - Uppercase all lexics found
+    * GESHI_CAPS_LOWER - Lowercase all lexics found
+
+Caution:
+
+When I say "lexic", I mean "keywords". Any keyword in any keyword array will be modified using this option! This is one small area of inflexibility I hope to fix in 1.2.X.
+
+I suspect this will only be used to specify GESHI_CAPS_NO_CHANGE to turn off autocaps for languages like SQL and BASIC variants, like so:
+$geshi = new GeSHi($source, 'sql');
+$geshi->set_case_keywords(GESHI_CAPS_NO_CHANGE); // don't want keywords capatalised
+
+All the same, it can be used for some interesting effects:
+$geshi = new GeSHi($source, 'java');
+// Anyone who's used java knows how picky it is about CapitalLetters...
+$geshi->set_case_keywords(GESHI_CAPS_LOWER);
+// No *way* the source will look right now ;)
+3.5.2: Setting Case Sensitivity
+Top | Contents | Next | Previous
+
+Some languages, like PHP, don't mind what case function names and keywords are in, while others, like Java, depend on such pickiness to maintain their bad reputations ;). In any event, you can use the set_case_sensitivity to change the case sensitiveness of a particular keyword group from the default:
+$geshi->set_case_sensitivity($key, $sensitivity);
+
+Where $key is the key of the group for which you wish to change case sensitivness for (see the language file for that language), and $sensitivity is a boolean value - true if the keyword is case sensitive, and false if not.
+3.6: Changing the Source, Language, Config Options
+Top | Contents | Next | Previous
+
+What happens if you want to change the source to be highlighted on the fly, or the language. Or if you want to specify any of those basic fields after you've created a GeSHi object? Well, that's where these methods come in.
+3.6.1: Changing the Source Code
+Top | Contents | Next | Previous
+
+To change the source code, you call the set_source() method:
+$geshi->set_source($newsource);
+
+Example:
+$geshi = new GeSHi($source1, 'php');
+
+// Method calls to specify various options...
+
+$code1 = $geshi->parse_code();
+
+$geshi->set_source($source2);
+$code2 = $geshi->parse_code();
+3.6.2: Changing the Language
+Top | Contents | Next | Previous
+
+What happens if you want to change the language used for highlighting? Just call set_language():
+$geshi->set_language('newlanguage');
+
+Example:
+$geshi = new GeSHi($source, 'php');
+
+$code = $geshi->parse_code();
+
+// Highlight GeSHi's output
+$geshi->set_source($code);
+$geshi->set_language('html4strict');
+$geshi->enable_classes(false);
+echo $geshi->parse_code();
+Note:
+
+Names are case-insensitive - they will be converted to lower case to match a language file however. So if you're making a language file, remember it should have a name in lower case.
+Note:
+
+What you pass to this method is the name of a language file, minus the .php extension. If you're writing a plugin for a particular application, it's up to you to somehow convert user input into a valid language name.
+Caution:
+
+GeSHi include()s the language file, so be careful to make sure that users can't pass some wierd language name to include any old script! GeSHi tries to strip non-valid characters out of a language name, but you should always do this your self anyway. In particular, language files are always lower-case, with either alphanumeric characters, dashes or underscores in their name.
+
+At the very least, strip "/" characters out of a language name.
+3.6.3: Changing the Language Path
+Top | Contents | Next | Previous
+
+What happens if all of a sudden you want to use language files from a different directory from the current language file location? You call the set_language_path() method:
+$geshi->set_language_path($newpath);
+
+It doesn't matter whether the path has a trailing slash after it or not - only that it points to a valid folder. If it doesn't, that's your tough luck ;)
+3.6.4: Changing the Character Set
+Top | Contents | Next | Previous
+Note:
+
+As of GeSHi 1.0.7.18, you don't need to use this, as htmlspecialchars is not being used due to a security flaw in it (that is unpatched in even the most recent PHP4 versions, and in PHP5 < 5.2). As long as you set the encoding properly with a php header() call, your foreign characters will be displayed correctly.
+
+As of version 1.0.3, you can use the method set_encoding to specify the character set that your source is in. Valid names are those names that are valid for the PHP function htmlentities():
+$geshi->set_encoding($encoding);
+
+There is a table of valid strings for $encoding at the php.net manual linked to above. If you do not specify an encoding, or specify an invalid encoding, the character set used is ISO-8859-1.
+Using load_from_file to Change the Language and Source Code
+Top | Contents | Next | Previous
+
+As of GeSHi 1.0.5, you can use the method load_from_file to load the source code and language from a file. Simply pass this method a file name and it will attempt to load the source and set the language.
+$geshi->load_from_file($file_name, $lookup);
+
+$file_name is the file name to use, and $lookup is an optional parameter that contains a lookup array to use for deciding which language to choose. You can use this to override GeSHi's default lookup array, which may not contain the extension of the file you're after, or perhaps does have your extension but under a different language. The lookup array is of the form:
+
+array(
+        *   'lang_name' => array('extension', 'extension', ...),
+        *   'lang_name' ...
+        * );
+
+Also, you can use the method get_language_name_from_extension if you need to convert a file extension to a valid language name. This method will return the empty string if it could not find a match in the lookup, and like load_from_file it accepts an optional second parameter that contains a lookup array.
+3.7: Error Handling
+Top | Contents | Next | Previous
+
+What happens if you try to highlight using a language that doesn't exist? Or if GeSHi can't read a required file? The results you get may be confusing. You may check your code over and over, and never find anything wrong. GeSHi provides ways of finding out if GeSHi itself found anything wrong with what you tried to do. After highlighting, you can call the error() method:
+$geshi = new GeSHi('hi', 'thisLangIsNotSupported');
+
+echo $geshi->error();  // echoes error message
+
+The error message you will get will look like this:
+
+    GeSHi Error: GeSHi could not find the language thisLangIsNotSupported (using path geshi/) (code 2)
+
+The error outputted will be the last error GeSHi came across, just like how mysql_error() works.
+3.8: Disabling styling of some Lexics
+Top | Contents | Next | Previous
+
+One disadvantage of GeSHi is that for large source files using complex languages, it can be quite slow with every option turned on. Although future releases will concentrate on the speed/resource side of highlighting, for now you can gain speed increases by disabling some of the highlighting options. This is done by using a series of set_*_highlighting methods:
+
+    * set_keyword_group_highlighting($group, $flag): Sets whether a particular $group of keywords is to be highlighted or not. Consult the necessary language file(s) to see what $group should be for each group (typically a positive integer). $flag is false if you want to disable highlighting of this group, and true if you want to re-enable higlighting of this group. If you disable a keyword group then even if the keyword group has a related URL one will not be generated for that keyword.
+    * set_comments_highlighting($group, $flag): Sets whether a particular $group of comments is to be highlighted or not. Consult the necessary language file(s) to see what $group should be for each group (typically a positive integer, or the string 'MULTI' for multiline comments. $flag is false if you want to disable highlighting of this group, and true if you want to re-enable highlighting of this group.
+    * set_regexps_highlighting($regexp, $flag): Sets whether a particular $regexp is to be highlighted or not. Consult the necessary language file(s) to see what $regexp should be for each regexp (typically a positive integer, or the string 'MULTI' for multiline comments. $flag is false if you want to disable highlighting of this group, and true if you want to re-enable highlighting of this group.
+    * The following methods:
+          o set_escape_characters_highlighting($flag)
+          o set_symbols_highlighting($flag)
+          o set_strings_highlighting($flag)
+          o set_numbers_highlighting($flag)
+          o set_methods_highlighting($flag)
+      Work on their respective lexics (e.g. set_methods_highlighting will disable/enable highlighting of methods). For each method, if $flag is false then the related lexics will not be highlighted at all (this means no HTML will surround the lexic like usual, saving on time and bandwidth.
+
+In case all highlighting should be disabled or reenabled GeSHi provides two methods called disable_highlighting() and enable_highlighting($flag). The optional paramter $flag has been added in 1.0.7.21 and specifies the desired state, i.e. true (default) to turn all highlighting on, or false to turn all highlighting off. Since 1.0.7.21 the method disnable_highlighting() has become deprecated.
+3.9: Setting the Tab Width
+Top | Contents | Next | Previous
+
+If you're using the <pre> header, tabs are handled automatically by your browser, and in general you can count on good results. However, if you're using the <div> header, you may want to specify a tab width explicitly.
+
+Note that tabs created in this fashion won't be like normal tabs - there won't be "tab-stops" as such, instead tabs will be replaced with the specified number of spaces.
+
+To change the tab width, you call the set_tab_width() method:
+$geshi->set_tab_width($width);
+
+Where $width is the width in spaces that you'd like tabs to be.
+3.10: Using Strict Mode
+Top | Contents | Next | Previous
+
+Some languages like to get tricky, and jump in and out of the file that they're in. For example, the vast majority of you reading this will have used a PHP file. And you know that PHP code is only executed if it's within delimiters like <?php and ?> (there are others of course...). So what happens if you do the following in a php file?
+<img src="<?php echo rand(1, 100) ?>" />
+
+Well normally using GeSHi with PHP, or using a bad highlighter, you'll end up with this:
+<img src="<?php echo rand(1, 100) ?>" />
+
+What a mess! Especially if you're being slack about where you're putting your quotes, you could end up with the rest of your file as bright red. Fortunately, you can tell GeSHi to be "strict" about just when it highlights and when it does not, using the enable_strict_mode method:
+$geshi->enable_strict_mode($mode);
+
+Where $mode is true or not specified to enable strict mode, or false to disable strict mode if you've already turned it and don't want it now.
+
+Here's the result: much better!
+<img src="<?php echo rand(1, 100) ?>" />
+3.11: Adding/Removing Keywords
+Top | Contents | Next | Previous
+
+Lets say that you're working on a large project, with many files, many classes and many functions. Perhaps also you have the source code on the web and highlighted by GeSHi, perhaps as a front end to CVS, as a learning tool, something to refer to, whatever. Well, why not highlight the names of the functions and classes *your* project uses, as well as the standard functions and classes? Or perhaps you're not interested in highlighting certain functions, and would like to remove them? Or maybe you don't mind if an entire function group goes west in the interest of speed? GeSHi can handle all of this!
+3.11.1: Adding a Keyword
+Top | Contents | Next | Previous
+
+If you want to add a keyword to an existing keyword group, you use the add_keyword method:
+$geshi->add_keyword($key, $word);
+
+Where $key is the index of the group of keywords you want to add this keyword to, and $word is the word to add.
+
+This implies knowledge of the language file to know the correct index.
+Note:
+
+Keywords should contain at least two alphabetical characters (lower or upper case letters only). This is to enable GeSHi to work much faster by not bothering to try to detect keywords in parts of your source where there is no alphabetical characters.
+3.11.2: Removing a Keyword
+Top | Contents | Next | Previous
+
+Perhaps you want to remove a keyword from an existing group. Maybe you don't use it and want to save yourself some time. Whatever the reason, you can remove it using the remove_keyword method:
+$geshi->remove_keyword($key, $word);
+
+Where $key is the index of the gropu of keywords that you want to remove this keyword from, and $word is the word to remove.
+
+This implies knowledge of the language file to know the correct index - most of the time the keywords you'll want to remove will be in group 3, but this is not guaranteed and you should check the language file first.
+
+This function is silent - if the keyword is not in the group you specified, nothing awful will happen ;)
+3.11.3: Adding a Keyword Group
+Top | Contents | Next | Previous
+
+Lets say for your big project you have several main functions and classes that you'd like highlighted. Why not add them as their own group instead of having them highlighted the same way as other keywords? Then you can make them stand out, and people can instantly see which functions and classes are user defined or inbuilt. Furthermore, you could set the URL for this group to point at the API documentation of your project.
+
+You add a keyword group by using the add_keyword_group method:
+$geshi->add_keyword_group($key, $styles, $case_sensitive, $words);
+
+Where $key is the key that you want to use to refer to this group, $styles is the styles that you want to use to style this group, $case_sensitive is true or false depending on whether you want this group of keywords to be case sensitive or not and $words is an array of words (or a string) of which words to add to this group. For example:
+$geshi->add_keyword_group(10, 'color: #600000;', false, array('myfunc_1', 'myfunc_2', 'myfunc_3'));
+
+Adds a keyword group referenced by index 10, of which all keywords in the group will be dark red, each keyword can be in any case and which contains the keywords "myfunc_1", "myfunc_2" and "myfunc_3".
+
+After creating such a keyword group, you may call other GeSHi methods on it, just as you would for any other keyword group.
+Caution:
+
+If you specify a $key for which there is already a keyword group, the old keyword group will be overwritten! Most language files don't use numbers larger than 5, so I recommend you play it safe and use a number like 10 or 42.
+3.11.4: Removing a Keyword Group
+Top | Contents | Next | Previous
+
+Perhaps you *really* need speed? Why not just remove an entire keyword group? GeSHi won't have to loop through each keyword checking for its existance, saving much time. You remove a keyword group by using the remove_keyword_group method:
+$geshi->remove_keyword_group($key);
+
+Where $key is the key of the group you wish to remove. This implies knowleged of the language file.
+3.12: Headers and Footers for Your Code
+Top | Contents | Next | Previous
+
+So you want to add some special information to the highlighted source? GeSHi can do that too! You can specify headers and footers for your code, style them, and insert information from the highlighted source into your header or footer.
+3.12.1: Keyword Substitution
+Top | Contents | Next | Previous
+
+In your header and footer, you can put special keywords that will be replaced with actual configuration values for this GeSHi object. The keywords you can use are:
+
+    * <TIME> or {TIME}: Is replaced by the time it took for the parse_code method - i.e., how long it took for your code to be highlighted. The time is returned to three decimal places.
+    * <LANGUAGE> or {LANGUAGE}: Is replaced by a nice, friendly version of the language name used to highlight this code.
+    * <VERSION> or {VERSION}: The GeSHi version used to highlight the code.
+
+3.12.2: Setting Header Content
+Top | Contents | Next | Previous
+
+The header for your code is a <div>, which is inside the containing block. Therefore, it is affected by the method set_overall_style, and should contain the sort of HTML that belongs in a <div>. You may use any HTML you like, and format it as an HTML document. You should use valid HTML - convert to entities any quotemarks or angle brackets you want displayed. You set the header content using the method set_header_content:
+$geshi->set_header_content($content);
+
+Where $content is the HTML you want to use for the header.
+3.12.3: Setting Footer Content
+Top | Contents | Next | Previous
+
+The footer for your code is a <div>, which is inside the containing block. Therefore, it is affected by the method set_overall_style, and should contain the sort of HTML that belongs in a <div>. You may use any HTML you like, and format it as an HTML document. You should use valid HTML - convert to entities any quotemarks or angle brackets you want displayed. You set the footer content using the method set_footer_content:
+$geshi->set_footer_content($content);
+
+Where $content is the HTML you want to use for the footer.
+3.12.4: Styling Header Content
+Top | Contents | Next | Previous
+
+You can apply styles to the header content you have set with the set_header_content_style:
+$geshi->set_header_content_style($styles);
+
+Where $styles is the stylesheet declarations you want to use to style the header content.
+3.12.5: Styling Footer Content
+Top | Contents | Next | Previous
+
+You can apply styles to the footer content you have set with the set_footer_content_style:
+$geshi->set_footer_content_style($styles);
+
+Where $styles is the stylesheet declarations you want to use to style the footer content.
+3.13: Keyword URLs
+Top | Contents | Next | Previous
+
+As of version 1.0.2, GeSHi allows you to specify a URL for keyword groups. This URL is used by GeSHi to convert the keywords in that group into URLs to appropriate documentation. And using add_keyword_group you can add functions and classes from your own projects and use the URL functionality to provide a link to your own API documentation.
+3.13.1: Setting a URL for a Keyword Group
+Top | Contents | Next | Previous
+
+To set the URL to be used for a keyword group, you use the set_url_for_keyword_group method:
+$geshi->set_url_for_keyword_group($group, $url);
+
+Where $group is the keyword group you want to assign the URL for, and $url is the URL for this group of keywords.
+
+You may be wondering how to make each keyword in the group point to the correct URL. You do this by putting {FNAME} in the URL at the correct place. For example, PHP makes it easy by linking www.php.net/function-name to the documentation for that function, so the URL used is http://www.php.net/{FNAME}.
+
+Of course, when you get to a language like Java, that puts its class documentation in related folders, it gets a little trickier to work out an appropriate URL (see the Java language file!). I hope to provide some kind of redirection service at the GeSHi website in the future.
+Note:
+
+As of Version 1.0.7.21 there have been added two more symbols you can use to link to functions. {FNAMEL} will generate the lowercase version of the keyword, {FNAMEU} will generate the upper-case version. {FNAME} will provide the keyword as specified in the language file.
+3.13.2: Disabling a URL for a Keyword Group
+Top | Contents | Next | Previous
+
+It's easy to disable a URL for a keyword group: Simply use the method set_url_for_keyword_group to pass an empty string as the URL:
+$geshi->set_url_for_keyword_group($group, '');
+3.13.3 Disabling all URLs for Keywords
+Top | Contents | Next | Previous
+
+As of GeSHi 1.0.7.18, you can disable all URL linking for keywords:
+$geshi->enable_keyword_links(false);
+3.13.4: Styling Links
+Top | Contents | Next | Previous
+
+You can also style the function links. You can style their default status, hovered, active and visited status. All of this is controlled by one method, set_link_styles:
+$geshi->set_link_styles($mode, $styles);
+
+Where $mode is one of four values:
+
+    * GESHI_LINK: The default style of the links.
+    * GESHI_HOVER: The style of the links when they have focus (the mouse is hovering over them).
+    * GESHI_ACTIVE: The style of the links when they are being clicked.
+    * GESHI_VISITED: The style of links that the user has already visited.
+
+And $styles is the stylesheet declarations to apply to the links.
+3.13.5: Setting the Link Target
+Top | Contents | Next | Previous
+
+Perhaps you want to set the target of link attributes, so the manual pages open in a new window? Use the set_link_target method:
+$geshi->set_link_target($target, $styles);
+
+Where $target is any valid (X)HTML target value - _blank or _top for example.
+3.14: Using Contextual Importance
+Top | Contents | Next | Previous
+Caution:
+
+This functionality is not only buggy, but is proving very hard to implement in 1.1.X. Therefore, this functionality may well be removed in 1.2.0. You are hereby warned!
+3.15: Highlighting Special Lines "Extra"
+Top | Contents | Next | Previous
+
+An alternative (and more stable) method of highlighting code that is important is to use extra highlighting by line. Although you may not know what line numbers contain the important lines, if you do this method is a much more flexible way of making important lines stand out.
+3.15.1: Specifying the Lines to Highlight Extra
+Top | Contents | Next | Previous
+
+To specify which lines to highlight extra, you past an array containing the line numbers to highlight_lines_extra:
+$geshi->highlight_lines_extra($array);
+
+The array could be in the form array(2, 3, 4, 7, 12, 344, 4242), made from a DB query, generated from looking through the source for certain important things and working out what line those things are... however you get the line numbers, the array should simply be an array of integers.
+
+Here's an example, using the same source as before:
+//
+// Here we go again! This time we'll simply highlight the 8th line
+//
+$source = 'public int[][] product ( n, m )
+{
+  int [][] ans = new int[n][m];
+  for ( int i = 0; i < n; i++ )
+  {
+    for ( int j = 0; i < m; j++ )
+    {
+      ans[i][j] = i * j;
+    }
+  }
+  return ans;
+}';
+
+$geshi = new GeSHi($source, 'java');
+
+$geshi->highlight_lines_extra(array(8));
+echo $geshi->parse_code();
+
+Which produces:
+public int[][] product ( n, m )
+{
+  int [][] ans = new int[n][m];
+  for ( int i = 0; i < n; i++ )
+  {
+    for ( int j = 0; i < m; j++ )
+    {
+      ans[i][j] = i * j;
+    }
+  }
+  return ans;
+}
+
+What's more, as you can see the code on a highlighted line is still actually highlighted itself.
+Note:
+
+As you can see, this is a little buggy, but that is because of HTML laws (code elements should not contain div elements). This works just fine if you use line numbers.
+3.15.2: Styles for the Highlighted Lines
+Top | Contents | Next | Previous
+
+Again as with contextual importance, you're not chained to the yellow theme that is the default. You can use the set_highlight_lines_extra_style method:
+$geshi->set_highlight_lines_extra_style($styles);
+
+Where $styles is the stylesheet declarations that you want to apply to highlighted lines.
+3.16: Adding IDs to Each Line
+Top | Contents | Next | Previous
+
+Perhaps you're a javascript junkie? GeSHi provides a way to give each line an ID so you can access that line with javascript, or perhaps just by plain CSS (though if you want to access lines by CSS you should use the method in the previous section). To enable IDs you call the enable_ids method:
+$geshi->enable_ids($flag);
+
+Where $flag is true or not present to enable IDs, and false to disable them again if you need.
+
+The ID generated is in the form {overall-css-id}-{line-number}. So for example, if you set the overall CSS id to be "mycode", then the IDs for each line would by "mycode-1", "mycode-2" etc. If there is no CSS ID set, then one is made up in the form geshi-[4 random characters], but this is not so useful for if you want to do javascript manipulation.
+3.17: Getting the Time of Styling
+Top | Contents | Next | Previous
+
+Once you've called parse_code, you can get the time it took to run the highlighting by calling the get_time method:
+$geshi = new GeSHi($source, $language, $path);
+
+$code = mysql_real_escape_string($geshi->parse_code());
+$time = $geshi->get_time();
+
+// do something with it
+mysql_query("INSERT INTO code VALUES ('$code', '$time')");
+4: Language Files
+Top | Contents | Next | Previous
+
+So now you know what features GeSHi offers, and perhaps you've even meddled with the source. Or perhaps you'd like a language file for language X but it doesn't seem to be supported? Rubbish! GeSHi will highlight anything, what do you think I coded this for? ^_^ You'll just have to learn how to make a language file yourself. And I promise it's not too hard - and if you're here you're in the right place!
+4.1: An Example Language File
+Top | Contents | Next | Previous
+
+Let's begin by looking at an example language file - the language file for the first language ever supported, PHP.
+
+<?php
+/*************************************************************************************
+ * php.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.2
+ * CVS Revision Version: $Revision: 1196 $
+ * Date Started: 2004/06/20
+ * Last Modified: $Date: 2008-06-08 17:55:42 +0000 (So, 08. Jun 2008) $
+ *
+ * PHP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/XX/XX (1.0.2)
+ *  -  Added URL support
+ *  -  Added extra constants
+ * 2004/08/05 (1.0.1)
+ *  -  Added support for symbols
+ * 2004/07/14 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Make sure the last few function I may have missed
+ *   (like eval()) are included for highlighting
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+       'LANG_NAME' => 'PHP',
+       'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+       'COMMENT_MULTI' => array('/*' => '*/'),
+       'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+       'QUOTEMARKS' => array("'", '"'),
+       'ESCAPE_CHAR' => '\\',
+       'KEYWORDS' => array(
+               1 => array(
+                       'include', 'require', 'include_once', 'require_once',
+                       'for', 'foreach', 'as', 'if', 'elseif', 'else', 'while', 'do', 'endwhile', 'endif', 'switch', 'case', 'endswitch',
+                       'return', 'break'
+                       ),
+               2 => array(
+                       'null', '__LINE__', '__FILE__',
+                       'false', '&lt;?php', '?&gt;', '&lt;?',
+                       '&lt;script language=', '&lt;/script&gt;',
+                       'true', 'var', 'default',
+                       'function', 'class', 'new',
+                       '__FUNCTION__', '__CLASS__', '__METHOD__', 'PHP_VERSION',
+                       'PHP_OS', 'DEFAULT_INCLUDE_PATH', 'PEAR_INSTALL_DIR', 'PEAR_EXTENSION_DIR',
+                       'PHP_EXTENSION_DIR', 'PHP_BINDIR', 'PHP_LIBDIR', 'PHP_DATADIR', 'PHP_SYSCONFDIR',
+                       'PHP_LOCALSTATEDIR', 'PHP_CONFIG_FILE_PATH', 'PHP_OUTPUT_HANDLER_START', 'PHP_OUTPUT_HANDLER_CONT',
+                       'PHP_OUTPUT_HANDLER_END', 'E_ERROR', 'E_WARNING', 'E_PARSE', 'E_NOTICE',
+                       'E_CORE_ERROR', 'E_CORE_WARNING', 'E_COMPILE_ERROR', 'E_COMPILE_WARNING', 'E_USER_ERROR',
+                       'E_USER_WARNING', 'E_USER_NOTICE', 'E_ALL'
+                       ),
+               3 => array(
+                       'zlib_get_coding_type','zend_version','zend_logo_guid','yp_order','yp_next',
+                       'yp_match','yp_master','yp_get_default_domain','yp_first','yp_errno','yp_err_string',
+                       'yp_cat','yp_all','xml_set_unparsed_entity_decl_handler','xml_set_start_namespace_decl_handler','xml_set_processing_instruction_handler','xml_set_object',
+                       'xml_set_notation_decl_handler','xml_set_external_entity_ref_handler','xml_set_end_namespace_decl_handler','xml_set_element_handler','xml_set_default_handler','xml_set_character_data_handler',
+                       'xml_parser_set_option','xml_parser_get_option','xml_parser_free','xml_parser_create_ns','xml_parser_create','xml_parse_into_struct',
+                       'xml_parse','xml_get_error_code','xml_get_current_line_number','xml_get_current_column_number','xml_get_current_byte_index','xml_error_string',
+                       'wordwrap','wddx_serialize_vars','wddx_serialize_value','wddx_packet_start','wddx_packet_end','wddx_deserialize',
+                       'wddx_add_vars','vsprintf','vprintf','virtual','version_compare','var_export',
+                       'var_dump','utf8_encode','utf8_decode','usort','usleep','user_error',
+                       'urlencode','urldecode','unserialize','unregister_tick_function','unpack','unlink',
+                       'unixtojd','uniqid','umask','uksort','ucwords','ucfirst',
+                       'uasort','trim','trigger_error','touch','token_name','token_get_all',
+                       'tmpfile','time','textdomain','tempnam','tanh','tan',
+                       'system','syslog','symlink','substr_replace','substr_count','substr',
+                       'strval','strtr','strtoupper','strtotime','strtolower','strtok',
+                       'strstr','strspn','strrpos','strrev','strrchr','strpos',
+                       'strncmp','strncasecmp','strnatcmp','strnatcasecmp','strlen','stristr',
+                       'stripslashes','stripcslashes','strip_tags','strftime','stream_wrapper_register','stream_set_write_buffer',
+                       'stream_set_timeout','stream_set_blocking','stream_select','stream_register_wrapper','stream_get_meta_data','stream_filter_prepend',
+                       'stream_filter_append','stream_context_set_params','stream_context_set_option','stream_context_get_options','stream_context_create','strcspn',
+                       'strcoll','strcmp','strchr','strcasecmp','str_word_count','str_shuffle',
+                       'str_rot13','str_replace','str_repeat','str_pad','stat','sscanf',
+                       'srand','sqrt','sql_regcase','sprintf','spliti','split',
+                       'soundex','sort','socket_writev','socket_write','socket_strerror','socket_shutdown',
+                       'socket_setopt','socket_set_timeout','socket_set_option','socket_set_nonblock','socket_set_blocking','socket_set_block',
+                       'socket_sendto','socket_sendmsg','socket_send','socket_select','socket_recvmsg','socket_recvfrom',
+                       'socket_recv','socket_readv','socket_read','socket_listen','socket_last_error','socket_iovec_set',
+                       'socket_iovec_free','socket_iovec_fetch','socket_iovec_delete','socket_iovec_alloc','socket_iovec_add','socket_getsockname',
+                       'socket_getpeername','socket_getopt','socket_get_status','socket_get_option','socket_create_pair','socket_create_listen',
+                       'socket_create','socket_connect','socket_close','socket_clear_error','socket_bind','socket_accept',
+                       'sleep','sizeof','sinh','sin','similar_text','shuffle',
+                       'show_source','shmop_write','shmop_size','shmop_read','shmop_open','shmop_delete',
+                       'shmop_close','shm_remove_var','shm_remove','shm_put_var','shm_get_var','shm_detach',
+                       'shm_attach','shell_exec','sha1_file','sha1','settype','setlocale',
+                       'setcookie','set_time_limit','set_socket_blocking','set_magic_quotes_runtime','set_include_path','set_file_buffer',
+                       'set_error_handler','session_write_close','session_unset','session_unregister','session_start','session_set_save_handler',
+                       'session_set_cookie_params','session_save_path','session_register','session_regenerate_id','session_name','session_module_name',
+                       'session_is_registered','session_id','session_get_cookie_params','session_encode','session_destroy','session_decode',
+                       'session_cache_limiter','session_cache_expire','serialize','sem_remove','sem_release','sem_get',
+                       'sem_acquire','rtrim','rsort','round','rmdir','rewinddir',
+                       'rewind','restore_include_path','restore_error_handler','reset','rename','register_tick_function',
+                       'register_shutdown_function','realpath','readlink','readgzfile','readfile','readdir',
+                       'read_exif_data','rawurlencode','rawurldecode','range','rand','rad2deg',
+                       'quotemeta','quoted_printable_decode','putenv','proc_open','proc_close','printf',
+                       'print_r','prev','preg_split','preg_replace_callback','preg_replace','preg_quote',
+                       'preg_match_all','preg_match','preg_grep','pow','posix_uname','posix_ttyname',
+                       'posix_times','posix_strerror','posix_setuid','posix_setsid','posix_setpgid','posix_setgid',
+                       'posix_seteuid','posix_setegid','posix_mkfifo','posix_kill','posix_isatty','posix_getuid',
+                       'posix_getsid','posix_getrlimit','posix_getpwuid','posix_getpwnam','posix_getppid','posix_getpid',
+                       'posix_getpgrp','posix_getpgid','posix_getlogin','posix_getgroups','posix_getgrnam','posix_getgrgid',
+                       'posix_getgid','posix_geteuid','posix_getegid','posix_getcwd','posix_get_last_error','posix_errno',
+                       'posix_ctermid','pos','popen','pi','phpversion','phpinfo',
+                       'phpcredits','php_uname','php_sapi_name','php_logo_guid','php_ini_scanned_files','pg_update',
+                       'pg_untrace','pg_unescape_bytea','pg_tty','pg_trace','pg_setclientencoding','pg_set_client_encoding',
+                       'pg_send_query','pg_select','pg_result_status','pg_result_seek','pg_result_error','pg_result',
+                       'pg_query','pg_put_line','pg_port','pg_ping','pg_pconnect','pg_options',
+                       'pg_numrows','pg_numfields','pg_num_rows','pg_num_fields','pg_meta_data','pg_lowrite',
+                       'pg_lounlink','pg_loreadall','pg_loread','pg_loopen','pg_loimport','pg_loexport',
+                       'pg_locreate','pg_loclose','pg_lo_write','pg_lo_unlink','pg_lo_tell','pg_lo_seek',
+                       'pg_lo_read_all','pg_lo_read','pg_lo_open','pg_lo_import','pg_lo_export','pg_lo_create',
+                       'pg_lo_close','pg_last_oid','pg_last_notice','pg_last_error','pg_insert','pg_host',
+                       'pg_getlastoid','pg_get_result','pg_get_pid','pg_get_notify','pg_freeresult','pg_free_result',
+                       'pg_fieldtype','pg_fieldsize','pg_fieldprtlen','pg_fieldnum','pg_fieldname','pg_fieldisnull',
+                       'pg_field_type','pg_field_size','pg_field_prtlen','pg_field_num','pg_field_name','pg_field_is_null',
+                       'pg_fetch_row','pg_fetch_result','pg_fetch_object','pg_fetch_assoc','pg_fetch_array','pg_fetch_all',
+                       'pg_exec','pg_escape_string','pg_escape_bytea','pg_errormessage','pg_end_copy','pg_delete',
+                       'pg_dbname','pg_copy_to','pg_copy_from','pg_convert','pg_connection_status','pg_connection_reset',
+                       'pg_connection_busy','pg_connect','pg_cmdtuples','pg_close','pg_clientencoding','pg_client_encoding',
+                       'pg_cancel_query','pg_affected_rows','pfsockopen','pclose','pathinfo','passthru',
+                       'parse_url','parse_str','parse_ini_file','pack','overload','output_reset_rewrite_vars',
+                       'output_add_rewrite_var','ord','openssl_x509_read','openssl_x509_parse','openssl_x509_free','openssl_x509_export_to_file',
+                       'openssl_x509_export','openssl_x509_checkpurpose','openssl_x509_check_private_key','openssl_verify','openssl_sign','openssl_seal',
+                       'openssl_public_encrypt','openssl_public_decrypt','openssl_private_encrypt','openssl_private_decrypt','openssl_pkey_new','openssl_pkey_get_public',
+                       'openssl_pkey_get_private','openssl_pkey_free','openssl_pkey_export_to_file','openssl_pkey_export','openssl_pkcs7_verify','openssl_pkcs7_sign',
+                       'openssl_pkcs7_encrypt','openssl_pkcs7_decrypt','openssl_open','openssl_get_publickey','openssl_get_privatekey','openssl_free_key',
+                       'openssl_error_string','openssl_csr_sign','openssl_csr_new','openssl_csr_export_to_file','openssl_csr_export','openlog',
+                       'opendir','octdec','ob_start','ob_list_handlers','ob_implicit_flush','ob_iconv_handler',
+                       'ob_gzhandler','ob_get_status','ob_get_level','ob_get_length','ob_get_flush','ob_get_contents',
+                       'ob_get_clean','ob_flush','ob_end_flush','ob_end_clean','ob_clean','number_format',
+                       'nl_langinfo','nl2br','ngettext','next','natsort','natcasesort',
+                       'mysql_unbuffered_query','mysql_thread_id','mysql_tablename','mysql_table_name','mysql_stat','mysql_selectdb',
+                       'mysql_select_db','mysql_result','mysql_real_escape_string','mysql_query','mysql_ping','mysql_pconnect',
+                       'mysql_numrows','mysql_numfields','mysql_num_rows','mysql_num_fields','mysql_listtables','mysql_listfields',
+                       'mysql_listdbs','mysql_list_tables','mysql_list_processes','mysql_list_fields','mysql_list_dbs','mysql_insert_id',
+                       'mysql_info','mysql_get_server_info','mysql_get_proto_info','mysql_get_host_info','mysql_get_client_info','mysql_freeresult',
+                       'mysql_free_result','mysql_fieldtype','mysql_fieldtable','mysql_fieldname','mysql_fieldlen','mysql_fieldflags',
+                       'mysql_field_type','mysql_field_table','mysql_field_seek','mysql_field_name','mysql_field_len','mysql_field_flags',
+                       'mysql_fetch_row','mysql_fetch_object','mysql_fetch_lengths','mysql_fetch_field','mysql_fetch_assoc','mysql_fetch_array',
+                       'mysql_escape_string','mysql_error','mysql_errno','mysql_dropdb','mysql_drop_db','mysql_dbname',
+                       'mysql_db_query','mysql_db_name','mysql_data_seek','mysql_createdb','mysql_create_db','mysql_connect',
+                       'mysql_close','mysql_client_encoding','mysql_affected_rows','mysql','mt_srand','mt_rand',
+                       'mt_getrandmax','move_uploaded_file','money_format','mktime','mkdir','min',
+                       'microtime','method_exists','metaphone','memory_get_usage','md5_file','md5',
+                       'mbsubstr','mbstrrpos','mbstrpos','mbstrlen','mbstrcut','mbsplit',
+                       'mbregex_encoding','mberegi_replace','mberegi','mbereg_search_setpos','mbereg_search_regs','mbereg_search_pos',
+                       'mbereg_search_init','mbereg_search_getregs','mbereg_search_getpos','mbereg_search','mbereg_replace','mbereg_match',
+                       'mbereg','mb_substr_count','mb_substr','mb_substitute_character','mb_strwidth','mb_strtoupper',
+                       'mb_strtolower','mb_strrpos','mb_strpos','mb_strlen','mb_strimwidth','mb_strcut',
+                       'mb_split','mb_send_mail','mb_regex_set_options','mb_regex_encoding','mb_preferred_mime_name','mb_parse_str',
+                       'mb_output_handler','mb_language','mb_internal_encoding','mb_http_output','mb_http_input','mb_get_info',
+                       'mb_eregi_replace','mb_eregi','mb_ereg_search_setpos','mb_ereg_search_regs','mb_ereg_search_pos','mb_ereg_search_init',
+                       'mb_ereg_search_getregs','mb_ereg_search_getpos','mb_ereg_search','mb_ereg_replace','mb_ereg_match','mb_ereg',
+                       'mb_encode_numericentity','mb_encode_mimeheader','mb_detect_order','mb_detect_encoding','mb_decode_numericentity','mb_decode_mimeheader',
+                       'mb_convert_variables','mb_convert_kana','mb_convert_encoding','mb_convert_case','max','mail',
+                       'magic_quotes_runtime','ltrim','lstat','long2ip','log1p','log10',
+                       'log','localtime','localeconv','linkinfo','link','levenshtein',
+                       'lcg_value','ksort','krsort','key_exists','key','juliantojd',
+                       'join','jewishtojd','jdtounix','jdtojulian','jdtojewish','jdtogregorian',
+                       'jdtofrench','jdmonthname','jddayofweek','is_writeable','is_writable','is_uploaded_file',
+                       'is_subclass_of','is_string','is_scalar','is_resource','is_real','is_readable',
+                       'is_object','is_numeric','is_null','is_nan','is_long','is_link',
+                       'is_integer','is_int','is_infinite','is_float','is_finite','is_file',
+                       'is_executable','is_double','is_dir','is_callable','is_bool','is_array',
+                       'is_a','iptcparse','iptcembed','ip2long','intval','ini_set',
+                       'ini_restore','ini_get_all','ini_get','ini_alter','in_array','import_request_variables',
+                       'implode','image_type_to_mime_type','ignore_user_abort','iconv_set_encoding','iconv_get_encoding','iconv',
+                       'i18n_mime_header_encode','i18n_mime_header_decode','i18n_ja_jp_hantozen','i18n_internal_encoding','i18n_http_output','i18n_http_input',
+                       'i18n_discover_encoding','i18n_convert','hypot','htmlspecialchars','htmlentities','html_entity_decode',
+                       'highlight_string','highlight_file','hexdec','hebrevc','hebrev','headers_sent',
+                       'header','gzwrite','gzuncompress','gztell','gzseek','gzrewind',
+                       'gzread','gzputs','gzpassthru','gzopen','gzinflate','gzgetss',
+                       'gzgets','gzgetc','gzfile','gzeof','gzencode','gzdeflate',
+                       'gzcompress','gzclose','gregoriantojd','gmstrftime','gmmktime','gmdate',
+                       'glob','gettype','gettimeofday','gettext','getservbyport','getservbyname',
+                       'getrusage','getrandmax','getprotobynumber','getprotobyname','getopt','getmyuid',
+                       'getmypid','getmyinode','getmygid','getmxrr','getlastmod','getimagesize',
+                       'gethostbynamel','gethostbyname','gethostbyaddr','getenv','getdate','getcwd',
+                       'getallheaders','get_resource_type','get_required_files','get_parent_class','get_object_vars','get_meta_tags',
+                       'get_magic_quotes_runtime','get_magic_quotes_gpc','get_loaded_extensions','get_included_files','get_include_path','get_html_translation_table',
+                       'get_extension_funcs','get_defined_vars','get_defined_functions','get_defined_constants','get_declared_classes','get_current_user',
+                       'get_class_vars','get_class_methods','get_class','get_cfg_var','get_browser','fwrite',
+                       'function_exists','func_num_args','func_get_args','func_get_arg','ftruncate','ftp_systype',
+                       'ftp_ssl_connect','ftp_size','ftp_site','ftp_set_option','ftp_rmdir','ftp_rename',
+                       'ftp_rawlist','ftp_quit','ftp_pwd','ftp_put','ftp_pasv','ftp_nlist',
+                       'ftp_nb_put','ftp_nb_get','ftp_nb_fput','ftp_nb_fget','ftp_nb_continue','ftp_mkdir',
+                       'ftp_mdtm','ftp_login','ftp_get_option','ftp_get','ftp_fput','ftp_fget',
+                       'ftp_exec','ftp_delete','ftp_connect','ftp_close','ftp_chdir','ftp_cdup',
+                       'ftok','ftell','fstat','fsockopen','fseek','fscanf',
+                       'frenchtojd','fread','fputs','fpassthru','fopen','fnmatch',
+                       'fmod','flush','floor','flock','floatval','filetype',
+                       'filesize','filepro_rowcount','filepro_retrieve','filepro_fieldwidth','filepro_fieldtype','filepro_fieldname',
+                       'filepro_fieldcount','filepro','fileperms','fileowner','filemtime','fileinode',
+                       'filegroup','filectime','fileatime','file_get_contents','file_exists','file',
+                       'fgetss','fgets','fgetcsv','fgetc','fflush','feof',
+                       'fclose','ezmlm_hash','extract','extension_loaded','expm1','explode',
+                       'exp','exif_thumbnail','exif_tagname','exif_read_data','exif_imagetype','exec',
+                       'escapeshellcmd','escapeshellarg','error_reporting','error_log','eregi_replace','eregi',
+                       'ereg_replace','ereg','end','easter_days','easter_date','each',
+                       'doubleval','dngettext','dl','diskfreespace','disk_total_space','disk_free_space',
+                       'dirname','dir','dgettext','deg2rad','defined','define_syslog_variables',
+                       'define','decoct','dechex','decbin','debug_zval_dump','debug_backtrace',
+                       'deaggregate','dcngettext','dcgettext','dba_sync','dba_replace','dba_popen',
+                       'dba_optimize','dba_open','dba_nextkey','dba_list','dba_insert','dba_handlers',
+                       'dba_firstkey','dba_fetch','dba_exists','dba_delete','dba_close','date',
+                       'current','ctype_xdigit','ctype_upper','ctype_space','ctype_punct','ctype_print',
+                       'ctype_lower','ctype_graph','ctype_digit','ctype_cntrl','ctype_alpha','ctype_alnum',
+                       'crypt','create_function','crc32','count_chars','count','cosh',
+                       'cos','copy','convert_cyr_string','constant','connection_status','connection_aborted',
+                       'compact','closelog','closedir','clearstatcache','class_exists','chunk_split',
+                       'chr','chown','chop','chmod','chgrp','checkdnsrr',
+                       'checkdate','chdir','ceil','call_user_method_array','call_user_method','call_user_func_array',
+                       'call_user_func','cal_to_jd','cal_info','cal_from_jd','cal_days_in_month','bzwrite',
+                       'bzread','bzopen','bzflush','bzerrstr','bzerror','bzerrno',
+                       'bzdecompress','bzcompress','bzclose','bindtextdomain','bindec','bind_textdomain_codeset',
+                       'bin2hex','bcsub','bcsqrt','bcscale','bcpow','bcmul',
+                       'bcmod','bcdiv','bccomp','bcadd','basename','base_convert',
+                       'base64_encode','base64_decode','atanh','atan2','atan','assert_options',
+                       'assert','asort','asinh','asin','arsort','array_walk',
+                       'array_values','array_unshift','array_unique','array_sum','array_splice','array_slice',
+                       'array_shift','array_search','array_reverse','array_reduce','array_rand','array_push',
+                       'array_pop','array_pad','array_multisort','array_merge_recursive','array_merge','array_map',
+                       'array_keys','array_key_exists','array_intersect_assoc','array_intersect','array_flip','array_filter',
+                       'array_fill','array_diff_assoc','array_diff','array_count_values','array_chunk','array_change_key_case',
+                       'apache_setenv','apache_response_headers','apache_request_headers','apache_note','apache_lookup_uri','apache_get_version',
+                       'apache_child_terminate','aggregation_info','aggregate_properties_by_regexp','aggregate_properties_by_list','aggregate_properties','aggregate_methods_by_regexp',
+                       'aggregate_methods_by_list','aggregate_methods','aggregate','addslashes','addcslashes','acosh',
+                       'acos','abs','_','echo', 'print', 'global', 'static', 'exit', 'array', 'empty', 'eval', 'isset', 'unset', 'die'
+                       )
+               ),
+       'SYMBOLS' => array(
+               '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+               ),
+       'CASE_SENSITIVE' => array(
+               GESHI_COMMENTS => false,
+               1 => false,
+               2 => false,
+               3 => false,
+               ),
+       'STYLES' => array(
+               'KEYWORDS' => array(
+                       1 => 'color: #b1b100;',
+                       2 => 'color: #000000; font-weight: bold;',
+                       3 => 'color: #000066;'
+                       ),
+               'COMMENTS' => array(
+                       1 => 'color: #808080; font-style: italic;',
+                       2 => 'color: #808080; font-style: italic;',
+                       'MULTI' => 'color: #808080; font-style: italic;'
+                       ),
+               'ESCAPE_CHAR' => array(
+                       0 => 'color: #000099; font-weight: bold;'
+                       ),
+               'BRACKETS' => array(
+                       0 => 'color: #66cc66;'
+                       ),
+               'STRINGS' => array(
+                       0 => 'color: #ff0000;'
+                       ),
+               'NUMBERS' => array(
+                       0 => 'color: #cc66cc;'
+                       ),
+               'METHODS' => array(
+                       0 => 'color: #006600;'
+                       ),
+               'SYMBOLS' => array(
+                       0 => 'color: #66cc66;'
+                       ),
+               'REGEXPS' => array(
+                       0 => 'color: #0000ff;'
+                       ),
+               'SCRIPT' => array(
+                       0 => '',
+                       1 => '',
+                       2 => '',
+                       3 => ''
+                       )
+               ),
+       'URLS' => array(
+               1 => '',
+               2 => '',
+               3 => 'http://www.php.net/{FNAME}',
+               4 => ''
+               ),
+       'OOLANG' => true,
+       'OBJECT_SPLITTER' => '-&gt;',
+       'REGEXPS' => array(
+               0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+               ),
+       'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+       'SCRIPT_DELIMITERS' => array(
+               0 => array(
+                       '<?php' => '?>'
+                       ),
+               1 => array(
+                       '<?' => '?>'
+                       ),
+               2 => array(
+                       '<%' => '%>'
+                       ),
+               3 => array(
+                       '<script language="php">' => '</script>'
+                       )
+               ),
+       'HIGHLIGHT_STRICT_BLOCK' => array(
+               0 => true,
+               1 => true,
+               2 => true,
+               3 => true
+               )
+);
+
+?>
+
+If you're remotely familiar with PHP (or even if you're not), you can see that all that a language file consists of is a glorified variable assignment. Easy! All a language file does is assign a variable $language_data. Though still, there's a lot of indices to that array... but this section is here to break each index down and explain it to you.
+4.2: Language File Conventions
+Top | Contents | Next | Previous
+
+There are several conventions that are used in language files. For ease of use and readability, your language files should obey the following rules:
+
+    * Indentation is in tabs, not spaces: Use tabs! There's no excuse for using spaces in this day and age, where almost every good editor allows you to change the tab width. Tabs also take up less space, and ensure proper alignment. When you indent, use tabs, and if your editor converts tabs to spaces, tell it not to.
+    * Strings are in single quotes: Every string in a language file should be in single quotes ('), unless you are specifying a single quote as a quotemark or escape character, in which case they can be in double quotes for readability; or if you are specifying a REGEXP (see below)
+    * Large arrays are multi-lined: An array with more than three or four values should be broken into multiple lines. In any case, lines should not be wider than a full-screen window (about 100 chars per line max).
+    * Ending brackets for multi-lined arrays on a new line: Also with a comma after them, unless the array is the last one in a parent array. See the PHP language file for examples of where to use commas.
+    * Use GeSHi's constants: For capatalisation, regular expressions etc. use the GeSHi constants, not their actual values.
+
+There are more notes on each convention where it may appear in the language file sections below.
+4.3: Language File Sections
+Top | Contents | Next | Previous
+
+This section will look at all the sections of a language file, and how they relate to the final highlighting result.
+4.3.1: The Header
+Top | Contents | Next | Previous
+
+The header of a language file is the first lines with the big comment and the start of the variable $language_data:
+
+<?php
+/*************************************************************************************
+ * <name-of-language-file.php>
+ * ---------------------------------
+ * Author: <name> (<e-mail address>)
+ * Copyright: (c) 2004 <name> (<website URL>)
+ * Release Version: 1.0.0
+ * CVS Revision Version: $Revision: 1196 $
+ * Date Started: <date started>
+ * Last Modified: $Date: 2008-06-08 17:55:42 +0000 (So, 08. Jun 2008) $
+ *
+ * <name-of-language> language file for GeSHi.
+ *
+ * <any-comments...>
+ *
+ * CHANGES
+ * -------
+ * <date-of-release> (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated <date-of-release>)
+ * -------------------------
+ * <things-to-do>
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+
+The parts in angle brackets are the parts that you change for your language file. Everything else *must* remain the same!
+
+Here are the parts you should change:
+
+    * <name-of-language-file.php> - This should become the name of your language file. Language file names are in lower case and contain only alphanumeric characters, dashes and underscores. Language files end with .php (which you should put with the name of your language file, eg language.php)
+    * <name> - Your name, or alias.
+    * <e-mail address> - Your e-mail address. If you want your language file included with GeSHi you must include an e-mail address that refers to an inbox controlled by you.
+    * <website> - A URL of a website of yours (perhaps to a page that deals with your contribution to GeSHi, or your home page/blog)
+    * <date-started> - The date you started working on the language file. If you can't remember, guestimate.
+    * <name-of-language> - The name of the language you made this language file for (probably similar to the language file name).
+    * <any-comments> - Any comments you have to make about this language file, perhaps on where you got the keywords for, what dialect of the language this language file is for etc etc. If you don't have any comments, remove the space for them.
+    * <date-of-release - The date you released the language file to the public. If you simply send it to me for inclusion in a new GeSHi and don't release it, leave this blank, and I'll replace it with the date of the GeSHi release that it is first added to.
+
+Everything should remain the same, including $Revision: 1196 $ and $Date: 2008-06-08 17:55:42 +0000 (So, 08. Jun 2008) $ (I know these may look funny but they have their purpose for those of you who don't know about SVN).
+
+Also: I'm not sure about the copyright on a new language file. I'm not a lawyer, could someone contact me about whether the copyright for a new language file should be exclusivly the authors, or joint with me (if included in a GeSHi release)?
+4.3.2: The First Indices
+Top | Contents | Next | Previous
+
+Here is an example from the php language file of the first indices:
+
+       'LANG_NAME' => 'PHP',
+       'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+       'COMMENT_MULTI' => array('/*' => '*/'),
+       'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+       'QUOTEMARKS' => array("'", '"'),
+       'ESCAPE_CHAR' => '\\',
+
+The first indices are the first few lines of a language file before the KEYWORDS index. These indices specify:
+
+    * 'LANG_NAME': The name of the language. This name should be a human-readable version of the name (e.g. HTML 4 (transitional) instead of html4trans)
+    * 'COMMENT_SINGLE': An array of single-line comments in your language, indexed by integers starting from 1. A single line comment is a comment that starts at the marker and goes until the end of the line. These comments may be any length > 0, and since they can be styled individually, can be used for other things than comments (for example the Java language file defines "import" as a single line comment). If you are making a language that uses a ' (apostrophe) as a comment (or in the comment marker somewhere), use double quotes. e.g.: "'"
+    * 'COMMENT_MULTI': Used to specify multiline comments, an array in the form 'OPEN' => 'CLOSE'. Unfortunately, all of these comments you add here will be styled the same way (an area of improvement for GeSHi 1.2.X). These comment markers may be any length > 0.
+    * 'CASE_KEYWORDS': Used to set whether the case of keywords should be changed automatically as they are found. For example, in an SQL or BASIC dialect you may want all keywords to be upper case. The accepted values for this are:
+          o GESHI_CAPS_UPPER: Convert the case of all keywords to upper case.
+          o GESHI_CAPS_LOWER: Convert the case of all keywords to lower case.
+          o GESHI_CAPS_NO_CHANGE: Don't change the case of any keyword.
+    * 'QUOTEMARKS': Specifies the characters that mark the beginning and end of a string. This is another example where if your language includes the ' string delimiter you should use double quotes around it.
+    * 'ESCAPE_CHAR': Specifies the escape character used in all strings. If your language does not have an escape character then make this the empty string (''). This is not an array! If found, any character after an escape character and the escape character itself will be highlighted differently, and the character after the escape character cannot end a string.
+
+4.3.3: Keywords
+Top | Contents | Next | Previous
+
+Keywords will make up the bulk of a language file. In this part you add keywords for your language, including inbuilt functions, data types, predefined constants etc etc.
+
+Here's a (shortened) example from the php language file:
+
+       'KEYWORDS' => array(
+               1 => array(
+                       'include', 'require', 'include_once', 'require_once',
+                       'for', 'foreach', 'as', 'if', 'elseif', 'else', 'while', 'do', 'endwhile', 'endif', 'switch', 'case', 'endswitch',
+                       'return', 'break'
+                       ),
+               2 => array(
+                       'null', '__LINE__', '__FILE__',
+                       'false', '<?php', '?>', '<?',
+                       '<script language=', '</script>',
+                       'true', 'var', 'default',
+                       'function', 'class', 'new',
+                       '__FUNCTION__', '__CLASS__', '__METHOD__', 'PHP_VERSION',
+                       'PHP_OS', 'DEFAULT_INCLUDE_PATH', 'PEAR_INSTALL_DIR', 'PEAR_EXTENSION_DIR',
+                       'PHP_EXTENSION_DIR', 'PHP_BINDIR', 'PHP_LIBDIR', 'PHP_DATADIR', 'PHP_SYSCONFDIR',
+                       'PHP_LOCALSTATEDIR', 'PHP_CONFIG_FILE_PATH', 'PHP_OUTPUT_HANDLER_START', 'PHP_OUTPUT_HANDLER_CONT',
+                       'PHP_OUTPUT_HANDLER_END', 'E_ERROR', 'E_WARNING', 'E_PARSE', 'E_NOTICE',
+                       'E_CORE_ERROR', 'E_CORE_WARNING', 'E_COMPILE_ERROR', 'E_COMPILE_WARNING', 'E_USER_ERROR',
+                       'E_USER_WARNING', 'E_USER_NOTICE', 'E_ALL'
+                       ),
+               3 => array(
+                       'zlib_get_coding_type','zend_version','zend_logo_guid','yp_order','yp_next',
+                       'yp_match','yp_master','yp_get_default_domain','yp_first','yp_errno','yp_err_string',
+                       'yp_cat','yp_all','xml_set_unparsed_entity_decl_handler','xml_set_start_namespace_decl_handler','xml_set_processing_instruction_handler','xml_set_object',
+                       'xml_set_notation_decl_handler','xml_set_external_entity_ref_handler','xml_set_end_namespace_decl_handler','xml_set_element_handler','xml_set_default_handler','xml_set_character_data_handler',
+                       'xml_parser_set_option','xml_parser_get_option','xml_parser_free','xml_parser_create_ns','xml_parser_create','xml_parse_into_struct'
+                       )
+               ),
+
+You can see that the index 'KEYWORDS' refers to an array of arrays, indexed by positive integers. In each array, there are some keywords (in the actual php language file there is in fact many more keywords in the array indexed by 3). Here are some points to note about these keywords:
+
+    * Indexed by positive integers: Use nothing else! I may change this in 1.2.X, but for the 1.0.X series, use positive integers only.
+    * Keywords sorted in reverse: Keywords *should* be sorted in reverse order. I know that many of the language files I've made do not follow this rule, but that's because I made the files before I discovered the following issue with GeSHi: If you have two keywords, as and ascfor example, then when GeSHi encounters the "as" keyword it will be highlighted even if the "as" is part of "asc". I would get GeSHi to reverse-sort keyword arrays, but there's no harm in you doing this yourself and saving some processing time. At the least (and in fact this is sufficient) you should swap any keywords you come across that would be caught by this issue.
+    * Keywords are case sensitive (sometimes): If your language is case-sensitive, the correct casing of the keywords is defined as the case of the keywords in these keyword arrays. If you check the java language file you will see that everything is in exact casing. So if any of these keyword arrays are case sensitive, put the keywords in as their correct case! (note that which groups are case sensitive and which are not is configurable, see later on)
+    * Keywords must be in htmlentities() form: All keywords should be written as if they had been run through the php function htmlentities(). E.g, the keyword is &lt;foo&gt;, not <foo>
+    * Don't use keywords to highlight symbols: Just don't. It doesn't work, and there will be seperate support for symbols later.
+    * Markup Languages are special cases: Check the html4strict language file for an example: keywords have to be specified twice for opening tags and twice for each closing tag.
+
+4.3.4: Symbols and Case Sensitivity
+Top | Contents | Next | Previous
+
+So you've put all the keywords for your language in? Now for a breather before we style them :). Symbols define what symbols your language uses, these are things like colons, brackets/braces, and other such general punctuation, and case sensitivity alludes to the previous section: here you can set which keyword groups are case sensitive.
+
+As of GeSHi version 1.0.7.21 the symbols section is used in two ways:
+
+    * Flat usage:
+      This mode is the suggested way for existing language files and languages that only need few symbols where no further differentiation is needed or desired. You simply put all the characters in an array under symbols as shown in the first example below. All symbols in flat usage belong to symbol style group 0.
+    * Group usage:
+      This is a slightly more enhanced way to provide GeSHi symbol information. To use group you create several subarrays each containing only a subset of the symbols to highlight. Every array will need to have an unique index thus you can assign the appropriate styles later.
+
+Here's an example for flat symbol usage
+
+       'SYMBOLS' => array(
+               '(', ')', '[', ']', '{', '}', '!', '@', '|', '&', '+', '-', '*', '/', '%', '=', '<', '>'
+               ),
+       'CASE_SENSITIVE' => array(
+               GESHI_COMMENTS => false,
+               1 => false,
+               2 => false,
+               3 => false,
+               ),
+
+which is not too different from the newly introduced group usage shown below:
+
+       'SYMBOLS' => array(
+               0 => array('(', ')', '[', ']', '{', '}'),
+               1 => array('!', '@', '|', '&'),
+               2 => array('+', '-', '*', '/', '%'),
+               3 => array('=', '<', '>')
+               ),
+       'CASE_SENSITIVE' => array(
+               GESHI_COMMENTS => false,
+               1 => false,
+               2 => false,
+               3 => false,
+               ),
+
+    * 'SYMBOLS': An array of the symbols, or - as of 1.0.7.21 - an array of symbol groups, used in your language. Please note that versions before 1.0.7.21 will silently ignore this setting.
+    * 'CASE_SENSITIVE': Note the GESHI_COMMENTS! This is used to set whether comments are case sensitive or not (for example, BASIC has the REM statement which while not being case sensitive is still alphanumeric, and as in the example given before about the Java language file using "import" as a single line comment, this can be useful sometimes. true if comments are case sensitive, false otherwise. All of the other indices correspond to indices in the 'KEYWORDS' section (see above).
+
+4.3.5: Styles for your Language File
+Top | Contents | Next | Previous
+
+This is the fun part! Here you get to choose the colours, fonts, backgrounds and anything else you'd like for your language file.
+
+Here's an example:
+
+       'STYLES' => array(
+               'KEYWORDS' => array(
+                       1 => 'color: #b1b100;',
+                       2 => 'color: #000000; font-weight: bold;',
+                       3 => 'color: #000066;'
+                       ),
+               'COMMENTS' => array(
+                       1 => 'color: #808080; font-style: italic;',
+                       2 => 'color: #808080; font-style: italic;',
+                       'MULTI' => 'color: #808080; font-style: italic;'
+                       ),
+               'ESCAPE_CHAR' => array(
+                       0 => 'color: #000099; font-weight: bold;'
+                       ),
+               'BRACKETS' => array(
+                       0 => 'color: #66cc66;'
+                       ),
+               'STRINGS' => array(
+                       0 => 'color: #ff0000;'
+                       ),
+               'NUMBERS' => array(
+                       0 => 'color: #cc66cc;'
+                       ),
+               'METHODS' => array(
+                       0 => 'color: #006600;'
+                       ),
+               'SYMBOLS' => array(
+                       0 => 'color: #66cc66;'
+                       ),
+               'REGEXPS' => array(
+                       0 => 'color: #0000ff;'
+                       ),
+               'SCRIPT' => array(
+                       0 => '',
+                       1 => '',
+                       2 => '',
+                       3 => ''
+                       )
+               ),
+
+Note that all style rules should end with a semi-colon! This is important: GeSHi may add extra rules to the rules you specify (and will do so if a user tries to change your styles on the fly), so the last semi-colon in any stylesheet rule is important.
+
+All strings here should contain valid stylesheet declarations (it's also find to have the empty string).
+
+    * 'KEYWORDS': This is an array, from keyword index to style. The index you use is the index you used in the keywords section to specify the keywords belonging to that group.
+    * 'COMMENTS': This is an array, from single-line comment index to style for that index. The index 'MULTI' is used for multiline comments (and cannot be an array)
+    * 'ESCAPE_CHAR' down to 'SYMBOLS': These are arrays with only one index: 0. You cannot add other indices to these arrays.
+    * 'REGEXPS':This is an array with a style for each matching regex. Also, since 1.0.7.21, you can specify the name of a function to be called, that will be given the text matched by the regex, each time a match is found. Note that my testing found that create_function would not work with this due to a PHP bug, so you have to put the function definition at the top of the language file. Be sure to prefix the function name with geshi_[languagename]_ as to not conflict with other functions!
+    * 'SCRIPT': For languages that use script delimiters, this is where you can style each block of script. For example, HTML and XML have blocks that begin with < and end with > (i.e. tags) and blocks that begin with & and end with ; (i.e. character entities), and you can set a style to apply to each whole block. You specify the delimiters for the blocks below. Note that many languages will not need this feature.
+
+4.3.6: URLs for Functions
+Top | Contents | Next | Previous
+
+This section lets you specify a url to visit for each keyword group. Useful for pointing functions at their online manual entries.
+
+Here is an example:
+
+       'URLS' => array(
+               1 => '',
+               2 => '',
+               3 => 'http://www.php.net/{FNAME}',
+               4 => ''
+               ),
+
+The indices of this array correspond to the keyword groups you specified in the keywords section. The string {FNAME} marks where the name of the function is substituted in. So for the example above, if the keyword being highlighted is "echo", then the keyword will be a URL pointing to http://www.php.net/echo. Because some languages (Java!) don't keep a uniform URL for functions/classes, you may have trouble in creating a URL for that language (though look in the java language file for a novel solution to it's problem)
+4.3.7: Object Orientation Support
+Top | Contents | Next | Previous
+
+Now we're reaching the most little-used section of a language file, which includes such goodies as object orientation support and context support. GeSHi can highlight methods and data fields of objects easily, all you need to do is to tell it to do so and what the "splitter" is between object/method etc.
+
+Here's an example:
+
+       'OOLANG' => true,
+       'OBJECT_SPLITTER' => '->',
+
+If your language has object orientation, the value of 'OOLANG' is true, otherwise it is false. If it is object orientated, in the 'OBJECT_SPLITTER' value you put the htmlentities() version of the "splitter" between objects and methods/fields. If it is not, then make this the empty string.
+4.3.8: Using Regular Expressions
+Top | Contents | Next | Previous
+
+Regular expressions are a good way to catch any other lexic that fits certain rules but can't be listed as a keyword. A good example is variables in PHP: variables always start with either one or two "$" signs, then alphanumeric characters (a simplification). This is easy to catch with regular expressions.
+
+And new to version 1.0.2, there is an advanced way of using regular expressions to catch certain things but highlight only part of those things. This is particularly useful for languages like XML.
+Caution:
+
+Regular expressions use the PCRE syntax (perl-style), not the ereg() style!
+
+Here is an example (this time the PHP file merged with the XML file):
+
+               0 => array(
+                       GESHI_SEARCH => '(((xml:)?[a-z\-]+))(=)',
+                       GESHI_REPLACE => '\\1',
+                       GESHI_MODIFIERS => '',
+                       GESHI_BEFORE => '',
+                       GESHI_AFTER => '\\4'
+                       ),
+               1 => array(
+                       GESHI_SEARCH => '(>/?[a-z0-9]*(>)?)',
+                       GESHI_REPLACE => '\\1',
+                       GESHI_MODIFIERS => '',
+                       GESHI_BEFORE => '',
+                       GESHI_AFTER => ''
+                       ),
+               2 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+
+As you can see there are two formats. One is the "simple" format used in GeSHi < 1.0.2, and the other is a more advanced syntax. Firstly, the simple syntax:
+
+    * May be in double quotes: To make it easier for those who always place their regular expressions in double quotes, you may place any regular expression here in double quotes if you wish.
+    * Don't use curly brackets where possible: If you want to use curly brackets (()) then by all means give it a try, but I'm not sure whether under some circumstances GeSHi may throw a wobbly. You have been warned! If you want to use brackets, it would be better to use the advanced syntax.
+    * Don't use the "everything" regex: (That's the .*? regex). Use advanced syntax instead.
+
+And now for advanced syntax, which gives you much more control over exactly what is highlighted:
+
+    * GESHI_SEARCH: This element specifies the regular expression to search for. If you plan to capture the output, use brackets (()). See how in the first example above, most of the regular expression is in one set of brackets (with the equals sign in other brackets). You should make sure that the part of the regular expression that is supposed to match what is highlighted is in brackets.
+    * GESHI_REPLACE: This is what the stuff matched by the regular expression will be replaced with. If you've grouped the stuff you want highlighted into brackets in the GESHI_SEARCH element, then you can use \\number to match that group, where number is a number corresponding to how many open brackets are between the open bracket of the group you want highlighted and the start of the GESHI_SEARCH string + 1. This may sound confusing, and it probably is, but if you're familiar with how PHP's regular expressions work you should understand. In the example above, the opening bracket for the stuff we want highlighted is the very first bracket in the string, so the number of brackets before that bracket and the start of the string is 0. So we add 1 and get our replacement string of \\1 (whew!).
+
+      If you didn't understand a word of that, make sure that there are brackets around the string in GESHI_SEARCH and use \\1 for GESHI_REPLACE ;)
+    * GESHI_MODIFIERS: Specify modifiers for your regular expression. If your regular expression includes the everything matcher (.*?), then your modifiers should include "s" and "i" (e.g. use 'si' for this).
+    * GESHI_BEFORE:Specifies a bracket group that should appear before the highlighted match (this bracketed group will not be highlighted). Use this if you had to match what you wanted by matching part of your regexp string to something before what you wanted to highlight, and you don't want that part to disappear in the highlighted result.
+    * GESHI_AFTER:Specifies a bracket group that should appear after the highlighted match (this bracketed group will not be highlighted). Use this if you had to match what you wanted by matching part of your regexp string to something after what you wanted to highlight, and you don't want that part to disappear in the highlighted result.
+
+Is that totally confusing? Here's the test for if you're an android or not: If you found that perfectly understandable then you're an android ;). Here's a better example:
+
+Let's say that I'm making a language, and variables in this language always start with a dollar sign ($), are always written in lowercase letters and always end with an ampersand (&). eg:
+$foo& = 'bar'
+
+I want to highlight only the text between the $ and the &. How do I do that? With simple regular expressions I can't, but with advanced, it's relatively easy:
+
+               1 => array(
+                       GESHI_SEARCH => '(\$)([a-z]+)(&)',   // search for a dollar sign, then one or more of the characters a-z, then an ampersand
+                       GESHI_REPLACE => '\\2',                  // we wanna highlight the characters, which are in the second bracketed group
+                       GESHI_MODIFIERS => '',                   // no modifiers, since we're not matching the "anything" regex
+                       GESHI_BEFORE => '\\1',                   // before the highlighted characters should be the first bracketed group (always a dollar sign in this example)
+                       GESHI_AFTER => '\\3'                     // after the highlighted characters should be the third bracketed group (always an ampersand in this example)
+                       ),
+
+So if someone tried to highlight using my language, all cases of $foo& would turn into:
+$<span style="color: blue;">foo</span>&
+
+(which would of course be viewed in a browser to get something like $foo&)
+4.3.9: Contextual Highlighting and Strict Mode
+Top | Contents | Next | Previous
+
+For languages like HTML, it's good if we can highlight a tag (like <a> for example). But how do we stop every single "a" in the source getting highlighted? What about for attributes? If I've got the word "colspan" in my text I don't want that highlighted! So how do you tell GeSHi not to highlight in that case? You do it with "Strict Blocks".
+
+Here is an example:
+
+       'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+       'SCRIPT_DELIMITERS' => array(
+               0 => array(
+                       '<?php' => '?>'
+                       ),
+               1 => array(
+                       '<?' => '?>'
+                       ),
+               2 => array(
+                       '<%' => '%>'
+                       ),
+               3 => array(
+                       '<script language="php">' => '</script>'
+                       )
+               ),
+       'HIGHLIGHT_STRICT_BLOCK' => array(
+               0 => true,
+               1 => true,
+               2 => true,
+               3 => true
+               )
+
+What is strict mode? Strict mode says that highlighting only occurs inside the blocks you specify. You can see from the example above that highlighting will only occur if the source is inside <?php ... ?> (though note the GESHI_MAYBE!). Here are some points about strict highlighting:
+
+    * 'STRICT_MODE_APPLIES': This takes three values (all constants):
+          o GESHI_ALWAYS: Strict mode always applies for all of the blocks you specify. Users of your language file cannot turn strict mode off. This should be used for markup languages.
+          o GESHI_NEVER: Strict mode is never used. Users of your language file cannot turn strict mode on. Use this value if there is no such thing as a block of code that would not be highlighted in your language (most languages, like C, Java etc. use this because anything in a C file should be highlighted).
+          o GESHI_MAYBE: Strict mode *sometimes* applies. It defaults to "off". Users can turn strict mode on if they please. If strict mode is off then everything in the source will be highlighted, even things outside the strict block markers. If strict mode is on the nothing outside strict block markers will be highlighted.
+    * SCRIPT_DELIMITERS: This is an array of script delimiters, in the format of the above. The indices are use in the 'SCRIPT' part of the styles section for highlighting everything in a strict block in a certain way. For example, you could set up your language file to make the background yellow of any code inside a strict block this way. The delimiters are in the form 'OPEN' => 'CLOSE'. Delimiters can be of any length > 0. Delimiters are not formatted as if they were run through htmlentities()!
+    * 'HIGHLIGHT_STRICT_BLOCK': specifies whether any highlighting should go on inside each block. Most of the time this should be true, but for example, in the XML language file highlighting is turned off for blocks beginning with <!DOCTYPE and ending with >. However, you can still style the overall block using the method described above, and the XML language file does just that.
+
+Note:
+
+The delimiters should be in reverse alphabetical order. Note that in the above example, <?php comes before <?.
+4.3.10: Tidying Up
+Top | Contents | Next | Previous
+
+All language files should end with:
+
+);
+
+?>
+
+5: Method/Constant Reference
+Top | Contents | Next | Previous
+
+I'm afraid I have been lying for a little while about this now! Since 1.0.7 I have been including a phpdoc API for the sourcecode in the api directory, but have forgot to update the documentation! However, it is available, and may assist you in coding, especially for plugin coders.
+
+That's all, folks!
+
+I've improved the documentation greatly from version 1.0.1, but there may still be problems with it, or it may still be confusing for you. Or perhaps I was just plain wrong about one point! If so, contact me and I'll do my best to sort it out.
+
+In case you were wondering, I've finished development of the 1.0.X thread of GeSHi. The only releases I'll make in this thread will be of the bug-fix/add language files type. In particular, version 1.0.2 was a "concept" release - testing how far I could take the highlighting idea (as well as ideas from others).
+
+I'm planning a code rewrite for 1.2.X, which will be based on a new engine - a "psuedo-tokenizer" engine. Hopefully it will massively reduce the server load and time taken (by almost eliminating regexps), while providing superior highlighting. But fear not! The interface and method names should all remain the same ^_^ (though I can't say the same for language files!)
+
+And finally, a couple of people have been asking me: how did you generate that documentation? The amazing answer is: my brain. And yes, it took a long time, and I don't reccommend doing it this way. And yes, you can borrow the styles if you like, though flick me an e-mail if you do.
+
+Anyway, enough blather from me. Get GeSHi working for you already! :D
+
+Nigel McNie
+nigel@geshi.org
+http://qbnz.com/highlighter/
diff --git a/examples/includes/geshi/docs/phpdoc.ini b/examples/includes/geshi/docs/phpdoc.ini
new file mode 100644 (file)
index 0000000..a55bc33
--- /dev/null
@@ -0,0 +1,90 @@
+;; phpDocumentor parse configuration file
+;;
+;; This file is designed to cut down on repetitive typing on the command-line or web interface
+;; You can copy this file to create a number of configuration files that can be used with the
+;; command-line switch -c, as in phpdoc -c default.ini or phpdoc -c myini.ini.  The web
+;; interface will automatically generate a list of .ini files that can be used.
+;;
+;; default.ini is used to generate the online manual at http://www.phpdoc.org/docs
+;;
+;; ALL .ini files must be in the user subdirectory of phpDocumentor with an extension of .ini
+;;
+;; Copyright 2002, Greg Beaver <cellog@users.sourceforge.net>
+;;
+;; WARNING: do not change the name of any command-line parameters, phpDocumentor will ignore them
+
+[Parse Data]
+;; title of all the documentation
+;; legal values: any string
+title = GeSHi 1.0.8
+
+;; parse files that start with a . like .bash_profile
+;; legal values: true, false
+hidden = false
+
+;; show elements marked @access private in documentation by setting this to on
+;; legal values: on, off
+parseprivate = off
+
+;; parse with javadoc-like description (first sentence is always the short description)
+;; legal values: on, off
+javadocdesc = off
+
+;; add any custom @tags separated by commas here
+;; legal values: any legal tagname separated by commas.
+customtags = note
+
+;; This is only used by the XML:DocBook/peardoc2 converter
+defaultcategoryname = Documentation
+
+;; what is the main package?
+;; legal values: alphanumeric string plus - and _
+defaultpackagename = core
+
+;; output any parsing information?  set to on for cron jobs
+;; legal values: on
+;quiet = on
+
+;; parse a PEAR-style repository.  Do not turn this on if your project does
+;; not have a parent directory named "pear"
+;; legal values: on/off
+;pear = on
+
+;; where should the documentation be written?
+;; legal values: a legal path
+target = api
+
+;; limit output to the specified packages, even if others are parsed
+;; legal values: package names separated by commas
+;packageoutput = package1,package2
+
+;; comma-separated list of files to parse
+;; legal values: paths separated by commas
+filename = ../geshi.php
+
+;; comma-separated list of directories to parse
+;; legal values: directory paths separated by commas
+;directory = /path1,/path2,.,..,subdirectory
+;directory = /home/jeichorn/cvs/pear
+;directory = geshi
+
+;; template base directory (the equivalent directory of <installdir>/phpDocumentor)
+;templatebase = /path/to/my/templates
+
+;; comma-separated list of files, directories or wildcards ? and * (any wildcard) to ignore
+;; legal values: any wildcard strings separated by commas
+;ignore = /path/to/ignore*,*list.php,myfile.php,subdirectory/
+ignore = /*.svn/*
+
+;; comma-separated list of Converters to use in outputformat:Convertername:templatedirectory format
+;; legal values: HTML:frames:default,HTML:frames:l0l33t,HTML:frames:phpdoc.de,HTML:frames:phphtmllib,
+;;               HTML:frames:earthli,
+;;               HTML:frames:DOM/default,HTML:frames:DOM/l0l33t,HTML:frames:DOM/phpdoc.de,
+;;               HTML:frames:DOM/phphtmllib,HTML:frames:DOM/earthli
+;;               HTML:Smarty:default,HTML:Smarty:PHP,HTML:Smarty:HandS
+;;               PDF:default:default,CHM:default:default,XML:DocBook/peardoc2:default
+output=HTML:frames:earthli
+
+;; turn this option on if you want highlighted source code for every file
+;; legal values: on/off
+sourcecode = on
diff --git a/examples/includes/geshi/geshi.php b/examples/includes/geshi/geshi.php
new file mode 100644 (file)
index 0000000..8cf1f9a
--- /dev/null
@@ -0,0 +1,4619 @@
+<?php
+/**
+ * GeSHi - Generic Syntax Highlighter
+ *
+ * The GeSHi class for Generic Syntax Highlighting. Please refer to the
+ * documentation at http://qbnz.com/highlighter/documentation.php for more
+ * information about how to use this class.
+ *
+ * For changes, release notes, TODOs etc, see the relevant files in the docs/
+ * directory.
+ *
+ *   This file is part of GeSHi.
+ *
+ *  GeSHi is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GeSHi is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GeSHi; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @package    geshi
+ * @subpackage core
+ * @author     Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
+ * @copyright  (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
+ * @license    http://gnu.org/copyleft/gpl.html GNU GPL
+ *
+ */
+
+//
+// GeSHi Constants
+// You should use these constant names in your programs instead of
+// their values - you never know when a value may change in a future
+// version
+//
+
+/** The version of this GeSHi file */
+define('GESHI_VERSION', '1.0.8.3');
+
+// Define the root directory for the GeSHi code tree
+if (!defined('GESHI_ROOT')) {
+    /** The root directory for GeSHi */
+    define('GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+/** The language file directory for GeSHi
+    @access private */
+define('GESHI_LANG_ROOT', GESHI_ROOT . 'geshi' . DIRECTORY_SEPARATOR);
+
+// Define if GeSHi should be paranoid about security
+if (!defined('GESHI_SECURITY_PARANOID')) {
+    /** Tells GeSHi to be paranoid about security settings */
+    define('GESHI_SECURITY_PARANOID', false);
+}
+
+// Line numbers - use with enable_line_numbers()
+/** Use no line numbers when building the result */
+define('GESHI_NO_LINE_NUMBERS', 0);
+/** Use normal line numbers when building the result */
+define('GESHI_NORMAL_LINE_NUMBERS', 1);
+/** Use fancy line numbers when building the result */
+define('GESHI_FANCY_LINE_NUMBERS', 2);
+
+// Container HTML type
+/** Use nothing to surround the source */
+define('GESHI_HEADER_NONE', 0);
+/** Use a "div" to surround the source */
+define('GESHI_HEADER_DIV', 1);
+/** Use a "pre" to surround the source */
+define('GESHI_HEADER_PRE', 2);
+/** Use a pre to wrap lines when line numbers are enabled or to wrap the whole code. */
+define('GESHI_HEADER_PRE_VALID', 3);
+/**
+ * Use a "table" to surround the source:
+ *
+ *  <table>
+ *    <thead><tr><td colspan="2">$header</td></tr></thead>
+ *    <tbody><tr><td><pre>$linenumbers</pre></td><td><pre>$code></pre></td></tr></tbody>
+ *    <tfooter><tr><td colspan="2">$footer</td></tr></tfoot>
+ *  </table>
+ *
+ * this is essentially only a workaround for Firefox, see sf#1651996 or take a look at
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=365805
+ * @note when linenumbers are disabled this is essentially the same as GESHI_HEADER_PRE
+ */
+define('GESHI_HEADER_PRE_TABLE', 4);
+
+// Capatalisation constants
+/** Lowercase keywords found */
+define('GESHI_CAPS_NO_CHANGE', 0);
+/** Uppercase keywords found */
+define('GESHI_CAPS_UPPER', 1);
+/** Leave keywords found as the case that they are */
+define('GESHI_CAPS_LOWER', 2);
+
+// Link style constants
+/** Links in the source in the :link state */
+define('GESHI_LINK', 0);
+/** Links in the source in the :hover state */
+define('GESHI_HOVER', 1);
+/** Links in the source in the :active state */
+define('GESHI_ACTIVE', 2);
+/** Links in the source in the :visited state */
+define('GESHI_VISITED', 3);
+
+// Important string starter/finisher
+// Note that if you change these, they should be as-is: i.e., don't
+// write them as if they had been run through htmlentities()
+/** The starter for important parts of the source */
+define('GESHI_START_IMPORTANT', '<BEGIN GeSHi>');
+/** The ender for important parts of the source */
+define('GESHI_END_IMPORTANT', '<END GeSHi>');
+
+/**#@+
+ *  @access private
+ */
+// When strict mode applies for a language
+/** Strict mode never applies (this is the most common) */
+define('GESHI_NEVER', 0);
+/** Strict mode *might* apply, and can be enabled or
+    disabled by {@link GeSHi->enable_strict_mode()} */
+define('GESHI_MAYBE', 1);
+/** Strict mode always applies */
+define('GESHI_ALWAYS', 2);
+
+// Advanced regexp handling constants, used in language files
+/** The key of the regex array defining what to search for */
+define('GESHI_SEARCH', 0);
+/** The key of the regex array defining what bracket group in a
+    matched search to use as a replacement */
+define('GESHI_REPLACE', 1);
+/** The key of the regex array defining any modifiers to the regular expression */
+define('GESHI_MODIFIERS', 2);
+/** The key of the regex array defining what bracket group in a
+    matched search to put before the replacement */
+define('GESHI_BEFORE', 3);
+/** The key of the regex array defining what bracket group in a
+    matched search to put after the replacement */
+define('GESHI_AFTER', 4);
+/** The key of the regex array defining a custom keyword to use
+    for this regexp's html tag class */
+define('GESHI_CLASS', 5);
+
+/** Used in language files to mark comments */
+define('GESHI_COMMENTS', 0);
+
+/** Used to work around missing PHP features **/
+define('GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION, '4.3.3') === 1));
+
+/** make sure we can call stripos **/
+if (!function_exists('stripos')) {
+    // the offset param of preg_match is not supported below PHP 4.3.3
+    if (GESHI_PHP_PRE_433) {
+        /**
+         * @ignore
+         */
+        function stripos($haystack, $needle, $offset = null) {
+            if (!is_null($offset)) {
+                $haystack = substr($haystack, $offset);
+            }
+            if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE)) {
+                return $match[0][1];
+            }
+            return false;
+        }
+    }
+    else {
+        /**
+         * @ignore
+         */
+        function stripos($haystack, $needle, $offset = null) {
+            if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE, $offset)) {
+                return $match[0][1];
+            }
+            return false;
+        }
+    }
+}
+
+/** some old PHP / PCRE subpatterns only support up to xxx subpatterns in
+    regular expressions. Set this to false if your PCRE lib is up to date
+    @see GeSHi->optimize_regexp_list()
+    **/
+define('GESHI_MAX_PCRE_SUBPATTERNS', 500);
+/** it's also important not to generate too long regular expressions
+    be generous here... but keep in mind, that when reaching this limit we
+    still have to close open patterns. 12k should do just fine on a 16k limit.
+    @see GeSHi->optimize_regexp_list()
+    **/
+define('GESHI_MAX_PCRE_LENGTH', 12288);
+
+//Number format specification
+/** Basic number format for integers */
+define('GESHI_NUMBER_INT_BASIC', 1);        //Default integers \d+
+/** Enhanced number format for integers like seen in C */
+define('GESHI_NUMBER_INT_CSTYLE', 2);       //Default C-Style \d+[lL]?
+/** Number format to highlight binary numbers with a suffix "b" */
+define('GESHI_NUMBER_BIN_SUFFIX', 16);           //[01]+[bB]
+/** Number format to highlight binary numbers with a prefix % */
+define('GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);   //%[01]+
+/** Number format to highlight binary numbers with a prefix 0b (C) */
+define('GESHI_NUMBER_BIN_PREFIX_0B', 64);        //0b[01]+
+/** Number format to highlight octal numbers with a leading zero */
+define('GESHI_NUMBER_OCT_PREFIX', 256);           //0[0-7]+
+/** Number format to highlight octal numbers with a suffix of o */
+define('GESHI_NUMBER_OCT_SUFFIX', 512);           //[0-7]+[oO]
+/** Number format to highlight hex numbers with a prefix 0x */
+define('GESHI_NUMBER_HEX_PREFIX', 4096);           //0x[0-9a-fA-F]+
+/** Number format to highlight hex numbers with a suffix of h */
+define('GESHI_NUMBER_HEX_SUFFIX', 8192);           //[0-9][0-9a-fA-F]*h
+/** Number format to highlight floating-point numbers without support for scientific notation */
+define('GESHI_NUMBER_FLT_NONSCI', 65536);          //\d+\.\d+
+/** Number format to highlight floating-point numbers without support for scientific notation */
+define('GESHI_NUMBER_FLT_NONSCI_F', 131072);       //\d+(\.\d+)?f
+/** Number format to highlight floating-point numbers with support for scientific notation (E) and optional leading zero */
+define('GESHI_NUMBER_FLT_SCI_SHORT', 262144);      //\.\d+e\d+
+/** Number format to highlight floating-point numbers with support for scientific notation (E) and required leading digit */
+define('GESHI_NUMBER_FLT_SCI_ZERO', 524288);       //\d+(\.\d+)?e\d+
+//Custom formats are passed by RX array
+
+// Error detection - use these to analyse faults
+/** No sourcecode to highlight was specified
+ * @deprecated
+ */
+define('GESHI_ERROR_NO_INPUT', 1);
+/** The language specified does not exist */
+define('GESHI_ERROR_NO_SUCH_LANG', 2);
+/** GeSHi could not open a file for reading (generally a language file) */
+define('GESHI_ERROR_FILE_NOT_READABLE', 3);
+/** The header type passed to {@link GeSHi->set_header_type()} was invalid */
+define('GESHI_ERROR_INVALID_HEADER_TYPE', 4);
+/** The line number type passed to {@link GeSHi->enable_line_numbers()} was invalid */
+define('GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
+/**#@-*/
+
+
+/**
+ * The GeSHi Class.
+ *
+ * Please refer to the documentation for GeSHi 1.0.X that is available
+ * at http://qbnz.com/highlighter/documentation.php for more information
+ * about how to use this class.
+ *
+ * @package   geshi
+ * @author    Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
+ * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
+ */
+class GeSHi {
+    /**#@+
+     * @access private
+     */
+    /**
+     * The source code to highlight
+     * @var string
+     */
+    var $source = '';
+
+    /**
+     * The language to use when highlighting
+     * @var string
+     */
+    var $language = '';
+
+    /**
+     * The data for the language used
+     * @var array
+     */
+    var $language_data = array();
+
+    /**
+     * The path to the language files
+     * @var string
+     */
+    var $language_path = GESHI_LANG_ROOT;
+
+    /**
+     * The error message associated with an error
+     * @var string
+     * @todo check err reporting works
+     */
+    var $error = false;
+
+    /**
+     * Possible error messages
+     * @var array
+     */
+    var $error_messages = array(
+        GESHI_ERROR_NO_SUCH_LANG => 'GeSHi could not find the language {LANGUAGE} (using path {PATH})',
+        GESHI_ERROR_FILE_NOT_READABLE => 'The file specified for load_from_file was not readable',
+        GESHI_ERROR_INVALID_HEADER_TYPE => 'The header type specified is invalid',
+        GESHI_ERROR_INVALID_LINE_NUMBER_TYPE => 'The line number type specified is invalid'
+    );
+
+    /**
+     * Whether highlighting is strict or not
+     * @var boolean
+     */
+    var $strict_mode = false;
+
+    /**
+     * Whether to use CSS classes in output
+     * @var boolean
+     */
+    var $use_classes = false;
+
+    /**
+     * The type of header to use. Can be one of the following
+     * values:
+     *
+     * - GESHI_HEADER_PRE: Source is outputted in a "pre" HTML element.
+     * - GESHI_HEADER_DIV: Source is outputted in a "div" HTML element.
+     * - GESHI_HEADER_NONE: No header is outputted.
+     *
+     * @var int
+     */
+    var $header_type = GESHI_HEADER_PRE;
+
+    /**
+     * Array of permissions for which lexics should be highlighted
+     * @var array
+     */
+    var $lexic_permissions = array(
+        'KEYWORDS' =>    array(),
+        'COMMENTS' =>    array('MULTI' => true),
+        'REGEXPS' =>     array(),
+        'ESCAPE_CHAR' => true,
+        'BRACKETS' =>    true,
+        'SYMBOLS' =>     false,
+        'STRINGS' =>     true,
+        'NUMBERS' =>     true,
+        'METHODS' =>     true,
+        'SCRIPT' =>      true
+    );
+
+    /**
+     * The time it took to parse the code
+     * @var double
+     */
+    var $time = 0;
+
+    /**
+     * The content of the header block
+     * @var string
+     */
+    var $header_content = '';
+
+    /**
+     * The content of the footer block
+     * @var string
+     */
+    var $footer_content = '';
+
+    /**
+     * The style of the header block
+     * @var string
+     */
+    var $header_content_style = '';
+
+    /**
+     * The style of the footer block
+     * @var string
+     */
+    var $footer_content_style = '';
+
+    /**
+     * Tells if a block around the highlighted source should be forced
+     * if not using line numbering
+     * @var boolean
+     */
+    var $force_code_block = false;
+
+    /**
+     * The styles for hyperlinks in the code
+     * @var array
+     */
+    var $link_styles = array();
+
+    /**
+     * Whether important blocks should be recognised or not
+     * @var boolean
+     * @deprecated
+     * @todo REMOVE THIS FUNCTIONALITY!
+     */
+    var $enable_important_blocks = false;
+
+    /**
+     * Styles for important parts of the code
+     * @var string
+     * @deprecated
+     * @todo As above - rethink the whole idea of important blocks as it is buggy and
+     * will be hard to implement in 1.2
+     */
+    var $important_styles = 'font-weight: bold; color: red;'; // Styles for important parts of the code
+
+    /**
+     * Whether CSS IDs should be added to the code
+     * @var boolean
+     */
+    var $add_ids = false;
+
+    /**
+     * Lines that should be highlighted extra
+     * @var array
+     */
+    var $highlight_extra_lines = array();
+
+    /**
+     * Styles of lines that should be highlighted extra
+     * @var array
+     */
+    var $highlight_extra_lines_styles = array();
+
+    /**
+     * Styles of extra-highlighted lines
+     * @var string
+     */
+    var $highlight_extra_lines_style = 'background-color: #ffc;';
+
+    /**
+     * The line ending
+     * If null, nl2br() will be used on the result string.
+     * Otherwise, all instances of \n will be replaced with $line_ending
+     * @var string
+     */
+    var $line_ending = null;
+
+    /**
+     * Number at which line numbers should start at
+     * @var int
+     */
+    var $line_numbers_start = 1;
+
+    /**
+     * The overall style for this code block
+     * @var string
+     */
+    var $overall_style = 'font-family:monospace;';
+
+    /**
+     *  The style for the actual code
+     * @var string
+     */
+    var $code_style = 'font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;';
+
+    /**
+     * The overall class for this code block
+     * @var string
+     */
+    var $overall_class = '';
+
+    /**
+     * The overall ID for this code block
+     * @var string
+     */
+    var $overall_id = '';
+
+    /**
+     * Line number styles
+     * @var string
+     */
+    var $line_style1 = 'font-weight: normal; vertical-align:top;';
+
+    /**
+     * Line number styles for fancy lines
+     * @var string
+     */
+    var $line_style2 = 'font-weight: bold; vertical-align:top;';
+
+    /**
+     * Style for line numbers when GESHI_HEADER_PRE_TABLE is chosen
+     * @var string
+     */
+    var $table_linenumber_style = 'width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;';
+
+    /**
+     * Flag for how line numbers are displayed
+     * @var boolean
+     */
+    var $line_numbers = GESHI_NO_LINE_NUMBERS;
+
+    /**
+     * Flag to decide if multi line spans are allowed. Set it to false to make sure
+     * each tag is closed before and reopened after each linefeed.
+     * @var boolean
+     */
+    var $allow_multiline_span = true;
+
+    /**
+     * The "nth" value for fancy line highlighting
+     * @var int
+     */
+    var $line_nth_row = 0;
+
+    /**
+     * The size of tab stops
+     * @var int
+     */
+    var $tab_width = 8;
+
+    /**
+     * Should we use language-defined tab stop widths?
+     * @var int
+     */
+    var $use_language_tab_width = false;
+
+    /**
+     * Default target for keyword links
+     * @var string
+     */
+    var $link_target = '';
+
+    /**
+     * The encoding to use for entity encoding
+     * NOTE: Used with Escape Char Sequences to fix UTF-8 handling (cf. SF#2037598)
+     * @var string
+     */
+    var $encoding = 'utf-8';
+
+    /**
+     * Should keywords be linked?
+     * @var boolean
+     */
+    var $keyword_links = true;
+
+    /**
+     * Currently loaded language file
+     * @var string
+     * @since 1.0.7.22
+     */
+    var $loaded_language = '';
+
+    /**
+     * Wether the caches needed for parsing are built or not
+     *
+     * @var bool
+     * @since 1.0.8
+     */
+    var $parse_cache_built = false;
+
+    /**
+     * Work around for Suhosin Patch with disabled /e modifier
+     *
+     * Note from suhosins author in config file:
+     * <blockquote>
+     *   The /e modifier inside <code>preg_replace()</code> allows code execution.
+     *   Often it is the cause for remote code execution exploits. It is wise to
+     *   deactivate this feature and test where in the application it is used.
+     *   The developer using the /e modifier should be made aware that he should
+     *   use <code>preg_replace_callback()</code> instead
+     * </blockquote>
+     *
+     * @var array
+     * @since 1.0.8
+     */
+    var $_kw_replace_group = 0;
+    var $_rx_key = 0;
+
+    /**
+     * some "callback parameters" for handle_multiline_regexps
+     *
+     * @since 1.0.8
+     * @access private
+     * @var string
+     */
+    var $_hmr_before = '';
+    var $_hmr_replace = '';
+    var $_hmr_after = '';
+    var $_hmr_key = 0;
+
+    /**#@-*/
+
+    /**
+     * Creates a new GeSHi object, with source and language
+     *
+     * @param string The source code to highlight
+     * @param string The language to highlight the source with
+     * @param string The path to the language file directory. <b>This
+     *               is deprecated!</b> I've backported the auto path
+     *               detection from the 1.1.X dev branch, so now it
+     *               should be automatically set correctly. If you have
+     *               renamed the language directory however, you will
+     *               still need to set the path using this parameter or
+     *               {@link GeSHi->set_language_path()}
+     * @since 1.0.0
+     */
+    function GeSHi($source = '', $language = '', $path = '') {
+        if (!empty($source)) {
+            $this->set_source($source);
+        }
+        if (!empty($language)) {
+            $this->set_language($language);
+        }
+        $this->set_language_path($path);
+    }
+
+    /**
+     * Returns an error message associated with the last GeSHi operation,
+     * or false if no error has occured
+     *
+     * @return string|false An error message if there has been an error, else false
+     * @since  1.0.0
+     */
+    function error() {
+        if ($this->error) {
+            //Put some template variables for debugging here ...
+            $debug_tpl_vars = array(
+                '{LANGUAGE}' => $this->language,
+                '{PATH}' => $this->language_path
+            );
+            $msg = str_replace(
+                array_keys($debug_tpl_vars),
+                array_values($debug_tpl_vars),
+                $this->error_messages[$this->error]);
+
+            return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
+        }
+        return false;
+    }
+
+    /**
+     * Gets a human-readable language name (thanks to Simon Patterson
+     * for the idea :))
+     *
+     * @return string The name for the current language
+     * @since  1.0.2
+     */
+    function get_language_name() {
+        if (GESHI_ERROR_NO_SUCH_LANG == $this->error) {
+            return $this->language_data['LANG_NAME'] . ' (Unknown Language)';
+        }
+        return $this->language_data['LANG_NAME'];
+    }
+
+    /**
+     * Sets the source code for this object
+     *
+     * @param string The source code to highlight
+     * @since 1.0.0
+     */
+    function set_source($source) {
+        $this->source = $source;
+        $this->highlight_extra_lines = array();
+    }
+
+    /**
+     * Sets the language for this object
+     *
+     * @note since 1.0.8 this function won't reset language-settings by default anymore!
+     *       if you need this set $force_reset = true
+     *
+     * @param string The name of the language to use
+     * @since 1.0.0
+     */
+    function set_language($language, $force_reset = false) {
+        if ($force_reset) {
+            $this->loaded_language = false;
+        }
+
+        //Clean up the language name to prevent malicious code injection
+        $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
+
+        $language = strtolower($language);
+
+        //Retreive the full filename
+        $file_name = $this->language_path . $language . '.php';
+        if ($file_name == $this->loaded_language) {
+            // this language is already loaded!
+            return;
+        }
+
+        $this->language = $language;
+
+        $this->error = false;
+        $this->strict_mode = GESHI_NEVER;
+
+        //Check if we can read the desired file
+        if (!is_readable($file_name)) {
+            $this->error = GESHI_ERROR_NO_SUCH_LANG;
+            return;
+        }
+
+        // Load the language for parsing
+        $this->load_language($file_name);
+    }
+
+    /**
+     * Sets the path to the directory containing the language files. Note
+     * that this path is relative to the directory of the script that included
+     * geshi.php, NOT geshi.php itself.
+     *
+     * @param string The path to the language directory
+     * @since 1.0.0
+     * @deprecated The path to the language files should now be automatically
+     *             detected, so this method should no longer be needed. The
+     *             1.1.X branch handles manual setting of the path differently
+     *             so this method will disappear in 1.2.0.
+     */
+    function set_language_path($path) {
+        if(strpos($path,':')) {
+            //Security Fix to prevent external directories using fopen wrappers.
+            if(DIRECTORY_SEPARATOR == "\\") {
+                if(!preg_match('#^[a-zA-Z]:#', $path) || false !== strpos($path, ':', 2)) {
+                    return;
+                }
+            } else {
+                return;
+            }
+        }
+        if(preg_match('#[^/a-zA-Z0-9_\.\-\\\s:]#', $path)) {
+            //Security Fix to prevent external directories using fopen wrappers.
+            return;
+        }
+        if(GESHI_SECURITY_PARANOID && false !== strpos($path, '/.')) {
+            //Security Fix to prevent external directories using fopen wrappers.
+            return;
+        }
+        if(GESHI_SECURITY_PARANOID && false !== strpos($path, '..')) {
+            //Security Fix to prevent external directories using fopen wrappers.
+            return;
+        }
+        if ($path) {
+            $this->language_path = ('/' == $path[strlen($path) - 1]) ? $path : $path . '/';
+            $this->set_language($this->language); // otherwise set_language_path has no effect
+        }
+    }
+
+    /**
+     * Sets the type of header to be used.
+     *
+     * If GESHI_HEADER_DIV is used, the code is surrounded in a "div".This
+     * means more source code but more control over tab width and line-wrapping.
+     * GESHI_HEADER_PRE means that a "pre" is used - less source, but less
+     * control. Default is GESHI_HEADER_PRE.
+     *
+     * From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code
+     * should be outputted.
+     *
+     * @param int The type of header to be used
+     * @since 1.0.0
+     */
+    function set_header_type($type) {
+        //Check if we got a valid header type
+        if (!in_array($type, array(GESHI_HEADER_NONE, GESHI_HEADER_DIV,
+            GESHI_HEADER_PRE, GESHI_HEADER_PRE_VALID, GESHI_HEADER_PRE_TABLE))) {
+            $this->error = GESHI_ERROR_INVALID_HEADER_TYPE;
+            return;
+        }
+
+        //Set that new header type
+        $this->header_type = $type;
+    }
+
+    /**
+     * Sets the styles for the code that will be outputted
+     * when this object is parsed. The style should be a
+     * string of valid stylesheet declarations
+     *
+     * @param string  The overall style for the outputted code block
+     * @param boolean Whether to merge the styles with the current styles or not
+     * @since 1.0.0
+     */
+    function set_overall_style($style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->overall_style = $style;
+        } else {
+            $this->overall_style .= $style;
+        }
+    }
+
+    /**
+     * Sets the overall classname for this block of code. This
+     * class can then be used in a stylesheet to style this object's
+     * output
+     *
+     * @param string The class name to use for this block of code
+     * @since 1.0.0
+     */
+    function set_overall_class($class) {
+        $this->overall_class = $class;
+    }
+
+    /**
+     * Sets the overall id for this block of code. This id can then
+     * be used in a stylesheet to style this object's output
+     *
+     * @param string The ID to use for this block of code
+     * @since 1.0.0
+     */
+    function set_overall_id($id) {
+        $this->overall_id = $id;
+    }
+
+    /**
+     * Sets whether CSS classes should be used to highlight the source. Default
+     * is off, calling this method with no arguments will turn it on
+     *
+     * @param boolean Whether to turn classes on or not
+     * @since 1.0.0
+     */
+    function enable_classes($flag = true) {
+        $this->use_classes = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the style for the actual code. This should be a string
+     * containing valid stylesheet declarations. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * Note: Use this method to override any style changes you made to
+     * the line numbers if you are using line numbers, else the line of
+     * code will have the same style as the line number! Consult the
+     * GeSHi documentation for more information about this.
+     *
+     * @param string  The style to use for actual code
+     * @param boolean Whether to merge the current styles with the new styles
+     * @since 1.0.2
+     */
+    function set_code_style($style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->code_style = $style;
+        } else {
+            $this->code_style .= $style;
+        }
+    }
+
+    /**
+     * Sets the styles for the line numbers.
+     *
+     * @param string The style for the line numbers that are "normal"
+     * @param string|boolean If a string, this is the style of the line
+     *        numbers that are "fancy", otherwise if boolean then this
+     *        defines whether the normal styles should be merged with the
+     *        new normal styles or not
+     * @param boolean If set, is the flag for whether to merge the "fancy"
+     *        styles with the current styles or not
+     * @since 1.0.2
+     */
+    function set_line_style($style1, $style2 = '', $preserve_defaults = false) {
+        //Check if we got 2 or three parameters
+        if (is_bool($style2)) {
+            $preserve_defaults = $style2;
+            $style2 = '';
+        }
+
+        //Actually set the new styles
+        if (!$preserve_defaults) {
+            $this->line_style1 = $style1;
+            $this->line_style2 = $style2;
+        } else {
+            $this->line_style1 .= $style1;
+            $this->line_style2 .= $style2;
+        }
+    }
+
+    /**
+     * Sets whether line numbers should be displayed.
+     *
+     * Valid values for the first parameter are:
+     *
+     *  - GESHI_NO_LINE_NUMBERS: Line numbers will not be displayed
+     *  - GESHI_NORMAL_LINE_NUMBERS: Line numbers will be displayed
+     *  - GESHI_FANCY_LINE_NUMBERS: Fancy line numbers will be displayed
+     *
+     * For fancy line numbers, the second parameter is used to signal which lines
+     * are to be fancy. For example, if the value of this parameter is 5 then every
+     * 5th line will be fancy.
+     *
+     * @param int How line numbers should be displayed
+     * @param int Defines which lines are fancy
+     * @since 1.0.0
+     */
+    function enable_line_numbers($flag, $nth_row = 5) {
+        if (GESHI_NO_LINE_NUMBERS != $flag && GESHI_NORMAL_LINE_NUMBERS != $flag
+            && GESHI_FANCY_LINE_NUMBERS != $flag) {
+            $this->error = GESHI_ERROR_INVALID_LINE_NUMBER_TYPE;
+        }
+        $this->line_numbers = $flag;
+        $this->line_nth_row = $nth_row;
+    }
+
+    /**
+     * Sets wether spans and other HTML markup generated by GeSHi can
+     * span over multiple lines or not. Defaults to true to reduce overhead.
+     * Set it to false if you want to manipulate the output or manually display
+     * the code in an ordered list.
+     *
+     * @param boolean Wether multiline spans are allowed or not
+     * @since 1.0.7.22
+     */
+    function enable_multiline_span($flag) {
+        $this->allow_multiline_span = (bool) $flag;
+    }
+
+    /**
+     * Get current setting for multiline spans, see GeSHi->enable_multiline_span().
+     *
+     * @see enable_multiline_span
+     * @return bool
+     */
+    function get_multiline_span() {
+        return $this->allow_multiline_span;
+    }
+
+    /**
+     * Sets the style for a keyword group. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param int     The key of the keyword group to change the styles of
+     * @param string  The style to make the keywords
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_keyword_group_style($key, $style, $preserve_defaults = false) {
+        //Set the style for this keyword group
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['KEYWORDS'][$key] = $style;
+        } else {
+            $this->language_data['STYLES']['KEYWORDS'][$key] .= $style;
+        }
+
+        //Update the lexic permissions
+        if (!isset($this->lexic_permissions['KEYWORDS'][$key])) {
+            $this->lexic_permissions['KEYWORDS'][$key] = true;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for a keyword group
+     *
+     * @param int     The key of the keyword group to turn on or off
+     * @param boolean Whether to turn highlighting for that group on or off
+     * @since 1.0.0
+     */
+    function set_keyword_group_highlighting($key, $flag = true) {
+        $this->lexic_permissions['KEYWORDS'][$key] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for comment groups.  If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param int     The key of the comment group to change the styles of
+     * @param string  The style to make the comments
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_comments_style($key, $style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['COMMENTS'][$key] = $style;
+        } else {
+            $this->language_data['STYLES']['COMMENTS'][$key] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for comment groups
+     *
+     * @param int     The key of the comment group to turn on or off
+     * @param boolean Whether to turn highlighting for that group on or off
+     * @since 1.0.0
+     */
+    function set_comments_highlighting($key, $flag = true) {
+        $this->lexic_permissions['COMMENTS'][$key] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for escaped characters. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param string  The style to make the escape characters
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_escape_characters_style($style, $preserve_defaults = false, $group = 0) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['ESCAPE_CHAR'][$group] = $style;
+        } else {
+            $this->language_data['STYLES']['ESCAPE_CHAR'][$group] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for escaped characters
+     *
+     * @param boolean Whether to turn highlighting for escape characters on or off
+     * @since 1.0.0
+     */
+    function set_escape_characters_highlighting($flag = true) {
+        $this->lexic_permissions['ESCAPE_CHAR'] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for brackets. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * This method is DEPRECATED: use set_symbols_style instead.
+     * This method will be removed in 1.2.X
+     *
+     * @param string  The style to make the brackets
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     * @deprecated In favour of set_symbols_style
+     */
+    function set_brackets_style($style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['BRACKETS'][0] = $style;
+        } else {
+            $this->language_data['STYLES']['BRACKETS'][0] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for brackets
+     *
+     * This method is DEPRECATED: use set_symbols_highlighting instead.
+     * This method will be remove in 1.2.X
+     *
+     * @param boolean Whether to turn highlighting for brackets on or off
+     * @since 1.0.0
+     * @deprecated In favour of set_symbols_highlighting
+     */
+    function set_brackets_highlighting($flag) {
+        $this->lexic_permissions['BRACKETS'] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for symbols. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param string  The style to make the symbols
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @param int     Tells the group of symbols for which style should be set.
+     * @since 1.0.1
+     */
+    function set_symbols_style($style, $preserve_defaults = false, $group = 0) {
+        // Update the style of symbols
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['SYMBOLS'][$group] = $style;
+        } else {
+            $this->language_data['STYLES']['SYMBOLS'][$group] .= $style;
+        }
+
+        // For backward compatibility
+        if (0 == $group) {
+            $this->set_brackets_style ($style, $preserve_defaults);
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for symbols
+     *
+     * @param boolean Whether to turn highlighting for symbols on or off
+     * @since 1.0.0
+     */
+    function set_symbols_highlighting($flag) {
+        // Update lexic permissions for this symbol group
+        $this->lexic_permissions['SYMBOLS'] = ($flag) ? true : false;
+
+        // For backward compatibility
+        $this->set_brackets_highlighting ($flag);
+    }
+
+    /**
+     * Sets the styles for strings. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param string  The style to make the escape characters
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_strings_style($style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['STRINGS'][0] = $style;
+        } else {
+            $this->language_data['STYLES']['STRINGS'][0] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for strings
+     *
+     * @param boolean Whether to turn highlighting for strings on or off
+     * @since 1.0.0
+     */
+    function set_strings_highlighting($flag) {
+        $this->lexic_permissions['STRINGS'] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for numbers. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param string  The style to make the numbers
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_numbers_style($style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['NUMBERS'][0] = $style;
+        } else {
+            $this->language_data['STYLES']['NUMBERS'][0] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for numbers
+     *
+     * @param boolean Whether to turn highlighting for numbers on or off
+     * @since 1.0.0
+     */
+    function set_numbers_highlighting($flag) {
+        $this->lexic_permissions['NUMBERS'] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for methods. $key is a number that references the
+     * appropriate "object splitter" - see the language file for the language
+     * you are highlighting to get this number. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param int     The key of the object splitter to change the styles of
+     * @param string  The style to make the methods
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_methods_style($key, $style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['METHODS'][$key] = $style;
+        } else {
+            $this->language_data['STYLES']['METHODS'][$key] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for methods
+     *
+     * @param boolean Whether to turn highlighting for methods on or off
+     * @since 1.0.0
+     */
+    function set_methods_highlighting($flag) {
+        $this->lexic_permissions['METHODS'] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets the styles for regexps. If $preserve_defaults is
+     * true, then styles are merged with the default styles, with the
+     * user defined styles having priority
+     *
+     * @param string  The style to make the regular expression matches
+     * @param boolean Whether to merge the new styles with the old or just
+     *                to overwrite them
+     * @since 1.0.0
+     */
+    function set_regexps_style($key, $style, $preserve_defaults = false) {
+        if (!$preserve_defaults) {
+            $this->language_data['STYLES']['REGEXPS'][$key] = $style;
+        } else {
+            $this->language_data['STYLES']['REGEXPS'][$key] .= $style;
+        }
+    }
+
+    /**
+     * Turns highlighting on/off for regexps
+     *
+     * @param int     The key of the regular expression group to turn on or off
+     * @param boolean Whether to turn highlighting for the regular expression group on or off
+     * @since 1.0.0
+     */
+    function set_regexps_highlighting($key, $flag) {
+        $this->lexic_permissions['REGEXPS'][$key] = ($flag) ? true : false;
+    }
+
+    /**
+     * Sets whether a set of keywords are checked for in a case sensitive manner
+     *
+     * @param int The key of the keyword group to change the case sensitivity of
+     * @param boolean Whether to check in a case sensitive manner or not
+     * @since 1.0.0
+     */
+    function set_case_sensitivity($key, $case) {
+        $this->language_data['CASE_SENSITIVE'][$key] = ($case) ? true : false;
+    }
+
+    /**
+     * Sets the case that keywords should use when found. Use the constants:
+     *
+     *  - GESHI_CAPS_NO_CHANGE: leave keywords as-is
+     *  - GESHI_CAPS_UPPER: convert all keywords to uppercase where found
+     *  - GESHI_CAPS_LOWER: convert all keywords to lowercase where found
+     *
+     * @param int A constant specifying what to do with matched keywords
+     * @since 1.0.1
+     */
+    function set_case_keywords($case) {
+        if (in_array($case, array(
+            GESHI_CAPS_NO_CHANGE, GESHI_CAPS_UPPER, GESHI_CAPS_LOWER))) {
+            $this->language_data['CASE_KEYWORDS'] = $case;
+        }
+    }
+
+    /**
+     * Sets how many spaces a tab is substituted for
+     *
+     * Widths below zero are ignored
+     *
+     * @param int The tab width
+     * @since 1.0.0
+     */
+    function set_tab_width($width) {
+        $this->tab_width = intval($width);
+
+        //Check if it fit's the constraints:
+        if ($this->tab_width < 1) {
+            //Return it to the default
+            $this->tab_width = 8;
+        }
+    }
+
+    /**
+     * Sets whether or not to use tab-stop width specifed by language
+     *
+     * @param boolean Whether to use language-specific tab-stop widths
+     * @since 1.0.7.20
+     */
+    function set_use_language_tab_width($use) {
+        $this->use_language_tab_width = (bool) $use;
+    }
+
+    /**
+     * Returns the tab width to use, based on the current language and user
+     * preference
+     *
+     * @return int Tab width
+     * @since 1.0.7.20
+     */
+    function get_real_tab_width() {
+        if (!$this->use_language_tab_width ||
+            !isset($this->language_data['TAB_WIDTH'])) {
+            return $this->tab_width;
+        } else {
+            return $this->language_data['TAB_WIDTH'];
+        }
+    }
+
+    /**
+     * Enables/disables strict highlighting. Default is off, calling this
+     * method without parameters will turn it on. See documentation
+     * for more details on strict mode and where to use it.
+     *
+     * @param boolean Whether to enable strict mode or not
+     * @since 1.0.0
+     */
+    function enable_strict_mode($mode = true) {
+        if (GESHI_MAYBE == $this->language_data['STRICT_MODE_APPLIES']) {
+            $this->strict_mode = ($mode) ? GESHI_ALWAYS : GESHI_NEVER;
+        }
+    }
+
+    /**
+     * Disables all highlighting
+     *
+     * @since 1.0.0
+     * @todo  Rewrite with array traversal
+     * @deprecated In favour of enable_highlighting
+     */
+    function disable_highlighting() {
+        $this->enable_highlighting(false);
+    }
+
+    /**
+     * Enables all highlighting
+     *
+     * The optional flag parameter was added in version 1.0.7.21 and can be used
+     * to enable (true) or disable (false) all highlighting.
+     *
+     * @since 1.0.0
+     * @param boolean A flag specifying whether to enable or disable all highlighting
+     * @todo  Rewrite with array traversal
+     */
+    function enable_highlighting($flag = true) {
+        $flag = $flag ? true : false;
+        foreach ($this->lexic_permissions as $key => $value) {
+            if (is_array($value)) {
+                foreach ($value as $k => $v) {
+                    $this->lexic_permissions[$key][$k] = $flag;
+                }
+            } else {
+                $this->lexic_permissions[$key] = $flag;
+            }
+        }
+
+        // Context blocks
+        $this->enable_important_blocks = $flag;
+    }
+
+    /**
+     * Given a file extension, this method returns either a valid geshi language
+     * name, or the empty string if it couldn't be found
+     *
+     * @param string The extension to get a language name for
+     * @param array  A lookup array to use instead of the default one
+     * @since 1.0.5
+     * @todo Re-think about how this method works (maybe make it private and/or make it
+     *       a extension->lang lookup?)
+     * @todo static?
+     */
+    function get_language_name_from_extension( $extension, $lookup = array() ) {
+        if ( !is_array($lookup) || empty($lookup)) {
+            $lookup = array(
+                'actionscript' => array('as'),
+                'ada' => array('a', 'ada', 'adb', 'ads'),
+                'apache' => array('conf'),
+                'asm' => array('ash', 'asm', 'inc'),
+                'asp' => array('asp'),
+                'bash' => array('sh'),
+                'bf' => array('bf'),
+                'c' => array('c', 'h'),
+                'c_mac' => array('c', 'h'),
+                'caddcl' => array(),
+                'cadlisp' => array(),
+                'cdfg' => array('cdfg'),
+                'cobol' => array('cbl'),
+                'cpp' => array('cpp', 'hpp', 'C', 'H', 'CPP', 'HPP'),
+                'csharp' => array('cs'),
+                'css' => array('css'),
+                'd' => array('d'),
+                'delphi' => array('dpk', 'dpr', 'pp', 'pas'),
+                'diff' => array('diff', 'patch'),
+                'dos' => array('bat', 'cmd'),
+                'gettext' => array('po', 'pot'),
+                'gml' => array('gml'),
+                'gnuplot' => array('plt'),
+                'groovy' => array('groovy'),
+                'haskell' => array('hs'),
+                'html4strict' => array('html', 'htm'),
+                'ini' => array('ini', 'desktop'),
+                'java' => array('java'),
+                'javascript' => array('js'),
+                'klonec' => array('kl1'),
+                'klonecpp' => array('klx'),
+                'latex' => array('tex'),
+                'lisp' => array('lisp'),
+                'lua' => array('lua'),
+                'matlab' => array('m'),
+                'mpasm' => array(),
+                'mysql' => array('sql'),
+                'nsis' => array(),
+                'objc' => array(),
+                'oobas' => array(),
+                'oracle8' => array(),
+                'oracle10' => array(),
+                'pascal' => array('pas'),
+                'perl' => array('pl', 'pm'),
+                'php' => array('php', 'php5', 'phtml', 'phps'),
+                'povray' => array('pov'),
+                'providex' => array('pvc', 'pvx'),
+                'prolog' => array('pl'),
+                'python' => array('py'),
+                'qbasic' => array('bi'),
+                'reg' => array('reg'),
+                'ruby' => array('rb'),
+                'sas' => array('sas'),
+                'scala' => array('scala'),
+                'scheme' => array('scm'),
+                'scilab' => array('sci'),
+                'smalltalk' => array('st'),
+                'smarty' => array(),
+                'tcl' => array('tcl'),
+                'vb' => array('bas'),
+                'vbnet' => array(),
+                'visualfoxpro' => array(),
+                'whitespace' => array('ws'),
+                'xml' => array('xml', 'svg'),
+                'z80' => array('z80', 'asm', 'inc')
+            );
+        }
+
+        foreach ($lookup as $lang => $extensions) {
+            if (in_array($extension, $extensions)) {
+                return $lang;
+            }
+        }
+        return '';
+    }
+
+    /**
+     * Given a file name, this method loads its contents in, and attempts
+     * to set the language automatically. An optional lookup table can be
+     * passed for looking up the language name. If not specified a default
+     * table is used
+     *
+     * The language table is in the form
+     * <pre>array(
+     *   'lang_name' => array('extension', 'extension', ...),
+     *   'lang_name' ...
+     * );</pre>
+     *
+     * @param string The filename to load the source from
+     * @param array  A lookup array to use instead of the default one
+     * @todo Complete rethink of this and above method
+     * @since 1.0.5
+     */
+    function load_from_file($file_name, $lookup = array()) {
+        if (is_readable($file_name)) {
+            $this->set_source(file_get_contents($file_name));
+            $this->set_language($this->get_language_name_from_extension(substr(strrchr($file_name, '.'), 1), $lookup));
+        } else {
+            $this->error = GESHI_ERROR_FILE_NOT_READABLE;
+        }
+    }
+
+    /**
+     * Adds a keyword to a keyword group for highlighting
+     *
+     * @param int    The key of the keyword group to add the keyword to
+     * @param string The word to add to the keyword group
+     * @since 1.0.0
+     */
+    function add_keyword($key, $word) {
+        if (!in_array($word, $this->language_data['KEYWORDS'][$key])) {
+            $this->language_data['KEYWORDS'][$key][] = $word;
+
+            //NEW in 1.0.8 don't recompile the whole optimized regexp, simply append it
+            if ($this->parse_cache_built) {
+                $subkey = count($this->language_data['CACHED_KEYWORD_LISTS'][$key]) - 1;
+                $this->language_data['CACHED_KEYWORD_LISTS'][$key][$subkey] .= '|' . preg_quote($word, '/');
+            }
+        }
+    }
+
+    /**
+     * Removes a keyword from a keyword group
+     *
+     * @param int    The key of the keyword group to remove the keyword from
+     * @param string The word to remove from the keyword group
+     * @param bool   Wether to automatically recompile the optimized regexp list or not.
+     *               Note: if you set this to false and @see GeSHi->parse_code() was already called once,
+     *               for the current language, you have to manually call @see GeSHi->optimize_keyword_group()
+     *               or the removed keyword will stay in cache and still be highlighted! On the other hand
+     *               it might be too expensive to recompile the regexp list for every removal if you want to
+     *               remove a lot of keywords.
+     * @since 1.0.0
+     */
+    function remove_keyword($key, $word, $recompile = true) {
+        $key_to_remove = array_search($word, $this->language_data['KEYWORDS'][$key]);
+        if ($key_to_remove !== false) {
+            unset($this->language_data['KEYWORDS'][$key][$key_to_remove]);
+
+            //NEW in 1.0.8, optionally recompile keyword group
+            if ($recompile && $this->parse_cache_built) {
+                $this->optimize_keyword_group($key);
+            }
+        }
+    }
+
+    /**
+     * Creates a new keyword group
+     *
+     * @param int    The key of the keyword group to create
+     * @param string The styles for the keyword group
+     * @param boolean Whether the keyword group is case sensitive ornot
+     * @param array  The words to use for the keyword group
+     * @since 1.0.0
+     */
+    function add_keyword_group($key, $styles, $case_sensitive = true, $words = array()) {
+        $words = (array) $words;
+        if  (empty($words)) {
+            // empty word lists mess up highlighting
+            return false;
+        }
+
+        //Add the new keyword group internally
+        $this->language_data['KEYWORDS'][$key] = $words;
+        $this->lexic_permissions['KEYWORDS'][$key] = true;
+        $this->language_data['CASE_SENSITIVE'][$key] = $case_sensitive;
+        $this->language_data['STYLES']['KEYWORDS'][$key] = $styles;
+
+        //NEW in 1.0.8, cache keyword regexp
+        if ($this->parse_cache_built) {
+            $this->optimize_keyword_group($key);
+        }
+    }
+
+    /**
+     * Removes a keyword group
+     *
+     * @param int    The key of the keyword group to remove
+     * @since 1.0.0
+     */
+    function remove_keyword_group ($key) {
+        //Remove the keyword group internally
+        unset($this->language_data['KEYWORDS'][$key]);
+        unset($this->lexic_permissions['KEYWORDS'][$key]);
+        unset($this->language_data['CASE_SENSITIVE'][$key]);
+        unset($this->language_data['STYLES']['KEYWORDS'][$key]);
+
+        //NEW in 1.0.8
+        unset($this->language_data['CACHED_KEYWORD_LISTS'][$key]);
+    }
+
+    /**
+     * compile optimized regexp list for keyword group
+     *
+     * @param int   The key of the keyword group to compile & optimize
+     * @since 1.0.8
+     */
+    function optimize_keyword_group($key) {
+        $this->language_data['CACHED_KEYWORD_LISTS'][$key] =
+            $this->optimize_regexp_list($this->language_data['KEYWORDS'][$key]);
+        $space_as_whitespace = false;
+        if(isset($this->language_data['PARSER_CONTROL'])) {
+            if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'])) {
+                if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['SPACE_AS_WHITESPACE'])) {
+                    $space_as_whitespace = $this->language_data['PARSER_CONTROL']['KEYWORDS']['SPACE_AS_WHITESPACE'];
+                }
+                if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'])) {
+                    if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'])) {
+                        $space_as_whitespace = $this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'];
+                    }
+                }
+            }
+        }
+        if($space_as_whitespace) {
+            foreach($this->language_data['CACHED_KEYWORD_LISTS'][$key] as $rxk => $rxv) {
+                $this->language_data['CACHED_KEYWORD_LISTS'][$key][$rxk] =
+                    str_replace(" ", "\\s+", $rxv);
+            }
+        }
+    }
+
+    /**
+     * Sets the content of the header block
+     *
+     * @param string The content of the header block
+     * @since 1.0.2
+     */
+    function set_header_content($content) {
+        $this->header_content = $content;
+    }
+
+    /**
+     * Sets the content of the footer block
+     *
+     * @param string The content of the footer block
+     * @since 1.0.2
+     */
+    function set_footer_content($content) {
+        $this->footer_content = $content;
+    }
+
+    /**
+     * Sets the style for the header content
+     *
+     * @param string The style for the header content
+     * @since 1.0.2
+     */
+    function set_header_content_style($style) {
+        $this->header_content_style = $style;
+    }
+
+    /**
+     * Sets the style for the footer content
+     *
+     * @param string The style for the footer content
+     * @since 1.0.2
+     */
+    function set_footer_content_style($style) {
+        $this->footer_content_style = $style;
+    }
+
+    /**
+     * Sets whether to force a surrounding block around
+     * the highlighted code or not
+     *
+     * @param boolean Tells whether to enable or disable this feature
+     * @since 1.0.7.20
+     */
+    function enable_inner_code_block($flag) {
+        $this->force_code_block = (bool)$flag;
+    }
+
+    /**
+     * Sets the base URL to be used for keywords
+     *
+     * @param int The key of the keyword group to set the URL for
+     * @param string The URL to set for the group. If {FNAME} is in
+     *               the url somewhere, it is replaced by the keyword
+     *               that the URL is being made for
+     * @since 1.0.2
+     */
+    function set_url_for_keyword_group($group, $url) {
+        $this->language_data['URLS'][$group] = $url;
+    }
+
+    /**
+     * Sets styles for links in code
+     *
+     * @param int A constant that specifies what state the style is being
+     *            set for - e.g. :hover or :visited
+     * @param string The styles to use for that state
+     * @since 1.0.2
+     */
+    function set_link_styles($type, $styles) {
+        $this->link_styles[$type] = $styles;
+    }
+
+    /**
+     * Sets the target for links in code
+     *
+     * @param string The target for links in the code, e.g. _blank
+     * @since 1.0.3
+     */
+    function set_link_target($target) {
+        if (!$target) {
+            $this->link_target = '';
+        } else {
+            $this->link_target = ' target="' . $target . '"';
+        }
+    }
+
+    /**
+     * Sets styles for important parts of the code
+     *
+     * @param string The styles to use on important parts of the code
+     * @since 1.0.2
+     */
+    function set_important_styles($styles) {
+        $this->important_styles = $styles;
+    }
+
+    /**
+     * Sets whether context-important blocks are highlighted
+     *
+     * @param boolean Tells whether to enable or disable highlighting of important blocks
+     * @todo REMOVE THIS SHIZ FROM GESHI!
+     * @deprecated
+     * @since 1.0.2
+     */
+    function enable_important_blocks($flag) {
+        $this->enable_important_blocks = ( $flag ) ? true : false;
+    }
+
+    /**
+     * Whether CSS IDs should be added to each line
+     *
+     * @param boolean If true, IDs will be added to each line.
+     * @since 1.0.2
+     */
+    function enable_ids($flag = true) {
+        $this->add_ids = ($flag) ? true : false;
+    }
+
+    /**
+     * Specifies which lines to highlight extra
+     *
+     * The extra style parameter was added in 1.0.7.21.
+     *
+     * @param mixed An array of line numbers to highlight, or just a line
+     *              number on its own.
+     * @param string A string specifying the style to use for this line.
+     *              If null is specified, the default style is used.
+     *              If false is specified, the line will be removed from
+     *              special highlighting
+     * @since 1.0.2
+     * @todo  Some data replication here that could be cut down on
+     */
+    function highlight_lines_extra($lines, $style = null) {
+        if (is_array($lines)) {
+            //Split up the job using single lines at a time
+            foreach ($lines as $line) {
+                $this->highlight_lines_extra($line, $style);
+            }
+        } else {
+            //Mark the line as being highlighted specially
+            $lines = intval($lines);
+            $this->highlight_extra_lines[$lines] = $lines;
+
+            //Decide on which style to use
+            if ($style === null) { //Check if we should use default style
+                unset($this->highlight_extra_lines_styles[$lines]);
+            } else if ($style === false) { //Check if to remove this line
+                unset($this->highlight_extra_lines[$lines]);
+                unset($this->highlight_extra_lines_styles[$lines]);
+            } else {
+                $this->highlight_extra_lines_styles[$lines] = $style;
+            }
+        }
+    }
+
+    /**
+     * Sets the style for extra-highlighted lines
+     *
+     * @param string The style for extra-highlighted lines
+     * @since 1.0.2
+     */
+    function set_highlight_lines_extra_style($styles) {
+        $this->highlight_extra_lines_style = $styles;
+    }
+
+    /**
+     * Sets the line-ending
+     *
+     * @param string The new line-ending
+     * @since 1.0.2
+     */
+    function set_line_ending($line_ending) {
+        $this->line_ending = (string)$line_ending;
+    }
+
+    /**
+     * Sets what number line numbers should start at. Should
+     * be a positive integer, and will be converted to one.
+     *
+     * <b>Warning:</b> Using this method will add the "start"
+     * attribute to the &lt;ol&gt; that is used for line numbering.
+     * This is <b>not</b> valid XHTML strict, so if that's what you
+     * care about then don't use this method. Firefox is getting
+     * support for the CSS method of doing this in 1.1 and Opera
+     * has support for the CSS method, but (of course) IE doesn't
+     * so it's not worth doing it the CSS way yet.
+     *
+     * @param int The number to start line numbers at
+     * @since 1.0.2
+     */
+    function start_line_numbers_at($number) {
+        $this->line_numbers_start = abs(intval($number));
+    }
+
+    /**
+     * Sets the encoding used for htmlspecialchars(), for international
+     * support.
+     *
+     * NOTE: This is not needed for now because htmlspecialchars() is not
+     * being used (it has a security hole in PHP4 that has not been patched).
+     * Maybe in a future version it may make a return for speed reasons, but
+     * I doubt it.
+     *
+     * @param string The encoding to use for the source
+     * @since 1.0.3
+     */
+    function set_encoding($encoding) {
+        if ($encoding) {
+          $this->encoding = strtolower($encoding);
+        }
+    }
+
+    /**
+     * Turns linking of keywords on or off.
+     *
+     * @param boolean If true, links will be added to keywords
+     * @since 1.0.2
+     */
+    function enable_keyword_links($enable = true) {
+        $this->keyword_links = (bool) $enable;
+    }
+
+    /**
+     * Setup caches needed for styling. This is automatically called in
+     * parse_code() and get_stylesheet() when appropriate. This function helps
+     * stylesheet generators as they rely on some style information being
+     * preprocessed
+     *
+     * @since 1.0.8
+     * @access private
+     */
+    function build_style_cache() {
+        //Build the style cache needed to highlight numbers appropriate
+        if($this->lexic_permissions['NUMBERS']) {
+            //First check what way highlighting information for numbers are given
+            if(!isset($this->language_data['NUMBERS'])) {
+                $this->language_data['NUMBERS'] = 0;
+            }
+
+            if(is_array($this->language_data['NUMBERS'])) {
+                $this->language_data['NUMBERS_CACHE'] = $this->language_data['NUMBERS'];
+            } else {
+                $this->language_data['NUMBERS_CACHE'] = array();
+                if(!$this->language_data['NUMBERS']) {
+                    $this->language_data['NUMBERS'] =
+                        GESHI_NUMBER_INT_BASIC |
+                        GESHI_NUMBER_FLT_NONSCI;
+                }
+
+                for($i = 0, $j = $this->language_data['NUMBERS']; $j > 0; ++$i, $j>>=1) {
+                    //Rearrange style indices if required ...
+                    if(isset($this->language_data['STYLES']['NUMBERS'][1<<$i])) {
+                        $this->language_data['STYLES']['NUMBERS'][$i] =
+                            $this->language_data['STYLES']['NUMBERS'][1<<$i];
+                        unset($this->language_data['STYLES']['NUMBERS'][1<<$i]);
+                    }
+
+                    //Check if this bit is set for highlighting
+                    if($j&1) {
+                        //So this bit is set ...
+                        //Check if it belongs to group 0 or the actual stylegroup
+                        if(isset($this->language_data['STYLES']['NUMBERS'][$i])) {
+                            $this->language_data['NUMBERS_CACHE'][$i] = 1 << $i;
+                        } else {
+                            if(!isset($this->language_data['NUMBERS_CACHE'][0])) {
+                                $this->language_data['NUMBERS_CACHE'][0] = 0;
+                            }
+                            $this->language_data['NUMBERS_CACHE'][0] |= 1 << $i;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Setup caches needed for parsing. This is automatically called in parse_code() when appropriate.
+     * This function makes stylesheet generators much faster as they do not need these caches.
+     *
+     * @since 1.0.8
+     * @access private
+     */
+    function build_parse_cache() {
+        // cache symbol regexp
+        //As this is a costy operation, we avoid doing it for multiple groups ...
+        //Instead we perform it for all symbols at once.
+        //
+        //For this to work, we need to reorganize the data arrays.
+        if ($this->lexic_permissions['SYMBOLS'] && !empty($this->language_data['SYMBOLS'])) {
+            $this->language_data['MULTIPLE_SYMBOL_GROUPS'] = count($this->language_data['STYLES']['SYMBOLS']) > 1;
+
+            $this->language_data['SYMBOL_DATA'] = array();
+            $symbol_preg_multi = array(); // multi char symbols
+            $symbol_preg_single = array(); // single char symbols
+            foreach ($this->language_data['SYMBOLS'] as $key => $symbols) {
+                if (is_array($symbols)) {
+                    foreach ($symbols as $sym) {
+                        $sym = $this->hsc($sym);
+                        if (!isset($this->language_data['SYMBOL_DATA'][$sym])) {
+                            $this->language_data['SYMBOL_DATA'][$sym] = $key;
+                            if (isset($sym[1])) { // multiple chars
+                                $symbol_preg_multi[] = preg_quote($sym, '/');
+                            } else { // single char
+                                if ($sym == '-') {
+                                    // don't trigger range out of order error
+                                    $symbol_preg_single[] = '\-';
+                                } else {
+                                    $symbol_preg_single[] = preg_quote($sym, '/');
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    $symbols = $this->hsc($symbols);
+                    if (!isset($this->language_data['SYMBOL_DATA'][$symbols])) {
+                        $this->language_data['SYMBOL_DATA'][$symbols] = 0;
+                        if (isset($symbols[1])) { // multiple chars
+                            $symbol_preg_multi[] = preg_quote($symbols, '/');
+                        } else if ($symbols == '-') {
+                            // don't trigger range out of order error
+                            $symbol_preg_single[] = '\-';
+                        } else { // single char
+                            $symbol_preg_single[] = preg_quote($symbols, '/');
+                        }
+                    }
+                }
+            }
+
+            //Now we have an array with each possible symbol as the key and the style as the actual data.
+            //This way we can set the correct style just the moment we highlight ...
+            //
+            //Now we need to rewrite our array to get a search string that
+            $symbol_preg = array();
+            if (!empty($symbol_preg_multi)) {
+                rsort($symbol_preg_multi);
+                $symbol_preg[] = implode('|', $symbol_preg_multi);
+            }
+            if (!empty($symbol_preg_single)) {
+                rsort($symbol_preg_single);
+                $symbol_preg[] = '[' . implode('', $symbol_preg_single) . ']';
+            }
+            $this->language_data['SYMBOL_SEARCH'] = implode("|", $symbol_preg);
+        }
+
+        // cache optimized regexp for keyword matching
+        // remove old cache
+        $this->language_data['CACHED_KEYWORD_LISTS'] = array();
+        foreach (array_keys($this->language_data['KEYWORDS']) as $key) {
+            if (!isset($this->lexic_permissions['KEYWORDS'][$key]) ||
+                    $this->lexic_permissions['KEYWORDS'][$key]) {
+                $this->optimize_keyword_group($key);
+            }
+        }
+
+        // brackets
+        if ($this->lexic_permissions['BRACKETS']) {
+            $this->language_data['CACHE_BRACKET_MATCH'] = array('[', ']', '(', ')', '{', '}');
+            if (!$this->use_classes && isset($this->language_data['STYLES']['BRACKETS'][0])) {
+                $this->language_data['CACHE_BRACKET_REPLACE'] = array(
+                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#91;|>',
+                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#93;|>',
+                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#40;|>',
+                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#41;|>',
+                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#123;|>',
+                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#125;|>',
+                );
+            }
+            else {
+                $this->language_data['CACHE_BRACKET_REPLACE'] = array(
+                    '<| class="br0">&#91;|>',
+                    '<| class="br0">&#93;|>',
+                    '<| class="br0">&#40;|>',
+                    '<| class="br0">&#41;|>',
+                    '<| class="br0">&#123;|>',
+                    '<| class="br0">&#125;|>',
+                );
+            }
+        }
+
+        //Build the parse cache needed to highlight numbers appropriate
+        if($this->lexic_permissions['NUMBERS']) {
+            //Check if the style rearrangements have been processed ...
+            //This also does some preprocessing to check which style groups are useable ...
+            if(!isset($this->language_data['NUMBERS_CACHE'])) {
+                $this->build_style_cache();
+            }
+
+            //Number format specification
+            //All this formats are matched case-insensitively!
+            static $numbers_format = array(
+                GESHI_NUMBER_INT_BASIC =>
+                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z\.])',
+                GESHI_NUMBER_INT_CSTYLE =>
+                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)l(?![0-9a-z\.])',
+                GESHI_NUMBER_BIN_SUFFIX =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[01]+?b(?![0-9a-z\.])',
+                GESHI_NUMBER_BIN_PREFIX_PERCENT =>
+                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])%[01]+?(?![0-9a-z\.])',
+                GESHI_NUMBER_BIN_PREFIX_0B =>
+                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0b[01]+?(?![0-9a-z\.])',
+                GESHI_NUMBER_OCT_PREFIX =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0[0-7]+?(?![0-9a-z\.])',
+                GESHI_NUMBER_OCT_SUFFIX =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[0-7]+?o(?![0-9a-z\.])',
+                GESHI_NUMBER_HEX_PREFIX =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0x[0-9a-f]+?(?![0-9a-z\.])',
+                GESHI_NUMBER_HEX_SUFFIX =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d[0-9a-f]*?h(?![0-9a-z\.])',
+                GESHI_NUMBER_FLT_NONSCI =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d+?\.\d+?(?![0-9a-z\.])',
+                GESHI_NUMBER_FLT_NONSCI_F =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)f(?![0-9a-z\.])',
+                GESHI_NUMBER_FLT_SCI_SHORT =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\.\d+?(?:e[+\-]?\d+?)?(?![0-9a-z\.])',
+                GESHI_NUMBER_FLT_SCI_ZERO =>
+                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)(?:e[+\-]?\d+?)?(?![0-9a-z\.])'
+                );
+
+            //At this step we have an associative array with flag groups for a
+            //specific style or an string denoting a regexp given its index.
+            $this->language_data['NUMBERS_RXCACHE'] = array();
+            foreach($this->language_data['NUMBERS_CACHE'] as $key => $rxdata) {
+                if(is_string($rxdata)) {
+                    $regexp = $rxdata;
+                } else {
+                    //This is a bitfield of number flags to highlight:
+                    //Build an array, implode them together and make this the actual RX
+                    $rxuse = array();
+                    for($i = 1; $i <= $rxdata; $i<<=1) {
+                        if($rxdata & $i) {
+                            $rxuse[] = $numbers_format[$i];
+                        }
+                    }
+                    $regexp = implode("|", $rxuse);
+                }
+
+                $this->language_data['NUMBERS_RXCACHE'][$key] =
+                    "/(?<!<\|\/NUM!)(?<!\d\/>)($regexp)(?!\|>)/i";
+            }
+        }
+
+        $this->parse_cache_built = true;
+    }
+
+    /**
+     * Returns the code in $this->source, highlighted and surrounded by the
+     * nessecary HTML.
+     *
+     * This should only be called ONCE, cos it's SLOW! If you want to highlight
+     * the same source multiple times, you're better off doing a whole lot of
+     * str_replaces to replace the &lt;span&gt;s
+     *
+     * @since 1.0.0
+     */
+    function parse_code () {
+        // Start the timer
+        $start_time = microtime();
+
+        // Firstly, if there is an error, we won't highlight
+        if ($this->error) {
+            //Escape the source for output
+            $result = $this->hsc($this->source);
+
+            //This fix is related to SF#1923020, but has to be applied regardless of
+            //actually highlighting symbols.
+            $result = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $result);
+
+            // Timing is irrelevant
+            $this->set_time($start_time, $start_time);
+            $this->finalise($result);
+            return $result;
+        }
+
+        // make sure the parse cache is up2date
+        if (!$this->parse_cache_built) {
+            $this->build_parse_cache();
+        }
+
+        // Replace all newlines to a common form.
+        $code = str_replace("\r\n", "\n", $this->source);
+        $code = str_replace("\r", "\n", $code);
+
+        // Add spaces for regular expression matching and line numbers
+//        $code = "\n" . $code . "\n";
+
+        // Initialise various stuff
+        $length           = strlen($code);
+        $COMMENT_MATCHED  = false;
+        $stuff_to_parse   = '';
+        $endresult        = '';
+
+        // "Important" selections are handled like multiline comments
+        // @todo GET RID OF THIS SHIZ
+        if ($this->enable_important_blocks) {
+            $this->language_data['COMMENT_MULTI'][GESHI_START_IMPORTANT] = GESHI_END_IMPORTANT;
+        }
+
+        if ($this->strict_mode) {
+            // Break the source into bits. Each bit will be a portion of the code
+            // within script delimiters - for example, HTML between < and >
+            $k = 0;
+            $parts = array();
+            $matches = array();
+            $next_match_pointer = null;
+            // we use a copy to unset delimiters on demand (when they are not found)
+            $delim_copy = $this->language_data['SCRIPT_DELIMITERS'];
+            $i = 0;
+            while ($i < $length) {
+                $next_match_pos = $length + 1; // never true
+                foreach ($delim_copy as $dk => $delimiters) {
+                    if(is_array($delimiters)) {
+                        foreach ($delimiters as $open => $close) {
+                            // make sure the cache is setup properly
+                            if (!isset($matches[$dk][$open])) {
+                                $matches[$dk][$open] = array(
+                                    'next_match' => -1,
+                                    'dk' => $dk,
+
+                                    'open' => $open, // needed for grouping of adjacent code blocks (see below)
+                                    'open_strlen' => strlen($open),
+
+                                    'close' => $close,
+                                    'close_strlen' => strlen($close),
+                                );
+                            }
+                            // Get the next little bit for this opening string
+                            if ($matches[$dk][$open]['next_match'] < $i) {
+                                // only find the next pos if it was not already cached
+                                $open_pos = strpos($code, $open, $i);
+                                if ($open_pos === false) {
+                                    // no match for this delimiter ever
+                                    unset($delim_copy[$dk][$open]);
+                                    continue;
+                                }
+                                $matches[$dk][$open]['next_match'] = $open_pos;
+                            }
+                            if ($matches[$dk][$open]['next_match'] < $next_match_pos) {
+                                //So we got a new match, update the close_pos
+                                $matches[$dk][$open]['close_pos'] =
+                                    strpos($code, $close, $matches[$dk][$open]['next_match']+1);
+
+                                $next_match_pointer =& $matches[$dk][$open];
+                                $next_match_pos = $matches[$dk][$open]['next_match'];
+                            }
+                        }
+                    } else {
+                        //So we should match an RegExp as Strict Block ...
+                        /**
+                         * The value in $delimiters is expected to be an RegExp
+                         * containing exactly 2 matching groups:
+                         *  - Group 1 is the opener
+                         *  - Group 2 is the closer
+                         */
+                        if(!GESHI_PHP_PRE_433 && //Needs proper rewrite to work with PHP >=4.3.0; 4.3.3 is guaranteed to work.
+                            preg_match($delimiters, $code, $matches_rx, PREG_OFFSET_CAPTURE, $i)) {
+                            //We got a match ...
+                            $matches[$dk] = array(
+                                'next_match' => $matches_rx[1][1],
+                                'dk' => $dk,
+
+                                'close_strlen' => strlen($matches_rx[2][0]),
+                                'close_pos' => $matches_rx[2][1],
+                                );
+                        } else {
+                            // no match for this delimiter ever
+                            unset($delim_copy[$dk]);
+                            continue;
+                        }
+
+                        if ($matches[$dk]['next_match'] <= $next_match_pos) {
+                            $next_match_pointer =& $matches[$dk];
+                            $next_match_pos = $matches[$dk]['next_match'];
+                        }
+                    }
+                }
+                // non-highlightable text
+                $parts[$k] = array(
+                    1 => substr($code, $i, $next_match_pos - $i)
+                );
+                ++$k;
+
+                if ($next_match_pos > $length) {
+                    // out of bounds means no next match was found
+                    break;
+                }
+
+                // highlightable code
+                $parts[$k][0] = $next_match_pointer['dk'];
+
+                //Only combine for non-rx script blocks
+                if(is_array($delim_copy[$next_match_pointer['dk']])) {
+                    // group adjacent script blocks, e.g. <foobar><asdf> should be one block, not three!
+                    $i = $next_match_pos + $next_match_pointer['open_strlen'];
+                    while (true) {
+                        $close_pos = strpos($code, $next_match_pointer['close'], $i);
+                        if ($close_pos == false) {
+                            break;
+                        }
+                        $i = $close_pos + $next_match_pointer['close_strlen'];
+                        if ($i == $length) {
+                            break;
+                        }
+                        if ($code[$i] == $next_match_pointer['open'][0] && ($next_match_pointer['open_strlen'] == 1 ||
+                            substr($code, $i, $next_match_pointer['open_strlen']) == $next_match_pointer['open'])) {
+                            // merge adjacent but make sure we don't merge things like <tag><!-- comment -->
+                            foreach ($matches as $submatches) {
+                                foreach ($submatches as $match) {
+                                    if ($match['next_match'] == $i) {
+                                        // a different block already matches here!
+                                        break 3;
+                                    }
+                                }
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                } else {
+                    $close_pos = $next_match_pointer['close_pos'] + $next_match_pointer['close_strlen'];
+                    $i = $close_pos;
+                }
+
+                if ($close_pos === false) {
+                    // no closing delimiter found!
+                    $parts[$k][1] = substr($code, $next_match_pos);
+                    ++$k;
+                    break;
+                } else {
+                    $parts[$k][1] = substr($code, $next_match_pos, $i - $next_match_pos);
+                    ++$k;
+                }
+            }
+            unset($delim_copy, $next_match_pointer, $next_match_pos, $matches);
+            $num_parts = $k;
+
+            if ($num_parts == 1 && $this->strict_mode == GESHI_MAYBE) {
+                // when we have only one part, we don't have anything to highlight at all.
+                // if we have a "maybe" strict language, this should be handled as highlightable code
+                $parts = array(
+                    0 => array(
+                        0 => '',
+                        1 => ''
+                    ),
+                    1 => array(
+                        0 => null,
+                        1 => $parts[0][1]
+                    )
+                );
+                $num_parts = 2;
+            }
+
+        } else {
+            // Not strict mode - simply dump the source into
+            // the array at index 1 (the first highlightable block)
+            $parts = array(
+                0 => array(
+                    0 => '',
+                    1 => ''
+                ),
+                1 => array(
+                    0 => null,
+                    1 => $code
+                )
+            );
+            $num_parts = 2;
+        }
+
+        //Unset variables we won't need any longer
+        unset($code);
+
+        //Preload some repeatedly used values regarding hardquotes ...
+        $hq = isset($this->language_data['HARDQUOTE']) ? $this->language_data['HARDQUOTE'][0] : false;
+        $hq_strlen = strlen($hq);
+
+        //Preload if line numbers are to be generated afterwards
+        //Added a check if line breaks should be forced even without line numbers, fixes SF#1727398
+        $check_linenumbers = $this->line_numbers != GESHI_NO_LINE_NUMBERS ||
+            !empty($this->highlight_extra_lines) || !$this->allow_multiline_span;
+
+        //preload the escape char for faster checking ...
+        $escaped_escape_char = $this->hsc($this->language_data['ESCAPE_CHAR']);
+
+        // this is used for single-line comments
+        $sc_disallowed_before = "";
+        $sc_disallowed_after = "";
+
+        if (isset($this->language_data['PARSER_CONTROL'])) {
+            if (isset($this->language_data['PARSER_CONTROL']['COMMENTS'])) {
+                if (isset($this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_BEFORE'])) {
+                    $sc_disallowed_before = $this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_BEFORE'];
+                }
+                if (isset($this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_AFTER'])) {
+                    $sc_disallowed_after = $this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_AFTER'];
+                }
+            }
+        }
+
+        //Fix for SF#1932083: Multichar Quotemarks unsupported
+        $is_string_starter = array();
+        if ($this->lexic_permissions['STRINGS']) {
+            foreach ($this->language_data['QUOTEMARKS'] as $quotemark) {
+                if (!isset($is_string_starter[$quotemark[0]])) {
+                    $is_string_starter[$quotemark[0]] = (string)$quotemark;
+                } else if (is_string($is_string_starter[$quotemark[0]])) {
+                    $is_string_starter[$quotemark[0]] = array(
+                        $is_string_starter[$quotemark[0]],
+                        $quotemark);
+                } else {
+                    $is_string_starter[$quotemark[0]][] = $quotemark;
+                }
+            }
+        }
+
+        // Now we go through each part. We know that even-indexed parts are
+        // code that shouldn't be highlighted, and odd-indexed parts should
+        // be highlighted
+        for ($key = 0; $key < $num_parts; ++$key) {
+            $STRICTATTRS = '';
+
+            // If this block should be highlighted...
+            if (!($key & 1)) {
+                // Else not a block to highlight
+                $endresult .= $this->hsc($parts[$key][1]);
+                unset($parts[$key]);
+                continue;
+            }
+
+            $result = '';
+            $part = $parts[$key][1];
+
+            $highlight_part = true;
+            if ($this->strict_mode && !is_null($parts[$key][0])) {
+                // get the class key for this block of code
+                $script_key = $parts[$key][0];
+                $highlight_part = $this->language_data['HIGHLIGHT_STRICT_BLOCK'][$script_key];
+                if ($this->language_data['STYLES']['SCRIPT'][$script_key] != '' &&
+                    $this->lexic_permissions['SCRIPT']) {
+                    // Add a span element around the source to
+                    // highlight the overall source block
+                    if (!$this->use_classes &&
+                        $this->language_data['STYLES']['SCRIPT'][$script_key] != '') {
+                        $attributes = ' style="' . $this->language_data['STYLES']['SCRIPT'][$script_key] . '"';
+                    } else {
+                        $attributes = ' class="sc' . $script_key . '"';
+                    }
+                    $result .= "<span$attributes>";
+                    $STRICTATTRS = $attributes;
+                }
+            }
+
+            if ($highlight_part) {
+                // Now, highlight the code in this block. This code
+                // is really the engine of GeSHi (along with the method
+                // parse_non_string_part).
+
+                // cache comment regexps incrementally
+                $next_comment_regexp_key = '';
+                $next_comment_regexp_pos = -1;
+                $next_comment_multi_pos = -1;
+                $next_comment_single_pos = -1;
+                $comment_regexp_cache_per_key = array();
+                $comment_multi_cache_per_key = array();
+                $comment_single_cache_per_key = array();
+                $next_open_comment_multi = '';
+                $next_comment_single_key = '';
+                $escape_regexp_cache_per_key = array();
+                $next_escape_regexp_key = '';
+                $next_escape_regexp_pos = -1;
+
+                $length = strlen($part);
+                for ($i = 0; $i < $length; ++$i) {
+                    // Get the next char
+                    $char = $part[$i];
+                    $char_len = 1;
+
+                    // update regexp comment cache if needed
+                    if (isset($this->language_data['COMMENT_REGEXP']) && $next_comment_regexp_pos < $i) {
+                        $next_comment_regexp_pos = $length;
+                        foreach ($this->language_data['COMMENT_REGEXP'] as $comment_key => $regexp) {
+                            $match_i = false;
+                            if (isset($comment_regexp_cache_per_key[$comment_key]) &&
+                                ($comment_regexp_cache_per_key[$comment_key]['pos'] >= $i ||
+                                 $comment_regexp_cache_per_key[$comment_key]['pos'] === false)) {
+                                // we have already matched something
+                                if ($comment_regexp_cache_per_key[$comment_key]['pos'] === false) {
+                                    // this comment is never matched
+                                    continue;
+                                }
+                                $match_i = $comment_regexp_cache_per_key[$comment_key]['pos'];
+                            } else if (
+                                //This is to allow use of the offset parameter in preg_match and stay as compatible with older PHP versions as possible
+                                (GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $i), $match, PREG_OFFSET_CAPTURE)) ||
+                                (!GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $i))
+                                ) {
+                                $match_i = $match[0][1];
+                                if (GESHI_PHP_PRE_433) {
+                                    $match_i += $i;
+                                }
+
+                                $comment_regexp_cache_per_key[$comment_key] = array(
+                                    'key' => $comment_key,
+                                    'length' => strlen($match[0][0]),
+                                    'pos' => $match_i
+                                );
+                            } else {
+                                $comment_regexp_cache_per_key[$comment_key]['pos'] = false;
+                                continue;
+                            }
+
+                            if ($match_i !== false && $match_i < $next_comment_regexp_pos) {
+                                $next_comment_regexp_pos = $match_i;
+                                $next_comment_regexp_key = $comment_key;
+                                if ($match_i === $i) {
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    $string_started = false;
+
+                    if (isset($is_string_starter[$char])) {
+                        // Possibly the start of a new string ...
+
+                        //Check which starter it was ...
+                        //Fix for SF#1932083: Multichar Quotemarks unsupported
+                        if (is_array($is_string_starter[$char])) {
+                            $char_new = '';
+                            foreach ($is_string_starter[$char] as $testchar) {
+                                if ($testchar === substr($part, $i, strlen($testchar)) &&
+                                    strlen($testchar) > strlen($char_new)) {
+                                    $char_new = $testchar;
+                                    $string_started = true;
+                                }
+                            }
+                            if ($string_started) {
+                                $char = $char_new;
+                            }
+                        } else {
+                            $testchar = $is_string_starter[$char];
+                            if ($testchar === substr($part, $i, strlen($testchar))) {
+                                $char = $testchar;
+                                $string_started = true;
+                            }
+                        }
+                        $char_len = strlen($char);
+                    }
+
+                    if ($string_started && $i != $next_comment_regexp_pos) {
+                        // Hand out the correct style information for this string
+                        $string_key = array_search($char, $this->language_data['QUOTEMARKS']);
+                        if (!isset($this->language_data['STYLES']['STRINGS'][$string_key]) ||
+                            !isset($this->language_data['STYLES']['ESCAPE_CHAR'][$string_key])) {
+                            $string_key = 0;
+                        }
+
+                        // parse the stuff before this
+                        $result .= $this->parse_non_string_part($stuff_to_parse);
+                        $stuff_to_parse = '';
+
+                        if (!$this->use_classes) {
+                            $string_attributes = ' style="' . $this->language_data['STYLES']['STRINGS'][$string_key] . '"';
+                        } else {
+                            $string_attributes = ' class="st'.$string_key.'"';
+                        }
+
+                        // now handle the string
+                        $string = "<span$string_attributes>" . GeSHi::hsc($char);
+                        $start = $i + $char_len;
+                        $string_open = true;
+
+                        if(empty($this->language_data['ESCAPE_REGEXP'])) {
+                            $next_escape_regexp_pos = $length;
+                        }
+
+                        do {
+                            //Get the regular ending pos ...
+                            $close_pos = strpos($part, $char, $start);
+                            if(false === $close_pos) {
+                                $close_pos = $length;
+                            }
+
+                            if($this->lexic_permissions['ESCAPE_CHAR']) {
+                                // update escape regexp cache if needed
+                                if (isset($this->language_data['ESCAPE_REGEXP']) && $next_escape_regexp_pos < $start) {
+                                    $next_escape_regexp_pos = $length;
+                                    foreach ($this->language_data['ESCAPE_REGEXP'] as $escape_key => $regexp) {
+                                        $match_i = false;
+                                        if (isset($escape_regexp_cache_per_key[$escape_key]) &&
+                                            ($escape_regexp_cache_per_key[$escape_key]['pos'] >= $start ||
+                                             $escape_regexp_cache_per_key[$escape_key]['pos'] === false)) {
+                                            // we have already matched something
+                                            if ($escape_regexp_cache_per_key[$escape_key]['pos'] === false) {
+                                                // this comment is never matched
+                                                continue;
+                                            }
+                                            $match_i = $escape_regexp_cache_per_key[$escape_key]['pos'];
+                                        } else if (
+                                            //This is to allow use of the offset parameter in preg_match and stay as compatible with older PHP versions as possible
+                                            (GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $start), $match, PREG_OFFSET_CAPTURE)) ||
+                                            (!GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $start))
+                                            ) {
+                                            $match_i = $match[0][1];
+                                            if (GESHI_PHP_PRE_433) {
+                                                $match_i += $start;
+                                            }
+
+                                            $escape_regexp_cache_per_key[$escape_key] = array(
+                                                'key' => $escape_key,
+                                                'length' => strlen($match[0][0]),
+                                                'pos' => $match_i
+                                            );
+                                        } else {
+                                            $escape_regexp_cache_per_key[$escape_key]['pos'] = false;
+                                            continue;
+                                        }
+
+                                        if ($match_i !== false && $match_i < $next_escape_regexp_pos) {
+                                            $next_escape_regexp_pos = $match_i;
+                                            $next_escape_regexp_key = $escape_key;
+                                            if ($match_i === $start) {
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                //Find the next simple escape position
+                                if('' != $this->language_data['ESCAPE_CHAR']) {
+                                    $simple_escape = strpos($part, $this->language_data['ESCAPE_CHAR'], $start);
+                                    if(false === $simple_escape) {
+                                        $simple_escape = $length;
+                                    }
+                                } else {
+                                    $simple_escape = $length;
+                                }
+                            } else {
+                                $next_escape_regexp_pos = $length;
+                                $simple_escape = $length;
+                            }
+
+                            if($simple_escape < $next_escape_regexp_pos &&
+                                $simple_escape < $length &&
+                                $simple_escape < $close_pos) {
+                                //The nexxt escape sequence is a simple one ...
+                                $es_pos = $simple_escape;
+
+                                //Add the stuff not in the string yet ...
+                                $string .= $this->hsc(substr($part, $start, $es_pos - $start));
+
+                                //Get the style for this escaped char ...
+                                if (!$this->use_classes) {
+                                    $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][0] . '"';
+                                } else {
+                                    $escape_char_attributes = ' class="es0"';
+                                }
+
+                                //Add the style for the escape char ...
+                                $string .= "<span$escape_char_attributes>" .
+                                    GeSHi::hsc($this->language_data['ESCAPE_CHAR']);
+
+                                //Get the byte AFTER the ESCAPE_CHAR we just found
+                                $es_char = $part[$es_pos + 1];
+                                if ($es_char == "\n") {
+                                    // don't put a newline around newlines
+                                    $string .= "</span>\n";
+                                    $start = $es_pos + 2;
+                                } else if (ord($es_char) >= 128) {
+                                    //This is an non-ASCII char (UTF8 or single byte)
+                                    //This code tries to work around SF#2037598 ...
+                                    if(function_exists('mb_substr')) {
+                                        $es_char_m = mb_substr(substr($part, $es_pos+1, 16), 0, 1, $this->encoding);
+                                        $string .= $es_char_m . '</span>';
+                                    } else if (!GESHI_PHP_PRE_433 && 'utf-8' == $this->encoding) {
+                                        if(preg_match("/[\xC2-\xDF][\x80-\xBF]".
+                                            "|\xE0[\xA0-\xBF][\x80-\xBF]".
+                                            "|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}".
+                                            "|\xED[\x80-\x9F][\x80-\xBF]".
+                                            "|\xF0[\x90-\xBF][\x80-\xBF]{2}".
+                                            "|[\xF1-\xF3][\x80-\xBF]{3}".
+                                            "|\xF4[\x80-\x8F][\x80-\xBF]{2}/s",
+                                            $part, $es_char_m, null, $es_pos + 1)) {
+                                            $es_char_m = $es_char_m[0];
+                                        } else {
+                                            $es_char_m = $es_char;
+                                        }
+                                        $string .= $this->hsc($es_char_m) . '</span>';
+                                    } else {
+                                        $es_char_m = $this->hsc($es_char);
+                                    }
+                                    $start = $es_pos + strlen($es_char_m) + 1;
+                                } else {
+                                    $string .= $this->hsc($es_char) . '</span>';
+                                    $start = $es_pos + 2;
+                                }
+                            } else if ($next_escape_regexp_pos < $length &&
+                                $next_escape_regexp_pos < $close_pos) {
+                                $es_pos = $next_escape_regexp_pos;
+                                //Add the stuff not in the string yet ...
+                                $string .= $this->hsc(substr($part, $start, $es_pos - $start));
+
+                                //Get the key and length of this match ...
+                                $escape = $escape_regexp_cache_per_key[$next_escape_regexp_key];
+                                $escape_str = substr($part, $es_pos, $escape['length']);
+                                $escape_key = $escape['key'];
+
+                                //Get the style for this escaped char ...
+                                if (!$this->use_classes) {
+                                    $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][$escape_key] . '"';
+                                } else {
+                                    $escape_char_attributes = ' class="es' . $escape_key . '"';
+                                }
+
+                                //Add the style for the escape char ...
+                                $string .= "<span$escape_char_attributes>" .
+                                    $this->hsc($escape_str) . '</span>';
+
+                                $start = $es_pos + $escape['length'];
+                            } else {
+                                //Copy the remainder of the string ...
+                                $string .= $this->hsc(substr($part, $start, $close_pos - $start + $char_len)) . '</span>';
+                                $start = $close_pos + $char_len;
+                                $string_open = false;
+                            }
+                        } while($string_open);
+
+                        if ($check_linenumbers) {
+                            // Are line numbers used? If, we should end the string before
+                            // the newline and begin it again (so when <li>s are put in the source
+                            // remains XHTML compliant)
+                            // note to self: This opens up possibility of config files specifying
+                            // that languages can/cannot have multiline strings???
+                            $string = str_replace("\n", "</span>\n<span$string_attributes>", $string);
+                        }
+
+                        $result .= $string;
+                        $string = '';
+                        $i = $start - 1;
+                        continue;
+                    } else if ($this->lexic_permissions['STRINGS'] && $hq && $hq[0] == $char &&
+                        substr($part, $i, $hq_strlen) == $hq) {
+                        // The start of a hard quoted string
+                        if (!$this->use_classes) {
+                            $string_attributes = ' style="' . $this->language_data['STYLES']['STRINGS']['HARD'] . '"';
+                            $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR']['HARD'] . '"';
+                        } else {
+                            $string_attributes = ' class="st_h"';
+                            $escape_char_attributes = ' class="es_h"';
+                        }
+                        // parse the stuff before this
+                        $result .= $this->parse_non_string_part($stuff_to_parse);
+                        $stuff_to_parse = '';
+
+                        // now handle the string
+                        $string = '';
+
+                        // look for closing quote
+                        $start = $i + $hq_strlen;
+                        while ($close_pos = strpos($part, $this->language_data['HARDQUOTE'][1], $start)) {
+                            $start = $close_pos + 1;
+                            if ($this->lexic_permissions['ESCAPE_CHAR'] && $part[$close_pos - 1] == $this->language_data['HARDCHAR']) {
+                                // make sure this quote is not escaped
+                                foreach ($this->language_data['HARDESCAPE'] as $hardescape) {
+                                    if (substr($part, $close_pos - 1, strlen($hardescape)) == $hardescape) {
+                                        // check wether this quote is escaped or if it is something like '\\'
+                                        $escape_char_pos = $close_pos - 1;
+                                        while ($escape_char_pos > 0
+                                                && $part[$escape_char_pos - 1] == $this->language_data['HARDCHAR']) {
+                                            --$escape_char_pos;
+                                        }
+                                        if (($close_pos - $escape_char_pos) & 1) {
+                                            // uneven number of escape chars => this quote is escaped
+                                            continue 2;
+                                        }
+                                    }
+                                }
+                            }
+
+                            // found closing quote
+                            break;
+                        }
+
+                        //Found the closing delimiter?
+                        if (!$close_pos) {
+                            // span till the end of this $part when no closing delimiter is found
+                            $close_pos = $length;
+                        }
+
+                        //Get the actual string
+                        $string = substr($part, $i, $close_pos - $i + 1);
+                        $i = $close_pos;
+
+                        // handle escape chars and encode html chars
+                        // (special because when we have escape chars within our string they may not be escaped)
+                        if ($this->lexic_permissions['ESCAPE_CHAR'] && $this->language_data['ESCAPE_CHAR']) {
+                            $start = 0;
+                            $new_string = '';
+                            while ($es_pos = strpos($string, $this->language_data['ESCAPE_CHAR'], $start)) {
+                                // hmtl escape stuff before
+                                $new_string .= $this->hsc(substr($string, $start, $es_pos - $start));
+                                // check if this is a hard escape
+                                foreach ($this->language_data['HARDESCAPE'] as $hardescape) {
+                                    if (substr($string, $es_pos, strlen($hardescape)) == $hardescape) {
+                                        // indeed, this is a hardescape
+                                        $new_string .= "<span$escape_char_attributes>" .
+                                            $this->hsc($hardescape) . '</span>';
+                                        $start = $es_pos + strlen($hardescape);
+                                        continue 2;
+                                    }
+                                }
+                                // not a hard escape, but a normal escape
+                                // they come in pairs of two
+                                $c = 0;
+                                while (isset($string[$es_pos + $c]) && isset($string[$es_pos + $c + 1])
+                                    && $string[$es_pos + $c] == $this->language_data['ESCAPE_CHAR']
+                                    && $string[$es_pos + $c + 1] == $this->language_data['ESCAPE_CHAR']) {
+                                    $c += 2;
+                                }
+                                if ($c) {
+                                    $new_string .= "<span$escape_char_attributes>" .
+                                        str_repeat($escaped_escape_char, $c) .
+                                        '</span>';
+                                    $start = $es_pos + $c;
+                                } else {
+                                    // this is just a single lonely escape char...
+                                    $new_string .= $escaped_escape_char;
+                                    $start = $es_pos + 1;
+                                }
+                            }
+                            $string = $new_string . $this->hsc(substr($string, $start));
+                        } else {
+                            $string = $this->hsc($string);
+                        }
+
+                        if ($check_linenumbers) {
+                            // Are line numbers used? If, we should end the string before
+                            // the newline and begin it again (so when <li>s are put in the source
+                            // remains XHTML compliant)
+                            // note to self: This opens up possibility of config files specifying
+                            // that languages can/cannot have multiline strings???
+                            $string = str_replace("\n", "</span>\n<span$string_attributes>", $string);
+                        }
+
+                        $result .= "<span$string_attributes>" . $string . '</span>';
+                        $string = '';
+                        continue;
+                    } else {
+                        //Have a look for regexp comments
+                        if ($i == $next_comment_regexp_pos) {
+                            $COMMENT_MATCHED = true;
+                            $comment = $comment_regexp_cache_per_key[$next_comment_regexp_key];
+                            $test_str = $this->hsc(substr($part, $i, $comment['length']));
+
+                            //@todo If remove important do remove here
+                            if ($this->lexic_permissions['COMMENTS']['MULTI']) {
+                                if (!$this->use_classes) {
+                                    $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment['key']] . '"';
+                                } else {
+                                    $attributes = ' class="co' . $comment['key'] . '"';
+                                }
+
+                                $test_str = "<span$attributes>" . $test_str . "</span>";
+
+                                // Short-cut through all the multiline code
+                                if ($check_linenumbers) {
+                                    // strreplace to put close span and open span around multiline newlines
+                                    $test_str = str_replace(
+                                        "\n", "</span>\n<span$attributes>",
+                                        str_replace("\n ", "\n&nbsp;", $test_str)
+                                    );
+                                }
+                            }
+
+                            $i += $comment['length'] - 1;
+
+                            // parse the rest
+                            $result .= $this->parse_non_string_part($stuff_to_parse);
+                            $stuff_to_parse = '';
+                        }
+
+                        // If we haven't matched a regexp comment, try multi-line comments
+                        if (!$COMMENT_MATCHED) {
+                            // Is this a multiline comment?
+                            if (!empty($this->language_data['COMMENT_MULTI']) && $next_comment_multi_pos < $i) {
+                                $next_comment_multi_pos = $length;
+                                foreach ($this->language_data['COMMENT_MULTI'] as $open => $close) {
+                                    $match_i = false;
+                                    if (isset($comment_multi_cache_per_key[$open]) &&
+                                        ($comment_multi_cache_per_key[$open] >= $i ||
+                                         $comment_multi_cache_per_key[$open] === false)) {
+                                        // we have already matched something
+                                        if ($comment_multi_cache_per_key[$open] === false) {
+                                            // this comment is never matched
+                                            continue;
+                                        }
+                                        $match_i = $comment_multi_cache_per_key[$open];
+                                    } else if (($match_i = stripos($part, $open, $i)) !== false) {
+                                        $comment_multi_cache_per_key[$open] = $match_i;
+                                    } else {
+                                        $comment_multi_cache_per_key[$open] = false;
+                                        continue;
+                                    }
+                                    if ($match_i !== false && $match_i < $next_comment_multi_pos) {
+                                        $next_comment_multi_pos = $match_i;
+                                        $next_open_comment_multi = $open;
+                                        if ($match_i === $i) {
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                            if ($i == $next_comment_multi_pos) {
+                                $open = $next_open_comment_multi;
+                                $close = $this->language_data['COMMENT_MULTI'][$open];
+                                $open_strlen = strlen($open);
+                                $close_strlen = strlen($close);
+                                $COMMENT_MATCHED = true;
+                                $test_str_match = $open;
+                                //@todo If remove important do remove here
+                                if ($this->lexic_permissions['COMMENTS']['MULTI'] ||
+                                    $open == GESHI_START_IMPORTANT) {
+                                    if ($open != GESHI_START_IMPORTANT) {
+                                        if (!$this->use_classes) {
+                                            $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS']['MULTI'] . '"';
+                                        } else {
+                                            $attributes = ' class="coMULTI"';
+                                        }
+                                        $test_str = "<span$attributes>" . $this->hsc($open);
+                                    } else {
+                                        if (!$this->use_classes) {
+                                            $attributes = ' style="' . $this->important_styles . '"';
+                                        } else {
+                                            $attributes = ' class="imp"';
+                                        }
+
+                                        // We don't include the start of the comment if it's an
+                                        // "important" part
+                                        $test_str = "<span$attributes>";
+                                    }
+                                } else {
+                                    $test_str = $this->hsc($open);
+                                }
+
+                                $close_pos = strpos( $part, $close, $i + $open_strlen );
+
+                                if ($close_pos === false) {
+                                    $close_pos = $length;
+                                }
+
+                                // Short-cut through all the multiline code
+                                $rest_of_comment = $this->hsc(substr($part, $i + $open_strlen, $close_pos - $i - $open_strlen + $close_strlen));
+                                if (($this->lexic_permissions['COMMENTS']['MULTI'] ||
+                                    $test_str_match == GESHI_START_IMPORTANT) &&
+                                    $check_linenumbers) {
+
+                                    // strreplace to put close span and open span around multiline newlines
+                                    $test_str .= str_replace(
+                                        "\n", "</span>\n<span$attributes>",
+                                        str_replace("\n ", "\n&nbsp;", $rest_of_comment)
+                                    );
+                                } else {
+                                    $test_str .= $rest_of_comment;
+                                }
+
+                                if ($this->lexic_permissions['COMMENTS']['MULTI'] ||
+                                    $test_str_match == GESHI_START_IMPORTANT) {
+                                    $test_str .= '</span>';
+                                }
+
+                                $i = $close_pos + $close_strlen - 1;
+
+                                // parse the rest
+                                $result .= $this->parse_non_string_part($stuff_to_parse);
+                                $stuff_to_parse = '';
+                            }
+                        }
+
+                        // If we haven't matched a multiline comment, try single-line comments
+                        if (!$COMMENT_MATCHED) {
+                            // cache potential single line comment occurances
+                            if (!empty($this->language_data['COMMENT_SINGLE']) && $next_comment_single_pos < $i) {
+                                $next_comment_single_pos = $length;
+                                foreach ($this->language_data['COMMENT_SINGLE'] as $comment_key => $comment_mark) {
+                                    $match_i = false;
+                                    if (isset($comment_single_cache_per_key[$comment_key]) &&
+                                        ($comment_single_cache_per_key[$comment_key] >= $i ||
+                                         $comment_single_cache_per_key[$comment_key] === false)) {
+                                        // we have already matched something
+                                        if ($comment_single_cache_per_key[$comment_key] === false) {
+                                            // this comment is never matched
+                                            continue;
+                                        }
+                                        $match_i = $comment_single_cache_per_key[$comment_key];
+                                    } else if (
+                                        // case sensitive comments
+                                        ($this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS] &&
+                                        ($match_i = stripos($part, $comment_mark, $i)) !== false) ||
+                                        // non case sensitive
+                                        (!$this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS] &&
+                                          (($match_i = strpos($part, $comment_mark, $i)) !== false))) {
+                                        $comment_single_cache_per_key[$comment_key] = $match_i;
+                                    } else {
+                                        $comment_single_cache_per_key[$comment_key] = false;
+                                        continue;
+                                    }
+                                    if ($match_i !== false && $match_i < $next_comment_single_pos) {
+                                        $next_comment_single_pos = $match_i;
+                                        $next_comment_single_key = $comment_key;
+                                        if ($match_i === $i) {
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                            if ($next_comment_single_pos == $i) {
+                                $comment_key = $next_comment_single_key;
+                                $comment_mark = $this->language_data['COMMENT_SINGLE'][$comment_key];
+                                $com_len = strlen($comment_mark);
+
+                                // This check will find special variables like $# in bash
+                                // or compiler directives of Delphi beginning {$
+                                if ((empty($sc_disallowed_before) || ($i == 0) ||
+                                    (false === strpos($sc_disallowed_before, $part[$i-1]))) &&
+                                    (empty($sc_disallowed_after) || ($length <= $i + $com_len) ||
+                                    (false === strpos($sc_disallowed_after, $part[$i + $com_len]))))
+                                {
+                                    // this is a valid comment
+                                    $COMMENT_MATCHED = true;
+                                    if ($this->lexic_permissions['COMMENTS'][$comment_key]) {
+                                        if (!$this->use_classes) {
+                                            $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment_key] . '"';
+                                        } else {
+                                            $attributes = ' class="co' . $comment_key . '"';
+                                        }
+                                        $test_str = "<span$attributes>" . $this->hsc($this->change_case($comment_mark));
+                                    } else {
+                                        $test_str = $this->hsc($comment_mark);
+                                    }
+
+                                    //Check if this comment is the last in the source
+                                    $close_pos = strpos($part, "\n", $i);
+                                    $oops = false;
+                                    if ($close_pos === false) {
+                                        $close_pos = $length;
+                                        $oops = true;
+                                    }
+                                    $test_str .= $this->hsc(substr($part, $i + $com_len, $close_pos - $i - $com_len));
+                                    if ($this->lexic_permissions['COMMENTS'][$comment_key]) {
+                                        $test_str .= "</span>";
+                                    }
+
+                                    // Take into account that the comment might be the last in the source
+                                    if (!$oops) {
+                                      $test_str .= "\n";
+                                    }
+
+                                    $i = $close_pos;
+
+                                    // parse the rest
+                                    $result .= $this->parse_non_string_part($stuff_to_parse);
+                                    $stuff_to_parse = '';
+                                }
+                            }
+                        }
+                    }
+
+                    // Where are we adding this char?
+                    if (!$COMMENT_MATCHED) {
+                        $stuff_to_parse .= $char;
+                    } else {
+                        $result .= $test_str;
+                        unset($test_str);
+                        $COMMENT_MATCHED = false;
+                    }
+                }
+                // Parse the last bit
+                $result .= $this->parse_non_string_part($stuff_to_parse);
+                $stuff_to_parse = '';
+            } else {
+                $result .= $this->hsc($part);
+            }
+            // Close the <span> that surrounds the block
+            if ($STRICTATTRS != '') {
+                $result = str_replace("\n", "</span>\n<span$STRICTATTRS>", $result);
+                $result .= '</span>';
+            }
+
+            $endresult .= $result;
+            unset($part, $parts[$key], $result);
+        }
+
+        //This fix is related to SF#1923020, but has to be applied regardless of
+        //actually highlighting symbols.
+        /** NOTE: memorypeak #3 */
+        $endresult = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $endresult);
+
+//        // Parse the last stuff (redundant?)
+//        $result .= $this->parse_non_string_part($stuff_to_parse);
+
+        // Lop off the very first and last spaces
+//        $result = substr($result, 1, -1);
+
+        // We're finished: stop timing
+        $this->set_time($start_time, microtime());
+
+        $this->finalise($endresult);
+        return $endresult;
+    }
+
+    /**
+     * Swaps out spaces and tabs for HTML indentation. Not needed if
+     * the code is in a pre block...
+     *
+     * @param  string The source to indent (reference!)
+     * @since  1.0.0
+     * @access private
+     */
+    function indent(&$result) {
+        /// Replace tabs with the correct number of spaces
+        if (false !== strpos($result, "\t")) {
+            $lines = explode("\n", $result);
+            $result = null;//Save memory while we process the lines individually
+            $tab_width = $this->get_real_tab_width();
+            $tab_string = '&nbsp;' . str_repeat(' ', $tab_width);
+
+            for ($key = 0, $n = count($lines); $key < $n; $key++) {
+                $line = $lines[$key];
+                if (false === strpos($line, "\t")) {
+                    continue;
+                }
+
+                $pos = 0;
+                $length = strlen($line);
+                $lines[$key] = ''; // reduce memory
+
+                $IN_TAG = false;
+                for ($i = 0; $i < $length; ++$i) {
+                    $char = $line[$i];
+                    // Simple engine to work out whether we're in a tag.
+                    // If we are we modify $pos. This is so we ignore HTML
+                    // in the line and only workout the tab replacement
+                    // via the actual content of the string
+                    // This test could be improved to include strings in the
+                    // html so that < or > would be allowed in user's styles
+                    // (e.g. quotes: '<' '>'; or similar)
+                    if ($IN_TAG) {
+                        if ('>' == $char) {
+                            $IN_TAG = false;
+                        }
+                        $lines[$key] .= $char;
+                    } else if ('<' == $char) {
+                        $IN_TAG = true;
+                        $lines[$key] .= '<';
+                    } else if ('&' == $char) {
+                        $substr = substr($line, $i + 3, 5);
+                        $posi = strpos($substr, ';');
+                        if (false === $posi) {
+                            ++$pos;
+                        } else {
+                            $pos -= $posi+2;
+                        }
+                        $lines[$key] .= $char;
+                    } else if ("\t" == $char) {
+                        $str = '';
+                        // OPTIMISE - move $strs out. Make an array:
+                        // $tabs = array(
+                        //  1 => '&nbsp;',
+                        //  2 => '&nbsp; ',
+                        //  3 => '&nbsp; &nbsp;' etc etc
+                        // to use instead of building a string every time
+                        $tab_end_width = $tab_width - ($pos % $tab_width); //Moved out of the look as it doesn't change within the loop
+                        if (($pos & 1) || 1 == $tab_end_width) {
+                            $str .= substr($tab_string, 6, $tab_end_width);
+                        } else {
+                            $str .= substr($tab_string, 0, $tab_end_width+5);
+                        }
+                        $lines[$key] .= $str;
+                        $pos += $tab_end_width;
+
+                        if (false === strpos($line, "\t", $i + 1)) {
+                            $lines[$key] .= substr($line, $i + 1);
+                            break;
+                        }
+                    } else if (0 == $pos && ' ' == $char) {
+                        $lines[$key] .= '&nbsp;';
+                        ++$pos;
+                    } else {
+                        $lines[$key] .= $char;
+                        ++$pos;
+                    }
+                }
+            }
+            $result = implode("\n", $lines);
+            unset($lines);//We don't need the lines separated beyond this --- free them!
+        }
+        // Other whitespace
+        // BenBE: Fix to reduce the number of replacements to be done
+        $result = preg_replace('/^ /m', '&nbsp;', $result);
+        $result = str_replace('  ', ' &nbsp;', $result);
+
+        if ($this->line_numbers == GESHI_NO_LINE_NUMBERS) {
+            if ($this->line_ending === null) {
+                $result = nl2br($result);
+            } else {
+                $result = str_replace("\n", $this->line_ending, $result);
+            }
+        }
+    }
+
+    /**
+     * Changes the case of a keyword for those languages where a change is asked for
+     *
+     * @param  string The keyword to change the case of
+     * @return string The keyword with its case changed
+     * @since  1.0.0
+     * @access private
+     */
+    function change_case($instr) {
+        switch ($this->language_data['CASE_KEYWORDS']) {
+            case GESHI_CAPS_UPPER:
+                return strtoupper($instr);
+            case GESHI_CAPS_LOWER:
+                return strtolower($instr);
+            default:
+                return $instr;
+        }
+    }
+
+    /**
+     * Handles replacements of keywords to include markup and links if requested
+     *
+     * @param  string The keyword to add the Markup to
+     * @return The HTML for the match found
+     * @since  1.0.8
+     * @access private
+     *
+     * @todo   Get rid of ender in keyword links
+     */
+    function handle_keyword_replace($match) {
+        $k = $this->_kw_replace_group;
+        $keyword = $match[0];
+
+        $before = '';
+        $after = '';
+
+        if ($this->keyword_links) {
+            // Keyword links have been ebabled
+
+            if (isset($this->language_data['URLS'][$k]) &&
+                $this->language_data['URLS'][$k] != '') {
+                // There is a base group for this keyword
+
+                // Old system: strtolower
+                //$keyword = ( $this->language_data['CASE_SENSITIVE'][$group] ) ? $keyword : strtolower($keyword);
+                // New system: get keyword from language file to get correct case
+                if (!$this->language_data['CASE_SENSITIVE'][$k] &&
+                    strpos($this->language_data['URLS'][$k], '{FNAME}') !== false) {
+                    foreach ($this->language_data['KEYWORDS'][$k] as $word) {
+                        if (strcasecmp($word, $keyword) == 0) {
+                            break;
+                        }
+                    }
+                } else {
+                    $word = $keyword;
+                }
+
+                $before = '<|UR1|"' .
+                    str_replace(
+                        array(
+                            '{FNAME}',
+                            '{FNAMEL}',
+                            '{FNAMEU}',
+                            '.'),
+                        array(
+                            str_replace('+', '%20', urlencode($this->hsc($word))),
+                            str_replace('+', '%20', urlencode($this->hsc(strtolower($word)))),
+                            str_replace('+', '%20', urlencode($this->hsc(strtoupper($word)))),
+                            '<DOT>'),
+                        $this->language_data['URLS'][$k]
+                    ) . '">';
+                $after = '</a>';
+            }
+        }
+
+        return $before . '<|/'. $k .'/>' . $this->change_case($keyword) . '|>' . $after;
+    }
+
+    /**
+     * handles regular expressions highlighting-definitions with callback functions
+     *
+     * @note this is a callback, don't use it directly
+     *
+     * @param array the matches array
+     * @return The highlighted string
+     * @since 1.0.8
+     * @access private
+     */
+    function handle_regexps_callback($matches) {
+        // before: "' style=\"' . call_user_func(\"$func\", '\\1') . '\"\\1|>'",
+        return  ' style="' . call_user_func($this->language_data['STYLES']['REGEXPS'][$this->_rx_key], $matches[1]) . '"'. $matches[1] . '|>';
+    }
+
+    /**
+     * handles newlines in REGEXPS matches. Set the _hmr_* vars before calling this
+     *
+     * @note this is a callback, don't use it directly
+     *
+     * @param array the matches array
+     * @return string
+     * @since 1.0.8
+     * @access private
+     */
+    function handle_multiline_regexps($matches) {
+        $before = $this->_hmr_before;
+        $after = $this->_hmr_after;
+        if ($this->_hmr_replace) {
+            $replace = $this->_hmr_replace;
+            $search = array();
+
+            foreach (array_keys($matches) as $k) {
+                $search[] = '\\' . $k;
+            }
+
+            $before = str_replace($search, $matches, $before);
+            $after = str_replace($search, $matches, $after);
+            $replace = str_replace($search, $matches, $replace);
+        } else {
+            $replace = $matches[0];
+        }
+        return $before
+                    . '<|!REG3XP' . $this->_hmr_key .'!>'
+                        . str_replace("\n", "|>\n<|!REG3XP" . $this->_hmr_key . '!>', $replace)
+                    . '|>'
+              . $after;
+    }
+
+    /**
+     * Takes a string that has no strings or comments in it, and highlights
+     * stuff like keywords, numbers and methods.
+     *
+     * @param string The string to parse for keyword, numbers etc.
+     * @since 1.0.0
+     * @access private
+     * @todo BUGGY! Why? Why not build string and return?
+     */
+    function parse_non_string_part($stuff_to_parse) {
+        $stuff_to_parse = ' ' . $this->hsc($stuff_to_parse);
+
+        // Regular expressions
+        foreach ($this->language_data['REGEXPS'] as $key => $regexp) {
+            if ($this->lexic_permissions['REGEXPS'][$key]) {
+                if (is_array($regexp)) {
+                    if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                        // produce valid HTML when we match multiple lines
+                        $this->_hmr_replace = $regexp[GESHI_REPLACE];
+                        $this->_hmr_before = $regexp[GESHI_BEFORE];
+                        $this->_hmr_key = $key;
+                        $this->_hmr_after = $regexp[GESHI_AFTER];
+                        $stuff_to_parse = preg_replace_callback(
+                            "/" . $regexp[GESHI_SEARCH] . "/{$regexp[GESHI_MODIFIERS]}",
+                            array($this, 'handle_multiline_regexps'),
+                            $stuff_to_parse);
+                        $this->_hmr_replace = false;
+                        $this->_hmr_before = '';
+                        $this->_hmr_after = '';
+                    } else {
+                        $stuff_to_parse = preg_replace(
+                            '/' . $regexp[GESHI_SEARCH] . '/' . $regexp[GESHI_MODIFIERS],
+                            $regexp[GESHI_BEFORE] . '<|!REG3XP'. $key .'!>' . $regexp[GESHI_REPLACE] . '|>' . $regexp[GESHI_AFTER],
+                            $stuff_to_parse);
+                    }
+                } else {
+                    if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                        // produce valid HTML when we match multiple lines
+                        $this->_hmr_key = $key;
+                        $stuff_to_parse = preg_replace_callback( "/(" . $regexp . ")/",
+                                              array($this, 'handle_multiline_regexps'), $stuff_to_parse);
+                        $this->_hmr_key = '';
+                    } else {
+                        $stuff_to_parse = preg_replace( "/(" . $regexp . ")/", "<|!REG3XP$key!>\\1|>", $stuff_to_parse);
+                    }
+                }
+            }
+        }
+
+        // Highlight numbers. As of 1.0.8 we support diffent types of numbers
+        $numbers_found = false;
+        if ($this->lexic_permissions['NUMBERS'] && preg_match('#\d#', $stuff_to_parse )) {
+            $numbers_found = true;
+
+            //For each of the formats ...
+            foreach($this->language_data['NUMBERS_RXCACHE'] as $id => $regexp) {
+                //Check if it should be highlighted ...
+                $stuff_to_parse = preg_replace($regexp, "<|/NUM!$id/>\\1|>", $stuff_to_parse);
+            }
+        }
+
+        // Highlight keywords
+        $disallowed_before = "(?<![a-zA-Z0-9\$_\|\#;>|^&";
+        $disallowed_after = "(?![a-zA-Z0-9_\|%\\-&;";
+        if ($this->lexic_permissions['STRINGS']) {
+            $quotemarks = preg_quote(implode($this->language_data['QUOTEMARKS']), '/');
+            $disallowed_before .= $quotemarks;
+            $disallowed_after .= $quotemarks;
+        }
+        $disallowed_before .= "])";
+        $disallowed_after .= "])";
+
+        $parser_control_pergroup = false;
+        if (isset($this->language_data['PARSER_CONTROL'])) {
+            if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'])) {
+                $x = 0; // check wether per-keyword-group parser_control is enabled
+                if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'])) {
+                    $disallowed_before = $this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
+                    ++$x;
+                }
+                if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'])) {
+                    $disallowed_after = $this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
+                    ++$x;
+                }
+                $parser_control_pergroup = (count($this->language_data['PARSER_CONTROL']['KEYWORDS']) - $x) > 0;
+            }
+        }
+
+        // if this is changed, don't forget to change it below
+//        if (!empty($disallowed_before)) {
+//            $disallowed_before = "(?<![$disallowed_before])";
+//        }
+//        if (!empty($disallowed_after)) {
+//            $disallowed_after = "(?![$disallowed_after])";
+//        }
+
+        foreach (array_keys($this->language_data['KEYWORDS']) as $k) {
+            if (!isset($this->lexic_permissions['KEYWORDS'][$k]) ||
+                $this->lexic_permissions['KEYWORDS'][$k]) {
+
+                $case_sensitive = $this->language_data['CASE_SENSITIVE'][$k];
+                $modifiers = $case_sensitive ? '' : 'i';
+
+                // NEW in 1.0.8 - per-keyword-group parser control
+                $disallowed_before_local = $disallowed_before;
+                $disallowed_after_local = $disallowed_after;
+                if ($parser_control_pergroup && isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k])) {
+                    if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_BEFORE'])) {
+                        $disallowed_before_local =
+                            $this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_BEFORE'];
+                    }
+
+                    if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_AFTER'])) {
+                        $disallowed_after_local =
+                            $this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_AFTER'];
+                    }
+                }
+
+                $this->_kw_replace_group = $k;
+
+                //NEW in 1.0.8, the cached regexp list
+                // since we don't want PHP / PCRE to crash due to too large patterns we split them into smaller chunks
+                for ($set = 0, $set_length = count($this->language_data['CACHED_KEYWORD_LISTS'][$k]); $set <  $set_length; ++$set) {
+                    $keywordset =& $this->language_data['CACHED_KEYWORD_LISTS'][$k][$set];
+                    // Might make a more unique string for putting the number in soon
+                    // Basically, we don't put the styles in yet because then the styles themselves will
+                    // get highlighted if the language has a CSS keyword in it (like CSS, for example ;))
+                    $stuff_to_parse = preg_replace_callback(
+                        "/$disallowed_before_local({$keywordset})(?!\<DOT\>(?:htm|php))$disallowed_after_local/$modifiers",
+                        array($this, 'handle_keyword_replace'),
+                        $stuff_to_parse
+                        );
+                }
+            }
+        }
+
+        //
+        // Now that's all done, replace /[number]/ with the correct styles
+        //
+        foreach (array_keys($this->language_data['KEYWORDS']) as $k) {
+            if (!$this->use_classes) {
+                $attributes = ' style="' .
+                    (isset($this->language_data['STYLES']['KEYWORDS'][$k]) ?
+                    $this->language_data['STYLES']['KEYWORDS'][$k] : "") . '"';
+            } else {
+                $attributes = ' class="kw' . $k . '"';
+            }
+            $stuff_to_parse = str_replace("<|/$k/>", "<|$attributes>", $stuff_to_parse);
+        }
+
+        if ($numbers_found) {
+            // Put number styles in
+            foreach($this->language_data['NUMBERS_RXCACHE'] as $id => $regexp) {
+//Commented out for now, as this needs some review ...
+//                if ($numbers_permissions & $id) {
+                    //Get the appropriate style ...
+                        //Checking for unset styles is done by the style cache builder ...
+                    if (!$this->use_classes) {
+                        $attributes = ' style="' . $this->language_data['STYLES']['NUMBERS'][$id] . '"';
+                    } else {
+                        $attributes = ' class="nu'.$id.'"';
+                    }
+
+                    //Set in the correct styles ...
+                    $stuff_to_parse = str_replace("/NUM!$id/", $attributes, $stuff_to_parse);
+//                }
+            }
+        }
+
+        // Highlight methods and fields in objects
+        if ($this->lexic_permissions['METHODS'] && $this->language_data['OOLANG']) {
+            $oolang_spaces = "[\s]*";
+            $oolang_before = "";
+            $oolang_after = "[a-zA-Z][a-zA-Z0-9_]*";
+            if (isset($this->language_data['PARSER_CONTROL'])) {
+                if (isset($this->language_data['PARSER_CONTROL']['OOLANG'])) {
+                    if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_BEFORE'])) {
+                        $oolang_before = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_BEFORE'];
+                    }
+                    if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_AFTER'])) {
+                        $oolang_after = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_AFTER'];
+                    }
+                    if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_SPACES'])) {
+                        $oolang_spaces = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_SPACES'];
+                    }
+                }
+            }
+
+            foreach ($this->language_data['OBJECT_SPLITTERS'] as $key => $splitter) {
+                if (false !== strpos($stuff_to_parse, $splitter)) {
+                    if (!$this->use_classes) {
+                        $attributes = ' style="' . $this->language_data['STYLES']['METHODS'][$key] . '"';
+                    } else {
+                        $attributes = ' class="me' . $key . '"';
+                    }
+                    $stuff_to_parse = preg_replace("/($oolang_before)(" . preg_quote($this->language_data['OBJECT_SPLITTERS'][$key], '/') . ")($oolang_spaces)($oolang_after)/", "\\1\\2\\3<|$attributes>\\4|>", $stuff_to_parse);
+                }
+            }
+        }
+
+        //
+        // Highlight brackets. Yes, I've tried adding a semi-colon to this list.
+        // You try it, and see what happens ;)
+        // TODO: Fix lexic permissions not converting entities if shouldn't
+        // be highlighting regardless
+        //
+        if ($this->lexic_permissions['BRACKETS']) {
+            $stuff_to_parse = str_replace( $this->language_data['CACHE_BRACKET_MATCH'],
+                              $this->language_data['CACHE_BRACKET_REPLACE'], $stuff_to_parse );
+        }
+
+
+        //FIX for symbol highlighting ...
+        if ($this->lexic_permissions['SYMBOLS'] && !empty($this->language_data['SYMBOLS'])) {
+            //Get all matches and throw away those witin a block that is already highlighted... (i.e. matched by a regexp)
+            $n_symbols = preg_match_all("/<\|(?:<DOT>|[^>])+>(?:(?!\|>).*?)\|>|<\/a>|(?:" . $this->language_data['SYMBOL_SEARCH'] . ")+/", $stuff_to_parse, $pot_symbols, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+            $global_offset = 0;
+            for ($s_id = 0; $s_id < $n_symbols; ++$s_id) {
+                $symbol_match = $pot_symbols[$s_id][0][0];
+                if (strpos($symbol_match, '<') !== false || strpos($symbol_match, '>') !== false) {
+                    // already highlighted blocks _must_ include either < or >
+                    // so if this conditional applies, we have to skip this match
+                    // BenBE: UNLESS the block contains <SEMI> or <PIPE>
+                    if(strpos($symbol_match, '<SEMI>') === false &&
+                        strpos($symbol_match, '<PIPE>') === false) {
+                        continue;
+                    }
+                }
+
+                // if we reach this point, we have a valid match which needs to be highlighted
+
+                $symbol_length = strlen($symbol_match);
+                $symbol_offset = $pot_symbols[$s_id][0][1];
+                unset($pot_symbols[$s_id]);
+                $symbol_end = $symbol_length + $symbol_offset;
+                $symbol_hl = "";
+
+                // if we have multiple styles, we have to handle them properly
+                if ($this->language_data['MULTIPLE_SYMBOL_GROUPS']) {
+                    $old_sym = -1;
+                    // Split the current stuff to replace into its atomic symbols ...
+                    preg_match_all("/" . $this->language_data['SYMBOL_SEARCH'] . "/", $symbol_match, $sym_match_syms, PREG_PATTERN_ORDER);
+                    foreach ($sym_match_syms[0] as $sym_ms) {
+                        //Check if consequtive symbols belong to the same group to save output ...
+                        if (isset($this->language_data['SYMBOL_DATA'][$sym_ms])
+                            && ($this->language_data['SYMBOL_DATA'][$sym_ms] != $old_sym)) {
+                            if (-1 != $old_sym) {
+                                $symbol_hl .= "|>";
+                            }
+                            $old_sym = $this->language_data['SYMBOL_DATA'][$sym_ms];
+                            if (!$this->use_classes) {
+                                $symbol_hl .= '<| style="' . $this->language_data['STYLES']['SYMBOLS'][$old_sym] . '">';
+                            } else {
+                                $symbol_hl .= '<| class="sy' . $old_sym . '">';
+                            }
+                        }
+                        $symbol_hl .= $sym_ms;
+                    }
+                    unset($sym_match_syms);
+
+                    //Close remaining tags and insert the replacement at the right position ...
+                    //Take caution if symbol_hl is empty to avoid doubled closing spans.
+                    if (-1 != $old_sym) {
+                        $symbol_hl .= "|>";
+                    }
+                } else {
+                    if (!$this->use_classes) {
+                        $symbol_hl = '<| style="' . $this->language_data['STYLES']['SYMBOLS'][0] . '">';
+                    } else {
+                        $symbol_hl = '<| class="sy0">';
+                    }
+                    $symbol_hl .= $symbol_match . '|>';
+                }
+
+                $stuff_to_parse = substr_replace($stuff_to_parse, $symbol_hl, $symbol_offset + $global_offset, $symbol_length);
+
+                // since we replace old text with something of different size,
+                // we'll have to keep track of the differences
+                $global_offset += strlen($symbol_hl) - $symbol_length;
+            }
+        }
+        //FIX for symbol highlighting ...
+
+        // Add class/style for regexps
+        foreach (array_keys($this->language_data['REGEXPS']) as $key) {
+            if ($this->lexic_permissions['REGEXPS'][$key]) {
+                if (is_callable($this->language_data['STYLES']['REGEXPS'][$key])) {
+                    $this->_rx_key = $key;
+                    $stuff_to_parse = preg_replace_callback("/!REG3XP$key!(.*)\|>/U",
+                        array($this, 'handle_regexps_callback'),
+                        $stuff_to_parse);
+                } else {
+                    if (!$this->use_classes) {
+                        $attributes = ' style="' . $this->language_data['STYLES']['REGEXPS'][$key] . '"';
+                    } else {
+                        if (is_array($this->language_data['REGEXPS'][$key]) &&
+                            array_key_exists(GESHI_CLASS, $this->language_data['REGEXPS'][$key])) {
+                            $attributes = ' class="' .
+                                $this->language_data['REGEXPS'][$key][GESHI_CLASS] . '"';
+                        } else {
+                           $attributes = ' class="re' . $key . '"';
+                        }
+                    }
+                    $stuff_to_parse = str_replace("!REG3XP$key!", "$attributes", $stuff_to_parse);
+                }
+            }
+        }
+
+        // Replace <DOT> with . for urls
+        $stuff_to_parse = str_replace('<DOT>', '.', $stuff_to_parse);
+        // Replace <|UR1| with <a href= for urls also
+        if (isset($this->link_styles[GESHI_LINK])) {
+            if ($this->use_classes) {
+                $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' href=', $stuff_to_parse);
+            } else {
+                $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' style="' . $this->link_styles[GESHI_LINK] . '" href=', $stuff_to_parse);
+            }
+        } else {
+            $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' href=', $stuff_to_parse);
+        }
+
+        //
+        // NOW we add the span thingy ;)
+        //
+
+        $stuff_to_parse = str_replace('<|', '<span', $stuff_to_parse);
+        $stuff_to_parse = str_replace ( '|>', '</span>', $stuff_to_parse );
+        return substr($stuff_to_parse, 1);
+    }
+
+    /**
+     * Sets the time taken to parse the code
+     *
+     * @param microtime The time when parsing started
+     * @param microtime The time when parsing ended
+     * @since 1.0.2
+     * @access private
+     */
+    function set_time($start_time, $end_time) {
+        $start = explode(' ', $start_time);
+        $end = explode(' ', $end_time);
+        $this->time = $end[0] + $end[1] - $start[0] - $start[1];
+    }
+
+    /**
+     * Gets the time taken to parse the code
+     *
+     * @return double The time taken to parse the code
+     * @since  1.0.2
+     */
+    function get_time() {
+        return $this->time;
+    }
+
+    /**
+     * Merges arrays recursively, overwriting values of the first array with values of later arrays
+     *
+     * @since 1.0.8
+     * @access private
+     */
+    function merge_arrays() {
+        $arrays = func_get_args();
+        $narrays = count($arrays);
+
+        // check arguments
+        // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array)
+        for ($i = 0; $i < $narrays; $i ++) {
+            if (!is_array($arrays[$i])) {
+                // also array_merge_recursive returns nothing in this case
+                trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning false!', E_USER_WARNING);
+                return false;
+            }
+        }
+
+        // the first array is in the output set in every case
+        $ret = $arrays[0];
+
+        // merege $ret with the remaining arrays
+        for ($i = 1; $i < $narrays; $i ++) {
+            foreach ($arrays[$i] as $key => $value) {
+                if (is_array($value) && isset($ret[$key])) {
+                    // if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays)
+                    // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be false.
+                    $ret[$key] = $this->merge_arrays($ret[$key], $value);
+                } else {
+                    $ret[$key] = $value;
+                }
+            }
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Gets language information and stores it for later use
+     *
+     * @param string The filename of the language file you want to load
+     * @since 1.0.0
+     * @access private
+     * @todo Needs to load keys for lexic permissions for keywords, regexps etc
+     */
+    function load_language($file_name) {
+        if ($file_name == $this->loaded_language) {
+            // this file is already loaded!
+            return;
+        }
+
+        //Prepare some stuff before actually loading the language file
+        $this->loaded_language = $file_name;
+        $this->parse_cache_built = false;
+        $this->enable_highlighting();
+        $language_data = array();
+
+        //Load the language file
+        require $file_name;
+
+        // Perhaps some checking might be added here later to check that
+        // $language data is a valid thing but maybe not
+        $this->language_data = $language_data;
+
+        // Set strict mode if should be set
+        $this->strict_mode = $this->language_data['STRICT_MODE_APPLIES'];
+
+        // Set permissions for all lexics to true
+        // so they'll be highlighted by default
+        foreach (array_keys($this->language_data['KEYWORDS']) as $key) {
+            if (!empty($this->language_data['KEYWORDS'][$key])) {
+                $this->lexic_permissions['KEYWORDS'][$key] = true;
+            } else {
+                $this->lexic_permissions['KEYWORDS'][$key] = false;
+            }
+        }
+
+        foreach (array_keys($this->language_data['COMMENT_SINGLE']) as $key) {
+            $this->lexic_permissions['COMMENTS'][$key] = true;
+        }
+        foreach (array_keys($this->language_data['REGEXPS']) as $key) {
+            $this->lexic_permissions['REGEXPS'][$key] = true;
+        }
+
+        // for BenBE and future code reviews:
+        // we can use empty here since we only check for existance and emptiness of an array
+        // if it is not an array at all but rather false or null this will work as intended as well
+        // even if $this->language_data['PARSER_CONTROL'] is undefined this won't trigger a notice
+        if (!empty($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS'])) {
+            foreach ($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS'] as $flag => $value) {
+                // it's either true or false and maybe is true as well
+                $perm = $value !== GESHI_NEVER;
+                if ($flag == 'ALL') {
+                    $this->enable_highlighting($perm);
+                    continue;
+                }
+                if (!isset($this->lexic_permissions[$flag])) {
+                    // unknown lexic permission
+                    continue;
+                }
+                if (is_array($this->lexic_permissions[$flag])) {
+                    foreach ($this->lexic_permissions[$flag] as $key => $val) {
+                        $this->lexic_permissions[$flag][$key] = $perm;
+                    }
+                } else {
+                    $this->lexic_permissions[$flag] = $perm;
+                }
+            }
+            unset($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS']);
+        }
+
+        //Fix: Problem where hardescapes weren't handled if no ESCAPE_CHAR was given
+        //You need to set one for HARDESCAPES only in this case.
+        if(!isset($this->language_data['HARDCHAR'])) {
+            $this->language_data['HARDCHAR'] = $this->language_data['ESCAPE_CHAR'];
+        }
+
+        //NEW in 1.0.8: Allow styles to be loaded from a separate file to override defaults
+        $style_filename = substr($file_name, 0, -4) . '.style.php';
+        if (is_readable($style_filename)) {
+            //Clear any style_data that could have been set before ...
+            if (isset($style_data)) {
+                unset($style_data);
+            }
+
+            //Read the Style Information from the style file
+            include $style_filename;
+
+            //Apply the new styles to our current language styles
+            if (isset($style_data) && is_array($style_data)) {
+                $this->language_data['STYLES'] =
+                    $this->merge_arrays($this->language_data['STYLES'], $style_data);
+            }
+        }
+    }
+
+    /**
+     * Takes the parsed code and various options, and creates the HTML
+     * surrounding it to make it look nice.
+     *
+     * @param  string The code already parsed (reference!)
+     * @since  1.0.0
+     * @access private
+     */
+    function finalise(&$parsed_code) {
+        // Remove end parts of important declarations
+        // This is BUGGY!! My fault for bad code: fix coming in 1.2
+        // @todo Remove this crap
+        if ($this->enable_important_blocks &&
+            (strpos($parsed_code, $this->hsc(GESHI_START_IMPORTANT)) === false)) {
+            $parsed_code = str_replace($this->hsc(GESHI_END_IMPORTANT), '', $parsed_code);
+        }
+
+        // Add HTML whitespace stuff if we're using the <div> header
+        if ($this->header_type != GESHI_HEADER_PRE && $this->header_type != GESHI_HEADER_PRE_VALID) {
+            $this->indent($parsed_code);
+        }
+
+        // purge some unnecessary stuff
+        /** NOTE: memorypeak #1 */
+        $parsed_code = preg_replace('#<span[^>]+>(\s*)</span>#', '\\1', $parsed_code);
+
+        // If we are using IDs for line numbers, there needs to be an overall
+        // ID set to prevent collisions.
+        if ($this->add_ids && !$this->overall_id) {
+            $this->overall_id = 'geshi-' . substr(md5(microtime()), 0, 4);
+        }
+
+        // Get code into lines
+        /** NOTE: memorypeak #2 */
+        $code = explode("\n", $parsed_code);
+        $parsed_code = $this->header();
+
+        // If we're using line numbers, we insert <li>s and appropriate
+        // markup to style them (otherwise we don't need to do anything)
+        if ($this->line_numbers != GESHI_NO_LINE_NUMBERS && $this->header_type != GESHI_HEADER_PRE_TABLE) {
+            // If we're using the <pre> header, we shouldn't add newlines because
+            // the <pre> will line-break them (and the <li>s already do this for us)
+            $ls = ($this->header_type != GESHI_HEADER_PRE && $this->header_type != GESHI_HEADER_PRE_VALID) ? "\n" : '';
+
+            // Set vars to defaults for following loop
+            $i = 0;
+
+            // Foreach line...
+            for ($i = 0, $n = count($code); $i < $n;) {
+                //Reset the attributes for a new line ...
+                $attrs = array();
+
+                // Make lines have at least one space in them if they're empty
+                // BenBE: Checking emptiness using trim instead of relying on blanks
+                if ('' == trim($code[$i])) {
+                    $code[$i] = '&nbsp;';
+                }
+
+                // If this is a "special line"...
+                if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
+                    $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
+                    // Set the attributes to style the line
+                    if ($this->use_classes) {
+                        //$attr = ' class="li2"';
+                        $attrs['class'][] = 'li2';
+                        $def_attr = ' class="de2"';
+                    } else {
+                        //$attr = ' style="' . $this->line_style2 . '"';
+                        $attrs['style'][] = $this->line_style2;
+                        // This style "covers up" the special styles set for special lines
+                        // so that styles applied to special lines don't apply to the actual
+                        // code on that line
+                        $def_attr = ' style="' . $this->code_style . '"';
+                    }
+                } else {
+                    if ($this->use_classes) {
+                        //$attr = ' class="li1"';
+                        $attrs['class'][] = 'li1';
+                        $def_attr = ' class="de1"';
+                    } else {
+                        //$attr = ' style="' . $this->line_style1 . '"';
+                        $attrs['style'][] = $this->line_style1;
+                        $def_attr = ' style="' . $this->code_style . '"';
+                    }
+                }
+
+                //Check which type of tag to insert for this line
+                if ($this->header_type == GESHI_HEADER_PRE_VALID) {
+                    $start = "<pre$def_attr>";
+                    $end = '</pre>';
+                } else {
+                    // Span or div?
+                    $start = "<div$def_attr>";
+                    $end = '</div>';
+                }
+
+                ++$i;
+
+                // Are we supposed to use ids? If so, add them
+                if ($this->add_ids) {
+                    $attrs['id'][] = "$this->overall_id-$i";
+                }
+
+                //Is this some line with extra styles???
+                if (in_array($i, $this->highlight_extra_lines)) {
+                    if ($this->use_classes) {
+                        if (isset($this->highlight_extra_lines_styles[$i])) {
+                            $attrs['class'][] = "lx$i";
+                        } else {
+                            $attrs['class'][] = "ln-xtra";
+                        }
+                    } else {
+                        array_push($attrs['style'], $this->get_line_style($i));
+                    }
+                }
+
+                // Add in the line surrounded by appropriate list HTML
+                $attr_string = '';
+                foreach ($attrs as $key => $attr) {
+                    $attr_string .= ' ' . $key . '="' . implode(' ', $attr) . '"';
+                }
+
+                $parsed_code .= "<li$attr_string>$start{$code[$i-1]}$end</li>$ls";
+                unset($code[$i - 1]);
+            }
+        } else {
+            $n = count($code);
+            if ($this->use_classes) {
+                $attributes = ' class="de1"';
+            } else {
+                $attributes = ' style="'. $this->code_style .'"';
+            }
+            if ($this->header_type == GESHI_HEADER_PRE_VALID) {
+                $parsed_code .= '<pre'. $attributes .'>';
+            } elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
+                if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                    if ($this->use_classes) {
+                        $attrs = ' class="ln"';
+                    } else {
+                        $attrs = ' style="'. $this->table_linenumber_style .'"';
+                    }
+                    $parsed_code .= '<td'.$attrs.'><pre'.$attributes.'>';
+                    // get linenumbers
+                    // we don't merge it with the for below, since it should be better for
+                    // memory consumption this way
+                    // @todo: but... actually it would still be somewhat nice to merge the two loops
+                    //        the mem peaks are at different positions
+                    for ($i = 0; $i < $n; ++$i) {
+                        $close = 0;
+                        // fancy lines
+                        if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
+                            $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
+                            // Set the attributes to style the line
+                            if ($this->use_classes) {
+                                $parsed_code .= '<span class="xtra li2"><span class="de2">';
+                            } else {
+                                // This style "covers up" the special styles set for special lines
+                                // so that styles applied to special lines don't apply to the actual
+                                // code on that line
+                                $parsed_code .= '<span style="display:block;' . $this->line_style2 . '">'
+                                                  .'<span style="' . $this->code_style .'">';
+                            }
+                            $close += 2;
+                        }
+                        //Is this some line with extra styles???
+                        if (in_array($i + 1, $this->highlight_extra_lines)) {
+                            if ($this->use_classes) {
+                                if (isset($this->highlight_extra_lines_styles[$i])) {
+                                    $parsed_code .= "<span class=\"xtra lx$i\">";
+                                } else {
+                                    $parsed_code .= "<span class=\"xtra ln-xtra\">";
+                                }
+                            } else {
+                                $parsed_code .= "<span style=\"display:block;" . $this->get_line_style($i) . "\">";
+                            }
+                            ++$close;
+                        }
+                        $parsed_code .= $this->line_numbers_start + $i;
+                        if ($close) {
+                            $parsed_code .= str_repeat('</span>', $close);
+                        } else if ($i != $n) {
+                            $parsed_code .= "\n";
+                        }
+                    }
+                    $parsed_code .= '</pre></td><td'.$attributes.'>';
+                }
+                $parsed_code .= '<pre'. $attributes .'>';
+            }
+            // No line numbers, but still need to handle highlighting lines extra.
+            // Have to use divs so the full width of the code is highlighted
+            $close = 0;
+            for ($i = 0; $i < $n; ++$i) {
+                // Make lines have at least one space in them if they're empty
+                // BenBE: Checking emptiness using trim instead of relying on blanks
+                if ('' == trim($code[$i])) {
+                    $code[$i] = '&nbsp;';
+                }
+                // fancy lines
+                if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
+                    $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
+                    // Set the attributes to style the line
+                    if ($this->use_classes) {
+                        $parsed_code .= '<span class="xtra li2"><span class="de2">';
+                    } else {
+                        // This style "covers up" the special styles set for special lines
+                        // so that styles applied to special lines don't apply to the actual
+                        // code on that line
+                        $parsed_code .= '<span style="display:block;' . $this->line_style2 . '">'
+                                          .'<span style="' . $this->code_style .'">';
+                    }
+                    $close += 2;
+                }
+                //Is this some line with extra styles???
+                if (in_array($i + 1, $this->highlight_extra_lines)) {
+                    if ($this->use_classes) {
+                        if (isset($this->highlight_extra_lines_styles[$i])) {
+                            $parsed_code .= "<span class=\"xtra lx$i\">";
+                        } else {
+                            $parsed_code .= "<span class=\"xtra ln-xtra\">";
+                        }
+                    } else {
+                        $parsed_code .= "<span style=\"display:block;" . $this->get_line_style($i) . "\">";
+                    }
+                    ++$close;
+                }
+
+                $parsed_code .= $code[$i];
+
+                if ($close) {
+                  $parsed_code .= str_repeat('</span>', $close);
+                  $close = 0;
+                }
+                elseif ($i + 1 < $n) {
+                    $parsed_code .= "\n";
+                }
+                unset($code[$i]);
+            }
+
+            if ($this->header_type == GESHI_HEADER_PRE_VALID || $this->header_type == GESHI_HEADER_PRE_TABLE) {
+                $parsed_code .= '</pre>';
+            }
+            if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                $parsed_code .= '</td>';
+            }
+        }
+
+        $parsed_code .= $this->footer();
+    }
+
+    /**
+     * Creates the header for the code block (with correct attributes)
+     *
+     * @return string The header for the code block
+     * @since  1.0.0
+     * @access private
+     */
+    function header() {
+        // Get attributes needed
+        /**
+         * @todo   Document behaviour change - class is outputted regardless of whether
+         *         we're using classes or not. Same with style
+         */
+        $attributes = ' class="' . $this->language;
+        if ($this->overall_class != '') {
+            $attributes .= " ".$this->overall_class;
+        }
+        $attributes .= '"';
+
+        if ($this->overall_id != '') {
+            $attributes .= " id=\"{$this->overall_id}\"";
+        }
+        if ($this->overall_style != '') {
+            $attributes .= ' style="' . $this->overall_style . '"';
+        }
+
+        $ol_attributes = '';
+
+        if ($this->line_numbers_start != 1) {
+            $ol_attributes .= ' start="' . $this->line_numbers_start . '"';
+        }
+
+        // Get the header HTML
+        $header = $this->header_content;
+        if ($header) {
+            if ($this->header_type == GESHI_HEADER_PRE || $this->header_type == GESHI_HEADER_PRE_VALID) {
+                $header = str_replace("\n", '', $header);
+            }
+            $header = $this->replace_keywords($header);
+
+            if ($this->use_classes) {
+                $attr = ' class="head"';
+            } else {
+                $attr = " style=\"{$this->header_content_style}\"";
+            }
+            if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                $header = "<thead><tr><td colspan=\"2\" $attr>$header</td></tr></thead>";
+            } else {
+                $header = "<div$attr>$header</div>";
+            }
+        }
+
+        if (GESHI_HEADER_NONE == $this->header_type) {
+            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                return "$header<ol$attributes$ol_attributes>";
+            }
+            return $header . ($this->force_code_block ? '<div>' : '');
+        }
+
+        // Work out what to return and do it
+        if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+            if ($this->header_type == GESHI_HEADER_PRE) {
+                return "<pre$attributes>$header<ol$ol_attributes>";
+            } else if ($this->header_type == GESHI_HEADER_DIV ||
+                $this->header_type == GESHI_HEADER_PRE_VALID) {
+                return "<div$attributes>$header<ol$ol_attributes>";
+            } else if ($this->header_type == GESHI_HEADER_PRE_TABLE) {
+                return "<table$attributes>$header<tbody><tr class=\"li1\">";
+            }
+        } else {
+            if ($this->header_type == GESHI_HEADER_PRE) {
+                return "<pre$attributes>$header"  .
+                    ($this->force_code_block ? '<div>' : '');
+            } else {
+                return "<div$attributes>$header" .
+                    ($this->force_code_block ? '<div>' : '');
+            }
+        }
+    }
+
+    /**
+     * Returns the footer for the code block.
+     *
+     * @return string The footer for the code block
+     * @since  1.0.0
+     * @access private
+     */
+    function footer() {
+        $footer = $this->footer_content;
+        if ($footer) {
+            if ($this->header_type == GESHI_HEADER_PRE) {
+                $footer = str_replace("\n", '', $footer);;
+            }
+            $footer = $this->replace_keywords($footer);
+
+            if ($this->use_classes) {
+                $attr = ' class="foot"';
+            } else {
+                $attr = " style=\"{$this->footer_content_style}\"";
+            }
+            if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                $footer = "<tfoot><tr><td colspan=\"2\">$footer</td></tr></tfoot>";
+            } else {
+                $footer = "<div$attr>$footer</div>";
+            }
+        }
+
+        if (GESHI_HEADER_NONE == $this->header_type) {
+            return ($this->line_numbers != GESHI_NO_LINE_NUMBERS) ? '</ol>' . $footer : $footer;
+        }
+
+        if ($this->header_type == GESHI_HEADER_DIV || $this->header_type == GESHI_HEADER_PRE_VALID) {
+            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                return "</ol>$footer</div>";
+            }
+            return ($this->force_code_block ? '</div>' : '') .
+                "$footer</div>";
+        }
+        elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
+            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                return "</tr></tbody>$footer</table>";
+            }
+            return ($this->force_code_block ? '</div>' : '') .
+                "$footer</div>";
+        }
+        else {
+            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+                return "</ol>$footer</pre>";
+            }
+            return ($this->force_code_block ? '</div>' : '') .
+                "$footer</pre>";
+        }
+    }
+
+    /**
+     * Replaces certain keywords in the header and footer with
+     * certain configuration values
+     *
+     * @param  string The header or footer content to do replacement on
+     * @return string The header or footer with replaced keywords
+     * @since  1.0.2
+     * @access private
+     */
+    function replace_keywords($instr) {
+        $keywords = $replacements = array();
+
+        $keywords[] = '<TIME>';
+        $keywords[] = '{TIME}';
+        $replacements[] = $replacements[] = number_format($time = $this->get_time(), 3);
+
+        $keywords[] = '<LANGUAGE>';
+        $keywords[] = '{LANGUAGE}';
+        $replacements[] = $replacements[] = $this->language_data['LANG_NAME'];
+
+        $keywords[] = '<VERSION>';
+        $keywords[] = '{VERSION}';
+        $replacements[] = $replacements[] = GESHI_VERSION;
+
+        $keywords[] = '<SPEED>';
+        $keywords[] = '{SPEED}';
+        if ($time <= 0) {
+            $speed = 'N/A';
+        } else {
+            $speed = strlen($this->source) / $time;
+            if ($speed >= 1024) {
+                $speed = sprintf("%.2f KB/s", $speed / 1024.0);
+            } else {
+                $speed = sprintf("%.0f B/s", $speed);
+            }
+        }
+        $replacements[] = $replacements[] = $speed;
+
+        return str_replace($keywords, $replacements, $instr);
+    }
+
+    /**
+     * Secure replacement for PHP built-in function htmlspecialchars().
+     *
+     * See ticket #427 (http://wush.net/trac/wikka/ticket/427) for the rationale
+     * for this replacement function.
+     *
+     * The INTERFACE for this function is almost the same as that for
+     * htmlspecialchars(), with the same default for quote style; however, there
+     * is no 'charset' parameter. The reason for this is as follows:
+     *
+     * The PHP docs say:
+     *      "The third argument charset defines character set used in conversion."
+     *
+     * I suspect PHP's htmlspecialchars() is working at the byte-value level and
+     * thus _needs_ to know (or asssume) a character set because the special
+     * characters to be replaced could exist at different code points in
+     * different character sets. (If indeed htmlspecialchars() works at
+     * byte-value level that goes some  way towards explaining why the
+     * vulnerability would exist in this function, too, and not only in
+     * htmlentities() which certainly is working at byte-value level.)
+     *
+     * This replacement function however works at character level and should
+     * therefore be "immune" to character set differences - so no charset
+     * parameter is needed or provided. If a third parameter is passed, it will
+     * be silently ignored.
+     *
+     * In the OUTPUT there is a minor difference in that we use '&#39;' instead
+     * of PHP's '&#039;' for a single quote: this provides compatibility with
+     *      get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)
+     * (see comment by mikiwoz at yahoo dot co dot uk on
+     * http://php.net/htmlspecialchars); it also matches the entity definition
+     * for XML 1.0
+     * (http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters).
+     * Like PHP we use a numeric character reference instead of '&apos;' for the
+     * single quote. For the other special characters we use the named entity
+     * references, as PHP is doing.
+     *
+     * @author      {@link http://wikkawiki.org/JavaWoman Marjolein Katsma}
+     *
+     * @license     http://www.gnu.org/copyleft/lgpl.html
+     *              GNU Lesser General Public License
+     * @copyright   Copyright 2007, {@link http://wikkawiki.org/CreditsPage
+     *              Wikka Development Team}
+     *
+     * @access      private
+     * @param       string  $string string to be converted
+     * @param       integer $quote_style
+     *                      - ENT_COMPAT:   escapes &, <, > and double quote (default)
+     *                      - ENT_NOQUOTES: escapes only &, < and >
+     *                      - ENT_QUOTES:   escapes &, <, >, double and single quotes
+     * @return      string  converted string
+     * @since       1.0.7.18
+     */
+    function hsc($string, $quote_style = ENT_COMPAT) {
+        // init
+        static $aTransSpecchar = array(
+            '&' => '&amp;',
+            '"' => '&quot;',
+            '<' => '&lt;',
+            '>' => '&gt;',
+
+            //This fix is related to SF#1923020, but has to be applied
+            //regardless of actually highlighting symbols.
+
+            //Circumvent a bug with symbol highlighting
+            //This is required as ; would produce undesirable side-effects if it
+            //was not to be processed as an entity.
+            ';' => '<SEMI>', // Force ; to be processed as entity
+            '|' => '<PIPE>' // Force | to be processed as entity
+            );                      // ENT_COMPAT set
+
+        switch ($quote_style) {
+            case ENT_NOQUOTES: // don't convert double quotes
+                unset($aTransSpecchar['"']);
+                break;
+            case ENT_QUOTES: // convert single quotes as well
+                $aTransSpecchar["'"] = '&#39;'; // (apos) htmlspecialchars() uses '&#039;'
+                break;
+        }
+
+        // return translated string
+        return strtr($string, $aTransSpecchar);
+    }
+
+    /**
+     * Returns a stylesheet for the highlighted code. If $economy mode
+     * is true, we only return the stylesheet declarations that matter for
+     * this code block instead of the whole thing
+     *
+     * @param  boolean Whether to use economy mode or not
+     * @return string A stylesheet built on the data for the current language
+     * @since  1.0.0
+     */
+    function get_stylesheet($economy_mode = true) {
+        // If there's an error, chances are that the language file
+        // won't have populated the language data file, so we can't
+        // risk getting a stylesheet...
+        if ($this->error) {
+            return '';
+        }
+
+        //Check if the style rearrangements have been processed ...
+        //This also does some preprocessing to check which style groups are useable ...
+        if(!isset($this->language_data['NUMBERS_CACHE'])) {
+            $this->build_style_cache();
+        }
+
+        // First, work out what the selector should be. If there's an ID,
+        // that should be used, the same for a class. Otherwise, a selector
+        // of '' means that these styles will be applied anywhere
+        if ($this->overall_id) {
+            $selector = '#' . $this->overall_id;
+        } else {
+            $selector = '.' . $this->language;
+            if ($this->overall_class) {
+                $selector .= '.' . $this->overall_class;
+            }
+        }
+        $selector .= ' ';
+
+        // Header of the stylesheet
+        if (!$economy_mode) {
+            $stylesheet = "/**\n".
+                " * GeSHi Dynamically Generated Stylesheet\n".
+                " * --------------------------------------\n".
+                " * Dynamically generated stylesheet for {$this->language}\n".
+                " * CSS class: {$this->overall_class}, CSS id: {$this->overall_id}\n".
+                " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann\n" .
+                " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
+                " * --------------------------------------\n".
+                " */\n";
+        } else {
+            $stylesheet = "/**\n".
+                " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann\n" .
+                " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
+                " */\n";
+        }
+
+        // Set the <ol> to have no effect at all if there are line numbers
+        // (<ol>s have margins that should be destroyed so all layout is
+        // controlled by the set_overall_style method, which works on the
+        // <pre> or <div> container). Additionally, set default styles for lines
+        if (!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+            //$stylesheet .= "$selector, {$selector}ol, {$selector}ol li {margin: 0;}\n";
+            $stylesheet .= "$selector.de1, $selector.de2 {{$this->code_style}}\n";
+        }
+
+        // Add overall styles
+        // note: neglect economy_mode, empty styles are meaningless
+        if ($this->overall_style != '') {
+            $stylesheet .= "$selector {{$this->overall_style}}\n";
+        }
+
+        // Add styles for links
+        // note: economy mode does not make _any_ sense here
+        //       either the style is empty and thus no selector is needed
+        //       or the appropriate key is given.
+        foreach ($this->link_styles as $key => $style) {
+            if ($style != '') {
+                switch ($key) {
+                    case GESHI_LINK:
+                        $stylesheet .= "{$selector}a:link {{$style}}\n";
+                        break;
+                    case GESHI_HOVER:
+                        $stylesheet .= "{$selector}a:hover {{$style}}\n";
+                        break;
+                    case GESHI_ACTIVE:
+                        $stylesheet .= "{$selector}a:active {{$style}}\n";
+                        break;
+                    case GESHI_VISITED:
+                        $stylesheet .= "{$selector}a:visited {{$style}}\n";
+                        break;
+                }
+            }
+        }
+
+        // Header and footer
+        // note: neglect economy_mode, empty styles are meaningless
+        if ($this->header_content_style != '') {
+            $stylesheet .= "$selector.head {{$this->header_content_style}}\n";
+        }
+        if ($this->footer_content_style != '') {
+            $stylesheet .= "$selector.foot {{$this->footer_content_style}}\n";
+        }
+
+        // Styles for important stuff
+        // note: neglect economy_mode, empty styles are meaningless
+        if ($this->important_styles != '') {
+            $stylesheet .= "$selector.imp {{$this->important_styles}}\n";
+        }
+
+        // Simple line number styles
+        if ((!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) && $this->line_style1 != '') {
+            $stylesheet .= "{$selector}li, {$selector}.li1 {{$this->line_style1}}\n";
+        }
+        if ((!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) && $this->table_linenumber_style != '') {
+            $stylesheet .= "{$selector}.ln {{$this->table_linenumber_style}}\n";
+        }
+        // If there is a style set for fancy line numbers, echo it out
+        if ((!$economy_mode || $this->line_numbers == GESHI_FANCY_LINE_NUMBERS) && $this->line_style2 != '') {
+            $stylesheet .= "{$selector}.li2 {{$this->line_style2}}\n";
+        }
+
+        // note: empty styles are meaningless
+        foreach ($this->language_data['STYLES']['KEYWORDS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode ||
+                (isset($this->lexic_permissions['KEYWORDS'][$group]) &&
+                $this->lexic_permissions['KEYWORDS'][$group]))) {
+                $stylesheet .= "$selector.kw$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['COMMENTS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode ||
+                (isset($this->lexic_permissions['COMMENTS'][$group]) &&
+                $this->lexic_permissions['COMMENTS'][$group]) ||
+                (!empty($this->language_data['COMMENT_REGEXP']) &&
+                !empty($this->language_data['COMMENT_REGEXP'][$group])))) {
+                $stylesheet .= "$selector.co$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['ESCAPE_CHAR'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['ESCAPE_CHAR'])) {
+                // NEW: since 1.0.8 we have to handle hardescapes
+                if ($group === 'HARD') {
+                    $group = '_h';
+                }
+                $stylesheet .= "$selector.es$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['BRACKETS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['BRACKETS'])) {
+                $stylesheet .= "$selector.br$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['SYMBOLS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['SYMBOLS'])) {
+                $stylesheet .= "$selector.sy$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['STRINGS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['STRINGS'])) {
+                // NEW: since 1.0.8 we have to handle hardquotes
+                if ($group === 'HARD') {
+                    $group = '_h';
+                }
+                $stylesheet .= "$selector.st$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['NUMBERS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['NUMBERS'])) {
+                $stylesheet .= "$selector.nu$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['METHODS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['METHODS'])) {
+                $stylesheet .= "$selector.me$group {{$styles}}\n";
+            }
+        }
+        // note: neglect economy_mode, empty styles are meaningless
+        foreach ($this->language_data['STYLES']['SCRIPT'] as $group => $styles) {
+            if ($styles != '') {
+                $stylesheet .= "$selector.sc$group {{$styles}}\n";
+            }
+        }
+        foreach ($this->language_data['STYLES']['REGEXPS'] as $group => $styles) {
+            if ($styles != '' && (!$economy_mode ||
+                (isset($this->lexic_permissions['REGEXPS'][$group]) &&
+                $this->lexic_permissions['REGEXPS'][$group]))) {
+                if (is_array($this->language_data['REGEXPS'][$group]) &&
+                    array_key_exists(GESHI_CLASS, $this->language_data['REGEXPS'][$group])) {
+                    $stylesheet .= "$selector.";
+                    $stylesheet .= $this->language_data['REGEXPS'][$group][GESHI_CLASS];
+                    $stylesheet .= " {{$styles}}\n";
+                } else {
+                    $stylesheet .= "$selector.re$group {{$styles}}\n";
+                }
+            }
+        }
+        // Styles for lines being highlighted extra
+        if (!$economy_mode || (count($this->highlight_extra_lines)!=count($this->highlight_extra_lines_styles))) {
+            $stylesheet .= "{$selector}.ln-xtra, {$selector}li.ln-xtra, {$selector}div.ln-xtra {{$this->highlight_extra_lines_style}}\n";
+        }
+        $stylesheet .= "{$selector}span.xtra { display:block; }\n";
+        foreach ($this->highlight_extra_lines_styles as $lineid => $linestyle) {
+            $stylesheet .= "{$selector}.lx$lineid, {$selector}li.lx$lineid, {$selector}div.lx$lineid {{$linestyle}}\n";
+        }
+
+        return $stylesheet;
+    }
+
+    /**
+     * Get's the style that is used for the specified line
+     *
+     * @param int The line number information is requested for
+     * @access private
+     * @since 1.0.7.21
+     */
+    function get_line_style($line) {
+        //$style = null;
+        $style = null;
+        if (isset($this->highlight_extra_lines_styles[$line])) {
+            $style = $this->highlight_extra_lines_styles[$line];
+        } else { // if no "extra" style assigned
+            $style = $this->highlight_extra_lines_style;
+        }
+
+        return $style;
+    }
+
+    /**
+    * this functions creates an optimized regular expression list
+    * of an array of strings.
+    *
+    * Example:
+    * <code>$list = array('faa', 'foo', 'foobar');
+    *          => string 'f(aa|oo(bar)?)'</code>
+    *
+    * @param $list array of (unquoted) strings
+    * @param $regexp_delimiter your regular expression delimiter, @see preg_quote()
+    * @return string for regular expression
+    * @author Milian Wolff <mail@milianw.de>
+    * @since 1.0.8
+    * @access private
+    */
+    function optimize_regexp_list($list, $regexp_delimiter = '/') {
+        $regex_chars = array('.', '\\', '+', '*', '?', '[', '^', ']', '$',
+            '(', ')', '{', '}', '=', '!', '<', '>', '|', ':', $regexp_delimiter);
+        sort($list);
+        $regexp_list = array('');
+        $num_subpatterns = 0;
+        $list_key = 0;
+
+        // the tokens which we will use to generate the regexp list
+        $tokens = array();
+        $prev_keys = array();
+        // go through all entries of the list and generate the token list
+        $cur_len = 0;
+        for ($i = 0, $i_max = count($list); $i < $i_max; ++$i) {
+            if ($cur_len > GESHI_MAX_PCRE_LENGTH) {
+                // seems like the length of this pcre is growing exorbitantly
+                $regexp_list[++$list_key] = $this->_optimize_regexp_list_tokens_to_string($tokens);
+                $num_subpatterns = substr_count($regexp_list[$list_key], '(?:');
+                $tokens = array();
+                $cur_len = 0;
+            }
+            $level = 0;
+            $entry = preg_quote((string) $list[$i], $regexp_delimiter);
+            $pointer = &$tokens;
+            // properly assign the new entry to the correct position in the token array
+            // possibly generate smaller common denominator keys
+            while (true) {
+                // get the common denominator
+                if (isset($prev_keys[$level])) {
+                    if ($prev_keys[$level] == $entry) {
+                        // this is a duplicate entry, skip it
+                        continue 2;
+                    }
+                    $char = 0;
+                    while (isset($entry[$char]) && isset($prev_keys[$level][$char])
+                            && $entry[$char] == $prev_keys[$level][$char]) {
+                        ++$char;
+                    }
+                    if ($char > 0) {
+                        // this entry has at least some chars in common with the current key
+                        if ($char == strlen($prev_keys[$level])) {
+                            // current key is totally matched, i.e. this entry has just some bits appended
+                            $pointer = &$pointer[$prev_keys[$level]];
+                        } else {
+                            // only part of the keys match
+                            $new_key_part1 = substr($prev_keys[$level], 0, $char);
+                            $new_key_part2 = substr($prev_keys[$level], $char);
+
+                            if (in_array($new_key_part1[0], $regex_chars)
+                                || in_array($new_key_part2[0], $regex_chars)) {
+                                // this is bad, a regex char as first character
+                                $pointer[$entry] = array('' => true);
+                                array_splice($prev_keys, $level, count($prev_keys), $entry);
+                                $cur_len += strlen($entry);
+                                continue;
+                            } else {
+                                // relocate previous tokens
+                                $pointer[$new_key_part1] = array($new_key_part2 => $pointer[$prev_keys[$level]]);
+                                unset($pointer[$prev_keys[$level]]);
+                                $pointer = &$pointer[$new_key_part1];
+                                // recreate key index
+                                array_splice($prev_keys, $level, count($prev_keys), array($new_key_part1, $new_key_part2));
+                                $cur_len += strlen($new_key_part2);
+                            }
+                        }
+                        ++$level;
+                        $entry = substr($entry, $char);
+                        continue;
+                    }
+                    // else: fall trough, i.e. no common denominator was found
+                }
+                if ($level == 0 && !empty($tokens)) {
+                    // we can dump current tokens into the string and throw them away afterwards
+                    $new_entry = $this->_optimize_regexp_list_tokens_to_string($tokens);
+                    $new_subpatterns = substr_count($new_entry, '(?:');
+                    if (GESHI_MAX_PCRE_SUBPATTERNS && $num_subpatterns + $new_subpatterns > GESHI_MAX_PCRE_SUBPATTERNS) {
+                        $regexp_list[++$list_key] = $new_entry;
+                        $num_subpatterns = $new_subpatterns;
+                    } else {
+                        if (!empty($regexp_list[$list_key])) {
+                            $new_entry = '|' . $new_entry;
+                        }
+                        $regexp_list[$list_key] .= $new_entry;
+                        $num_subpatterns += $new_subpatterns;
+                    }
+                    $tokens = array();
+                    $cur_len = 0;
+                }
+                // no further common denominator found
+                $pointer[$entry] = array('' => true);
+                array_splice($prev_keys, $level, count($prev_keys), $entry);
+
+                $cur_len += strlen($entry);
+                break;
+            }
+            unset($list[$i]);
+        }
+        // make sure the last tokens get converted as well
+        $new_entry = $this->_optimize_regexp_list_tokens_to_string($tokens);
+        if (GESHI_MAX_PCRE_SUBPATTERNS && $num_subpatterns + substr_count($new_entry, '(?:') > GESHI_MAX_PCRE_SUBPATTERNS) {
+            $regexp_list[++$list_key] = $new_entry;
+        } else {
+            if (!empty($regexp_list[$list_key])) {
+                $new_entry = '|' . $new_entry;
+            }
+            $regexp_list[$list_key] .= $new_entry;
+        }
+        return $regexp_list;
+    }
+    /**
+    * this function creates the appropriate regexp string of an token array
+    * you should not call this function directly, @see $this->optimize_regexp_list().
+    *
+    * @param &$tokens array of tokens
+    * @param $recursed bool to know wether we recursed or not
+    * @return string
+    * @author Milian Wolff <mail@milianw.de>
+    * @since 1.0.8
+    * @access private
+    */
+    function _optimize_regexp_list_tokens_to_string(&$tokens, $recursed = false) {
+        $list = '';
+        foreach ($tokens as $token => $sub_tokens) {
+            $list .= $token;
+            $close_entry = isset($sub_tokens['']);
+            unset($sub_tokens['']);
+            if (!empty($sub_tokens)) {
+                $list .= '(?:' . $this->_optimize_regexp_list_tokens_to_string($sub_tokens, true) . ')';
+                if ($close_entry) {
+                    // make sub_tokens optional
+                    $list .= '?';
+                }
+            }
+            $list .= '|';
+        }
+        if (!$recursed) {
+            // do some optimizations
+            // common trailing strings
+            // BUGGY!
+            //$list = preg_replace_callback('#(?<=^|\:|\|)\w+?(\w+)(?:\|.+\1)+(?=\|)#', create_function(
+            //    '$matches', 'return "(?:" . preg_replace("#" . preg_quote($matches[1], "#") . "(?=\||$)#", "", $matches[0]) . ")" . $matches[1];'), $list);
+            // (?:p)? => p?
+            $list = preg_replace('#\(\?\:(.)\)\?#', '\1?', $list);
+            // (?:a|b|c|d|...)? => [abcd...]?
+            // TODO: a|bb|c => [ac]|bb
+            static $callback_2;
+            if (!isset($callback_2)) {
+                $callback_2 = create_function('$matches', 'return "[" . str_replace("|", "", $matches[1]) . "]";');
+            }
+            $list = preg_replace_callback('#\(\?\:((?:.\|)+.)\)#', $callback_2, $list);
+        }
+        // return $list without trailing pipe
+        return substr($list, 0, -1);
+    }
+} // End Class GeSHi
+
+
+if (!function_exists('geshi_highlight')) {
+    /**
+     * Easy way to highlight stuff. Behaves just like highlight_string
+     *
+     * @param string The code to highlight
+     * @param string The language to highlight the code in
+     * @param string The path to the language files. You can leave this blank if you need
+     *               as from version 1.0.7 the path should be automatically detected
+     * @param boolean Whether to return the result or to echo
+     * @return string The code highlighted (if $return is true)
+     * @since 1.0.2
+     */
+    function geshi_highlight($string, $language, $path = null, $return = false) {
+        $geshi = new GeSHi($string, $language, $path);
+        $geshi->set_header_type(GESHI_HEADER_NONE);
+
+        if ($return) {
+            return '<code>' . $geshi->parse_code() . '</code>';
+        }
+
+        echo '<code>' . $geshi->parse_code() . '</code>';
+
+        if ($geshi->error()) {
+            return false;
+        }
+        return true;
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/abap.php b/examples/includes/geshi/geshi/abap.php
new file mode 100644 (file)
index 0000000..ffd8d10
--- /dev/null
@@ -0,0 +1,1419 @@
+<?php
+/*************************************************************************************
+ * abap.php
+ * --------
+ * Author: Andres Picazo (andres@andrespicazo.com)
+ * Contributors:
+ *  - Sandra Rossi (sandra.rossi@gmail.com)
+ *  - Jacob Laursen (jlu@kmd.dk)
+ * Copyright: (c) 2007 Andres Picazo
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * ABAP language file for GeSHi.
+ *
+ * Reference abap language documentation (abap 7.1) : http://help.sap.com/abapdocu/en/ABENABAP_INDEX.htm
+ *
+ * ABAP syntax is highly complex, several problems could not be addressed, see TODO below if you dare ;-)
+ * Be aware that in ABAP language, keywords may be composed of several tokens,
+ *    separated by one or more spaces or carriage returns
+ *    (for example CONCATENATE 'hello' 'world' INTO string SEPARATED  BY ' ')
+ *    it's why we must decode them with REGEXPS. As there are many keywords with several tokens,
+ *    I had to create a separate section in the code to simplify the reading.
+ * Be aware that some words may be highlighted several times like for "ref to data", which is first
+ *    highlighted for "ref to data", then secondly for "ref to". It is very important to
+ *    position "ref to" after "ref to data" otherwise "data" wouldn't be highlighted because
+ *    of the previous highlight.
+ * Styles used : keywords are all displayed in upper case, and they are organized into 4 categories :
+ *    1) control statements (blue), 2) declarative statements (red-maroon),
+ *    3) other statements (blue-green), 4) keywords (violet).
+ *    + GeSHi : literals (red) + symbols (green) + methods/attributes (mauve)
+ *    + unchanged style for other words.
+ * Control, declarative and other statements are assigned URLs to sap documentation website:
+ *    http://help.sap.com/abapdocu/en/ABAP<statement_name>.htm
+ *
+ * CHANGES
+ * -------
+ * 2009/02/25 (1.0.8.3)
+ *   -  Some more rework of the language file
+ * 2009/01/04 (1.0.8.2)
+ *   -  Major Release, more than 1000 statements and keywords added = whole abap 7.1 (Sandra Rossi)
+ * 2007/06/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *   - in DATA data TYPE type, 2nd "data" and 2nd "type" are highlighted with data
+ *     style, but should be ignored. Same problem for all words!!! This is quite impossible to
+ *     solve it as we should define syntaxes of all statements (huge effort!) and use a lex
+ *     or something like that instead of regexp I guess.
+ *   - Some words are considered as being statement names (report, tables, etc.) though they
+ *     are used as keyword in some statements. For example: FORM xxxx TABLES itab. It was
+ *     arbitrary decided to define them as statement instead of keyword, because it may be
+ *     useful to have the URL to SAP help for some of them.
+ *   - if a comment is between 2 words of a keyword (for example SEPARATED "comment \n BY),
+ *     it is not considered as a keyword, but it should!
+ *   - for statements like "READ DATASET", GeSHi does not allow to set URLs because these
+ *     statements are determined by REGEXPS. For "READ DATASET", the URL should be
+ *     ABAPREAD_DATASET.htm. If a technical solution is found, be careful : URLs
+ *     are sometimes not valid because the URL does not exist. For example, for "AT NEW"
+ *     statement, the URL should be ABAPAT_ITAB.htm (not ABAPAT_NEW.htm).
+ *     There are many other exceptions.
+ *     Note: for adding this functionality within your php program, you can execute this code:
+ *       function add_urls_to_multi_tokens( $matches ) {
+ *           $url = preg_replace( "/[ \n]+/" , "_" , $matches[3] );
+ *           if( $url == $matches[3] ) return $matches[0] ;
+ *           else return $matches[1]."<a href=\"http://help.sap.com/abapdocu/en/ABAP".strtoupper($url).".htm\">".$matches[3]."</a>".$matches[4];
+ *           }
+ *       $html = $geshi->parse_code();
+ *       $html = preg_replace_callback( "£(zzz:(control|statement|data);\">)(.+?)(</span>)£s", "add_urls_to_multi_tokens", $html );
+ *       echo $html;
+ *   - Numbers followed by a dot terminating the statement are not properly recognized
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+    'LANG_NAME' => 'ABAP',
+    'COMMENT_SINGLE' => array(
+        1 => '"'
+        ),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        // lines beginning with star at 1st position are comments
+        // (star anywhere else is not a comment, especially be careful with
+        // "assign dref->* to <fs>" statement)
+        2 => '/^\*.*?$/m'
+        ),
+    'CASE_KEYWORDS' => 0,
+    'QUOTEMARKS' => array(
+        1 => "'",
+        2 => "`"
+        ),
+    'ESCAPE_CHAR' => '',
+
+    'KEYWORDS' => array(
+        //***********************************************
+        // Section 2 : process sequences of several tokens
+        //***********************************************
+
+        7 => array(
+            'at new',
+            'at end of',
+            'at first',
+            'at last',
+            'loop at',
+            'loop at screen',
+            ),
+
+        8 => array(
+            'private section',
+            'protected section',
+            'public section',
+            'at line-selection',
+            'at selection-screen',
+            'at user-command',
+            'assign component',
+            'assign table field',
+            'call badi',
+            'call customer-function',
+            'call customer subscreen',
+            'call dialog',
+            'call function',
+            'call method',
+            'call screen',
+            'call selection-screen',
+            'call transaction',
+            'call transformation',
+            'close cursor',
+            'close dataset',
+            'commit work',
+            'convert date',
+            'convert text',
+            'convert time stamp',
+            'create data',
+            'create object',
+            'delete dataset',
+            'delete from',
+            'describe distance',
+            'describe field',
+            'describe list',
+            'describe table',
+            'exec sql',
+            'exit from sql',
+            'exit from step-loop',
+            'export dynpro',
+            'export nametab',
+            'free memory',
+            'generate subroutine-pool',
+            'get badi',
+            'get bit',
+            'get cursor',
+            'get dataset',
+            'get locale',
+            'get parameter',
+            'get pf-status',
+            'get property',
+            'get reference',
+            'get run time',
+            'get time',
+            'get time stamp',
+            'import directory',
+            'insert report',
+            'insert text-pool',
+            'leave list-processing',
+            'leave program',
+            'leave screen',
+            'leave to list-processing',
+            'leave to transaction',
+            'modify line',
+            'modify screen',
+            'move percentage',
+            'open cursor',
+            'open dataset',
+            'raise event',
+            'raise exception',
+            'read dataset',
+            'read line',
+            'read report',
+            'read table',
+            'read textpool',
+            'receive results from function',
+            'refresh control',
+            'rollback work',
+            'set bit',
+            'set blank lines',
+            'set country',
+            'set cursor',
+            'set dataset',
+            'set extended check',
+            'set handler',
+            'set hold data',
+            'set language',
+            'set left scroll-boundary',
+            'set locale',
+            'set margin',
+            'set parameter',
+            'set pf-status',
+            'set property',
+            'set run time analyzer',
+            'set run time clock',
+            'set screen',
+            'set titlebar',
+            'set update task',
+            'set user-command',
+            'suppress dialog',
+            'truncate dataset',
+            'wait until',
+            'wait up to',
+            ),
+
+        9 => array(
+            'accepting duplicate keys',
+            'accepting padding',
+            'accepting truncation',
+            'according to',
+            'actual length',
+            'adjacent duplicates',
+            'after input',
+            'all blob columns',
+            'all clob columns',
+            'all fields',
+            'all methods',
+            'all other columns',
+            'and mark',
+            'and return to screen',
+            'and return',
+            'and skip first screen',
+            'and wait',
+            'any table',
+            'appendage type',
+            'archive mode',
+            'archiving parameters',
+            'area handle',
+            'as checkbox',
+            'as icon',
+            'as line',
+            'as listbox',
+            'as person table',
+            'as search patterns',
+            'as separate unit',
+            'as subscreen',
+            'as symbol',
+            'as text',
+            'as window',
+            'at cursor-selection',
+            'at exit-command',
+            'at next application statement',
+            'at position',
+
+            'backup into',
+            'before output',
+            'before unwind',
+            'begin of block',
+            'begin of common part',
+            'begin of line',
+            'begin of screen',
+            'begin of tabbed block',
+            'begin of version',
+            'begin of',
+            'big endian',
+            'binary mode',
+            'binary search',
+            'by kernel module',
+            'bypassing buffer',
+
+            'client specified',
+            'code page',
+            'code page hint',
+            'code page into',
+            'color black',
+            'color blue',
+            'color green',
+            'color pink',
+            'color red',
+            'color yellow',
+            'compression off',
+            'compression on',
+            'connect to',
+            'corresponding fields of table',
+            'corresponding fields of',
+            'cover page',
+            'cover text',
+            'create package',
+            'create private',
+            'create protected',
+            'create public',
+            'current position',
+
+            'data buffer',
+            'data values',
+            'dataset expiration',
+            'daylight saving time',
+            'default key',
+            'default program',
+            'default screen',
+            'defining database',
+            'deleting leading',
+            'deleting trailing',
+            'directory entry',
+            'display like',
+            'display offset',
+            'during line-selection',
+            'dynamic selections',
+
+            'edit mask',
+            'end of block',
+            'end of common part',
+            'end of file',
+            'end of line',
+            'end of screen',
+            'end of tabbed block',
+            'end of version',
+            'end of',
+            'endian into',
+            'ending at',
+            'enhancement options into',
+            'enhancement into',
+            'environment time format',
+            'execute procedure',
+            'exporting list to memory',
+            'extension type',
+
+            'field format',
+            'field selection',
+            'field value into',
+            'final methods',
+            'first occurrence of',
+            'fixed-point arithmetic',
+            'for all entries',
+            'for all instances',
+            'for appending',
+            'for columns',
+            'for event of',
+            'for field',
+            'for high',
+            'for input',
+            'for lines',
+            'for low',
+            'for node',
+            'for output',
+            'for select',
+            'for table',
+            'for testing',
+            'for update',
+            'for user',
+            'frame entry',
+            'frame program from',
+            'from code page',
+            'from context',
+            'from database',
+            'from logfile id',
+            'from number format',
+            'from screen',
+            'from table',
+            'function key',
+
+            'get connection',
+            'global friends',
+            'group by',
+
+            'hashed table of',
+            'hashed table',
+
+            'if found',
+            'ignoring case',
+            'ignoring conversion errors',
+            'ignoring structure boundaries',
+            'implementations from',
+            'in background',
+            'in background task',
+            'in background unit',
+            'in binary mode',
+            'in byte mode',
+            'in char-to-hex mode',
+            'in character mode',
+            'in group',
+            'in legacy binary mode',
+            'in legacy text mode',
+            'in program',
+            'in remote task',
+            'in text mode',
+            'in table',
+            'in update task',
+            'include bound',
+            'include into',
+            'include program from',
+            'include structure',
+            'include type',
+            'including gaps',
+            'index table',
+            'inheriting from',
+            'init destination',
+            'initial line of',
+            'initial line',
+            'initial size',
+            'internal table',
+            'into sortable code',
+
+            'keep in spool',
+            'keeping directory entry',
+            'keeping logical unit of work',
+            'keeping task',
+            'keywords from',
+
+            'left margin',
+            'left outer',
+            'levels into',
+            'line format',
+            'line into',
+            'line of',
+            'line page',
+            'line value from',
+            'line value into',
+            'lines of',
+            'list authority',
+            'list dataset',
+            'list name',
+            'little endian',
+            'lob handle for',
+            'local friends',
+            'locator for',
+            'lower case',
+
+            'main table field',
+            'match count',
+            'match length',
+            'match line',
+            'match offset',
+            'matchcode object',
+            'maximum length',
+            'maximum width into',
+            'memory id',
+            'message into',
+            'messages into',
+            'modif id',
+
+            'nesting level',
+            'new list identification',
+            'next cursor',
+            'no database selection',
+            'no dialog',
+            'no end of line',
+            'no fields',
+            'no flush',
+            'no intervals',
+            'no intervals off',
+            'no standard page heading',
+            'no-extension off',
+            'non-unique key',
+            'non-unique sorted key',
+            'not at end of mode',
+            'number of lines',
+            'number of pages',
+
+            'object key',
+            'obligatory off',
+            'of current page',
+            'of page',
+            'of program',
+            'offset into',
+            'on block',
+            'on commit',
+            'on end of task',
+            'on end of',
+            'on exit-command',
+            'on help-request for',
+            'on radiobutton group',
+            'on rollback',
+            'on value-request for',
+            'open for package',
+            'option class-coding',
+            'option class',
+            'option coding',
+            'option expand',
+            'option syncpoints',
+            'options from',
+            'order by',
+            'overflow into',
+
+            'package section',
+            'package size',
+            'preferred parameter',
+            'preserving identifier escaping',
+            'primary key',
+            'print off',
+            'print on',
+            'program from',
+            'program type',
+
+            'radiobutton groups',
+            'radiobutton group',
+            'range of',
+            'reader for',
+            'receive buffer',
+            'reduced functionality',
+            'ref to data',
+            'ref to object',
+            'ref to',
+
+            'reference into',
+            'renaming with suffix',
+            'replacement character',
+            'replacement count',
+            'replacement length',
+            'replacement line',
+            'replacement offset',
+            'respecting blanks',
+            'respecting case',
+            'result into',
+            'risk level',
+
+            'sap cover page',
+            'search fkeq',
+            'search fkge',
+            'search gkeq',
+            'search gkge',
+            'section of',
+            'send buffer',
+            'separated by',
+            'shared buffer',
+            'shared memory',
+            'shared memory enabled',
+            'skipping byte-order mark',
+            'sorted by',
+            'sorted table of',
+            'sorted table',
+            'spool parameters',
+            'standard table of',
+            'standard table',
+            'starting at',
+            'starting new task',
+            'statements into',
+            'structure default',
+            'structures into',
+
+            'table field',
+            'table of',
+            'text mode',
+            'time stamp',
+            'time zone',
+            'to code page',
+            'to column',
+            'to context',
+            'to first page',
+            'to last page',
+            'to last line',
+            'to line',
+            'to lower case',
+            'to number format',
+            'to page',
+            'to sap spool',
+            'to upper case',
+            'tokens into',
+            'transporting no fields',
+            'type tableview',
+            'type tabstrip',
+
+            'unicode enabling',
+            'up to',
+            'upper case',
+            'using edit mask',
+            'using key',
+            'using no edit mask',
+            'using screen',
+            'using selection-screen',
+            'using selection-set',
+            'using selection-sets of program',
+
+            'valid between',
+            'valid from',
+            'value check',
+            'via job',
+            'via selection-screen',
+            'visible length',
+
+            'whenever found',
+            'with analysis',
+            'with byte-order mark',
+            'with comments',
+            'with current switchstates',
+            'with explicit enhancements',
+            'with frame',
+            'with free selections',
+            'with further secondary keys',
+            'with header line',
+            'with hold',
+            'with implicit enhancements',
+            'with inactive enhancements',
+            'with includes',
+            'with key',
+            'with linefeed',
+            'with list tokenization',
+            'with native linefeed',
+            'with non-unique key',
+            'with null',
+            'with pragmas',
+            'with precompiled headers',
+            'with selection-table',
+            'with smart linefeed',
+            'with table key',
+            'with test code',
+            'with type-pools',
+            'with unique key',
+            'with unix linefeed',
+            'with windows linefeed',
+            'without further secondary keys',
+            'without selection-screen',
+            'without spool dynpro',
+            'without trmac',
+            'word into',
+            'writer for'
+            ),
+
+        //**********************************************************
+        // Other abap statements
+        //**********************************************************
+        3 => array(
+            'add',
+            'add-corresponding',
+            'aliases',
+            'append',
+            'assign',
+            'at',
+            'authority-check',
+
+            'break-point',
+
+            'clear',
+            'collect',
+            'compute',
+            'concatenate',
+            'condense',
+            'class',
+            'class-events',
+            'class-methods',
+            'class-pool',
+
+            'define',
+            'delete',
+            'demand',
+            'detail',
+            'divide',
+            'divide-corresponding',
+
+            'editor-call',
+            'end-of-file',
+            'end-enhancement-section',
+            'end-of-definition',
+            'end-of-page',
+            'end-of-selection',
+            'endclass',
+            'endenhancement',
+            'endexec',
+            'endform',
+            'endfunction',
+            'endinterface',
+            'endmethod',
+            'endmodule',
+            'endon',
+            'endprovide',
+            'endselect',
+            'enhancement',
+            'enhancement-point',
+            'enhancement-section',
+            'export',
+            'extract',
+            'events',
+
+            'fetch',
+            'field-groups',
+            'find',
+            'format',
+            'form',
+            'free',
+            'function-pool',
+            'function',
+
+            'get',
+
+            'hide',
+
+            'import',
+            'infotypes',
+            'input',
+            'insert',
+            'include',
+            'initialization',
+            'interface',
+            'interface-pool',
+            'interfaces',
+
+            'leave',
+            'load-of-program',
+            'log-point',
+
+            'maximum',
+            'message',
+            'methods',
+            'method',
+            'minimum',
+            'modify',
+            'move',
+            'move-corresponding',
+            'multiply',
+            'multiply-corresponding',
+
+            'new-line',
+            'new-page',
+            'new-section',
+
+            'overlay',
+
+            'pack',
+            'perform',
+            'position',
+            'print-control',
+            'program',
+            'provide',
+            'put',
+
+            'raise',
+            'refresh',
+            'reject',
+            'replace',
+            'report',
+            'reserve',
+
+            'scroll',
+            'search',
+            'select',
+            'selection-screen',
+            'shift',
+            'skip',
+            'sort',
+            'split',
+            'start-of-selection',
+            'submit',
+            'subtract',
+            'subtract-corresponding',
+            'sum',
+            'summary',
+            'summing',
+            'supply',
+            'syntax-check',
+
+            'top-of-page',
+            'transfer',
+            'translate',
+            'type-pool',
+
+            'uline',
+            'unpack',
+            'update',
+
+            'window',
+            'write'
+
+            ),
+
+        //**********************************************************
+        // keywords
+        //**********************************************************
+
+        4 => array(
+            'abbreviated',
+            'abstract',
+            'accept',
+            'acos',
+            'activation',
+            'alias',
+            'align',
+            'all',
+            'allocate',
+            'and',
+            'assigned',
+            'any',
+            'appending',
+            'area',
+            'as',
+            'ascending',
+            'asin',
+            'assigning',
+            'atan',
+            'attributes',
+            'avg',
+
+            'backward',
+            'between',
+            'bit-and',
+            'bit-not',
+            'bit-or',
+            'bit-set',
+            'bit-xor',
+            'boolc',
+            'boolx',
+            'bound',
+            'bt',
+            'blocks',
+            'bounds',
+            'boxed',
+            'by',
+            'byte-ca',
+            'byte-cn',
+            'byte-co',
+            'byte-cs',
+            'byte-na',
+            'byte-ns',
+
+            'c',
+            'ca',
+            'calling',
+            'casting',
+            'ceil',
+            'center',
+            'centered',
+            'changing',
+            'char_off',
+            'charlen',
+            'circular',
+            'class_constructor',
+            'client',
+            'clike',
+            'close',
+            'cmax',
+            'cmin',
+            'cn',
+            'cnt',
+            'co',
+            'col_background',
+            'col_group',
+            'col_heading',
+            'col_key',
+            'col_negative',
+            'col_normal',
+            'col_positive',
+            'col_total',
+            'color',
+            'column',
+            'comment',
+            'comparing',
+            'components',
+            'condition',
+            'constructor',
+            'context',
+            'copies',
+            'count',
+            'country',
+            'cpi',
+            'creating',
+            'critical',
+            'concat_lines_of',
+            'cos',
+            'cosh',
+            'count_any_not_of',
+            'count_any_of',
+            'cp',
+            'cs',
+            'csequence',
+            'currency',
+            'current',
+            'cx_static_check',
+            'cx_root',
+            'cx_dynamic_check',
+
+            'd',
+            'dangerous',
+            'database',
+            'datainfo',
+            'date',
+            'dbmaxlen',
+            'dd/mm/yy',
+            'dd/mm/yyyy',
+            'ddmmyy',
+            'deallocate',
+            'decfloat',
+            'decfloat16',
+            'decfloat34',
+            'decimals',
+            'default',
+            'deferred',
+            'definition',
+            'department',
+            'descending',
+            'destination',
+            'disconnect',
+            'display-mode',
+            'distance',
+            'distinct',
+            'div',
+            'dummy',
+
+            'e',
+            'encoding',
+            'end-lines',
+            'engineering',
+            'environment',
+            'eq',
+            'equiv',
+            'error_message',
+            'errormessage',
+            'escape',
+            'exact',
+            'exception-table',
+            'exceptions',
+            'exclude',
+            'excluding',
+            'exists',
+            'exp',
+            'exponent',
+            'exporting',
+            'extended_monetary',
+
+            'field',
+            'filter-table',
+            'filters',
+            'filter',
+            'final',
+            'find_any_not_of',
+            'find_any_of',
+            'find_end',
+            'floor',
+            'first-line',
+            'font',
+            'forward',
+            'for',
+            'frac',
+            'from_mixed',
+            'friends',
+            'from',
+            'f',
+
+            'giving',
+            'ge',
+            'gt',
+
+            'handle',
+            'harmless',
+            'having',
+            'head-lines',
+            'help-id',
+            'help-request',
+            'high',
+            'hold',
+            'hotspot',
+
+            'i',
+            'id',
+            'ids',
+            'immediately',
+            'implementation',
+            'importing',
+            'in',
+            'initial',
+            'incl',
+            'including',
+            'increment',
+            'index',
+            'index-line',
+            'inner',
+            'inout',
+            'intensified',
+            'into',
+            'inverse',
+            'is',
+            'iso',
+
+            'join',
+
+            'key',
+            'kind',
+
+            'log10',
+            'language',
+            'late',
+            'layout',
+            'le',
+            'lt',
+            'left-justified',
+            'leftplus',
+            'leftspace',
+            'left',
+            'length',
+            'level',
+            'like',
+            'line-count',
+            'line-size',
+            'lines',
+            'line',
+            'load',
+            'long',
+            'lower',
+            'low',
+            'lpi',
+
+            'matches',
+            'match',
+            'mail',
+            'major-id',
+            'max',
+            'medium',
+            'memory',
+            'message-id',
+            'module',
+            'minor-id',
+            'min',
+            'mm/dd/yyyy',
+            'mm/dd/yy',
+            'mmddyy',
+            'mode',
+            'modifier',
+            'mod',
+            'monetary',
+
+            'name',
+            'nb',
+            'ne',
+            'next',
+            'no-display',
+            'no-extension',
+            'no-gap',
+            'no-gaps',
+            'no-grouping',
+            'no-heading',
+            'no-scrolling',
+            'no-sign',
+            'no-title',
+            'no-topofpage',
+            'no-zero',
+            'nodes',
+            'non-unicode',
+            'no',
+            'number',
+            'n',
+            'nmax',
+            'nmin',
+            'not',
+            'null',
+            'numeric',
+            'numofchar',
+
+            'o',
+            'objects',
+            'obligatory',
+            'occurs',
+            'offset',
+            'off',
+            'of',
+            'only',
+            'open',
+            'option',
+            'optional',
+            'options',
+            'output-length',
+            'output',
+            'out',
+            'on change of',
+            'or',
+            'others',
+
+            'pad',
+            'page',
+            'pages',
+            'parameter-table',
+            'part',
+            'performing',
+            'pos_high',
+            'pos_low',
+            'priority',
+            'public',
+            'pushbutton',
+            'p',
+
+            'queue-only',
+            'quickinfo',
+
+            'raising',
+            'range',
+            'read-only',
+            'received',
+            'receiver',
+            'receiving',
+            'redefinition',
+            'reference',
+            'regex',
+            'replacing',
+            'reset',
+            'responsible',
+            'result',
+            'results',
+            'resumable',
+            'returncode',
+            'returning',
+            'right',
+            'right-specified',
+            'rightplus',
+            'rightspace',
+            'round',
+            'rows',
+            'repeat',
+            'requested',
+            'rescale',
+            'reverse',
+
+            'scale_preserving',
+            'scale_preserving_scientific',
+            'scientific',
+            'scientific_with_leading_zero',
+            'screen',
+            'scrolling',
+            'seconds',
+            'segment',
+            'shift_left',
+            'shift_right',
+            'sign',
+            'simple',
+            'sin',
+            'sinh',
+            'short',
+            'shortdump-id',
+            'sign_as_postfix',
+            'single',
+            'size',
+            'some',
+            'source',
+            'space',
+            'spots',
+            'stable',
+            'state',
+            'static',
+            'statusinfo',
+            'sqrt',
+            'string',
+            'strlen',
+            'structure',
+            'style',
+            'subkey',
+            'submatches',
+            'substring',
+            'substring_after',
+            'substring_before',
+            'substring_from',
+            'substring_to',
+            'super',
+            'supplied',
+            'switch',
+
+            't',
+            'tan',
+            'tanh',
+            'table_line',
+            'table',
+            'tab',
+            'then',
+            'timestamp',
+            'times',
+            'time',
+            'timezone',
+            'title-lines',
+            'title',
+            'top-lines',
+            'to',
+            'to_lower',
+            'to_mixed',
+            'to_upper',
+            'trace-file',
+            'trace-table',
+            'transporting',
+            'trunc',
+            'type',
+
+            'under',
+            'unique',
+            'unit',
+            'user-command',
+            'using',
+            'utf-8',
+
+            'valid',
+            'value',
+            'value-request',
+            'values',
+            'vary',
+            'varying',
+            'version',
+
+            'warning',
+            'where',
+            'width',
+            'with',
+            'word',
+            'with-heading',
+            'with-title',
+
+            'x',
+            'xsequence',
+            'xstring',
+            'xstrlen',
+
+            'yes',
+            'yymmdd',
+
+            'z',
+            'zero'
+
+            ),
+
+        //**********************************************************
+        // screen statements
+        //**********************************************************
+
+        5 => array(
+            'call subscreen',
+            'chain',
+            'endchain',
+            'on chain-input',
+            'on chain-request',
+            'on help-request',
+            'on input',
+            'on request',
+            'on value-request',
+            'process'
+            ),
+
+        //**********************************************************
+        // internal statements
+        //**********************************************************
+
+        6 => array(
+            'generate dynpro',
+            'generate report',
+            'import dynpro',
+            'import nametab',
+            'include methods',
+            'load report',
+            'scan abap-source',
+            'scan and check abap-source',
+            'syntax-check for dynpro',
+            'syntax-check for program',
+            'syntax-trace',
+            'system-call',
+            'system-exit',
+            'verification-message'
+            ),
+
+        //**********************************************************
+        // Control statements
+        //**********************************************************
+
+        1 => array(
+            'assert',
+            'case',
+            'catch',
+            'check',
+            'cleanup',
+            'continue',
+            'do',
+            'else',
+            'elseif',
+            'endat',
+            'endcase',
+            'endcatch',
+            'endif',
+            'enddo',
+            'endloop',
+            'endtry',
+            'endwhile',
+            'exit',
+            'if',
+            'loop',
+            'resume',
+            'retry',
+            'return',
+            'stop',
+            'try',
+            'when',
+            'while'
+
+            ),
+
+        //**********************************************************
+        // variable declaration statements
+        //**********************************************************
+
+        2 => array(
+            'class-data',
+            'controls',
+            'constants',
+            'data',
+            'field-symbols',
+            'fields',
+            'local',
+            'parameters',
+            'ranges',
+            'select-options',
+            'statics',
+            'tables',
+            'type-pools',
+            'types'
+            )
+        ),
+    'SYMBOLS' => array(
+        0 => array(
+            '='
+            ),
+        1 => array(
+            '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+            )
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false,
+        8 => false,
+        9 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000066; text-transform: uppercase; font-weight: bold; zzz:control;', //control statements
+            2 => 'color: #cc4050; text-transform: uppercase; font-weight: bold; zzz:data;', //data statements
+            3 => 'color: #005066; text-transform: uppercase; font-weight: bold; zzz:statement;', //first token of other statements
+            4 => 'color: #500066; text-transform: uppercase; font-weight: bold; zzz:keyword;', // next tokens of other statements ("keywords")
+            5 => 'color: #005066; text-transform: uppercase; font-weight: bold; zzz:statement;',
+            6 => 'color: #000066; text-transform: uppercase; font-weight: bold; zzz:control;',
+            7 => 'color: #000066; text-transform: uppercase; font-weight: bold; zzz:control;',
+            8 => 'color: #005066; text-transform: uppercase; font-weight: bold; zzz:statement;',
+            9 => 'color: #500066; text-transform: uppercase; font-weight: bold; zzz:keyword;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #339933;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #808080;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #4da619;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #3399ff;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;',
+            2 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #800080;',
+            1 => 'color: #808080;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://help.sap.com/abapdocu/en/ABAP{FNAMEU}.htm',
+        2 => 'http://help.sap.com/abapdocu/en/ABAP{FNAMEU}.htm',
+        3 => 'http://help.sap.com/abapdocu/en/ABAP{FNAMEU}.htm',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => '',
+        8 => '',
+        9 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '-&gt;',
+        2 => '=&gt;'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            7 => array(
+                'SPACE_AS_WHITESPACE' => true
+                ),
+            8 => array(
+                'SPACE_AS_WHITESPACE' => true
+                ),
+            9 => array(
+                'SPACE_AS_WHITESPACE' => true
+                )
+            )
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/actionscript.php b/examples/includes/geshi/geshi/actionscript.php
new file mode 100644 (file)
index 0000000..658491d
--- /dev/null
@@ -0,0 +1,197 @@
+<?php
+/*************************************************************************************
+ * actionscript.php
+ * ----------------
+ * Author: Steffen Krause (Steffen.krause@muse.de)
+ * Copyright: (c) 2004 Steffen Krause, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/20
+ *
+ * Actionscript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'ActionScript',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            '#include', 'for', 'foreach', 'if', 'elseif', 'else', 'while', 'do', 'dowhile',
+            'endwhile', 'endif', 'switch', 'case', 'endswitch', 'return', 'break', 'continue', 'in'
+            ),
+        2 => array(
+            'null', 'false', 'true', 'var',
+            'default', 'function', 'class',
+            'new', '_global'
+            ),
+        3 => array(
+            '#endinitclip', '#initclip', '__proto__', '_accProps', '_alpha', '_currentframe',
+            '_droptarget', '_focusrect', '_framesloaded', '_height', '_highquality', '_lockroot',
+            '_name', '_parent', '_quality', '_root', '_rotation', '_soundbuftime', '_target', '_totalframes',
+            '_url', '_visible', '_width', '_x', '_xmouse', '_xscale', '_y', '_ymouse', '_yscale', 'abs',
+            'Accessibility', 'acos', 'activityLevel', 'add', 'addListener', 'addPage', 'addProperty',
+            'addRequestHeader', 'align', 'allowDomain', 'allowInsecureDomain', 'and', 'appendChild',
+            'apply', 'Arguments', 'Array', 'asfunction', 'asin', 'atan', 'atan2', 'attachAudio', 'attachMovie',
+            'attachSound', 'attachVideo', 'attributes', 'autosize', 'avHardwareDisable', 'background',
+            'backgroundColor', 'BACKSPACE', 'bandwidth', 'beginFill', 'beginGradientFill', 'blockIndent',
+            'bold', 'Boolean', 'border', 'borderColor', 'bottomScroll', 'bufferLength', 'bufferTime',
+            'builtInItems', 'bullet', 'Button', 'bytesLoaded', 'bytesTotal', 'call', 'callee', 'caller',
+            'Camera', 'capabilities', 'CAPSLOCK', 'caption', 'catch', 'ceil', 'charAt', 'charCodeAt',
+            'childNodes', 'chr', 'clear', 'clearInterval', 'cloneNode', 'close', 'Color', 'concat',
+            'connect', 'condenseWhite', 'constructor', 'contentType', 'ContextMenu', 'ContextMenuItem',
+            'CONTROL', 'copy', 'cos', 'createElement', 'createEmptyMovieClip', 'createTextField',
+            'createTextNode', 'currentFps', 'curveTo', 'CustomActions', 'customItems', 'data', 'Date',
+            'deblocking', 'delete', 'DELETEKEY', 'docTypeDecl', 'domain', 'DOWN',
+            'duplicateMovieClip', 'duration', 'dynamic', 'E', 'embedFonts', 'enabled',
+            'END', 'endFill', 'ENTER', 'eq', 'Error', 'ESCAPE(Konstante)', 'escape(Funktion)', 'eval',
+            'exactSettings', 'exp', 'extends', 'finally', 'findText', 'firstChild', 'floor',
+            'flush', 'focusEnabled', 'font', 'fps', 'fromCharCode', 'fscommand',
+            'gain', 'ge', 'get', 'getAscii', 'getBeginIndex', 'getBounds', 'getBytesLoaded', 'getBytesTotal',
+            'getCaretIndex', 'getCode', 'getCount', 'getDate', 'getDay', 'getDepth', 'getEndIndex', 'getFocus',
+            'getFontList', 'getFullYear', 'getHours', 'getInstanceAtDepth', 'getLocal', 'getMilliseconds',
+            'getMinutes', 'getMonth', 'getNewTextFormat', 'getNextHighestDepth', 'getPan', 'getProgress',
+            'getProperty', 'getRGB', 'getSeconds', 'getSelected', 'getSelectedText', 'getSize', 'getStyle',
+            'getStyleNames', 'getSWFVersion', 'getText', 'getTextExtent', 'getTextFormat', 'getTextSnapshot',
+            'getTime', 'getTimer', 'getTimezoneOffset', 'getTransform', 'getURL', 'getUTCDate', 'getUTCDay',
+            'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds',
+            'getVersion', 'getVolume', 'getYear', 'globalToLocal', 'goto', 'gotoAndPlay', 'gotoAndStop',
+            'hasAccessibility', 'hasAudio', 'hasAudioEncoder', 'hasChildNodes', 'hasEmbeddedVideo', 'hasMP3',
+            'hasPrinting', 'hasScreenBroadcast', 'hasScreenPlayback', 'hasStreamingAudio', 'hasStreamingVideo',
+            'hasVideoEncoder', 'height', 'hide', 'hideBuiltInItems', 'hitArea', 'hitTest', 'hitTestTextNearPos',
+            'HOME', 'hscroll', 'html', 'htmlText', 'ID3', 'ifFrameLoaded', 'ignoreWhite', 'implements',
+            'import', 'indent', 'index', 'indexOf', 'Infinity', '-Infinity', 'INSERT', 'insertBefore', 'install',
+            'instanceof', 'int', 'interface', 'isActive', 'isDebugger', 'isDown', 'isFinite', 'isNaN', 'isToggled',
+            'italic', 'join', 'Key', 'language', 'lastChild', 'lastIndexOf', 'le', 'leading', 'LEFT', 'leftMargin',
+            'length', 'level', 'lineStyle', 'lineTo', 'list', 'LN10', 'LN2', 'load', 'loadClip', 'loaded', 'loadMovie',
+            'loadMovieNum', 'loadSound', 'loadVariables', 'loadVariablesNum', 'LoadVars', 'LocalConnection',
+            'localFileReadDisable', 'localToGlobal', 'log', 'LOG10E', 'LOG2E', 'manufacturer', 'Math', 'max',
+            'MAX_VALUE', 'maxChars', 'maxhscroll', 'maxscroll', 'mbchr', 'mblength', 'mbord', 'mbsubstring', 'menu',
+            'message', 'Microphone', 'min', 'MIN_VALUE', 'MMExecute', 'motionLevel', 'motionTimeOut', 'Mouse',
+            'mouseWheelEnabled', 'moveTo', 'Movieclip', 'MovieClipLoader', 'multiline', 'muted', 'name', 'names', 'NaN',
+            'ne', 'NEGATIVE_INFINITY', 'NetConnection', 'NetStream', 'newline', 'nextFrame',
+            'nextScene', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue', 'not', 'Number', 'Object',
+            'on', 'onActivity', 'onChanged', 'onClipEvent', 'onClose', 'onConnect', 'onData', 'onDragOut',
+            'onDragOver', 'onEnterFrame', 'onID3', 'onKeyDown', 'onKeyUp', 'onKillFocus', 'onLoad', 'onLoadComplete',
+            'onLoadError', 'onLoadInit', 'onLoadProgress', 'onLoadStart', 'onMouseDown', 'onMouseMove', 'onMouseUp',
+            'onMouseWheel', 'onPress', 'onRelease', 'onReleaseOutside', 'onResize', 'onRollOut', 'onRollOver',
+            'onScroller', 'onSelect', 'onSetFocus', 'onSoundComplete', 'onStatus', 'onUnload', 'onUpdate', 'onXML',
+            'or(logischesOR)', 'ord', 'os', 'parentNode', 'parseCSS', 'parseFloat', 'parseInt', 'parseXML', 'password',
+            'pause', 'PGDN', 'PGUP', 'PI', 'pixelAspectRatio', 'play', 'playerType', 'pop', 'position',
+            'POSITIVE_INFINITY', 'pow', 'prevFrame', 'previousSibling', 'prevScene', 'print', 'printAsBitmap',
+            'printAsBitmapNum', 'PrintJob', 'printNum', 'private', 'prototype', 'public', 'push', 'quality',
+            'random', 'rate', 'registerClass', 'removeListener', 'removeMovieClip', 'removeNode', 'removeTextField',
+            'replaceSel', 'replaceText', 'resolutionX', 'resolutionY', 'restrict', 'reverse', 'RIGHT',
+            'rightMargin', 'round', 'scaleMode', 'screenColor', 'screenDPI', 'screenResolutionX', 'screenResolutionY',
+            'scroll', 'seek', 'selectable', 'Selection', 'send', 'sendAndLoad', 'separatorBefore', 'serverString',
+            'set', 'setvariable', 'setBufferTime', 'setClipboard', 'setDate', 'setFocus', 'setFullYear', 'setGain',
+            'setHours', 'setInterval', 'setMask', 'setMilliseconds', 'setMinutes', 'setMode', 'setMonth',
+            'setMotionLevel', 'setNewTextFormat', 'setPan', 'setProperty', 'setQuality', 'setRate', 'setRGB',
+            'setSeconds', 'setSelectColor', 'setSelected', 'setSelection', 'setSilenceLevel', 'setStyle',
+            'setTextFormat', 'setTime', 'setTransform', 'setUseEchoSuppression', 'setUTCDate', 'setUTCFullYear',
+            'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setVolume',
+            'setYear', 'SharedObject', 'SHIFT(Konstante)', 'shift(Methode)', 'show', 'showMenu', 'showSettings',
+            'silenceLevel', 'silenceTimeout', 'sin', 'size', 'slice', 'smoothing', 'sort', 'sortOn', 'Sound', 'SPACE',
+            'splice', 'split', 'sqrt', 'SQRT1_2', 'SQRT2', 'Stage', 'start', 'startDrag', 'static', 'status', 'stop',
+            'stopAllSounds', 'stopDrag', 'String', 'StyleSheet(Klasse)', 'styleSheet(Eigenschaft)', 'substr',
+            'substring', 'super', 'swapDepths', 'System', 'TAB', 'tabChildren', 'tabEnabled', 'tabIndex',
+            'tabStops', 'tan', 'target', 'targetPath', 'tellTarget', 'text', 'textColor', 'TextField', 'TextFormat',
+            'textHeight', 'TextSnapshot', 'textWidth', 'this', 'throw', 'time', 'toggleHighQuality', 'toLowerCase',
+            'toString', 'toUpperCase', 'trace', 'trackAsMenu', 'try', 'type', 'typeof', 'undefined',
+            'underline', 'unescape', 'uninstall', 'unloadClip', 'unloadMovie', 'unLoadMovieNum', 'unshift', 'unwatch',
+            'UP', 'updateAfterEvent', 'updateProperties', 'url', 'useCodePage', 'useEchoSuppression', 'useHandCursor',
+            'UTC', 'valueOf', 'variable', 'version', 'Video', 'visible', 'void', 'watch', 'width',
+            'with', 'wordwrap', 'XML', 'xmlDecl', 'XMLNode', 'XMLSocket'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #0066CC;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/actionscript3.php b/examples/includes/geshi/geshi/actionscript3.php
new file mode 100644 (file)
index 0000000..b98002f
--- /dev/null
@@ -0,0 +1,467 @@
+<?php
+/*************************************************************************************
+ * actionscript3.php
+ * ----------------
+ * Author: Jordi Boggiano (j.boggiano@seld.be)
+ * Copyright: (c) 2007 Jordi Boggiano (http://www.seld.be/), Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/11/26
+ *
+ * ActionScript3 language file for GeSHi.
+ *
+ * All keywords scraped from the Flex 2.0.1 Documentation
+ *
+ * The default style is based on FlexBuilder2 coloring, with the addition of class, package, method and
+ * constant names that are highlighted to help identifying problem when used on public pastebins.
+ *
+ * For styling, keywords data from 0 to 1 (accessible through .kw1, etc.) are described here :
+ *
+ *   1 : operators
+ *   2 : 'var' keyword
+ *   3 : 'function' keyword
+ *   4 : 'class' and 'package' keywords
+ *   5 : all flash.* class names plus Top Level classes, mx are excluded
+ *   6 : all flash.* package names, mx are excluded
+ *   7 : valid flash method names and properties (there is no type checks sadly, for example String().x will be highlighted as 'x' is valid, but obviously strings don't have a x property)
+ *   8 : valid flash constant names (again, no type check)
+ *
+ *
+ * CHANGES
+ * -------
+ * 2007/12/06 (1.0.7.22)
+ *  -  Added the 'this' keyword (oops)
+ *
+ * TODO (updated 2007/11/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'ActionScript 3',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'with', 'while', 'void', 'undefined', 'typeof', 'try', 'true',
+            'throw', 'this', 'switch', 'super', 'set', 'return', 'public', 'protected',
+            'private', 'null', 'new', 'is', 'internal', 'instanceof', 'in',
+            'import', 'if', 'get', 'for', 'false', 'else', 'each', 'do',
+            'delete', 'default', 'continue', 'catch', 'case', 'break', 'as'
+            ),
+        2 => array(
+            'var'
+            ),
+        3 => array(
+            'function'
+            ),
+        4 => array(
+            'class', 'package'
+            ),
+        6 => array(
+            'flash.xml', 'flash.utils', 'flash.ui', 'flash.text',
+            'flash.system', 'flash.profiler', 'flash.printing', 'flash.net',
+            'flash.media', 'flash.geom', 'flash.filters', 'flash.external',
+            'flash.events', 'flash.errors', 'flash.display',
+            'flash.accessibility'
+            ),
+        7 => array(
+            'zoom', 'year', 'y', 'xmlDecl', 'x', 'writeUnsignedInt',
+            'writeUTFBytes', 'writeUTF', 'writeShort', 'writeObject',
+            'writeMultiByte', 'writeInt', 'writeFloat', 'writeExternal',
+            'writeDynamicProperty', 'writeDynamicProperties', 'writeDouble',
+            'writeBytes', 'writeByte', 'writeBoolean', 'wordWrap',
+            'willTrigger', 'width', 'volume', 'visible', 'videoWidth',
+            'videoHeight', 'version', 'valueOf', 'value', 'usingTLS',
+            'useRichTextClipboard', 'useHandCursor', 'useEchoSuppression',
+            'useCodePage', 'url', 'uri', 'uploadCompleteData', 'upload',
+            'updateProperties', 'updateAfterEvent', 'upState', 'unshift',
+            'unlock', 'unload', 'union', 'unescapeMultiByte', 'unescape',
+            'underline', 'uncompress', 'type', 'ty', 'tx', 'transparent',
+            'translate', 'transformPoint', 'transform', 'trackAsMenu', 'track',
+            'trace', 'totalMemory', 'totalFrames', 'topLeft', 'top',
+            'togglePause', 'toXMLString', 'toUpperCase', 'toUTCString',
+            'toTimeString', 'toString', 'toPrecision', 'toLowerCase',
+            'toLocaleUpperCase', 'toLocaleTimeString', 'toLocaleString',
+            'toLocaleLowerCase', 'toLocaleDateString', 'toFixed',
+            'toExponential', 'toDateString', 'timezoneOffset', 'timerComplete',
+            'timer', 'time', 'threshold', 'thickness', 'textWidth',
+            'textSnapshot', 'textInput', 'textHeight', 'textColor', 'text',
+            'test', 'target', 'tan', 'tabStops', 'tabIndexChange', 'tabIndex',
+            'tabEnabledChange', 'tabEnabled', 'tabChildrenChange',
+            'tabChildren', 'sync', 'swfVersion', 'swapChildrenAt',
+            'swapChildren', 'subtract', 'substring', 'substr', 'styleSheet',
+            'styleNames', 'strength', 'stopPropagation',
+            'stopImmediatePropagation', 'stopDrag', 'stopAll', 'stop', 'status',
+            'startDrag', 'start', 'stageY', 'stageX', 'stageWidth',
+            'stageHeight', 'stageFocusRect', 'stage', 'sqrt', 'split', 'splice',
+            'source', 'soundTransform', 'soundComplete', 'sortOn', 'sort',
+            'songName', 'some', 'socketData', 'smoothing', 'slice', 'size',
+            'sin', 'silent', 'silenceTimeout', 'silenceLevel', 'showSettings',
+            'showRedrawRegions', 'showDefaultContextMenu', 'show', 'shortcut',
+            'shiftKey', 'shift', 'sharpness', 'sharedEvents', 'shadowColor',
+            'shadowAlpha', 'settings', 'setUseEchoSuppression', 'setUTCSeconds',
+            'setUTCMonth', 'setUTCMinutes', 'setUTCMilliseconds', 'setUTCHours',
+            'setUTCFullYear', 'setUTCDate', 'setTimeout', 'setTime',
+            'setTextFormat', 'setStyle', 'setSilenceLevel', 'setSettings',
+            'setSelection', 'setSelected', 'setSelectColor', 'setSeconds',
+            'setQuality', 'setPropertyIsEnumerable', 'setProperty', 'setPixels',
+            'setPixel32', 'setPixel', 'setNamespace', 'setName',
+            'setMotionLevel', 'setMonth', 'setMode', 'setMinutes',
+            'setMilliseconds', 'setLoopback', 'setLoopBack', 'setLocalName',
+            'setKeyFrameInterval', 'setInterval', 'setHours', 'setFullYear',
+            'setEmpty', 'setDirty', 'setDate', 'setCompositionString',
+            'setClipboard', 'setChildren', 'setChildIndex',
+            'setAdvancedAntiAliasingTable', 'serverString', 'separatorBefore',
+            'sendToURL', 'send', 'selectionEndIndex', 'selectionBeginIndex',
+            'selectable', 'select', 'seek', 'securityError', 'securityDomain',
+            'secondsUTC', 'seconds', 'search', 'scrollV', 'scrollRect',
+            'scrollH', 'scroll', 'screenResolutionY', 'screenResolutionX',
+            'screenDPI', 'screenColor', 'scenes', 'scaleY', 'scaleX',
+            'scaleMode', 'scale9Grid', 'scale', 'save', 'sandboxType',
+            'sameDomain', 'running', 'round', 'rotation', 'rotate', 'root',
+            'rollOver', 'rollOut', 'rightToRight', 'rightToLeft', 'rightPeak',
+            'rightMargin', 'right', 'rewind', 'reverse', 'resume', 'restrict',
+            'resize', 'reset', 'requestHeaders', 'replaceText',
+            'replaceSelectedText', 'replace', 'repeatCount', 'render',
+            'removedFromStage', 'removed', 'removeNode', 'removeNamespace',
+            'removeEventListener', 'removeChildAt', 'removeChild',
+            'relatedObject', 'registerFont', 'registerClassAlias', 'redOffset',
+            'redMultiplier', 'rect', 'receiveVideo', 'receiveAudio',
+            'readUnsignedShort', 'readUnsignedInt', 'readUnsignedByte',
+            'readUTFBytes', 'readUTF', 'readShort', 'readObject',
+            'readMultiByte', 'readInt', 'readFloat', 'readExternal',
+            'readDouble', 'readBytes', 'readByte', 'readBoolean', 'ratios',
+            'rate', 'random', 'quality', 'push', 'publish', 'proxyType',
+            'prototype', 'propertyIsEnumerable', 'progress',
+            'processingInstructions', 'printAsBitmap', 'print',
+            'previousSibling', 'preventDefault', 'prevScene', 'prevFrame',
+            'prettyPrinting', 'prettyIndent', 'preserveAlpha', 'prependChild',
+            'prefix', 'pow', 'position', 'pop', 'polar', 'playerType', 'play',
+            'pixelSnapping', 'pixelDissolve', 'pixelBounds', 'pixelAspectRatio',
+            'perlinNoise', 'pause', 'parseXML', 'parseInt', 'parseFloat',
+            'parseCSS', 'parse', 'parentNode', 'parentDomain',
+            'parentAllowsChild', 'parent', 'parameters', 'paperWidth',
+            'paperHeight', 'pan', 'paletteMap', 'pageWidth', 'pageHeight',
+            'overState', 'outsideCutoff', 'os', 'orientation', 'open',
+            'opaqueBackground', 'onPlayStatus', 'onMetaData', 'onCuePoint',
+            'offsetPoint', 'offset', 'objectID', 'objectEncoding', 'numLock',
+            'numLines', 'numFrames', 'numChildren', 'normalize', 'noise',
+            'nodeValue', 'nodeType', 'nodeName', 'nodeKind', 'noAutoLabeling',
+            'nextValue', 'nextSibling', 'nextScene', 'nextNameIndex',
+            'nextName', 'nextFrame', 'netStatus', 'navigateToURL',
+            'namespaceURI', 'namespaceDeclarations', 'namespace', 'names',
+            'name', 'muted', 'multiline', 'moveTo', 'mouseY', 'mouseX',
+            'mouseWheelEnabled', 'mouseWheel', 'mouseUp', 'mouseTarget',
+            'mouseOver', 'mouseOut', 'mouseMove', 'mouseLeave',
+            'mouseFocusChange', 'mouseEnabled', 'mouseDown', 'mouseChildren',
+            'motionTimeout', 'motionLevel', 'monthUTC', 'month',
+            'modificationDate', 'mode', 'minutesUTC', 'minutes', 'min',
+            'millisecondsUTC', 'milliseconds', 'method', 'message', 'merge',
+            'menuSelect', 'menuItemSelect', 'maxScrollV', 'maxScrollH',
+            'maxLevel', 'maxChars', 'max', 'matrixY', 'matrixX', 'matrix',
+            'match', 'mask', 'mapPoint', 'mapBitmap', 'map', 'manufacturer',
+            'macType', 'loopback', 'loop', 'log', 'lock', 'localeCompare',
+            'localY', 'localX', 'localToGlobal', 'localName',
+            'localFileReadDisable', 'loaderURL', 'loaderInfo', 'loader',
+            'loadPolicyFile', 'loadBytes', 'load', 'liveDelay', 'link',
+            'lineTo', 'lineStyle', 'lineGradientStyle', 'level',
+            'letterSpacing', 'length', 'leftToRight', 'leftToLeft', 'leftPeak',
+            'leftMargin', 'left', 'leading', 'lastIndexOf', 'lastIndex',
+            'lastChild', 'language', 'labels', 'knockout', 'keyUp',
+            'keyLocation', 'keyFrameInterval', 'keyFocusChange', 'keyDown',
+            'keyCode', 'kerning', 'join', 'italic', 'isXMLName',
+            'isPrototypeOf', 'isNaN', 'isFocusInaccessible', 'isFinite',
+            'isEmpty', 'isDefaultPrevented', 'isDebugger', 'isBuffering',
+            'isAttribute', 'isAccessible', 'ioError', 'invert', 'invalidate',
+            'intersects', 'intersection', 'interpolate', 'insideCutoff',
+            'insertChildBefore', 'insertChildAfter', 'insertBefore', 'inner',
+            'init', 'info', 'inflatePoint', 'inflate', 'indexOf', 'index',
+            'indent', 'inScopeNamespaces', 'imeComposition', 'ime',
+            'ignoreWhitespace', 'ignoreWhite', 'ignoreProcessingInstructions',
+            'ignoreComments', 'ignoreCase', 'identity', 'idMap', 'id3',
+            'httpStatus', 'htmlText', 'hoursUTC', 'hours', 'hitTestTextNearPos',
+            'hitTestState', 'hitTestPoint', 'hitTestObject', 'hitTest',
+            'hitArea', 'highlightColor', 'highlightAlpha', 'hideObject',
+            'hideBuiltInItems', 'hide', 'height', 'hasVideoEncoder', 'hasTLS',
+            'hasStreamingVideo', 'hasStreamingAudio', 'hasSimpleContent',
+            'hasScreenPlayback', 'hasScreenBroadcast', 'hasProperty',
+            'hasPrinting', 'hasOwnProperty', 'hasMP3', 'hasIME', 'hasGlyphs',
+            'hasEventListener', 'hasEmbeddedVideo', 'hasDefinition',
+            'hasComplexContent', 'hasChildNodes', 'hasAudioEncoder', 'hasAudio',
+            'hasAccessibility', 'gridFitType', 'greenOffset', 'greenMultiplier',
+            'graphics', 'gotoAndStop', 'gotoAndPlay', 'globalToLocal', 'global',
+            'getUTCSeconds', 'getUTCMonth', 'getUTCMinutes',
+            'getUTCMilliseconds', 'getUTCHours', 'getUTCFullYear', 'getUTCDay',
+            'getUTCDate', 'getTimezoneOffset', 'getTimer', 'getTime',
+            'getTextRunInfo', 'getTextFormat', 'getText', 'getStyle',
+            'getStackTrace', 'getSelectedText', 'getSelected', 'getSeconds',
+            'getRemote', 'getRect', 'getQualifiedSuperclassName',
+            'getQualifiedClassName', 'getProperty', 'getPrefixForNamespace',
+            'getPixels', 'getPixel32', 'getPixel', 'getParagraphLength',
+            'getObjectsUnderPoint', 'getNamespaceForPrefix', 'getMonth',
+            'getMinutes', 'getMilliseconds', 'getMicrophone', 'getLocal',
+            'getLineText', 'getLineOffset', 'getLineMetrics', 'getLineLength',
+            'getLineIndexOfChar', 'getLineIndexAtPoint', 'getImageReference',
+            'getHours', 'getFullYear', 'getFirstCharInParagraph',
+            'getDescendants', 'getDefinitionByName', 'getDefinition', 'getDay',
+            'getDate', 'getColorBoundsRect', 'getClassByAlias', 'getChildIndex',
+            'getChildByName', 'getChildAt', 'getCharIndexAtPoint',
+            'getCharBoundaries', 'getCamera', 'getBounds', 'genre',
+            'generateFilterRect', 'gain', 'fullYearUTC', 'fullYear',
+            'fullScreen', 'fscommand', 'fromCharCode', 'framesLoaded',
+            'frameRate', 'frame', 'fps', 'forwardAndBack', 'formatToString',
+            'forceSimple', 'forEach', 'fontType', 'fontStyle', 'fontSize',
+            'fontName', 'font', 'focusRect', 'focusOut', 'focusIn', 'focus',
+            'flush', 'floor', 'floodFill', 'firstChild', 'findText', 'filters',
+            'filter', 'fillRect', 'fileList', 'extension', 'extended', 'exp',
+            'exec', 'exactSettings', 'every', 'eventPhase', 'escapeMultiByte',
+            'escape', 'errorID', 'error', 'equals', 'enumerateFonts',
+            'enterFrame', 'endian', 'endFill', 'encodeURIComponent',
+            'encodeURI', 'enabled', 'embedFonts', 'elements',
+            'dynamicPropertyWriter', 'dropTarget', 'drawRoundRect', 'drawRect',
+            'drawEllipse', 'drawCircle', 'draw', 'download', 'downState',
+            'doubleClickEnabled', 'doubleClick', 'dotall', 'domain',
+            'docTypeDecl', 'doConversion', 'divisor', 'distance', 'dispose',
+            'displayState', 'displayMode', 'displayAsPassword', 'dispatchEvent',
+            'description', 'describeType', 'descent', 'descendants',
+            'deltaTransformPoint', 'delta', 'deleteProperty', 'delay',
+            'defaultTextFormat', 'defaultSettings', 'defaultObjectEncoding',
+            'decodeURIComponent', 'decodeURI', 'decode', 'deblocking',
+            'deactivate', 'dayUTC', 'day', 'dateUTC', 'date', 'dataFormat',
+            'data', 'd', 'customItems', 'curveTo', 'currentTarget',
+            'currentScene', 'currentLabels', 'currentLabel', 'currentFrame',
+            'currentFPS', 'currentDomain', 'currentCount', 'ctrlKey', 'creator',
+            'creationDate', 'createTextNode', 'createGradientBox',
+            'createElement', 'createBox', 'cos', 'copyPixels', 'copyChannel',
+            'copy', 'conversionMode', 'contextMenuOwner', 'contextMenu',
+            'contentType', 'contentLoaderInfo', 'content', 'containsRect',
+            'containsPoint', 'contains', 'constructor', 'connectedProxyType',
+            'connected', 'connect', 'condenseWhite', 'concatenatedMatrix',
+            'concatenatedColorTransform', 'concat', 'computeSpectrum',
+            'compress', 'componentY', 'componentX', 'complete', 'compare',
+            'comments', 'comment', 'colors', 'colorTransform', 'color', 'code',
+            'close', 'cloneNode', 'clone', 'client', 'click', 'clearTimeout',
+            'clearInterval', 'clear', 'clamp', 'children', 'childNodes',
+            'childIndex', 'childAllowsParent', 'child', 'checkPolicyFile',
+            'charCount', 'charCodeAt', 'charCode', 'charAt', 'changeList',
+            'change', 'ceil', 'caretIndex', 'caption', 'capsLock', 'cancelable',
+            'cancel', 'callee', 'callProperty', 'call', 'cacheAsBitmap', 'c',
+            'bytesTotal', 'bytesLoaded', 'bytesAvailable', 'buttonMode',
+            'buttonDown', 'bullet', 'builtInItems', 'bufferTime',
+            'bufferLength', 'bubbles', 'browse', 'bottomScrollV', 'bottomRight',
+            'bottom', 'borderColor', 'border', 'bold', 'blurY', 'blurX',
+            'blueOffset', 'blueMultiplier', 'blockIndent', 'blendMode',
+            'bitmapData', 'bias', 'beginGradientFill', 'beginFill',
+            'beginBitmapFill', 'bandwidth', 'backgroundColor', 'background',
+            'b', 'available', 'avHardwareDisable', 'autoSize', 'attributes',
+            'attribute', 'attachNetStream', 'attachCamera', 'attachAudio',
+            'atan2', 'atan', 'asyncError', 'asin', 'ascent', 'artist',
+            'areSoundsInaccessible', 'areInaccessibleObjectsUnderPoint',
+            'applyFilter', 'apply', 'applicationDomain', 'appendText',
+            'appendChild', 'antiAliasType', 'angle', 'alwaysShowSelection',
+            'altKey', 'alphas', 'alphaOffset', 'alphaMultiplier', 'alpha',
+            'allowInsecureDomain', 'allowDomain', 'align', 'album',
+            'addedToStage', 'added', 'addPage', 'addNamespace', 'addHeader',
+            'addEventListener', 'addChildAt', 'addChild', 'addCallback', 'add',
+            'activityLevel', 'activity', 'active', 'activating', 'activate',
+            'actionScriptVersion', 'acos', 'accessibilityProperties', 'abs'
+            ),
+        8 => array(
+            'WRAP', 'VERTICAL', 'VARIABLES',
+            'UTC', 'UPLOAD_COMPLETE_DATA', 'UP', 'UNLOAD', 'UNKNOWN',
+            'UNIQUESORT', 'TOP_RIGHT', 'TOP_LEFT', 'TOP', 'TIMER_COMPLETE',
+            'TIMER', 'TEXT_NODE', 'TEXT_INPUT', 'TEXT', 'TAB_INDEX_CHANGE',
+            'TAB_ENABLED_CHANGE', 'TAB_CHILDREN_CHANGE', 'TAB', 'SYNC',
+            'SUBTRACT', 'SUBPIXEL', 'STATUS', 'STANDARD', 'SQUARE', 'SQRT2',
+            'SQRT1_2', 'SPACE', 'SOUND_COMPLETE', 'SOCKET_DATA', 'SHOW_ALL',
+            'SHIFT', 'SETTINGS_MANAGER', 'SELECT', 'SECURITY_ERROR', 'SCROLL',
+            'SCREEN', 'ROUND', 'ROLL_OVER', 'ROLL_OUT', 'RIGHT', 'RGB',
+            'RETURNINDEXEDARRAY', 'RESIZE', 'REPEAT', 'RENDER',
+            'REMOVED_FROM_STAGE', 'REMOVED', 'REMOTE', 'REGULAR', 'REFLECT',
+            'RED', 'RADIAL', 'PROGRESS', 'PRIVACY', 'POST', 'POSITIVE_INFINITY',
+            'PORTRAIT', 'PIXEL', 'PI', 'PENDING', 'PAGE_UP', 'PAGE_DOWN', 'PAD',
+            'OVERLAY', 'OUTER', 'OPEN', 'NaN', 'NUM_PAD', 'NUMPAD_SUBTRACT',
+            'NUMPAD_MULTIPLY', 'NUMPAD_ENTER', 'NUMPAD_DIVIDE',
+            'NUMPAD_DECIMAL', 'NUMPAD_ADD', 'NUMPAD_9', 'NUMPAD_8', 'NUMPAD_7',
+            'NUMPAD_6', 'NUMPAD_5', 'NUMPAD_4', 'NUMPAD_3', 'NUMPAD_2',
+            'NUMPAD_1', 'NUMPAD_0', 'NUMERIC', 'NO_SCALE', 'NO_BORDER',
+            'NORMAL', 'NONE', 'NEVER', 'NET_STATUS', 'NEGATIVE_INFINITY',
+            'MULTIPLY', 'MOUSE_WHEEL', 'MOUSE_UP', 'MOUSE_OVER', 'MOUSE_OUT',
+            'MOUSE_MOVE', 'MOUSE_LEAVE', 'MOUSE_FOCUS_CHANGE', 'MOUSE_DOWN',
+            'MITER', 'MIN_VALUE', 'MICROPHONE', 'MENU_SELECT',
+            'MENU_ITEM_SELECT', 'MEDIUM', 'MAX_VALUE', 'LOW', 'LOG2E', 'LOG10E',
+            'LOCAL_WITH_NETWORK', 'LOCAL_WITH_FILE', 'LOCAL_TRUSTED',
+            'LOCAL_STORAGE', 'LN2', 'LN10', 'LITTLE_ENDIAN', 'LINK',
+            'LINEAR_RGB', 'LINEAR', 'LIGHT_COLOR', 'LIGHTEN', 'LEFT', 'LCD',
+            'LAYER', 'LANDSCAPE', 'KOREAN', 'KEY_UP', 'KEY_FOCUS_CHANGE',
+            'KEY_DOWN', 'JUSTIFY', 'JAPANESE_KATAKANA_HALF',
+            'JAPANESE_KATAKANA_FULL', 'JAPANESE_HIRAGANA', 'Infinity', 'ITALIC',
+            'IO_ERROR', 'INVERT', 'INSERT', 'INPUT', 'INNER', 'INIT',
+            'IME_COMPOSITION', 'IGNORE', 'ID3', 'HTTP_STATUS', 'HORIZONTAL',
+            'HOME', 'HIGH', 'HARDLIGHT', 'GREEN', 'GET', 'FULLSCREEN', 'FULL',
+            'FOCUS_OUT', 'FOCUS_IN', 'FLUSHED', 'FLASH9', 'FLASH8', 'FLASH7',
+            'FLASH6', 'FLASH5', 'FLASH4', 'FLASH3', 'FLASH2', 'FLASH1', 'F9',
+            'F8', 'F7', 'F6', 'F5', 'F4', 'F3', 'F2', 'F15', 'F14', 'F13',
+            'F12', 'F11', 'F10', 'F1', 'EXACT_FIT', 'ESCAPE', 'ERROR', 'ERASE',
+            'ENTER_FRAME', 'ENTER', 'END', 'EMBEDDED', 'ELEMENT_NODE', 'E',
+            'DYNAMIC', 'DOWN', 'DOUBLE_CLICK', 'DIFFERENCE', 'DEVICE',
+            'DESCENDING', 'DELETE', 'DEFAULT', 'DEACTIVATE', 'DATA',
+            'DARK_COLOR', 'DARKEN', 'CRT', 'CONTROL', 'CONNECT', 'COMPLETE',
+            'COLOR', 'CLOSE', 'CLICK', 'CLAMP', 'CHINESE', 'CHANGE', 'CENTER',
+            'CASEINSENSITIVE', 'CAPTURING_PHASE', 'CAPS_LOCK', 'CANCEL',
+            'CAMERA', 'BUBBLING_PHASE', 'BOTTOM_RIGHT', 'BOTTOM_LEFT', 'BOTTOM',
+            'BOLD_ITALIC', 'BOLD', 'BLUE', 'BINARY', 'BIG_ENDIAN', 'BEVEL',
+            'BEST', 'BACKSPACE', 'AUTO', 'AT_TARGET', 'ASYNC_ERROR', 'AMF3',
+            'AMF0', 'ALWAYS', 'ALPHANUMERIC_HALF', 'ALPHANUMERIC_FULL', 'ALPHA',
+            'ADVANCED', 'ADDED_TO_STAGE', 'ADDED', 'ADD', 'ACTIVITY',
+            'ACTIONSCRIPT3', 'ACTIONSCRIPT2'
+            ),
+        //FIX: Must be last in order to avoid conflicts with keywords present
+        //in other keyword groups, that might get highlighted as part of the URL.
+        //I know this is not a proper work-around, but should do just fine.
+        5 => array(
+            'uint', 'int', 'arguments', 'XMLSocket', 'XMLNodeType', 'XMLNode',
+            'XMLList', 'XMLDocument', 'XML', 'Video', 'VerifyError',
+            'URLVariables', 'URLStream', 'URLRequestMethod', 'URLRequestHeader',
+            'URLRequest', 'URLLoaderDataFormat', 'URLLoader', 'URIError',
+            'TypeError', 'Transform', 'TimerEvent', 'Timer', 'TextSnapshot',
+            'TextRenderer', 'TextLineMetrics', 'TextFormatAlign', 'TextFormat',
+            'TextFieldType', 'TextFieldAutoSize', 'TextField', 'TextEvent',
+            'TextDisplayMode', 'TextColorType', 'System', 'SyntaxError',
+            'SyncEvent', 'StyleSheet', 'String', 'StatusEvent', 'StaticText',
+            'StageScaleMode', 'StageQuality', 'StageAlign', 'Stage',
+            'StackOverflowError', 'Sprite', 'SpreadMethod', 'SoundTransform',
+            'SoundMixer', 'SoundLoaderContext', 'SoundChannel', 'Sound',
+            'Socket', 'SimpleButton', 'SharedObjectFlushStatus', 'SharedObject',
+            'Shape', 'SecurityPanel', 'SecurityErrorEvent', 'SecurityError',
+            'SecurityDomain', 'Security', 'ScriptTimeoutError', 'Scene',
+            'SWFVersion', 'Responder', 'RegExp', 'ReferenceError', 'Rectangle',
+            'RangeError', 'QName', 'Proxy', 'ProgressEvent',
+            'PrintJobOrientation', 'PrintJobOptions', 'PrintJob', 'Point',
+            'PixelSnapping', 'ObjectEncoding', 'Object', 'Number', 'NetStream',
+            'NetStatusEvent', 'NetConnection', 'Namespace', 'MovieClip',
+            'MouseEvent', 'Mouse', 'MorphShape', 'Microphone', 'MemoryError',
+            'Matrix', 'Math', 'LocalConnection', 'LoaderInfo', 'LoaderContext',
+            'Loader', 'LineScaleMode', 'KeyboardEvent', 'Keyboard',
+            'KeyLocation', 'JointStyle', 'InvalidSWFError',
+            'InterpolationMethod', 'InteractiveObject', 'IllegalOperationError',
+            'IOErrorEvent', 'IOError', 'IMEEvent', 'IMEConversionMode', 'IME',
+            'IExternalizable', 'IEventDispatcher', 'IDynamicPropertyWriter',
+            'IDynamicPropertyOutput', 'IDataOutput', 'IDataInput', 'ID3Info',
+            'IBitmapDrawable', 'HTTPStatusEvent', 'GridFitType', 'Graphics',
+            'GradientType', 'GradientGlowFilter', 'GradientBevelFilter',
+            'GlowFilter', 'Function', 'FrameLabel', 'FontType', 'FontStyle',
+            'Font', 'FocusEvent', 'FileReferenceList', 'FileReference',
+            'FileFilter', 'ExternalInterface', 'EventPhase', 'EventDispatcher',
+            'Event', 'EvalError', 'ErrorEvent', 'Error', 'Endian', 'EOFError',
+            'DropShadowFilter', 'DisplayObjectContainer', 'DisplayObject',
+            'DisplacementMapFilterMode', 'DisplacementMapFilter', 'Dictionary',
+            'DefinitionError', 'Date', 'DataEvent', 'ConvolutionFilter',
+            'ContextMenuItem', 'ContextMenuEvent', 'ContextMenuBuiltInItems',
+            'ContextMenu', 'ColorTransform', 'ColorMatrixFilter', 'Class',
+            'CapsStyle', 'Capabilities', 'Camera', 'CSMSettings', 'ByteArray',
+            'Boolean', 'BlurFilter', 'BlendMode', 'BitmapFilterType',
+            'BitmapFilterQuality', 'BitmapFilter', 'BitmapDataChannel',
+            'BitmapData', 'Bitmap', 'BevelFilter', 'AsyncErrorEvent', 'Array',
+            'ArgumentError', 'ApplicationDomain', 'AntiAliasType',
+            'ActivityEvent', 'ActionScriptVersion', 'AccessibilityProperties',
+            'Accessibility', 'AVM1Movie'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '%', '&', '*', '|', '/', '<', '>', '^', '-', '+', '~', '?', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0033ff; font-weight: bold;',
+            2 => 'color: #6699cc; font-weight: bold;',
+            3 => 'color: #339966; font-weight: bold;',
+            4 => 'color: #9900cc; font-weight: bold;',
+            5 => 'color: #004993;',
+            6 => 'color: #004993;',
+            7 => 'color: #004993;',
+            8 => 'color: #004993;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #009900;',
+            'MULTI' => 'color: #3f5fbf;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #990000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000; font-weight:bold;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #000000;',
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => 'http://www.google.com/search?q={FNAMEL}%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:{FNAMEL}.html&amp;filter=0&amp;num=100&amp;btnI=lucky',
+        6 => '',
+        7 => '',
+        8 => ''
+        ),
+    'OOLANG' => false,//Save some time as OO identifiers aren't used
+    'OBJECT_SPLITTERS' => array(
+        // commented out because it's not very relevant for AS, as all properties, methods and constants are dot-accessed.
+        // I believe it's preferable to have package highlighting for example, which is not possible with this enabled.
+        // 0 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/ada.php b/examples/includes/geshi/geshi/ada.php
new file mode 100644 (file)
index 0000000..1013883
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+/*************************************************************************************
+ * ada.php
+ * -------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/29
+ *
+ * Ada language file for GeSHi.
+ * Words are from SciTe configuration file
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.2)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   -  Removed apostrophe as string delimiter
+ *   -  Added URL support
+ * 2004/08/05 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Ada',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'begin', 'declare', 'do', 'else', 'elsif', 'exception', 'for', 'if',
+            'is', 'loop', 'while', 'then', 'end', 'select', 'case', 'until',
+            'goto', 'return'
+            ),
+        2 => array(
+            'abs', 'and', 'mod', 'not', 'or', 'rem', 'xor'
+            ),
+        3 => array(
+            'abort', 'abstract', 'accept', 'access', 'aliased', 'all', 'array', 'at', 'body',
+            'constant', 'delay', 'delta', 'digits', 'entry', 'exit',
+            'function', 'generic', 'in', 'limited', 'new', 'null', 'of', 'others', 'out', 'package', 'pragma',
+            'private', 'procedure', 'protected', 'raise', 'range', 'record', 'renames', 'requeue', 'reverse',
+            'separate', 'subtype', 'tagged', 'task', 'terminate', 'type', 'use', 'when', 'with'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00007f;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #46aa03; font-weight:bold;',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/apache.php b/examples/includes/geshi/geshi/apache.php
new file mode 100644 (file)
index 0000000..fa06afe
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+/*************************************************************************************
+ * apache.php
+ * ----------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/29/07
+ *
+ * Apache language file for GeSHi.
+ * Words are from SciTe configuration file
+ *
+ * CHANGES
+ * -------
+ * 2008/17/06 (1.0.8)
+ *  -  Added support for apache configuration sections (milian)
+ *  -  Added missing php keywords (milian)
+ *  -  Added some more keywords
+ *  -  Disabled highlighting of brackets by default
+ * 2004/11/27 (1.0.2)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/07/29)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Apache configuration',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        /*keywords*/
+        1 => array(
+            'accessconfig','accessfilename','action','addalt',
+            'addaltbyencoding','addaltbytype','addcharset',
+            'adddefaultcharset','adddescription',
+            'addencoding','addhandler','addicon','addiconbyencoding',
+            'addiconbytype','addlanguage','addmodule','addmoduleinfo',
+            'addtype','agentlog','alias','aliasmatch',
+            'allow','allowconnect','allowoverride','anonymous',
+            'anonymous_authoritative','anonymous_logemail','anonymous_mustgiveemail',
+            'anonymous_nouserid','anonymous_verifyemail','authauthoritative',
+            'authdbauthoritative','authdbgroupfile','authdbmauthoritative',
+            'authdbmgroupfile','authdbuserfile','authdbmuserfile',
+            'authdigestfile','authgroupfile','authname','authtype',
+            'authuserfile','bindaddress','browsermatch','browsermatchnocase',
+            'bs2000account','cachedefaultexpire','cachedirlength','cachedirlevels',
+            'cacheforcecompletion','cachegcinterval','cachelastmodifiedfactor','cachemaxexpire',
+            'cachenegotiateddocs','cacheroot','cachesize','checkspelling',
+            'clearmodulelist','contentdigest','cookieexpires','cookielog',
+            'cookietracking','coredumpdirectory','customlog',
+            'defaulticon','defaultlanguage','defaulttype','define',
+            'deny','directory','directorymatch','directoryindex',
+            'documentroot','errordocument','errorlog','example',
+            'expiresactive','expiresbytype','expiresdefault','extendedstatus',
+            'fancyindexing','files','filesmatch','forcetype',
+            'group','header','headername','hostnamelookups',
+            'identitycheck','ifdefine','ifmodule','imapbase',
+            'imapdefault','imapmenu','include','indexignore','indexorderdefault',
+            'indexoptions','keepalive','keepalivetimeout','languagepriority',
+            'limit','limitexcept','limitrequestbody','limitrequestfields',
+            'limitrequestfieldsize','limitrequestline','listen','listenbacklog',
+            'loadfile','loadmodule','location','locationmatch',
+            'lockfile','logformat','loglevel','maxclients',
+            'maxkeepaliverequests','maxrequestsperchild','maxspareservers','maxsparethreads','metadir',
+            'metafiles','metasuffix','mimemagicfile','minspareservers','minsparethreads',
+            'mmapfile','namevirtualhost','nocache','options','order',
+            'passenv','php_admin_value','php_admin_flag','php_value','pidfile','port','proxyblock','proxydomain',
+            'proxypass','proxypassreverse','proxyreceivebuffersize','proxyremote',
+            'proxyrequests','proxyvia','qsc','readmename',
+            'redirect','redirectmatch','redirectpermanent','redirecttemp',
+            'refererignore','refererlog','removehandler','require',
+            'resourceconfig','rewritebase','rewritecond','rewriteengine',
+            'rewritelock','rewritelog','rewriteloglevel','rewritemap',
+            'rewriteoptions','rewriterule','rlimitcpu','rlimitmem',
+            'rlimitnproc','satisfy','scoreboardfile','script',
+            'scriptalias','scriptaliasmatch','scriptinterpretersource','scriptlog',
+            'scriptlogbuffer','scriptloglength','sendbuffersize',
+            'serveradmin','serveralias','servername','serverpath',
+            'serverroot','serversignature','servertokens','servertype',
+            'setenv','setenvif','setenvifnocase','sethandler',
+            'singlelisten','startservers','threadsperchild','timeout',
+            'transferlog','typesconfig','unsetenv','usecanonicalname',
+            'user','userdir','virtualhost','virtualdocumentroot',
+            'virtualdocumentrootip','virtualscriptalias','virtualscriptaliasip',
+            'xbithack','from','all'
+            ),
+        /*keywords 2*/
+        2 => array(
+            'on','off','standalone','inetd','indexes',
+            'force-response-1.0','downgrade-1.0','nokeepalive',
+            'ndexes','includes','followsymlinks','none',
+            'x-compress','x-gzip'
+        ),
+        /*keywords 3*/
+        3 => array(
+            'Directory',
+            'DirectoryMatch',
+            'Files',
+            'FilesMatch',
+            'IfDefine',
+            'IfModule',
+            'IfVersion',
+            'Location',
+            'LocationMatch',
+            'Proxy',
+            'ProxyMatch',
+            'VirtualHost'
+        )
+    ),
+    'SYMBOLS' => array(
+        '+', '-'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00007f;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #000000; font-weight:bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #339933;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'BRACKETS' => GESHI_NEVER,
+            'SYMBOLS' => GESHI_NEVER
+        ),
+        'KEYWORDS' => array(
+            3 => array(
+                'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+                'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+            )
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/applescript.php b/examples/includes/geshi/geshi/applescript.php
new file mode 100644 (file)
index 0000000..395bba7
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/*************************************************************************************
+ * applescript.php
+ * --------
+ * Author: Stephan Klimek (http://www.initware.org)
+ * Copyright: Stephan Klimek (http://www.initware.org)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/07/20
+ *
+ * AppleScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ *
+ * TODO
+ * -------------------------
+ * URL settings to references
+ *
+ **************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'AppleScript',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array( '(*' => '*)'),
+    'COMMENT_REGEXP' => array(
+        2 => '/(?<=[a-z])\'/i',
+        3 => '/(?<![a-z])\'.*?\'/i',
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'application','close','count','delete','duplicate','exists','launch','make','move','open',
+            'print','quit','reopen','run','save','saving', 'idle', 'path to', 'number', 'alias', 'list', 'text', 'string',
+            'integer', 'it','me','version','pi','result','space','tab','anything','case','diacriticals','expansion',
+            'hyphens','punctuation','bold','condensed','expanded','hidden','italic','outline','plain',
+            'shadow','strikethrough','subscript','superscript','underline','ask','no','yes','false', 'id',
+            'true','weekday','monday','mon','tuesday','tue','wednesday','wed','thursday','thu','friday',
+            'fri','saturday','sat','sunday','sun','month','january','jan','february','feb','march',
+            'mar','april','apr','may','june','jun','july','jul','august','aug','september', 'quote', 'do JavaScript',
+            'sep','october','oct','november','nov','december','dec','minutes','hours', 'name', 'default answer',
+            'days','weeks', 'folder', 'folders', 'file', 'files', 'window', 'eject', 'disk', 'reveal', 'sleep',
+            'shut down', 'restart', 'display dialog', 'buttons', 'invisibles', 'item', 'items', 'delimiters', 'offset of',
+            'AppleScript\'s', 'choose file', 'choose folder', 'choose from list', 'beep', 'contents', 'do shell script',
+            'paragraph', 'paragraphs', 'missing value', 'quoted form', 'desktop', 'POSIX path', 'POSIX file',
+            'activate', 'document', 'adding', 'receiving', 'content', 'new', 'properties', 'info for', 'bounds',
+            'selection', 'extension', 'into', 'onto', 'by', 'between', 'against', 'set the clipboard to', 'the clipboard'
+            ),
+        2 => array(
+            'each','some','every','whose','where','index','first','second','third','fourth',
+            'fifth','sixth','seventh','eighth','ninth','tenth','last','front','back','st','nd',
+            'rd','th','middle','named','through','thru','before','after','beginning','the', 'as',
+            'div','mod','and','not','or','contains','equal','equals','isnt', 'less', 'greater'
+            ),
+        3 => array(
+            'script','property','prop','end','to','set','global','local','on','of',
+            'in','given','with','without','return','continue','tell','if','then','else','repeat',
+            'times','while','until','from','exit','try','error','considering','ignoring','timeout',
+            'transaction','my','get','put','is', 'copy'
+            )
+        ),
+    'SYMBOLS' => array(
+        ')','+','-','^','*','/','&','<','>=','<','<=','=','�'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0066ff;',
+            2 => 'color: #ff0033;',
+            3 => 'color: #ff0033; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => '',
+            3 => 'color: #ff0000;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000000; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #009900;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #339933;',
+            4 => 'color: #0066ff;',
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => ',+-=&lt;&gt;/?^&amp;*'
+        ),
+    'REGEXPS' => array(
+        //Variables
+        0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*',
+        //File descriptors
+        4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'SPACE_AS_WHITESPACE' => true
+            )
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/apt_sources.php b/examples/includes/geshi/geshi/apt_sources.php
new file mode 100644 (file)
index 0000000..1321032
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * apt_sources.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/06/17
+ *
+ * Apt sources.list language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/17 (1.0.8)
+ *  -  Initial import
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Apt sources',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        /*keywords*/
+        1 => array(
+            'deb-src', 'deb'
+            ),
+        2 => array(
+            //Generic
+            'stable', 'old-stable', 'testing', 'testing-proposed-updates',
+            'unstable', 'unstable-proposed-updates', 'experimental',
+            'non-US', 'security', 'volatile', 'volatile-sloppy',
+            'apt-build',
+            'stable/updates',
+            //Debian
+            'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato', 'woody', 'sarge',
+            'etch', 'lenny', 'sid',
+            //Ubuntu
+            'warty', 'warty-updates', 'warty-security', 'warty-proposed', 'warty-backports',
+            'hoary', 'hoary-updates', 'hoary-security', 'hoary-proposed', 'hoary-backports',
+            'breezy', 'breezy-updates', 'breezy-security', 'breezy-proposed', 'breezy-backports',
+            'dapper', 'dapper-updates', 'dapper-security', 'dapper-proposed', 'dapper-backports',
+            'edgy', 'edgy-updates', 'edgy-security', 'edgy-proposed', 'edgy-backports',
+            'feisty', 'feisty-updates', 'feisty-security', 'feisty-proposed', 'feisty-backports',
+            'gutsy', 'gutsy-updates', 'gutsy-security', 'gutsy-proposed', 'gutsy-backports',
+            'hardy', 'hardy-updates', 'hardy-security', 'hardy-proposed', 'hardy-backports',
+            'intrepid', 'intrepid-updates', 'intrepid-security', 'intrepid-proposed', 'intrepid-backports'
+            ),
+        3 => array(
+            'main', 'restricted', 'preview', 'contrib', 'non-free',
+            'commercial', 'universe', 'multiverse'
+            )
+    ),
+    'REGEXPS' => array(
+        0 => "(((http|ftp):\/\/|file:\/)[^\s]+)|(cdrom:\[[^\]]*\][^\s]*)",
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => true,
+        3 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00007f;',
+            2 => 'color: #b1b100;',
+            3 => 'color: #b16000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            ),
+        'STRINGS' => array(
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #009900;',
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'NUMBERS' => GESHI_NEVER,
+            'METHODS' => GESHI_NEVER,
+            'SCRIPT' => GESHI_NEVER,
+            'SYMBOLS' => GESHI_NEVER,
+            'ESCAPE_CHAR' => GESHI_NEVER,
+            'BRACKETS' => GESHI_NEVER,
+            'STRINGS' => GESHI_NEVER,
+        ),
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#;>|^\/])',
+            'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-&\.])'
+        )
+    ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/asm.php b/examples/includes/geshi/geshi/asm.php
new file mode 100644 (file)
index 0000000..af4eef7
--- /dev/null
@@ -0,0 +1,225 @@
+<?php
+/*************************************************************************************
+ * asm.php
+ * -------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/27
+ *
+ * x86 Assembler language file for GeSHi.
+ * Words are from SciTe configuration file (based on NASM syntax)
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.2)
+ *   -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   -  Added support for URLs
+ *   -  Added binary and hexadecimal regexps
+ * 2004/08/05 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'ASM',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    //Line address prefix suppression
+    'COMMENT_REGEXP' => array(2 => "/^(?:[0-9a-f]{0,4}:)?[0-9a-f]{4}(?:[0-9a-f]{4})?/mi"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /*CPU*/
+        1 => array(
+            'aaa','aad','aam','aas','adc','add','and','call','cbw','clc','cld','cli','cmc','cmp',
+            'cmps','cmpsb','cmpsw','cwd','daa','das','dec','div','esc','hlt','idiv','imul','in','inc',
+            'int','into','iret','ja','jae','jb','jbe','jc','jcxz','je','jg','jge','jl','jle','jmp',
+            'jna','jnae','jnb','jnbe','jnc','jne','jng','jnge','jnl','jnle','jno','jnp','jns','jnz',
+            'jo','jp','jpe','jpo','js','jz','lahf','lds','lea','les','lods','lodsb','lodsw','loop',
+            'loope','loopew','loopne','loopnew','loopnz','loopnzw','loopw','loopz','loopzw','mov',
+            'movs','movsb','movsw','mul','neg','nop','not','or','out','pop','popf','push','pushf',
+            'rcl','rcr','ret','retf','retn','rol','ror','sahf','sal','sar','sbb','scas','scasb','scasw',
+            'shl','shr','stc','std','sti','stos','stosb','stosw','sub','test','wait','xchg','xlat',
+            'xlatb','xor','bound','enter','ins','insb','insw','leave','outs','outsb','outsw','popa','pusha','pushw',
+            'arpl','lar','lsl','sgdt','sidt','sldt','smsw','str','verr','verw','clts','lgdt','lidt','lldt','lmsw','ltr',
+            'bsf','bsr','bt','btc','btr','bts','cdq','cmpsd','cwde','insd','iretd','iretdf','iretf',
+            'jecxz','lfs','lgs','lodsd','loopd','looped','loopned','loopnzd','loopzd','lss','movsd',
+            'movsx','movzx','outsd','popad','popfd','pushad','pushd','pushfd','scasd','seta','setae',
+            'setb','setbe','setc','sete','setg','setge','setl','setle','setna','setnae','setnb','setnbe',
+            'setnc','setne','setng','setnge','setnl','setnle','setno','setnp','setns','setnz','seto','setp',
+            'setpe','setpo','sets','setz','shld','shrd','stosd','bswap','cmpxchg','invd','invlpg','wbinvd','xadd','lock',
+            'rep','repe','repne','repnz','repz'
+            ),
+        /*FPU*/
+        2 => array(
+            'f2xm1','fabs','fadd','faddp','fbld','fbstp','fchs','fclex','fcom','fcomp','fcompp','fdecstp',
+            'fdisi','fdiv','fdivp','fdivr','fdivrp','feni','ffree','fiadd','ficom','ficomp','fidiv',
+            'fidivr','fild','fimul','fincstp','finit','fist','fistp','fisub','fisubr','fld','fld1',
+            'fldcw','fldenv','fldenvw','fldl2e','fldl2t','fldlg2','fldln2','fldpi','fldz','fmul',
+            'fmulp','fnclex','fndisi','fneni','fninit','fnop','fnsave','fnsavew','fnstcw','fnstenv',
+            'fnstenvw','fnstsw','fpatan','fprem','fptan','frndint','frstor','frstorw','fsave',
+            'fsavew','fscale','fsqrt','fst','fstcw','fstenv','fstenvw','fstp','fstsw','fsub','fsubp',
+            'fsubr','fsubrp','ftst','fwait','fxam','fxch','fxtract','fyl2x','fyl2xp1',
+            'fsetpm','fcos','fldenvd','fnsaved','fnstenvd','fprem1','frstord','fsaved','fsin','fsincos',
+            'fstenvd','fucom','fucomp','fucompp'
+            ),
+        /*registers*/
+        3 => array(
+            'ah','al','ax','bh','bl','bp','bx','ch','cl','cr0','cr2','cr3','cs','cx','dh','di','dl',
+            'dr0','dr1','dr2','dr3','dr6','dr7','ds','dx','eax','ebp','ebx','ecx','edi','edx',
+            'es','esi','esp','fs','gs','si','sp','ss','st','tr3','tr4','tr5','tr6','tr7'
+            ),
+        /*Directive*/
+        4 => array(
+            '186','286','286c','286p','287','386','386c','386p','387','486','486p',
+            '8086','8087','alpha','break','code','const','continue','cref','data','data?',
+            'dosseg','else','elseif','endif','endw','err','err1','err2','errb',
+            'errdef','errdif','errdifi','erre','erridn','erridni','errnb','errndef',
+            'errnz','exit','fardata','fardata?','if','lall','lfcond','list','listall',
+            'listif','listmacro','listmacroall',' model','no87','nocref','nolist',
+            'nolistif','nolistmacro','radix','repeat','sall','seq','sfcond','stack',
+            'startup','tfcond','type','until','untilcxz','while','xall','xcref',
+            'xlist','alias','align','assume','catstr','comm','comment','db','dd','df','dq',
+            'dt','dup','dw','echo','elseif1','elseif2','elseifb','elseifdef','elseifdif',
+            'elseifdifi','elseife','elseifidn','elseifidni','elseifnb','elseifndef','end',
+            'endm','endp','ends','eq',' equ','even','exitm','extern','externdef','extrn','for',
+            'forc','ge','goto','group','high','highword','if1','if2','ifb','ifdef','ifdif',
+            'ifdifi','ife',' ifidn','ifidni','ifnb','ifndef','include','includelib','instr','invoke',
+            'irp','irpc','label','le','length','lengthof','local','low','lowword','lroffset',
+            'macro','mask','mod','msfloat','name','ne','offset','opattr','option','org','%out',
+            'page','popcontext','private','proc','proto','ptr','public','purge','pushcontext','record',
+            'rept','seg','segment','short','size','sizeof','sizestr','struc','struct',
+            'substr','subtitle','subttl','textequ','this','title','typedef','union','width',
+            '.model', '.stack', '.code', '.data'
+            ),
+        /*Operands*/
+        5 => array(
+            '@b','@f','addr','basic','byte','c','carry?','dword',
+            'far','far16','fortran','fword','near','near16','overflow?','parity?','pascal','qword',
+            'real4',' real8','real10','sbyte','sdword','sign?','stdcall','sword','syscall','tbyte',
+            'vararg','word','zero?','flat','near32','far32',
+            'abs','all','assumes','at','casemap','common','compact',
+            'cpu','dotname','emulator','epilogue','error','export','expr16','expr32','farstack',
+            'forceframe','huge','language','large','listing','ljmp','loadds','m510','medium','memory',
+            'nearstack','nodotname','noemulator','nokeyword','noljmp','nom510','none','nonunique',
+            'nooldmacros','nooldstructs','noreadonly','noscoped','nosignextend','nothing',
+            'notpublic','oldmacros','oldstructs','os_dos','para','prologue',
+            'readonly','req','scoped','setif2','smallstack','tiny','use16','use32','uses'
+            )
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '(', ')',
+        '+', '-', '*', '/', '%',
+        '.', ',', ';', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00007f; font-weight: bold;',
+            2 => 'color: #0000ff; font-weight: bold;',
+            3 => 'color: #00007f;',
+            4 => 'color: #000000; font-weight: bold;',
+            5 => 'color: #000000; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900; font-weight: bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+//            0 => 'color: #0000ff;',
+//            1 => 'color: #0000ff;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => ''
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_BIN_PREFIX_PERCENT |
+        GESHI_NUMBER_BIN_SUFFIX |
+        GESHI_NUMBER_HEX_PREFIX |
+        GESHI_NUMBER_HEX_SUFFIX |
+        GESHI_NUMBER_OCT_SUFFIX |
+        GESHI_NUMBER_INT_BASIC |
+        GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_NONSCI_F |
+        GESHI_NUMBER_FLT_SCI_ZERO,
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Hex numbers
+//        0 => /*  */ "(?<=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))(?:[0-9][0-9a-fA-F]{0,31}[hH]|0x[0-9a-fA-F]{1,32})(?=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))",
+        //Binary numbers
+//        1 => "(?<=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))[01]{1,64}[bB](?=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 8,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+            'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%])"
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/asp.php b/examples/includes/geshi/geshi/asp.php
new file mode 100644 (file)
index 0000000..d2404bb
--- /dev/null
@@ -0,0 +1,164 @@
+<?php
+/*************************************************************************************
+ * asp.php
+ * --------
+ * Author: Amit Gupta (http://blog.igeek.info/)
+ * Copyright: (c) 2004 Amit Gupta (http://blog.igeek.info/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/13
+ *
+ * ASP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/30 (1.0.3)
+ *   -  Strings only delimited by ", comments by '
+ * 2004/11/27 (1.0.2)
+ *   -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   -  Added support for URLs
+ * 2004/08/13 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Include all the functions, keywords etc that I have missed
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'ASP',
+    'COMMENT_SINGLE' => array(1 => "'", 2 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'include', 'file', 'Const', 'Dim', 'Option', 'Explicit', 'Implicit', 'Set', 'Select', 'ReDim', 'Preserve',
+            'ByVal', 'ByRef', 'End', 'Private', 'Public', 'If', 'Then', 'Else', 'ElseIf', 'Case', 'With', 'NOT',
+            'While', 'Wend', 'For', 'Loop', 'Do', 'Request', 'Response', 'Server', 'ADODB', 'Session', 'Application',
+            'Each', 'In', 'Get', 'Next', 'INT', 'CINT', 'CBOOL', 'CDATE', 'CBYTE', 'CCUR', 'CDBL', 'CLNG', 'CSNG',
+            'CSTR', 'Fix', 'Is', 'Sgn', 'String', 'Boolean', 'Currency', 'Me', 'Single', 'Long', 'Integer', 'Byte',
+            'Variant', 'Double', 'To', 'Let', 'Xor', 'Resume', 'On', 'Error', 'Imp', 'GoTo', 'Call', 'Global'
+            ),
+        2 => array(
+            'Null', 'Nothing', 'And',
+            'False',
+            'True', 'var', 'Or', 'BOF', 'EOF', 'xor',
+            'Function', 'Class', 'New', 'Sub'
+            ),
+        3 => array(
+            'CreateObject', 'Write', 'Redirect', 'Cookies', 'BinaryRead', 'ClientCertificate', 'Form', 'QueryString',
+            'ServerVariables', 'TotalBytes', 'AddHeader', 'AppendToLog', 'BinaryWrite', 'Buffer', 'CacheControl',
+            'Charset', 'Clear', 'ContentType', 'End()', 'Expires', 'ExpiresAbsolute', 'Flush()', 'IsClientConnected',
+            'PICS', 'Status', 'Connection', 'Recordset', 'Execute', 'Abandon', 'Lock', 'UnLock', 'Command', 'Fields',
+            'Properties', 'Property', 'Send', 'Replace', 'InStr', 'TRIM', 'NOW', 'Day', 'Month', 'Hour', 'Minute', 'Second',
+            'Year', 'MonthName', 'LCase', 'UCase', 'Abs', 'Array', 'As', 'LEN', 'MoveFirst', 'MoveLast', 'MovePrevious',
+            'MoveNext', 'LBound', 'UBound', 'Transfer', 'Open', 'Close', 'MapPath', 'FileExists', 'OpenTextFile', 'ReadAll'
+            )
+        ),
+    'SYMBOLS' => array(
+        1 => array(
+            '<%', '%>'
+            ),
+        0 => array(
+            '(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>',
+            ';', ':', '?', '='),
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #990099; font-weight: bold;',
+            2 => 'color: #0000ff; font-weight: bold;',
+            3 => 'color: #330066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000;',
+            2 => 'color: #ff6600;',
+            'MULTI' => 'color: #008000;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #006600; font-weight:bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #cc0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #800000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #9900cc;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #006600; font-weight: bold;',
+            1 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<%' => '%>'
+            ),
+        1 => array(
+            '<script language="vbscript" runat="server">' => '</script>'
+            ),
+        2 => array(
+            '<script language="javascript" runat="server">' => '</script>'
+            ),
+        3 => "/(<%=?)(?:\"[^\"]*?\"|\/\*(?!\*\/).*?\*\/|.)*?(%>|\Z)/sm"
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/autoit.php b/examples/includes/geshi/geshi/autoit.php
new file mode 100644 (file)
index 0000000..259c822
--- /dev/null
@@ -0,0 +1,1171 @@
+<?php
+/*************************************************************************************
+ * autoit.php
+ * --------
+ * Author: big_daddy (robert.i.anthony@gmail.com)
+ * Copyright: (c) 2006 and to GESHi ;)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/01/26
+ *
+ * AutoIT language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * Release 1.0.8.1 (2008/09/15)
+ * - Updated on 22.03.2008 By Tlem (tlem@tuxolem.fr)
+ * - The link on functions will now correctly re-direct to
+ * - http://www.autoitscript.com/autoit3/docs/functions/{FNAME}.htm
+ * - Updated whith au3.api (09.02.2008).
+ * - Updated - 16 Mai 2008 - v3.2.12.0
+ * - Updated - 12 June 2008 - v3.2.12.1
+ * Release 1.0.7.20 (2006/01/26)
+ * - First Release
+ *
+ * Current bugs & todo:
+ * ----------
+ * - not sure how to get sendkeys to work " {!}, {SPACE} etc... "
+ * - just copyied the regexp for variable from php so this HAVE to be checked and fixed to a better one ;)
+ *
+ * Reference: http://www.autoitscript.com/autoit3/docs/
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License,
+or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not,
+write to the Free Software
+ *   Foundation,
+Inc.,
+59 Temple Place,
+Suite 330,
+Boston,
+MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'AutoIt',
+    'COMMENT_SINGLE' => array(';'),
+    'COMMENT_MULTI' => array(
+        '#comments-start' => '#comments-end',
+        '#cs' => '#ce'),
+    'COMMENT_REGEXP' => array(0 => '/(?<!#)#(\s.*)?$/m'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'And','ByRef','Case','Const','ContinueCase','ContinueLoop',
+            'Default','Dim','Do','Else','ElseIf','EndFunc','EndIf','EndSelect',
+            'EndSwitch','EndWith','Enum','Exit','ExitLoop','False','For','Func',
+            'Global','If','In','Local','Next','Not','Or','ReDim','Return',
+            'Select','Step','Switch','Then','To','True','Until','WEnd','While',
+            'With'
+            ),
+        2 => array(
+            '@AppDataCommonDir','@AppDataDir','@AutoItExe','@AutoItPID',
+            '@AutoItUnicode','@AutoItVersion','@AutoItX64','@COM_EventObj',
+            '@CommonFilesDir','@Compiled','@ComputerName','@ComSpec','@CR',
+            '@CRLF','@DesktopCommonDir','@DesktopDepth','@DesktopDir',
+            '@DesktopHeight','@DesktopRefresh','@DesktopWidth',
+            '@DocumentsCommonDir','@error','@exitCode','@exitMethod',
+            '@extended','@FavoritesCommonDir','@FavoritesDir','@GUI_CtrlHandle',
+            '@GUI_CtrlId','@GUI_DragFile','@GUI_DragId','@GUI_DropId',
+            '@GUI_WinHandle','@HomeDrive','@HomePath','@HomeShare',
+            '@HotKeyPressed','@HOUR','@InetGetActive','@InetGetBytesRead',
+            '@IPAddress1','@IPAddress2','@IPAddress3','@IPAddress4','@KBLayout',
+            '@LF','@LogonDNSDomain','@LogonDomain','@LogonServer','@MDAY',
+            '@MIN','@MON','@MyDocumentsDir','@NumParams','@OSBuild','@OSLang',
+            '@OSServicePack','@OSTYPE','@OSVersion','@ProcessorArch',
+            '@ProgramFilesDir','@ProgramsCommonDir','@ProgramsDir','@ScriptDir',
+            '@ScriptFullPath','@ScriptLineNumber','@ScriptName','@SEC',
+            '@StartMenuCommonDir','@StartMenuDir','@StartupCommonDir',
+            '@StartupDir','@SW_DISABLE','@SW_ENABLE','@SW_HIDE','@SW_LOCK',
+            '@SW_MAXIMIZE','@SW_MINIMIZE','@SW_RESTORE','@SW_SHOW',
+            '@SW_SHOWDEFAULT','@SW_SHOWMAXIMIZED','@SW_SHOWMINIMIZED',
+            '@SW_SHOWMINNOACTIVE','@SW_SHOWNA','@SW_SHOWNOACTIVATE',
+            '@SW_SHOWNORMAL','@SW_UNLOCK','@SystemDir','@TAB','@TempDir',
+            '@TRAY_ID','@TrayIconFlashing','@TrayIconVisible','@UserName',
+            '@UserProfileDir','@WDAY','@WindowsDir','@WorkingDir','@YDAY',
+            '@YEAR'
+            ),
+        3 => array(
+            'Abs','ACos','AdlibDisable','AdlibEnable','Asc','AscW','ASin',
+            'Assign','ATan','AutoItSetOption','AutoItWinGetTitle',
+            'AutoItWinSetTitle','Beep','Binary','BinaryLen','BinaryMid',
+            'BinaryToString','BitAND','BitNOT','BitOR','BitRotate','BitShift',
+            'BitXOR','BlockInput','Break','Call','CDTray','Ceiling','Chr',
+            'ChrW','ClipGet','ClipPut','ConsoleRead','ConsoleWrite',
+            'ConsoleWriteError','ControlClick','ControlCommand',
+            'ControlDisable','ControlEnable','ControlFocus','ControlGetFocus',
+            'ControlGetHandle','ControlGetPos','ControlGetText','ControlHide',
+            'ControlListView','ControlMove','ControlSend','ControlSetText',
+            'ControlShow','ControlTreeView','Cos','Dec','DirCopy','DirCreate',
+            'DirGetSize','DirMove','DirRemove','DllCall','DllCallbackFree',
+            'DllCallbackGetPtr','DllCallbackRegister','DllClose','DllOpen',
+            'DllStructCreate','DllStructGetData','DllStructGetPtr',
+            'DllStructGetSize','DllStructSetData','DriveGetDrive',
+            'DriveGetFileSystem','DriveGetLabel','DriveGetSerial',
+            'DriveGetType','DriveMapAdd','DriveMapDel','DriveMapGet',
+            'DriveSetLabel','DriveSpaceFree','DriveSpaceTotal','DriveStatus',
+            'EnvGet','EnvSet','EnvUpdate','Eval','Execute','Exp',
+            'FileChangeDir','FileClose','FileCopy','FileCreateNTFSLink',
+            'FileCreateShortcut','FileDelete','FileExists','FileFindFirstFile',
+            'FileFindNextFile','FileGetAttrib','FileGetLongName',
+            'FileGetShortcut','FileGetShortName','FileGetSize','FileGetTime',
+            'FileGetVersion','FileInstall','FileMove','FileOpen',
+            'FileOpenDialog','FileRead','FileReadLine','FileRecycle',
+            'FileRecycleEmpty','FileSaveDialog','FileSelectFolder',
+            'FileSetAttrib','FileSetTime','FileWrite','FileWriteLine','Floor',
+            'FtpSetProxy','GUICreate','GUICtrlCreateAvi','GUICtrlCreateButton',
+            'GUICtrlCreateCheckbox','GUICtrlCreateCombo',
+            'GUICtrlCreateContextMenu','GUICtrlCreateDate','GUICtrlCreateDummy',
+            'GUICtrlCreateEdit','GUICtrlCreateGraphic','GUICtrlCreateGroup',
+            'GUICtrlCreateIcon','GUICtrlCreateInput','GUICtrlCreateLabel',
+            'GUICtrlCreateList','GUICtrlCreateListView',
+            'GUICtrlCreateListViewItem','GUICtrlCreateMenu',
+            'GUICtrlCreateMenuItem','GUICtrlCreateMonthCal','GUICtrlCreateObj',
+            'GUICtrlCreatePic','GUICtrlCreateProgress','GUICtrlCreateRadio',
+            'GUICtrlCreateSlider','GUICtrlCreateTab','GUICtrlCreateTabItem',
+            'GUICtrlCreateTreeView','GUICtrlCreateTreeViewItem',
+            'GUICtrlCreateUpdown','GUICtrlDelete','GUICtrlGetHandle',
+            'GUICtrlGetState','GUICtrlRead','GUICtrlRecvMsg',
+            'GUICtrlRegisterListViewSort','GUICtrlSendMsg','GUICtrlSendToDummy',
+            'GUICtrlSetBkColor','GUICtrlSetColor','GUICtrlSetCursor',
+            'GUICtrlSetData','GUICtrlSetFont','GUICtrlSetDefColor',
+            'GUICtrlSetDefBkColor','GUICtrlSetGraphic','GUICtrlSetImage',
+            'GUICtrlSetLimit','GUICtrlSetOnEvent','GUICtrlSetPos',
+            'GUICtrlSetResizing','GUICtrlSetState','GUICtrlSetStyle',
+            'GUICtrlSetTip','GUIDelete','GUIGetCursorInfo','GUIGetMsg',
+            'GUIGetStyle','GUIRegisterMsg','GUISetAccelerators()',
+            'GUISetBkColor','GUISetCoord','GUISetCursor','GUISetFont',
+            'GUISetHelp','GUISetIcon','GUISetOnEvent','GUISetState',
+            'GUISetStyle','GUIStartGroup','GUISwitch','Hex','HotKeySet',
+            'HttpSetProxy','HWnd','InetGet','InetGetSize','IniDelete','IniRead',
+            'IniReadSection','IniReadSectionNames','IniRenameSection',
+            'IniWrite','IniWriteSection','InputBox','Int','IsAdmin','IsArray',
+            'IsBinary','IsBool','IsDeclared','IsDllStruct','IsFloat','IsHWnd',
+            'IsInt','IsKeyword','IsNumber','IsObj','IsPtr','IsString','Log',
+            'MemGetStats','Mod','MouseClick','MouseClickDrag','MouseDown',
+            'MouseGetCursor','MouseGetPos','MouseMove','MouseUp','MouseWheel',
+            'MsgBox','Number','ObjCreate','ObjEvent','ObjGet','ObjName','Opt',
+            'Ping','PixelChecksum','PixelGetColor','PixelSearch','PluginClose',
+            'PluginOpen','ProcessClose','ProcessExists','ProcessGetStats',
+            'ProcessList','ProcessSetPriority','ProcessWait','ProcessWaitClose',
+            'ProgressOff','ProgressOn','ProgressSet','Ptr','Random','RegDelete',
+            'RegEnumKey','RegEnumVal','RegRead','RegWrite','Round','Run',
+            'RunAs','RunAsWait','RunWait','Send','SendKeepActive','SetError',
+            'SetExtended','ShellExecute','ShellExecuteWait','Shutdown','Sin',
+            'Sleep','SoundPlay','SoundSetWaveVolume','SplashImageOn',
+            'SplashOff','SplashTextOn','Sqrt','SRandom','StatusbarGetText',
+            'StderrRead','StdinWrite','StdioClose','StdoutRead','String',
+            'StringAddCR','StringCompare','StringFormat','StringInStr',
+            'StringIsAlNum','StringIsAlpha','StringIsASCII','StringIsDigit',
+            'StringIsFloat','StringIsInt','StringIsLower','StringIsSpace',
+            'StringIsUpper','StringIsXDigit','StringLeft','StringLen',
+            'StringLower','StringMid','StringRegExp','StringRegExpReplace',
+            'StringReplace','StringRight','StringSplit','StringStripCR',
+            'StringStripWS','StringToBinary','StringTrimLeft','StringTrimRight',
+            'StringUpper','Tan','TCPAccept','TCPCloseSocket','TCPConnect',
+            'TCPListen','TCPNameToIP','TCPRecv','TCPSend','TCPShutdown',
+            'TCPStartup','TimerDiff','TimerInit','ToolTip','TrayCreateItem',
+            'TrayCreateMenu','TrayGetMsg','TrayItemDelete','TrayItemGetHandle',
+            'TrayItemGetState','TrayItemGetText','TrayItemSetOnEvent',
+            'TrayItemSetState','TrayItemSetText','TraySetClick','TraySetIcon',
+            'TraySetOnEvent','TraySetPauseIcon','TraySetState','TraySetToolTip',
+            'TrayTip','UBound','UDPBind','UDPCloseSocket','UDPOpen','UDPRecv',
+            'UDPSend','UDPShutdown','UDPStartup','VarGetType','WinActivate',
+            'WinActive','WinClose','WinExists','WinFlash','WinGetCaretPos',
+            'WinGetClassList','WinGetClientSize','WinGetHandle','WinGetPos',
+            'WinGetProcess','WinGetState','WinGetText','WinGetTitle','WinKill',
+            'WinList','WinMenuSelectItem','WinMinimizeAll','WinMinimizeAllUndo',
+            'WinMove','WinSetOnTop','WinSetState','WinSetTitle','WinSetTrans',
+            'WinWait','WinWaitActive','WinWaitClose','WinWaitNotActive'
+            ),
+        4 => array(
+            'ArrayAdd','ArrayBinarySearch','ArrayConcatenate','ArrayDelete',
+            'ArrayDisplay','ArrayFindAll','ArrayInsert','ArrayMax',
+            'ArrayMaxIndex','ArrayMin','ArrayMinIndex','ArrayPop','ArrayPush',
+            'ArrayReverse','ArraySearch','ArraySort','ArraySwap','ArrayToClip',
+            'ArrayToString','ArrayTrim','ChooseColor','ChooseFont',
+            'ClipBoard_ChangeChain','ClipBoard_Close','ClipBoard_CountFormats',
+            'ClipBoard_Empty','ClipBoard_EnumFormats','ClipBoard_FormatStr',
+            'ClipBoard_GetData','ClipBoard_GetDataEx','ClipBoard_GetFormatName',
+            'ClipBoard_GetOpenWindow','ClipBoard_GetOwner',
+            'ClipBoard_GetPriorityFormat','ClipBoard_GetSequenceNumber',
+            'ClipBoard_GetViewer','ClipBoard_IsFormatAvailable',
+            'ClipBoard_Open','ClipBoard_RegisterFormat','ClipBoard_SetData',
+            'ClipBoard_SetDataEx','ClipBoard_SetViewer','ClipPutFile',
+            'ColorConvertHSLtoRGB','ColorConvertRGBtoHSL','ColorGetBlue',
+            'ColorGetGreen','ColorGetRed','Date_Time_CompareFileTime',
+            'Date_Time_DOSDateTimeToArray','Date_Time_DOSDateTimeToFileTime',
+            'Date_Time_DOSDateTimeToStr','Date_Time_DOSDateToArray',
+            'Date_Time_DOSDateToStr','Date_Time_DOSTimeToArray',
+            'Date_Time_DOSTimeToStr','Date_Time_EncodeFileTime',
+            'Date_Time_EncodeSystemTime','Date_Time_FileTimeToArray',
+            'Date_Time_FileTimeToDOSDateTime',
+            'Date_Time_FileTimeToLocalFileTime','Date_Time_FileTimeToStr',
+            'Date_Time_FileTimeToSystemTime','Date_Time_GetFileTime',
+            'Date_Time_GetLocalTime','Date_Time_GetSystemTime',
+            'Date_Time_GetSystemTimeAdjustment',
+            'Date_Time_GetSystemTimeAsFileTime',
+            'Date_Time_GetSystemTimes','Date_Time_GetTickCount',
+            'Date_Time_GetTimeZoneInformation',
+            'Date_Time_LocalFileTimeToFileTime','Date_Time_SetFileTime',
+            'Date_Time_SetLocalTime','Date_Time_SetSystemTime',
+            'Date_Time_SetSystemTimeAdjustment',
+            'Date_Time_SetTimeZoneInformation','Date_Time_SystemTimeToArray',
+            'Date_Time_SystemTimeToDateStr','Date_Time_SystemTimeToDateTimeStr',
+            'Date_Time_SystemTimeToFileTime','Date_Time_SystemTimeToTimeStr',
+            'Date_Time_SystemTimeToTzSpecificLocalTime',
+            'Date_Time_TzSpecificLocalTimeToSystemTime','DateAdd',
+            'DateDayOfWeek','DateDaysInMonth','DateDiff','DateIsLeapYear',
+            'DateIsValid','DateTimeFormat','DateTimeSplit','DateToDayOfWeek',
+            'DateToDayOfWeekISO','DateToDayValue','DateToMonth',
+            'DayValueToDate','DebugBugReportEnv','DebugOut','DebugSetup',
+            'Degree','EventLog__Backup','EventLog__Clear','EventLog__Close',
+            'EventLog__Count','EventLog__DeregisterSource','EventLog__Full',
+            'EventLog__Notify','EventLog__Oldest','EventLog__Open',
+            'EventLog__OpenBackup','EventLog__Read','EventLog__RegisterSource',
+            'EventLog__Report','FileCountLines','FileCreate','FileListToArray',
+            'FilePrint','FileReadToArray','FileWriteFromArray',
+            'FileWriteLog','FileWriteToLine','GDIPlus_ArrowCapCreate',
+            'GDIPlus_ArrowCapDispose','GDIPlus_ArrowCapGetFillState',
+            'GDIPlus_ArrowCapGetHeight','GDIPlus_ArrowCapGetMiddleInset',
+            'GDIPlus_ArrowCapGetWidth','GDIPlus_ArrowCapSetFillState',
+            'GDIPlus_ArrowCapSetHeight','GDIPlus_ArrowCapSetMiddleInset',
+            'GDIPlus_ArrowCapSetWidth','GDIPlus_BitmapCloneArea',
+            'GDIPlus_BitmapCreateFromFile','GDIPlus_BitmapCreateFromGraphics',
+            'GDIPlus_BitmapCreateFromHBITMAP',
+            'GDIPlus_BitmapCreateHBITMAPFromBitmap','GDIPlus_BitmapDispose',
+            'GDIPlus_BitmapLockBits','GDIPlus_BitmapUnlockBits',
+            'GDIPlus_BrushClone','GDIPlus_BrushCreateSolid',
+            'GDIPlus_BrushDispose','GDIPlus_BrushGetType',
+            'GDIPlus_CustomLineCapDispose','GDIPlus_Decoders',
+            'GDIPlus_DecodersGetCount','GDIPlus_DecodersGetSize',
+            'GDIPlus_Encoders','GDIPlus_EncodersGetCLSID',
+            'GDIPlus_EncodersGetCount','GDIPlus_EncodersGetParamList',
+            'GDIPlus_EncodersGetParamListSize','GDIPlus_EncodersGetSize',
+            'GDIPlus_FontCreate','GDIPlus_FontDispose',
+            'GDIPlus_FontFamilyCreate','GDIPlus_FontFamilyDispose',
+            'GDIPlus_GraphicsClear','GDIPlus_GraphicsCreateFromHDC',
+            'GDIPlus_GraphicsCreateFromHWND','GDIPlus_GraphicsDispose',
+            'GDIPlus_GraphicsDrawArc','GDIPlus_GraphicsDrawBezier',
+            'GDIPlus_GraphicsDrawClosedCurve','GDIPlus_GraphicsDrawCurve',
+            'GDIPlus_GraphicsDrawEllipse','GDIPlus_GraphicsDrawImage',
+            'GDIPlus_GraphicsDrawImageRect','GDIPlus_GraphicsDrawImageRectRect',
+            'GDIPlus_GraphicsDrawLine','GDIPlus_GraphicsDrawPie',
+            'GDIPlus_GraphicsDrawPolygon','GDIPlus_GraphicsDrawRect',
+            'GDIPlus_GraphicsDrawString','GDIPlus_GraphicsDrawStringEx',
+            'GDIPlus_GraphicsFillClosedCurve','GDIPlus_GraphicsFillEllipse',
+            'GDIPlus_GraphicsFillPie','GDIPlus_GraphicsFillRect',
+            'GDIPlus_GraphicsGetDC','GDIPlus_GraphicsGetSmoothingMode',
+            'GDIPlus_GraphicsMeasureString','GDIPlus_GraphicsReleaseDC',
+            'GDIPlus_GraphicsSetSmoothingMode','GDIPlus_GraphicsSetTransform',
+            'GDIPlus_ImageDispose','GDIPlus_ImageGetGraphicsContext',
+            'GDIPlus_ImageGetHeight','GDIPlus_ImageGetWidth',
+            'GDIPlus_ImageLoadFromFile','GDIPlus_ImageSaveToFile',
+            'GDIPlus_ImageSaveToFileEx','GDIPlus_MatrixCreate',
+            'GDIPlus_MatrixDispose','GDIPlus_MatrixRotate','GDIPlus_ParamAdd',
+            'GDIPlus_ParamInit','GDIPlus_PenCreate','GDIPlus_PenDispose',
+            'GDIPlus_PenGetAlignment','GDIPlus_PenGetColor',
+            'GDIPlus_PenGetCustomEndCap','GDIPlus_PenGetDashCap',
+            'GDIPlus_PenGetDashStyle','GDIPlus_PenGetEndCap',
+            'GDIPlus_PenGetWidth','GDIPlus_PenSetAlignment',
+            'GDIPlus_PenSetColor','GDIPlus_PenSetCustomEndCap',
+            'GDIPlus_PenSetDashCap','GDIPlus_PenSetDashStyle',
+            'GDIPlus_PenSetEndCap','GDIPlus_PenSetWidth','GDIPlus_RectFCreate',
+            'GDIPlus_Shutdown','GDIPlus_Startup','GDIPlus_StringFormatCreate',
+            'GDIPlus_StringFormatDispose','GetIP','GUICtrlAVI_Close',
+            'GUICtrlAVI_Create','GUICtrlAVI_Destroy','GUICtrlAVI_Open',
+            'GUICtrlAVI_OpenEx','GUICtrlAVI_Play','GUICtrlAVI_Seek',
+            'GUICtrlAVI_Show','GUICtrlAVI_Stop','GUICtrlButton_Click',
+            'GUICtrlButton_Create','GUICtrlButton_Destroy',
+            'GUICtrlButton_Enable','GUICtrlButton_GetCheck',
+            'GUICtrlButton_GetFocus','GUICtrlButton_GetIdealSize',
+            'GUICtrlButton_GetImage','GUICtrlButton_GetImageList',
+            'GUICtrlButton_GetState','GUICtrlButton_GetText',
+            'GUICtrlButton_GetTextMargin','GUICtrlButton_SetCheck',
+            'GUICtrlButton_SetFocus','GUICtrlButton_SetImage',
+            'GUICtrlButton_SetImageList','GUICtrlButton_SetSize',
+            'GUICtrlButton_SetState','GUICtrlButton_SetStyle',
+            'GUICtrlButton_SetText','GUICtrlButton_SetTextMargin',
+            'GUICtrlButton_Show','GUICtrlComboBox_AddDir',
+            'GUICtrlComboBox_AddString','GUICtrlComboBox_AutoComplete',
+            'GUICtrlComboBox_BeginUpdate','GUICtrlComboBox_Create',
+            'GUICtrlComboBox_DeleteString','GUICtrlComboBox_Destroy',
+            'GUICtrlComboBox_EndUpdate','GUICtrlComboBox_FindString',
+            'GUICtrlComboBox_FindStringExact','GUICtrlComboBox_GetComboBoxInfo',
+            'GUICtrlComboBox_GetCount','GUICtrlComboBox_GetCurSel',
+            'GUICtrlComboBox_GetDroppedControlRect',
+            'GUICtrlComboBox_GetDroppedControlRectEx',
+            'GUICtrlComboBox_GetDroppedState','GUICtrlComboBox_GetDroppedWidth',
+            'GUICtrlComboBox_GetEditSel','GUICtrlComboBox_GetEditText',
+            'GUICtrlComboBox_GetExtendedUI',
+            'GUICtrlComboBox_GetHorizontalExtent',
+            'GUICtrlComboBox_GetItemHeight','GUICtrlComboBox_GetLBText',
+            'GUICtrlComboBox_GetLBTextLen','GUICtrlComboBox_GetList',
+            'GUICtrlComboBox_GetListArray','GUICtrlComboBox_GetLocale',
+            'GUICtrlComboBox_GetLocaleCountry','GUICtrlComboBox_GetLocaleLang',
+            'GUICtrlComboBox_GetLocalePrimLang',
+            'GUICtrlComboBox_GetLocaleSubLang','GUICtrlComboBox_GetMinVisible',
+            'GUICtrlComboBox_GetTopIndex','GUICtrlComboBox_InitStorage',
+            'GUICtrlComboBox_InsertString','GUICtrlComboBox_LimitText',
+            'GUICtrlComboBox_ReplaceEditSel','GUICtrlComboBox_ResetContent',
+            'GUICtrlComboBox_SelectString','GUICtrlComboBox_SetCurSel',
+            'GUICtrlComboBox_SetDroppedWidth','GUICtrlComboBox_SetEditSel',
+            'GUICtrlComboBox_SetEditText','GUICtrlComboBox_SetExtendedUI',
+            'GUICtrlComboBox_SetHorizontalExtent',
+            'GUICtrlComboBox_SetItemHeight','GUICtrlComboBox_SetMinVisible',
+            'GUICtrlComboBox_SetTopIndex','GUICtrlComboBox_ShowDropDown',
+            'GUICtrlComboBoxEx_AddDir','GUICtrlComboBoxEx_AddString',
+            'GUICtrlComboBoxEx_BeginUpdate','GUICtrlComboBoxEx_Create',
+            'GUICtrlComboBoxEx_CreateSolidBitMap',
+            'GUICtrlComboBoxEx_DeleteString','GUICtrlComboBoxEx_Destroy',
+            'GUICtrlComboBoxEx_EndUpdate','GUICtrlComboBoxEx_FindStringExact',
+            'GUICtrlComboBoxEx_GetComboBoxInfo',
+            'GUICtrlComboBoxEx_GetComboControl','GUICtrlComboBoxEx_GetCount',
+            'GUICtrlComboBoxEx_GetCurSel',
+            'GUICtrlComboBoxEx_GetDroppedControlRect',
+            'GUICtrlComboBoxEx_GetDroppedControlRectEx',
+            'GUICtrlComboBoxEx_GetDroppedState',
+            'GUICtrlComboBoxEx_GetDroppedWidth',
+            'GUICtrlComboBoxEx_GetEditControl','GUICtrlComboBoxEx_GetEditSel',
+            'GUICtrlComboBoxEx_GetEditText',
+            'GUICtrlComboBoxEx_GetExtendedStyle',
+            'GUICtrlComboBoxEx_GetExtendedUI','GUICtrlComboBoxEx_GetImageList',
+            'GUICtrlComboBoxEx_GetItem','GUICtrlComboBoxEx_GetItemEx',
+            'GUICtrlComboBoxEx_GetItemHeight','GUICtrlComboBoxEx_GetItemImage',
+            'GUICtrlComboBoxEx_GetItemIndent',
+            'GUICtrlComboBoxEx_GetItemOverlayImage',
+            'GUICtrlComboBoxEx_GetItemParam',
+            'GUICtrlComboBoxEx_GetItemSelectedImage',
+            'GUICtrlComboBoxEx_GetItemText','GUICtrlComboBoxEx_GetItemTextLen',
+            'GUICtrlComboBoxEx_GetList','GUICtrlComboBoxEx_GetListArray',
+            'GUICtrlComboBoxEx_GetLocale','GUICtrlComboBoxEx_GetLocaleCountry',
+            'GUICtrlComboBoxEx_GetLocaleLang',
+            'GUICtrlComboBoxEx_GetLocalePrimLang',
+            'GUICtrlComboBoxEx_GetLocaleSubLang',
+            'GUICtrlComboBoxEx_GetMinVisible','GUICtrlComboBoxEx_GetTopIndex',
+            'GUICtrlComboBoxEx_InitStorage','GUICtrlComboBoxEx_InsertString',
+            'GUICtrlComboBoxEx_LimitText','GUICtrlComboBoxEx_ReplaceEditSel',
+            'GUICtrlComboBoxEx_ResetContent','GUICtrlComboBoxEx_SetCurSel',
+            'GUICtrlComboBoxEx_SetDroppedWidth','GUICtrlComboBoxEx_SetEditSel',
+            'GUICtrlComboBoxEx_SetEditText',
+            'GUICtrlComboBoxEx_SetExtendedStyle',
+            'GUICtrlComboBoxEx_SetExtendedUI','GUICtrlComboBoxEx_SetImageList',
+            'GUICtrlComboBoxEx_SetItem','GUICtrlComboBoxEx_SetItemEx',
+            'GUICtrlComboBoxEx_SetItemHeight','GUICtrlComboBoxEx_SetItemImage',
+            'GUICtrlComboBoxEx_SetItemIndent',
+            'GUICtrlComboBoxEx_SetItemOverlayImage',
+            'GUICtrlComboBoxEx_SetItemParam',
+            'GUICtrlComboBoxEx_SetItemSelectedImage',
+            'GUICtrlComboBoxEx_SetMinVisible','GUICtrlComboBoxEx_SetTopIndex',
+            'GUICtrlComboBoxEx_ShowDropDown','GUICtrlDTP_Create',
+            'GUICtrlDTP_Destroy','GUICtrlDTP_GetMCColor','GUICtrlDTP_GetMCFont',
+            'GUICtrlDTP_GetMonthCal','GUICtrlDTP_GetRange',
+            'GUICtrlDTP_GetRangeEx','GUICtrlDTP_GetSystemTime',
+            'GUICtrlDTP_GetSystemTimeEx','GUICtrlDTP_SetFormat',
+            'GUICtrlDTP_SetMCColor','GUICtrlDTP_SetMCFont',
+            'GUICtrlDTP_SetRange','GUICtrlDTP_SetRangeEx',
+            'GUICtrlDTP_SetSystemTime','GUICtrlDTP_SetSystemTimeEx',
+            'GUICtrlEdit_AppendText','GUICtrlEdit_BeginUpdate',
+            'GUICtrlEdit_CanUndo','GUICtrlEdit_CharFromPos',
+            'GUICtrlEdit_Create','GUICtrlEdit_Destroy',
+            'GUICtrlEdit_EmptyUndoBuffer','GUICtrlEdit_EndUpdate',
+            'GUICtrlEdit_Find','GUICtrlEdit_FmtLines',
+            'GUICtrlEdit_GetFirstVisibleLine','GUICtrlEdit_GetLimitText',
+            'GUICtrlEdit_GetLine','GUICtrlEdit_GetLineCount',
+            'GUICtrlEdit_GetMargins','GUICtrlEdit_GetModify',
+            'GUICtrlEdit_GetPasswordChar','GUICtrlEdit_GetRECT',
+            'GUICtrlEdit_GetRECTEx','GUICtrlEdit_GetSel','GUICtrlEdit_GetText',
+            'GUICtrlEdit_GetTextLen','GUICtrlEdit_HideBalloonTip',
+            'GUICtrlEdit_InsertText','GUICtrlEdit_LineFromChar',
+            'GUICtrlEdit_LineIndex','GUICtrlEdit_LineLength',
+            'GUICtrlEdit_LineScroll','GUICtrlEdit_PosFromChar',
+            'GUICtrlEdit_ReplaceSel','GUICtrlEdit_Scroll',
+            'GUICtrlEdit_SetLimitText','GUICtrlEdit_SetMargins',
+            'GUICtrlEdit_SetModify','GUICtrlEdit_SetPasswordChar',
+            'GUICtrlEdit_SetReadOnly','GUICtrlEdit_SetRECT',
+            'GUICtrlEdit_SetRECTEx','GUICtrlEdit_SetRECTNP',
+            'GUICtrlEdit_SetRectNPEx','GUICtrlEdit_SetSel',
+            'GUICtrlEdit_SetTabStops','GUICtrlEdit_SetText',
+            'GUICtrlEdit_ShowBalloonTip','GUICtrlEdit_Undo',
+            'GUICtrlHeader_AddItem','GUICtrlHeader_ClearFilter',
+            'GUICtrlHeader_ClearFilterAll','GUICtrlHeader_Create',
+            'GUICtrlHeader_CreateDragImage','GUICtrlHeader_DeleteItem',
+            'GUICtrlHeader_Destroy','GUICtrlHeader_EditFilter',
+            'GUICtrlHeader_GetBitmapMargin','GUICtrlHeader_GetImageList',
+            'GUICtrlHeader_GetItem','GUICtrlHeader_GetItemAlign',
+            'GUICtrlHeader_GetItemBitmap','GUICtrlHeader_GetItemCount',
+            'GUICtrlHeader_GetItemDisplay','GUICtrlHeader_GetItemFlags',
+            'GUICtrlHeader_GetItemFormat','GUICtrlHeader_GetItemImage',
+            'GUICtrlHeader_GetItemOrder','GUICtrlHeader_GetItemParam',
+            'GUICtrlHeader_GetItemRect','GUICtrlHeader_GetItemRectEx',
+            'GUICtrlHeader_GetItemText','GUICtrlHeader_GetItemWidth',
+            'GUICtrlHeader_GetOrderArray','GUICtrlHeader_GetUnicodeFormat',
+            'GUICtrlHeader_HitTest','GUICtrlHeader_InsertItem',
+            'GUICtrlHeader_Layout','GUICtrlHeader_OrderToIndex',
+            'GUICtrlHeader_SetBitmapMargin',
+            'GUICtrlHeader_SetFilterChangeTimeout',
+            'GUICtrlHeader_SetHotDivider','GUICtrlHeader_SetImageList',
+            'GUICtrlHeader_SetItem','GUICtrlHeader_SetItemAlign',
+            'GUICtrlHeader_SetItemBitmap','GUICtrlHeader_SetItemDisplay',
+            'GUICtrlHeader_SetItemFlags','GUICtrlHeader_SetItemFormat',
+            'GUICtrlHeader_SetItemImage','GUICtrlHeader_SetItemOrder',
+            'GUICtrlHeader_SetItemParam','GUICtrlHeader_SetItemText',
+            'GUICtrlHeader_SetItemWidth','GUICtrlHeader_SetOrderArray',
+            'GUICtrlHeader_SetUnicodeFormat','GUICtrlIpAddress_ClearAddress',
+            'GUICtrlIpAddress_Create','GUICtrlIpAddress_Destroy',
+            'GUICtrlIpAddress_Get','GUICtrlIpAddress_GetArray',
+            'GUICtrlIpAddress_GetEx','GUICtrlIpAddress_IsBlank',
+            'GUICtrlIpAddress_Set','GUICtrlIpAddress_SetArray',
+            'GUICtrlIpAddress_SetEx','GUICtrlIpAddress_SetFocus',
+            'GUICtrlIpAddress_SetFont','GUICtrlIpAddress_SetRange',
+            'GUICtrlIpAddress_ShowHide','GUICtrlListBox_AddFile',
+            'GUICtrlListBox_AddString','GUICtrlListBox_BeginUpdate',
+            'GUICtrlListBox_Create','GUICtrlListBox_DeleteString',
+            'GUICtrlListBox_Destroy','GUICtrlListBox_Dir',
+            'GUICtrlListBox_EndUpdate','GUICtrlListBox_FindInText',
+            'GUICtrlListBox_FindString','GUICtrlListBox_GetAnchorIndex',
+            'GUICtrlListBox_GetCaretIndex','GUICtrlListBox_GetCount',
+            'GUICtrlListBox_GetCurSel','GUICtrlListBox_GetHorizontalExtent',
+            'GUICtrlListBox_GetItemData','GUICtrlListBox_GetItemHeight',
+            'GUICtrlListBox_GetItemRect','GUICtrlListBox_GetItemRectEx',
+            'GUICtrlListBox_GetListBoxInfo','GUICtrlListBox_GetLocale',
+            'GUICtrlListBox_GetLocaleCountry','GUICtrlListBox_GetLocaleLang',
+            'GUICtrlListBox_GetLocalePrimLang',
+            'GUICtrlListBox_GetLocaleSubLang','GUICtrlListBox_GetSel',
+            'GUICtrlListBox_GetSelCount','GUICtrlListBox_GetSelItems',
+            'GUICtrlListBox_GetSelItemsText','GUICtrlListBox_GetText',
+            'GUICtrlListBox_GetTextLen','GUICtrlListBox_GetTopIndex',
+            'GUICtrlListBox_InitStorage','GUICtrlListBox_InsertString',
+            'GUICtrlListBox_ItemFromPoint','GUICtrlListBox_ReplaceString',
+            'GUICtrlListBox_ResetContent','GUICtrlListBox_SelectString',
+            'GUICtrlListBox_SelItemRange','GUICtrlListBox_SelItemRangeEx',
+            'GUICtrlListBox_SetAnchorIndex','GUICtrlListBox_SetCaretIndex',
+            'GUICtrlListBox_SetColumnWidth','GUICtrlListBox_SetCurSel',
+            'GUICtrlListBox_SetHorizontalExtent','GUICtrlListBox_SetItemData',
+            'GUICtrlListBox_SetItemHeight','GUICtrlListBox_SetLocale',
+            'GUICtrlListBox_SetSel','GUICtrlListBox_SetTabStops',
+            'GUICtrlListBox_SetTopIndex','GUICtrlListBox_Sort',
+            'GUICtrlListBox_SwapString','GUICtrlListBox_UpdateHScroll',
+            'GUICtrlListView_AddArray','GUICtrlListView_AddColumn',
+            'GUICtrlListView_AddItem','GUICtrlListView_AddSubItem',
+            'GUICtrlListView_ApproximateViewHeight',
+            'GUICtrlListView_ApproximateViewRect',
+            'GUICtrlListView_ApproximateViewWidth','GUICtrlListView_Arrange',
+            'GUICtrlListView_BeginUpdate','GUICtrlListView_CancelEditLabel',
+            'GUICtrlListView_ClickItem','GUICtrlListView_CopyItems',
+            'GUICtrlListView_Create','GUICtrlListView_CreateDragImage',
+            'GUICtrlListView_CreateSolidBitMap',
+            'GUICtrlListView_DeleteAllItems','GUICtrlListView_DeleteColumn',
+            'GUICtrlListView_DeleteItem','GUICtrlListView_DeleteItemsSelected',
+            'GUICtrlListView_Destroy','GUICtrlListView_DrawDragImage',
+            'GUICtrlListView_EditLabel','GUICtrlListView_EnableGroupView',
+            'GUICtrlListView_EndUpdate','GUICtrlListView_EnsureVisible',
+            'GUICtrlListView_FindInText','GUICtrlListView_FindItem',
+            'GUICtrlListView_FindNearest','GUICtrlListView_FindParam',
+            'GUICtrlListView_FindText','GUICtrlListView_GetBkColor',
+            'GUICtrlListView_GetBkImage','GUICtrlListView_GetCallbackMask',
+            'GUICtrlListView_GetColumn','GUICtrlListView_GetColumnCount',
+            'GUICtrlListView_GetColumnOrder',
+            'GUICtrlListView_GetColumnOrderArray',
+            'GUICtrlListView_GetColumnWidth','GUICtrlListView_GetCounterPage',
+            'GUICtrlListView_GetEditControl',
+            'GUICtrlListView_GetExtendedListViewStyle',
+            'GUICtrlListView_GetGroupInfo',
+            'GUICtrlListView_GetGroupViewEnabled','GUICtrlListView_GetHeader',
+            'GUICtrlListView_GetHotCursor','GUICtrlListView_GetHotItem',
+            'GUICtrlListView_GetHoverTime','GUICtrlListView_GetImageList',
+            'GUICtrlListView_GetISearchString','GUICtrlListView_GetItem',
+            'GUICtrlListView_GetItemChecked','GUICtrlListView_GetItemCount',
+            'GUICtrlListView_GetItemCut','GUICtrlListView_GetItemDropHilited',
+            'GUICtrlListView_GetItemEx','GUICtrlListView_GetItemFocused',
+            'GUICtrlListView_GetItemGroupID','GUICtrlListView_GetItemImage',
+            'GUICtrlListView_GetItemIndent','GUICtrlListView_GetItemParam',
+            'GUICtrlListView_GetItemPosition',
+            'GUICtrlListView_GetItemPositionX',
+            'GUICtrlListView_GetItemPositionY','GUICtrlListView_GetItemRect',
+            'GUICtrlListView_GetItemRectEx','GUICtrlListView_GetItemSelected',
+            'GUICtrlListView_GetItemSpacing','GUICtrlListView_GetItemSpacingX',
+            'GUICtrlListView_GetItemSpacingY','GUICtrlListView_GetItemState',
+            'GUICtrlListView_GetItemStateImage','GUICtrlListView_GetItemText',
+            'GUICtrlListView_GetItemTextArray',
+            'GUICtrlListView_GetItemTextString','GUICtrlListView_GetNextItem',
+            'GUICtrlListView_GetNumberOfWorkAreas','GUICtrlListView_GetOrigin',
+            'GUICtrlListView_GetOriginX','GUICtrlListView_GetOriginY',
+            'GUICtrlListView_GetOutlineColor',
+            'GUICtrlListView_GetSelectedColumn',
+            'GUICtrlListView_GetSelectedCount',
+            'GUICtrlListView_GetSelectedIndices',
+            'GUICtrlListView_GetSelectionMark','GUICtrlListView_GetStringWidth',
+            'GUICtrlListView_GetSubItemRect','GUICtrlListView_GetTextBkColor',
+            'GUICtrlListView_GetTextColor','GUICtrlListView_GetToolTips',
+            'GUICtrlListView_GetTopIndex','GUICtrlListView_GetUnicodeFormat',
+            'GUICtrlListView_GetView','GUICtrlListView_GetViewDetails',
+            'GUICtrlListView_GetViewLarge','GUICtrlListView_GetViewList',
+            'GUICtrlListView_GetViewRect','GUICtrlListView_GetViewSmall',
+            'GUICtrlListView_GetViewTile','GUICtrlListView_HideColumn',
+            'GUICtrlListView_HitTest','GUICtrlListView_InsertColumn',
+            'GUICtrlListView_InsertGroup','GUICtrlListView_InsertItem',
+            'GUICtrlListView_JustifyColumn','GUICtrlListView_MapIDToIndex',
+            'GUICtrlListView_MapIndexToID','GUICtrlListView_RedrawItems',
+            'GUICtrlListView_RegisterSortCallBack',
+            'GUICtrlListView_RemoveAllGroups','GUICtrlListView_RemoveGroup',
+            'GUICtrlListView_Scroll','GUICtrlListView_SetBkColor',
+            'GUICtrlListView_SetBkImage','GUICtrlListView_SetCallBackMask',
+            'GUICtrlListView_SetColumn','GUICtrlListView_SetColumnOrder',
+            'GUICtrlListView_SetColumnOrderArray',
+            'GUICtrlListView_SetColumnWidth',
+            'GUICtrlListView_SetExtendedListViewStyle',
+            'GUICtrlListView_SetGroupInfo','GUICtrlListView_SetHotItem',
+            'GUICtrlListView_SetHoverTime','GUICtrlListView_SetIconSpacing',
+            'GUICtrlListView_SetImageList','GUICtrlListView_SetItem',
+            'GUICtrlListView_SetItemChecked','GUICtrlListView_SetItemCount',
+            'GUICtrlListView_SetItemCut','GUICtrlListView_SetItemDropHilited',
+            'GUICtrlListView_SetItemEx','GUICtrlListView_SetItemFocused',
+            'GUICtrlListView_SetItemGroupID','GUICtrlListView_SetItemImage',
+            'GUICtrlListView_SetItemIndent','GUICtrlListView_SetItemParam',
+            'GUICtrlListView_SetItemPosition',
+            'GUICtrlListView_SetItemPosition32',
+            'GUICtrlListView_SetItemSelected','GUICtrlListView_SetItemState',
+            'GUICtrlListView_SetItemStateImage','GUICtrlListView_SetItemText',
+            'GUICtrlListView_SetOutlineColor',
+            'GUICtrlListView_SetSelectedColumn',
+            'GUICtrlListView_SetSelectionMark','GUICtrlListView_SetTextBkColor',
+            'GUICtrlListView_SetTextColor','GUICtrlListView_SetToolTips',
+            'GUICtrlListView_SetUnicodeFormat','GUICtrlListView_SetView',
+            'GUICtrlListView_SetWorkAreas','GUICtrlListView_SimpleSort',
+            'GUICtrlListView_SortItems','GUICtrlListView_SubItemHitTest',
+            'GUICtrlListView_UnRegisterSortCallBack',
+            'GUICtrlMenu_AddMenuItem','GUICtrlMenu_AppendMenu',
+            'GUICtrlMenu_CheckMenuItem','GUICtrlMenu_CheckRadioItem',
+            'GUICtrlMenu_CreateMenu','GUICtrlMenu_CreatePopup',
+            'GUICtrlMenu_DeleteMenu','GUICtrlMenu_DestroyMenu',
+            'GUICtrlMenu_DrawMenuBar','GUICtrlMenu_EnableMenuItem',
+            'GUICtrlMenu_FindItem','GUICtrlMenu_FindParent',
+            'GUICtrlMenu_GetItemBmp','GUICtrlMenu_GetItemBmpChecked',
+            'GUICtrlMenu_GetItemBmpUnchecked','GUICtrlMenu_GetItemChecked',
+            'GUICtrlMenu_GetItemCount','GUICtrlMenu_GetItemData',
+            'GUICtrlMenu_GetItemDefault','GUICtrlMenu_GetItemDisabled',
+            'GUICtrlMenu_GetItemEnabled','GUICtrlMenu_GetItemGrayed',
+            'GUICtrlMenu_GetItemHighlighted','GUICtrlMenu_GetItemID',
+            'GUICtrlMenu_GetItemInfo','GUICtrlMenu_GetItemRect',
+            'GUICtrlMenu_GetItemRectEx','GUICtrlMenu_GetItemState',
+            'GUICtrlMenu_GetItemStateEx','GUICtrlMenu_GetItemSubMenu',
+            'GUICtrlMenu_GetItemText','GUICtrlMenu_GetItemType',
+            'GUICtrlMenu_GetMenu','GUICtrlMenu_GetMenuBackground',
+            'GUICtrlMenu_GetMenuBarInfo','GUICtrlMenu_GetMenuContextHelpID',
+            'GUICtrlMenu_GetMenuData','GUICtrlMenu_GetMenuDefaultItem',
+            'GUICtrlMenu_GetMenuHeight','GUICtrlMenu_GetMenuInfo',
+            'GUICtrlMenu_GetMenuStyle','GUICtrlMenu_GetSystemMenu',
+            'GUICtrlMenu_InsertMenuItem','GUICtrlMenu_InsertMenuItemEx',
+            'GUICtrlMenu_IsMenu','GUICtrlMenu_LoadMenu',
+            'GUICtrlMenu_MapAccelerator','GUICtrlMenu_MenuItemFromPoint',
+            'GUICtrlMenu_RemoveMenu','GUICtrlMenu_SetItemBitmaps',
+            'GUICtrlMenu_SetItemBmp','GUICtrlMenu_SetItemBmpChecked',
+            'GUICtrlMenu_SetItemBmpUnchecked','GUICtrlMenu_SetItemChecked',
+            'GUICtrlMenu_SetItemData','GUICtrlMenu_SetItemDefault',
+            'GUICtrlMenu_SetItemDisabled','GUICtrlMenu_SetItemEnabled',
+            'GUICtrlMenu_SetItemGrayed','GUICtrlMenu_SetItemHighlighted',
+            'GUICtrlMenu_SetItemID','GUICtrlMenu_SetItemInfo',
+            'GUICtrlMenu_SetItemState','GUICtrlMenu_SetItemSubMenu',
+            'GUICtrlMenu_SetItemText','GUICtrlMenu_SetItemType',
+            'GUICtrlMenu_SetMenu','GUICtrlMenu_SetMenuBackground',
+            'GUICtrlMenu_SetMenuContextHelpID','GUICtrlMenu_SetMenuData',
+            'GUICtrlMenu_SetMenuDefaultItem','GUICtrlMenu_SetMenuHeight',
+            'GUICtrlMenu_SetMenuInfo','GUICtrlMenu_SetMenuStyle',
+            'GUICtrlMenu_TrackPopupMenu','GUICtrlMonthCal_Create',
+            'GUICtrlMonthCal_Destroy','GUICtrlMonthCal_GetColor',
+            'GUICtrlMonthCal_GetColorArray','GUICtrlMonthCal_GetCurSel',
+            'GUICtrlMonthCal_GetCurSelStr','GUICtrlMonthCal_GetFirstDOW',
+            'GUICtrlMonthCal_GetFirstDOWStr','GUICtrlMonthCal_GetMaxSelCount',
+            'GUICtrlMonthCal_GetMaxTodayWidth',
+            'GUICtrlMonthCal_GetMinReqHeight','GUICtrlMonthCal_GetMinReqRect',
+            'GUICtrlMonthCal_GetMinReqRectArray',
+            'GUICtrlMonthCal_GetMinReqWidth','GUICtrlMonthCal_GetMonthDelta',
+            'GUICtrlMonthCal_GetMonthRange','GUICtrlMonthCal_GetMonthRangeMax',
+            'GUICtrlMonthCal_GetMonthRangeMaxStr',
+            'GUICtrlMonthCal_GetMonthRangeMin',
+            'GUICtrlMonthCal_GetMonthRangeMinStr',
+            'GUICtrlMonthCal_GetMonthRangeSpan','GUICtrlMonthCal_GetRange',
+            'GUICtrlMonthCal_GetRangeMax','GUICtrlMonthCal_GetRangeMaxStr',
+            'GUICtrlMonthCal_GetRangeMin','GUICtrlMonthCal_GetRangeMinStr',
+            'GUICtrlMonthCal_GetSelRange','GUICtrlMonthCal_GetSelRangeMax',
+            'GUICtrlMonthCal_GetSelRangeMaxStr',
+            'GUICtrlMonthCal_GetSelRangeMin',
+            'GUICtrlMonthCal_GetSelRangeMinStr','GUICtrlMonthCal_GetToday',
+            'GUICtrlMonthCal_GetTodayStr','GUICtrlMonthCal_GetUnicodeFormat',
+            'GUICtrlMonthCal_HitTest','GUICtrlMonthCal_SetColor',
+            'GUICtrlMonthCal_SetCurSel','GUICtrlMonthCal_SetDayState',
+            'GUICtrlMonthCal_SetFirstDOW','GUICtrlMonthCal_SetMaxSelCount',
+            'GUICtrlMonthCal_SetMonthDelta','GUICtrlMonthCal_SetRange',
+            'GUICtrlMonthCal_SetSelRange','GUICtrlMonthCal_SetToday',
+            'GUICtrlMonthCal_SetUnicodeFormat','GUICtrlRebar_AddBand',
+            'GUICtrlRebar_AddToolBarBand','GUICtrlRebar_BeginDrag',
+            'GUICtrlRebar_Create','GUICtrlRebar_DeleteBand',
+            'GUICtrlRebar_Destroy','GUICtrlRebar_DragMove',
+            'GUICtrlRebar_EndDrag','GUICtrlRebar_GetBandBackColor',
+            'GUICtrlRebar_GetBandBorders','GUICtrlRebar_GetBandBordersEx',
+            'GUICtrlRebar_GetBandChildHandle','GUICtrlRebar_GetBandChildSize',
+            'GUICtrlRebar_GetBandCount','GUICtrlRebar_GetBandForeColor',
+            'GUICtrlRebar_GetBandHeaderSize','GUICtrlRebar_GetBandID',
+            'GUICtrlRebar_GetBandIdealSize','GUICtrlRebar_GetBandLength',
+            'GUICtrlRebar_GetBandLParam','GUICtrlRebar_GetBandMargins',
+            'GUICtrlRebar_GetBandMarginsEx','GUICtrlRebar_GetBandRect',
+            'GUICtrlRebar_GetBandRectEx','GUICtrlRebar_GetBandStyle',
+            'GUICtrlRebar_GetBandStyleBreak',
+            'GUICtrlRebar_GetBandStyleChildEdge',
+            'GUICtrlRebar_GetBandStyleFixedBMP',
+            'GUICtrlRebar_GetBandStyleFixedSize',
+            'GUICtrlRebar_GetBandStyleGripperAlways',
+            'GUICtrlRebar_GetBandStyleHidden',
+            'GUICtrlRebar_GetBandStyleHideTitle',
+            'GUICtrlRebar_GetBandStyleNoGripper',
+            'GUICtrlRebar_GetBandStyleTopAlign',
+            'GUICtrlRebar_GetBandStyleUseChevron',
+            'GUICtrlRebar_GetBandStyleVariableHeight',
+            'GUICtrlRebar_GetBandText','GUICtrlRebar_GetBarHeight',
+            'GUICtrlRebar_GetBKColor','GUICtrlRebar_GetColorScheme',
+            'GUICtrlRebar_GetRowCount','GUICtrlRebar_GetRowHeight',
+            'GUICtrlRebar_GetTextColor','GUICtrlRebar_GetToolTips',
+            'GUICtrlRebar_GetUnicodeFormat','GUICtrlRebar_HitTest',
+            'GUICtrlRebar_IDToIndex','GUICtrlRebar_MaximizeBand',
+            'GUICtrlRebar_MinimizeBand','GUICtrlRebar_MoveBand',
+            'GUICtrlRebar_SetBandBackColor','GUICtrlRebar_SetBandForeColor',
+            'GUICtrlRebar_SetBandHeaderSize','GUICtrlRebar_SetBandID',
+            'GUICtrlRebar_SetBandIdealSize','GUICtrlRebar_SetBandLength',
+            'GUICtrlRebar_SetBandLParam','GUICtrlRebar_SetBandStyle',
+            'GUICtrlRebar_SetBandStyleBreak',
+            'GUICtrlRebar_SetBandStyleChildEdge',
+            'GUICtrlRebar_SetBandStyleFixedBMP',
+            'GUICtrlRebar_SetBandStyleFixedSize',
+            'GUICtrlRebar_SetBandStyleGripperAlways',
+            'GUICtrlRebar_SetBandStyleHidden',
+            'GUICtrlRebar_SetBandStyleHideTitle',
+            'GUICtrlRebar_SetBandStyleNoGripper',
+            'GUICtrlRebar_SetBandStyleTopAlign',
+            'GUICtrlRebar_SetBandStyleUseChevron',
+            'GUICtrlRebar_SetBandStyleVariableHeight',
+            'GUICtrlRebar_SetBandText','GUICtrlRebar_SetBKColor',
+            'GUICtrlRebar_SetColorScheme','GUICtrlRebar_SetTextColor',
+            'GUICtrlRebar_SetToolTips','GUICtrlRebar_SetUnicodeFormat',
+            'GUICtrlRebar_ShowBand','GUICtrlSlider_ClearSel',
+            'GUICtrlSlider_ClearTics','GUICtrlSlider_Create',
+            'GUICtrlSlider_Destroy','GUICtrlSlider_GetBuddy',
+            'GUICtrlSlider_GetChannelRect','GUICtrlSlider_GetLineSize',
+            'GUICtrlSlider_GetNumTics','GUICtrlSlider_GetPageSize',
+            'GUICtrlSlider_GetPos','GUICtrlSlider_GetPTics',
+            'GUICtrlSlider_GetRange','GUICtrlSlider_GetRangeMax',
+            'GUICtrlSlider_GetRangeMin','GUICtrlSlider_GetSel',
+            'GUICtrlSlider_GetSelEnd','GUICtrlSlider_GetSelStart',
+            'GUICtrlSlider_GetThumbLength','GUICtrlSlider_GetThumbRect',
+            'GUICtrlSlider_GetThumbRectEx','GUICtrlSlider_GetTic',
+            'GUICtrlSlider_GetTicPos','GUICtrlSlider_GetToolTips',
+            'GUICtrlSlider_GetUnicodeFormat','GUICtrlSlider_SetBuddy',
+            'GUICtrlSlider_SetLineSize','GUICtrlSlider_SetPageSize',
+            'GUICtrlSlider_SetPos','GUICtrlSlider_SetRange',
+            'GUICtrlSlider_SetRangeMax','GUICtrlSlider_SetRangeMin',
+            'GUICtrlSlider_SetSel','GUICtrlSlider_SetSelEnd',
+            'GUICtrlSlider_SetSelStart','GUICtrlSlider_SetThumbLength',
+            'GUICtrlSlider_SetTic','GUICtrlSlider_SetTicFreq',
+            'GUICtrlSlider_SetTipSide','GUICtrlSlider_SetToolTips',
+            'GUICtrlSlider_SetUnicodeFormat','GUICtrlStatusBar_Create',
+            'GUICtrlStatusBar_Destroy','GUICtrlStatusBar_EmbedControl',
+            'GUICtrlStatusBar_GetBorders','GUICtrlStatusBar_GetBordersHorz',
+            'GUICtrlStatusBar_GetBordersRect','GUICtrlStatusBar_GetBordersVert',
+            'GUICtrlStatusBar_GetCount','GUICtrlStatusBar_GetHeight',
+            'GUICtrlStatusBar_GetIcon','GUICtrlStatusBar_GetParts',
+            'GUICtrlStatusBar_GetRect','GUICtrlStatusBar_GetRectEx',
+            'GUICtrlStatusBar_GetText','GUICtrlStatusBar_GetTextFlags',
+            'GUICtrlStatusBar_GetTextLength','GUICtrlStatusBar_GetTextLengthEx',
+            'GUICtrlStatusBar_GetTipText','GUICtrlStatusBar_GetUnicodeFormat',
+            'GUICtrlStatusBar_GetWidth','GUICtrlStatusBar_IsSimple',
+            'GUICtrlStatusBar_Resize','GUICtrlStatusBar_SetBkColor',
+            'GUICtrlStatusBar_SetIcon','GUICtrlStatusBar_SetMinHeight',
+            'GUICtrlStatusBar_SetParts','GUICtrlStatusBar_SetSimple',
+            'GUICtrlStatusBar_SetText','GUICtrlStatusBar_SetTipText',
+            'GUICtrlStatusBar_SetUnicodeFormat','GUICtrlStatusBar_ShowHide',
+            'GUICtrlTab_Create','GUICtrlTab_DeleteAllItems',
+            'GUICtrlTab_DeleteItem','GUICtrlTab_DeselectAll',
+            'GUICtrlTab_Destroy','GUICtrlTab_FindTab','GUICtrlTab_GetCurFocus',
+            'GUICtrlTab_GetCurSel','GUICtrlTab_GetDisplayRect',
+            'GUICtrlTab_GetDisplayRectEx','GUICtrlTab_GetExtendedStyle',
+            'GUICtrlTab_GetImageList','GUICtrlTab_GetItem',
+            'GUICtrlTab_GetItemCount','GUICtrlTab_GetItemImage',
+            'GUICtrlTab_GetItemParam','GUICtrlTab_GetItemRect',
+            'GUICtrlTab_GetItemRectEx','GUICtrlTab_GetItemState',
+            'GUICtrlTab_GetItemText','GUICtrlTab_GetRowCount',
+            'GUICtrlTab_GetToolTips','GUICtrlTab_GetUnicodeFormat',
+            'GUICtrlTab_HighlightItem','GUICtrlTab_HitTest',
+            'GUICtrlTab_InsertItem','GUICtrlTab_RemoveImage',
+            'GUICtrlTab_SetCurFocus','GUICtrlTab_SetCurSel',
+            'GUICtrlTab_SetExtendedStyle','GUICtrlTab_SetImageList',
+            'GUICtrlTab_SetItem','GUICtrlTab_SetItemImage',
+            'GUICtrlTab_SetItemParam','GUICtrlTab_SetItemSize',
+            'GUICtrlTab_SetItemState','GUICtrlTab_SetItemText',
+            'GUICtrlTab_SetMinTabWidth','GUICtrlTab_SetPadding',
+            'GUICtrlTab_SetToolTips','GUICtrlTab_SetUnicodeFormat',
+            'GUICtrlToolbar_AddBitmap','GUICtrlToolbar_AddButton',
+            'GUICtrlToolbar_AddButtonSep','GUICtrlToolbar_AddString',
+            'GUICtrlToolbar_ButtonCount','GUICtrlToolbar_CheckButton',
+            'GUICtrlToolbar_ClickAccel','GUICtrlToolbar_ClickButton',
+            'GUICtrlToolbar_ClickIndex','GUICtrlToolbar_CommandToIndex',
+            'GUICtrlToolbar_Create','GUICtrlToolbar_Customize',
+            'GUICtrlToolbar_DeleteButton','GUICtrlToolbar_Destroy',
+            'GUICtrlToolbar_EnableButton','GUICtrlToolbar_FindToolbar',
+            'GUICtrlToolbar_GetAnchorHighlight','GUICtrlToolbar_GetBitmapFlags',
+            'GUICtrlToolbar_GetButtonBitmap','GUICtrlToolbar_GetButtonInfo',
+            'GUICtrlToolbar_GetButtonInfoEx','GUICtrlToolbar_GetButtonParam',
+            'GUICtrlToolbar_GetButtonRect','GUICtrlToolbar_GetButtonRectEx',
+            'GUICtrlToolbar_GetButtonSize','GUICtrlToolbar_GetButtonState',
+            'GUICtrlToolbar_GetButtonStyle','GUICtrlToolbar_GetButtonText',
+            'GUICtrlToolbar_GetColorScheme',
+            'GUICtrlToolbar_GetDisabledImageList',
+            'GUICtrlToolbar_GetExtendedStyle','GUICtrlToolbar_GetHotImageList',
+            'GUICtrlToolbar_GetHotItem','GUICtrlToolbar_GetImageList',
+            'GUICtrlToolbar_GetInsertMark','GUICtrlToolbar_GetInsertMarkColor',
+            'GUICtrlToolbar_GetMaxSize','GUICtrlToolbar_GetMetrics',
+            'GUICtrlToolbar_GetPadding','GUICtrlToolbar_GetRows',
+            'GUICtrlToolbar_GetString','GUICtrlToolbar_GetStyle',
+            'GUICtrlToolbar_GetStyleAltDrag',
+            'GUICtrlToolbar_GetStyleCustomErase','GUICtrlToolbar_GetStyleFlat',
+            'GUICtrlToolbar_GetStyleList','GUICtrlToolbar_GetStyleRegisterDrop',
+            'GUICtrlToolbar_GetStyleToolTips',
+            'GUICtrlToolbar_GetStyleTransparent',
+            'GUICtrlToolbar_GetStyleWrapable','GUICtrlToolbar_GetTextRows',
+            'GUICtrlToolbar_GetToolTips','GUICtrlToolbar_GetUnicodeFormat',
+            'GUICtrlToolbar_HideButton','GUICtrlToolbar_HighlightButton',
+            'GUICtrlToolbar_HitTest','GUICtrlToolbar_IndexToCommand',
+            'GUICtrlToolbar_InsertButton','GUICtrlToolbar_InsertMarkHitTest',
+            'GUICtrlToolbar_IsButtonChecked','GUICtrlToolbar_IsButtonEnabled',
+            'GUICtrlToolbar_IsButtonHidden',
+            'GUICtrlToolbar_IsButtonHighlighted',
+            'GUICtrlToolbar_IsButtonIndeterminate',
+            'GUICtrlToolbar_IsButtonPressed','GUICtrlToolbar_LoadBitmap',
+            'GUICtrlToolbar_LoadImages','GUICtrlToolbar_MapAccelerator',
+            'GUICtrlToolbar_MoveButton','GUICtrlToolbar_PressButton',
+            'GUICtrlToolbar_SetAnchorHighlight','GUICtrlToolbar_SetBitmapSize',
+            'GUICtrlToolbar_SetButtonBitMap','GUICtrlToolbar_SetButtonInfo',
+            'GUICtrlToolbar_SetButtonInfoEx','GUICtrlToolbar_SetButtonParam',
+            'GUICtrlToolbar_SetButtonSize','GUICtrlToolbar_SetButtonState',
+            'GUICtrlToolbar_SetButtonStyle','GUICtrlToolbar_SetButtonText',
+            'GUICtrlToolbar_SetButtonWidth','GUICtrlToolbar_SetCmdID',
+            'GUICtrlToolbar_SetColorScheme',
+            'GUICtrlToolbar_SetDisabledImageList',
+            'GUICtrlToolbar_SetDrawTextFlags','GUICtrlToolbar_SetExtendedStyle',
+            'GUICtrlToolbar_SetHotImageList','GUICtrlToolbar_SetHotItem',
+            'GUICtrlToolbar_SetImageList','GUICtrlToolbar_SetIndent',
+            'GUICtrlToolbar_SetIndeterminate','GUICtrlToolbar_SetInsertMark',
+            'GUICtrlToolbar_SetInsertMarkColor','GUICtrlToolbar_SetMaxTextRows',
+            'GUICtrlToolbar_SetMetrics','GUICtrlToolbar_SetPadding',
+            'GUICtrlToolbar_SetParent','GUICtrlToolbar_SetRows',
+            'GUICtrlToolbar_SetStyle','GUICtrlToolbar_SetStyleAltDrag',
+            'GUICtrlToolbar_SetStyleCustomErase','GUICtrlToolbar_SetStyleFlat',
+            'GUICtrlToolbar_SetStyleList','GUICtrlToolbar_SetStyleRegisterDrop',
+            'GUICtrlToolbar_SetStyleToolTips',
+            'GUICtrlToolbar_SetStyleTransparent',
+            'GUICtrlToolbar_SetStyleWrapable','GUICtrlToolbar_SetToolTips',
+            'GUICtrlToolbar_SetUnicodeFormat','GUICtrlToolbar_SetWindowTheme',
+            'GUICtrlTreeView_Add','GUICtrlTreeView_AddChild',
+            'GUICtrlTreeView_AddChildFirst','GUICtrlTreeView_AddFirst',
+            'GUICtrlTreeView_BeginUpdate','GUICtrlTreeView_ClickItem',
+            'GUICtrlTreeView_Create','GUICtrlTreeView_CreateDragImage',
+            'GUICtrlTreeView_CreateSolidBitMap','GUICtrlTreeView_Delete',
+            'GUICtrlTreeView_DeleteAll','GUICtrlTreeView_DeleteChildren',
+            'GUICtrlTreeView_Destroy','GUICtrlTreeView_DisplayRect',
+            'GUICtrlTreeView_DisplayRectEx','GUICtrlTreeView_EditText',
+            'GUICtrlTreeView_EndEdit','GUICtrlTreeView_EndUpdate',
+            'GUICtrlTreeView_EnsureVisible','GUICtrlTreeView_Expand',
+            'GUICtrlTreeView_ExpandedOnce','GUICtrlTreeView_FindItem',
+            'GUICtrlTreeView_FindItemEx','GUICtrlTreeView_GetBkColor',
+            'GUICtrlTreeView_GetBold','GUICtrlTreeView_GetChecked',
+            'GUICtrlTreeView_GetChildCount','GUICtrlTreeView_GetChildren',
+            'GUICtrlTreeView_GetCount','GUICtrlTreeView_GetCut',
+            'GUICtrlTreeView_GetDropTarget','GUICtrlTreeView_GetEditControl',
+            'GUICtrlTreeView_GetExpanded','GUICtrlTreeView_GetFirstChild',
+            'GUICtrlTreeView_GetFirstItem','GUICtrlTreeView_GetFirstVisible',
+            'GUICtrlTreeView_GetFocused','GUICtrlTreeView_GetHeight',
+            'GUICtrlTreeView_GetImageIndex',
+            'GUICtrlTreeView_GetImageListIconHandle',
+            'GUICtrlTreeView_GetIndent','GUICtrlTreeView_GetInsertMarkColor',
+            'GUICtrlTreeView_GetISearchString','GUICtrlTreeView_GetItemByIndex',
+            'GUICtrlTreeView_GetItemHandle','GUICtrlTreeView_GetItemParam',
+            'GUICtrlTreeView_GetLastChild','GUICtrlTreeView_GetLineColor',
+            'GUICtrlTreeView_GetNext','GUICtrlTreeView_GetNextChild',
+            'GUICtrlTreeView_GetNextSibling','GUICtrlTreeView_GetNextVisible',
+            'GUICtrlTreeView_GetNormalImageList',
+            'GUICtrlTreeView_GetParentHandle','GUICtrlTreeView_GetParentParam',
+            'GUICtrlTreeView_GetPrev','GUICtrlTreeView_GetPrevChild',
+            'GUICtrlTreeView_GetPrevSibling','GUICtrlTreeView_GetPrevVisible',
+            'GUICtrlTreeView_GetScrollTime','GUICtrlTreeView_GetSelected',
+            'GUICtrlTreeView_GetSelectedImageIndex',
+            'GUICtrlTreeView_GetSelection','GUICtrlTreeView_GetSiblingCount',
+            'GUICtrlTreeView_GetState','GUICtrlTreeView_GetStateImageIndex',
+            'GUICtrlTreeView_GetStateImageList','GUICtrlTreeView_GetText',
+            'GUICtrlTreeView_GetTextColor','GUICtrlTreeView_GetToolTips',
+            'GUICtrlTreeView_GetTree','GUICtrlTreeView_GetUnicodeFormat',
+            'GUICtrlTreeView_GetVisible','GUICtrlTreeView_GetVisibleCount',
+            'GUICtrlTreeView_HitTest','GUICtrlTreeView_HitTestEx',
+            'GUICtrlTreeView_HitTestItem','GUICtrlTreeView_Index',
+            'GUICtrlTreeView_InsertItem','GUICtrlTreeView_IsFirstItem',
+            'GUICtrlTreeView_IsParent','GUICtrlTreeView_Level',
+            'GUICtrlTreeView_SelectItem','GUICtrlTreeView_SelectItemByIndex',
+            'GUICtrlTreeView_SetBkColor','GUICtrlTreeView_SetBold',
+            'GUICtrlTreeView_SetChecked','GUICtrlTreeView_SetCheckedByIndex',
+            'GUICtrlTreeView_SetChildren','GUICtrlTreeView_SetCut',
+            'GUICtrlTreeView_SetDropTarget','GUICtrlTreeView_SetFocused',
+            'GUICtrlTreeView_SetHeight','GUICtrlTreeView_SetIcon',
+            'GUICtrlTreeView_SetImageIndex','GUICtrlTreeView_SetIndent',
+            'GUICtrlTreeView_SetInsertMark',
+            'GUICtrlTreeView_SetInsertMarkColor',
+            'GUICtrlTreeView_SetItemHeight','GUICtrlTreeView_SetItemParam',
+            'GUICtrlTreeView_SetLineColor','GUICtrlTreeView_SetNormalImageList',
+            'GUICtrlTreeView_SetScrollTime','GUICtrlTreeView_SetSelected',
+            'GUICtrlTreeView_SetSelectedImageIndex','GUICtrlTreeView_SetState',
+            'GUICtrlTreeView_SetStateImageIndex',
+            'GUICtrlTreeView_SetStateImageList','GUICtrlTreeView_SetText',
+            'GUICtrlTreeView_SetTextColor','GUICtrlTreeView_SetToolTips',
+            'GUICtrlTreeView_SetUnicodeFormat','GUICtrlTreeView_Sort',
+            'GUIImageList_Add','GUIImageList_AddBitmap','GUIImageList_AddIcon',
+            'GUIImageList_AddMasked','GUIImageList_BeginDrag',
+            'GUIImageList_Copy','GUIImageList_Create','GUIImageList_Destroy',
+            'GUIImageList_DestroyIcon','GUIImageList_DragEnter',
+            'GUIImageList_DragLeave','GUIImageList_DragMove',
+            'GUIImageList_Draw','GUIImageList_DrawEx','GUIImageList_Duplicate',
+            'GUIImageList_EndDrag','GUIImageList_GetBkColor',
+            'GUIImageList_GetIcon','GUIImageList_GetIconHeight',
+            'GUIImageList_GetIconSize','GUIImageList_GetIconSizeEx',
+            'GUIImageList_GetIconWidth','GUIImageList_GetImageCount',
+            'GUIImageList_GetImageInfoEx','GUIImageList_Remove',
+            'GUIImageList_ReplaceIcon','GUIImageList_SetBkColor',
+            'GUIImageList_SetIconSize','GUIImageList_SetImageCount',
+            'GUIImageList_Swap','GUIScrollBars_EnableScrollBar',
+            'GUIScrollBars_GetScrollBarInfoEx','GUIScrollBars_GetScrollBarRect',
+            'GUIScrollBars_GetScrollBarRGState',
+            'GUIScrollBars_GetScrollBarXYLineButton',
+            'GUIScrollBars_GetScrollBarXYThumbBottom',
+            'GUIScrollBars_GetScrollBarXYThumbTop',
+            'GUIScrollBars_GetScrollInfo','GUIScrollBars_GetScrollInfoEx',
+            'GUIScrollBars_GetScrollInfoMax','GUIScrollBars_GetScrollInfoMin',
+            'GUIScrollBars_GetScrollInfoPage','GUIScrollBars_GetScrollInfoPos',
+            'GUIScrollBars_GetScrollInfoTrackPos','GUIScrollBars_GetScrollPos',
+            'GUIScrollBars_GetScrollRange','GUIScrollBars_Init',
+            'GUIScrollBars_ScrollWindow','GUIScrollBars_SetScrollInfo',
+            'GUIScrollBars_SetScrollInfoMax','GUIScrollBars_SetScrollInfoMin',
+            'GUIScrollBars_SetScrollInfoPage','GUIScrollBars_SetScrollInfoPos',
+            'GUIScrollBars_SetScrollRange','GUIScrollBars_ShowScrollBar',
+            'GUIToolTip_Activate','GUIToolTip_AddTool','GUIToolTip_AdjustRect',
+            'GUIToolTip_BitsToTTF','GUIToolTip_Create','GUIToolTip_DelTool',
+            'GUIToolTip_Destroy','GUIToolTip_EnumTools',
+            'GUIToolTip_GetBubbleHeight','GUIToolTip_GetBubbleSize',
+            'GUIToolTip_GetBubbleWidth','GUIToolTip_GetCurrentTool',
+            'GUIToolTip_GetDelayTime','GUIToolTip_GetMargin',
+            'GUIToolTip_GetMarginEx','GUIToolTip_GetMaxTipWidth',
+            'GUIToolTip_GetText','GUIToolTip_GetTipBkColor',
+            'GUIToolTip_GetTipTextColor','GUIToolTip_GetTitleBitMap',
+            'GUIToolTip_GetTitleText','GUIToolTip_GetToolCount',
+            'GUIToolTip_GetToolInfo','GUIToolTip_HitTest',
+            'GUIToolTip_NewToolRect','GUIToolTip_Pop','GUIToolTip_PopUp',
+            'GUIToolTip_SetDelayTime','GUIToolTip_SetMargin',
+            'GUIToolTip_SetMaxTipWidth','GUIToolTip_SetTipBkColor',
+            'GUIToolTip_SetTipTextColor','GUIToolTip_SetTitle',
+            'GUIToolTip_SetToolInfo','GUIToolTip_SetWindowTheme',
+            'GUIToolTip_ToolExists','GUIToolTip_ToolToArray',
+            'GUIToolTip_TrackActivate','GUIToolTip_TrackPosition',
+            'GUIToolTip_TTFToBits','GUIToolTip_Update',
+            'GUIToolTip_UpdateTipText','HexToString','IE_Example',
+            'IE_Introduction','IE_VersionInfo','IEAction','IEAttach',
+            'IEBodyReadHTML','IEBodyReadText','IEBodyWriteHTML','IECreate',
+            'IECreateEmbedded','IEDocGetObj','IEDocInsertHTML',
+            'IEDocInsertText','IEDocReadHTML','IEDocWriteHTML',
+            'IEErrorHandlerDeRegister','IEErrorHandlerRegister','IEErrorNotify',
+            'IEFormElementCheckBoxSelect','IEFormElementGetCollection',
+            'IEFormElementGetObjByName','IEFormElementGetValue',
+            'IEFormElementOptionSelect','IEFormElementRadioSelect',
+            'IEFormElementSetValue','IEFormGetCollection','IEFormGetObjByName',
+            'IEFormImageClick','IEFormReset','IEFormSubmit',
+            'IEFrameGetCollection','IEFrameGetObjByName','IEGetObjById',
+            'IEGetObjByName','IEHeadInsertEventScript','IEImgClick',
+            'IEImgGetCollection','IEIsFrameSet','IELinkClickByIndex',
+            'IELinkClickByText','IELinkGetCollection','IELoadWait',
+            'IELoadWaitTimeout','IENavigate','IEPropertyGet','IEPropertySet',
+            'IEQuit','IETableGetCollection','IETableWriteToArray',
+            'IETagNameAllGetCollection','IETagNameGetCollection','Iif',
+            'INetExplorerCapable','INetGetSource','INetMail','INetSmtpMail',
+            'IsPressed','MathCheckDiv','Max','MemGlobalAlloc','MemGlobalFree',
+            'MemGlobalLock','MemGlobalSize','MemGlobalUnlock','MemMoveMemory',
+            'MemMsgBox','MemShowError','MemVirtualAlloc','MemVirtualAllocEx',
+            'MemVirtualFree','MemVirtualFreeEx','Min','MouseTrap',
+            'NamedPipes_CallNamedPipe','NamedPipes_ConnectNamedPipe',
+            'NamedPipes_CreateNamedPipe','NamedPipes_CreatePipe',
+            'NamedPipes_DisconnectNamedPipe',
+            'NamedPipes_GetNamedPipeHandleState','NamedPipes_GetNamedPipeInfo',
+            'NamedPipes_PeekNamedPipe','NamedPipes_SetNamedPipeHandleState',
+            'NamedPipes_TransactNamedPipe','NamedPipes_WaitNamedPipe',
+            'Net_Share_ConnectionEnum','Net_Share_FileClose',
+            'Net_Share_FileEnum','Net_Share_FileGetInfo','Net_Share_PermStr',
+            'Net_Share_ResourceStr','Net_Share_SessionDel',
+            'Net_Share_SessionEnum','Net_Share_SessionGetInfo',
+            'Net_Share_ShareAdd','Net_Share_ShareCheck','Net_Share_ShareDel',
+            'Net_Share_ShareEnum','Net_Share_ShareGetInfo',
+            'Net_Share_ShareSetInfo','Net_Share_StatisticsGetSvr',
+            'Net_Share_StatisticsGetWrk','Now','NowCalc','NowCalcDate',
+            'NowDate','NowTime','PathFull','PathMake','PathSplit',
+            'ProcessGetName','ProcessGetPriority','Radian',
+            'ReplaceStringInFile','RunDOS','ScreenCapture_Capture',
+            'ScreenCapture_CaptureWnd','ScreenCapture_SaveImage',
+            'ScreenCapture_SetBMPFormat','ScreenCapture_SetJPGQuality',
+            'ScreenCapture_SetTIFColorDepth','ScreenCapture_SetTIFCompression',
+            'Security__AdjustTokenPrivileges','Security__GetAccountSid',
+            'Security__GetLengthSid','Security__GetTokenInformation',
+            'Security__ImpersonateSelf','Security__IsValidSid',
+            'Security__LookupAccountName','Security__LookupAccountSid',
+            'Security__LookupPrivilegeValue','Security__OpenProcessToken',
+            'Security__OpenThreadToken','Security__OpenThreadTokenEx',
+            'Security__SetPrivilege','Security__SidToStringSid',
+            'Security__SidTypeStr','Security__StringSidToSid','SendMessage',
+            'SendMessageA','SetDate','SetTime','Singleton','SoundClose',
+            'SoundLength','SoundOpen','SoundPause','SoundPlay','SoundPos',
+            'SoundResume','SoundSeek','SoundStatus','SoundStop',
+            'SQLite_Changes','SQLite_Close','SQLite_Display2DResult',
+            'SQLite_Encode','SQLite_ErrCode','SQLite_ErrMsg','SQLite_Escape',
+            'SQLite_Exec','SQLite_FetchData','SQLite_FetchNames',
+            'SQLite_GetTable','SQLite_GetTable2d','SQLite_LastInsertRowID',
+            'SQLite_LibVersion','SQLite_Open','SQLite_Query',
+            'SQLite_QueryFinalize','SQLite_QueryReset','SQLite_QuerySingleRow',
+            'SQLite_SaveMode','SQLite_SetTimeout','SQLite_Shutdown',
+            'SQLite_SQLiteExe','SQLite_Startup','SQLite_TotalChanges',
+            'StringAddComma','StringBetween','StringEncrypt','StringInsert',
+            'StringProper','StringRepeat','StringReverse','StringSplit',
+            'StringToHex','TCPIpToName','TempFile','TicksToTime','Timer_Diff',
+            'Timer_GetTimerID','Timer_Init','Timer_KillAllTimers',
+            'Timer_KillTimer','Timer_SetTimer','TimeToTicks','VersionCompare',
+            'viClose','viExecCommand','viFindGpib','viGpibBusReset','viGTL',
+            'viOpen','viSetAttribute','viSetTimeout','WeekNumberISO',
+            'WinAPI_AttachConsole','WinAPI_AttachThreadInput','WinAPI_Beep',
+            'WinAPI_BitBlt','WinAPI_CallNextHookEx','WinAPI_Check',
+            'WinAPI_ClientToScreen','WinAPI_CloseHandle',
+            'WinAPI_CommDlgExtendedError','WinAPI_CopyIcon',
+            'WinAPI_CreateBitmap','WinAPI_CreateCompatibleBitmap',
+            'WinAPI_CreateCompatibleDC','WinAPI_CreateEvent',
+            'WinAPI_CreateFile','WinAPI_CreateFont','WinAPI_CreateFontIndirect',
+            'WinAPI_CreateProcess','WinAPI_CreateSolidBitmap',
+            'WinAPI_CreateSolidBrush','WinAPI_CreateWindowEx',
+            'WinAPI_DefWindowProc','WinAPI_DeleteDC','WinAPI_DeleteObject',
+            'WinAPI_DestroyIcon','WinAPI_DestroyWindow','WinAPI_DrawEdge',
+            'WinAPI_DrawFrameControl','WinAPI_DrawIcon','WinAPI_DrawIconEx',
+            'WinAPI_DrawText','WinAPI_EnableWindow','WinAPI_EnumDisplayDevices',
+            'WinAPI_EnumWindows','WinAPI_EnumWindowsPopup',
+            'WinAPI_EnumWindowsTop','WinAPI_ExpandEnvironmentStrings',
+            'WinAPI_ExtractIconEx','WinAPI_FatalAppExit','WinAPI_FillRect',
+            'WinAPI_FindExecutable','WinAPI_FindWindow','WinAPI_FlashWindow',
+            'WinAPI_FlashWindowEx','WinAPI_FloatToInt',
+            'WinAPI_FlushFileBuffers','WinAPI_FormatMessage','WinAPI_FrameRect',
+            'WinAPI_FreeLibrary','WinAPI_GetAncestor','WinAPI_GetAsyncKeyState',
+            'WinAPI_GetClassName','WinAPI_GetClientHeight',
+            'WinAPI_GetClientRect','WinAPI_GetClientWidth',
+            'WinAPI_GetCurrentProcess','WinAPI_GetCurrentProcessID',
+            'WinAPI_GetCurrentThread','WinAPI_GetCurrentThreadId',
+            'WinAPI_GetCursorInfo','WinAPI_GetDC','WinAPI_GetDesktopWindow',
+            'WinAPI_GetDeviceCaps','WinAPI_GetDIBits','WinAPI_GetDlgCtrlID',
+            'WinAPI_GetDlgItem','WinAPI_GetFileSizeEx','WinAPI_GetFocus',
+            'WinAPI_GetForegroundWindow','WinAPI_GetIconInfo',
+            'WinAPI_GetLastError','WinAPI_GetLastErrorMessage',
+            'WinAPI_GetModuleHandle','WinAPI_GetMousePos','WinAPI_GetMousePosX',
+            'WinAPI_GetMousePosY','WinAPI_GetObject','WinAPI_GetOpenFileName',
+            'WinAPI_GetOverlappedResult','WinAPI_GetParent',
+            'WinAPI_GetProcessAffinityMask','WinAPI_GetSaveFileName',
+            'WinAPI_GetStdHandle','WinAPI_GetStockObject','WinAPI_GetSysColor',
+            'WinAPI_GetSysColorBrush','WinAPI_GetSystemMetrics',
+            'WinAPI_GetTextExtentPoint32','WinAPI_GetWindow',
+            'WinAPI_GetWindowDC','WinAPI_GetWindowHeight',
+            'WinAPI_GetWindowLong','WinAPI_GetWindowRect',
+            'WinAPI_GetWindowText','WinAPI_GetWindowThreadProcessId',
+            'WinAPI_GetWindowWidth','WinAPI_GetXYFromPoint',
+            'WinAPI_GlobalMemStatus','WinAPI_GUIDFromString',
+            'WinAPI_GUIDFromStringEx','WinAPI_HiWord','WinAPI_InProcess',
+            'WinAPI_IntToFloat','WinAPI_InvalidateRect','WinAPI_IsClassName',
+            'WinAPI_IsWindow','WinAPI_IsWindowVisible','WinAPI_LoadBitmap',
+            'WinAPI_LoadImage','WinAPI_LoadLibrary','WinAPI_LoadLibraryEx',
+            'WinAPI_LoadShell32Icon','WinAPI_LoadString','WinAPI_LocalFree',
+            'WinAPI_LoWord','WinAPI_MakeDWord','WinAPI_MAKELANGID',
+            'WinAPI_MAKELCID','WinAPI_MakeLong','WinAPI_MessageBeep',
+            'WinAPI_Mouse_Event','WinAPI_MoveWindow','WinAPI_MsgBox',
+            'WinAPI_MulDiv','WinAPI_MultiByteToWideChar',
+            'WinAPI_MultiByteToWideCharEx','WinAPI_OpenProcess',
+            'WinAPI_PointFromRect','WinAPI_PostMessage','WinAPI_PrimaryLangId',
+            'WinAPI_PtInRect','WinAPI_ReadFile','WinAPI_ReadProcessMemory',
+            'WinAPI_RectIsEmpty','WinAPI_RedrawWindow',
+            'WinAPI_RegisterWindowMessage','WinAPI_ReleaseCapture',
+            'WinAPI_ReleaseDC','WinAPI_ScreenToClient','WinAPI_SelectObject',
+            'WinAPI_SetBkColor','WinAPI_SetCapture','WinAPI_SetCursor',
+            'WinAPI_SetDefaultPrinter','WinAPI_SetDIBits','WinAPI_SetEvent',
+            'WinAPI_SetFocus','WinAPI_SetFont','WinAPI_SetHandleInformation',
+            'WinAPI_SetLastError','WinAPI_SetParent',
+            'WinAPI_SetProcessAffinityMask','WinAPI_SetSysColors',
+            'WinAPI_SetTextColor','WinAPI_SetWindowLong','WinAPI_SetWindowPos',
+            'WinAPI_SetWindowsHookEx','WinAPI_SetWindowText',
+            'WinAPI_ShowCursor','WinAPI_ShowError','WinAPI_ShowMsg',
+            'WinAPI_ShowWindow','WinAPI_StringFromGUID','WinAPI_SubLangId',
+            'WinAPI_SystemParametersInfo','WinAPI_TwipsPerPixelX',
+            'WinAPI_TwipsPerPixelY','WinAPI_UnhookWindowsHookEx',
+            'WinAPI_UpdateLayeredWindow','WinAPI_UpdateWindow',
+            'WinAPI_ValidateClassName','WinAPI_WaitForInputIdle',
+            'WinAPI_WaitForMultipleObjects','WinAPI_WaitForSingleObject',
+            'WinAPI_WideCharToMultiByte','WinAPI_WindowFromPoint',
+            'WinAPI_WriteConsole','WinAPI_WriteFile',
+            'WinAPI_WriteProcessMemory','WinNet_AddConnection',
+            'WinNet_AddConnection2','WinNet_AddConnection3',
+            'WinNet_CancelConnection','WinNet_CancelConnection2',
+            'WinNet_CloseEnum','WinNet_ConnectionDialog',
+            'WinNet_ConnectionDialog1','WinNet_DisconnectDialog',
+            'WinNet_DisconnectDialog1','WinNet_EnumResource',
+            'WinNet_GetConnection','WinNet_GetConnectionPerformance',
+            'WinNet_GetLastError','WinNet_GetNetworkInformation',
+            'WinNet_GetProviderName','WinNet_GetResourceInformation',
+            'WinNet_GetResourceParent','WinNet_GetUniversalName',
+            'WinNet_GetUser','WinNet_OpenEnum','WinNet_RestoreConnection',
+            'WinNet_UseConnection','Word_VersionInfo','WordAttach','WordCreate',
+            'WordDocAdd','WordDocAddLink','WordDocAddPicture','WordDocClose',
+            'WordDocFindReplace','WordDocGetCollection',
+            'WordDocLinkGetCollection','WordDocOpen','WordDocPrint',
+            'WordDocPropertyGet','WordDocPropertySet','WordDocSave',
+            'WordDocSaveAs','WordErrorHandlerDeRegister',
+            'WordErrorHandlerRegister','WordErrorNotify','WordMacroRun',
+            'WordPropertyGet','WordPropertySet','WordQuit'
+            ),
+        5 => array(
+            'ce','comments-end','comments-start','cs','include','include-once',
+            'NoTrayIcon','RequireAdmin'
+            ),
+        6 => array(
+            'AutoIt3Wrapper_Au3Check_Parameters',
+            'AutoIt3Wrapper_Au3Check_Stop_OnWarning',
+            'AutoIt3Wrapper_Change2CUI','AutoIt3Wrapper_Compression',
+            'AutoIt3Wrapper_cvsWrapper_Parameters','AutoIt3Wrapper_Icon',
+            'AutoIt3Wrapper_Outfile','AutoIt3Wrapper_Outfile_Type',
+            'AutoIt3Wrapper_Plugin_Funcs','AutoIt3Wrapper_Res_Comment',
+            'AutoIt3Wrapper_Res_Description','AutoIt3Wrapper_Res_Field',
+            'AutoIt3Wrapper_Res_File_Add','AutoIt3Wrapper_Res_Fileversion',
+            'AutoIt3Wrapper_Res_FileVersion_AutoIncrement',
+            'AutoIt3Wrapper_Res_Icon_Add','AutoIt3Wrapper_Res_Language',
+            'AutoIt3Wrapper_Res_LegalCopyright',
+            'AutoIt3Wrapper_res_requestedExecutionLevel',
+            'AutoIt3Wrapper_Res_SaveSource','AutoIt3Wrapper_Run_After',
+            'AutoIt3Wrapper_Run_Au3check','AutoIt3Wrapper_Run_Before',
+            'AutoIt3Wrapper_Run_cvsWrapper','AutoIt3Wrapper_Run_Debug_Mode',
+            'AutoIt3Wrapper_Run_Obfuscator','AutoIt3Wrapper_Run_Tidy',
+            'AutoIt3Wrapper_Tidy_Stop_OnError','AutoIt3Wrapper_UseAnsi',
+            'AutoIt3Wrapper_UseUpx','AutoIt3Wrapper_UseX64',
+            'AutoIt3Wrapper_Version','EndRegion','forceref',
+            'Obfuscator_Ignore_Funcs','Obfuscator_Ignore_Variables',
+            'Obfuscator_Parameters','Region','Tidy_Parameters'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(',')','[',']',
+        '+','-','*','/','&','^',
+        '=','+=','-=','*=','/=','&=',
+        '==','<','<=','>','>=',
+        ',','.'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000FF; font-weight: bold;',
+            2 => 'color: #800000; font-weight: bold;',
+            3 => 'color: #000080; font-style: italic; font-weight: bold;',
+            4 => 'color: #0080FF; font-style: italic; font-weight: bold;',
+            5 => 'color: #F000FF; font-style: italic;',
+            6 => 'color: #A00FF0; font-style: italic;'
+            ),
+        'COMMENTS' => array(
+            0 => 'font-style: italic; color: #009933;',
+            'MULTI' => 'font-style: italic; color: #669900;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #FF0000; font-weight: bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'font-weight: bold; color: #008080;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #AC00A9; font-style: italic; font-weight: bold;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000FF; font-style: italic; font-weight: bold;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #FF0000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'font-weight: bold; color: #AA0000;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.autoitscript.com/autoit3/docs/keywords.htm',
+        2 => 'http://www.autoitscript.com/autoit3/docs/macros.htm',
+        3 => 'http://www.autoitscript.com/autoit3/docs/functions/{FNAME}.htm',
+        4 => '',
+        5 => '',
+        6 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        //Variables
+        0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            4 => array(
+                'DISALLOWED_BEFORE' => '(?<!\w)\_'
+            ),
+            5 => array(
+                'DISALLOWED_BEFORE' => '(?<!\w)\#'
+            ),
+            6 => array(
+                'DISALLOWED_BEFORE' => '(?<!\w)\#'
+            )
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/avisynth.php b/examples/includes/geshi/geshi/avisynth.php
new file mode 100644 (file)
index 0000000..a3f60d0
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * avisynth.php
+ * --------
+ * Author: Ryan Jones (sciguyryan@gmail.com)
+ * Copyright: (c) 2008 Ryan Jones
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/10/08
+ *
+ * AviSynth language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/08 (1.0.8.1)
+ *  -  First Release
+ *
+ * TODO (updated 2008/10/08)
+ * -------------------------
+ * * There are also some special words that can't currently be specified directly in GeSHi as they may
+ *      also be used as variables which would really mess things up.
+ * * Also there is an issue with the escape character as this language uses a muti-character escape system. Escape char should be """ but has been left
+ *      as empty due to this restiction.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'AviSynth',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/', '[*' => '*]'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        //  Reserved words.
+        1 => array(
+            'try', 'cache', 'function', 'global', 'return'
+            ),
+        // Constants / special variables.
+        2 => array(
+            'true', 'yes', 'false', 'no', '__END__'
+            ),
+        // Internal Filters.
+        3 => array(
+            'AviSource', 'AviFileSource', 'AddBorders', 'AlignedSplice', 'AssumeFPS', 'AssumeScaledFPS',
+            'AssumeFrameBased', 'AssumeFieldBased', 'AssumeBFF', 'AssumeTFF', 'Amplify', 'AmplifydB',
+            'AssumeSampleRate', 'AudioDub', 'AudioDubEx', 'Animate', 'ApplyRange',
+            'BicubicResize', 'BilinearResize', 'BlackmanResize', 'Blur', 'Bob', 'BlankClip', 'Blackness',
+            'ColorYUV', 'ConvertBackToYUY2', 'ConvertToRGB', 'ConvertToRGB24', 'ConvertToRGB32',
+            'ConvertToYUY2', 'ConvertToY8', 'ConvertToYV411', 'ConvertToYV12', 'ConvertToYV16', 'ConvertToYV24',
+            'ColorKeyMask', 'Crop', 'CropBottom', 'ChangeFPS', 'ConvertFPS', 'ComplementParity', 'ConvertAudioTo8bit',
+            'ConvertAudioTo16bit', 'ConvertAudioTo24bit', 'ConvertAudioTo32bit', 'ConvertAudioToFloat', 'ConvertToMono',
+            'ConditionalFilter', 'ConditionalReader', 'ColorBars', 'Compare',
+            'DirectShowSource', 'DeleteFrame', 'Dissolve', 'DuplicateFrame', 'DoubleWeave', 'DelayAudio',
+            'EnsureVBRMP3Sync',
+            'FixLuminance', 'FlipHorizontal', 'FlipVertical', 'FixBrokenChromaUpsampling', 'FadeIn0', 'FadeIn',
+            'FadeIn2', 'FadeOut0', 'FadeOut', 'FadeOut2', 'FadeIO0', 'FadeIO', 'FadeIO2', 'FreezeFrame', 'FrameEvaluate',
+            'GreyScale', 'GaussResize', 'GeneralConvolution', 'GetChannel', 'GetLeftChannel', 'GetRightChannel',
+            'HorizontalReduceBy2', 'Histogram',
+            'ImageReader', 'ImageSource', 'ImageWriter', 'Invert', 'Interleave', 'Info',
+            'KillAudio', 'KillVideo',
+            'Levels', 'Limiter', 'Layer', 'Letterbox', 'LanczosResize', 'Lanczos4Resize', 'Loop',
+            'MergeARGB', 'MergeRGB', 'MergeChroma', 'MergeLuma', 'Merge', 'Mask', 'MaskHS', 'MergeChannels', 'MixAudio',
+            'MonoToStereo', 'MessageClip',
+            'Normalize',
+            'OpenDMLSource', 'Overlay',
+            'PointResize', 'PeculiarBlend', 'Pulldown',
+            'RGBAdjust', 'ResetMask', 'Reverse', 'ResampleAudio', 'ReduceBy2',
+            'SegmentedAviSource', 'SegmentedDirectShowSource', 'SoundOut', 'ShowAlpha', 'ShowRed', 'ShowGreen',
+            'ShowBlue', 'SwapUV', 'Subtract', 'SincResize', 'Spline16Resize', 'Spline36Resize', 'Spline64Resize',
+            'SelectEven', 'SelectOdd', 'SelectEvery', 'SelectRangeEvery', 'Sharpen', 'SpatialSoften', 'SeparateFields',
+            'ShowFiveVersions', 'ShowFrameNumber', 'ShowSMPTE', 'ShowTime', 'StackHorizontal', 'StackVertical', 'Subtitle',
+            'SwapFields', 'SuperEQ', 'SSRC', 'ScriptClip',
+            'Tweak', 'TurnLeft', 'TurnRight', 'Turn180', 'TemporalSoften', 'TimeStretch', 'TCPServer', 'TCPSource', 'Trim',
+            'Tone',
+            'UToY', 'UToY8', 'UnalignedSplice',
+            'VToY', 'VToY8', 'VerticalReduceBy2', 'Version',
+            'WavSource', 'Weave', 'WriteFile', 'WriteFileIf', 'WriteFileStart', 'WriteFileEnd',
+            'YToUV'
+            ),
+        // Internal functions.
+        4 => array(
+            'Abs', 'Apply', 'Assert', 'AverageLuma', 'AverageChromaU', 'AverageChromaV',
+            'Ceil', 'Cos', 'Chr', 'ChromaUDifference', 'ChromaVDifference',
+            'Defined', 'Default',
+            'Exp', 'Exist', 'Eval',
+            'Floor', 'Frac', 'Float', 'Findstr', 'GetMTMode',
+            'HexValue',
+            'Int', 'IsBool', 'IsClip', 'IsFloat', 'IsInt', 'IsString', 'Import',
+            'LoadPlugin', 'Log', 'LCase', 'LeftStr', 'LumaDifference', 'LoadVirtualDubPlugin', 'LoadVFAPIPlugin',
+            'LoadCPlugin', 'Load_Stdcall_Plugin',
+            'Max', 'MulDiv', 'MidStr',
+            'NOP',
+            'OPT_AllowFloatAudio', 'OPT_UseWaveExtensible',
+            'Pi', 'Pow',
+            'Round', 'Rand', 'RevStr', 'RightStr', 'RGBDifference', 'RGBDifferenceFromPrevious', 'RGBDifferenceToNext',
+            'Sin', 'Sqrt', 'Sign', 'Spline', 'StrLen', 'String', 'Select', 'SetMemoryMax', 'SetWorkingDir', 'SetMTMode',
+            'SetPlanarLegacyAlignment',
+            'Time',
+            'UCase', 'UDifferenceFromPrevious', 'UDifferenceToNext', 'UPlaneMax', 'UPlaneMin', 'UPlaneMedian',
+            'UPlaneMinMaxDifference',
+            'Value', 'VersionNumber', 'VersionString', 'VDifferenceFromPrevious', 'VDifferenceToNext', 'VPlaneMax',
+            'VPlaneMin', 'VPlaneMedian', 'VPlaneMinMaxDifference',
+            'YDifferenceFromPrevious', 'YDifferenceToNext', 'YPlaneMax', 'YPlaneMin', 'YPlaneMedian',
+            'YPlaneMinMaxDifference'
+            )
+        ),
+    'SYMBOLS' => array(
+        '+', '++', '-', '--', '/', '*', '%',
+        '=', '==', '<', '<=', '>', '>=', '<>', '!=',
+        '!', '?', ':',
+        '|', '||', '&&',
+        '\\',
+        '(', ')', '{', '}',
+        '.', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color:#9966CC; font-weight:bold;',
+            2 => 'color:#0000FF; font-weight:bold;',
+            3 => 'color:#CC3300; font-weight:bold;',
+            4 => 'color:#660000; font-weight:bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color:#008000; font-style:italic;',
+            'MULTI' => 'color:#000080; font-style:italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color:#000099;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color:#006600; font-weight:bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color:#996600;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color:#006666;'
+            ),
+        'METHODS' => array(
+            1 => 'color:#9900CC;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color:#006600; font-weight:bold;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://avisynth.org/mediawiki/{FNAME}',
+        4 => ''
+        ),
+    'REGEXPS' => array(
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+?>
diff --git a/examples/includes/geshi/geshi/bash.php b/examples/includes/geshi/geshi/bash.php
new file mode 100644 (file)
index 0000000..b41f895
--- /dev/null
@@ -0,0 +1,282 @@
+<?php
+/*************************************************************************************
+ * bash.php
+ * --------
+ * Author: Andreas Gohr (andi@splitbrain.org)
+ * Copyright: (c) 2004 Andreas Gohr, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/20
+ *
+ * BASH language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/21 (1.0.8)
+ *  -  Added loads of keywords and commands of GNU/Linux
+ *  -  Added support for parameters starting with a dash
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2007/09/05 (1.0.7.21)
+ *  -  PARSER_CONTROL patch using SF #1788408 (BenBE)
+ * 2007/06/11 (1.0.7.20)
+ *  -  Added a lot of keywords (BenBE / Jan G)
+ * 2004/11/27 (1.0.2)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   -  Added support for URLs
+ * 2004/08/20 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Get symbols working
+ * * Highlight builtin vars
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Bash',
+    // Bash DOES have single line comments with # markers. But bash also has
+    // the  $# variable, so comments need special handling (see sf.net
+    // 1564839)
+    'COMMENT_SINGLE' => array('#'),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        //Variables
+        1 => "/\\$\\{[^\\n\\}]*?\\}/i",
+        //BASH-style Heredoc
+        2 => '/<<-?\s*?(\'?)([a-zA-Z0-9]+)\1\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+        //Escaped String Starters
+        3 => "/\\\\['\"]/siU"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array("\'"),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[nfrtv\\$\\\"\n]#i",
+        // $var
+        2 => "#\\$[a-z_][a-z0-9_]*#i",
+        // ${...}
+        3 => "/\\$\\{[^\\n\\}]*?\\}/i",
+        // $(...)
+        4 => "/\\$\\([^\\n\\)]*?\\)/i",
+        // `...`
+        5 => "/`[^`]*`/"
+        ),
+    'KEYWORDS' => array(
+        1 => array(
+            'case', 'do', 'done', 'elif', 'else', 'esac', 'fi', 'for', 'function',
+            'if', 'in', 'select', 'set', 'then', 'until', 'while', 'time'
+            ),
+        2 => array(
+            'aclocal', 'aconnect', 'aplay', 'apm', 'apmsleep', 'apropos',
+            'apt-cache', 'apt-get', 'apt-key', 'aptitude',
+            'ar', 'arch', 'arecord', 'as', 'as86', 'ash', 'autoconf',
+            'autoheader', 'automake', 'awk',
+
+            'basename', 'bash', 'bc', 'bison', 'bunzip2', 'bzcat',
+            'bzcmp', 'bzdiff', 'bzegrep', 'bzfgrep', 'bzgrep',
+            'bzip2', 'bzip2recover', 'bzless', 'bzmore',
+
+            'c++', 'cal', 'cat', 'chattr', 'cc', 'cdda2wav', 'cdparanoia',
+            'cdrdao', 'cd-read', 'cdrecord', 'chfn', 'chgrp', 'chmod',
+            'chown', 'chroot', 'chsh', 'chvt', 'clear', 'cmp', 'comm', 'co',
+            'col', 'cp', 'cpio', 'cpp', 'csh', 'cut', 'cvs', 'cvs-pserver',
+
+            'dash', 'date', 'dd', 'dc', 'dcop', 'deallocvt', 'df', 'dialog',
+            'diff', 'diff3', 'dir', 'dircolors', 'directomatic', 'dirname',
+            'dmesg', 'dnsdomainname', 'domainname', 'dpkg', 'dselect', 'du',
+            'dumpkeys',
+
+            'ed', 'egrep', 'env', 'expr',
+
+            'false', 'fbset', 'ffmpeg', 'fgconsole','fgrep', 'file', 'find',
+            'flex', 'flex++', 'fmt', 'free', 'ftp', 'funzip', 'fuser',
+
+            'g++', 'gawk', 'gc','gcc', 'gdb', 'getent', 'getkeycodes',
+            'getopt', 'gettext', 'gettextize', 'gimp', 'gimp-remote',
+            'gimptool', 'gmake', 'gocr', 'grep', 'groups', 'gs', 'gunzip',
+            'gzexe', 'gzip',
+
+            'head', 'hexdump', 'hostname',
+
+            'id', 'ifconfig', 'igawk', 'install',
+
+            'join',
+
+            'kbd_mode','kbdrate', 'kdialog', 'kfile', 'kill', 'killall',
+
+            'lame', 'last', 'lastb', 'ld', 'ld86', 'ldd', 'less', 'lex', 'link',
+            'ln', 'loadkeys', 'loadunimap', 'locate', 'lockfile', 'login',
+            'logname', 'lp', 'lpr', 'ls', 'lsattr', 'lsmod', 'lsmod.old',
+            'lspci', 'ltrace', 'lynx',
+
+            'm4', 'make', 'man', 'mapscrn', 'mesg', 'mkdir', 'mkfifo',
+            'mknod', 'mktemp', 'more', 'mount', 'mplayer', 'msgfmt', 'mv',
+
+            'namei', 'nano', 'nasm', 'nawk', 'netstat', 'nice',
+            'nisdomainname', 'nl', 'nm', 'nm86', 'nmap', 'nohup', 'nop',
+
+            'od', 'openvt',
+
+            'passwd', 'patch', 'pcregrep', 'pcretest', 'perl', 'perror',
+            'pgawk', 'pidof', 'ping', 'pr', 'procmail', 'prune', 'ps', 'pstree',
+            'ps2ascii', 'ps2epsi', 'ps2frag', 'ps2pdf', 'ps2ps', 'psbook',
+            'psmerge', 'psnup', 'psresize', 'psselect', 'pstops',
+
+            'rbash', 'rcs', 'rcs2log', 'read', 'readlink', 'red', 'resizecons',
+            'rev', 'rm', 'rmdir', 'rsh', 'run-parts',
+
+            'sash', 'scp', 'screen', 'sed', 'seq', 'sendmail', 'setfont',
+            'setkeycodes', 'setleds', 'setmetamode', 'setserial', 'setterm',
+            'sh', 'showkey', 'shred', 'size', 'size86', 'skill', 'sleep',
+            'slogin', 'snice', 'sort', 'sox', 'split', 'ssed', 'ssh', 'ssh-add',
+            'ssh-agent', 'ssh-keygen', 'ssh-keyscan', 'stat', 'strace',
+            'strings', 'strip', 'stty', 'su', 'sudo', 'suidperl', 'sum', 'svn',
+            'svnadmin', 'svndumpfilter', 'svnlook', 'svnmerge', 'svnmucc',
+            'svnserve', 'svnshell', 'svnsync', 'svnversion', 'svnwrap', 'sync',
+
+            'tac', 'tail', 'tar', 'tee', 'tempfile', 'touch', 'tr', 'tree',
+            'true',
+
+            'umount', 'uname', 'unicode_start', 'unicode_stop', 'uniq',
+            'unlink', 'unzip', 'updatedb', 'updmap', 'uptime', 'users',
+            'utmpdump', 'uuidgen',
+
+            'valgrind', 'vdir', 'vi', 'vim', 'vmstat',
+
+            'w', 'wall', 'wc', 'wget', 'whatis', 'whereis', 'which', 'whiptail',
+            'who', 'whoami', 'write',
+
+            'xargs', 'xhost', 'xmodmap', 'xset',
+
+            'yacc', 'yes', 'ypdomainname',
+
+            'zcat', 'zcmp', 'zdiff', 'zdump', 'zegrep', 'zfgrep', 'zforce',
+            'zgrep', 'zip', 'zipgrep', 'zipinfo', 'zless', 'zmore', 'znew',
+            'zsh', 'zsoelim'
+            ),
+        3 => array(
+            'alias', 'bg', 'bind', 'break', 'builtin', 'cd', 'command',
+            'compgen', 'complete', 'continue', 'declare', 'dirs', 'disown',
+            'echo', 'enable', 'eval', 'exec', 'exit', 'export', 'fc',
+            'fg', 'getopts', 'hash', 'help', 'history', 'jobs', 'let',
+            'local', 'logout', 'popd', 'printf', 'pushd', 'pwd', 'readonly',
+            'return', 'shift', 'shopt', 'source', 'suspend', 'test', 'times',
+            'trap', 'type', 'typeset', 'ulimit', 'umask', 'unalias', 'unset',
+            'wait'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>', ';;', '`'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #c20cb9; font-weight: bold;',
+            3 => 'color: #7a0874; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            0 => 'color: #666666; font-style: italic;',
+            1 => 'color: #800000;',
+            2 => 'color: #cc0000; font-style: italic;',
+            3 => 'color: #000000; font-weight: bold;'
+            ),
+        'ESCAPE_CHAR' => array(
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #007800;',
+            3 => 'color: #007800;',
+            4 => 'color: #007800;',
+            5 => 'color: #780078;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #7a0874; font-weight: bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;',
+            'HARD' => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #007800;',
+            1 => 'color: #007800;',
+            2 => 'color: #007800;',
+            4 => 'color: #007800;',
+            5 => 'color: #660033;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Variables (will be handled by comment_regexps)
+        0 => "\\$\\{[a-zA-Z_][a-zA-Z0-9_]*?\\}",
+        //Variables without braces
+        1 => "\\$[a-zA-Z_][a-zA-Z0-9_]*",
+        //Variable assignment
+        2 => "(?<![\.a-zA-Z_\-])([a-zA-Z_][a-zA-Z0-9_]*?)(?==)",
+        //Shorthand shell variables
+        4 => "\\$[*#\$\\-\\?!]",
+        //Parameters of commands
+        5 => "(?<=\s)--?[0-9a-zA-Z\-]+(?=[\s=]|$)"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'COMMENTS' => array(
+            'DISALLOWED_BEFORE' => '$'
+        ),
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#])",
+            'DISALLOWED_AFTER' =>  "(?![\.\-a-zA-Z0-9_%\\/])"
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/basic4gl.php b/examples/includes/geshi/geshi/basic4gl.php
new file mode 100644 (file)
index 0000000..a7b00b9
--- /dev/null
@@ -0,0 +1,341 @@
+<?php
+/*************************************************************************************
+ * basic4gl.php
+ * ---------------------------------
+ * Author: Matthew Webb (bmatthew1@blueyonder.co.uk)
+ * Copyright: (c) 2004 Matthew Webb (http://matthew-4gl.wikispaces.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/09/15
+ *
+ * Basic4GL language file for GeSHi.
+ *
+ * You can find the Basic4GL Website at (http://www.basic4gl.net/)
+ *
+ * CHANGES
+ * -------
+ * 2007/09/17 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2007/09/17)
+ * -------------------------
+ * Make sure all the OpenGL and Basic4GL commands have been added and are complete.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Basic4GL',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+
+            // Navy Blue Bold Keywords
+
+            'true','rnd_max','m_pi','m_e','false','VK_ZOOM','VK_UP','VK_TAB','VK_SUBTRACT','VK_SPACE','VK_SNAPSHOT',
+            'VK_SHIFT','VK_SEPARATOR','VK_SELECT','VK_SCROLL','VK_RWIN','VK_RSHIFT','VK_RMENU','VK_RIGHT','VK_RETURN',
+            'VK_RCONTROL','VK_RBUTTON','VK_PROCESSKEY','VK_PRIOR','VK_PRINT','VK_PLAY','VK_PAUSE','VK_NUMPAD9','VK_NUMPAD8',
+            'VK_NUMPAD7','VK_NUMPAD6','VK_NUMPAD5','VK_NUMPAD4','VK_NUMPAD3','VK_NUMPAD2','VK_NUMPAD1','VK_NUMPAD0',
+            'VK_NUMLOCK','VK_NONCONVERT','VK_NEXT','VK_MULTIPLY','VK_MODECHANGE','VK_MENU','VK_MBUTTON','VK_LWIN',
+            'VK_LSHIFT','VK_LMENU','VK_LEFT','VK_LCONTROL','VK_LBUTTON','VK_KANJI','VK_KANA','VK_JUNJA','VK_INSERT',
+            'VK_HOME','VK_HELP','VK_HANJA','VK_HANGUL','VK_HANGEUL','VK_FINAL','VK_F9','VK_F8','VK_F7','VK_F6','VK_F5',
+            'VK_F4','VK_F3','VK_F24','VK_F23','VK_F22','VK_F21','VK_F20','VK_F2','VK_F19','VK_F18','VK_F17','VK_F16',
+            'VK_F15','VK_F14','VK_F13','VK_F12','VK_F11','VK_F10','VK_F1','VK_EXSEL','VK_EXECUTE','VK_ESCAPE','VK_EREOF',
+            'VK_END','VK_DOWN','VK_DIVIDE','VK_DELETE','VK_DECIMAL','VK_CRSEL','VK_CONVERT','VK_CONTROL','VK_CLEAR',
+            'VK_CAPITAL','VK_CANCEL','VK_BACK','VK_ATTN','VK_APPS','VK_ADD','VK_ACCEPT','TEXT_SIMPLE','TEXT_OVERLAID',
+            'TEXT_BUFFERED','SPR_TILEMAP','SPR_SPRITE','SPR_INVALID','MOUSE_RBUTTON','MOUSE_MBUTTON','MOUSE_LBUTTON',
+            'GL_ZOOM_Y','GL_ZOOM_X','GL_ZERO','GL_XOR','GL_WIN_swap_hint','GL_WIN_draw_range_elements','GL_VIEWPORT_BIT',
+            'GL_VIEWPORT','GL_VERTEX_ARRAY_TYPE_EXT','GL_VERTEX_ARRAY_TYPE','GL_VERTEX_ARRAY_STRIDE_EXT','GL_VERTEX_ARRAY_STRIDE',
+            'GL_VERTEX_ARRAY_SIZE_EXT','GL_VERTEX_ARRAY_SIZE','GL_VERTEX_ARRAY_POINTER_EXT','GL_VERTEX_ARRAY_POINTER',
+            'GL_VERTEX_ARRAY_EXT','GL_VERTEX_ARRAY_COUNT_EXT','GL_VERTEX_ARRAY','GL_VERSION_1_1','GL_VERSION','GL_VENDOR',
+            'GL_V3F','GL_V2F','GL_UNSIGNED_SHORT','GL_UNSIGNED_INT','GL_UNSIGNED_BYTE','GL_UNPACK_SWAP_BYTES','GL_UNPACK_SKIP_ROWS',
+            'GL_UNPACK_SKIP_PIXELS','GL_UNPACK_ROW_LENGTH','GL_UNPACK_LSB_FIRST','GL_UNPACK_ALIGNMENT','GL_TRUE','GL_TRIANGLE_STRIP',
+            'GL_TRIANGLE_FAN','GL_TRIANGLES','GL_TRANSFORM_BIT','GL_TEXTURE_WRAP_T','GL_TEXTURE_WRAP_S','GL_TEXTURE_WIDTH',
+            'GL_TEXTURE_STACK_DEPTH','GL_TEXTURE_RESIDENT','GL_TEXTURE_RED_SIZE','GL_TEXTURE_PRIORITY','GL_TEXTURE_MIN_FILTER',
+            'GL_TEXTURE_MATRIX','GL_TEXTURE_MAG_FILTER','GL_TEXTURE_LUMINANCE_SIZE','GL_TEXTURE_INTERNAL_FORMAT','GL_TEXTURE_INTENSITY_SIZE',
+            'GL_TEXTURE_HEIGHT','GL_TEXTURE_GREEN_SIZE','GL_TEXTURE_GEN_T','GL_TEXTURE_GEN_S','GL_TEXTURE_GEN_R','GL_TEXTURE_GEN_Q',
+            'GL_TEXTURE_GEN_MODE','GL_TEXTURE_ENV_MODE','GL_TEXTURE_ENV_COLOR','GL_TEXTURE_ENV','GL_TEXTURE_COORD_ARRAY_TYPE_EXT',
+            'GL_TEXTURE_COORD_ARRAY_TYPE','GL_TEXTURE_COORD_ARRAY_STRIDE_EXT','GL_TEXTURE_COORD_ARRAY_STRIDE','GL_TEXTURE_COORD_ARRAY_SIZE_EXT',
+            'GL_TEXTURE_COORD_ARRAY_SIZE','GL_TEXTURE_COORD_ARRAY_POINTER_EXT','GL_TEXTURE_COORD_ARRAY_POINTER','GL_TEXTURE_COORD_ARRAY_EXT',
+            'GL_TEXTURE_COORD_ARRAY_COUNT_EXT','GL_TEXTURE_COORD_ARRAY','GL_TEXTURE_COMPONENTS','GL_TEXTURE_BORDER_COLOR','GL_TEXTURE_BORDER',
+            'GL_TEXTURE_BLUE_SIZE','GL_TEXTURE_BIT','GL_TEXTURE_BINDING_2D','GL_TEXTURE_BINDING_1D','GL_TEXTURE_ALPHA_SIZE',
+            'GL_TEXTURE_2D','GL_TEXTURE_1D','GL_TEXTURE9_ARB','GL_TEXTURE9','GL_TEXTURE8_ARB','GL_TEXTURE8','GL_TEXTURE7_ARB',
+            'GL_TEXTURE7','GL_TEXTURE6_ARB','GL_TEXTURE6','GL_TEXTURE5_ARB','GL_TEXTURE5','GL_TEXTURE4_ARB','GL_TEXTURE4',
+            'GL_TEXTURE3_ARB','GL_TEXTURE31_ARB','GL_TEXTURE31','GL_TEXTURE30_ARB','GL_TEXTURE30','GL_TEXTURE3','GL_TEXTURE2_ARB',
+            'GL_TEXTURE29_ARB','GL_TEXTURE29','GL_TEXTURE28_ARB','GL_TEXTURE28','GL_TEXTURE27_ARB','GL_TEXTURE27','GL_TEXTURE26_ARB',
+            'GL_TEXTURE26','GL_TEXTURE25_ARB','GL_TEXTURE25','GL_TEXTURE24_ARB','GL_TEXTURE24','GL_TEXTURE23_ARB','GL_TEXTURE23',
+            'GL_TEXTURE22_ARB','GL_TEXTURE22','GL_TEXTURE21_ARB','GL_TEXTURE21','GL_TEXTURE20_ARB','GL_TEXTURE20','GL_TEXTURE2',
+            'GL_TEXTURE1_ARB','GL_TEXTURE19_ARB','GL_TEXTURE19','GL_TEXTURE18_ARB','GL_TEXTURE18','GL_TEXTURE17_ARB',
+            'GL_TEXTURE17','GL_TEXTURE16_ARB','GL_TEXTURE16','GL_TEXTURE15_ARB','GL_TEXTURE15','GL_TEXTURE14_ARB','GL_TEXTURE14',
+            'GL_TEXTURE13_ARB','GL_TEXTURE13','GL_TEXTURE12_ARB','GL_TEXTURE12','GL_TEXTURE11_ARB','GL_TEXTURE11','GL_TEXTURE10_ARB',
+            'GL_TEXTURE10','GL_TEXTURE1','GL_TEXTURE0_ARB','GL_TEXTURE0','GL_TEXTURE','GL_T4F_V4F','GL_T4F_C4F_N3F_V4F','GL_T2F_V3F',
+            'GL_T2F_N3F_V3F','GL_T2F_C4UB_V3F','GL_T2F_C4F_N3F_V3F','GL_T2F_C3F_V3F','GL_T','GL_SUBPIXEL_BITS','GL_STEREO',
+            'GL_STENCIL_WRITEMASK','GL_STENCIL_VALUE_MASK','GL_STENCIL_TEST','GL_STENCIL_REF','GL_STENCIL_PASS_DEPTH_PASS',
+            'GL_STENCIL_PASS_DEPTH_FAIL','GL_STENCIL_INDEX','GL_STENCIL_FUNC','GL_STENCIL_FAIL','GL_STENCIL_CLEAR_VALUE',
+            'GL_STENCIL_BUFFER_BIT','GL_STENCIL_BITS','GL_STENCIL','GL_STACK_UNDERFLOW','GL_STACK_OVERFLOW','GL_SRC_COLOR',
+            'GL_SRC_ALPHA_SATURATE','GL_SRC_ALPHA','GL_SPOT_EXPONENT','GL_SPOT_DIRECTION','GL_SPOT_CUTOFF','GL_SPHERE_MAP',
+            'GL_SPECULAR','GL_SOURCE2_RGB_EXT','GL_SOURCE2_RGB','GL_SOURCE2_ALPHA_EXT','GL_SOURCE2_ALPHA','GL_SOURCE1_RGB_EXT',
+            'GL_SOURCE1_RGB','GL_SOURCE1_ALPHA_EXT','GL_SOURCE1_ALPHA','GL_SOURCE0_RGB_EXT','GL_SOURCE0_RGB','GL_SOURCE0_ALPHA_EXT',
+            'GL_SOURCE0_ALPHA','GL_SMOOTH','GL_SHORT','GL_SHININESS','GL_SHADE_MODEL','GL_SET','GL_SELECTION_BUFFER_SIZE',
+            'GL_SELECTION_BUFFER_POINTER','GL_SELECT','GL_SCISSOR_TEST','GL_SCISSOR_BOX','GL_SCISSOR_BIT','GL_S','GL_RIGHT',
+            'GL_RGB_SCALE_EXT','GL_RGB_SCALE','GL_RGBA_MODE','GL_RGBA8','GL_RGBA4','GL_RGBA2','GL_RGBA16','GL_RGBA12','GL_RGBA',
+            'GL_RGB8','GL_RGB5_A1','GL_RGB5','GL_RGB4','GL_RGB16','GL_RGB12','GL_RGB10_A2','GL_RGB10','GL_RGB','GL_RETURN',
+            'GL_REPLACE','GL_REPEAT','GL_RENDER_MODE','GL_RENDERER','GL_RENDER','GL_RED_SCALE','GL_RED_BITS','GL_RED_BIAS',
+            'GL_RED','GL_READ_BUFFER','GL_R3_G3_B2','GL_R','GL_QUAD_STRIP','GL_QUADS','GL_QUADRATIC_ATTENUATION','GL_Q',
+            'GL_PROXY_TEXTURE_2D','GL_PROXY_TEXTURE_1D','GL_PROJECTION_STACK_DEPTH','GL_PROJECTION_MATRIX','GL_PROJECTION',
+            'GL_PRIMARY_COLOR_EXT','GL_PRIMARY_COLOR','GL_PREVIOUS_EXT','GL_PREVIOUS','GL_POSITION','GL_POLYGON_TOKEN',
+            'GL_POLYGON_STIPPLE_BIT','GL_POLYGON_STIPPLE','GL_POLYGON_SMOOTH_HINT','GL_POLYGON_SMOOTH','GL_POLYGON_OFFSET_UNITS',
+            'GL_POLYGON_OFFSET_POINT','GL_POLYGON_OFFSET_LINE','GL_POLYGON_OFFSET_FILL','GL_POLYGON_OFFSET_FACTOR','GL_POLYGON_MODE',
+            'GL_POLYGON_BIT','GL_POLYGON','GL_POINT_TOKEN','GL_POINT_SMOOTH_HINT','GL_POINT_SMOOTH','GL_POINT_SIZE_RANGE',
+            'GL_POINT_SIZE_GRANULARITY','GL_POINT_SIZE','GL_POINT_BIT','GL_POINTS','GL_POINT','GL_PIXEL_MODE_BIT',
+            'GL_PIXEL_MAP_S_TO_S_SIZE','GL_PIXEL_MAP_S_TO_S','GL_PIXEL_MAP_R_TO_R_SIZE','GL_PIXEL_MAP_R_TO_R','GL_PIXEL_MAP_I_TO_R_SIZE',
+            'GL_PIXEL_MAP_I_TO_R','GL_PIXEL_MAP_I_TO_I_SIZE','GL_PIXEL_MAP_I_TO_I','GL_PIXEL_MAP_I_TO_G_SIZE','GL_PIXEL_MAP_I_TO_G',
+            'GL_PIXEL_MAP_I_TO_B_SIZE','GL_PIXEL_MAP_I_TO_B','GL_PIXEL_MAP_I_TO_A_SIZE','GL_PIXEL_MAP_I_TO_A','GL_PIXEL_MAP_G_TO_G_SIZE',
+            'GL_PIXEL_MAP_G_TO_G','GL_PIXEL_MAP_B_TO_B_SIZE','GL_PIXEL_MAP_B_TO_B','GL_PIXEL_MAP_A_TO_A_SIZE','GL_PIXEL_MAP_A_TO_A',
+            'GL_PHONG_WIN','GL_PHONG_HINT_WIN','GL_PERSPECTIVE_CORRECTION_HINT','GL_PASS_THROUGH_TOKEN','GL_PACK_SWAP_BYTES',
+            'GL_PACK_SKIP_ROWS','GL_PACK_SKIP_PIXELS','GL_PACK_ROW_LENGTH','GL_PACK_LSB_FIRST','GL_PACK_ALIGNMENT','GL_OUT_OF_MEMORY',
+            'GL_OR_REVERSE','GL_OR_INVERTED','GL_ORDER','GL_OR','GL_OPERAND2_RGB_EXT','GL_OPERAND2_RGB','GL_OPERAND2_ALPHA_EXT',
+            'GL_OPERAND2_ALPHA','GL_OPERAND1_RGB_EXT','GL_OPERAND1_RGB','GL_OPERAND1_ALPHA_EXT','GL_OPERAND1_ALPHA','GL_OPERAND0_RGB_EXT',
+            'GL_OPERAND0_RGB','GL_OPERAND0_ALPHA_EXT','GL_OPERAND0_ALPHA','GL_ONE_MINUS_SRC_COLOR','GL_ONE_MINUS_SRC_ALPHA',
+            'GL_ONE_MINUS_DST_COLOR','GL_ONE_MINUS_DST_ALPHA','GL_ONE','GL_OBJECT_PLANE','GL_OBJECT_LINEAR','GL_NO_ERROR',
+            'GL_NOTEQUAL','GL_NORMAL_ARRAY_TYPE_EXT','GL_NORMAL_ARRAY_TYPE','GL_NORMAL_ARRAY_STRIDE_EXT','GL_NORMAL_ARRAY_STRIDE',
+            'GL_NORMAL_ARRAY_POINTER_EXT','GL_NORMAL_ARRAY_POINTER','GL_NORMAL_ARRAY_EXT','GL_NORMAL_ARRAY_COUNT_EXT',
+            'GL_NORMAL_ARRAY','GL_NORMALIZE','GL_NOR','GL_NOOP','GL_NONE','GL_NICEST','GL_NEVER','GL_NEAREST_MIPMAP_NEAREST','GL_NEAREST_MIPMAP_LINEAR',
+            'GL_NEAREST','GL_NAND','GL_NAME_STACK_DEPTH','GL_N3F_V3F','GL_MULT','GL_MODULATE','GL_MODELVIEW_STACK_DEPTH','GL_MODELVIEW_MATRIX',
+            'GL_MODELVIEW','GL_MAX_VIEWPORT_DIMS','GL_MAX_TEXTURE_UNITS_ARB','GL_MAX_TEXTURE_UNITS','GL_MAX_TEXTURE_STACK_DEPTH',
+            'GL_MAX_TEXTURE_SIZE','GL_MAX_PROJECTION_STACK_DEPTH','GL_MAX_PIXEL_MAP_TABLE','GL_MAX_NAME_STACK_DEPTH','GL_MAX_MODELVIEW_STACK_DEPTH',
+            'GL_MAX_LIST_NESTING','GL_MAX_LIGHTS','GL_MAX_EVAL_ORDER','GL_MAX_ELEMENTS_VERTICES_WIN','GL_MAX_ELEMENTS_INDICES_WIN',
+            'GL_MAX_CLIP_PLANES','GL_MAX_CLIENT_ATTRIB_STACK_DEPTH','GL_MAX_ATTRIB_STACK_DEPTH','GL_MATRIX_MODE','GL_MAP_STENCIL',
+            'GL_MAP_COLOR','GL_MAP2_VERTEX_4','GL_MAP2_VERTEX_3','GL_MAP2_TEXTURE_COORD_4','GL_MAP2_TEXTURE_COORD_3','GL_MAP2_TEXTURE_COORD_2',
+            'GL_MAP2_TEXTURE_COORD_1','GL_MAP2_NORMAL','GL_MAP2_INDEX','GL_MAP2_GRID_SEGMENTS','GL_MAP2_GRID_DOMAIN','GL_MAP2_COLOR_4',
+            'GL_MAP1_VERTEX_4','GL_MAP1_VERTEX_3','GL_MAP1_TEXTURE_COORD_4','GL_MAP1_TEXTURE_COORD_3','GL_MAP1_TEXTURE_COORD_2',
+            'GL_MAP1_TEXTURE_COORD_1','GL_MAP1_NORMAL','GL_MAP1_INDEX','GL_MAP1_GRID_SEGMENTS','GL_MAP1_GRID_DOMAIN',
+            'GL_MAP1_COLOR_4','GL_LUMINANCE_ALPHA','GL_LUMINANCE8_ALPHA8','GL_LUMINANCE8','GL_LUMINANCE6_ALPHA2','GL_LUMINANCE4_ALPHA4',
+            'GL_LUMINANCE4','GL_LUMINANCE16_ALPHA16','GL_LUMINANCE16','GL_LUMINANCE12_ALPHA4','GL_LUMINANCE12_ALPHA12','GL_LUMINANCE12',
+            'GL_LUMINANCE','GL_LOGIC_OP_MODE','GL_LOGIC_OP','GL_LOAD','GL_LIST_MODE','GL_LIST_INDEX','GL_LIST_BIT',
+            'GL_LIST_BASE','GL_LINE_WIDTH_RANGE','GL_LINE_WIDTH_GRANULARITY','GL_LINE_WIDTH','GL_LINE_TOKEN','GL_LINE_STRIP','GL_LINE_STIPPLE_REPEAT',
+            'GL_LINE_STIPPLE_PATTERN','GL_LINE_STIPPLE','GL_LINE_SMOOTH_HINT','GL_LINE_SMOOTH','GL_LINE_RESET_TOKEN','GL_LINE_LOOP',
+            'GL_LINE_BIT','GL_LINES','GL_LINEAR_MIPMAP_NEAREST','GL_LINEAR_MIPMAP_LINEAR','GL_LINEAR_ATTENUATION','GL_LINEAR',
+            'GL_LINE','GL_LIGHT_MODEL_TWO_SIDE','GL_LIGHT_MODEL_LOCAL_VIEWER','GL_LIGHT_MODEL_AMBIENT','GL_LIGHTING_BIT',
+            'GL_LIGHTING','GL_LIGHT7','GL_LIGHT6','GL_LIGHT5','GL_LIGHT4','GL_LIGHT3','GL_LIGHT2','GL_LIGHT1','GL_LIGHT0',
+            'GL_LESS','GL_LEQUAL','GL_LEFT','GL_KEEP','GL_INVERT','GL_INVALID_VALUE','GL_INVALID_OPERATION','GL_INVALID_ENUM','GL_INTERPOLATE_EXT',
+            'GL_INTERPOLATE','GL_INTENSITY8','GL_INTENSITY4','GL_INTENSITY16','GL_INTENSITY12','GL_INTENSITY','GL_INT',
+            'GL_INDEX_WRITEMASK','GL_INDEX_SHIFT','GL_INDEX_OFFSET','GL_INDEX_MODE','GL_INDEX_LOGIC_OP','GL_INDEX_CLEAR_VALUE','GL_INDEX_BITS',
+            'GL_INDEX_ARRAY_TYPE_EXT','GL_INDEX_ARRAY_TYPE','GL_INDEX_ARRAY_STRIDE_EXT','GL_INDEX_ARRAY_STRIDE','GL_INDEX_ARRAY_POINTER_EXT',
+            'GL_INDEX_ARRAY_POINTER','GL_INDEX_ARRAY_EXT','GL_INDEX_ARRAY_COUNT_EXT','GL_INDEX_ARRAY','GL_INCR','GL_HINT_BIT',
+            'GL_GREEN_SCALE','GL_GREEN_BITS','GL_GREEN_BIAS','GL_GREEN','GL_GREATER','GL_GEQUAL','GL_FRONT_RIGHT','GL_FRONT_LEFT',
+            'GL_FRONT_FACE','GL_FRONT_AND_BACK','GL_FRONT','GL_FOG_START','GL_FOG_SPECULAR_TEXTURE_WIN','GL_FOG_MODE','GL_FOG_INDEX',
+            'GL_FOG_HINT','GL_FOG_END','GL_FOG_DENSITY','GL_FOG_COLOR','GL_FOG_BIT','GL_FOG','GL_FLOAT','GL_FLAT','GL_FILL',
+            'GL_FEEDBACK_BUFFER_TYPE','GL_FEEDBACK_BUFFER_SIZE','GL_FEEDBACK_BUFFER_POINTER','GL_FEEDBACK','GL_FASTEST','GL_FALSE',
+            'GL_EYE_PLANE','GL_EYE_LINEAR','GL_EXT_vertex_array','GL_EXT_paletted_texture','GL_EXT_bgra','GL_EXTENSIONS','GL_EXP2',
+            'GL_EXP','GL_EVAL_BIT','GL_EQUIV','GL_EQUAL','GL_ENABLE_BIT','GL_EMISSION','GL_EDGE_FLAG_ARRAY_STRIDE_EXT','GL_EDGE_FLAG_ARRAY_STRIDE',
+            'GL_EDGE_FLAG_ARRAY_POINTER_EXT','GL_EDGE_FLAG_ARRAY_POINTER','GL_EDGE_FLAG_ARRAY_EXT','GL_EDGE_FLAG_ARRAY_COUNT_EXT','GL_EDGE_FLAG_ARRAY',
+            'GL_EDGE_FLAG','GL_DST_COLOR','GL_DST_ALPHA','GL_DRAW_PIXEL_TOKEN','GL_DRAW_BUFFER','GL_DOUBLE_EXT','GL_DOUBLEBUFFER',
+            'GL_DOUBLE','GL_DONT_CARE','GL_DOMAIN','GL_DITHER','GL_DIFFUSE','GL_DEPTH_WRITEMASK','GL_DEPTH_TEST','GL_DEPTH_SCALE',
+            'GL_DEPTH_RANGE','GL_DEPTH_FUNC','GL_DEPTH_COMPONENT','GL_DEPTH_CLEAR_VALUE','GL_DEPTH_BUFFER_BIT','GL_DEPTH_BITS',
+            'GL_DEPTH_BIAS','GL_DEPTH','GL_DECR','GL_DECAL','GL_CW','GL_CURRENT_TEXTURE_COORDS','GL_CURRENT_RASTER_TEXTURE_COORDS','GL_CURRENT_RASTER_POSITION_VALID',
+            'GL_CURRENT_RASTER_POSITION','GL_CURRENT_RASTER_INDEX','GL_CURRENT_RASTER_DISTANCE','GL_CURRENT_RASTER_COLOR','GL_CURRENT_NORMAL',
+            'GL_CURRENT_INDEX','GL_CURRENT_COLOR','GL_CURRENT_BIT','GL_CULL_FACE_MODE','GL_CULL_FACE','GL_COPY_PIXEL_TOKEN',
+            'GL_COPY_INVERTED','GL_COPY','GL_CONSTANT_EXT','GL_CONSTANT_ATTENUATION','GL_CONSTANT','GL_COMPILE_AND_EXECUTE','GL_COMPILE','GL_COMBINE_RGB_EXT',
+            'GL_COMBINE_RGB','GL_COMBINE_EXT','GL_COMBINE_ALPHA_EXT','GL_COMBINE_ALPHA','GL_COMBINE','GL_COLOR_WRITEMASK',
+            'GL_COLOR_TABLE_WIDTH_EXT','GL_COLOR_TABLE_RED_SIZE_EXT','GL_COLOR_TABLE_LUMINANCE_SIZE_EXT','GL_COLOR_TABLE_INTENSITY_SIZE_EXT',
+            'GL_COLOR_TABLE_GREEN_SIZE_EXT','GL_COLOR_TABLE_FORMAT_EXT','GL_COLOR_TABLE_BLUE_SIZE_EXT','GL_COLOR_TABLE_ALPHA_SIZE_EXT',
+            'GL_COLOR_MATERIAL_PARAMETER','GL_COLOR_MATERIAL_FACE','GL_COLOR_MATERIAL','GL_COLOR_LOGIC_OP','GL_COLOR_INDEXES',
+            'GL_COLOR_INDEX8_EXT','GL_COLOR_INDEX4_EXT','GL_COLOR_INDEX2_EXT','GL_COLOR_INDEX1_EXT','GL_COLOR_INDEX16_EXT',
+            'GL_COLOR_INDEX12_EXT','GL_COLOR_INDEX','GL_COLOR_CLEAR_VALUE','GL_COLOR_BUFFER_BIT','GL_COLOR_ARRAY_TYPE_EXT',
+            'GL_COLOR_ARRAY_TYPE','GL_COLOR_ARRAY_STRIDE_EXT','GL_COLOR_ARRAY_STRIDE','GL_COLOR_ARRAY_SIZE_EXT','GL_COLOR_ARRAY_SIZE',
+            'GL_COLOR_ARRAY_POINTER_EXT','GL_COLOR_ARRAY_POINTER','GL_COLOR_ARRAY_EXT','GL_COLOR_ARRAY_COUNT_EXT','GL_COLOR_ARRAY',
+            'GL_COLOR','GL_COEFF','GL_CLIP_PLANE5','GL_CLIP_PLANE4','GL_CLIP_PLANE3','GL_CLIP_PLANE2','GL_CLIP_PLANE1','GL_CLIP_PLANE0',
+            'GL_CLIENT_VERTEX_ARRAY_BIT','GL_CLIENT_PIXEL_STORE_BIT','GL_CLIENT_ATTRIB_STACK_DEPTH','GL_CLIENT_ALL_ATTRIB_BITS',
+            'GL_CLIENT_ACTIVE_TEXTURE_ARB','GL_CLIENT_ACTIVE_TEXTURE','GL_CLEAR','GL_CLAMP','GL_CCW','GL_C4UB_V3F','GL_C4UB_V2F',
+            'GL_C4F_N3F_V3F','GL_C3F_V3F','GL_BYTE','GL_BLUE_SCALE','GL_BLUE_BITS','GL_BLUE_BIAS','GL_BLUE','GL_BLEND_SRC','GL_BLEND_DST',
+            'GL_BLEND','GL_BITMAP_TOKEN','GL_BITMAP','GL_BGR_EXT','GL_BGRA_EXT','GL_BACK_RIGHT','GL_BACK_LEFT','GL_BACK',
+            'GL_AUX_BUFFERS','GL_AUX3','GL_AUX2','GL_AUX1','GL_AUX0','GL_AUTO_NORMAL','GL_ATTRIB_STACK_DEPTH','GL_AND_REVERSE',
+            'GL_AND_INVERTED','GL_AND','GL_AMBIENT_AND_DIFFUSE','GL_AMBIENT','GL_ALWAYS','GL_ALPHA_TEST_REF','GL_ALPHA_TEST_FUNC',
+            'GL_ALPHA_TEST','GL_ALPHA_SCALE','GL_ALPHA_BITS','GL_ALPHA_BIAS','GL_ALPHA8','GL_ALPHA4','GL_ALPHA16','GL_ALPHA12',
+            'GL_ALPHA','GL_ALL_ATTRIB_BITS','GL_ADD_SIGNED_EXT','GL_ADD_SIGNED','GL_ADD','GL_ACTIVE_TEXTURE_ARB','GL_ACTIVE_TEXTURE',
+            'GL_ACCUM_RED_BITS','GL_ACCUM_GREEN_BITS','GL_ACCUM_CLEAR_VALUE','GL_ACCUM_BUFFER_BIT','GL_ACCUM_BLUE_BITS','GL_ACCUM_ALPHA_BITS',
+            'GL_ACCUM','GL_4_BYTES','GL_4D_COLOR_TEXTURE','GL_3_BYTES','GL_3D_COLOR_TEXTURE','GL_3D_COLOR','GL_3D','GL_2_BYTES',
+            'GL_2D','GLU_V_STEP','GLU_VERTEX','GLU_VERSION_1_2','GLU_VERSION_1_1','GLU_VERSION','GLU_U_STEP','GLU_UNKNOWN','GLU_TRUE',
+            'GLU_TESS_WINDING_RULE','GLU_TESS_WINDING_POSITIVE','GLU_TESS_WINDING_ODD','GLU_TESS_WINDING_NONZERO','GLU_TESS_WINDING_NEGATIVE',
+            'GLU_TESS_WINDING_ABS_GEQ_TWO','GLU_TESS_VERTEX_DATA','GLU_TESS_VERTEX','GLU_TESS_TOLERANCE','GLU_TESS_NEED_COMBINE_CALLBACK','GLU_TESS_MISSING_END_POLYGON',
+            'GLU_TESS_MISSING_END_CONTOUR','GLU_TESS_MISSING_BEGIN_POLYGON','GLU_TESS_MISSING_BEGIN_CONTOUR','GLU_TESS_ERROR_DATA',
+            'GLU_TESS_ERROR8','GLU_TESS_ERROR7','GLU_TESS_ERROR6','GLU_TESS_ERROR5','GLU_TESS_ERROR4','GLU_TESS_ERROR3','GLU_TESS_ERROR2',
+            'GLU_TESS_ERROR1','GLU_TESS_ERROR','GLU_TESS_END_DATA','GLU_TESS_END','GLU_TESS_EDGE_FLAG_DATA','GLU_TESS_EDGE_FLAG',
+            'GLU_TESS_COORD_TOO_LARGE','GLU_TESS_COMBINE_DATA','GLU_TESS_COMBINE','GLU_TESS_BOUNDARY_ONLY','GLU_TESS_BEGIN_DATA',
+            'GLU_TESS_BEGIN','GLU_SMOOTH','GLU_SILHOUETTE','GLU_SAMPLING_TOLERANCE','GLU_SAMPLING_METHOD','GLU_POINT','GLU_PATH_LENGTH',
+            'GLU_PARAMETRIC_TOLERANCE','GLU_PARAMETRIC_ERROR','GLU_OUT_OF_MEMORY','GLU_OUTSIDE','GLU_OUTLINE_POLYGON','GLU_OUTLINE_PATCH',
+            'GLU_NURBS_ERROR9','GLU_NURBS_ERROR8','GLU_NURBS_ERROR7','GLU_NURBS_ERROR6','GLU_NURBS_ERROR5','GLU_NURBS_ERROR4',
+            'GLU_NURBS_ERROR37','GLU_NURBS_ERROR36','GLU_NURBS_ERROR35','GLU_NURBS_ERROR34','GLU_NURBS_ERROR33','GLU_NURBS_ERROR32',
+            'GLU_NURBS_ERROR31','GLU_NURBS_ERROR30','GLU_NURBS_ERROR3','GLU_NURBS_ERROR29','GLU_NURBS_ERROR28','GLU_NURBS_ERROR27','GLU_NURBS_ERROR26',
+            'GLU_NURBS_ERROR25','GLU_NURBS_ERROR24','GLU_NURBS_ERROR23','GLU_NURBS_ERROR22','GLU_NURBS_ERROR21','GLU_NURBS_ERROR20',
+            'GLU_NURBS_ERROR2','GLU_NURBS_ERROR19','GLU_NURBS_ERROR18','GLU_NURBS_ERROR17','GLU_NURBS_ERROR16','GLU_NURBS_ERROR15','GLU_NURBS_ERROR14',
+            'GLU_NURBS_ERROR13','GLU_NURBS_ERROR12','GLU_NURBS_ERROR11','GLU_NURBS_ERROR10','GLU_NURBS_ERROR1','GLU_NONE',
+            'GLU_MAP1_TRIM_3','GLU_MAP1_TRIM_2','GLU_LINE','GLU_INVALID_VALUE','GLU_INVALID_ENUM','GLU_INTERIOR','GLU_INSIDE','GLU_INCOMPATIBLE_GL_VERSION',
+            'GLU_FLAT','GLU_FILL','GLU_FALSE','GLU_EXTERIOR','GLU_EXTENSIONS','GLU_ERROR','GLU_END','GLU_EDGE_FLAG','GLU_DOMAIN_DISTANCE',
+            'GLU_DISPLAY_MODE','GLU_CW','GLU_CULLING','GLU_CCW','GLU_BEGIN','GLU_AUTO_LOAD_MATRIX','CHANNEL_UNORDERED','CHANNEL_ORDERED',
+            'CHANNEL_MAX'
+            ),
+        2 => array(
+
+            // Red Lowercase Keywords
+
+            'WriteWord','WriteString','WriteReal','WriteLine','WriteInt','WriteFloat','WriteDouble','WriteChar','WriteByte',
+            'windowwidth','windowheight','waittimer','Vec4','Vec3','Vec2','val','UpdateJoystick','ucase$','Transpose','tickcount',
+            'textscroll','textrows','textmode','textcols','tanh','tand','tan','synctimercatchup','synctimer','swapbuffers',
+            'str$','stopsoundvoice','stopsounds','stopmusic','sqrt','sqr','sprzorder','spryvel','sprytiles','sprysize','spryrepeat',
+            'spryflip','sprycentre','spry','sprxvel','sprxtiles','sprxsize','sprxrepeat','sprxflip','sprxcentre','sprx',
+            'sprvisible','sprvel','sprtype','sprtop','sprspin','sprsolid','sprsetzorder','sprsetyvel','sprsetysize','sprsetyrepeat',
+            'sprsetyflip','sprsetycentre','sprsety','sprsetxvel','sprsetxsize','sprsetxrepeat','sprsetxflip','sprsetxcentre',
+            'sprsetx','sprsetvisible','sprsetvel','sprsettiles','sprsettextures','sprsettexture','sprsetspin','sprsetsolid',
+            'sprsetsize','sprsetscale','sprsetpos','sprsetparallax','sprsetframe','sprsetcolor','sprsetanimspeed','sprsetanimloop',
+            'sprsetangle','sprsetalpha','sprscale','sprright','sprpos','sprparallax','sprleft','spriteareawidth','spriteareaheight',
+            'sprframe','sprcolor','sprcameraz','sprcameray','sprcamerax','sprcamerasetz','sprcamerasety','sprcamerasetx',
+            'sprcamerasetpos','sprcamerasetfov','sprcamerasetangle','sprcamerapos','sprcamerafov','sprcameraangle',
+            'sprbottom','spranimspeed','spranimloop','spranimdone','sprangle','spralpha','spraddtextures','spraddtexture',
+            'sounderror','sleep','sind','sin','showcursor','sgn','settextscroll','setmusicvolume','SendMessage','Seek',
+            'scankeydown','RTInvert','rnd','right$','resizetext','resizespritearea','RejectConnection','ReceiveMessage','ReadWord',
+            'ReadText','ReadReal','ReadLine','ReadInt','ReadFloat','ReadDouble','ReadChar','ReadByte','randomize','printr',
+            'print','pow','playsound','playmusic','performancecounter','Orthonormalize','OpenFileWrite','OpenFileRead','Normalize',
+            'newtilemap','newsprite','NewServer','NewConnection','musicplaying','mouse_yd','mouse_y','mouse_xd','mouse_x',
+            'mouse_wheel','mouse_button','mid$','MessageSmoothed','MessageReliable','MessagePending','MessageChannel','maxtextureunits',
+            'MatrixZero','MatrixTranslate','MatrixScale','MatrixRotateZ','MatrixRotateY','MatrixRotateX','MatrixRotate','MatrixIdentity',
+            'MatrixCrossProduct','MatrixBasis','log','locate','loadtexture','loadsound','loadmipmaptexture','loadmipmapimagestrip',
+            'loadimagestrip','loadimage','Length','len','left$','lcase$','keydown','Joy_Y','Joy_X','Joy_Up','Joy_Right','Joy_Left',
+            'Joy_Keys','Joy_Down','Joy_Button','Joy_3','Joy_2','Joy_1','Joy_0','int','inscankey','input$','inkey$','inittimer',
+            'imagewidth','imagestripframes','imageheight','imageformat','imagedatatype','hidecursor','glViewport','glVertex4sv',
+            'glVertex4s','glVertex4iv','glVertex4i','glVertex4fv','glVertex4f','glVertex4dv','glVertex4d','glVertex3sv','glVertex3s',
+            'glVertex3iv','glVertex3i','glVertex3fv','glVertex3f','glVertex3dv','glVertex3d','glVertex2sv','glVertex2s','glVertex2iv',
+            'glVertex2i','glVertex2fv','glVertex2f','glVertex2dv','glVertex2d','gluPerspective','gluOrtho2D','gluLookAt',
+            'glubuild2dmipmaps','glTranslatef','glTranslated','gltexsubimage2d','glTexParameteriv','glTexParameteri',
+            'glTexParameterfv','glTexParameterf','glteximage2d','glTexGeniv','glTexGeni','glTexGenfv','glTexGenf','glTexGendv',
+            'glTexGend','glTexEnviv','glTexEnvi','glTexEnvfv','glTexEnvf','glTexCoord4sv','glTexCoord4s','glTexCoord4iv','glTexCoord4i',
+            'glTexCoord4fv','glTexCoord4f','glTexCoord4dv','glTexCoord4d','glTexCoord3sv','glTexCoord3s','glTexCoord3iv','glTexCoord3i',
+            'glTexCoord3fv','glTexCoord3f','glTexCoord3dv','glTexCoord3d','glTexCoord2sv','glTexCoord2s','glTexCoord2iv','glTexCoord2i',
+            'glTexCoord2fv','glTexCoord2f','glTexCoord2dv','glTexCoord2d','glTexCoord1sv','glTexCoord1s','glTexCoord1iv','glTexCoord1i','glTexCoord1fv',
+            'glTexCoord1f','glTexCoord1dv','glTexCoord1d','glStencilOp','glStencilMask','glStencilFunc','glShadeModel','glSelectBuffer',
+            'glScissor','glScalef','glScaled','glRotatef','glRotated','glRenderMode','glRectsv','glRects','glRectiv','glRecti',
+            'glRectfv','glRectf','glRectdv','glRectd','glReadBuffer','glRasterPos4sv','glRasterPos4s','glRasterPos4iv',
+            'glRasterPos4i','glRasterPos4fv','glRasterPos4f','glRasterPos4dv','glRasterPos4d','glRasterPos3sv','glRasterPos3s',
+            'glRasterPos3iv','glRasterPos3i','glRasterPos3fv','glRasterPos3f','glRasterPos3dv','glRasterPos3d','glRasterPos2sv',
+            'glRasterPos2s','glRasterPos2iv','glRasterPos2i','glRasterPos2fv','glRasterPos2f','glRasterPos2dv','glRasterPos2d',
+            'glPushName','glPushMatrix','glPushClientAttrib','glPushAttrib','glPrioritizeTextures','glPopName','glPopMatrix',
+            'glPopClientAttrib','glPopAttrib','glpolygonstipple','glPolygonOffset','glPolygonMode','glPointSize','glPixelZoom',
+            'glPixelTransferi','glPixelTransferf','glPixelStorei','glPixelStoref','glPassThrough','glOrtho','glNormal3sv','glNormal3s',
+            'glNormal3iv','glNormal3i','glNormal3fv','glNormal3f','glNormal3dv','glNormal3d','glNormal3bv','glNormal3b','glNewList',
+            'glMultMatrixf','glMultMatrixd','glmultitexcoord2f','glmultitexcoord2d','glMatrixMode','glMaterialiv','glMateriali',
+            'glMaterialfv','glMaterialf','glMapGrid2f','glMapGrid2d','glMapGrid1f','glMapGrid1d','glLogicOp','glLoadName','glLoadMatrixf',
+            'glLoadMatrixd','glLoadIdentity','glListBase','glLineWidth','glLineStipple','glLightModeliv','glLightModeli','glLightModelfv',
+            'glLightModelf','glLightiv','glLighti','glLightfv','glLightf','glIsTexture','glIsList','glIsEnabled','glInitNames',
+            'glIndexubv','glIndexub','glIndexsv','glIndexs','glIndexMask','glIndexiv','glIndexi','glIndexfv','glIndexf','glIndexdv',
+            'glIndexd','glHint','glGetTexParameteriv','glGetTexParameterfv','glGetTexLevelParameteriv','glGetTexLevelParameterfv',
+            'glGetTexGeniv','glGetTexGenfv','glGetTexGendv','glGetTexEnviv','glGetTexEnvfv','glgetstring','glgetpolygonstipple','glGetPixelMapuiv',
+            'glGetMaterialiv','glGetMaterialfv','glGetLightiv','glGetLightfv','glGetIntegerv','glGetFloatv',
+            'glGetError','glGetDoublev','glGetClipPlane','glGetBooleanv','glgentextures','glgentexture',
+            'glgenlists','glFrustum','glFrontFace','glFogiv','glFogi','glFogfv','glFogf','glFlush','glFinish','glFeedbackBuffer',
+            'glEvalPoint2','glEvalPoint1','glEvalMesh2','glEvalMesh1','glEvalCoord2fv','glEvalCoord2f','glEvalCoord2dv','glEvalCoord2d',
+            'glEvalCoord1fv','glEvalCoord1f','glEvalCoord1dv','glEvalCoord1d','glEndList','glEnd','glEnableClientState','glEnable',
+            'glEdgeFlagv','glEdgeFlag','glDrawBuffer','glDrawArrays','glDisableClientState','glDisable','glDepthRange','glDepthMask',
+            'glDepthFunc','gldeletetextures','gldeletetexture','gldeletelists','glCullFace','glCopyTexSubImage2D','glCopyTexSubImage1D',
+            'glCopyTexImage2D','glCopyTexImage1D','glColorMaterial','glColorMask','glColor4usv','glColor4us','glColor4uiv','glColor4ui',
+            'glColor4ubv','glColor4ub','glColor4sv','glColor4s','glColor4iv','glColor4i','glColor4fv','glColor4f','glColor4dv',
+            'glColor4d','glColor4bv','glColor4b','glColor3usv','glColor3us','glColor3uiv','glColor3ui','glColor3ubv','glColor3ub',
+            'glColor3sv','glColor3s','glColor3iv','glColor3i','glColor3fv','glColor3f','glColor3dv','glColor3d','glColor3bv',
+            'glColor3b','glClipPlane','glClearStencil','glClearIndex','glClearDepth','glClearColor','glClearAccum','glClear',
+            'glcalllists','glCallList','glBlendFunc','glBindTexture','glBegin','glArrayElement','glAreTexturesResident',
+            'glAlphaFunc','glactivetexture','glAccum','font','FindNextFile','FindFirstFile','FindClose','FileError',
+            'extensionsupported','exp','execute','EndOfFile','drawtext','divbyzero','Determinant','deletesprite','deletesound',
+            'DeleteServer','deleteimage','DeleteConnection','defaultfont','CrossProduct','cosd','cos','copysprite','ConnectionPending',
+            'ConnectionHandShaking','ConnectionConnected','ConnectionAddress','compilererrorline','compilererrorcol','compilererror',
+            'compilefile','compile','color','cls','CloseFile','clearregion','clearline','clearkeys','chr$','charat$','bindsprite',
+            'beep','atnd','atn2d','atn2','atn','atand','asc','argcount','arg','animatesprites','AcceptConnection','abs'
+            ),
+        3 => array(
+
+            // Blue Lowercase Keywords
+
+            'xor','while','wend','until','type','traditional_print','traditional','to','then','struc','string','step','single',
+            'run','return','reset','read','or','null','not','next','lor','loop','language','land','integer','input','if',
+            'goto','gosub','for','endstruc','endif','end','elseif','else','double','do','dim','data','const','basic4gl','as',
+            'and','alloc'
+            )
+
+        ),
+    'SYMBOLS' => array(
+        '=', '<', '>', '>=', '<=', '+', '-', '*', '/', '%', '(', ')', '{', '}', '[', ']', '&', ';', ':', '$'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000080; font-weight: bold;',
+            2 => 'color: #FF0000;',
+            3 => 'color: #0000FF;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #657CC4; font-style: italic;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000080;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #008000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000080; font-weight: bold;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #0000FF;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/bf.php b/examples/includes/geshi/geshi/bf.php
new file mode 100644 (file)
index 0000000..e5dcc42
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/*************************************************************************************
+ * bf.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/10/31
+ *
+ * Brainfuck language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'Brainfuck',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(1 => '/[^\n+\-<>\[\]\.\,Y]+/s'),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        ),
+    'SYMBOLS' => array(
+        0 => array('+', '-'),
+        1 => array('[', ']'),
+        2 => array('<', '>'),
+        3 => array('.', ','),
+        4 => array('Y') //Brainfork Extension ;-)
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #006600;',
+            1 => 'color: #660000;',
+            2 => 'color: #000066;',
+            3 => 'color: #660066;',
+            4 => 'color: #666600;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'STRINGS' => GESHI_NEVER,
+            'NUMBERS' => GESHI_NEVER
+            ),
+        'KEYWORDS' => array(
+            'DISALLOW_BEFORE' => '',
+            'DISALLOW_AFTER' => ''
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/blitzbasic.php b/examples/includes/geshi/geshi/blitzbasic.php
new file mode 100644 (file)
index 0000000..a8c3259
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+/*************************************************************************************
+ * blitzbasic.php
+ * --------------
+ * Author: P�draig O`Connel (info@moonsword.info)
+ * Copyright: (c) 2005 P�draig O`Connel (http://moonsword.info)
+ * Release Version: 1.0.8.3
+ * Date Started: 16.10.2005
+ *
+ * BlitzBasic language file for GeSHi.
+ *
+ * It is a simple Basic dialect. Released for Games and Network Connections.
+ * In this Language File are all functions included (2D BB and 3D BB)
+ *
+ *
+ * CHANGES
+ * -------
+ * 2005/12/28 (1.0.1)
+ *   -  Remove unnecessary style index for regexps
+ * 2005/10/22 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2005/10/22)
+ * -------------------------
+ * * Sort out the Basic commands for splitting up.
+ * * To set up the right colors.
+ *      (the colors are ok, but not the correct ones)
+ * * Split to BlitzBasic 2D and BlitzBasic 3D.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'BlitzBasic',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'If','EndIf','ElseIf','Else If','Else','While','Wend','Return','Next','Include','End Type','End Select','End If','End Function','End','Select',
+            'Type','Forever','For','Or','And','AppTitle','Case','Goto','Gosub','Step','Stop','Int','Last','False','Then','To','True','Until','Float',
+            'String','Before','Not'
+            ),
+        2 => array(
+            // All Functions - 2D BB and 3D BB
+            'Xor','WriteString','WriteShort','WritePixelFast','WritePixel','WriteLine','WriteInt','WriteFloat','WriteFile','WriteBytes',
+            'WriteByte','Write','WaitTimer','WaitMouse','WaitKey','WaitJoy','VWait','Viewport',
+            'Upper','UpdateGamma','UnlockBuffer','UDPTimeouts','UDPStreamPort','UDPStreamIP','UDPMsgPort','UDPMsgIP',
+            'Trim','TotalVidMem','TileImage','TileBlock','TFormImage','TFormFilter','Text',
+            'TCPTimeouts','TCPStreamPort','TCPStreamIP','Tan','SystemProperty','StringWidth','StringHeight','Str','StopNetGame',
+            'StopChannel','StartNetGame','Sqr','SoundVolume','SoundPitch','SoundPan','Sin','Shr',
+            'ShowPointer','Shl','Sgn','SetGfxDriver','SetGamma','SetFont','SetEnv','SetBuffer','SendUDPMsg','SendNetMsg',
+            'SeekFile','SeedRnd','ScanLine','ScaleImage','SaveImage','SaveBuffer','Sar','RuntimeError','RSet',
+            'RotateImage','RndSeed','Rnd','Right','ResumeChannel','Restore','ResizeImage','ResizeBank','Replace',
+            'Repeat','RecvUDPMsg','RecvNetMsg','RectsOverlap','Rect','ReadString','ReadShort','ReadPixelFast','ReadPixel','ReadLine',
+            'ReadInt','ReadFloat','ReadFile','ReadDir','ReadBytes','ReadByte','ReadAvail','Read','Rand','Print',
+            'PokeShort','PokeInt','PokeFloat','PokeByte','Plot','PlaySound','PlayMusic','PlayCDTrack','Pi','PeekShort',
+            'PeekInt','PeekFloat','PeekByte','PauseChannel','Oval','Origin','OpenTCPStream','OpenMovie','OpenFile',
+            'Null','NextFile','New','NetPlayerName','NetPlayerLocal','NetMsgType','NetMsgTo','NetMsgFrom',
+            'NetMsgData','MovieWidth','MoviePlaying','MovieHeight','MoveMouse','MouseZSpeed','MouseZ','MouseYSpeed','MouseY','MouseXSpeed',
+            'MouseX','MouseHit','MouseDown','Mod','Millisecs','MidHandle','Mid','MaskImage','LSet','Lower',
+            'LoopSound','Log10','Log','LockBuffer','Locate','Local','LoadSound','LoadImage','LoadFont','LoadBuffer',
+            'LoadAnimImage','Line','Len','Left','KeyHit','KeyDown','JoyZDir','JoyZ','JoyYDir',
+            'JoyYaw','JoyY','JoyXDir','JoyX','JoyVDir','JoyV','JoyUDir','JoyU','JoyType','JoyRoll',
+            'JoyPitch','JoyHit','JoyHat','JoyDown','JoinNetGame','Instr','Insert','Input',
+            'ImageYHandle','ImageXHandle','ImageWidth','ImagesOverlap','ImagesCollide','ImageRectOverlap','ImageRectCollide','ImageHeight','ImageBuffer',
+            'HostNetGame','HostIP','HidePointer','Hex','HandleImage','GraphicsWidth','GraphicsHeight','GraphicsDepth','GraphicsBuffer','Graphics',
+            'GrabImage','Global','GFXModeWidth','GFXModeHeight','GfxModeExists','GFXModeDepth','GfxDriverName','GetMouse',
+            'GetKey','GetJoy','GetEnv','GetColor','GammaRed','GammaGreen','GammaBlue','Function','FrontBuffer','FreeTimer',
+            'FreeSound','FreeImage','FreeFont','FreeBank','FontWidth','FontHeight','FlushMouse','FlushKeys',
+            'FlushJoy','Floor','Flip','First','FileType','FileSize','FilePos','Field',
+            'Exp','Exit','ExecFile','Eof','EndGraphics','Each','DrawMovie','DrawImageRect','DrawImage','DrawBlockRect','DrawBlock',
+            'DottedIP','Dim','DeleteNetPlayer','DeleteFile','DeleteDir','Delete','Delay','Default','DebugLog','Data',
+            'CurrentTime','CurrentDir','CurrentDate','CreateUDPStream','CreateTimer','CreateTCPServer','CreateNetPlayer','CreateImage','CreateDir','CreateBank',
+            'CountHostIPs','CountGFXModes','CountGfxDrivers','Cos','CopyStream','CopyRect','CopyPixelFast','CopyPixel','CopyImage','CopyFile',
+            'CopyBank','Const','CommandLine','ColorRed','ColorGreen','ColorBlue','Color','ClsColor','Cls','CloseUDPStream',
+            'CloseTCPStream','CloseTCPServer','CloseMovie','CloseFile','CloseDir','Chr','ChannelVolume','ChannelPlaying','ChannelPitch','ChannelPan',
+            'ChangeDir','Ceil','CallDLL','Bin','BankSize','BackBuffer','AvailVidMem','AutoMidHandle',
+            'ATan2','ATan','ASin','Asc','After','ACos','AcceptTCPStream','Abs',
+            // 3D Commands
+            'Wireframe','Windowed3D','WBuffer','VertexZ','VertexY',
+            'VertexX','VertexW','VertexV','VertexU','VertexTexCoords','VertexRed','VertexNZ','VertexNY','VertexNX','VertexNormal',
+            'VertexGreen','VertexCoords','VertexColor','VertexBlue','VertexAlpha','VectorYaw','VectorPitch','UpdateWorld','UpdateNormals','TurnEntity',
+            'TrisRendered','TriangleVertex','TranslateEntity','TFormVector','TFormPoint','TFormNormal','TFormedZ','TFormedY','TFormedX','TextureWidth',
+            'TextureName','TextureHeight','TextureFilter','TextureCoords','TextureBuffer','TextureBlend','TerrainZ','TerrainY','TerrainX','TerrainSize',
+            'TerrainShading','TerrainHeight','TerrainDetail','SpriteViewMode','ShowEntity','SetCubeFace','SetAnimTime','SetAnimKey','ScaleTexture','ScaleSprite',
+            'ScaleMesh','ScaleEntity','RotateTexture','RotateSprite','RotateMesh','RotateEntity','ResetEntity','RenderWorld','ProjectedZ','ProjectedY',
+            'ProjectedX','PositionTexture','PositionMesh','PositionEntity','PointEntity','PickedZ','PickedY','PickedX','PickedTriangle','PickedTime',
+            'PickedSurface','PickedNZ','PickedNY','PickedNX','PickedEntity','PaintSurface','PaintMesh','PaintEntity','NameEntity','MoveEntity',
+            'ModifyTerrain','MeshWidth','MeshHeight','MeshesIntersect','MeshDepth','MD2AnimTime','MD2AnimLength','MD2Animating','LoadTexture','LoadTerrain',
+            'LoadSprite','LoadMesh','LoadMD2','LoaderMatrix','LoadBSP','LoadBrush','LoadAnimTexture','LoadAnimSeq','LoadAnimMesh','Load3DSound',
+            'LinePick','LightRange','LightMesh','LightConeAngles','LightColor','HWMultiTex','HideEntity','HandleSprite','Graphics3D','GfxMode3DExists',
+            'GfxMode3D','GfxDriverCaps3D','GfxDriver3D','GetSurfaceBrush','GetSurface','GetParent','GetMatElement','GetEntityType','GetEntityBrush','GetChild',
+            'GetBrushTexture','FreeTexture','FreeEntity','FreeBrush','FlipMesh','FitMesh','FindSurface','FindChild','ExtractAnimSeq','EntityZ',
+            'EntityYaw','EntityY','EntityX','EntityVisible','EntityType','EntityTexture','EntityShininess','EntityRoll','EntityRadius','EntityPitch',
+            'EntityPickMode','EntityPick','EntityParent','EntityOrder','EntityName','EntityInView','EntityFX','EntityDistance','EntityColor','EntityCollided',
+            'EntityBox','EntityBlend','EntityAutoFade','EntityAlpha','EmitSound','Dither','DeltaYaw','DeltaPitch','CreateTexture','CreateTerrain',
+            'CreateSurface','CreateSprite','CreateSphere','CreatePlane','CreatePivot','CreateMirror','CreateMesh','CreateListener','CreateLight','CreateCylinder',
+            'CreateCube','CreateCone','CreateCamera','CreateBrush','CountVertices','CountTriangles','CountSurfaces','CountGfxModes3D','CountCollisions','CountChildren',
+            'CopyMesh','CopyEntity','CollisionZ','CollisionY','CollisionX','CollisionTriangle','CollisionTime','CollisionSurface','Collisions','CollisionNZ',
+            'CollisionNY','CollisionNX','CollisionEntity','ClearWorld','ClearTextureFilters','ClearSurface','ClearCollisions','CaptureWorld','CameraZoom','CameraViewport',
+            'CameraRange','CameraProjMode','CameraProject','CameraPick','CameraFogRange','CameraFogMode','CameraFogColor','CameraClsMode','CameraClsColor','BSPLighting',
+            'BSPAmbientLight','BrushTexture','BrushShininess','BrushFX','BrushColor','BrushBlend','BrushAlpha','AntiAlias','AnimTime','AnimSeq',
+            'AnimLength','Animating','AnimateMD2','Animate','AmbientLight','AlignToVector','AddVertex','AddTriangle','AddMesh','AddAnimSeq',
+            )
+        ),
+    'SYMBOLS' => array(
+        '(',')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000066; font-weight: bold;',
+            2 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #D9D100; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000066;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #009900;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #CC0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        1 => '\\'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => false,
+        1 => false
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/bnf.php b/examples/includes/geshi/geshi/bnf.php
new file mode 100644 (file)
index 0000000..c9b3aae
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+/*************************************************************************************
+ * bnf.php
+ * --------
+ * Author: Rowan Rodrik van der Molen (rowan@bigsmoke.us)
+ * Copyright: (c) 2006 Rowan Rodrik van der Molen (http://www.bigsmoke.us/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/09/28
+ *
+ * BNF (Backus-Naur form) language file for GeSHi.
+ *
+ * See http://en.wikipedia.org/wiki/Backus-Naur_form for more info on BNF.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ *  -  Removed superflicious regexps
+ * 2006/09/18 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2006/09/18)
+ * -------------------------
+ * * Nothing I can think of
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'bnf',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', "'"),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(),
+    'SYMBOLS' => array(
+        '(', ')', '<', '>', '::=', '|'
+    ),
+    'CASE_SENSITIVE' => array(
+        //GESHI_COMMENTS => false
+    ),
+    'STYLES' => array(
+        'KEYWORDS' => array(),
+        'COMMENTS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => ''
+            ),
+        'STRINGS' => array(
+            0 => 'color: #a00;',
+            1 => 'color: #a00;'
+            ),
+        'NUMBERS' => array(
+            0 => ''
+            ),
+        'METHODS' => array(
+            0 => ''
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066; font-weight: bold;', // Unused
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #007;',
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            )
+        ),
+    'URLS' => array(),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        //terminal symbols
+        0 => array(
+            GESHI_SEARCH => '(&lt;)([^&]+?)(&gt;)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/boo.php b/examples/includes/geshi/geshi/boo.php
new file mode 100644 (file)
index 0000000..1741d2c
--- /dev/null
@@ -0,0 +1,217 @@
+<?php
+/*************************************************************************************
+ * boo.php
+ * --------
+ * Author: Marcus Griep (neoeinstein+GeSHi@gmail.com)
+ * Copyright: (c) 2007 Marcus Griep (http://www.xpdm.us)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/09/10
+ *
+ * Boo language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/09/10 (1.0.8)
+ *  -  First Release
+ *
+ * TODO (updated 2007/09/10)
+ * -------------------------
+ * Regular Expression Literal matching
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Boo',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'''", "'", '"""', '"'),
+    'HARDQUOTE' => array('"""', '"""'),
+    'HARDESCAPE' => array('\"""'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(//Namespace
+            'namespace', 'import', 'from'
+            ),
+        2 => array(//Jump
+            'yield', 'return', 'goto', 'continue', 'break'
+            ),
+        3 => array(//Conditional
+            'while', 'unless', 'then', 'in', 'if', 'for', 'else', 'elif'
+            ),
+        4 => array(//Property
+            'set', 'get'
+            ),
+        5 => array(//Exception
+            'try', 'raise', 'failure', 'except', 'ensure'
+            ),
+        6 => array(//Visibility
+            'public', 'private', 'protected', 'internal'
+            ),
+        7 => array(//Define
+            'struct', 'ref', 'of', 'interface', 'event', 'enum', 'do', 'destructor', 'def', 'constructor', 'class'
+            ),
+        8 => array(//Cast
+            'typeof', 'cast', 'as'
+            ),
+        9 => array(//BiMacro
+            'yieldAll', 'using', 'unchecked', 'rawArayIndexing', 'print', 'normalArrayIndexing', 'lock',
+            'debug', 'checked', 'assert'
+            ),
+        10 => array(//BiAttr
+            'required', 'property', 'meta', 'getter', 'default'
+            ),
+        11 => array(//BiFunc
+            'zip', 'shellp', 'shellm', 'shell', 'reversed', 'range', 'prompt',
+            'matrix', 'map', 'len', 'join', 'iterator', 'gets', 'enumerate', 'cat', 'array'
+            ),
+        12 => array(//HiFunc
+            '__switch__', '__initobj__', '__eval__', '__addressof__', 'quack'
+            ),
+        13 => array(//Primitive
+            'void', 'ushort', 'ulong', 'uint', 'true', 'timespan', 'string', 'single',
+            'short', 'sbyte', 'regex', 'object', 'null', 'long', 'int', 'false', 'duck',
+            'double', 'decimal', 'date', 'char', 'callable', 'byte', 'bool'
+            ),
+        14 => array(//Operator
+            'not', 'or', 'and', 'is', 'isa',
+            ),
+        15 => array(//Modifier
+            'virtual', 'transient', 'static', 'partial', 'override', 'final', 'abstract'
+            ),
+        16 => array(//Access
+            'super', 'self'
+            ),
+        17 => array(//Pass
+            'pass'
+            )
+        ),
+    'SYMBOLS' => array(
+        '[|', '|]', '${', '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>', '+', '-', ';'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true,
+        9 => true,
+        10 => true,
+        11 => true,
+        12 => true,
+        13 => true,
+        14 => true,
+        15 => true,
+        16 => true,
+        17 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color:green;font-weight:bold;',
+            2 => 'color:navy;',
+            3 => 'color:blue;font-weight:bold;',
+            4 => 'color:#8B4513;',
+            5 => 'color:teal;font-weight:bold;',
+            6 => 'color:blue;font-weight:bold;',
+            7 => 'color:blue;font-weight:bold;',
+            8 => 'color:blue;font-weight:bold;',
+            9 => 'color:maroon;',
+            10 => 'color:maroon;',
+            11 => 'color:purple;',
+            12 => 'color:#4B0082;',
+            13 => 'color:purple;font-weight:bold;',
+            14 => 'color:#008B8B;font-weight:bold;',
+            15 => 'color:brown;',
+            16 => 'color:black;font-weight:bold;',
+            17 => 'color:gray;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #999999; font-style: italic;',
+            2 => 'color: #999999; font-style: italic;',
+            'MULTI' => 'color: #008000; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #0000FF; font-weight: bold;',
+            'HARD' => 'color: #0000FF; font-weight: bold;',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #006400;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #008000;',
+            'HARD' => 'color: #008000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #00008B;'
+            ),
+        'METHODS' => array(
+            0 => 'color: 000000;',
+            1 => 'color: 000000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #006400;'
+            ),
+        'REGEXPS' => array(
+            #0 => 'color: #0066ff;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => '',
+        8 => '',
+        9 => '',
+        10 => '',
+        11 => '',
+        12 => '',
+        13 => '',
+        14 => '',
+        15 => '',
+        16 => '',
+        17 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        0 => '.',
+        1 => '::'
+        ),
+    'REGEXPS' => array(
+        #0 => '%(@)?\/(?:(?(1)[^\/\\\\\r\n]+|[^\/\\\\\r\n \t]+)|\\\\[\/\\\\\w+()|.*?$^[\]{}\d])+\/%'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/c.php b/examples/includes/geshi/geshi/c.php
new file mode 100644 (file)
index 0000000..272885a
--- /dev/null
@@ -0,0 +1,188 @@
+<?php
+/*************************************************************************************
+ * c.php
+ * -----
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Contributors:
+ *  - Jack Lloyd (lloyd@randombit.net)
+ *  - Michael Mol (mikemol@gmail.com)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * C language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/01/22 (1.0.8.3)
+ *   -  Made keywords case-sensitive.
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2004/XX/XX (1.0.4)
+ *   -  Added a couple of new keywords (Jack Lloyd)
+ * 2004/11/27 (1.0.3)
+ *   -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.1)
+ *   -  Added support for symbols
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2009/02/08)
+ * -------------------------
+ *  -  Get a list of inbuilt functions to add (and explore C more
+ *     to complete this rather bare language file
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'C',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Multiline-continued single-line comments
+        1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        //Multiline-continued preprocessor define
+        2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[abfnrtv\\'\"?\n]#i",
+        //Hexadecimal Char Specs
+        2 => "#\\\\x[\da-fA-F]{2}#",
+        //Hexadecimal Char Specs
+        3 => "#\\\\u[\da-fA-F]{4}#",
+        //Hexadecimal Char Specs
+        4 => "#\\\\U[\da-fA-F]{8}#",
+        //Octal Char Specs
+        5 => "#\\\\[0-7]{1,3}#"
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+        GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'if', 'return', 'while', 'case', 'continue', 'default',
+            'do', 'else', 'for', 'switch', 'goto'
+            ),
+        2 => array(
+            'null', 'false', 'break', 'true', 'function', 'enum', 'extern', 'inline'
+            ),
+        3 => array(
+            'printf', 'cout'
+            ),
+        4 => array(
+            'auto', 'char', 'const', 'double',  'float', 'int', 'long',
+            'register', 'short', 'signed', 'sizeof', 'static', 'string', 'struct',
+            'typedef', 'union', 'unsigned', 'void', 'volatile', 'wchar_t'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']',
+        '+', '-', '*', '/', '%',
+        '=', '<', '>',
+        '!', '^', '&', '|',
+        '?', ':',
+        ';', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;',
+            4 => 'color: #993333;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #339933;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #660099; font-weight: bold;',
+            3 => 'color: #660099; font-weight: bold;',
+            4 => 'color: #660099; font-weight: bold;',
+            5 => 'color: #006699; font-weight: bold;',
+            'HARD' => '',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000dd;',
+            GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;',
+            2 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/c_mac.php b/examples/includes/geshi/geshi/c_mac.php
new file mode 100644 (file)
index 0000000..3478fba
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+/*************************************************************************************
+ * c_mac.php
+ * ---------
+ * Author: M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ * Copyright: (c) 2004 M. Uli Kusterer, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * C for Macs language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2004/11/27
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'C (Mac)',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Multiline-continued single-line comments
+        1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        //Multiline-continued preprocessor define
+        2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[abfnrtv\\'\"?\n]#i",
+        //Hexadecimal Char Specs
+        2 => "#\\\\x[\da-fA-F]{2}#",
+        //Hexadecimal Char Specs
+        3 => "#\\\\u[\da-fA-F]{4}#",
+        //Hexadecimal Char Specs
+        4 => "#\\\\U[\da-fA-F]{8}#",
+        //Octal Char Specs
+        5 => "#\\\\[0-7]{1,3}#"
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+        GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'if', 'return', 'while', 'case', 'continue', 'default',
+            'do', 'else', 'for', 'switch', 'goto'
+            ),
+        2 => array(
+            'NULL', 'false', 'break', 'true', 'enum', 'errno', 'EDOM',
+            'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+            'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+            'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+            'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+            'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+            'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+            'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+            'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+            'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+            'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+            'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+            // Mac-specific constants:
+            'kCFAllocatorDefault'
+            ),
+        3 => array(
+            'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+            'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+            'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+            'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+            'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+            'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+            'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+            'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+            'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+            'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+            'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+            'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+            'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+            'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+            'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+            'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+            'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+            'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+            'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+            ),
+        4 => array(
+            'auto', 'char', 'const', 'double',  'float', 'int', 'long',
+            'register', 'short', 'signed', 'static', 'string', 'struct',
+            'typedef', 'union', 'unsigned', 'void', 'volatile', 'extern', 'jmp_buf',
+            'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+            'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm',
+            // Mac-specific types:
+            'CFArrayRef', 'CFDictionaryRef', 'CFMutableDictionaryRef', 'CFBundleRef', 'CFSetRef', 'CFStringRef',
+            'CFURLRef', 'CFLocaleRef', 'CFDateFormatterRef', 'CFNumberFormatterRef', 'CFPropertyListRef',
+            'CFTreeRef', 'CFWriteStreamRef', 'CFCharacterSetRef', 'CFMutableStringRef', 'CFNotificationRef',
+            'CFReadStreamRef', 'CFNull', 'CFAllocatorRef', 'CFBagRef', 'CFBinaryHeapRef',
+            'CFBitVectorRef', 'CFBooleanRef', 'CFDataRef', 'CFDateRef', 'CFMachPortRef', 'CFMessagePortRef',
+            'CFMutableArrayRef', 'CFMutableBagRef', 'CFMutableBitVectorRef', 'CFMutableCharacterSetRef',
+            'CFMutableDataRef', 'CFMutableSetRef', 'CFNumberRef', 'CFPlugInRef', 'CFPlugInInstanceRef',
+            'CFRunLoopRef', 'CFRunLoopObserverRef', 'CFRunLoopSourceRef', 'CFRunLoopTimerRef', 'CFSocketRef',
+            'CFTimeZoneRef', 'CFTypeRef', 'CFUserNotificationRef', 'CFUUIDRef', 'CFXMLNodeRef', 'CFXMLParserRef',
+            'CFXMLTreeRef'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #0000dd;',
+            4 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #ff0000;',
+            2 => 'color: #339900;',
+            'MULTI' => 'color: #ff0000; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #660099; font-weight: bold;',
+            3 => 'color: #660099; font-weight: bold;',
+            4 => 'color: #660099; font-weight: bold;',
+            5 => 'color: #006699; font-weight: bold;',
+            'HARD' => '',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #666666;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000dd;',
+            GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #00eeff;',
+            2 => 'color: #00eeff;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/caddcl.php b/examples/includes/geshi/geshi/caddcl.php
new file mode 100644 (file)
index 0000000..69d19dc
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+/*************************************************************************************
+ * caddcl.php
+ * ----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * CAD DCL (Dialog Control Language) language file for GeSHi.
+ *
+ * DCL for AutoCAD 12 or later and IntelliCAD all versions.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/1!/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'CAD DCL',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'boxed_column','boxed_radio_column','boxed_radio_row','boxed_row',
+            'column','concatenation','button','dialog','edit_box','image','image_button',
+            'errtile','list_box','ok_cancel','ok_cancel_help','ok_cancel_help_errtile',
+            'ok_cancel_help_info','ok_only','paragraph','popup_list','radio_button',
+            'radio_column','radio_row','row','slider','spacer','spacer_0','spacer_1','text',
+            'text_part','toggle',
+            'action','alignment','allow_accept','aspect_ratio','big_increment',
+            'children_alignment','children_fixed_height',
+            'children_fixed_width','color',
+            'edit_limit','edit_width','fixed_height','fixed_width',
+            'height','initial_focus','is_cancel','is_default',
+            'is_enabled','is_tab_stop','is-bold','key','label','layout','list',
+            'max_value','min_value','mnemonic','multiple_select','password_char',
+            'small_increment','tabs','tab_truncate','value','width',
+            'false','true','left','right','centered','top','bottom',
+            'dialog_line','dialog_foreground','dialog_background',
+            'graphics_background','black','red','yellow','green','cyan',
+            'blue','magenta','whitegraphics_foreground',
+            'horizontal','vertical'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/cadlisp.php b/examples/includes/geshi/geshi/cadlisp.php
new file mode 100644 (file)
index 0000000..9865840
--- /dev/null
@@ -0,0 +1,186 @@
+<?php
+/*************************************************************************************
+ * cadlisp.php
+ * -----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/blog)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * AutoCAD/IntelliCAD Lisp language file for GeSHi.
+ *
+ * For AutoCAD V.12..2005 and IntelliCAD all versions.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'CAD Lisp',
+    'COMMENT_SINGLE' => array(1 => ";"),
+    'COMMENT_MULTI' => array(";|" => "|;"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'abs','acad_colordlg','acad_helpdlg','acad_strlsort','action_tile',
+            'add_list','alert','alloc','and','angle','angtof','angtos','append','apply',
+            'arx','arxload','arxunload','ascii','assoc','atan','atof','atoi','atom',
+            'atoms-family','autoarxload','autoload','Boole','boundp','caddr',
+            'cadr','car','cdr','chr','client_data_tile','close','command','cond',
+            'cons','cos','cvunit','defun','defun-q','defun-q-list-ref',
+            'defun-q-list-set','dictadd','dictnext','dictremove','dictrename',
+            'dictsearch','dimx_tile','dimy_tile','distance','distof','done_dialog',
+            'end_image','end_list','entdel','entget','entlast','entmake',
+            'entmakex','entmod','entnext','entsel','entupd','eq','equal','eval','exit',
+            'exp','expand','expt','fill_image','findfile','fix','float','foreach','function',
+            'gc','gcd','get_attr','get_tile','getangle','getcfg','getcname','getcorner',
+            'getdist','getenv','getfiled','getint','getkword','getorient','getpoint',
+            'getreal','getstring','getvar','graphscr','grclear','grdraw','grread','grtext',
+            'grvecs','handent','help','if','initdia','initget','inters','itoa','lambda','last',
+            'layoutlist','length','list','listp','load','load_dialog','log','logand','logior',
+            'lsh','mapcar','max','mem','member','menucmd','menugroup','min','minusp','mode_tile',
+            'namedobjdict','nentsel','nentselp','new_dialog','nil','not','nth','null',
+            'numberp','open','or','osnap','polar','prin1','princ','print','progn','prompt',
+            'quit','quote','read','read-char','read-line','redraw','regapp','rem','repeat',
+            'reverse','rtos','set','set_tile','setcfg','setenv','setfunhelp','setq','setvar',
+            'setview','sin','slide_image','snvalid','sqrt','ssadd','ssdel','ssget','ssgetfirst',
+            'sslength','ssmemb','ssname','ssnamex','sssetfirst','start_dialog','start_image',
+            'start_list','startapp','strcase','strcat','strlen','subst','substr','t','tablet',
+            'tblnext','tblobjname','tblsearch','term_dialog','terpri','textbox','textpage',
+            'textscr','trace','trans','type','unload_dialog','untrace','vector_image','ver',
+            'vports','wcmatch','while','write-char','write-line','xdroom','xdsize','zerop',
+            'vl-acad-defun','vl-acad-undefun','vl-arx-import','vlax-3D-point',
+            'vlax-add-cmd','vlax-create-object','vlax-curve-getArea',
+            'vlax-curve-getClosestPointTo','vlax-curve-getClosestPointToProjection',
+            'vlax-curve-getDistAtParam','vlax-curve-getDistAtPoint',
+            'vlax-curve-getEndParam','vlax-curve-getEndPoint',
+            'vlax-curve-getFirstDeriv','vlax-curve-getParamAtDist',
+            'vlax-curve-getParamAtPoint','vlax-curve-getPointAtDist',
+            'vlax-curve-getPointAtParam','vlax-curve-getSecondDeriv',
+            'vlax-curve-getStartParam','vlax-curve-getStartPoint',
+            'vlax-curve-isClosed','vlax-curve-isPeriodic','vlax-curve-isPlanar',
+            'vlax-dump-object','vlax-erased-p','vlax-for','vlax-get-acad-object',
+            'vlax-get-object','vlax-get-or-create-object','vlax-get-property',
+            'vlax-import-type-library','vlax-invoke-method','vlax-ldata-delete',
+            'vlax-ldata-get','vlax-ldata-list','vlax-ldata-put','vlax-ldata-test',
+            'vlax-make-safearray','vlax-make-variant','vlax-map-collection',
+            'vlax-method-applicable-p','vlax-object-released-p','vlax-product-key',
+            'vlax-property-available-p','vlax-put-property','vlax-read-enabled-p',
+            'vlax-release-object','vlax-remove-cmd','vlax-safearray-fill',
+            'vlax-safearray-get-dim','vlax-safearray-get-element',
+            'vlax-safearray-get-l-bound','vlax-safearray-get-u-bound',
+            'vlax-safearray-put-element','vlax-safearray-type','vlax-tmatrix',
+            'vlax-typeinfo-available-p','vlax-variant-change-type',
+            'vlax-variant-type','vlax-variant-value','vlax-write-enabled-p',
+            'vl-bb-ref','vl-bb-set','vl-catch-all-apply','vl-catch-all-error-message',
+            'vl-catch-all-error-p','vl-cmdf','vl-consp','vl-directory-files','vl-doc-export',
+            'vl-doc-import','vl-doc-ref','vl-doc-set','vl-every','vl-exit-with-error',
+            'vl-exit-with-value','vl-file-copy','vl-file-delete','vl-file-directory-p',
+            'vl-filename-base','vl-filename-directory','vl-filename-extension',
+            'vl-filename-mktemp','vl-file-rename','vl-file-size','vl-file-systime',
+            'vl-get-resource','vlisp-compile','vl-list-exported-functions',
+            'vl-list-length','vl-list-loaded-vlx','vl-load-all','vl-load-com',
+            'vl-load-reactors','vl-member-if','vl-member-if-not','vl-position',
+            'vl-prin1-to-string','vl-princ-to-string','vl-propagate','vlr-acdb-reactor',
+            'vlr-add','vlr-added-p','vlr-beep-reaction','vlr-command-reactor',
+            'vlr-current-reaction-name','vlr-data','vlr-data-set',
+            'vlr-deepclone-reactor','vlr-docmanager-reactor','vlr-dwg-reactor',
+            'vlr-dxf-reactor','vlr-editor-reactor','vl-registry-delete',
+            'vl-registry-descendents','vl-registry-read','vl-registry-write',
+            'vl-remove','vl-remove-if','vl-remove-if-not','vlr-insert-reactor',
+            'vlr-linker-reactor','vlr-lisp-reactor','vlr-miscellaneous-reactor',
+            'vlr-mouse-reactor','vlr-notification','vlr-object-reactor',
+            'vlr-owner-add','vlr-owner-remove','vlr-owners','vlr-pers','vlr-pers-list',
+            'vlr-pers-p','vlr-pers-release','vlr-reaction-names','vlr-reactions',
+            'vlr-reaction-set','vlr-reactors','vlr-remove','vlr-remove-all',
+            'vlr-set-notification','vlr-sysvar-reactor','vlr-toolbar-reactor',
+            'vlr-trace-reaction','vlr-type','vlr-types','vlr-undo-reactor',
+            'vlr-wblock-reactor','vlr-window-reactor','vlr-xref-reactor',
+            'vl-some','vl-sort','vl-sort-i','vl-string-elt','vl-string-left-trim',
+            'vl-string-mismatch','vl-string-position','vl-string-right-trim',
+            'vl-string-search','vl-string-subst','vl-string-translate','vl-string-trim',
+            'vl-symbol-name','vl-symbolp','vl-symbol-value','vl-unload-vlx','vl-vbaload',
+            'vl-vbarun','vl-vlx-loaded-p'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '!', '%', '^', '&', '/','+','-','*','=','<','>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/cfdg.php b/examples/includes/geshi/geshi/cfdg.php
new file mode 100644 (file)
index 0000000..fc097ca
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+/*************************************************************************************
+ * cfdg.php
+ * --------
+ * Author: John Horigan <john@glyphic.com>
+ * Copyright: (c) 2006 John Horigan http://www.ozonehouse.com/john/
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/03/11
+ *
+ * CFDG language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006/03/11 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2006/03/11)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'CFDG',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'include', 'startshape', 'rule', 'background'
+            ),
+        2 => array(
+            'SQUARE', 'CIRCLE', 'TRIANGLE',
+            ),
+        3 => array(
+            'b','brightness','h','hue','sat','saturation',
+            'a','alpha','x','y','z','s','size',
+            'r','rotate','f','flip','skew','xml_set_object'
+            )
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '{', '}', '*', '|'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #717100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #006666;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/cfm.php b/examples/includes/geshi/geshi/cfm.php
new file mode 100644 (file)
index 0000000..e900f46
--- /dev/null
@@ -0,0 +1,299 @@
+<?php
+/*************************************************************************************
+ * cfm.php
+ * -------
+ * Author: Diego
+ * Copyright: (c) 2006 Diego
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/02/25
+ *
+ * ColdFusion language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006/02/25 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2006/02/25)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'ColdFusion',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        /* CFM Tags */
+        1 => array(
+            'cfabort', 'cfapplet', 'cfapplication', 'cfargument', 'cfassociate',
+            'cfbreak', 'cfcache', 'cfcase', 'cfcatch', 'cfchart', 'cfchartdata',
+            'cfchartseries', 'cfcol', 'cfcollection', 'cfcomponent',
+            'cfcontent', 'cfcookie', 'cfdefaultcase', 'cfdirectory',
+            'cfdocument', 'cfdocumentitem', 'cfdocumentsection', 'cfdump',
+            'cfelse', 'cfelseif', 'cferror', 'cfexecute', 'cfexit', 'cffile',
+            'cfflush', 'cfform', 'cfformgroup', 'cfformitem', 'cfftp',
+            'cffunction', 'cfgrid', 'cfgridcolumn', 'cfgridrow', 'cfgridupdate',
+            'cfheader', 'cfhtmlhead', 'cfhttp', 'cfhttpparam', 'cfif',
+            'cfimport', 'cfinclude', 'cfindex', 'cfinput', 'cfinsert',
+            'cfinvoke', 'cfinvokeargument', 'cfldap', 'cflocation', 'cflock',
+            'cflog', 'cflogin', 'cfloginuser', 'cflogout', 'cfloop', 'cfmail',
+            'cfmailparam', 'cfmailpart', 'cfmodule', 'cfNTauthenticate',
+            'cfobject', 'cfobjectcache', 'cfoutput', 'cfparam', 'cfpop',
+            'cfprocessingdirective', 'cfprocparam',
+            'cfprocresult', 'cfproperty', 'cfquery', 'cfqueryparam',
+            'cfregistry', 'cfreport', 'cfreportparam', 'cfrethrow', 'cfreturn',
+            'cfsavecontent', 'cfschedule', 'cfscript', 'cfsearch', 'cfselect',
+            'cfset', 'cfsetting', 'cfsilent', 'cfstoredproc',
+            'cfswitch', 'cftable', 'cftextarea', 'cfthrow', 'cftimer',
+            'cftrace', 'cftransaction', 'cftree', 'cftreeitem', 'cftry',
+            'cfupdate', 'cfwddx'
+            ),
+        /* HTML Tags */
+        2 => array(
+            'a', 'abbr', 'acronym', 'address', 'applet',
+
+            'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+            'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+            'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+            'em',
+
+            'fieldset', 'font', 'form', 'frame', 'frameset',
+
+            'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+            'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+            'kbd',
+
+            'label', 'legend', 'link', 'li',
+
+            'map', 'meta',
+
+            'noframes', 'noscript',
+
+            'object', 'ol', 'optgroup', 'option',
+
+            'param', 'pre', 'p',
+
+            'q',
+
+            'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+            'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+            'ul', 'u',
+
+            'var',
+            ),
+        /* HTML attributes */
+        3 => array(
+            'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+            'background', 'bgcolor', 'border',
+            'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+            'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+            'enctype',
+            'face', 'for', 'frame', 'frameborder',
+            'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+            'id', 'ismap',
+            'label', 'lang', 'language', 'link', 'longdesc',
+            'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+            'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+            'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+            'profile', 'prompt',
+            'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+            'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+            'tabindex', 'target', 'text', 'title', 'type',
+            'usemap',
+            'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+            'width'
+            ),
+        /* CFM Script delimeters */
+        4 => array(
+            'var', 'function', 'while', 'if','else'
+            ),
+        /* CFM Functions */
+        5 => array(
+            'Abs', 'GetFunctionList', 'LSTimeFormat','ACos','GetGatewayHelper','LTrim','AddSOAPRequestHeader','GetHttpRequestData',
+            'Max','AddSOAPResponseHeader','GetHttpTimeString','Mid','ArrayAppend','GetLocale','Min','ArrayAvg','GetLocaleDisplayName',
+            'Minute','ArrayClear','GetMetaData','Month','ArrayDeleteAt','GetMetricData','MonthAsString','ArrayInsertAt','GetPageContext',
+            'Now','ArrayIsEmpty','GetProfileSections','NumberFormat','ArrayLen','GetProfileString','ParagraphFormat','ArrayMax',
+            'GetLocalHostIP','ParseDateTime','ArrayMin','GetSOAPRequest','Pi','ArrayNew','GetSOAPRequestHeader','PreserveSingleQuotes',
+            'ArrayPrepend','GetSOAPResponse','Quarter','ArrayResize','GetSOAPResponseHeader','QueryAddColumn','ArraySet',
+            'GetTempDirectory','QueryAddRow','ArraySort','QueryNew','ArraySum','GetTempFile','QuerySetCell',
+            'ArraySwap','GetTickCount','QuotedValueList','ArrayToList','GetTimeZoneInfo','Rand','Asc','GetToken','Randomize',
+            'ASin','Hash','RandRange','Atn','Hour','REFind','BinaryDecode','HTMLCodeFormat','REFindNoCase','BinaryEncode',
+            'HTMLEditFormat','ReleaseComObject','BitAnd','IIf','RemoveChars','BitMaskClear','IncrementValue','RepeatString',
+            'BitMaskRead','InputBaseN','Replace','BitMaskSet','Insert','ReplaceList','BitNot','Int','ReplaceNoCase','BitOr',
+            'IsArray','REReplace','BitSHLN','IsBinary','REReplaceNoCase','BitSHRN','IsBoolean','Reverse','BitXor','IsCustomFunction',
+            'Right','Ceiling','IsDate','RJustify','CharsetDecode','IsDebugMode','Round','CharsetEncode','IsDefined','RTrim',
+            'Chr','IsLeapYear','Second','CJustify','IsLocalHost','SendGatewayMessage','Compare','IsNumeric','SetEncoding',
+            'CompareNoCase','IsNumericDate','SetLocale','Cos','IsObject','SetProfileString','CreateDate','IsQuery','SetVariable',
+            'CreateDateTime','IsSimpleValue','Sgn','CreateObject','IsSOAPRequest','Sin','CreateODBCDate','IsStruct','SpanExcluding',
+            'CreateODBCDateTime','IsUserInRole','SpanIncluding','CreateODBCTime','IsValid','Sqr','CreateTime','IsWDDX','StripCR',
+            'CreateTimeSpan','IsXML','StructAppend','CreateUUID','IsXmlAttribute','StructClear','DateAdd','IsXmlDoc','StructCopy',
+            'DateCompare','IsXmlElem','StructCount','DateConvert','IsXmlNode','StructDelete','DateDiff','IsXmlRoot','StructFind',
+            'DateFormat','JavaCast','StructFindKey','DatePart','JSStringFormat','StructFindValue','Day','LCase','StructGet',
+            'DayOfWeek','Left','StructInsert','DayOfWeekAsString','Len','StructIsEmpty','DayOfYear','ListAppend','StructKeyArray',
+            'DaysInMonth','ListChangeDelims','StructKeyExists','DaysInYear','ListContains','StructKeyList','DE','ListContainsNoCase',
+            'StructNew','DecimalFormat','ListDeleteAt','StructSort','DecrementValue','ListFind','StructUpdate','Decrypt','ListFindNoCase',
+            'Tan','DecryptBinary','ListFirst','TimeFormat','DeleteClientVariable','ListGetAt','ToBase64','DirectoryExists',
+            'ListInsertAt','ToBinary','DollarFormat','ListLast','ToScript','Duplicate','ListLen','ToString','Encrypt','ListPrepend',
+            'Trim','EncryptBinary','ListQualify','UCase','Evaluate','ListRest','URLDecode','Exp','ListSetAt','URLEncodedFormat',
+            'ExpandPath','ListSort','URLSessionFormat','FileExists','ListToArray','Val','Find','ListValueCount','ValueList',
+            'FindNoCase','ListValueCountNoCase','Week','FindOneOf','LJustify','Wrap','FirstDayOfMonth','Log','WriteOutput',
+            'Fix','Log10','XmlChildPos','FormatBaseN','LSCurrencyFormat','XmlElemNew','GetAuthUser','LSDateFormat','XmlFormat',
+            'GetBaseTagData','LSEuroCurrencyFormat','XmlGetNodeType','GetBaseTagList','LSIsCurrency','XmlNew','GetBaseTemplatePath',
+            'LSIsDate','XmlParse','GetClientVariablesList','LSIsNumeric','XmlSearch','GetCurrentTemplatePath','LSNumberFormat',
+            'XmlTransform','GetDirectoryFromPath','LSParseCurrency','XmlValidate','GetEncoding','LSParseDateTime','Year',
+            'GetException','LSParseEuroCurrency','YesNoFormat','GetFileFromPath','LSParseNumber'
+            ),
+        /* CFM Attributes */
+        6 => array(
+            'dbtype','connectstring','datasource','username','password','query','delimeter','description','required','hint','default','access','from','to','list','index'
+            ),
+        7 => array(
+            'EQ', 'GT', 'LT', 'GTE', 'LTE', 'IS', 'LIKE', 'NEQ'
+            )
+        ),
+    'SYMBOLS' => array(
+        '/', '=', '{', '}', '(', ')', '[', ']', '<', '>', '&'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #990000; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #0000FF;',
+            4 => 'color: #000000; font-weight: bold;',
+            5 => 'color: #0000FF;',
+            6 => 'color: #0000FF;',
+            7 => 'color: #0000FF;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #0000FF;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #009900;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #0000FF;'
+            ),
+        'SCRIPT' => array(
+            0 => 'color: #808080; font-style: italic;',
+            1 => 'color: #00bbdd;',
+            2 => 'color: #0000FF;',
+            3 => 'color: #000099;',
+            4 => 'color: #333333;',
+            5 => 'color: #333333;'
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => 'http://december.com/html/4/element/{FNAMEL}.html',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<!--' => '-->'
+            ),
+        1 => array(
+            '<!DOCTYPE' => '>'
+            ),
+        2 => "/(?!<#)(?:(?:##)*)(#)[a-zA-Z0-9_\.\(\)]+(#)/",
+        3 => array(
+            '<cfscript>' => '</cfscript>'
+            ),
+        4 => array(
+            '<' => '>'
+            ),
+        5 => '/((?!<!)<)(?:"[^"]*"|\'[^\']*\'|(?R)|[^">])+?(>)/si'
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => false,
+        1 => false,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            1 => array(
+                'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+                'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+                ),
+            2 => array(
+                'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+                'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+                ),
+            3 => array(
+                'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>|^])', // allow ; before keywords
+                'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-])', // allow & after keywords
+                ),
+            7 => array(
+                'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>&|^])', // allow ; before keywords
+                'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-])', // allow & after keywords
+                )
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/cil.php b/examples/includes/geshi/geshi/cil.php
new file mode 100644 (file)
index 0000000..41777d6
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/*************************************************************************************
+ * cil.php
+ * --------
+ * Author: Marcus Griep (neoeinstein+GeSHi@gmail.com)
+ * Copyright: (c) 2007 Marcus Griep (http://www.xpdm.us)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/10/24
+ *
+ * CIL (Common Intermediate Language) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/10/24 (1.0.8)
+ *  -  First Release
+ *
+ * TODO (updated 2007/10/24)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'CIL',
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'COMMENT_SINGLE' => array('//'),
+    'COMMENT_MULTI' => array(),
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(//Dotted
+            '.zeroinit', '.vtfixup', '.vtentry', '.vtable', '.ver', '.try', '.subsystem', '.size', '.set', '.removeon',
+            '.publickeytoken', '.publickey', '.property', '.permissionset', '.permission', '.pdirect', '.param', '.pack',
+            '.override', '.other', '.namespace', '.mresource', '.module', '.method', '.maxstack', '.manifestres', '.locals',
+            '.localized', '.locale', '.line', '.language', '.import', '.imagebase', '.hash', '.get', '.fire', '.file', '.field',
+            '.export', '.event', '.entrypoint', '.emitbyte', '.data', '.custom', '.culture', '.ctor', '.corflags', '.class',
+            '.cctor', '.assembly', '.addon'
+            ),
+        2 => array(//Attributes
+            'wrapper', 'with', 'winapi', 'virtual', 'vector', 'vararg', 'value', 'userdefined', 'unused', 'unmanagedexp',
+            'unmanaged', 'unicode', 'to', 'tls', 'thiscall', 'synchronized', 'struct', 'strict', 'storage', 'stdcall',
+            'static', 'specialname', 'special', 'serializable', 'sequential', 'sealed', 'runtime', 'rtspecialname', 'request',
+            'reqsecobj', 'reqrefuse', 'reqopt', 'reqmin', 'record', 'public', 'privatescope', 'private', 'preservesig',
+            'prejitgrant', 'prejitdeny', 'platformapi', 'pinvokeimpl', 'pinned', 'permitonly', 'out', 'optil', 'opt',
+            'notserialized', 'notremotable', 'not_in_gc_heap', 'noprocess', 'noncaslinkdemand', 'noncasinheritance',
+            'noncasdemand', 'nometadata', 'nomangle', 'nomachine', 'noinlining', 'noappdomain', 'newslot', 'nested', 'native',
+            'modreq', 'modopt', 'marshal', 'managed', 'literal', 'linkcheck', 'lcid', 'lasterr', 'internalcall', 'interface',
+            'instance', 'initonly', 'init', 'inheritcheck', 'in', 'import', 'implicitres', 'implicitcom', 'implements',
+            'illegal', 'il', 'hidebysig', 'handler', 'fromunmanaged', 'forwardref', 'fixed', 'finally', 'final', 'filter',
+            'filetime', 'field', 'fault', 'fastcall', 'famorassem', 'family', 'famandassem', 'extern', 'extends', 'explicit',
+            'error', 'enum', 'endmac', 'deny', 'demand', 'default', 'custom', 'compilercontrolled', 'clsid', 'class', 'cil',
+            'cf', 'cdecl', 'catch', 'beforefieldinit', 'autochar', 'auto', 'at', 'assert', 'assembly', 'as', 'any', 'ansi',
+            'alignment', 'algorithm', 'abstract'
+            ),
+        3 => array(//Types
+            'wchar', 'void', 'variant', 'unsigned', 'valuetype', 'typedref', 'tbstr', 'sysstring', 'syschar', 'string',
+            'streamed_object', 'stream', 'stored_object', 'safearray', 'objectref', 'object', 'nullref', 'method', 'lpwstr',
+            'lpvoid', 'lptstr', 'lpstruct', 'lpstr', 'iunknown', 'int64', 'int32', 'int16', 'int8', 'int', 'idispatch',
+            'hresult', 'float64', 'float32', 'float', 'decimal', 'date', 'currency', 'char', 'carray', 'byvalstr',
+            'bytearray', 'boxed', 'bool', 'blob_object', 'blob', 'array'
+            ),
+        4 => array(//Prefix
+            'volatile', 'unaligned', 'tail', 'readonly', 'no', 'constrained'
+            ),
+        5 => array(//Suffix
+            'un', 'u8', 'u4', 'u2', 'u1', 'u', 's', 'ref', 'r8', 'r4', 'm1', 'i8', 'i4', 'i2', 'i1', 'i'#, '.8', '.7', '.6', '.5', '.4', '.3', '.2', '.1', '.0'
+            ),
+        6 => array(//Base
+            'xor', 'switch', 'sub', 'stloc',
+            'stind', 'starg',
+            'shr', 'shl', 'ret', 'rem', 'pop', 'or', 'not', 'nop', 'neg', 'mul',
+            'localloc', 'leave', 'ldnull', 'ldloca',
+            'ldloc', 'ldind', 'ldftn', 'ldc', 'ldarga',
+            'ldarg', 'jmp', 'initblk', 'endfinally', 'endfilter',
+            'endfault', 'dup', 'div', 'cpblk', 'conv', 'clt', 'ckfinite', 'cgt', 'ceq', 'calli',
+            'call', 'brzero', 'brtrue', 'brnull', 'brinst',
+            'brfalse', 'break', 'br', 'bne', 'blt', 'ble', 'bgt', 'bge', 'beq', 'arglist',
+            'and', 'add'
+            ),
+        7 => array(//Object
+            'unbox.any', 'unbox', 'throw', 'stsfld', 'stobj', 'stfld', 'stelem', 'sizeof', 'rethrow', 'refanyval', 'refanytype', 'newobj',
+            'newarr', 'mkrefany', 'ldvirtftn', 'ldtoken', 'ldstr', 'ldsflda', 'ldsfld', 'ldobj', 'ldlen', 'ldflda', 'ldfld',
+            'ldelema', 'ldelem', 'isinst', 'initobj', 'cpobj', 'castclass',
+            'callvirt', 'callmostderived', 'box'
+            ),
+        8 => array(//Other
+            'prefixref', 'prefix7', 'prefix6', 'prefix5', 'prefix4', 'prefix3', 'prefix2', 'prefix1', 'prefix0'
+            ),
+        9 => array(//Literal
+            'true', 'null', 'false'
+            ),
+        10 => array(//Comment-like
+            '#line', '^THE_END^'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '!!'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true,
+        9 => true,
+        10 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color:maroon;font-weight:bold;',
+            2 => 'color:blue;font-weight:bold;',
+            3 => 'color:purple;font-weight:bold;',
+            4 => 'color:teal;',
+            5 => 'color:blue;',
+            6 => 'color:blue;',
+            7 => 'color:blue;',
+            8 => 'color:blue;',
+            9 => 'color:00008B',
+            10 => 'color:gray'
+            ),
+        'COMMENTS' => array(
+            0 => 'color:gray;font-style:italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008000; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #006400;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #008000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #00008B;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #000033;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #006400;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color:blue;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => '',
+        8 => '',
+        9 => '',
+        10 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '::'
+        ),
+    'REGEXPS' => array(
+        0 => '(?<=ldc\\.i4\\.)[0-8]|(?<=(?:ldarg|ldloc|stloc)\\.)[0-3]' # Pickup the opcodes that end with integers
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/cobol.php b/examples/includes/geshi/geshi/cobol.php
new file mode 100644 (file)
index 0000000..71f9828
--- /dev/null
@@ -0,0 +1,244 @@
+<?php
+/*************************************************************************************
+ * cobol.php
+ * ----------
+ * Author: BenBE (BenBE@omorphia.org)
+ * Copyright: (c) 2007-2008 BenBE (http://www.omorphia.de/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/07/02
+ *
+ * COBOL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO (updated 2007/07/02)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'COBOL',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(1 => '/^\*.*?$/m'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', "'"),
+    'ESCAPE_CHAR' => '\\',
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC |
+        GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_SCI_SHORT |
+        GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array( //Compiler Directives
+            'ANSI', 'BLANK', 'NOBLANK', 'CALL-SHARED', 'CANCEL', 'NOCANCEL',
+            'CHECK', 'CODE', 'NOCODE', 'COLUMNS', 'COMPACT', 'NOCOMPACT',
+            'COMPILE', 'CONSULT', 'NOCONSULT', 'CROSSREF', 'NOCROSSREF',
+            'DIAGNOSE-74', 'NODIAGNOSE-74', 'DIAGNOSE-85', 'NODIAGNOSE-85',
+            'DIAGNOSEALL', 'NODIAGNOSEALL', 'ENDIF', 'ENDUNIT', 'ENV',
+            'ERRORFILE', 'ERRORS', 'FIPS', 'NOFIPS', 'FMAP', 'HEADING', 'HEAP',
+            'HIGHPIN', 'HIGHREQUESTERS', 'ICODE', 'NOICODE', 'IF', 'IFNOT',
+            'INNERLIST', 'NOINNERLIST', 'INSPECT', 'NOINSPECT', 'LARGEDATA',
+            'LD', 'LESS-CODE', 'LIBRARY', 'LINES', 'LIST', 'NOLIST', 'LMAP',
+            'NOLMAP', 'MAIN', 'MAP', 'NOMAP', 'NLD', 'NONSTOP', 'NON-SHARED',
+            'OPTIMIZE', 'PERFORM-TRACE', 'PORT', 'NOPORT', 'RESETTOG',
+            'RUNNABLE', 'RUNNAMED', 'SAVE', 'SAVEABEND', 'NOSAVEABEND',
+            'SEARCH', 'NOSEARCH', 'SECTION', 'SETTOG', 'SHARED', 'SHOWCOPY',
+            'NOSHOWCOPY', 'SHOWFILE', 'NOSHOWFILE', 'SOURCE', 'SQL', 'NOSQL',
+            'SQLMEM', 'SUBSET', 'SUBTYPE', 'SUPPRESS', 'NOSUPPRESS', 'SYMBOLS',
+            'NOSYMBOLS', 'SYNTAX', 'TANDEM', 'TRAP2', 'NOTRAP2', 'TRAP2-74',
+            'NOTRAP2-74', 'UL', 'WARN', 'NOWARN'
+            ),
+        2 => array( //Statement Keywords
+            'ACCEPT', 'ADD', 'TO', 'GIVING', 'CORRESPONDING', 'ALTER', 'CALL',
+            'CHECKPOINT', 'CLOSE', 'COMPUTE', 'CONTINUE', 'COPY',
+            'DELETE', 'DISPLAY', 'DIVIDE', 'INTO', 'REMAINDER', 'ENTER',
+            'COBOL', 'EVALUATE', 'EXIT', 'GO', 'INITIALIZE',
+            'TALLYING', 'REPLACING', 'CONVERTING', 'LOCKFILE', 'MERGE', 'MOVE',
+            'MULTIPLY', 'OPEN', 'PERFORM', 'TIMES',
+            'UNTIL', 'VARYING', 'RETURN',
+            ),
+        3 => array( //Reserved in some contexts
+            'ACCESS', 'ADDRESS', 'ADVANCING', 'AFTER', 'ALL',
+            'ALPHABET', 'ALPHABETIC', 'ALPHABETIC-LOWER', 'ALPHABETIC-UPPER',
+            'ALPHANUMERIC', 'ALPHANUMERIC-EDITED', 'ALSO', 'ALTERNATE',
+            'AND', 'ANY', 'APPROXIMATE', 'AREA', 'AREAS', 'ASCENDING', 'ASSIGN',
+            'AT', 'AUTHOR', 'BEFORE', 'BINARY', 'BLOCK', 'BOTTOM', 'BY',
+            'CD', 'CF', 'CH', 'CHARACTER', 'CHARACTERS',
+            'CHARACTER-SET', 'CLASS', 'CLOCK-UNITS',
+            'CODE-SET', 'COLLATING', 'COLUMN', 'COMMA',
+            'COMMON', 'COMMUNICATION', 'COMP', 'COMP-3', 'COMP-5',
+            'COMPUTATIONAL', 'COMPUTATIONAL-3', 'COMPUTATIONAL-5',
+            'CONFIGURATION', 'CONTAINS', 'CONTENT', 'CONTROL',
+            'CONTROLS', 'CORR', 'COUNT',
+            'CURRENCY', 'DATA', 'DATE', 'DATE-COMPILED', 'DATE-WRITTEN', 'DAY',
+            'DAY-OF-WEEK', 'DE', 'DEBUG-CONTENTS', 'DEBUG-ITEM', 'DEBUG-LINE',
+            'DEBUG-SUB-2', 'DEBUG-SUB-3', 'DEBUGGING', 'DECIMAL-POINT',
+            'DECLARATIVES', 'DEBUG-NAME', 'DEBUG-SUB-1', 'DELIMITED',
+            'DELIMITER', 'DEPENDING', 'DESCENDING', 'DESTINATION', 'DETAIL',
+            'DISABLE', 'DIVISION', 'DOWN', 'DUPLICATES',
+            'DYNAMIC', 'EGI', 'ELSE', 'EMI', 'ENABLE', 'END', 'END-ADD',
+            'END-COMPUTE', 'END-DELETE', 'END-DIVIDE', 'END-EVALUATE', 'END-IF',
+            'END-MULTIPLY', 'END-OF-PAGE', 'END-PERFORM', 'END-READ',
+            'END-RECEIVE', 'END-RETURN', 'END-REWRITE', 'END-SEARCH',
+            'END-START', 'END-STRING', 'END-SUBTRACT', 'END-UNSTRING',
+            'END-WRITE', 'EOP', 'EQUAL', 'ERROR', 'ESI',
+            'EVERY', 'EXCEPTION', 'EXCLUSIVE', 'EXTEND',
+            'EXTENDED-STORAGE', 'EXTERNAL', 'FALSE', 'FD', 'FILE',
+            'FILE-CONTROL', 'FILLER', 'FINAL', 'FIRST', 'FOOTING', 'FOR',
+            'FROM', 'FUNCTION', 'GENERATE', 'GENERIC', 'GLOBAL',
+            'GREATER', 'GROUP', 'GUARDIAN-ERR', 'HIGH-VALUE',
+            'HIGH-VALUES', 'I-O', 'I-O-CONTROL', 'IDENTIFICATION', 'IN',
+            'INDEX', 'INDEXED', 'INDICATE', 'INITIAL', 'INITIATE',
+            'INPUT', 'INPUT-OUTPUT', 'INSTALLATION',
+            'INVALID', 'IS', 'JUST', 'JUSTIFIED', 'KEY', 'LABEL', 'LAST',
+            'LEADING', 'LEFT', 'LESS', 'LIMIT', 'LIMITS', 'LINAGE',
+            'LINAGE-COUNTER', 'LINE', 'LINE-COUNTER', 'LINKAGE', 'LOCK',
+            'LOW-VALUE', 'LOW-VALUES', 'MEMORY', 'MESSAGE',
+            'MODE', 'MODULES', 'MULTIPLE', 'NATIVE',
+            'NEGATIVE', 'NEXT', 'NO', 'NOT', 'NULL', 'NULLS', 'NUMBER',
+            'NUMERIC', 'NUMERIC-EDITED', 'OBJECT-COMPUTER', 'OCCURS', 'OF',
+            'OFF', 'OMITTED', 'ON', 'OPTIONAL', 'OR', 'ORDER',
+            'ORGANIZATION', 'OTHER', 'OUTPUT', 'OVERFLOW', 'PACKED-DECIMAL',
+            'PADDING', 'PAGE', 'PAGE-COUNTER', 'PF', 'PH', 'PIC',
+            'PICTURE', 'PLUS', 'POINTER', 'POSITION', 'POSITIVE', 'PRINTING',
+            'PROCEDURE', 'PROCEDURES', 'PROCEED', 'PROGRAM', 'PROGRAM-ID',
+            'PROGRAM-STATUS', 'PROGRAM-STATUS-1', 'PROGRAM-STATUS-2', 'PROMPT',
+            'PROTECTED', 'PURGE', 'QUEUE', 'QUOTE', 'QUOTES', 'RD',
+            'RECEIVE', 'RECEIVE-CONTROL', 'RECORD', 'RECORDS',
+            'REDEFINES', 'REEL', 'REFERENCE', 'REFERENCES', 'RELATIVE',
+            'REMOVAL', 'RENAMES', 'REPLACE',
+            'REPLY', 'REPORT', 'REPORTING', 'REPORTS', 'RERUN',
+            'RESERVE', 'RESET', 'REVERSED', 'REWIND', 'REWRITE', 'RF',
+            'RH', 'RIGHT', 'ROUNDED', 'RUN', 'SAME', 'SD',
+            'SECURITY', 'SEGMENT', 'SEGMENT-LIMIT', 'SELECT', 'SEND',
+            'SENTENCE', 'SEPARATE', 'SEQUENCE', 'SEQUENTIAL', 'SET',
+            'SIGN', 'SIZE', 'SORT', 'SORT-MERGE', 'SOURCE-COMPUTER',
+            'SPACE', 'SPACES', 'SPECIAL-NAMES', 'STANDARD', 'STANDARD-1',
+            'STANDARD-2', 'START', 'STARTBACKUP', 'STATUS', 'STOP', 'STRING',
+            'SUB-QUEUE-1', 'SUB-QUEUE-2', 'SUB-QUEUE-3', 'SUBTRACT',
+            'SYMBOLIC', 'SYNC', 'SYNCDEPTH', 'SYNCHRONIZED',
+            'TABLE', 'TAL', 'TAPE', 'TERMINAL', 'TERMINATE', 'TEST',
+            'TEXT', 'THAN', 'THEN', 'THROUGH', 'THRU', 'TIME',
+            'TOP', 'TRAILING', 'TRUE', 'TYPE', 'UNIT', 'UNLOCK', 'UNLOCKFILE',
+            'UNLOCKRECORD', 'UNSTRING', 'UP', 'UPON', 'USAGE', 'USE',
+            'USING', 'VALUE', 'VALUES', 'WHEN', 'WITH', 'WORDS',
+            'WORKING-STORAGE', 'WRITE', 'ZERO', 'ZEROES'
+            ),
+        4 => array( //Standard functions
+            'ACOS', 'ANNUITY', 'ASIN', 'ATAN', 'CHAR', 'COS', 'CURRENT-DATE',
+            'DATE-OF-INTEGER', 'DAY-OF-INTEGER', 'FACTORIAL', 'INTEGER',
+            'INTEGER-OF-DATE', 'INTEGER-OF-DAY', 'INTEGER-PART', 'LENGTH',
+            'LOG', 'LOG10', 'LOWER-CASE', 'MAX', 'MEAN', 'MEDIAN', 'MIDRANGE',
+            'MIN', 'MOD', 'NUMVAL', 'NUMVAL-C', 'ORD', 'ORD-MAX', 'ORD-MIN',
+            'PRESENT-VALUE', 'RANDOM', 'RANGE', 'REM', 'REVERSE', 'SIN', 'SQRT',
+            'STANDARD-DEVIATION', 'SUM', 'TAN', 'UPPER-CASE', 'VARIANCE',
+            'WHEN-COMPILED'
+            ),
+        5 => array( //Privileged Built-in Functions
+            '#IN', '#OUT', '#TERM', '#TEMP', '#DYNAMIC', 'COBOL85^ARMTRAP',
+            'COBOL85^COMPLETION', 'COBOL_COMPLETION_', 'COBOL_CONTROL_',
+            'COBOL_GETENV_', 'COBOL_PUTENV_', 'COBOL85^RETURN^SORT^ERRORS',
+            'COBOL_RETURN_SORT_ERRORS_', 'COBOL85^REWIND^SEQUENTIAL',
+            'COBOL_REWIND_SEQUENTIAL_', 'COBOL85^SET^SORT^PARAM^TEXT',
+            'COBOL_SET_SORT_PARAM_TEXT_', 'COBOL85^SET^SORT^PARAM^VALUE',
+            'COBOL_SET_SORT_PARAM_VALUE_', 'COBOL_SET_MAX_RECORD_',
+            'COBOL_SETMODE_', 'COBOL85^SPECIAL^OPEN', 'COBOL_SPECIAL_OPEN_',
+            'COBOLASSIGN', 'COBOL_ASSIGN_', 'COBOLFILEINFO', 'COBOL_FILE_INFO_',
+            'COBOLSPOOLOPEN', 'CREATEPROCESS', 'ALTERPARAMTEXT',
+            'CHECKLOGICALNAME', 'CHECKMESSAGE', 'DELETEASSIGN', 'DELETEPARAM',
+            'DELETESTARTUP', 'GETASSIGNTEXT', 'GETASSIGNVALUE', 'GETBACKUPCPU',
+            'GETPARAMTEXT', 'GETSTARTUPTEXT', 'PUTASSIGNTEXT', 'PUTASSIGNVALUE',
+            'PUTPARAMTEXT', 'PUTSTARTUPTEXT'
+            )
+        ),
+    'SYMBOLS' => array(
+        //Avoid having - in identifiers marked as symbols
+        ' + ', ' - ', ' * ', ' / ', ' ** ',
+        '.', ',',
+        '=',
+        '(', ')', '[', ']'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000080; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #008000; font-weight: bold;',
+            4 => 'color: #000080;',
+            5 => 'color: #008000;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #a0a0a0; font-style: italic;',
+            'MULTI' => 'color: #a0a0a0; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #339933;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #993399;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+    );
+
+?>
diff --git a/examples/includes/geshi/geshi/cpp-qt.php b/examples/includes/geshi/geshi/cpp-qt.php
new file mode 100644 (file)
index 0000000..79ec3c6
--- /dev/null
@@ -0,0 +1,315 @@
+<?php
+/*************************************************************************************
+ * cpp.php
+ * -------
+ * Author: Iulian M
+ * Copyright: (c) 2006 Iulian M
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/09/27
+ *
+ * C++ (with QT extensions) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'C++ (QT)',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Multiline-continued single-line comments
+        1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        //Multiline-continued preprocessor define
+        2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[abfnrtv\\'\"?\n]#i",
+        //Hexadecimal Char Specs
+        2 => "#\\\\x[\da-fA-F]{2}#",
+        //Hexadecimal Char Specs
+        3 => "#\\\\u[\da-fA-F]{4}#",
+        //Hexadecimal Char Specs
+        4 => "#\\\\U[\da-fA-F]{8}#",
+        //Octal Char Specs
+        5 => "#\\\\[0-7]{1,3}#"
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+        GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'case', 'continue', 'default', 'do', 'else', 'for', 'goto', 'if', 'return',
+            'switch', 'while', 'delete', 'new', 'this'
+            ),
+        2 => array(
+            'NULL', 'false', 'break', 'true', 'enum', 'errno', 'EDOM',
+            'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+            'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+            'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+            'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+            'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+            'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+            'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+            'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+            'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+            'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+            'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+            'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+            'try', 'catch', 'inline', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+            'static_cast', 'explicit', 'friend', 'wchar_t', 'typename', 'typeid', 'class' ,
+            'foreach','connect', 'Q_OBJECT' , 'slots' , 'signals'
+            ),
+        3 => array(
+            'cin', 'cerr', 'clog', 'cout',
+            'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+            'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+            'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+            'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+            'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+            'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+            'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+            'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+            'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+            'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+            'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+            'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+            'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+            'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+            'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+            'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+            'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+            'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+            'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+            ),
+        4 => array(
+            'auto', 'bool', 'char', 'const', 'double', 'float', 'int', 'long', 'longint',
+            'register', 'short', 'shortint', 'signed', 'static', 'struct',
+            'typedef', 'union', 'unsigned', 'void', 'volatile', 'extern', 'jmp_buf',
+            'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+            'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm',
+            ),
+        5 => array(
+            'QAbstractButton','QDir','QIntValidator','QRegExpValidator','QTabWidget','QAbstractEventDispatcher',
+            'QDirectPainter','QIODevice','QRegion','QTcpServer','QAbstractExtensionFactory','QDirModel',
+            'QItemDelegate','QResizeEvent','QTcpSocket','QAbstractExtensionManager','QDockWidget',
+            'QItemEditorCreatorBase','QResource','QTemporaryFile','QAbstractFileEngine','QDomAttr',
+            'QItemEditorFactory','QRubberBand','QTestEventList','QAbstractFileEngineHandler','QDomCDATASection',
+            'QItemSelection','QScreen','QTextBlock','QAbstractFormBuilder','QDomCharacterData','QItemSelectionModel',
+            'QScreenCursor','QTextBlockFormat','QAbstractGraphicsShapeItem','QDomComment','QItemSelectionRange',
+            'QScreenDriverFactory','QTextBlockGroup','QAbstractItemDelegate','QDomDocument','QKbdDriverFactory',
+            'QScreenDriverPlugin','QTextBlockUserData','QAbstractItemModel','QDomDocumentFragment','QKbdDriverPlugin',
+            'QScrollArea','QTextBrowser','QAbstractItemView','QDomDocumentType','QKeyEvent','QScrollBar',
+            'QTextCharFormat','QAbstractListModel','QDomElement','QKeySequence','QSemaphore','QTextCodec',
+            'QAbstractPrintDialog','QDomEntity','QLabel','QSessionManager','QTextCodecPlugin','QAbstractProxyModel',
+            'QDomEntityReference','QLatin1Char','QSet','QTextCursor','QAbstractScrollArea','QDomImplementation',
+            'QLatin1String','QSetIterator','QTextDecoder','QAbstractSlider','QDomNamedNodeMap','QLayout','QSettings',
+            'QTextDocument','QAbstractSocket','QDomNode','QLayoutItem','QSharedData','QTextDocumentFragment',
+            'QAbstractSpinBox','QDomNodeList','QLCDNumber','QSharedDataPointer','QTextEdit','QAbstractTableModel',
+            'QDomNotation','QLibrary','QShortcut','QTextEncoder','QAbstractTextDocumentLayout',
+            'QDomProcessingInstruction','QLibraryInfo','QShortcutEvent','QTextFormat','QAccessible','QDomText',
+            'QLine','QShowEvent','QTextFragment','QAccessibleBridge','QDoubleSpinBox','QLinearGradient',
+            'QSignalMapper','QTextFrame','QAccessibleBridgePlugin','QDoubleValidator','QLineEdit','QSignalSpy',
+            'QTextFrameFormat','QAccessibleEvent','QDrag','QLineF','QSize','QTextImageFormat','QAccessibleInterface',
+            'QDragEnterEvent','QLinkedList','QSizeF','QTextInlineObject','QAccessibleObject','QDragLeaveEvent',
+            'QLinkedListIterator','QSizeGrip','QTextLayout','QAccessiblePlugin','QDragMoveEvent','QLinuxFbScreen',
+            'QSizePolicy','QTextLength','QAccessibleWidget','QDropEvent','QList','QSlider','QTextLine','QAction',
+            'QDynamicPropertyChangeEvent','QListIterator','QSocketNotifier','QTextList','QActionEvent','QErrorMessage',
+            'QListView','QSortFilterProxyModel','QTextListFormat','QActionGroup','QEvent','QListWidget','QSound',
+            'QTextObject','QApplication','QEventLoop','QListWidgetItem','QSpacerItem','QTextOption','QAssistantClient',
+            'QExtensionFactory','QLocale','QSpinBox','QTextStream','QAxAggregated','QExtensionManager',
+            'QMacPasteboardMime','QSplashScreen','QTextTable','QAxBase','QFile','QMacStyle','QSplitter',
+            'QTextTableCell','QAxBindable','QFileDialog','QMainWindow','QSplitterHandle','QTextTableFormat',
+            'QAxFactory','QFileIconProvider','QMap','QSqlDatabase','QThread','QAxObject','QFileInfo','QMapIterator',
+            'QSqlDriver','QThreadStorage','QAxScript','QFileOpenEvent','QMatrix','QSqlDriverCreator','QTime',
+            'QAxScriptEngine','QFileSystemWatcher','QMenu','QSqlDriverCreatorBase','QTimeEdit','QAxScriptManager',
+            'QFlag','QMenuBar','QSqlDriverPlugin','QTimeLine','QAxWidget','QFlags','QMessageBox','QSqlError','QTimer',
+            'QBasicTimer','QFocusEvent','QMetaClassInfo','QSqlField','QTimerEvent','QBitArray','QFocusFrame',
+            'QMetaEnum','QSqlIndex','QToolBar','QBitmap','QFont','QMetaMethod','QSqlQuery','QToolBox','QBoxLayout',
+            'QFontComboBox','QMetaObject','QSqlQueryModel','QToolButton','QBrush','QFontDatabase','QMetaProperty',
+            'QSqlRecord','QToolTip','QBuffer','QFontDialog','QMetaType','QSqlRelation','QTransformedScreen',
+            'QButtonGroup','QFontInfo','QMimeData','QSqlRelationalDelegate','QTranslator','QByteArray','QFontMetrics',
+            'QMimeSource','QSqlRelationalTableModel','QTreeView','QByteArrayMatcher','QFontMetricsF','QModelIndex',
+            'QSqlResult','QTreeWidget','QCache','QFormBuilder','QMotifStyle','QSqlTableModel','QTreeWidgetItem',
+            'QCalendarWidget','QFrame','QMouseDriverFactory','QStack','QTreeWidgetItemIterator','QCDEStyle',
+            'QFSFileEngine','QMouseDriverPlugin','QStackedLayout','QUdpSocket','QChar','QFtp','QMouseEvent',
+            'QStackedWidget','QUiLoader','QCheckBox','QGenericArgument','QMoveEvent','QStandardItem','QUndoCommand',
+            'QChildEvent','QGenericReturnArgument','QMovie','QStandardItemEditorCreator','QUndoGroup',
+            'QCleanlooksStyle','QGLColormap','QMultiHash','QStandardItemModel','QUndoStack','QClipboard',
+            'QGLContext','QMultiMap','QStatusBar','QUndoView','QCloseEvent','QGLFormat','QMutableHashIterator',
+            'QStatusTipEvent','QUrl','QColor','QGLFramebufferObject','QMutableLinkedListIterator','QString',
+            'QUrlInfo','QColorDialog','QGLPixelBuffer','QMutableListIterator','QStringList','QUuid','QColormap',
+            'QGLWidget','QMutableMapIterator','QStringListModel','QValidator','QComboBox','QGradient',
+            'QMutableSetIterator','QStringMatcher','QVariant','QCommonStyle','QGraphicsEllipseItem',
+            'QMutableVectorIterator','QStyle','QVarLengthArray','QCompleter','QGraphicsItem','QMutex',
+            'QStyleFactory','QVBoxLayout','QConicalGradient','QGraphicsItemAnimation','QMutexLocker',
+            'QStyleHintReturn','QVector','QContextMenuEvent','QGraphicsItemGroup','QNetworkAddressEntry',
+            'QStyleHintReturnMask','QVectorIterator','QCopChannel','QGraphicsLineItem','QNetworkInterface',
+            'QStyleOption','QVFbScreen','QCoreApplication','QGraphicsPathItem','QNetworkProxy','QStyleOptionButton',
+            'QVNCScreen','QCursor','QGraphicsPixmapItem','QObject','QStyleOptionComboBox','QWaitCondition',
+            'QCustomRasterPaintDevice','QGraphicsPolygonItem','QObjectCleanupHandler','QStyleOptionComplex',
+            'QWhatsThis','QDataStream','QGraphicsRectItem','QPageSetupDialog','QStyleOptionDockWidget',
+            'QWhatsThisClickedEvent','QDataWidgetMapper','QGraphicsScene','QPaintDevice','QStyleOptionFocusRect',
+            'QWheelEvent','QDate','QGraphicsSceneContextMenuEvent','QPaintEngine','QStyleOptionFrame','QWidget',
+            'QDateEdit','QGraphicsSceneEvent','QPaintEngineState','QStyleOptionFrameV2','QWidgetAction','QDateTime',
+            'QGraphicsSceneHoverEvent','QPainter','QStyleOptionGraphicsItem','QWidgetItem','QDateTimeEdit',
+            'QGraphicsSceneMouseEvent','QPainterPath','QStyleOptionGroupBox','QWindowsMime','QDBusAbstractAdaptor',
+            'QGraphicsSceneWheelEvent','QPainterPathStroker','QStyleOptionHeader','QWindowsStyle',
+            'QDBusAbstractInterface','QGraphicsSimpleTextItem','QPaintEvent','QStyleOptionMenuItem',
+            'QWindowStateChangeEvent','QDBusArgument','QGraphicsSvgItem','QPair','QStyleOptionProgressBar',
+            'QWindowsXPStyle','QDBusConnection','QGraphicsTextItem','QPalette','QStyleOptionProgressBarV2',
+            'QWorkspace','QDBusConnectionInterface','QGraphicsView','QPen','QStyleOptionQ3DockWindow','QWriteLocker',
+            'QDBusError','QGridLayout','QPersistentModelIndex','QStyleOptionQ3ListView','QWSCalibratedMouseHandler',
+            'QDBusInterface','QGroupBox','QPicture','QStyleOptionQ3ListViewItem','QWSClient','QDBusMessage','QHash',
+            'QPictureFormatPlugin','QStyleOptionRubberBand','QWSEmbedWidget','QDBusObjectPath','QHashIterator',
+            'QPictureIO','QStyleOptionSizeGrip','QWSEvent','QDBusReply','QHBoxLayout','QPixmap','QStyleOptionSlider',
+            'QWSInputMethod','QDBusServer','QHeaderView','QPixmapCache','QStyleOptionSpinBox','QWSKeyboardHandler',
+            'QDBusSignature','QHelpEvent','QPlastiqueStyle','QStyleOptionTab','QWSMouseHandler','QDBusVariant',
+            'QHideEvent','QPluginLoader','QStyleOptionTabBarBase','QWSPointerCalibrationData','QDecoration',
+            'QHostAddress','QPoint','QStyleOptionTabV2','QWSScreenSaver','QDecorationFactory','QHostInfo','QPointer',
+            'QStyleOptionTabWidgetFrame','QWSServer','QDecorationPlugin','QHoverEvent','QPointF','QStyleOptionTitleBar',
+            'QWSTslibMouseHandler','QDesignerActionEditorInterface','QHttp','QPolygon','QStyleOptionToolBar','QWSWindow',
+            'QDesignerContainerExtension','QHttpHeader','QPolygonF','QStyleOptionToolBox','QWSWindowSurface',
+            'QDesignerCustomWidgetCollectionInterface','QHttpRequestHeader','QPrintDialog','QStyleOptionToolButton',
+            'QX11EmbedContainer','QDesignerCustomWidgetInterface','QHttpResponseHeader','QPrintEngine',
+            'QStyleOptionViewItem','QX11EmbedWidget','QDesignerFormEditorInterface','QIcon','QPrinter',
+            'QStyleOptionViewItemV2','QX11Info','QDesignerFormWindowCursorInterface','QIconDragEvent','QProcess',
+            'QStylePainter','QXmlAttributes','QDesignerFormWindowInterface','QIconEngine','QProgressBar',
+            'QStylePlugin','QXmlContentHandler','QDesignerFormWindowManagerInterface','QIconEnginePlugin',
+            'QProgressDialog','QSvgRenderer','QXmlDeclHandler','QDesignerMemberSheetExtension','QImage',
+            'QProxyModel','QSvgWidget','QXmlDefaultHandler','QDesignerObjectInspectorInterface','QImageIOHandler',
+            'QPushButton','QSyntaxHighlighter','QXmlDTDHandler','QDesignerPropertyEditorInterface','QImageIOPlugin',
+            'QQueue','QSysInfo','QXmlEntityResolver','QDesignerPropertySheetExtension','QImageReader','QRadialGradient',
+            'QSystemLocale','QXmlErrorHandler','QDesignerTaskMenuExtension','QImageWriter','QRadioButton',
+            'QSystemTrayIcon','QXmlInputSource','QDesignerWidgetBoxInterface','QInputContext','QRasterPaintEngine',
+            'QTabBar','QXmlLexicalHandler','QDesktopServices','QInputContextFactory','QReadLocker','QTabletEvent',
+            'QXmlLocator','QDesktopWidget','QInputContextPlugin','QReadWriteLock','QTableView','QXmlNamespaceSupport',
+            'QDial','QInputDialog','QRect','QTableWidget','QXmlParseException','QDialog','QInputEvent','QRectF',
+            'QTableWidgetItem','QXmlReader','QDialogButtonBox','QInputMethodEvent','QRegExp',
+            'QTableWidgetSelectionRange','QXmlSimpleReader'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':', ',', ';', '|', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight:bold;',
+            2 => 'color: #0057AE;',
+            3 => 'color: #2B74C7;',
+            4 => 'color: #0057AE;',
+            5 => 'color: #22aadd;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #888888;',
+            2 => 'color: #006E28;',
+            'MULTI' => 'color: #888888; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #660099; font-weight: bold;',
+            3 => 'color: #660099; font-weight: bold;',
+            4 => 'color: #660099; font-weight: bold;',
+            5 => 'color: #006699; font-weight: bold;',
+            'HARD' => '',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #006E28;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #BF0303;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #B08000;',
+            GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #2B74C7;',
+            2 => 'color: #2B74C7;',
+            3 => 'color: #2B74C7;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #006E28;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => 'http://doc.trolltech.com/latest/{FNAMEL}.html'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::',
+        3 => '-&gt;',
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+            'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-])"
+        ),
+        'OOLANG' => array(
+            'MATCH_AFTER' => '~?[a-zA-Z][a-zA-Z0-9_]*',
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/cpp.php b/examples/includes/geshi/geshi/cpp.php
new file mode 100644 (file)
index 0000000..28b585d
--- /dev/null
@@ -0,0 +1,226 @@
+<?php
+/*************************************************************************************
+ * cpp.php
+ * -------
+ * Author: Dennis Bayer (Dennis.Bayer@mnifh-giessen.de)
+ * Contributors:
+ *  - M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ *  - Jack Lloyd (lloyd@randombit.net)
+ * Copyright: (c) 2004 Dennis Bayer, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/09/27
+ *
+ * C++ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/XX/XX (1.0.2)
+ *  -  Added several new keywords (Jack Lloyd)
+ * 2004/11/27 (1.0.1)
+ *  -  Added StdCLib function and constant names, changed color scheme to
+ *     a cleaner one. (M. Uli Kusterer)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'C++',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Multiline-continued single-line comments
+        1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        //Multiline-continued preprocessor define
+        2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[abfnrtv\\'\"?\n]#i",
+        //Hexadecimal Char Specs
+        2 => "#\\\\x[\da-fA-F]{2}#",
+        //Hexadecimal Char Specs
+        3 => "#\\\\u[\da-fA-F]{4}#",
+        //Hexadecimal Char Specs
+        4 => "#\\\\U[\da-fA-F]{8}#",
+        //Octal Char Specs
+        5 => "#\\\\[0-7]{1,3}#"
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+        GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'break', 'case', 'continue', 'default', 'do', 'else', 'for', 'goto', 'if', 'return',
+            'switch', 'throw', 'while'
+            ),
+        2 => array(
+            'NULL', 'false', 'true', 'enum', 'errno', 'EDOM',
+            'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+            'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+            'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+            'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+            'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+            'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+            'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+            'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+            'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+            'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+            'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+            'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+            'try', 'catch', 'inline', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+            'static_cast', 'explicit', 'friend', 'wchar_t', 'typename', 'typeid', 'class'
+            ),
+        3 => array(
+            'cin', 'cerr', 'clog', 'cout', 'delete', 'new', 'this',
+            'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+            'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+            'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+            'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+            'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+            'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+            'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+            'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+            'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+            'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+            'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+            'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+            'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+            'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+            'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+            'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+            'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+            'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+            'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+            ),
+        4 => array(
+            'auto', 'bool', 'char', 'const', 'double', 'float', 'int', 'long', 'longint',
+            'register', 'short', 'shortint', 'signed', 'static', 'struct',
+            'typedef', 'union', 'unsigned', 'void', 'volatile', 'extern', 'jmp_buf',
+            'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+            'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm',
+            ),
+        ),
+    'SYMBOLS' => array(
+        0 => array('(', ')', '{', '}', '[', ']'),
+        1 => array('<', '>','='),
+        2 => array('+', '-', '*', '/', '%'),
+        3 => array('!', '^', '&', '|'),
+        4 => array('?', ':', ';')
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #0000dd;',
+            4 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666;',
+            2 => 'color: #339900;',
+            'MULTI' => 'color: #ff0000; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #660099; font-weight: bold;',
+            3 => 'color: #660099; font-weight: bold;',
+            4 => 'color: #660099; font-weight: bold;',
+            5 => 'color: #006699; font-weight: bold;',
+            'HARD' => '',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #008000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000dd;',
+            GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #007788;',
+            2 => 'color: #007788;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;',
+            1 => 'color: #000080;',
+            2 => 'color: #000040;',
+            3 => 'color: #000040;',
+            4 => 'color: #008080;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#])",
+            'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-])"
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/csharp.php b/examples/includes/geshi/geshi/csharp.php
new file mode 100644 (file)
index 0000000..2d79ee2
--- /dev/null
@@ -0,0 +1,249 @@
+<?php
+/*************************************************************************************
+ * csharp.php
+ * ----------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * C# language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/25 (1.0.7.22)
+ *   -  Added highlighting of using and namespace directives as non-OOP
+ * 2005/01/05 (1.0.1)
+ *  -  Used hardquote support for @"..." strings (Cliff Stanford)
+ * 2004/11/27 (1.0.0)
+ *  -  Initial release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'C#',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Using and Namespace directives (basic support)
+        //Please note that the alias syntax for using is not supported
+        3 => '/(?:(?<=using[\\n\\s])|(?<=namespace[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*[a-zA-Z0-9_]+[\n\s]*(?=[;=])/i'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'HARDQUOTE' => array('@"', '"'),
+    'HARDESCAPE' => array('""'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'as', 'auto', 'base', 'break', 'case', 'catch', 'const', 'continue',
+            'default', 'do', 'else', 'event', 'explicit', 'extern', 'false',
+            'finally', 'fixed', 'for', 'foreach', 'goto', 'if', 'implicit',
+            'in', 'internal', 'lock', 'namespace', 'null', 'operator', 'out',
+            'override', 'params', 'partial', 'private', 'protected', 'public',
+            'readonly', 'ref', 'return', 'sealed', 'stackalloc', 'static',
+            'switch', 'this', 'throw', 'true', 'try', 'unsafe', 'using',
+            'virtual', 'void', 'while'
+            ),
+        2 => array(
+            '#elif', '#endif', '#endregion', '#else', '#error', '#define', '#if',
+            '#line', '#region', '#undef', '#warning'
+            ),
+        3 => array(
+            'checked', 'is', 'new', 'sizeof', 'typeof', 'unchecked'
+            ),
+        4 => array(
+            'bool', 'byte', 'char', 'class', 'decimal', 'delegate', 'double',
+            'enum', 'float', 'int', 'interface', 'long', 'object', 'sbyte',
+            'short', 'string', 'struct', 'uint', 'ulong', 'ushort'
+            ),
+        5 => array(
+            'Microsoft.Win32',
+            'System',
+            'System.CodeDOM',
+            'System.CodeDOM.Compiler',
+            'System.Collections',
+            'System.Collections.Bases',
+            'System.ComponentModel',
+            'System.ComponentModel.Design',
+            'System.ComponentModel.Design.CodeModel',
+            'System.Configuration',
+            'System.Configuration.Assemblies',
+            'System.Configuration.Core',
+            'System.Configuration.Install',
+            'System.Configuration.Interceptors',
+            'System.Configuration.Schema',
+            'System.Configuration.Web',
+            'System.Core',
+            'System.Data',
+            'System.Data.ADO',
+            'System.Data.Design',
+            'System.Data.Internal',
+            'System.Data.SQL',
+            'System.Data.SQLTypes',
+            'System.Data.XML',
+            'System.Data.XML.DOM',
+            'System.Data.XML.XPath',
+            'System.Data.XML.XSLT',
+            'System.Diagnostics',
+            'System.Diagnostics.SymbolStore',
+            'System.DirectoryServices',
+            'System.Drawing',
+            'System.Drawing.Design',
+            'System.Drawing.Drawing2D',
+            'System.Drawing.Imaging',
+            'System.Drawing.Printing',
+            'System.Drawing.Text',
+            'System.Globalization',
+            'System.IO',
+            'System.IO.IsolatedStorage',
+            'System.Messaging',
+            'System.Net',
+            'System.Net.Sockets',
+            'System.NewXml',
+            'System.NewXml.XPath',
+            'System.NewXml.Xsl',
+            'System.Reflection',
+            'System.Reflection.Emit',
+            'System.Resources',
+            'System.Runtime.InteropServices',
+            'System.Runtime.InteropServices.Expando',
+            'System.Runtime.Remoting',
+            'System.Runtime.Serialization',
+            'System.Runtime.Serialization.Formatters',
+            'System.Runtime.Serialization.Formatters.Binary',
+            'System.Security',
+            'System.Security.Cryptography',
+            'System.Security.Cryptography.X509Certificates',
+            'System.Security.Permissions',
+            'System.Security.Policy',
+            'System.Security.Principal',
+            'System.ServiceProcess',
+            'System.Text',
+            'System.Text.RegularExpressions',
+            'System.Threading',
+            'System.Timers',
+            'System.Web',
+            'System.Web.Caching',
+            'System.Web.Configuration',
+            'System.Web.Security',
+            'System.Web.Services',
+            'System.Web.Services.Description',
+            'System.Web.Services.Discovery',
+            'System.Web.Services.Protocols',
+            'System.Web.UI',
+            'System.Web.UI.Design',
+            'System.Web.UI.Design.WebControls',
+            'System.Web.UI.Design.WebControls.ListControls',
+            'System.Web.UI.HtmlControls',
+            'System.Web.UI.WebControls',
+            'System.WinForms',
+            'System.WinForms.ComponentModel',
+            'System.WinForms.Design',
+            'System.Xml',
+            'System.Xml.Serialization',
+            'System.Xml.Serialization.Code',
+            'System.Xml.Serialization.Schema'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!', ':', ';',
+        '(', ')', '{', '}', '[', ']', '|'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0600FF;',
+            2 => 'color: #FF8000; font-weight: bold;',
+            3 => 'color: #008000;',
+            4 => 'color: #FF0000;',
+            5 => 'color: #000000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008080; font-style: italic;',
+            2 => 'color: #008080;',
+            3 => 'color: #008080;',
+            'MULTI' => 'color: #008080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008080; font-weight: bold;',
+            'HARD' => 'color: #008080; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #666666;',
+            'HARD' => 'color: #666666;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000FF;',
+            2 => 'color: #0000FF;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.google.com/search?q={FNAMEL}+msdn.microsoft.com',
+        4 => '',
+        5 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+            'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-])"
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/css.php b/examples/includes/geshi/geshi/css.php
new file mode 100644 (file)
index 0000000..0080325
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+/*************************************************************************************
+ * css.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/18
+ *
+ * CSS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.3)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ *   -  Changed regexps to catch "-" symbols
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.1)
+ *   -  Added support for symbols
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Improve or drop regexps for class/id/psuedoclass highlighting
+ * * Re-look at keywords - possibly to make several CSS language
+ *   files, all with different versions of CSS in them
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'CSS',
+    'COMMENT_SINGLE' => array(1 => '@'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        2 => "/(?<=\\()\\s*(?:(?:[a-z0-9]+?:\\/\\/)?[a-z0-9_\\-\\.\\/:]+?)?[a-z]+?\\.[a-z]+?(\\?[^\)]+?)?\\s*?(?=\\))/i"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', "'"),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'aqua', 'azimuth', 'background-attachment', 'background-color',
+            'background-image', 'background-position', 'background-repeat',
+            'background', 'black', 'blue', 'border-bottom-color',
+            'border-bottom-style', 'border-bottom-width', 'border-left-color',
+            'border-left-style', 'border-left-width', 'border-right',
+            'border-right-color', 'border-right-style', 'border-right-width',
+            'border-top-color', 'border-top-style',
+            'border-top-width','border-bottom', 'border-collapse',
+            'border-left', 'border-width', 'border-color', 'border-spacing',
+            'border-style', 'border-top', 'border', 'caption-side', 'clear',
+            'clip', 'color', 'content', 'counter-increment', 'counter-reset',
+            'cue-after', 'cue-before', 'cue', 'cursor', 'direction', 'display',
+            'elevation', 'empty-cells', 'float', 'font-family', 'font-size',
+            'font-size-adjust', 'font-stretch', 'font-style', 'font-variant',
+            'font-weight', 'font', 'line-height', 'letter-spacing',
+            'list-style', 'list-style-image', 'list-style-position',
+            'list-style-type', 'margin-bottom', 'margin-left', 'margin-right',
+            'margin-top', 'margin', 'marker-offset', 'marks', 'max-height',
+            'max-width', 'min-height', 'min-width', 'orphans', 'outline',
+            'outline-color', 'outline-style', 'outline-width', 'overflow',
+            'padding-bottom', 'padding-left', 'padding-right', 'padding-top',
+            'padding', 'page', 'page-break-after', 'page-break-before',
+            'page-break-inside', 'pause-after', 'pause-before', 'pause',
+            'pitch', 'pitch-range', 'play-during', 'position', 'quotes',
+            'richness', 'right', 'size', 'speak-header', 'speak-numeral',
+            'speak-punctuation', 'speak', 'speech-rate', 'stress',
+            'table-layout', 'text-align', 'text-decoration', 'text-indent',
+            'text-shadow', 'text-transform', 'top', 'unicode-bidi',
+            'vertical-align', 'visibility', 'voice-family', 'volume',
+            'white-space', 'widows', 'width', 'word-spacing', 'z-index',
+            'bottom', 'left', 'height'
+            ),
+        2 => array(
+            'above', 'absolute', 'always', 'armenian', 'aural', 'auto',
+            'avoid', 'baseline', 'behind', 'below', 'bidi-override', 'blink',
+            'block', 'bold', 'bolder', 'both', 'capitalize', 'center-left',
+            'center-right', 'center', 'circle', 'cjk-ideographic',
+            'close-quote', 'collapse', 'condensed', 'continuous', 'crop',
+            'crosshair', 'cross', 'cursive', 'dashed', 'decimal-leading-zero',
+            'decimal', 'default', 'digits', 'disc', 'dotted', 'double',
+            'e-resize', 'embed', 'extra-condensed', 'extra-expanded',
+            'expanded', 'fantasy', 'far-left', 'far-right', 'faster', 'fast',
+            'fixed', 'fuchsia', 'georgian', 'gray', 'green', 'groove',
+            'hebrew', 'help', 'hidden', 'hide', 'higher', 'high',
+            'hiragana-iroha', 'hiragana', 'icon', 'inherit', 'inline-table',
+            'inline', 'inset', 'inside', 'invert', 'italic', 'justify',
+            'katakana-iroha', 'katakana', 'landscape', 'larger', 'large',
+            'left-side', 'leftwards', 'level', 'lighter', 'lime',
+            'line-through', 'list-item', 'loud', 'lower-alpha', 'lower-greek',
+            'lower-roman', 'lowercase', 'ltr', 'lower', 'low', 'maroon',
+            'medium', 'message-box', 'middle', 'mix', 'monospace', 'n-resize',
+            'narrower', 'navy', 'ne-resize', 'no-close-quote',
+            'no-open-quote', 'no-repeat', 'none', 'normal', 'nowrap',
+            'nw-resize', 'oblique', 'olive', 'once', 'open-quote', 'outset',
+            'outside', 'overline', 'pointer', 'portrait', 'purple', 'px',
+            'red', 'relative', 'repeat-x', 'repeat-y', 'repeat', 'rgb',
+            'ridge', 'right-side', 'rightwards', 's-resize', 'sans-serif',
+            'scroll', 'se-resize', 'semi-condensed', 'semi-expanded',
+            'separate', 'serif', 'show', 'silent', 'silver', 'slow', 'slower',
+            'small-caps', 'small-caption', 'smaller', 'soft', 'solid',
+            'spell-out', 'square', 'static', 'status-bar', 'super',
+            'sw-resize', 'table-caption', 'table-cell', 'table-column',
+            'table-column-group', 'table-footer-group', 'table-header-group',
+            'table-row', 'table-row-group', 'teal', 'text', 'text-bottom',
+            'text-top', 'thick', 'thin', 'transparent', 'ultra-condensed',
+            'ultra-expanded', 'underline', 'upper-alpha', 'upper-latin',
+            'upper-roman', 'uppercase', 'url', 'visible', 'w-resize', 'wait',
+            'white', 'wider', 'x-fast', 'x-high', 'x-large', 'x-loud',
+            'x-low', 'x-small', 'x-soft', 'xx-large', 'xx-small', 'yellow',
+            'yes'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', ':', ';',
+        '>', '+', '*', ',', '^', '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #993333;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #a1a100;',
+            2 => 'color: #ff0000; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #00AA00;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #00AA00;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #cc00cc;',
+            1 => 'color: #6666ff;',
+            2 => 'color: #3333ff;',
+            3 => 'color: #933;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //DOM Node ID
+        0 => '\#[a-zA-Z0-9\-_]+(?:\\\\:[a-zA-Z0-9\-_]+)*',
+        //CSS classname
+        1 => '\.(?!\d)[a-zA-Z0-9\-_]+(?:\\\\:[a-zA-Z0-9\-_]+)*\b(?=[\{\.#\s,:].|<\|)',
+        //CSS Pseudo classes
+        //note: & is needed for &gt; (i.e. > )
+        2 => '(?<!\\\\):(?!\d)[a-zA-Z0-9\-]+\b(?:\s*(?=[\{\.#a-zA-Z,:+*&](.|\n)|<\|))',
+        //Measurements
+        3 => '[+\-]?(\d+|(\d*\.\d+))(em|ex|pt|px|cm|in|%)',
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-&\.])'
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/d.php b/examples/includes/geshi/geshi/d.php
new file mode 100644 (file)
index 0000000..9711a6e
--- /dev/null
@@ -0,0 +1,272 @@
+<?php
+/*************************************************************************************
+ * d.php
+ * -----
+ * Author: Thomas Kuehne (thomas@kuehne.cn)
+ * Copyright: (c) 2005 Thomas Kuehne (http://thomas.kuehne.cn/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/04/22
+ *
+ * D language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/04/22 (0.0.2)
+ *  -  added _d_* and sizeof/ptrdiff_t
+ * 2005/04/20 (0.0.1)
+ *  -  First release
+ *
+ * TODO (updated 2005/04/22)
+ * -------------------------
+ * * nested comments
+ * * correct handling of r"" and ``
+ * * correct handling of ... and ..
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'D',
+    'COMMENT_SINGLE' => array(2 => '///', 1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        // doxygen comments
+        3 => '#/\*\*(?![\*\/]).*\*/#sU',
+        // raw strings
+        4 => '#r"[^"]*"#s',
+        // Script Style interpreter comment
+        5 => "/\A#!(?=\\/).*?$/m"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', "'"),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[abfnrtv\\'\"?\n\\\\]#i",
+        //Hexadecimal Char Specs
+        2 => "#\\\\x[\da-fA-F]{2}#",
+        //Hexadecimal Char Specs
+        3 => "#\\\\u[\da-fA-F]{4}#",
+        //Hexadecimal Char Specs
+        4 => "#\\\\U[\da-fA-F]{8}#",
+        //Octal Char Specs
+        5 => "#\\\\[0-7]{1,3}#",
+        //Named entity escapes
+        /*6 => "#\\\\&(?:quot|amp|lt|gt|OElig|oelig|Scaron|scaron|Yuml|circ|tilde|".
+            "ensp|emsp|thinsp|zwnj|zwj|lrm|rlm|ndash|mdash|lsquo|rsquo|sbquo|".
+            "ldquo|rdquo|bdquo|dagger|Dagger|permil|lsaquo|rsaquo|euro|nbsp|".
+            "iexcl|cent|pound|curren|yen|brvbar|sect|uml|copy|ordf|laquo|not|".
+            "shy|reg|macr|deg|plusmn|sup2|sup3|acute|micro|para|middot|cedil|".
+            "sup1|ordm|raquo|frac14|frac12|frac34|iquest|Agrave|Aacute|Acirc|".
+            "Atilde|Auml|Aring|AElig|Ccedil|Egrave|Eacute|Ecirc|Euml|Igrave|".
+            "Iacute|Icirc|Iuml|ETH|Ntilde|Ograve|Oacute|Ocirc|Otilde|Ouml|".
+            "times|Oslash|Ugrave|Uacute|Ucirc|Uuml|Yacute|THORN|szlig|agrave|".
+            "aacute|acirc|atilde|auml|aring|aelig|ccedil|egrave|eacute|ecirc|".
+            "euml|igrave|iacute|icirc|iuml|eth|ntilde|ograve|oacute|ocirc|".
+            "otilde|ouml|divide|oslash|ugrave|uacute|ucirc|uuml|yacute|thorn|".
+            "yuml|fnof|Alpha|Beta|Gamma|Delta|Epsilon|Zeta|Eta|Theta|Iota|".
+            "Kappa|Lambda|Mu|Nu|Xi|Omicron|Pi|Rho|Sigma|Tau|Upsilon|Phi|Chi|".
+            "Psi|Omega|alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|".
+            "kappa|lambda|mu|nu|xi|omicron|pi|rho|sigmaf|sigma|tau|upsilon|".
+            "phi|chi|psi|omega|thetasym|upsih|piv|bull|hellip|prime|Prime|".
+            "oline|frasl|weierp|image|real|trade|alefsym|larr|uarr|rarr|darr|".
+            "harr|crarr|lArr|uArr|rArr|dArr|hArr|forall|part|exist|empty|".
+            "nabla|isin|notin|ni|prod|sum|minus|lowast|radic|prop|infin|ang|".
+            "and|or|cap|cup|int|there4|sim|cong|asymp|ne|equiv|le|ge|sub|sup|".
+            "nsub|sube|supe|oplus|otimes|perp|sdot|lceil|rceil|lfloor|rfloor|".
+            "lang|rang|loz|spades|clubs|hearts|diams);#",*/
+        // optimized:
+        6 => "#\\\\&(?:A(?:Elig|acute|circ|grave|lpha|ring|tilde|uml)|Beta|".
+            "C(?:cedil|hi)|D(?:agger|elta)|E(?:TH|acute|circ|grave|psilon|ta|uml)|".
+            "Gamma|I(?:acute|circ|grave|ota|uml)|Kappa|Lambda|Mu|N(?:tilde|u)|".
+            "O(?:Elig|acute|circ|grave|m(?:ega|icron)|slash|tilde|uml)|".
+            "P(?:hi|i|rime|si)|Rho|S(?:caron|igma)|T(?:HORN|au|heta)|".
+            "U(?:acute|circ|grave|psilon|uml)|Xi|Y(?:acute|uml)|Zeta|".
+            "a(?:acute|c(?:irc|ute)|elig|grave|l(?:efsym|pha)|mp|n[dg]|ring|".
+            "symp|tilde|uml)|b(?:dquo|eta|rvbar|ull)|c(?:ap|cedil|e(?:dil|nt)|".
+            "hi|irc|lubs|o(?:ng|py)|rarr|u(?:p|rren))|d(?:Arr|a(?:gger|rr)|".
+            "e(?:g|lta)|i(?:ams|vide))|e(?:acute|circ|grave|m(?:pty|sp)|nsp|".
+            "psilon|quiv|t[ah]|u(?:ml|ro)|xist)|f(?:nof|orall|ra(?:c(?:1[24]|34)|sl))|".
+            "g(?:amma|e|t)|h(?:Arr|arr|e(?:arts|llip))|i(?:acute|circ|excl|grave|mage|".
+            "n(?:fin|t)|ota|quest|sin|uml)|kappa|l(?:Arr|a(?:mbda|ng|quo|rr)|ceil|".
+            "dquo|e|floor|o(?:wast|z)|rm|s(?:aquo|quo)|t)|m(?:acr|dash|".
+            "i(?:cro|ddot|nus)|u)|n(?:abla|bsp|dash|e|i|ot(?:in)?|sub|tilde|u)|".
+            "o(?:acute|circ|elig|grave|line|m(?:ega|icron)|plus|r(?:d[fm])?|".
+            "slash|ti(?:lde|mes)|uml)|p(?:ar[at]|er(?:mil|p)|hi|iv?|lusmn|ound|".
+            "r(?:ime|o[dp])|si)|quot|r(?:Arr|a(?:dic|ng|quo|rr)|ceil|dquo|e(?:al|g)|".
+            "floor|ho|lm|s(?:aquo|quo))|s(?:bquo|caron|dot|ect|hy|i(?:gmaf?|m)|".
+            "pades|u(?:be?|m|p[123e]?)|zlig)|t(?:au|h(?:e(?:re4|ta(?:sym)?)|insp|".
+            "orn)|i(?:lde|mes)|rade)|u(?:Arr|a(?:cute|rr)|circ|grave|ml|".
+            "psi(?:h|lon)|uml)|weierp|xi|y(?:acute|en|uml)|z(?:eta|w(?:j|nj)));#",
+        ),
+    'HARDQUOTE' => array('`', '`'),
+    'HARDESCAPE' => array(),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+        GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+                'break', 'case', 'continue', 'do', 'else',
+                'for', 'foreach', 'goto', 'if', 'return',
+                'switch', 'while'
+            ),
+        2 => array(
+                'alias', 'asm', 'assert', 'body', 'cast',
+                'catch', 'default', 'delegate', 'delete',
+                'extern', 'false', 'finally', 'function',
+                'import', 'in', 'inout', 'interface',
+                'invariant', 'is', 'mixin', 'module', 'new',
+                'null', 'out', 'pragma', 'ref', 'super', 'this',
+                'throw', 'true', 'try', 'typedef', 'typeid',
+                'typeof', 'union', 'with'
+            ),
+        3 => array(
+                'ArrayBoundsError', 'AssertError',
+                'ClassInfo', 'Error', 'Exception',
+                'Interface', 'ModuleInfo', 'Object',
+                'OutOfMemoryException', 'SwitchError',
+                'TypeInfo', '_d_arrayappend',
+                '_d_arrayappendb', '_d_arrayappendc',
+                '_d_arrayappendcb', '_d_arraycast',
+                '_d_arraycast_frombit', '_d_arraycat',
+                '_d_arraycatb', '_d_arraycatn',
+                '_d_arraycopy', '_d_arraycopybit',
+                '_d_arraysetbit', '_d_arraysetbit2',
+                '_d_arraysetlength', '_d_arraysetlengthb',
+                '_d_callfinalizer',
+                '_d_create_exception_object',
+                '_d_criticalenter', '_d_criticalexit',
+                '_d_delarray', '_d_delclass',
+                '_d_delinterface', '_d_delmemory',
+                '_d_dynamic_cast', '_d_exception',
+                '_d_exception_filter', '_d_framehandler',
+                '_d_interface_cast', '_d_interface_vtbl',
+                '_d_invariant', '_d_isbaseof',
+                '_d_isbaseof2', '_d_local_unwind',
+                '_d_monitorenter', '_d_monitorexit',
+                '_d_monitorrelease', '_d_monitor_epilog',
+                '_d_monitor_handler', '_d_monitor_prolog',
+                '_d_new', '_d_newarrayi', '_d_newbitarray',
+                '_d_newclass', '_d_obj_cmp', '_d_obj_eq',
+                '_d_OutOfMemory', '_d_switch_dstring',
+                '_d_switch_string', '_d_switch_ustring',
+                '_d_throw',
+            ),
+        4 => array(
+                'abstract', 'align', 'auto', 'bit', 'bool',
+                'byte', 'cdouble', 'cent', 'cfloat', 'char',
+                'class', 'const', 'creal', 'dchar', 'debug',
+                'deprecated', 'double', 'enum', 'export',
+                'final', 'float', 'idouble', 'ifloat', 'int',
+                'ireal', 'long', 'override', 'package',
+                'private', 'protected', 'ptrdiff_t',
+                'public', 'real', 'short', 'size_t',
+                'static', 'struct', 'synchronized',
+                'template', 'ubyte', 'ucent', 'uint',
+                'ulong', 'unittest', 'ushort', 'version',
+                'void', 'volatile', 'wchar'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '?', '!', ';', ':', ',', '...', '..',
+        '+', '-', '*', '/', '%', '&', '|', '^', '<', '>', '=', '~',
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #aaaadd; font-weight: bold;',
+            4 => 'color: #993333;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #009933; font-style: italic;',
+            3 => 'color: #009933; font-style: italic;',
+            4 => 'color: #ff0000;',
+            5 => 'color: #0040ff;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #660099; font-weight: bold;',
+            3 => 'color: #660099; font-weight: bold;',
+            4 => 'color: #660099; font-weight: bold;',
+            5 => 'color: #006699; font-weight: bold;',
+            6 => 'color: #666699; font-weight: bold; font-style: italic;',
+            'HARD' => '',
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;',
+            'HARD' => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000dd;',
+            GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+            GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/dcs.php b/examples/includes/geshi/geshi/dcs.php
new file mode 100644 (file)
index 0000000..b9fe581
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+/*************************************************************************************
+ * dcs.php
+ * ---------------------------------
+ * Author: Stelio Passaris (GeSHi@stelio.net)
+ * Copyright: (c) 2009 Stelio Passaris (http://stelio.net/stiki/GeSHi)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/01/20
+ *
+ * DCS language file for GeSHi.
+ *
+ * DCS (Data Conversion System) is part of Sungard iWorks' Prophet suite and is used
+ * to convert external data files into a format that Prophet and Glean can read.
+ * See http://www.prophet-web.com/Products/DCS for product information.
+ * This language file is current for DCS version 7.3.2.
+ *
+ * Note that the DCS IDE does not handle escape characters correctly. The IDE thinks
+ * that a backslash '\' is an escape character, but in practice the backslash does
+ * not escape the string delimiter character '"' when the program runs. A '\\' is
+ * escaped to '\' when the program runs, but '\"' is treated as '\' at the end of a
+ * string. Therefore in this language file, we do not recognise the backslash as an
+ * escape character. For the purposes of GeSHi, there is no character escaping.
+ *
+ * CHANGES
+ * -------
+ * 2009/02/21 (1.0.8.3)
+ *  -  First Release
+ *
+ * TODO (updated 2009/02/21)
+ * -------------------------
+ * * Add handling for embedded C code. Note that the DCS IDE does not highlight C code
+ *   correctly, but that doesn't mean that we can't! This will be included for a
+ *   stable release of GeSHi of version 1.1.x (or later) that allows for highlighting
+ *   embedded code using that code's appropriate language file.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'DCS',
+    'COMMENT_SINGLE' => array(
+        1 => ';'
+        ),
+    'COMMENT_MULTI' => array(
+        ),
+    'HARDQUOTE' => array(
+        ),
+    'HARDESCAPE' => '',
+    'COMMENT_REGEXP' => array(
+        // Highlight embedded C code in a separate color:
+        2 => '/\bINSERT_C_CODE\b.*?\bEND_C_CODE\b/ims'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array(
+        '"'
+        ),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => '',
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'abs', 'ascii_value', 'bit_value', 'blank_date', 'calc_unit_values', 'cm',
+            'complete_months', 'complete_years', 'correct', 'create_input_file', 'cy',
+            'date_convert', 'day', 'del_output_separator',
+            'delete_existing_output_files', 'div', 'ex', 'exact_years', 'exp',
+            'extract_date', 'failed_validation', 'file_number', 'first_record',
+            'fract', 'fund_fac_a', 'fund_fac_b', 'fund_fac_c', 'fund_fac_d',
+            'fund_fac_e', 'fund_fac_f', 'fund_fac_g', 'fund_fac_h', 'fund_fac_i',
+            'fund_fac_j', 'fund_fac_k', 'fund_fac_l', 'fund_fac_m', 'fund_fac_n',
+            'fund_fac_o', 'fund_fac_p', 'fund_fac_q', 'fund_fac_r', 'fund_fac_s',
+            'fund_fac_t', 'fund_fac_u', 'fund_fac_v', 'fund_fac_w', 'fund_fac_x',
+            'fund_fac_y', 'fund_fac_z', 'group', 'group_record',
+            'input_file_date_time', 'input_file_extension', 'input_file_location',
+            'input_file_name', 'int', 'invalid', 'last_record', 'leap_year', 'len',
+            'ln', 'log', 'main_format_name', 'max', 'max_num_subrecords', 'message',
+            'min', 'mod', 'month', 'months_add', 'months_sub', 'nearest_months',
+            'nearest_years', 'next_record', 'nm', 'no_of_current_records',
+            'no_of_records', 'numval', 'ny', 'output', 'output_array_as_constants',
+            'output_file_path', 'output_record', 'pmdf_output', 'previous', 'rand',
+            're_start', 'read_generic_table', 'read_generic_table_text',
+            'read_input_footer', 'read_input_footer_text', 'read_input_header',
+            'read_input_header_text', 'record_count', 'record_suppressed', 'round',
+            'round_down', 'round_near', 'round_up', 'run_dcs_program', 'run_parameter',
+            'run_parameter_text', 'set_main_record', 'set_num_subrecords',
+            'sort_array', 'sort_current_records', 'sort_input', 'strval', 'substr',
+            'summarise', 'summarise_record', 'summarise_units',
+            'summarise_units_record', 'suppress_record', 'table_correct',
+            'table_validate', 'terminate', 'time', 'today', 'trim', 'ubound', 'year',
+            'years_add', 'years_sub'
+            ),
+        2 => array(
+            'and', 'as', 'begin', 'boolean', 'byref', 'byval', 'call', 'case', 'date',
+            'default', 'do', 'else', 'elseif', 'end_c_code', 'endfor', 'endfunction',
+            'endif', 'endproc', 'endswitch', 'endwhile', 'eq',
+            'explicit_declarations', 'false', 'for', 'from', 'function', 'ge', 'gt',
+            'if', 'insert_c_code', 'integer', 'le', 'loop', 'lt', 'ne', 'not',
+            'number', 'or', 'private', 'proc', 'public', 'quitloop', 'return',
+            'short', 'step', 'switch', 'text', 'then', 'to', 'true', 'while'
+            ),
+        3 => array(
+            // These keywords are not highlighted by the DCS IDE but we may as well
+            // keep track of them anyway:
+            'mp_file', 'odbc_file'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']',
+        '=', '<', '>',
+        '+', '-', '*', '/', '^',
+        ':', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: red;',
+            2 => 'color: blue;',
+            3 => 'color: black;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: black; background-color: silver;',
+            // Colors for highlighting embedded C code:
+            2 => 'color: maroon; background-color: pink;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: black;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: green;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: green;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: black;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/delphi.php b/examples/includes/geshi/geshi/delphi.php
new file mode 100644 (file)
index 0000000..7de1f8c
--- /dev/null
@@ -0,0 +1,289 @@
+<?php
+/*************************************************************************************
+ * delphi.php
+ * ----------
+ * Author: J�rja Norbert (jnorbi@vipmail.hu), Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2004 J�rja Norbert, Benny Baumann (BenBE@omorphia.de), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/26
+ *
+ * Delphi (Object Pascal) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2005/11/19 (1.0.3)
+ *   -  Updated the very incomplete keyword and type lists
+ * 2005/09/03 (1.0.2)
+ *   -  Added support for hex numbers and string entities
+ * 2004/11/27 (1.0.1)
+ *   -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Delphi',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('(*' => '*)', '{' => '}'),
+    //Compiler directives
+    'COMMENT_REGEXP' => array(2 => '/{\\$.*?}|\\(\\*\\$.*?\\*\\)/U'),
+    'CASE_KEYWORDS' => 0,
+    'QUOTEMARKS' => array("'"),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'Abstract', 'And', 'Array', 'As', 'Asm', 'At', 'Begin', 'Case',
+            'Class', 'Const', 'Constructor', 'Contains', 'Destructor',
+            'DispInterface', 'Div', 'Do', 'DownTo', 'Else', 'End', 'Except',
+            'Export', 'Exports', 'External', 'File', 'Finalization', 'Finally',
+            'For', 'Function', 'Goto', 'If', 'Implementation', 'In', 'Inherited',
+            'Initialization', 'Inline', 'Interface', 'Is', 'Label', 'Library',
+            'Mod', 'Not', 'Object', 'Of', 'On', 'Or', 'Overload', 'Override',
+            'Package', 'Packed', 'Private', 'Procedure', 'Program', 'Property',
+            'Protected', 'Public', 'Published', 'Raise', 'Record', 'Register',
+            'Repeat', 'Requires', 'Resourcestring', 'Set', 'Shl', 'Shr', 'Then',
+            'ThreadVar', 'To', 'Try', 'Type', 'Unit', 'Until', 'Uses', 'Var',
+            'Virtual', 'While', 'With', 'Xor', 'assembler', 'far',
+            'near', 'pascal', 'register', 'cdecl', 'safecall', 'stdcall', 'varargs'
+            ),
+        2 => array(
+            'nil', 'false', 'self', 'true', 'var', 'type', 'const'
+            ),
+        3 => array(
+            'Abs', 'AcquireExceptionObject', 'Addr', 'AnsiToUtf8', 'Append', 'ArcTan',
+            'Assert', 'AssignFile', 'Assigned', 'BeginThread', 'BlockRead',
+            'BlockWrite', 'Break', 'ChDir', 'Chr', 'Close', 'CloseFile',
+            'CompToCurrency', 'CompToDouble', 'Concat', 'Continue', 'Copy', 'Cos',
+            'Dec', 'Delete', 'Dispose', 'DoubleToComp', 'EndThread', 'EnumModules',
+            'EnumResourceModules', 'Eof', 'Eoln', 'Erase', 'ExceptAddr',
+            'ExceptObject', 'Exclude', 'Exit', 'Exp', 'FilePos', 'FileSize',
+            'FillChar', 'Finalize', 'FindClassHInstance', 'FindHInstance',
+            'FindResourceHInstance', 'Flush', 'Frac', 'FreeMem', 'Get8087CW',
+            'GetDir', 'GetLastError', 'GetMem', 'GetMemoryManager',
+            'GetModuleFileName', 'GetVariantManager', 'Halt', 'Hi', 'High',
+            'IOResult', 'Inc', 'Include', 'Initialize', 'Insert', 'Int',
+            'IsMemoryManagerSet', 'IsVariantManagerSet', 'Length', 'Ln', 'Lo', 'Low',
+            'MkDir', 'Move', 'New', 'Odd', 'OleStrToStrVar', 'OleStrToString', 'Ord',
+            'PUCS4Chars', 'ParamCount', 'ParamStr', 'Pi', 'Pos', 'Pred', 'Ptr',
+            'Random', 'Randomize', 'Read', 'ReadLn', 'ReallocMem',
+            'ReleaseExceptionObject', 'Rename', 'Reset', 'Rewrite', 'RmDir', 'Round',
+            'RunError', 'Seek', 'SeekEof', 'SeekEoln', 'Set8087CW', 'SetLength',
+            'SetLineBreakStyle', 'SetMemoryManager', 'SetString', 'SetTextBuf',
+            'SetVariantManager', 'Sin', 'SizeOf', 'Slice', 'Sqr', 'Sqrt', 'Str',
+            'StringOfChar', 'StringToOleStr', 'StringToWideChar', 'Succ', 'Swap',
+            'Trunc', 'Truncate', 'TypeInfo', 'UCS4StringToWideString', 'UTF8Decode',
+            'UTF8Encode', 'UnicodeToUtf8', 'UniqueString', 'UpCase', 'Utf8ToAnsi',
+            'Utf8ToUnicode', 'Val', 'VarArrayRedim', 'VarClear',
+            'WideCharLenToStrVar', 'WideCharLenToString', 'WideCharToStrVar',
+            'WideCharToString', 'WideStringToUCS4String', 'Write', 'WriteLn',
+
+            'Abort', 'AddExitProc', 'AddTerminateProc', 'AdjustLineBreaks', 'AllocMem',
+            'AnsiCompareFileName', 'AnsiCompareStr', 'AnsiCompareText',
+            'AnsiDequotedStr', 'AnsiExtractQuotedStr', 'AnsiLastChar',
+            'AnsiLowerCase', 'AnsiLowerCaseFileName', 'AnsiPos', 'AnsiQuotedStr',
+            'AnsiSameStr', 'AnsiSameText', 'AnsiStrComp', 'AnsiStrIComp',
+            'AnsiStrLComp', 'AnsiStrLIComp', 'AnsiStrLastChar', 'AnsiStrLower',
+            'AnsiStrPos', 'AnsiStrRScan', 'AnsiStrScan', 'AnsiStrUpper',
+            'AnsiUpperCase', 'AnsiUpperCaseFileName', 'AppendStr', 'AssignStr',
+            'Beep', 'BoolToStr', 'ByteToCharIndex', 'ByteToCharLen', 'ByteType',
+            'CallTerminateProcs', 'ChangeFileExt', 'CharLength', 'CharToByteIndex',
+            'CharToByteLen', 'CompareMem', 'CompareStr', 'CompareText', 'CreateDir',
+            'CreateGUID', 'CurrToStr', 'CurrToStrF', 'CurrentYear', 'Date',
+            'DateTimeToFileDate', 'DateTimeToStr', 'DateTimeToString',
+            'DateTimeToSystemTime', 'DateTimeToTimeStamp', 'DateToStr', 'DayOfWeek',
+            'DecodeDate', 'DecodeDateFully', 'DecodeTime', 'DeleteFile',
+            'DirectoryExists', 'DiskFree', 'DiskSize', 'DisposeStr', 'EncodeDate',
+            'EncodeTime', 'ExceptionErrorMessage', 'ExcludeTrailingBackslash',
+            'ExcludeTrailingPathDelimiter', 'ExpandFileName', 'ExpandFileNameCase',
+            'ExpandUNCFileName', 'ExtractFileDir', 'ExtractFileDrive',
+            'ExtractFileExt', 'ExtractFileName', 'ExtractFilePath',
+            'ExtractRelativePath', 'ExtractShortPathName', 'FileAge', 'FileClose',
+            'FileCreate', 'FileDateToDateTime', 'FileExists', 'FileGetAttr',
+            'FileGetDate', 'FileIsReadOnly', 'FileOpen', 'FileRead', 'FileSearch',
+            'FileSeek', 'FileSetAttr', 'FileSetDate', 'FileSetReadOnly', 'FileWrite',
+            'FinalizePackage', 'FindClose', 'FindCmdLineSwitch', 'FindFirst',
+            'FindNext', 'FloatToCurr', 'FloatToDateTime', 'FloatToDecimal',
+            'FloatToStr', 'FloatToStrF', 'FloatToText', 'FloatToTextFmt',
+            'FmtLoadStr', 'FmtStr', 'ForceDirectories', 'Format', 'FormatBuf',
+            'FormatCurr', 'FormatDateTime', 'FormatFloat', 'FreeAndNil',
+            'GUIDToString', 'GetCurrentDir', 'GetEnvironmentVariable',
+            'GetFileVersion', 'GetFormatSettings', 'GetLocaleFormatSettings',
+            'GetModuleName', 'GetPackageDescription', 'GetPackageInfo', 'GetTime',
+            'IncAMonth', 'IncMonth', 'IncludeTrailingBackslash',
+            'IncludeTrailingPathDelimiter', 'InitializePackage', 'IntToHex',
+            'IntToStr', 'InterlockedDecrement', 'InterlockedExchange',
+            'InterlockedExchangeAdd', 'InterlockedIncrement', 'IsDelimiter',
+            'IsEqualGUID', 'IsLeapYear', 'IsPathDelimiter', 'IsValidIdent',
+            'Languages', 'LastDelimiter', 'LoadPackage', 'LoadStr', 'LowerCase',
+            'MSecsToTimeStamp', 'NewStr', 'NextCharIndex', 'Now', 'OutOfMemoryError',
+            'QuotedStr', 'RaiseLastOSError', 'RaiseLastWin32Error', 'RemoveDir',
+            'RenameFile', 'ReplaceDate', 'ReplaceTime', 'SafeLoadLibrary',
+            'SameFileName', 'SameText', 'SetCurrentDir', 'ShowException', 'Sleep',
+            'StrAlloc', 'StrBufSize', 'StrByteType', 'StrCat', 'StrCharLength',
+            'StrComp', 'StrCopy', 'StrDispose', 'StrECopy', 'StrEnd', 'StrFmt',
+            'StrIComp', 'StrLCat', 'StrLComp', 'StrLCopy', 'StrLFmt', 'StrLIComp',
+            'StrLen', 'StrLower', 'StrMove', 'StrNew', 'StrNextChar', 'StrPCopy',
+            'StrPLCopy', 'StrPas', 'StrPos', 'StrRScan', 'StrScan', 'StrToBool',
+            'StrToBoolDef', 'StrToCurr', 'StrToCurrDef', 'StrToDate', 'StrToDateDef',
+            'StrToDateTime', 'StrToDateTimeDef', 'StrToFloat', 'StrToFloatDef',
+            'StrToInt', 'StrToInt64', 'StrToInt64Def', 'StrToIntDef', 'StrToTime',
+            'StrToTimeDef', 'StrUpper', 'StringReplace', 'StringToGUID', 'Supports',
+            'SysErrorMessage', 'SystemTimeToDateTime', 'TextToFloat', 'Time',
+            'TimeStampToDateTime', 'TimeStampToMSecs', 'TimeToStr', 'Trim',
+            'TrimLeft', 'TrimRight', 'TryEncodeDate', 'TryEncodeTime',
+            'TryFloatToCurr', 'TryFloatToDateTime', 'TryStrToBool', 'TryStrToCurr',
+            'TryStrToDate', 'TryStrToDateTime', 'TryStrToFloat', 'TryStrToInt',
+            'TryStrToInt64', 'TryStrToTime', 'UnloadPackage', 'UpperCase',
+            'WideCompareStr', 'WideCompareText', 'WideFmtStr', 'WideFormat',
+            'WideFormatBuf', 'WideLowerCase', 'WideSameStr', 'WideSameText',
+            'WideUpperCase', 'Win32Check', 'WrapText',
+
+            'ActivateClassGroup', 'AllocateHwnd', 'BinToHex', 'CheckSynchronize',
+            'CollectionsEqual', 'CountGenerations', 'DeallocateHwnd', 'EqualRect',
+            'ExtractStrings', 'FindClass', 'FindGlobalComponent', 'GetClass',
+            'GroupDescendantsWith', 'HexToBin', 'IdentToInt',
+            'InitInheritedComponent', 'IntToIdent', 'InvalidPoint',
+            'IsUniqueGlobalComponentName', 'LineStart', 'ObjectBinaryToText',
+            'ObjectResourceToText', 'ObjectTextToBinary', 'ObjectTextToResource',
+            'PointsEqual', 'ReadComponentRes', 'ReadComponentResEx',
+            'ReadComponentResFile', 'Rect', 'RegisterClass', 'RegisterClassAlias',
+            'RegisterClasses', 'RegisterComponents', 'RegisterIntegerConsts',
+            'RegisterNoIcon', 'RegisterNonActiveX', 'SmallPoint', 'StartClassGroup',
+            'TestStreamFormat', 'UnregisterClass', 'UnregisterClasses',
+            'UnregisterIntegerConsts', 'UnregisterModuleClasses',
+            'WriteComponentResFile',
+
+            'ArcCos', 'ArcCosh', 'ArcCot', 'ArcCotH', 'ArcCsc', 'ArcCscH', 'ArcSec',
+            'ArcSecH', 'ArcSin', 'ArcSinh', 'ArcTan2', 'ArcTanh', 'Ceil',
+            'CompareValue', 'Cosecant', 'Cosh', 'Cot', 'CotH', 'Cotan', 'Csc', 'CscH',
+            'CycleToDeg', 'CycleToGrad', 'CycleToRad', 'DegToCycle', 'DegToGrad',
+            'DegToRad', 'DivMod', 'DoubleDecliningBalance', 'EnsureRange', 'Floor',
+            'Frexp', 'FutureValue', 'GetExceptionMask', 'GetPrecisionMode',
+            'GetRoundMode', 'GradToCycle', 'GradToDeg', 'GradToRad', 'Hypot',
+            'InRange', 'IntPower', 'InterestPayment', 'InterestRate',
+            'InternalRateOfReturn', 'IsInfinite', 'IsNan', 'IsZero', 'Ldexp', 'LnXP1',
+            'Log10', 'Log2', 'LogN', 'Max', 'MaxIntValue', 'MaxValue', 'Mean',
+            'MeanAndStdDev', 'Min', 'MinIntValue', 'MinValue', 'MomentSkewKurtosis',
+            'NetPresentValue', 'Norm', 'NumberOfPeriods', 'Payment', 'PeriodPayment',
+            'Poly', 'PopnStdDev', 'PopnVariance', 'Power', 'PresentValue',
+            'RadToCycle', 'RadToDeg', 'RadToGrad', 'RandG', 'RandomRange', 'RoundTo',
+            'SLNDepreciation', 'SYDDepreciation', 'SameValue', 'Sec', 'SecH',
+            'Secant', 'SetExceptionMask', 'SetPrecisionMode', 'SetRoundMode', 'Sign',
+            'SimpleRoundTo', 'SinCos', 'Sinh', 'StdDev', 'Sum', 'SumInt',
+            'SumOfSquares', 'SumsAndSquares', 'Tan', 'Tanh', 'TotalVariance',
+            'Variance'
+            ),
+        4 => array(
+            'AnsiChar', 'AnsiString', 'Bool', 'Boolean', 'Byte', 'ByteBool', 'Cardinal', 'Char',
+            'Comp', 'Currency', 'DWORD', 'Double', 'Extended', 'Int64', 'Integer', 'IUnknown',
+            'LongBool', 'LongInt', 'LongWord', 'PAnsiChar', 'PAnsiString', 'PBool', 'PBoolean', 'PByte',
+            'PByteArray', 'PCardinal', 'PChar', 'PComp', 'PCurrency', 'PDWORD', 'PDate', 'PDateTime',
+            'PDouble', 'PExtended', 'PInt64', 'PInteger', 'PLongInt', 'PLongWord', 'Pointer', 'PPointer',
+            'PShortInt', 'PShortString', 'PSingle', 'PSmallInt', 'PString', 'PHandle', 'PVariant', 'PWord',
+            'PWordArray', 'PWordBool', 'PWideChar', 'PWideString', 'Real', 'Real48', 'ShortInt', 'ShortString',
+            'Single', 'SmallInt', 'String', 'TClass', 'TDate', 'TDateTime', 'TextFile', 'THandle',
+            'TObject', 'TTime', 'Variant', 'WideChar', 'WideString', 'Word', 'WordBool'
+            ),
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'SYMBOLS' => array(
+        0 => array('(', ')', '[', ']'),
+        1 => array('.', ',', ':', ';'),
+        2 => array('@', '^'),
+        3 => array('=', '+', '-', '*', '/')
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;',
+            4 => 'color: #000066; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #008000; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #ff0000; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000066;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #9ac;',
+            1 => 'color: #ff0000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066;',
+            1 => 'color: #000066;',
+            2 => 'color: #000066;',
+            3 => 'color: #000066;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        //Hex numbers
+        0 => '\$[0-9a-fA-F]+',
+        //Characters
+        1 => '\#\$?[0-9]{1,3}'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 2
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/diff.php b/examples/includes/geshi/geshi/diff.php
new file mode 100644 (file)
index 0000000..c82e65c
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/*************************************************************************************
+ * diff.php
+ * --------
+ * Author: Conny Brunnkvist (conny@fuchsia.se), W. Tasin (tasin@fhm.edu)
+ * Copyright: (c) 2004 Fuchsia Open Source Solutions (http://www.fuchsia.se/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/12/29
+ *
+ * Diff-output language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2006/02/27
+ *  -  changing language file to use matching of start (^) and end ($) (wt)
+ * 2004/12/29 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2006/02/27)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+
+$language_data = array (
+    'LANG_NAME' => 'Diff',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => ' ',
+    'KEYWORDS' => array(
+            1 => array(
+                '\ No newline at end of file'
+            ),
+//            2 => array(
+//                '***************' /* This only seems to works in some cases? */
+//            ),
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        1 => false,
+//        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #aaaaaa; font-style: italic;',
+//            2 => 'color: #dd6611;',
+            ),
+        'COMMENTS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => ''
+            ),
+        'STRINGS' => array(
+            0 => ''
+            ),
+        'NUMBERS' => array(
+            0 => ''
+            ),
+        'METHODS' => array(
+            0 => ''
+            ),
+        'SYMBOLS' => array(
+            0 => ''
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #440088;',
+            1 => 'color: #991111;',
+            2 => 'color: #00b000;',
+            3 => 'color: #888822;',
+            4 => 'color: #888822;',
+            5 => 'color: #0011dd;',
+            6 => 'color: #440088;',
+            7 => 'color: #991111;',
+            8 => 'color: #00b000;',
+            9 => 'color: #888822;',
+            ),
+        ),
+    'URLS' => array(
+        1 => '',
+//        2 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        0 => "[0-9,]+[acd][0-9,]+",
+        //Removed lines
+        1 => array(
+            GESHI_SEARCH => '^\\&lt;.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //Inserted lines
+        2 => array(
+            GESHI_SEARCH => '^\\&gt;.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //Location line
+        3 => array(
+            GESHI_SEARCH => '^[\\-]{3}\\s.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //Inserted line
+        4 => array(
+            GESHI_SEARCH => '^(\\+){3}\\s.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //Modified line
+        5 => array(
+            GESHI_SEARCH => '^\\!.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //File specification
+        6 => array(
+            GESHI_SEARCH => '^[\\@]{2}.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //Removed line
+        7 => array(
+            GESHI_SEARCH => '^\\-.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //Inserted line
+        8 => array(
+            GESHI_SEARCH => '^\\+.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        //File specification
+        9 => array(
+            GESHI_SEARCH => '^(\\*){3}\\s.*$',
+            GESHI_REPLACE => '\\0',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/div.php b/examples/includes/geshi/geshi/div.php
new file mode 100644 (file)
index 0000000..d3d506d
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+/*************************************************************************************
+ * div.php
+ * ---------------------------------
+ * Author: Gabriel Lorenzo (ermakina@gmail.com)
+ * Copyright: (c) 2005 Gabriel Lorenzo (http://ermakina.gazpachito.net)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/06/19
+ *
+ * DIV language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/06/22 (1.0.0)
+ *  -  First Release, includes "2nd gen" ELSEIF statement
+ *
+ * TODO (updated 2005/06/22)
+ * -------------------------
+ *  -  I'm pretty satisfied with this, so nothing for now... :P
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'DIV',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'while','until','to','switch','step','return','repeat','loop','if','from','frame','for','end','elseif',
+            'else','default','debug','continue','clone','case','break','begin'
+            ),
+        2 => array(
+            'xor','whoami','type','sizeof','pointer','or','offset','not','neg','mod','id','dup','and','_ne','_lt',
+            '_le','_gt','_ge','_eq'
+            ),
+        3 => array(
+            'setup_program','program','process','private','local','import','global','function','const',
+            'compiler_options'
+            ),
+        4 => array(
+            'word','struct','string','int','byte'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(',')','[',']','=','+','-','*','/','!','%','^','&',':',';',',','<','>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0040b1;',
+            2 => 'color: #000000;',
+            3 => 'color: #000066; font-weight: bold;',
+            4 => 'color: #993333;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #44aa44;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #202020;',
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #44aa44;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/dos.php b/examples/includes/geshi/geshi/dos.php
new file mode 100644 (file)
index 0000000..af8fdae
--- /dev/null
@@ -0,0 +1,198 @@
+<?php
+/*************************************************************************************
+ * dos.php
+ * -------
+ * Author: Alessandro Staltari (staltari@geocities.com)
+ * Copyright: (c) 2005 Alessandro Staltari (http://www.geocities.com/SiliconValley/Vista/8155/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/07/05
+ *
+ * DOS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2005/07/05 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2005/07/05)
+ * -------------------------
+ *
+ * - Highlight pipes and redirection (do we really need this?)
+ * - Add missing keywords.
+ * - Find a good hyperlink for keywords.
+ * - Improve styles.
+ *
+ * KNOWN ISSUES (updated 2005/07/07)
+ * ---------------------------------
+ *
+ * - Doesn't even try to handle spaces in variables name or labels (I can't
+ *   find a reliable way to establish if a sting is a name or not, in some
+ *   cases it depends on the contex or enviroment status).
+ * - Doesn't handle %%[letter] pseudo variable used inside FOR constructs
+ *   (it should be done only into its scope: how to handle variable it?).
+ * - Doesn't handle %~[something] pseudo arguments.
+ * - If the same keyword is placed at the end of the line and the
+ *   beginning of the next, the second occourrence is not highlighted
+ *   (this should be a GeSHi bug, not related to the language definition).
+ * - I can't avoid to have keyword highlighted even when they are not used
+ *   as keywords but, for example, as arguments to the echo command.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'DOS',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    //DOS comment lines
+    'COMMENT_REGEXP' => array(1 => "/^\s*@?REM.*$/mi"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /* Flow control keywords */
+        1 => array(
+            'if', 'else', 'goto', 'shift',
+            'for', 'in', 'do',
+            'call', 'exit'
+            ),
+        /* IF statement keywords */
+        2 => array(
+            'not', 'exist', 'errorlevel',
+            'defined',
+            'equ', 'neq', 'lss', 'leq', 'gtr', 'geq'
+            ),
+        /* Internal commands */
+        3 => array(
+            'cd', 'md', 'rd', 'chdir', 'mkdir', 'rmdir', 'dir',
+            'del', 'copy', 'move', 'ren', 'rename',
+            'echo',
+            'setlocal', 'endlocal', 'set',
+            'pause',
+            'pushd', 'popd', 'title', 'verify'
+            ),
+        /* Special files */
+        4 => array(
+            'prn', 'nul', 'lpt3', 'lpt2', 'lpt1', 'con',
+            'com4', 'com3', 'com2', 'com1', 'aux'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '@', '%'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00b100; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #b1b100; font-weight: bold;',
+            4 => 'color: #0000ff; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #ff0000; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #33cc33;',
+            1 => 'color: #33cc33;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #b100b1; font-weight: bold;',
+            1 => 'color: #448844;',
+            2 => 'color: #448888;'
+            )
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'URLS' => array(
+        1 => 'http://www.ss64.com/nt/{FNAMEL}.html',
+        2 => 'http://www.ss64.com/nt/{FNAMEL}.html',
+        3 => 'http://www.ss64.com/nt/{FNAMEL}.html',
+        4 => 'http://www.ss64.com/nt/{FNAMEL}.html'
+        ),
+    'REGEXPS' => array(
+        /* Label */
+        0 => array(
+/*            GESHI_SEARCH => '((?si:[@\s]+GOTO\s+|\s+:)[\s]*)((?<!\n)[^\s\n]*)',*/
+            GESHI_SEARCH => '((?si:[@\s]+GOTO\s+|\s+:)[\s]*)((?<!\n)[^\n]*)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'si',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+        ),
+        /* Variable assignement */
+        1 => array(
+/*            GESHI_SEARCH => '(SET[\s]+(?si:\/A[\s]+|\/P[\s]+|))([^=\s\n]+)([\s]*=)',*/
+            GESHI_SEARCH => '(SET[\s]+(?si:\/A[\s]+|\/P[\s]+|))([^=\n]+)([\s]*=)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'si',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+        /* Arguments or variable evaluation */
+        2 => array(
+/*            GESHI_SEARCH => '(%)([\d*]|[^%\s]*(?=%))((?<!%\d)%|)',*/
+            GESHI_SEARCH => '(%(?:%(?=[a-z0-9]))?)([\d*]|(?:~[adfnpstxz]*(?:$\w+:)?)?[a-z0-9](?!\w)|[^%\n]*(?=%))((?<!%\d)%|)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'si',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            4 => array(
+                'DISALLOWED_BEFORE' => '(?<!\w)'
+                )
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/dot.php b/examples/includes/geshi/geshi/dot.php
new file mode 100644 (file)
index 0000000..35d3d9b
--- /dev/null
@@ -0,0 +1,164 @@
+<?php
+/*************************************************************************************
+ * dot.php
+ * ---------------------------------
+ * Author: Adrien Friggeri (adrien@friggeri.net)
+ * Copyright: (c) 2007 Adrien Friggeri (http://www.friggeri.net)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/05/30
+ *
+ * dot language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/05/30 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2007/05/30)
+ * -------------------------
+ * Everything
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'dot',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'URL', 'arrowhead', 'arrowsize', 'arrowtail', 'bb', 'bgcolor', 'bottomlabel',
+            'center', 'clusterrank', 'color', 'comment', 'constraint', 'decorate',
+            'dir', 'distortion', 'fillcolor', 'fixedsize', 'fontcolor',
+            'fontname', 'fontsize', 'group', 'headclip', 'headlabel', 'headport',
+            'height', 'id', 'label', 'labelangle', 'labeldistance', 'labelfontcolor',
+            'labelfontname', 'labelfontsize', 'layer', 'layers', 'margin', 'mclimit',
+            'minlen', 'nodesep', 'nslimit', 'ordering', 'orientation', 'page',
+            'pagedir', 'peripheries', 'port_label_distance', 'quantum', 'rank', 'rankdir',
+            'ranksep', 'ratio', 'regular', 'rotate', 'samehead', 'sametail', 'searchsize',
+            'shape', 'shapefile', 'showboxes', 'sides', 'size', 'skew', 'style',
+            'tailclip', 'taillabel', 'tailport', 'toplabel', 'weight', 'width'
+            ),
+        2 => array(
+            'node', 'graph', 'digraph', 'strict', 'edge', 'subgraph'
+            ),
+        3 => array(
+            'Mcircle', 'Mdiamond', 'Mrecord', 'Msquare', 'TRUE', 'auto', 'back',
+            'bold', 'both', 'box', 'circle', 'compress', 'dashed', 'diamond', 'dot',
+            'dotted', 'doublecircle', 'doubleoctagon', 'egg', 'ellipse', 'epsf', 'false',
+            'fill', 'filled', 'forward', 'global', 'hexagon', 'house', 'inv', 'invdot',
+            'invhouse', 'invis', 'invodot', 'invtrapezium', 'invtriangle', 'local', 'max',
+            'min', 'none', 'normal', 'octagon', 'odot', 'out', 'parallelogram', 'plaintext',
+            'polygon', 'record', 'same', 'solid', 'trapezium', 'triangle', 'tripleoctagon',
+            'true'
+            ),
+        4 => array(
+            'aliceblue', 'antiquewhite', 'aquamarine', 'azure', 'beige', 'bisque', 'black',
+            'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue',
+            'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson',
+            'cyan', 'darkgoldenrod', 'darkgreen', 'darkkhaki', 'darkolivegreen',
+            'darkorange', 'darkorchid', 'darksalmon', 'darkseagreen', 'darkslateblue',
+            'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue',
+            'dimgray', 'dodgerblue', 'firebrick', 'forestgreen', 'gainsboro', 'ghostwhite',
+            'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink',
+            'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush',
+            'lawngreen', 'lemonchiffon', 'lightblue', 'lightcyan', 'lightgoldenrod',
+            'lightgoldenrodyellow', 'lightgray', 'lightpink', 'lightsalmon',
+            'lightseagreen', 'lightskyblue', 'lightslateblue', 'lightslategray',
+            'lightyellow', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine',
+            'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen',
+            'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred',
+            'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy',
+            'navyblue', 'oldlace', 'olivedrab', 'oralwhite', 'orange', 'orangered',
+            'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred',
+            'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple',
+            'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'salmon2', 'sandybrown',
+            'seagreen', 'seashell', 'sienna', 'skyblue', 'slateblue', 'slategray', 'snow',
+            'springgreen', 'steelblue', 'tan', 'thistle', 'tomato', 'turquoise', 'violet',
+            'violetred', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'
+            )
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '{', '}', '-', '+', '*', '/', '<', '>', '!', '~', '%', '&', '|', '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000066;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #993333;',
+            4 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #339933;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #af624d; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'METHODS' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            ),
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/eiffel.php b/examples/includes/geshi/geshi/eiffel.php
new file mode 100644 (file)
index 0000000..7a9a61e
--- /dev/null
@@ -0,0 +1,395 @@
+<?php
+/*************************************************************************************
+ * eiffel.php
+ * ----------
+ * Author: Zoran Simic (zsimic@axarosenberg.com)
+ * Copyright: (c) 2005 Zoran Simic
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/06/30
+ *
+ * Eiffel language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/06/30 (1.0.7)
+ *  -  Initial release
+ *
+ * TODO (updated 2005/06/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Eiffel',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '%',
+    'KEYWORDS' => array(
+        1 => array(
+            'separate',
+            'invariant',
+            'inherit',
+            'indexing',
+            'feature',
+            'expanded',
+            'deferred',
+            'class'
+            ),
+        2 => array(
+            'xor',
+            'when',
+            'variant',
+            'until',
+            'unique',
+            'undefine',
+            'then',
+            'strip',
+            'select',
+            'retry',
+            'rescue',
+            'require',
+            'rename',
+            'reference',
+            'redefine',
+            'prefix',
+            'or',
+            'once',
+            'old',
+            'obsolete',
+            'not',
+            'loop',
+            'local',
+            'like',
+            'is',
+            'inspect',
+            'infix',
+            'include',
+            'implies',
+            'if',
+            'frozen',
+            'from',
+            'external',
+            'export',
+            'ensure',
+            'end',
+            'elseif',
+            'else',
+            'do',
+            'creation',
+            'create',
+            'check',
+            'as',
+            'and',
+            'alias',
+            'agent'
+            ),
+        3 => array(
+            'Void',
+            'True',
+            'Result',
+            'Precursor',
+            'False',
+            'Current'
+            ),
+        4 => array(
+            'UNIX_SIGNALS',
+            'UNIX_FILE_INFO',
+            'UNBOUNDED',
+            'TWO_WAY_TREE_CURSOR',
+            'TWO_WAY_TREE',
+            'TWO_WAY_SORTED_SET',
+            'TWO_WAY_LIST',
+            'TWO_WAY_CURSOR_TREE',
+            'TWO_WAY_CIRCULAR',
+            'TWO_WAY_CHAIN_ITERATOR',
+            'TUPLE',
+            'TREE',
+            'TRAVERSABLE',
+            'TO_SPECIAL',
+            'THREAD_CONTROL',
+            'THREAD_ATTRIBUTES',
+            'THREAD',
+            'TABLE',
+            'SUBSET',
+            'STRING_HANDLER',
+            'STRING',
+            'STREAM',
+            'STORABLE',
+            'STD_FILES',
+            'STACK',
+            'SPECIAL',
+            'SORTED_TWO_WAY_LIST',
+            'SORTED_STRUCT',
+            'SORTED_LIST',
+            'SINGLE_MATH',
+            'SET',
+            'SEQUENCE',
+            'SEQ_STRING',
+            'SEMAPHORE',
+            'ROUTINE',
+            'RESIZABLE',
+            'RECURSIVE_TREE_CURSOR',
+            'RECURSIVE_CURSOR_TREE',
+            'REAL_REF',
+            'REAL',
+            'RAW_FILE',
+            'RANDOM',
+            'QUEUE',
+            'PROXY',
+            'PROFILING_SETTING',
+            'PROCEDURE',
+            'PRIORITY_QUEUE',
+            'PRIMES',
+            'PRECOMP',
+            'POINTER_REF',
+            'POINTER',
+            'PLATFORM',
+            'PLAIN_TEXT_FILE',
+            'PATH_NAME',
+            'PART_SORTED_TWO_WAY_LIST',
+            'PART_SORTED_SET',
+            'PART_SORTED_LIST',
+            'PART_COMPARABLE',
+            'OPERATING_ENVIRONMENT',
+            'ONCE_CONTROL',
+            'OBJECT_OWNER',
+            'OBJECT_CONTROL',
+            'NUMERIC',
+            'NONE',
+            'MUTEX',
+            'MULTI_ARRAY_LIST',
+            'MULTAR_LIST_CURSOR',
+            'MEMORY',
+            'MEM_INFO',
+            'MEM_CONST',
+            'MATH_CONST',
+            'LIST',
+            'LINKED_TREE_CURSOR',
+            'LINKED_TREE',
+            'LINKED_STACK',
+            'LINKED_SET',
+            'LINKED_QUEUE',
+            'LINKED_PRIORITY_QUEUE',
+            'LINKED_LIST_CURSOR',
+            'LINKED_LIST',
+            'LINKED_CURSOR_TREE',
+            'LINKED_CIRCULAR',
+            'LINKABLE',
+            'LINEAR_ITERATOR',
+            'LINEAR',
+            'ITERATOR',
+            'IO_MEDIUM',
+            'INTERNAL',
+            'INTEGER_REF',
+            'INTEGER_INTERVAL',
+            'INTEGER',
+            'INFINITE',
+            'INDEXABLE',
+            'IDENTIFIED_CONTROLLER',
+            'IDENTIFIED',
+            'HIERARCHICAL',
+            'HEAP_PRIORITY_QUEUE',
+            'HASHABLE',
+            'HASH_TABLE_CURSOR',
+            'HASH_TABLE',
+            'GENERAL',
+            'GC_INFO',
+            'FUNCTION',
+            'FORMAT_INTEGER',
+            'FORMAT_DOUBLE',
+            'FIXED_TREE',
+            'FIXED_LIST',
+            'FIXED',
+            'FINITE',
+            'FILE_NAME',
+            'FILE',
+            'FIBONACCI',
+            'EXECUTION_ENVIRONMENT',
+            'EXCEPTIONS',
+            'EXCEP_CONST',
+            'DYNAMIC_TREE',
+            'DYNAMIC_LIST',
+            'DYNAMIC_CIRCULAR',
+            'DYNAMIC_CHAIN',
+            'DOUBLE_REF',
+            'DOUBLE_MATH',
+            'DOUBLE',
+            'DISPENSER',
+            'DIRECTORY_NAME',
+            'DIRECTORY',
+            'DECLARATOR',
+            'DEBUG_OUTPUT',
+            'CURSOR_TREE_ITERATOR',
+            'CURSOR_TREE',
+            'CURSOR_STRUCTURE',
+            'CURSOR',
+            'COUNTABLE_SEQUENCE',
+            'COUNTABLE',
+            'CONTAINER',
+            'CONSOLE',
+            'CONDITION_VARIABLE',
+            'COMPARABLE_STRUCT',
+            'COMPARABLE_SET',
+            'COMPARABLE',
+            'COMPACT_TREE_CURSOR',
+            'COMPACT_CURSOR_TREE',
+            'COLLECTION',
+            'CIRCULAR_CURSOR',
+            'CIRCULAR',
+            'CHARACTER_REF',
+            'CHARACTER',
+            'CHAIN',
+            'CELL',
+            'BOX',
+            'BOUNDED_STACK',
+            'BOUNDED_QUEUE',
+            'BOUNDED',
+            'BOOLEAN_REF',
+            'BOOLEAN',
+            'BOOL_STRING',
+            'BIT_REF',
+            'BINARY_TREE',
+            'BINARY_SEARCH_TREE_SET',
+            'BINARY_SEARCH_TREE',
+            'BILINEAR',
+            'BI_LINKABLE',
+            'BASIC_ROUTINES',
+            'BAG',
+            'ASCII',
+            'ARRAYED_TREE',
+            'ARRAYED_STACK',
+            'ARRAYED_QUEUE',
+            'ARRAYED_LIST_CURSOR',
+            'ARRAYED_LIST',
+            'ARRAYED_CIRCULAR',
+            'ARRAY2',
+            'ARRAY',
+            'ARGUMENTS',
+            'ANY',
+            'ACTIVE'
+            ),
+        5 => array(
+            'yes',
+            'visible',
+            'trace',
+            'system',
+            'root',
+            'profile',
+            'override_cluster',
+            'object',
+            'no',
+            'multithreaded',
+            'msil_generation_type',
+            'line_generation',
+            'library',
+            'inlining_size',
+            'inlining',
+            'include_path',
+            'il_verifiable',
+            'exclude',
+            'exception_trace',
+            'dynamic_runtime',
+            'dotnet_naming_convention',
+            'disabled_debug',
+            'default',
+            'debug',
+            'dead_code_removal',
+            'console_application',
+            'cluster',
+            'cls_compliant',
+            'check_vape',
+            'assertion',
+            'array_optimization',
+            'all',
+            'address_expression'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!', '|', ':',
+        '(', ')', '{', '}', '[', ']', '#'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => true,
+        5 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0600FF; font-weight: bold;',
+            2 => 'color: #0600FF; font-weight: bold;',
+            3 => 'color: #800080;',
+            4 => 'color: #800000',
+            5 => 'color: #603000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000; font-style: italic;',
+            'MULTI' => ''
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #005070; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0080A0;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #000060;',
+            2 => 'color: #000050;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #600000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => 'http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+{FNAMEL}&amp;btnI=I%27m+Feeling+Lucky',
+        5 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/email.php b/examples/includes/geshi/geshi/email.php
new file mode 100644 (file)
index 0000000..26466dc
--- /dev/null
@@ -0,0 +1,209 @@
+<?php
+/*************************************************************************************
+ * email.php
+ * ---------------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/10/19
+ *
+ * Email (mbox \ eml \ RFC format) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/19 (1.0.8.1)
+ *   -  First Release
+ *
+ * TODO (updated 2008/10/19)
+ * -------------------------
+ * * Better checks when a header field should be expected
+ * * Fix the bound checks for kw groups 2 and 3, as well as rx group 1
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'eMail (mbox)',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'HTTP', 'SMTP', 'ASMTP', 'ESMTP'
+            ),
+        2 => array(
+            'Content-Type','Content-Transfer-Encoding','Content-Disposition',
+            'Delivered-To','Dkim-Signature','Domainkey-Signature','In-Reply-To',
+            'Message-Id','MIME-Version','Received','Received-SPF','References',
+            'Resend-From','Resend-To','Return-Path'
+            ),
+        3 => array(
+            'Date','From','Subject','To',
+            ),
+        4 => array(
+            'by', 'for', 'from', 'id', 'with'
+            )
+        ),
+    'SYMBOLS' => array(
+        ':', ';', '<', '>', '[', ']'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => false,
+        3 => false,
+        4 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000FF; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #800000; font-weight: bold;',
+            4 => 'font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            0 => 'color: #000040;',
+            ),
+        'REGEXPS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #0000FF;',
+            3 => 'color: #008000;',
+            4 => 'color: #0000FF; font-weight: bold;',
+            5 => 'font-weight: bold;',
+            6 => 'color: #400080;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        // Non-Standard-Header
+        1 => array(
+            GESHI_SEARCH => "(?<=\A\x20|\n)x-[a-z0-9\-]*(?=\s*:|\s*<)",
+            GESHI_REPLACE => "\\0",
+            GESHI_MODIFIERS => "smi",
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        //Email-Adresses or Mail-IDs
+        2 => array(
+            GESHI_SEARCH => "\b[\w\.]+@\w+(?:(?:\.\w+)*\.\w{2,4})?",
+            GESHI_REPLACE => "\\0",
+            GESHI_MODIFIERS => "mi",
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        //Date values in RFC format
+        3 => array(
+            GESHI_SEARCH => "\b(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s+\d\d?\s+" .
+                "(?:Jan|Feb|Mar|apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+" .
+                "\d{4}\s+\d\d?:\d\d:\d\d\s+[+\-]\d{4}(?:\s+\(\w+\))?",
+            GESHI_REPLACE => "\\0",
+            GESHI_MODIFIERS => "mi",
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        //IP addresses
+        4 => array(
+            GESHI_SEARCH => "(?<=\s)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=\s)|".
+                "(?<=\[)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=\])|".
+                "(?<==)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=<)",
+            GESHI_REPLACE => "\\0",
+            GESHI_MODIFIERS => "i",
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        //Field-Assignments
+        5 => array(
+            GESHI_SEARCH => "(?<=\s)[A-Z0-9\-]+(?==(?!\s|$))",
+            GESHI_REPLACE => "\\0",
+            GESHI_MODIFIERS => "mi",
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        //MIME type
+        6 => array(
+            GESHI_SEARCH => "(?<=\s)(?:audio|application|image|multipart|text|".
+                "video|x-[a-z0-9\-]+)\/[a-z0-9][a-z0-9\-]*(?=\s|<|$)",
+            GESHI_REPLACE => "\\0",
+            GESHI_MODIFIERS => "m",
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        0 => "/(^)[A-Z][a-zA-Z0-9\-]*\s*:\s*(?:.|(?=\n\s)\n)*($)/m"
+    ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            2 => array(
+                'DISALLOWED_BEFORE' => '(?<=\A\x20|\n)',
+                'DISALLOWED_AFTER' => '(?=\s*:)',
+            ),
+            3 => array(
+                'DISALLOWED_BEFORE' => '(?<=\A\x20|\n)',
+                'DISALLOWED_AFTER' => '(?=\s*:)',
+            ),
+            4 => array(
+                'DISALLOWED_BEFORE' => '(?<=\s)',
+                'DISALLOWED_AFTER' => '(?=\s|\b)',
+            )
+        ),
+        'ENABLE_FLAGS' => array(
+            'BRACKETS' => GESHI_NEVER,
+            'COMMENTS' => GESHI_NEVER,
+            'NUMBERS' => GESHI_NEVER
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/fortran.php b/examples/includes/geshi/geshi/fortran.php
new file mode 100644 (file)
index 0000000..1caf09d
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+/*************************************************************************************
+ * fortran.php
+ * -----------
+ * Author: Cedric Arrabie (cedric.arrabie@univ-pau.fr)
+ * Copyright: (C) 2006 Cetric Arrabie
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/04/22
+ *
+ * Fortran language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2006/04/20 (1.0.0)
+ *   -  First Release
+ *
+ * TODO
+ * -------------------------
+ *  -  Get a list of inbuilt functions to add (and explore fortran more
+ *     to complete this rather bare language file)
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME'=>'Fortran',
+    'COMMENT_SINGLE'=> array(1 =>'!',2=>'Cf2py'),
+    'COMMENT_MULTI'=> array(),
+    //Fortran Comments
+    'COMMENT_REGEXP' => array(1 => '/^C.*?$/mi'),
+    'CASE_KEYWORDS'=> GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS'=> array("'",'"'),
+    'ESCAPE_CHAR'=>'\\',
+    'KEYWORDS'=> array(
+        1 => array(
+            'allocate','block','call','case','contains','continue','cycle','deallocate',
+            'default','do','else','elseif','elsewhere','end','enddo','endif','endwhere',
+            'entry','exit','function','go','goto','if','interface','module','nullify','only',
+            'operator','procedure','program','recursive','return','select','stop',
+            'subroutine','then','to','where','while',
+            'access','action','advance','blank','blocksize','carriagecontrol',
+            'delim','direct','eor','err','exist','file','flen','fmt','form','formatted',
+            'iostat','name','named','nextrec','nml','number','opened','pad','position',
+            'readwrite','recl','sequential','status','unformatted','unit'
+            ),
+        2 => array(
+            '.AND.','.EQ.','.EQV.','.GE.','.GT.','.LE.','.LT.','.NE.','.NEQV.','.NOT.',
+            '.OR.','.TRUE.','.FALSE.'
+            ),
+        3 => array(
+            'allocatable','character','common','complex','data','dimension','double',
+            'equivalence','external','implicit','in','inout','integer','intent','intrinsic',
+            'kind','logical','namelist','none','optional','out','parameter','pointer',
+            'private','public','real','result','save','sequence','target','type','use'
+            ),
+        4 => array(
+            'abs','achar','acos','adjustl','adjustr','aimag','aint','all','allocated',
+            'anint','any','asin','atan','atan2','bit_size','break','btest','carg',
+            'ceiling','char','cmplx','conjg','cos','cosh','cpu_time','count','cshift',
+            'date_and_time','dble','digits','dim','dot_product','dprod dvchk',
+            'eoshift','epsilon','error','exp','exponent','floor','flush','fraction',
+            'getcl','huge','iachar','iand','ibclr','ibits','ibset','ichar','ieor','index',
+            'int','intrup','invalop','ior','iostat_msg','ishft','ishftc','lbound',
+            'len','len_trim','lge','lgt','lle','llt','log','log10','matmul','max','maxexponent',
+            'maxloc','maxval','merge','min','minexponent','minloc','minval','mod','modulo',
+            'mvbits','nbreak','ndperr','ndpexc','nearest','nint','not','offset','ovefl',
+            'pack','precfill','precision','present','product','prompt','radix',
+            'random_number','random_seed','range','repeat','reshape','rrspacing',
+            'scale','scan','segment','selected_int_kind','selected_real_kind',
+            'set_exponent','shape','sign','sin','sinh','size','spacing','spread','sqrt',
+            'sum system','system_clock','tan','tanh','timer','tiny','transfer','transpose',
+            'trim','ubound','undfl','unpack','val','verify'
+            ),
+        ),
+    'SYMBOLS'=> array(
+        '(',')','{','}','[',']','=','+','-','*','/','!','%','^','&',':'
+        ),
+    'CASE_SENSITIVE'=> array(
+        GESHI_COMMENTS => true,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES'=> array(
+        'KEYWORDS'=> array(
+            1 =>'color: #b1b100;',
+            2 =>'color: #000000; font-weight: bold;',
+            3 =>'color: #000066;',
+            4 =>'color: #993333;'
+            ),
+        'COMMENTS'=> array(
+            1 =>'color: #666666; font-style: italic;',
+            2 =>'color: #339933;',
+            'MULTI'=>'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR'=> array(
+            0 =>'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS'=> array(
+            0 =>'color: #009900;'
+            ),
+        'STRINGS'=> array(
+            0 =>'color: #ff0000;'
+            ),
+        'NUMBERS'=> array(
+            0 =>'color: #cc66cc;'
+            ),
+        'METHODS'=> array(
+            1 =>'color: #202020;',
+            2 =>'color: #202020;'
+            ),
+        'SYMBOLS'=> array(
+            0 =>'color: #339933;'
+            ),
+        'REGEXPS'=> array(
+            ),
+        'SCRIPT'=> array(
+            )
+        ),
+    'URLS'=> array(
+        1 =>'',
+        2 =>'',
+        3 =>'',
+        4 =>''
+        ),
+    'OOLANG'=> true,
+    'OBJECT_SPLITTERS'=> array(
+        1 =>'.',
+        2 =>'::'
+        ),
+    'REGEXPS'=> array(
+        ),
+    'STRICT_MODE_APPLIES'=> GESHI_NEVER,
+    'SCRIPT_DELIMITERS'=> array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK'=> array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/freebasic.php b/examples/includes/geshi/geshi/freebasic.php
new file mode 100644 (file)
index 0000000..0ddc46c
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * freebasic.php
+ * -------------
+ * Author: Roberto Rossi
+ * Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/08/19
+ *
+ * FreeBasic (http://www.freebasic.net/) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/19 (1.0.0)
+ *  -  First Release
+ *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'FreeBasic',
+    'COMMENT_SINGLE' => array(1 => "'", 2 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            "append", "as", "asc", "asin", "asm", "atan2", "atn", "beep", "bin", "binary", "bit",
+            "bitreset", "bitset", "bload", "bsave", "byref", "byte", "byval", "call",
+            "callocate", "case", "cbyte", "cdbl", "cdecl", "chain", "chdir", "chr", "cint",
+            "circle", "clear", "clng", "clngint", "close", "cls", "color", "command",
+            "common", "cons", "const", "continue", "cos", "cshort", "csign", "csng",
+            "csrlin", "cubyte", "cuint", "culngint", "cunsg", "curdir", "cushort", "custom",
+            "cvd", "cvi", "cvl", "cvlongint", "cvs", "cvshort", "data", "date",
+            "deallocate", "declare", "defbyte", "defdbl", "defined", "defint", "deflng",
+            "deflngint", "defshort", "defsng", "defstr", "defubyte", "defuint",
+            "defulngint", "defushort", "dim", "dir", "do", "double", "draw", "dylibload",
+            "dylibsymbol", "else", "elseif", "end", "enum", "environ", 'environ$', "eof",
+            "eqv", "erase", "err", "error", "exec", "exepath", "exit", "exp", "export",
+            "extern", "field", "fix", "flip", "for", "fre", "freefile", "function", "get",
+            "getjoystick", "getkey", "getmouse", "gosub", "goto", "hex", "hibyte", "hiword",
+            "if", "iif", "imagecreate", "imagedestroy", "imp", "inkey", "inp", "input",
+            "instr", "int", "integer", "is", "kill", "lbound", "lcase", "left", "len",
+            "let", "lib", "line", "lobyte", "loc", "local", "locate", "lock", "lof", "log",
+            "long", "longint", "loop", "loword", "lset", "ltrim", "mid", "mkd", "mkdir",
+            "mki", "mkl", "mklongint", "mks", "mkshort", "mod", "multikey", "mutexcreate",
+            "mutexdestroy", "mutexlock", "mutexunlock", "name", "next", "not", "oct", "on",
+            "once", "open", "option", "or", "out", "output", "overload", "paint", "palette",
+            "pascal", "pcopy", "peek", "peeki", "peeks", "pipe", "pmap", "point", "pointer",
+            "poke", "pokei", "pokes", "pos", "preserve", "preset", "print", "private",
+            "procptr", "pset", "ptr", "public", "put", "random", "randomize", "read",
+            "reallocate", "redim", "rem", "reset", "restore", "resume",
+            "return", "rgb", "rgba", "right", "rmdir", "rnd", "rset", "rtrim", "run",
+            "sadd", "screen", "screencopy", "screeninfo", "screenlock", "screenptr",
+            "screenres", "screenset", "screensync", "screenunlock", "seek", "statement",
+            "selectcase", "setdate", "setenviron", "setmouse",
+            "settime", "sgn", "shared", "shell", "shl", "short", "shr", "sin", "single",
+            "sizeof", "sleep", "space", "spc", "sqr", "static", "stdcall", "step", "stop",
+            "str", "string", "strptr", "sub", "swap", "system", "tab", "tan",
+            "then", "threadcreate", "threadwait", "time", "timer", "to", "trans",
+            "trim", "type", "ubound", "ubyte", "ucase", "uinteger", "ulongint", "union",
+            "unlock", "unsigned", "until", "ushort", "using", "va_arg", "va_first",
+            "va_next", "val", "val64", "valint", "varptr", "view", "viewprint", "wait",
+            "wend", "while", "width", "window", "windowtitle", "with", "write", "xor",
+            "zstring", "explicit", "escape", "true", "false"
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080;',
+            2 => 'color: #339933;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/genero.php b/examples/includes/geshi/geshi/genero.php
new file mode 100644 (file)
index 0000000..997e21f
--- /dev/null
@@ -0,0 +1,463 @@
+<?php
+/*************************************************************************************
+ * genero.php
+ * ----------
+ * Author: Lars Gersmann (lars.gersmann@gmail.com)
+ * Copyright: (c) 2007 Lars Gersmann, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/07/01
+ *
+ * Genero (FOURJ's Genero 4GL) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/07/01 (1.0.0)
+ *  -  Initial release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'genero',
+    'COMMENT_SINGLE' => array(1 => '--', 2 => '#'),
+    'COMMENT_MULTI' => array('{' => '}'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            "ABSOLUTE",
+            "ACCEPT",
+            "ACTION",
+            "ADD",
+            "AFTER",
+            "ALL",
+            "ALTER",
+            "AND",
+            "ANY",
+            "APPEND",
+            "APPLICATION",
+            "AS",
+            "AT",
+            "ATTRIBUTE",
+            "ATTRIBUTES",
+            "AUDIT",
+            "AVG",
+            "BEFORE",
+            "BEGIN",
+            "BETWEEN",
+            "BORDER",
+            "BOTTOM",
+            "BREAKPOINT",
+            "BUFFER",
+            "BUFFERED",
+            "BY",
+            "CALL",
+            "CANCEL",
+            "CASE",
+            "CENTURY",
+            "CHANGE",
+            "CHECK",
+            "CLEAR",
+            "CLIPPED",
+            "CLOSE",
+            "CLUSTER",
+            "COLUMN",
+            "COLUMNS",
+            "COMMAND",
+            "COMMENT",
+            "COMMIT",
+            "COMMITTED",
+            "CONCURRENT ",
+            "CONNECT",
+            "CONNECTION",
+            "CONSTANT",
+            "CONSTRAINED",
+            "CONSTRAINT",
+            "CONSTRUCT",
+            "CONTINUE",
+            "CONTROL",
+            "COUNT",
+            "CREATE",
+            "CROSS",
+            "CURRENT",
+            "DATABASE",
+            "DBA",
+            "DEC",
+            "DECLARE",
+            "DEFAULT",
+            "DEFAULTS",
+            "DEFER",
+            "DEFINE",
+            "DELETE",
+            "DELIMITER",
+            "DESCRIBE",
+            "DESTINATION",
+            "DIM",
+            "DIALOG",
+            "DIMENSION",
+            "DIRTY",
+            "DISCONNECT",
+            "DISPLAY",
+            "DISTINCT",
+            "DORMANT",
+            "DOWN",
+            "DROP",
+            "DYNAMIC",
+            "ELSE",
+            "END",
+            "ERROR",
+            "ESCAPE",
+            "EVERY",
+            "EXCLUSIVE",
+            "EXECUTE",
+            "EXISTS",
+            "EXIT",
+            "EXPLAIN",
+            "EXTEND",
+            "EXTENT",
+            "EXTERNAL",
+            "FETCH",
+            "FGL_DRAWBOX",
+            "FIELD",
+            "FIELD_TOUCHED",
+            "FILE",
+            "FILL",
+            "FINISH",
+            "FIRST",
+            "FLOAT",
+            "FLUSH",
+            "FOR",
+            "FOREACH",
+            "FORM",
+            "FORMAT",
+            "FOUND",
+            "FRACTION",
+            "FREE",
+            "FROM",
+            "FULL",
+            "FUNCTION",
+            "GET_FLDBUF",
+            "GLOBALS",
+            "GO",
+            "GOTO",
+            "GRANT",
+            "GROUP",
+            "HAVING",
+            "HEADER",
+            "HELP",
+            "HIDE",
+            "HOLD",
+            "HOUR",
+            "IDLE",
+            "IF",
+            "IMAGE",
+            "IMMEDIATE",
+            "IN",
+            "INDEX",
+            "INFIELD",
+            "INITIALIZE",
+            "INNER",
+            "INPUT",
+            "INSERT",
+            "INTERRUPT",
+            "INTERVAL",
+            "INTO",
+            "INVISIBLE",
+            "IS",
+            "ISOLATION",
+            "JOIN",
+            "KEEP",
+            "KEY",
+            "LABEL",
+            "LAST",
+            "LEFT",
+            "LENGTH",
+            "LET",
+            "LIKE",
+            "LINE",
+            "LINENO",
+            "LINES",
+            "LOAD",
+            "LOCATE",
+            "LOCK",
+            "LOG",
+            "LSTR",
+            "MAIN",
+            "MARGIN",
+            "MATCHES",
+            "MAX",
+            "MAXCOUNT",
+            "MDY",
+            "MEMORY",
+            "MENU",
+            "MESSAGE",
+            "MIN",
+            "MINUTE",
+            "MOD",
+            "MODE",
+            "MODIFY",
+            "MONEY",
+            "NAME",
+            "NEED",
+            "NEXT",
+            "NO",
+            "NORMAL",
+            "NOT",
+            "NOTFOUND",
+            "NULL",
+            "NUMERIC",
+            "OF",
+            "ON",
+            "OPEN",
+            "OPTION",
+            "OPTIONS",
+            "OR",
+            "ORDER",
+            "OTHERWISE",
+            "OUTER",
+            "OUTPUT",
+            "PAGE",
+            "PAGENO",
+            "PAUSE",
+            "PERCENT",
+            "PICTURE",
+            "PIPE",
+            "PRECISION",
+            "PREPARE",
+            "PREVIOUS",
+            "PRINT",
+            "PRINTER",
+            "PRINTX",
+            "PRIOR",
+            "PRIVILEGES",
+            "PROCEDURE",
+            "PROGRAM",
+            "PROMPT",
+            "PUBLIC",
+            "PUT",
+            "QUIT",
+            "READ",
+            "REAL",
+            "RECORD",
+            "RECOVER",
+            "RED ",
+            "RELATIVE",
+            "RENAME",
+            "REOPTIMIZATION",
+            "REPEATABLE",
+            "REPORT",
+            "RESOURCE",
+            "RETURN",
+            "RETURNING",
+            "REVERSE",
+            "REVOKE",
+            "RIGHT",
+            "ROLLBACK",
+            "ROLLFORWARD",
+            "ROW",
+            "ROWS",
+            "RUN",
+            "SCHEMA",
+            "SCREEN",
+            "SCROLL",
+            "SECOND",
+            "SELECT",
+            "SERIAL",
+            "SET",
+            "SFMT",
+            "SHARE",
+            "SHIFT",
+            "SHOW",
+            "SIGNAL ",
+            "SIZE",
+            "SKIP",
+            "SLEEP",
+            "SOME",
+            "SPACE",
+            "SPACES",
+            "SQL",
+            "SQLERRMESSAGE",
+            "SQLERROR",
+            "SQLSTATE",
+            "STABILITY",
+            "START",
+            "STATISTICS",
+            "STEP",
+            "STOP",
+            "STYLE",
+            "SUM",
+            "SYNONYM",
+            "TABLE",
+            "TEMP",
+            "TERMINATE",
+            "TEXT",
+            "THEN",
+            "THROUGH",
+            "THRU",
+            "TO",
+            "TODAY",
+            "TOP",
+            "TRAILER",
+            "TRANSACTION ",
+            "UNBUFFERED",
+            "UNCONSTRAINED",
+            "UNDERLINE",
+            "UNION",
+            "UNIQUE",
+            "UNITS",
+            "UNLOAD",
+            "UNLOCK",
+            "UP",
+            "UPDATE",
+            "USE",
+            "USER",
+            "USING",
+            "VALIDATE",
+            "VALUE",
+            "VALUES",
+            "VARCHAR",
+            "VIEW",
+            "WAIT",
+            "WAITING",
+            "WARNING",
+            "WHEN",
+            "WHENEVER",
+            "WHERE",
+            "WHILE",
+            "WINDOW",
+            "WITH",
+            "WITHOUT",
+            "WORDWRAP",
+            "WORK",
+            "WRAP"
+            ),
+        2 => array(
+            '&amp;IFDEF', '&amp;ENDIF'
+            ),
+        3 => array(
+            "ARRAY",
+            "BYTE",
+            "CHAR",
+            "CHARACTER",
+            "CURSOR",
+            "DATE",
+            "DATETIME",
+            "DECIMAL",
+            "DOUBLE",
+            "FALSE",
+            "INT",
+            "INTEGER",
+            "SMALLFLOAT",
+            "SMALLINT",
+            "STRING",
+            "TIME",
+            "TRUE"
+            ),
+        4 => array(
+            "BLACK",
+            "BLINK",
+            "BLUE",
+            "BOLD",
+            "ANSI",
+            "ASC",
+            "ASCENDING",
+            "ASCII",
+            "CYAN",
+            "DESC",
+            "DESCENDING",
+            "GREEN",
+            "MAGENTA",
+            "OFF",
+            "WHITE",
+            "YELLOW",
+            "YEAR",
+            "DAY",
+            "MONTH",
+            "WEEKDAY"
+            ),
+        ),
+    'SYMBOLS' => array(
+        '+', '-', '*', '?', '=', '/', '%', '>', '<', '^', '!', '|', ':',
+        '(', ')', '[', ']'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0600FF;',
+            2 => 'color: #0000FF; font-weight: bold;',
+            3 => 'color: #008000;',
+            4 => 'color: #FF0000;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008080; font-style: italic;',
+            2 => 'color: #008080;',
+            'MULTI' => 'color: #008080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008080; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #808080;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000FF;',
+            2 => 'color: #0000FF;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/gettext.php b/examples/includes/geshi/geshi/gettext.php
new file mode 100644 (file)
index 0000000..78e8bff
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+/*************************************************************************************
+ * gettext.php
+ * --------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/05/25
+ *
+ * GNU Gettext .po/.pot language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/02 (1.0.8)
+ *  -  New comments: flags and previous-fields
+ *  -  New keywords: msgctxt, msgid_plural
+ *  -  Msgstr array indices
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'GNU Gettext',
+    'COMMENT_SINGLE' => array('#:', '#.', '#,', '#|', '#'),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array('msgctxt', 'msgid_plural', 'msgid', 'msgstr'),
+    ),
+    'SYMBOLS' => array(),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+    ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;'
+        ),
+        'COMMENTS' => array(
+            0 => 'color: #000099;',
+            1 => 'color: #000099;',
+            2 => 'color: #000099;',
+            3 => 'color: #006666;',
+            4 => 'color: #666666; font-style: italic;',
+        ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+        ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+        ),
+        'REGEXPS' => array(),
+        'SYMBOLS' => array(),
+        'NUMBERS' => array(
+            0 => 'color: #000099;'
+        ),
+        'METHODS' => array(),
+        'SCRIPT' => array(),
+        'BRACKETS' => array(
+            0 => 'color: #000099;'
+        ),
+    ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/glsl.php b/examples/includes/geshi/geshi/glsl.php
new file mode 100644 (file)
index 0000000..1f10cf8
--- /dev/null
@@ -0,0 +1,205 @@
+<?php
+/*************************************************************************************
+ * glsl.php
+ * -----
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2008 Benny Baumann (BenBE@omorphia.de)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/03/20
+ *
+ * glSlang language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/03/20 (1.0.7.21)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'glSlang',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Multiline-continued single-line comments
+        1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        //Multiline-continued preprocessor define
+        2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'if', 'else', 'for', 'while', 'do', 'break', 'continue', 'asm',
+            'switch', 'case', 'default', 'return', 'discard',
+            'namespace', 'using', 'sizeof', 'cast'
+            ),
+        2 => array(
+            'const', 'uniform', 'attribute', 'centroid', 'varying', 'invariant',
+            'in', 'out', 'inout', 'input', 'output', 'typedef', 'volatile',
+            'public', 'static', 'extern', 'external', 'packed',
+            'inline', 'noinline', 'noperspective', 'flat'
+            ),
+        3 => array(
+            'void', 'bool', 'int', 'long', 'short', 'float', 'half', 'fixed',
+            'unsigned', 'lowp', 'mediump', 'highp', 'precision',
+            'vec2', 'vec3', 'vec4', 'bvec2', 'bvec3', 'bvec4',
+            'dvec2', 'dvec3', 'dvec4', 'fvec2', 'fvec3', 'fvec4',
+            'hvec2', 'hvec3', 'hvec4', 'ivec2', 'ivec3', 'ivec4',
+            'mat2', 'mat3', 'mat4', 'mat2x2', 'mat3x2', 'mat4x2',
+            'mat2x3', 'mat3x3', 'mat4x3', 'mat2x4', 'mat3x4', 'mat4x4',
+            'sampler1D', 'sampler2D', 'sampler3D', 'samplerCube',
+            'sampler1DShadow', 'sampler2DShadow',
+            'struct', 'class', 'union', 'enum', 'interface', 'template'
+            ),
+        4 => array(
+            'this', 'false', 'true'
+            ),
+        5 => array(
+            'radians', 'degrees', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan',
+            'pow', 'exp2', 'log2', 'sqrt', 'inversesqrt', 'abs', 'sign', 'ceil',
+            'floor', 'fract', 'mod', 'min', 'max', 'clamp', 'mix', 'step',
+            'smoothstep', 'length', 'distance', 'dot', 'cross', 'normalize',
+            'ftransform', 'faceforward', 'reflect', 'matrixCompMult', 'equal',
+            'lessThan', 'lessThanEqual', 'greaterThan', 'greaterThanEqual',
+            'notEqual', 'any', 'all', 'not', 'texture1D', 'texture1DProj',
+            'texture1DLod', 'texture1DProjLod', 'texture2D', 'texture2DProj',
+            'texture2DLod', 'texture2DProjLod', 'texture3D', 'texture3DProj',
+            'texture3DLod', 'texture3DProjLod', 'textureCube', 'textureCubeLod',
+            'shadow1D', 'shadow1DProj', 'shadow1DLod', 'shadow1DProjLod',
+            'shadow2D', 'shadow2DProj', 'shadow2DLod', 'shadow2DProjLod',
+            'noise1', 'noise2', 'noise3', 'noise4'
+            ),
+        6 => array(
+            'gl_Position', 'gl_PointSize', 'gl_ClipVertex', 'gl_FragColor',
+            'gl_FragData', 'gl_FragDepth', 'gl_FragCoord', 'gl_FrontFacing',
+            'gl_Color', 'gl_SecondaryColor', 'gl_Normal', 'gl_Vertex',
+            'gl_MultiTexCoord0', 'gl_MultiTexCoord1', 'gl_MultiTexCoord2',
+            'gl_MultiTexCoord3', 'gl_MultiTexCoord4', 'gl_MultiTexCoord5',
+            'gl_MultiTexCoord6', 'gl_MultiTexCoord7', 'gl_FogCoord',
+            'gl_MaxLights', 'gl_MaxClipPlanes', 'gl_MaxTextureUnits',
+            'gl_MaxTextureCoords', 'gl_MaxVertexAttribs', 'gl_MaxVaryingFloats',
+            'gl_MaxVertexUniformComponents', 'gl_MaxVertexTextureImageUnits',
+            'gl_MaxCombinedTextureImageUnits', 'gl_MaxTextureImageUnits',
+            'gl_MaxFragmentUniformComponents', 'gl_MaxDrawBuffers', 'gl_Point',
+            'gl_ModelViewMatrix', 'gl_ProjectionMatrix', 'gl_FrontMaterial',
+            'gl_ModelViewProjectionMatrix', 'gl_TextureMatrix', 'gl_ClipPlane',
+            'gl_NormalMatrix', 'gl_ModelViewMatrixInverse', 'gl_BackMaterial',
+            'gl_ProjectionMatrixInverse', 'gl_ModelViewProjectionMatrixInverse',
+            'gl_TextureMatrixInverse', 'gl_ModelViewMatrixTranspose', 'gl_Fog',
+            'gl_ProjectionMatrixTranspose', 'gl_NormalScale', 'gl_DepthRange',
+            'gl_odelViewProjectionMatrixTranspose', 'gl_TextureMatrixTranspose',
+            'gl_ModelViewMatrixInverseTranspose', 'gl_LightSource',
+            'gl_ProjectionMatrixInverseTranspose', 'gl_LightModel',
+            'gl_ModelViewProjectionMatrixInverseTranspose', 'gl_TexCoord',
+            'gl_TextureMatrixInverseTranspose', 'gl_TextureEnvColor',
+            'gl_FrontLightModelProduct', 'gl_BackLightModelProduct',
+            'gl_FrontLightProduct', 'gl_BackLightProduct', 'gl_ObjectPlaneS',
+            'gl_ObjectPlaneT', 'gl_ObjectPlaneR', 'gl_ObjectPlaneQ',
+            'gl_EyePlaneS', 'gl_EyePlaneT', 'gl_EyePlaneR', 'gl_EyePlaneQ',
+            'gl_FrontColor', 'gl_BackColor', 'gl_FrontSecondaryColor',
+            'gl_BackSecondaryColor', 'gl_FogFragCoord', 'gl_PointCoord'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^',
+        '&', '?', ':', '.', '|', ';', ',', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #333399; font-weight: bold;',
+            3 => 'color: #000066; font-weight: bold;',
+            4 => 'color: #333399; font-weight: bold;',
+            5 => 'color: #993333; font-weight: bold;',
+            6 => 'color: #551111;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #009900;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000066;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'OOLANG' => array(
+            'MATCH_BEFORE' => '',
+            'MATCH_AFTER' => '[a-zA-Z_][a-zA-Z0-9_]*',
+            'MATCH_SPACES' => '[\s]*'
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/gml.php b/examples/includes/geshi/geshi/gml.php
new file mode 100644 (file)
index 0000000..77966bc
--- /dev/null
@@ -0,0 +1,506 @@
+<?php
+/*************************************************************************************
+ * gml.php
+ * --------
+ * Author: Jos� Jorge Enr�quez (jenriquez@users.sourceforge.net)
+ * Copyright: (c) 2005 Jos� Jorge Enr�quez Rodr�guez (http://www.zonamakers.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/06/21
+ *
+ * GML language file for GeSHi.
+ *
+ * GML (Game Maker Language) is a script language that is built-in into Game Maker,
+ * a game creation program, more info about Game Maker can be found at
+ * http://www.gamemaker.nl/
+ * All GML keywords were extracted from the Game Maker HTML Help file using a PHP
+ * script (one section at a time). I love PHP for saving me that bunch of work :P!.
+ * I think all GML functions have been indexed here, but I'm not sure about it, so
+ * please let me know of any issue you may find.
+ *
+ * CHANGES
+ * -------
+ * 2005/11/11
+ *  -  Changed 'CASE_KEYWORDS' fom 'GESHI_CAPS_LOWER' to 'GESHI_CAPS_NO_CHANGE',
+ *     so that MCI_command appears correctly (the only GML function using capitals).
+ *  -  Changed 'CASE_SENSITIVE' options, 'GESHI_COMMENTS' from true to false and all
+ *     of the others from false to true.
+ *  -  Deleted repeated entries.
+ *  -  div and mod are language keywords, moved (from symbols) to the appropiate section (1).
+ *  -  Moved self, other, all, noone and global identifiers to language keywords section 1.
+ *  -  Edited this file lines to a maximum width of 100 characters (as stated in
+ *     the GeSHi docs). Well, not strictly to 100 but around it.
+ *  -  Corrected some minor issues (the vk_f1...vk_f12 keys and similar).
+ *  -  Deleted the KEYWORDS=>5 and KEYWORDS=>6 sections (actually, they were empty).
+ *     I was planning of using those for the GML functions available only in the
+ *     registered version of the program, but not anymore.
+ *
+ * 2005/06/26 (1.0.3)
+ *  -  First Release.
+ *
+ * TODO (updated 2005/11/11)
+ * -------------------------
+ *  -  Test it for a while and make the appropiate corrections.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'GML',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'"),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        // language keywords
+        1 => array(
+            'break', 'continue', 'do', 'until', 'if', 'else',
+            'exit', 'for', 'repeat', 'return', 'switch',
+            'case', 'default', 'var', 'while', 'with', 'div', 'mod',
+            // GML Language overview
+            'self', 'other', 'all', 'noone', 'global',
+            ),
+        // modifiers and built-in variables
+        2 => array(
+            // Game play
+            'x','y','xprevious','yprevious','xstart','ystart','hspeed','vspeed','direction','speed',
+            'friction','gravity','gravity_direction',
+            'path_index','path_position','path_positionprevious','path_speed','path_orientation',
+            'path_endaction',
+            'object_index','id','mask_index','solid','persistent','instance_count','instance_id',
+            'room_speed','fps','current_time','current_year','current_month','current_day','current_weekday',
+            'current_hour','current_minute','current_second','alarm','timeline_index','timeline_position',
+            'timeline_speed',
+            'room','room_first','room_last','room_width','room_height','room_caption','room_persistent',
+            'score','lives','health','show_score','show_lives','show_health','caption_score','caption_lives',
+            'caption_health',
+            'event_type','event_number','event_object','event_action',
+            'error_occurred','error_last',
+            // User interaction
+            'keyboard_lastkey','keyboard_key','keyboard_lastchar','keyboard_string',
+            'mouse_x','mouse_y','mouse_button','mouse_lastbutton',
+            // Game Graphics
+            'sprite_index','sprite_width','sprite_height','sprite_xoffset','sprite_yoffset',
+            'image_number','image_index','image_speed','image_xscale','image_yscale','image_angle',
+            'image_alpha','image_blend','bbox_left','bbox_right','bbox_top','bbox_bottom',
+            'background_color','background_showcolor','background_visible','background_foreground',
+            'background_index','background_x','background_y','background_width','background_height',
+            'background_htiled','background_vtiled','background_xscale','background_yscale',
+            'background_hspeed','background_vspeed','background_blend','background_alpha',
+            'background','left, top, width, height','depth','visible','xscale','yscale','blend','alpha',
+            'view_enabled','view_current','view_visible','view_yview','view_wview','view_hview','view_xport',
+            'view_yport','view_wport','view_hport','view_angle','view_hborder','view_vborder','view_hspeed',
+            'view_vspeed','view_object',
+            'transition_kind',
+            // Files, registry and executing programs
+            'game_id','working_directory','temp_directory',
+            'secure_mode',
+            // Creating particles
+            'xmin', 'xmax', 'ymin', 'ymax','shape','distribution','particle type','number',
+            'force','dist','kind','additive', 'parttype1', 'parttype2'
+            ),
+        // functions
+        3 => array(
+            // Computing things
+            'random','choose','abs','sign','round','floor','ceil','frac','sqrt','sqr','power','exp','ln',
+            'log2','log10','logn','sin','cos','tan','arcsin','arccos','arctan','arctan2','degtorad',
+            'radtodeg','min','max','mean','median','point_distance','point_direction','lengthdir_x',
+            'lengthdir_y','is_real','is_string',
+            'chr','ord','real','string','string_format','string_length','string_pos','string_copy',
+            'string_char_at','string_delete','string_insert','string_replace','string_replace_all',
+            'string_count','string_lower','string_upper','string_repeat','string_letters','string_digits',
+            'string_lettersdigits','clipboard_has_text','clipboard_get_text','clipboard_set_text',
+            'date_current_datetime','date_current_date','date_current_time','date_create_datetime',
+            'date_create_date','date_create_time','date_valid_datetime','date_valid_date','date_valid_time',
+            'date_inc_year','date_inc_month','date_inc_week','date_inc_day','date_inc_hour',
+            'date_inc_minute','date_inc_second','date_get_year','date_get_month','date_get_week',
+            'date_get_day','date_get_hour', 'date_get_minute','date_get_second','date_get_weekday',
+            'date_get_day_of_year','date_get_hour_of_year','date_get_minute_of_year',
+            'date_get_second_of_year','date_year_span','date_month_span','date_week_span','date_day_span',
+            'date_hour_span','date_minute_span','date_second_span','date_compare_datetime',
+            'date_compare_date','date_compare_time','date_date_of','date_time_of','date_datetime_string',
+            'date_date_string','date_time_string','date_days_in_month','date_days_in_year','date_leap_year',
+            'date_is_today',
+            // Game play
+            'motion_set','motion_add','place_free','place_empty','place_meeting','place_snapped',
+            'move_random','move_snap','move_wrap','move_towards_point','move_bounce_solid','move_bounce_all',
+            'move_contact_solid','move_contact_all','move_outside_solid','move_outside_all',
+            'distance_to_point','distance_to_object','position_empty','position_meeting',
+            'path_start','path_end',
+            'mp_linear_step','mp_linear_step_object','mp_potential_step','mp_potential_step_object',
+            'mp_potential_settings','mp_linear_path','mp_linear_path_object', 'mp_potential_path',
+            'mp_potential_path_object','mp_grid_create','mp_grid_destroy','mp_grid_clear_all',
+            'mp_grid_clear_cell','mp_grid_clear_rectangle','mp_grid_add_cell','mp_grid_add_rectangle',
+            'mp_grid_add_instances','mp_grid_path','mp_grid_draw',
+            'collision_point','collision_rectangle','collision_circle','collision_ellipse','collision_line',
+            'instance_find','instance_exists','instance_number','instance_position','instance_nearest',
+            'instance_furthest','instance_place','instance_create','instance_copy','instance_destroy',
+            'instance_change','position_destroy','position_change',
+            'instance_deactivate_all','instance_deactivate_object','instance_deactivate_region',
+            'instance_activate_all','instance_activate_object','instance_activate_region',
+            'sleep',
+            'room_goto','room_goto_previous','room_goto_next','room_restart','room_previous','room_next',
+            'game_end','game_restart','game_save','game_load',
+            'event_perform', 'event_perform_object','event_user','event_inherited',
+            'show_debug_message','variable_global_exists','variable_local_exists','variable_global_get',
+            'variable_global_array_get','variable_global_array2_get','variable_local_get',
+            'variable_local_array_get','variable_local_array2_get','variable_global_set',
+            'variable_global_array_set','variable_global_array2_set','variable_local_set',
+            'variable_local_array_set','variable_local_array2_set','set_program_priority',
+            // User interaction
+            'keyboard_set_map','keyboard_get_map','keyboard_unset_map','keyboard_check',
+            'keyboard_check_pressed','keyboard_check_released','keyboard_check_direct',
+            'keyboard_get_numlock','keyboard_set_numlock','keyboard_key_press','keyboard_key_release',
+            'keyboard_clear','io_clear','io_handle','keyboard_wait',
+            'mouse_check_button','mouse_check_button_pressed','mouse_check_button_released','mouse_clear',
+            'mouse_wait',
+            'joystick_exists','joystick_name','joystick_axes','joystick_buttons','joystick_has_pov',
+            'joystick_direction','joystick_check_button','joystick_xpos','joystick_ypos','joystick_zpos',
+            'joystick_rpos','joystick_upos','joystick_vpos','joystick_pov',
+            // Game Graphics
+            'draw_sprite','draw_sprite_stretched','draw_sprite_tiled','draw_sprite_part','draw_background',
+            'draw_background_stretched','draw_background_tiled','draw_background_part','draw_sprite_ext',
+            'draw_sprite_stretched_ext','draw_sprite_tiled_ext','draw_sprite_part_ext','draw_sprite_general',
+            'draw_background_ext','draw_background_stretched_ext','draw_background_tiled_ext',
+            'draw_background_part_ext','draw_background_general',
+            'draw_clear','draw_clear_alpha','draw_point','draw_line','draw_rectangle','draw_roundrect',
+            'draw_triangle','draw_circle','draw_ellipse','draw_arrow','draw_button','draw_path',
+            'draw_healthbar','draw_set_color','draw_set_alpha','draw_get_color','draw_get_alpha',
+            'make_color_rgb','make_color_hsv','color_get_red','color_get_green','color_get_blue',
+            'color_get_hue','color_get_saturation','color_get_value','merge_color','draw_getpixel',
+            'screen_save','screen_save_part',
+            'draw_set_font','draw_set_halign','draw_set_valign','draw_text','draw_text_ext','string_width',
+            'string_height','string_width_ext','string_height_ext','draw_text_transformed',
+            'draw_text_ext_transformed','draw_text_color','draw_text_ext_color',
+            'draw_text_transformed_color','draw_text_ext_transformed_color',
+            'draw_point_color','draw_line_color','draw_rectangle_color','draw_roundrect_color',
+            'draw_triangle_color','draw_circle_color','draw_ellipse_color','draw_primitive_begin',
+            'draw_vertex','draw_vertex_color','draw_primitive_end','sprite_get_texture',
+            'background_get_texture','texture_preload','texture_set_priority',
+            'texture_get_width','texture_get_height','draw_primitive_begin_texture','draw_vertex_texture',
+            'draw_vertex_texture_color','texture_set_interpolation',
+            'texture_set_blending','texture_set_repeat','draw_set_blend_mode','draw_set_blend_mode_ext',
+            'surface_create','surface_free','surface_exists','surface_get_width','surface_get_height',
+            'surface_get_texture','surface_set_target','surface_reset_target','surface_getpixel',
+            'surface_save','surface_save_part','draw_surface','draw_surface_stretched','draw_surface_tiled',
+            'draw_surface_part','draw_surface_ext','draw_surface_stretched_ext','draw_surface_tiled_ext',
+            'draw_surface_part_ext','draw_surface_general','surface_copy','surface_copy_part',
+            'tile_add','tile_delete','tile_exists','tile_get_x','tile_get_y','tile_get_left','tile_get_top',
+            'tile_get_width','tile_get_height','tile_get_depth','tile_get_visible','tile_get_xscale',
+            'tile_get_yscale','tile_get_background','tile_get_blend','tile_get_alpha','tile_set_position',
+            'tile_set_region','tile_set_background','tile_set_visible','tile_set_depth','tile_set_scale',
+            'tile_set_blend','tile_set_alpha','tile_layer_hide','tile_layer_show','tile_layer_delete',
+            'tile_layer_shift','tile_layer_find','tile_layer_delete_at','tile_layer_depth',
+            'display_get_width','display_get_height','display_get_colordepth','display_get_frequency',
+            'display_set_size','display_set_colordepth','display_set_frequency','display_set_all',
+            'display_test_all','display_reset','display_mouse_get_x','display_mouse_get_y','display_mouse_set',
+            'window_set_visible','window_get_visible','window_set_fullscreen','window_get_fullscreen',
+            'window_set_showborder','window_get_showborder','window_set_showicons','window_get_showicons',
+            'window_set_stayontop','window_get_stayontop','window_set_sizeable','window_get_sizeable',
+            'window_set_caption','window_get_caption','window_set_cursor', 'window_get_cursor',
+            'window_set_color','window_get_color','window_set_region_scale','window_get_region_scale',
+            'window_set_position','window_set_size','window_set_rectangle','window_center','window_default',
+            'window_get_x','window_get_y','window_get_width','window_get_height','window_mouse_get_x',
+            'window_mouse_get_y','window_mouse_set',
+            'window_set_region_size','window_get_region_width','window_get_region_height',
+            'window_view_mouse_get_x','window_view_mouse_get_y','window_view_mouse_set',
+            'window_views_mouse_get_x','window_views_mouse_get_y','window_views_mouse_set',
+            'screen_redraw','screen_refresh','set_automatic_draw','set_synchronization','screen_wait_vsync',
+            // Sound and music)
+            'sound_play','sound_loop','sound_stop','sound_stop_all','sound_isplaying','sound_volume',
+            'sound_global_volume','sound_fade','sound_pan','sound_background_tempo','sound_set_search_directory',
+            'sound_effect_set','sound_effect_chorus','sound_effect_echo',    'sound_effect_flanger',
+            'sound_effect_gargle','sound_effect_reverb','sound_effect_compressor','sound_effect_equalizer',
+            'sound_3d_set_sound_position','sound_3d_set_sound_velocity','sound_3d_set_sound_distance',
+            'sound_3d_set_sound_cone',
+            'cd_init','cd_present','cd_number','cd_playing','cd_paused','cd_track','cd_length',
+            'cd_track_length','cd_position','cd_track_position','cd_play','cd_stop','cd_pause','cd_resume',
+            'cd_set_position','cd_set_track_position','cd_open_door','cd_close_door','MCI_command',
+            // Splash screens, highscores, and other pop-ups
+            'show_text','show_image','show_video','show_info','load_info',
+            'show_message','show_message_ext','show_question','get_integer','get_string',
+            'message_background','message_alpha','message_button','message_text_font','message_button_font',
+            'message_input_font','message_mouse_color','message_input_color','message_caption',
+            'message_position','message_size','show_menu','show_menu_pos','get_color','get_open_filename',
+            'get_save_filename','get_directory','get_directory_alt','show_error',
+            'highscore_show','highscore_set_background','highscore_set_border','highscore_set_font',
+            'highscore_set_colors','highscore_set_strings','highscore_show_ext','highscore_clear',
+            'highscore_add','highscore_add_current','highscore_value','highscore_name','draw_highscore',
+            // Resources
+            'sprite_exists','sprite_get_name','sprite_get_number','sprite_get_width','sprite_get_height',
+            'sprite_get_transparent','sprite_get_smooth','sprite_get_preload','sprite_get_xoffset',
+            'sprite_get_yoffset','sprite_get_bbox_left','sprite_get_bbox_right','sprite_get_bbox_top',
+            'sprite_get_bbox_bottom','sprite_get_bbox_mode','sprite_get_precise',
+            'sound_exists','sound_get_name','sound_get_kind','sound_get_preload','sound_discard',
+            'sound_restore',
+            'background_exists','background_get_name','background_get_width','background_get_height',
+            'background_get_transparent','background_get_smooth','background_get_preload',
+            'font_exists','font_get_name','font_get_fontname','font_get_bold','font_get_italic',
+            'font_get_first','font_get_last',
+            'path_exists','path_get_name','path_get_length','path_get_kind','path_get_closed',
+            'path_get_precision','path_get_number','path_get_point_x','path_get_point_y',
+            'path_get_point_speed','path_get_x','path_get_y','path_get_speed',
+            'script_exists','script_get_name','script_get_text',
+            'timeline_exists','timeline_get_name',
+            'object_exists','object_get_name','object_get_sprite','object_get_solid','object_get_visible',
+            'object_get_depth','object_get_persistent','object_get_mask','object_get_parent',
+            'object_is_ancestor',
+            'room_exists','room_get_name',
+            // Changing resources
+            'sprite_set_offset','sprite_set_bbox_mode','sprite_set_bbox','sprite_set_precise',
+            'sprite_duplicate','sprite_assign','sprite_merge','sprite_add','sprite_replace',
+            'sprite_create_from_screen','sprite_add_from_screen','sprite_create_from_surface',
+            'sprite_add_from_surface','sprite_delete','sprite_set_alpha_from_sprite',
+            'sound_add','sound_replace','sound_delete',
+            'background_duplicate','background_assign','background_add','background_replace',
+            'background_create_color','background_create_gradient','background_create_from_screen',
+            'background_create_from_surface','background_delete','background_set_alpha_from_background',
+            'font_add','font_add_sprite','font_replace_sprite','font_delete',
+            'path_set_kind','path_set_closed','path_set_precision','path_add','path_delete','path_duplicate',
+            'path_assign','path_append','path_add_point','path_insert_point','path_change_point',
+            'path_delete_point','path_clear_points','path_reverse','path_mirror','path_flip','path_rotate',
+            'path_scale','path_shift',
+            'execute_string','execute_file','script_execute',
+            'timeline_add','timeline_delete','timeline_moment_add','timeline_moment_clear',
+            'object_set_sprite','object_set_solid','object_set_visible','object_set_depth',
+            'object_set_persistent','object_set_mask','object_set_parent','object_add','object_delete',
+            'object_event_add','object_event_clear',
+            'room_set_width','room_set_height','room_set_caption','room_set_persistent','room_set_code',
+            'room_set_background_color','room_set_background','room_set_view','room_set_view_enabled',
+            'room_add','room_duplicate','room_assign','room_instance_add','room_instance_clear',
+            'room_tile_add','room_tile_add_ext','room_tile_clear',
+            // Files, registry and executing programs
+            'file_text_open_read','file_text_open_write','file_text_open_append','file_text_close',
+            'file_text_write_string','file_text_write_real','file_text_writeln','file_text_read_string',
+            'file_text_read_real','file_text_readln','file_text_eof','file_exists','file_delete',
+            'file_rename','file_copy','directory_exists','directory_create','file_find_first',
+            'file_find_next','file_find_close','file_attributes', 'filename_name','filename_path',
+            'filename_dir','filename_drive','filename_ext','filename_change_ext','file_bin_open',
+            'file_bin_rewrite','file_bin_close','file_bin_size','file_bin_position','file_bin_seek',
+            'file_bin_write_byte','file_bin_read_byte','parameter_count','parameter_string',
+            'environment_get_variable',
+            'registry_write_string','registry_write_real','registry_read_string','registry_read_real',
+            'registry_exists','registry_write_string_ext','registry_write_real_ext',
+            'registry_read_string_ext','registry_read_real_ext','registry_exists_ext','registry_set_root',
+            'ini_open','ini_close','ini_read_string','ini_read_real','ini_write_string','ini_write_real',
+            'ini_key_exists','ini_section_exists','ini_key_delete','ini_section_delete',
+            'execute_program','execute_shell',
+            // Data structures
+            'ds_stack_create','ds_stack_destroy','ds_stack_clear','ds_stack_size','ds_stack_empty',
+            'ds_stack_push','ds_stack_pop','ds_stack_top',
+            'ds_queue_create','ds_queue_destroy','ds_queue_clear','ds_queue_size','ds_queue_empty',
+            'ds_queue_enqueue','ds_queue_dequeue','ds_queue_head','ds_queue_tail',
+            'ds_list_create','ds_list_destroy','ds_list_clear','ds_list_size','ds_list_empty','ds_list_add',
+            'ds_list_insert','ds_list_replace','ds_list_delete','ds_list_find_index','ds_list_find_value',
+            'ds_list_sort',
+            'ds_map_create','ds_map_destroy','ds_map_clear','ds_map_size','ds_map_empty','ds_map_add',
+            'ds_map_replace','ds_map_delete','ds_map_exists','ds_map_find_value','ds_map_find_previous',
+            'ds_map_find_next','ds_map_find_first','ds_map_find_last',
+            'ds_priority_create','ds_priority_destroy','ds_priority_clear','ds_priority_size',
+            'ds_priority_empty','ds_priority_add','ds_priority_change_priority','ds_priority_find_priority',
+            'ds_priority_delete_value','ds_priority_delete_min','ds_priority_find_min',
+            'ds_priority_delete_max','ds_priority_find_max',
+            'ds_grid_create','ds_grid_destroy','ds_grid_resize','ds_grid_width','ds_grid_height',
+            'ds_grid_clear','ds_grid_set','ds_grid_add','ds_grid_multiply','ds_grid_set_region',
+            'ds_grid_add_region','ds_grid_multiply_region','ds_grid_set_disk','ds_grid_add_disk',
+            'ds_grid_multiply_disk','ds_grid_get','ds_grid_get_sum','ds_grid_get_max','ds_grid_get_min',
+            'ds_grid_get_mean','ds_grid_get_disk_sum','ds_grid_get_disk_min','ds_grid_get_disk_max',
+            'ds_grid_get_disk_mean','ds_grid_value_exists','ds_grid_value_x','ds_grid_value_y',
+            'ds_grid_value_disk_exists','ds_grid_value_disk_x','ds_grid_value_disk_y',
+            // Creating particles
+            'effect_create_below','effect_create_above','effect_clear',
+            'part_type_create','part_type_destroy','part_type_exists','part_type_clear','part_type_shape',
+            'part_type_sprite','part_type_size','part_type_scale',
+            'part_type_orientation','part_type_color1','part_type_color2','part_type_color3',
+            'part_type_color_mix','part_type_color_rgb','part_type_color_hsv',
+            'part_type_alpha1','part_type_alpha2','part_type_alpha3','part_type_blend','part_type_life',
+            'part_type_step','part_type_death','part_type_speed','part_type_direction','part_type_gravity',
+            'part_system_create','part_system_destroy','part_system_exists','part_system_clear',
+            'part_system_draw_order','part_system_depth','part_system_position',
+            'part_system_automatic_update','part_system_automatic_draw','part_system_update',
+            'part_system_drawit','part_particles_create','part_particles_create_color',
+            'part_particles_clear','part_particles_count',
+            'part_emitter_create','part_emitter_destroy','part_emitter_destroy_all','part_emitter_exists',
+            'part_emitter_clear','part_emitter_region','part_emitter_burst','part_emitter_stream',
+            'part_attractor_create','part_attractor_destroy','part_attractor_destroy_all',
+            'part_attractor_exists','part_attractor_clear','part_attractor_position','part_attractor_force',
+            'part_destroyer_create','part_destroyer_destroy','part_destroyer_destroy_all',
+            'part_destroyer_exists','part_destroyer_clear','part_destroyer_region',
+            'part_deflector_create','part_deflector_destroy','part_deflector_destroy_all',
+            'part_deflector_exists','part_deflector_clear','part_deflector_region','part_deflector_kind',
+            'part_deflector_friction',
+            'part_changer_create','part_changer_destroy','part_changer_destroy_all','part_changer_exists',
+            'part_changer_clear','part_changer_region','part_changer_types','part_changer_kind',
+            // Multiplayer games
+            'mplay_init_ipx','mplay_init_tcpip','mplay_init_modem','mplay_init_serial',
+            'mplay_connect_status','mplay_end','mplay_ipaddress',
+            'mplay_session_create','mplay_session_find','mplay_session_name','mplay_session_join',
+            'mplay_session_mode','mplay_session_status','mplay_session_end',
+            'mplay_player_find','mplay_player_name','mplay_player_id',
+            'mplay_data_write','mplay_data_read','mplay_data_mode',
+            'mplay_message_send','mplay_message_send_guaranteed','mplay_message_receive','mplay_message_id',
+            'mplay_message_value','mplay_message_player','mplay_message_name','mplay_message_count',
+            'mplay_message_clear',
+            // Using DLL's
+            'external_define','external_call','external_free','window_handle',
+            // 3D Graphics
+            'd3d_start','d3d_end','d3d_set_hidden','d3d_set_perspective',
+            'd3d_set_depth',
+            'd3d_primitive_begin','d3d_vertex','d3d_vertex_color','d3d_primitive_end',
+            'd3d_primitive_begin_texture','d3d_vertex_texture','d3d_vertex_texture_color','d3d_set_culling',
+            'd3d_draw_block','d3d_draw_cylinder','d3d_draw_cone','d3d_draw_ellipsoid','d3d_draw_wall',
+            'd3d_draw_floor',
+            'd3d_set_projection','d3d_set_projection_ext','d3d_set_projection_ortho',
+            'd3d_set_projection_perspective',
+            'd3d_transform_set_identity','d3d_transform_set_translation','d3d_transform_set_scaling',
+            'd3d_transform_set_rotation_x','d3d_transform_set_rotation_y','d3d_transform_set_rotation_z',
+            'd3d_transform_set_rotation_axis','d3d_transform_add_translation','d3d_transform_add_scaling',
+            'd3d_transform_add_rotation_x','d3d_transform_add_rotation_y','d3d_transform_add_rotation_z',
+            'd3d_transform_add_rotation_axis','d3d_transform_stack_clear','d3d_transform_stack_empty',
+            'd3d_transform_stack_push','d3d_transform_stack_pop','d3d_transform_stack_top',
+            'd3d_transform_stack_discard',
+            'd3d_set_fog',
+            'd3d_set_lighting','d3d_set_shading','d3d_light_define_direction','d3d_light_define_point',
+            'd3d_light_enable','d3d_vertex_normal','d3d_vertex_normal_color','d3d_vertex_normal_texture',
+            'd3d_vertex_normal_texture_color',
+            'd3d_model_create','d3d_model_destroy','d3d_model_clear','d3d_model_save','d3d_model_load',
+            'd3d_model_draw','d3d_model_primitive_begin','d3d_model_vertex','d3d_model_vertex_color',
+            'd3d_model_vertex_texture','d3d_model_vertex_texture_color','d3d_model_vertex_normal',
+            'd3d_model_vertex_normal_color','d3d_model_vertex_normal_texture',
+            'd3d_model_vertex_normal_texture_color','d3d_model_primitive_end','d3d_model_block',
+            'd3d_model_cylinder','d3d_model_cone','d3d_model_ellipsoid','d3d_model_wall','d3d_model_floor'
+            ),
+        // constants
+        4 => array(
+            'true', 'false', 'pi',
+            'ev_destroy','ev_step','ev_alarm','ev_keyboard','ev_mouse','ev_collision','ev_other','ev_draw',
+            'ev_keypress','ev_keyrelease','ev_left_button','ev_right_button','ev_middle_button',
+            'ev_no_button','ev_left_press','ev_right_press','ev_middle_press','ev_left_release',
+            'ev_right_release','ev_middle_release','ev_mouse_enter','ev_mouse_leave','ev_mouse_wheel_up',
+            'ev_mouse_wheel_down','ev_global_left_button','ev_global_right_button','ev_global_middle_button',
+            'ev_global_left_press','ev_global_right_press','ev_global_middle_press','ev_global_left_release',
+            'ev_global_right_release','ev_global_middle_release','ev_joystick1_left','ev_joystick1_right',
+            'ev_joystick1_up','ev_joystick1_down','ev_joystick1_button1','ev_joystick1_button2',
+            'ev_joystick1_button3','ev_joystick1_button4','ev_joystick1_button5','ev_joystick1_button6',
+            'ev_joystick1_button7','ev_joystick1_button8','ev_joystick2_left','ev_joystick2_right',
+            'ev_joystick2_up','ev_joystick2_down','ev_joystick2_button1','ev_joystick2_button2',
+            'ev_joystick2_button3','ev_joystick2_button4','ev_joystick2_button5','ev_joystick2_button6',
+            'ev_joystick2_button7','ev_joystick2_button8',
+            'ev_outside','ev_boundary','ev_game_start','ev_game_end','ev_room_start','ev_room_end',
+            'ev_no_more_lives','ev_no_more_health','ev_animation_end','ev_end_of_path','ev_user0','ev_user1',
+            'ev_user2','ev_user3','ev_user4','ev_user5','ev_user6','ev_user7','ev_user8','ev_user9',
+            'ev_user10','ev_user11','ev_user12','ev_user13','ev_user14','ev_user15','ev_step_normal',
+            'ev_step_begin','ev_step_end',
+            'vk_nokey','vk_anykey','vk_left','vk_right','vk_up','vk_down','vk_enter','vk_escape','vk_space',
+            'vk_shift','vk_control','vk_alt','vk_backspace','vk_tab','vk_home','vk_end','vk_delete',
+            'vk_insert','vk_pageup','vk_pagedown','vk_pause','vk_printscreen',
+            'vk_f1','vk_f2','vk_f3','vk_f4','vk_f5','vk_f6','vk_f7','vk_f8','vk_f9','vk_f10','vk_f11','vk_f12',
+            'vk_numpad0','vk_numpad1','vk_numpad2','vk_numpad3','vk_numpad4','vk_numpad5','vk_numpad6',
+            'vk_numpad7','vk_numpad8','vk_numpad9', 'vk_multiply','vk_divide','vk_add','vk_subtract',
+            'vk_decimal','vk_lshift','vk_lcontrol','vk_lalt','vk_rshift','vk_rcontrol','vk_ralt',
+            'c_aqua','c_black','c_blue','c_dkgray','c_fuchsia','c_gray','c_green','c_lime','c_ltgray',
+            'c_maroon','c_navy','c_olive','c_purple','c_red','c_silver','c_teal','c_white','c_yellow',
+            'fa_left', 'fa_center','fa_right','fa_top','fa_middle','fa_bottom',
+            'pr_pointlist','pr_linelist','pr_linestrip','pr_trianglelist','pr_trianglestrip',
+            'pr_trianglefan',
+            'cr_none','cr_arrow','cr_cross','cr_beam','cr_size_nesw','cr_size_ns','cr_size_nwse',
+            'cr_size_we','cr_uparrow','cr_hourglass','cr_drag','cr_nodrop','cr_hsplit','cr_vsplit',
+            'cr_multidrag','cr_sqlwait','cr_no','cr_appstart','cr_help','cr_handpoint','cr_size_all',
+            'se_chorus','se_echo','se_flanger','se_gargle','se_reverb','se_compressor','se_equalizer',
+            'fa_readonly','fa_hidden','fa_sysfile','fa_volumeid','fa_directory','fa_archive',
+            'pt_shape_pixel','pt_shape_disk','pt_shape_square','pt_shape_line','pt_shape_star',
+            'pt_shape_circle','pt_shape_ring','pt_shape_sphere','pt_shape_flare','pt_shape_spark',
+            'pt_shape_explosion','pt_shape_cloud','pt_shape_smoke','pt_shape_snow',
+            'ps_shape_rectangle','ps_shape_ellipse ','ps_shape_diamond','ps_shape_line',
+            'ps_distr_linear','ps_distr_gaussian','ps_force_constant','ps_force_linear','ps_force_quadratic',
+            'ps_deflect_horizontal', 'ps_deflect_vertical',
+            'ps_change_motion','ps_change_shape','ps_change_all'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']',
+        '&&', '||', '^^', '&', '|', '^',
+        '<', '<=', '==', '!=', '>', '>=', '=',
+        '<<', '>>',
+        '+=', '-=', '*=', '/=',
+        '+', '-', '*', '/',
+        '!', '~', ',', ';'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'font-weight: bold; color: #000000;',
+            2 => 'font-weight: bold; color: #000000;',
+            3 => 'color: navy;',
+            4 => 'color: #663300;',
+            ),
+        'COMMENTS' => array(
+            1 => 'font-style: italic; color: green;',
+            'MULTI' => 'font-style: italic; color: green;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;' //'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/gnuplot.php b/examples/includes/geshi/geshi/gnuplot.php
new file mode 100644 (file)
index 0000000..3b67fb6
--- /dev/null
@@ -0,0 +1,296 @@
+<?php
+/*************************************************************************************
+ * gnuplot.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/07/07
+ *
+ * Gnuplot script language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/07 (1.0.8)
+ *  -  Initial import
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Gnuplot',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('`', '"', "'"),
+    'ESCAPE_CHAR' => '\\',
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC |
+        GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_SCI_SHORT |
+        GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        // copy output of help command, indent properly and use this replace regexp:
+        // ([a-z0-9_\-]+)(( )+|$)          =>     '\1',\3
+
+        // commands as found in `help commands`
+        1 => array(
+            'bind', 'call', 'cd', 'clear',
+            'exit', 'fit', 'help', 'history',
+            'if', 'load', 'lower', 'pause',
+            'plot', 'print', 'pwd', 'quit',
+            'raise', 'replot', 'reread', 'reset',
+            'save', 'set', 'shell', 'show',
+            'splot', 'system', 'test', 'unset',
+            'update'
+            ),
+        2 => array(
+            // set commands as returned by `help set`
+            'angles', 'arrow', 'autoscale', 'bars',
+            'bmargin', 'border', 'boxwidth', 'cbdata',
+            'cbdtics', 'cblabel', 'cbmtics', 'cbrange',
+            'cbtics', 'clabel', 'clip', 'cntrparam',
+            'colorbox', 'contour', 'datafile', 'date_specifiers',
+            'decimalsign', 'dgrid3d', 'dummy', 'encoding',
+            'fontpath', 'format', 'grid',
+            'hidden3d', 'historysize', 'isosamples', 'key',
+            'label', 'lmargin', 'loadpath', 'locale',
+            'log', 'logscale', 'macros', 'mapping',
+            'margin', 'missing', 'mouse', 'multiplot',
+            'mx2tics', 'mxtics', 'my2tics', 'mytics',
+            'mztics', 'object', 'offsets', 'origin',
+            'output', 'palette', 'parametric', 'pm3d',
+            'pointsize', 'polar', 'rmargin',
+            'rrange', 'samples', 'size', 'style',
+            'surface', 'table', 'term', 'terminal',
+            'termoption', 'tics', 'ticscale', 'ticslevel',
+            'time_specifiers', 'timefmt', 'timestamp', 'title',
+            'trange', 'urange', 'view',
+            'vrange', 'x2data', 'x2dtics', 'x2label',
+            'x2mtics', 'x2range', 'x2tics', 'x2zeroaxis',
+            'xdata', 'xdtics', 'xlabel', 'xmtics',
+            'xrange', 'xtics', 'xyplane', 'xzeroaxis',
+            'y2data', 'y2dtics', 'y2label', 'y2mtics',
+            'y2range', 'y2tics', 'y2zeroaxis', 'ydata',
+            'ydtics', 'ylabel', 'ymtics', 'yrange',
+            'ytics', 'yzeroaxis', 'zdata', 'zdtics',
+            'zero', 'zeroaxis', 'zlabel', 'zmtics',
+            'zrange', 'ztics', 'zzeroaxis',
+            // same but with leading no
+            'noangles', 'noarrow', 'noautoscale', 'nobars',
+            'nobmargin', 'noborder', 'noboxwidth', 'nocbdata',
+            'nocbdtics', 'nocblabel', 'nocbmtics', 'nocbrange',
+            'nocbtics', 'noclabel', 'noclip', 'nocntrparam',
+            'nocolorbox', 'nocontour', 'nodatafile', 'nodate_specifiers',
+            'nodecimalsign', 'nodgrid3d', 'nodummy', 'noencoding',
+            'nofit', 'nofontpath', 'noformat', 'nogrid',
+            'nohidden3d', 'nohistorysize', 'noisosamples', 'nokey',
+            'nolabel', 'nolmargin', 'noloadpath', 'nolocale',
+            'nolog', 'nologscale', 'nomacros', 'nomapping',
+            'nomargin', 'nomissing', 'nomouse', 'nomultiplot',
+            'nomx2tics', 'nomxtics', 'nomy2tics', 'nomytics',
+            'nomztics', 'noobject', 'nooffsets', 'noorigin',
+            'nooutput', 'nopalette', 'noparametric', 'nopm3d',
+            'nopointsize', 'nopolar', 'noprint', 'normargin',
+            'norrange', 'nosamples', 'nosize', 'nostyle',
+            'nosurface', 'notable', 'noterm', 'noterminal',
+            'notermoption', 'notics', 'noticscale', 'noticslevel',
+            'notime_specifiers', 'notimefmt', 'notimestamp', 'notitle',
+            'notmargin', 'notrange', 'nourange', 'noview',
+            'novrange', 'nox2data', 'nox2dtics', 'nox2label',
+            'nox2mtics', 'nox2range', 'nox2tics', 'nox2zeroaxis',
+            'noxdata', 'noxdtics', 'noxlabel', 'noxmtics',
+            'noxrange', 'noxtics', 'noxyplane', 'noxzeroaxis',
+            'noy2data', 'noy2dtics', 'noy2label', 'noy2mtics',
+            'noy2range', 'noy2tics', 'noy2zeroaxis', 'noydata',
+            'noydtics', 'noylabel', 'noymtics', 'noyrange',
+            'noytics', 'noyzeroaxis', 'nozdata', 'nozdtics',
+            'nozero', 'nozeroaxis', 'nozlabel', 'nozmtics',
+            'nozrange', 'noztics', 'nozzeroaxis',
+            ),
+        3 => array(
+            // predefined variables
+            'pi', 'NaN', 'GNUTERM',
+            'GPVAL_X_MIN', 'GPVAL_X_MAX', 'GPVAL_Y_MIN', 'GPVAL_Y_MAX',
+            'GPVAL_TERM', 'GPVAL_TERMOPTIONS', 'GPVAL_OUTPUT',
+            'GPVAL_VERSION', 'GPVAL_PATcHLEVEL', 'GPVAL_COMPILE_OPTIONS',
+            'MOUSE_KEY', 'MOUSE_X', 'MOUSE_X2', 'MOUSE_Y', 'MOUSE_Y2',
+            'MOUSE_BUTTON', 'MOUSE_SHIFT', 'MOUSE_ALT', 'MOUSE_CTRL'
+            ),
+        4 => array(
+            // predefined functions `help functions`
+            'abs', 'acos', 'acosh', 'arg',
+            'asin', 'asinh', 'atan', 'atan2',
+            'atanh', 'besj0', 'besj1', 'besy0',
+            'besy1', 'ceil', 'column', 'cos',
+            'cosh', 'defined', 'erf', 'erfc',
+            'exists', 'exp', 'floor', 'gamma',
+            'gprintf', 'ibeta', 'igamma', 'imag',
+            'int', 'inverf', 'invnorm', 'lambertw',
+            'lgamma', 'log10', 'norm',
+            'rand', 'random', 'real', 'sgn',
+            'sin', 'sinh', 'sprintf', 'sqrt',
+            'stringcolumn', 'strlen', 'strstrt', 'substr',
+            'tan', 'tanh', 'timecolumn',
+            'tm_hour', 'tm_mday', 'tm_min', 'tm_mon',
+            'tm_sec', 'tm_wday', 'tm_yday', 'tm_year',
+            'valid', 'word', 'words',
+            ),
+        5 => array(
+            // mixed arguments
+            // there is no sane way to get these ones easily...
+            'autofreq', 'x', 'y', 'z',
+            'lt', 'linetype', 'lw', 'linewidth', 'ls', 'linestyle',
+            'out', 'rotate by', 'screen',
+            'enhanced', 'via',
+            // `help set key`
+            'on', 'off', 'default', 'inside', 'outside', 'tmargin',
+            'at', 'left', 'right', 'center', 'top', 'bottom', 'vertical', 'horizontal', 'Left', 'Right',
+            'noreverse', 'reverse', 'noinvert', 'invert', 'samplen', 'spacing', 'width', 'height',
+            'noautotitle', 'autotitle', 'noenhanced', 'nobox', 'box',
+
+            // help set terminal postscript
+            'landscape', 'portrait', 'eps', 'defaultplex', 'simplex', 'duplex',
+            'fontfile', 'add', 'delete', 'nofontfiles', 'level1', 'leveldefault',
+            'color', 'colour', 'monochrome', 'solid', 'dashed', 'dashlength', 'dl',
+            'rounded', 'butt', 'palfuncparam', 'blacktext', 'colortext', 'colourtext',
+            'font',
+
+            // help set terminal png
+            'notransparent', 'transparent', 'nointerlace', 'interlace',
+            'notruecolor', 'truecolor', 'tiny', 'small', 'medium', 'large', 'giant',
+            'nocrop', 'crop',
+
+            // `help plot`
+            'acsplines', 'bezier', 'binary', 'csplines',
+            'every',
+            'example', 'frequency', 'index', 'matrix',
+            'ranges', 'sbezier', 'smooth',
+            'special-filenames', 'thru',
+            'unique', 'using', 'with',
+
+            // `help plotting styles`
+            'boxerrorbars', 'boxes', 'boxxyerrorbars', 'candlesticks',
+            'dots', 'errorbars', 'errorlines', 'filledcurves',
+            'financebars', 'fsteps', 'histeps', 'histograms',
+            'image', 'impulses', 'labels', 'lines',
+            'linespoints', 'points', 'rgbimage', 'steps',
+            'vectors', 'xerrorbars', 'xerrorlines', 'xyerrorbars',
+            'xyerrorlines', 'yerrorbars', 'yerrorlines',
+
+
+            // terminals `help terminals`
+            'aed512', 'aed767', 'aifm', 'bitgraph',
+            'cgm', 'corel', 'dumb', 'dxf',
+            'eepic', 'emf', 'emtex', 'epslatex',
+            'epson-180dpi', 'epson-60dpi', 'epson-lx800', 'fig',
+            'gif', 'gpic', 'hp2623a', 'hp2648',
+            'hp500c', 'hpdj', 'hpgl', 'hpljii',
+            'hppj', 'imagen', 'jpeg', 'kc-tek40xx',
+            'km-tek40xx', 'latex', 'mf', 'mif',
+            'mp', 'nec-cp6', 'okidata', 'pbm',
+            'pcl5', 'png', 'pop', 'postscript',
+            'pslatex', 'pstex', 'pstricks', 'push',
+            'qms', 'regis', 'selanar', 'starc',
+            'svg', 'tandy-60dpi', 'tek40xx', 'tek410x',
+            'texdraw', 'tgif', 'tkcanvas', 'tpic',
+            'vttek', 'x11', 'xlib',
+            )
+        ),
+    'REGEXPS' => array(
+        //Variable assignment
+        0 => "([a-zA-Z_][a-zA-Z0-9_]*)\s*=",
+        //Numbers with unit
+        1 => "(?<=^|\s)([0-9]*\.?[0-9]+\s*cm)"
+        ),
+    'SYMBOLS' => array(
+        '-', '+', '~', '!', '$',
+        '*', '/', '%', '=', '<', '>', '&',
+        '^', '|', '.', 'eq', 'ne', '?:', ':', '`', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #990000;',
+            3 => 'color: #550000;',
+            4 => 'color: #7a0874;',
+            5 => 'color: #448888;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight:bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000099; font-weight:bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;',
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #007800;',
+            1 => 'color: #cc66cc;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => 'http://www.google.com/search?q=%22set+{FNAME}%22+site%3Ahttp%3A%2F%2Fwww.gnuplot.info%2Fdocs%2F&amp;btnI=lucky',
+        3 => '',
+        4 => '',
+        5 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            4 => array(
+                'DISALLOWED_AFTER' =>  "(?![\.\-a-zA-Z0-9_%])"
+            )
+        )
+    ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/groovy.php b/examples/includes/geshi/geshi/groovy.php
new file mode 100644 (file)
index 0000000..332f163
--- /dev/null
@@ -0,0 +1,1011 @@
+<?php
+/*************************************************************************************
+ * groovy.php
+ * ----------
+ * Author: Ivan F. Villanueva B. (geshi_groovy@artificialidea.com)
+ * Copyright: (c) 2006 Ivan F. Villanueva B.(http://www.artificialidea.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/04/29
+ *
+ * Groovy language file for GeSHi.
+ *
+ * Keywords from http: http://docs.codehaus.org/download/attachments/2715/groovy-reference-card.pdf?version=1
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2006/04/29 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2006/04/29)
+ * -------------------------
+ * Testing
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Groovy',
+    'COMMENT_SINGLE' => array(1 => '//', 3 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Import and Package directives (Basic Support only)
+        2 => '/(?:(?<=import[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'''", '"""', "'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'case', 'do', 'else', 'for', 'foreach', 'if', 'in', 'switch',
+            'while',
+            ),
+        2 => array(
+            'abstract', 'as', 'assert', 'break', 'catch', 'class', 'const',
+            'continue', 'def', 'default', 'enum', 'extends',
+            'false', 'final', 'finally', 'goto', 'implements', 'import',
+            'instanceof', 'interface', 'native', 'new', 'null',
+            'package', 'private', 'property', 'protected',
+            'public', 'return', 'static', 'strictfp', 'super',
+            'synchronized', 'this', 'throw', 'throws',
+            'transient', 'true', 'try', 'volatile'
+            ),
+        3 => array(
+            'AbstractAction', 'AbstractBorder', 'AbstractButton',
+            'AbstractCellEditor', 'AbstractCollection',
+            'AbstractColorChooserPanel', 'AbstractDocument',
+            'AbstractDocument.AttributeContext',
+            'AbstractDocument.Content',
+            'AbstractDocument.ElementEdit',
+            'AbstractLayoutCache',
+            'AbstractLayoutCache.NodeDimensions', 'AbstractList',
+            'AbstractListModel', 'AbstractMap',
+            'AbstractMethodError', 'AbstractSequentialList',
+            'AbstractSet', 'AbstractTableModel',
+            'AbstractUndoableEdit', 'AbstractWriter',
+            'AccessControlContext', 'AccessControlException',
+            'AccessController', 'AccessException', 'Accessible',
+            'AccessibleAction', 'AccessibleBundle',
+            'AccessibleComponent', 'AccessibleContext',
+            'AccessibleHyperlink', 'AccessibleHypertext',
+            'AccessibleIcon', 'AccessibleObject',
+            'AccessibleRelation', 'AccessibleRelationSet',
+            'AccessibleResourceBundle', 'AccessibleRole',
+            'AccessibleSelection', 'AccessibleState',
+            'AccessibleStateSet', 'AccessibleTable',
+            'AccessibleTableModelChange', 'AccessibleText',
+            'AccessibleValue', 'Acl', 'AclEntry',
+            'AclNotFoundException', 'Action', 'ActionEvent',
+            'ActionListener', 'ActionMap', 'ActionMapUIResource',
+            'Activatable', 'ActivateFailedException',
+            'ActivationDesc', 'ActivationException',
+            'ActivationGroup', 'ActivationGroupDesc',
+            'ActivationGroupDesc.CommandEnvironment',
+            'ActivationGroupID', 'ActivationID',
+            'ActivationInstantiator', 'ActivationMonitor',
+            'ActivationSystem', 'Activator', 'ActiveEvent',
+            'Adjustable', 'AdjustmentEvent',
+            'AdjustmentListener', 'Adler32', 'AffineTransform',
+            'AffineTransformOp', 'AlgorithmParameterGenerator',
+            'AlgorithmParameterGeneratorSpi',
+            'AlgorithmParameters', 'AlgorithmParameterSpec',
+            'AlgorithmParametersSpi', 'AllPermission',
+            'AlphaComposite', 'AlreadyBound',
+            'AlreadyBoundException', 'AlreadyBoundHelper',
+            'AlreadyBoundHolder', 'AncestorEvent',
+            'AncestorListener', 'Annotation', 'Any', 'AnyHolder',
+            'AnySeqHelper', 'AnySeqHolder', 'Applet',
+            'AppletContext', 'AppletInitializer', 'AppletStub',
+            'ApplicationException', 'Arc2D', 'Arc2D.Double',
+            'Arc2D.Float', 'Area', 'AreaAveragingScaleFilter',
+            'ARG_IN', 'ARG_INOUT', 'ARG_OUT',
+            'ArithmeticException', 'Array',
+            'ArrayIndexOutOfBoundsException', 'ArrayList',
+            'Arrays', 'ArrayStoreException', 'AsyncBoxView',
+            'Attribute', 'AttributedCharacterIterator',
+            'AttributedCharacterIterator.Attribute',
+            'AttributedString', 'AttributeInUseException',
+            'AttributeList', 'AttributeModificationException',
+            'Attributes', 'Attributes.Name', 'AttributeSet',
+            'AttributeSet.CharacterAttribute',
+            'AttributeSet.ColorAttribute',
+            'AttributeSet.FontAttribute',
+            'AttributeSet.ParagraphAttribute', 'AudioClip',
+            'AudioFileFormat', 'AudioFileFormat.Type',
+            'AudioFileReader', 'AudioFileWriter', 'AudioFormat',
+            'AudioFormat.Encoding', 'AudioInputStream',
+            'AudioPermission', 'AudioSystem',
+            'AuthenticationException',
+            'AuthenticationNotSupportedException',
+            'Authenticator', 'Autoscroll', 'AWTError',
+            'AWTEvent', 'AWTEventListener',
+            'AWTEventMulticaster', 'AWTException',
+            'AWTPermission', 'BadKind', 'BadLocationException',
+            'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION',
+            'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE',
+            'BAD_POLICY_VALUE', 'BAD_TYPECODE', 'BandCombineOp',
+            'BandedSampleModel', 'BasicArrowButton',
+            'BasicAttribute', 'BasicAttributes', 'BasicBorders',
+            'BasicBorders.ButtonBorder',
+            'BasicBorders.FieldBorder',
+            'BasicBorders.MarginBorder',
+            'BasicBorders.MenuBarBorder',
+            'BasicBorders.RadioButtonBorder',
+            'BasicBorders.SplitPaneBorder',
+            'BasicBorders.ToggleButtonBorder',
+            'BasicButtonListener', 'BasicButtonUI',
+            'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI',
+            'BasicColorChooserUI', 'BasicComboBoxEditor',
+            'BasicComboBoxEditor.UIResource',
+            'BasicComboBoxRenderer',
+            'BasicComboBoxRenderer.UIResource',
+            'BasicComboBoxUI', 'BasicComboPopup',
+            'BasicDesktopIconUI', 'BasicDesktopPaneUI',
+            'BasicDirectoryModel', 'BasicEditorPaneUI',
+            'BasicFileChooserUI', 'BasicGraphicsUtils',
+            'BasicHTML', 'BasicIconFactory',
+            'BasicInternalFrameTitlePane',
+            'BasicInternalFrameUI', 'BasicLabelUI',
+            'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI',
+            'BasicMenuItemUI', 'BasicMenuUI',
+            'BasicOptionPaneUI',
+            'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI',
+            'BasicPasswordFieldUI', 'BasicPermission',
+            'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI',
+            'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI',
+            'BasicRadioButtonUI', 'BasicRootPaneUI',
+            'BasicScrollBarUI', 'BasicScrollPaneUI',
+            'BasicSeparatorUI', 'BasicSliderUI',
+            'BasicSplitPaneDivider', 'BasicSplitPaneUI',
+            'BasicStroke', 'BasicTabbedPaneUI',
+            'BasicTableHeaderUI', 'BasicTableUI',
+            'BasicTextAreaUI', 'BasicTextFieldUI',
+            'BasicTextPaneUI', 'BasicTextUI',
+            'BasicTextUI.BasicCaret',
+            'BasicTextUI.BasicHighlighter',
+            'BasicToggleButtonUI', 'BasicToolBarSeparatorUI',
+            'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI',
+            'BasicViewportUI', 'BatchUpdateException',
+            'BeanContext', 'BeanContextChild',
+            'BeanContextChildComponentProxy',
+            'BeanContextChildSupport',
+            'BeanContextContainerProxy', 'BeanContextEvent',
+            'BeanContextMembershipEvent',
+            'BeanContextMembershipListener', 'BeanContextProxy',
+            'BeanContextServiceAvailableEvent',
+            'BeanContextServiceProvider',
+            'BeanContextServiceProviderBeanInfo',
+            'BeanContextServiceRevokedEvent',
+            'BeanContextServiceRevokedListener',
+            'BeanContextServices', 'BeanContextServicesListener',
+            'BeanContextServicesSupport',
+            'BeanContextServicesSupport.BCSSServiceProvider',
+            'BeanContextSupport',
+            'BeanContextSupport.BCSIterator', 'BeanDescriptor',
+            'BeanInfo', 'Beans', 'BevelBorder', 'BigDecimal',
+            'BigInteger', 'BinaryRefAddr', 'BindException',
+            'Binding', 'BindingHelper', 'BindingHolder',
+            'BindingIterator', 'BindingIteratorHelper',
+            'BindingIteratorHolder', 'BindingIteratorOperations',
+            'BindingListHelper', 'BindingListHolder',
+            'BindingType', 'BindingTypeHelper',
+            'BindingTypeHolder', 'BitSet', 'Blob', 'BlockView',
+            'Book', 'Boolean', 'BooleanControl',
+            'BooleanControl.Type', 'BooleanHolder',
+            'BooleanSeqHelper', 'BooleanSeqHolder', 'Border',
+            'BorderFactory', 'BorderLayout', 'BorderUIResource',
+            'BorderUIResource.BevelBorderUIResource',
+            'BorderUIResource.CompoundBorderUIResource',
+            'BorderUIResource.EmptyBorderUIResource',
+            'BorderUIResource.EtchedBorderUIResource',
+            'BorderUIResource.LineBorderUIResource',
+            'BorderUIResource.MatteBorderUIResource',
+            'BorderUIResource.TitledBorderUIResource',
+            'BoundedRangeModel', 'Bounds', 'Box', 'Box.Filler',
+            'BoxedValueHelper', 'BoxLayout', 'BoxView',
+            'BreakIterator', 'BufferedImage',
+            'BufferedImageFilter', 'BufferedImageOp',
+            'BufferedInputStream', 'BufferedOutputStream',
+            'BufferedReader', 'BufferedWriter', 'Button',
+            'ButtonGroup', 'ButtonModel', 'ButtonUI', 'Byte',
+            'ByteArrayInputStream', 'ByteArrayOutputStream',
+            'ByteHolder', 'ByteLookupTable', 'Calendar',
+            'CallableStatement', 'CannotProceed',
+            'CannotProceedException', 'CannotProceedHelper',
+            'CannotProceedHolder', 'CannotRedoException',
+            'CannotUndoException', 'Canvas', 'CardLayout',
+            'Caret', 'CaretEvent', 'CaretListener', 'CellEditor',
+            'CellEditorListener', 'CellRendererPane',
+            'Certificate', 'Certificate.CertificateRep',
+            'CertificateEncodingException',
+            'CertificateException',
+            'CertificateExpiredException', 'CertificateFactory',
+            'CertificateFactorySpi',
+            'CertificateNotYetValidException',
+            'CertificateParsingException',
+            'ChangedCharSetException', 'ChangeEvent',
+            'ChangeListener', 'Character', 'Character.Subset',
+            'Character.UnicodeBlock', 'CharacterIterator',
+            'CharArrayReader', 'CharArrayWriter',
+            'CharConversionException', 'CharHolder',
+            'CharSeqHelper', 'CharSeqHolder', 'Checkbox',
+            'CheckboxGroup', 'CheckboxMenuItem',
+            'CheckedInputStream', 'CheckedOutputStream',
+            'Checksum', 'Choice', 'ChoiceFormat', 'Class',
+            'ClassCastException', 'ClassCircularityError',
+            'ClassDesc', 'ClassFormatError', 'ClassLoader',
+            'ClassNotFoundException', 'Clip', 'Clipboard',
+            'ClipboardOwner', 'Clob', 'Cloneable',
+            'CloneNotSupportedException', 'CMMException',
+            'CodeSource', 'CollationElementIterator',
+            'CollationKey', 'Collator', 'Collection',
+            'Collections', 'Color',
+            'ColorChooserComponentFactory', 'ColorChooserUI',
+            'ColorConvertOp', 'ColorModel',
+            'ColorSelectionModel', 'ColorSpace',
+            'ColorUIResource', 'ComboBoxEditor', 'ComboBoxModel',
+            'ComboBoxUI', 'ComboPopup', 'CommunicationException',
+            'COMM_FAILURE', 'Comparable', 'Comparator',
+            'Compiler', 'CompletionStatus',
+            'CompletionStatusHelper', 'Component',
+            'ComponentAdapter', 'ComponentColorModel',
+            'ComponentEvent', 'ComponentInputMap',
+            'ComponentInputMapUIResource', 'ComponentListener',
+            'ComponentOrientation', 'ComponentSampleModel',
+            'ComponentUI', 'ComponentView', 'Composite',
+            'CompositeContext', 'CompositeName', 'CompositeView',
+            'CompoundBorder', 'CompoundControl',
+            'CompoundControl.Type', 'CompoundEdit',
+            'CompoundName', 'ConcurrentModificationException',
+            'ConfigurationException', 'ConnectException',
+            'ConnectIOException', 'Connection', 'Constructor',
+            'Container', 'ContainerAdapter', 'ContainerEvent',
+            'ContainerListener', 'ContentHandler',
+            'ContentHandlerFactory', 'ContentModel', 'Context',
+            'ContextList', 'ContextNotEmptyException',
+            'ContextualRenderedImageFactory', 'Control',
+            'Control.Type', 'ControlFactory',
+            'ControllerEventListener', 'ConvolveOp', 'CRC32',
+            'CRL', 'CRLException', 'CropImageFilter', 'CSS',
+            'CSS.Attribute', 'CTX_RESTRICT_SCOPE',
+            'CubicCurve2D', 'CubicCurve2D.Double',
+            'CubicCurve2D.Float', 'Current', 'CurrentHelper',
+            'CurrentHolder', 'CurrentOperations', 'Cursor',
+            'Customizer', 'CustomMarshal', 'CustomValue',
+            'DatabaseMetaData', 'DataBuffer', 'DataBufferByte',
+            'DataBufferInt', 'DataBufferShort',
+            'DataBufferUShort', 'DataFlavor',
+            'DataFormatException', 'DatagramPacket',
+            'DatagramSocket', 'DatagramSocketImpl',
+            'DatagramSocketImplFactory', 'DataInput',
+            'DataInputStream', 'DataLine', 'DataLine.Info',
+            'DataOutput', 'DataOutputStream', 'DataTruncation',
+            'DATA_CONVERSION', 'Date', 'DateFormat',
+            'DateFormatSymbols', 'DebugGraphics',
+            'DecimalFormat', 'DecimalFormatSymbols',
+            'DefaultBoundedRangeModel', 'DefaultButtonModel',
+            'DefaultCaret', 'DefaultCellEditor',
+            'DefaultColorSelectionModel', 'DefaultComboBoxModel',
+            'DefaultDesktopManager', 'DefaultEditorKit',
+            'DefaultEditorKit.BeepAction',
+            'DefaultEditorKit.CopyAction',
+            'DefaultEditorKit.CutAction',
+            'DefaultEditorKit.DefaultKeyTypedAction',
+            'DefaultEditorKit.InsertBreakAction',
+            'DefaultEditorKit.InsertContentAction',
+            'DefaultEditorKit.InsertTabAction',
+            'DefaultEditorKit.PasteAction,',
+            'DefaultFocusManager', 'DefaultHighlighter',
+            'DefaultHighlighter.DefaultHighlightPainter',
+            'DefaultListCellRenderer',
+            'DefaultListCellRenderer.UIResource',
+            'DefaultListModel', 'DefaultListSelectionModel',
+            'DefaultMenuLayout', 'DefaultMetalTheme',
+            'DefaultMutableTreeNode',
+            'DefaultSingleSelectionModel',
+            'DefaultStyledDocument',
+            'DefaultStyledDocument.AttributeUndoableEdit',
+            'DefaultStyledDocument.ElementSpec',
+            'DefaultTableCellRenderer',
+            'DefaultTableCellRenderer.UIResource',
+            'DefaultTableColumnModel', 'DefaultTableModel',
+            'DefaultTextUI', 'DefaultTreeCellEditor',
+            'DefaultTreeCellRenderer', 'DefaultTreeModel',
+            'DefaultTreeSelectionModel', 'DefinitionKind',
+            'DefinitionKindHelper', 'Deflater',
+            'DeflaterOutputStream', 'Delegate', 'DesignMode',
+            'DesktopIconUI', 'DesktopManager', 'DesktopPaneUI',
+            'DGC', 'Dialog', 'Dictionary', 'DigestException',
+            'DigestInputStream', 'DigestOutputStream',
+            'Dimension', 'Dimension2D', 'DimensionUIResource',
+            'DirContext', 'DirectColorModel', 'DirectoryManager',
+            'DirObjectFactory', 'DirStateFactory',
+            'DirStateFactory.Result', 'DnDConstants', 'Document',
+            'DocumentEvent', 'DocumentEvent.ElementChange',
+            'DocumentEvent.EventType', 'DocumentListener',
+            'DocumentParser', 'DomainCombiner', 'DomainManager',
+            'DomainManagerOperations', 'Double', 'DoubleHolder',
+            'DoubleSeqHelper', 'DoubleSeqHolder',
+            'DragGestureEvent', 'DragGestureListener',
+            'DragGestureRecognizer', 'DragSource',
+            'DragSourceContext', 'DragSourceDragEvent',
+            'DragSourceDropEvent', 'DragSourceEvent',
+            'DragSourceListener', 'Driver', 'DriverManager',
+            'DriverPropertyInfo', 'DropTarget',
+            'DropTarget.DropTargetAutoScroller',
+            'DropTargetContext', 'DropTargetDragEvent',
+            'DropTargetDropEvent', 'DropTargetEvent',
+            'DropTargetListener', 'DSAKey',
+            'DSAKeyPairGenerator', 'DSAParameterSpec',
+            'DSAParams', 'DSAPrivateKey', 'DSAPrivateKeySpec',
+            'DSAPublicKey', 'DSAPublicKeySpec', 'DTD',
+            'DTDConstants', 'DynamicImplementation', 'DynAny',
+            'DynArray', 'DynEnum', 'DynFixed', 'DynSequence',
+            'DynStruct', 'DynUnion', 'DynValue', 'EditorKit',
+            'Element', 'ElementIterator', 'Ellipse2D',
+            'Ellipse2D.Double', 'Ellipse2D.Float', 'EmptyBorder',
+            'EmptyStackException', 'EncodedKeySpec', 'Entity',
+            'EnumControl', 'EnumControl.Type', 'Enumeration',
+            'Environment', 'EOFException', 'Error',
+            'EtchedBorder', 'Event', 'EventContext',
+            'EventDirContext', 'EventListener',
+            'EventListenerList', 'EventObject', 'EventQueue',
+            'EventSetDescriptor', 'Exception',
+            'ExceptionInInitializerError', 'ExceptionList',
+            'ExpandVetoException', 'ExportException',
+            'ExtendedRequest', 'ExtendedResponse',
+            'Externalizable', 'FeatureDescriptor', 'Field',
+            'FieldNameHelper', 'FieldPosition', 'FieldView',
+            'File', 'FileChooserUI', 'FileDescriptor',
+            'FileDialog', 'FileFilter', 'FileInputStream',
+            'FilenameFilter', 'FileNameMap',
+            'FileNotFoundException', 'FileOutputStream',
+            'FilePermission', 'FileReader', 'FileSystemView',
+            'FileView', 'FileWriter', 'FilteredImageSource',
+            'FilterInputStream', 'FilterOutputStream',
+            'FilterReader', 'FilterWriter',
+            'FixedHeightLayoutCache', 'FixedHolder',
+            'FlatteningPathIterator', 'FlavorMap', 'Float',
+            'FloatControl', 'FloatControl.Type', 'FloatHolder',
+            'FloatSeqHelper', 'FloatSeqHolder', 'FlowLayout',
+            'FlowView', 'FlowView.FlowStrategy', 'FocusAdapter',
+            'FocusEvent', 'FocusListener', 'FocusManager',
+            'Font', 'FontFormatException', 'FontMetrics',
+            'FontRenderContext', 'FontUIResource', 'Format',
+            'FormatConversionProvider', 'FormView', 'Frame',
+            'FREE_MEM', 'GapContent', 'GeneralPath',
+            'GeneralSecurityException', 'GlyphJustificationInfo',
+            'GlyphMetrics', 'GlyphVector', 'GlyphView',
+            'GlyphView.GlyphPainter', 'GradientPaint',
+            'GraphicAttribute', 'Graphics', 'Graphics2D',
+            'GraphicsConfigTemplate', 'GraphicsConfiguration',
+            'GraphicsDevice', 'GraphicsEnvironment',
+            'GrayFilter', 'GregorianCalendar',
+            'GridBagConstraints', 'GridBagLayout', 'GridLayout',
+            'Group', 'Guard', 'GuardedObject', 'GZIPInputStream',
+            'GZIPOutputStream', 'HasControls', 'HashMap',
+            'HashSet', 'Hashtable', 'HierarchyBoundsAdapter',
+            'HierarchyBoundsListener', 'HierarchyEvent',
+            'HierarchyListener', 'Highlighter',
+            'Highlighter.Highlight',
+            'Highlighter.HighlightPainter', 'HTML',
+            'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag',
+            'HTMLDocument', 'HTMLDocument.Iterator',
+            'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory',
+            'HTMLEditorKit.HTMLTextAction',
+            'HTMLEditorKit.InsertHTMLTextAction',
+            'HTMLEditorKit.LinkController',
+            'HTMLEditorKit.Parser',
+            'HTMLEditorKit.ParserCallback',
+            'HTMLFrameHyperlinkEvent', 'HTMLWriter',
+            'HttpURLConnection', 'HyperlinkEvent',
+            'HyperlinkEvent.EventType', 'HyperlinkListener',
+            'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray',
+            'ICC_ProfileRGB', 'Icon', 'IconUIResource',
+            'IconView', 'IdentifierHelper', 'Identity',
+            'IdentityScope', 'IDLEntity', 'IDLType',
+            'IDLTypeHelper', 'IDLTypeOperations',
+            'IllegalAccessError', 'IllegalAccessException',
+            'IllegalArgumentException',
+            'IllegalComponentStateException',
+            'IllegalMonitorStateException',
+            'IllegalPathStateException', 'IllegalStateException',
+            'IllegalThreadStateException', 'Image',
+            'ImageConsumer', 'ImageFilter',
+            'ImageGraphicAttribute', 'ImageIcon',
+            'ImageObserver', 'ImageProducer',
+            'ImagingOpException', 'IMP_LIMIT',
+            'IncompatibleClassChangeError',
+            'InconsistentTypeCode', 'IndexColorModel',
+            'IndexedPropertyDescriptor',
+            'IndexOutOfBoundsException', 'IndirectionException',
+            'InetAddress', 'Inflater', 'InflaterInputStream',
+            'InheritableThreadLocal', 'InitialContext',
+            'InitialContextFactory',
+            'InitialContextFactoryBuilder', 'InitialDirContext',
+            'INITIALIZE', 'Initializer', 'InitialLdapContext',
+            'InlineView', 'InputContext', 'InputEvent',
+            'InputMap', 'InputMapUIResource', 'InputMethod',
+            'InputMethodContext', 'InputMethodDescriptor',
+            'InputMethodEvent', 'InputMethodHighlight',
+            'InputMethodListener', 'InputMethodRequests',
+            'InputStream', 'InputStreamReader', 'InputSubset',
+            'InputVerifier', 'Insets', 'InsetsUIResource',
+            'InstantiationError', 'InstantiationException',
+            'Instrument', 'InsufficientResourcesException',
+            'Integer', 'INTERNAL', 'InternalError',
+            'InternalFrameAdapter', 'InternalFrameEvent',
+            'InternalFrameListener', 'InternalFrameUI',
+            'InterruptedException', 'InterruptedIOException',
+            'InterruptedNamingException', 'INTF_REPOS',
+            'IntHolder', 'IntrospectionException',
+            'Introspector', 'Invalid',
+            'InvalidAlgorithmParameterException',
+            'InvalidAttributeIdentifierException',
+            'InvalidAttributesException',
+            'InvalidAttributeValueException',
+            'InvalidClassException',
+            'InvalidDnDOperationException',
+            'InvalidKeyException', 'InvalidKeySpecException',
+            'InvalidMidiDataException', 'InvalidName',
+            'InvalidNameException', 'InvalidNameHelper',
+            'InvalidNameHolder', 'InvalidObjectException',
+            'InvalidParameterException',
+            'InvalidParameterSpecException',
+            'InvalidSearchControlsException',
+            'InvalidSearchFilterException', 'InvalidSeq',
+            'InvalidTransactionException', 'InvalidValue',
+            'INVALID_TRANSACTION', 'InvocationEvent',
+            'InvocationHandler', 'InvocationTargetException',
+            'InvokeHandler', 'INV_FLAG', 'INV_IDENT',
+            'INV_OBJREF', 'INV_POLICY', 'IOException',
+            'IRObject', 'IRObjectOperations', 'IstringHelper',
+            'ItemEvent', 'ItemListener', 'ItemSelectable',
+            'Iterator', 'JApplet', 'JarEntry', 'JarException',
+            'JarFile', 'JarInputStream', 'JarOutputStream',
+            'JarURLConnection', 'JButton', 'JCheckBox',
+            'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox',
+            'JComboBox.KeySelectionManager', 'JComponent',
+            'JDesktopPane', 'JDialog', 'JEditorPane',
+            'JFileChooser', 'JFrame', 'JInternalFrame',
+            'JInternalFrame.JDesktopIcon', 'JLabel',
+            'JLayeredPane', 'JList', 'JMenu', 'JMenuBar',
+            'JMenuItem', 'JobAttributes',
+            'JobAttributes.DefaultSelectionType',
+            'JobAttributes.DestinationType',
+            'JobAttributes.DialogType',
+            'JobAttributes.MultipleDocumentHandlingType',
+            'JobAttributes.SidesType', 'JOptionPane', 'JPanel',
+            'JPasswordField', 'JPopupMenu',
+            'JPopupMenu.Separator', 'JProgressBar',
+            'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane',
+            'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider',
+            'JSplitPane', 'JTabbedPane', 'JTable',
+            'JTableHeader', 'JTextArea', 'JTextComponent',
+            'JTextComponent.KeyBinding', 'JTextField',
+            'JTextPane', 'JToggleButton',
+            'JToggleButton.ToggleButtonModel', 'JToolBar',
+            'JToolBar.Separator', 'JToolTip', 'JTree',
+            'JTree.DynamicUtilTreeNode',
+            'JTree.EmptySelectionModel', 'JViewport', 'JWindow',
+            'Kernel', 'Key', 'KeyAdapter', 'KeyEvent',
+            'KeyException', 'KeyFactory', 'KeyFactorySpi',
+            'KeyListener', 'KeyManagementException', 'Keymap',
+            'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi',
+            'KeySpec', 'KeyStore', 'KeyStoreException',
+            'KeyStoreSpi', 'KeyStroke', 'Label', 'LabelUI',
+            'LabelView', 'LastOwnerException',
+            'LayeredHighlighter',
+            'LayeredHighlighter.LayerPainter', 'LayoutManager',
+            'LayoutManager2', 'LayoutQueue', 'LdapContext',
+            'LdapReferralException', 'Lease',
+            'LimitExceededException', 'Line', 'Line.Info',
+            'Line2D', 'Line2D.Double', 'Line2D.Float',
+            'LineBorder', 'LineBreakMeasurer', 'LineEvent',
+            'LineEvent.Type', 'LineListener', 'LineMetrics',
+            'LineNumberInputStream', 'LineNumberReader',
+            'LineUnavailableException', 'LinkageError',
+            'LinkedList', 'LinkException', 'LinkLoopException',
+            'LinkRef', 'List', 'ListCellRenderer',
+            'ListDataEvent', 'ListDataListener', 'ListIterator',
+            'ListModel', 'ListResourceBundle',
+            'ListSelectionEvent', 'ListSelectionListener',
+            'ListSelectionModel', 'ListUI', 'ListView',
+            'LoaderHandler', 'Locale', 'LocateRegistry',
+            'LogStream', 'Long', 'LongHolder',
+            'LongLongSeqHelper', 'LongLongSeqHolder',
+            'LongSeqHelper', 'LongSeqHolder', 'LookAndFeel',
+            'LookupOp', 'LookupTable', 'MalformedLinkException',
+            'MalformedURLException', 'Manifest', 'Map',
+            'Map.Entry', 'MARSHAL', 'MarshalException',
+            'MarshalledObject', 'Math', 'MatteBorder',
+            'MediaTracker', 'Member', 'MemoryImageSource',
+            'Menu', 'MenuBar', 'MenuBarUI', 'MenuComponent',
+            'MenuContainer', 'MenuDragMouseEvent',
+            'MenuDragMouseListener', 'MenuElement', 'MenuEvent',
+            'MenuItem', 'MenuItemUI', 'MenuKeyEvent',
+            'MenuKeyListener', 'MenuListener',
+            'MenuSelectionManager', 'MenuShortcut',
+            'MessageDigest', 'MessageDigestSpi', 'MessageFormat',
+            'MetaEventListener', 'MetalBorders',
+            'MetalBorders.ButtonBorder',
+            'MetalBorders.Flush3DBorder',
+            'MetalBorders.InternalFrameBorder',
+            'MetalBorders.MenuBarBorder',
+            'MetalBorders.MenuItemBorder',
+            'MetalBorders.OptionDialogBorder',
+            'MetalBorders.PaletteBorder',
+            'MetalBorders.PopupMenuBorder',
+            'MetalBorders.RolloverButtonBorder',
+            'MetalBorders.ScrollPaneBorder',
+            'MetalBorders.TableHeaderBorder',
+            'MetalBorders.TextFieldBorder',
+            'MetalBorders.ToggleButtonBorder',
+            'MetalBorders.ToolBarBorder', 'MetalButtonUI',
+            'MetalCheckBoxIcon', 'MetalCheckBoxUI',
+            'MetalComboBoxButton', 'MetalComboBoxEditor',
+            'MetalComboBoxEditor.UIResource',
+            'MetalComboBoxIcon', 'MetalComboBoxUI',
+            'MetalDesktopIconUI', 'MetalFileChooserUI',
+            'MetalIconFactory', 'MetalIconFactory.FileIcon16',
+            'MetalIconFactory.FolderIcon16',
+            'MetalIconFactory.PaletteCloseIcon',
+            'MetalIconFactory.TreeControlIcon',
+            'MetalIconFactory.TreeFolderIcon',
+            'MetalIconFactory.TreeLeafIcon',
+            'MetalInternalFrameTitlePane',
+            'MetalInternalFrameUI', 'MetalLabelUI',
+            'MetalLookAndFeel', 'MetalPopupMenuSeparatorUI',
+            'MetalProgressBarUI', 'MetalRadioButtonUI',
+            'MetalScrollBarUI', 'MetalScrollButton',
+            'MetalScrollPaneUI', 'MetalSeparatorUI',
+            'MetalSliderUI', 'MetalSplitPaneUI',
+            'MetalTabbedPaneUI', 'MetalTextFieldUI',
+            'MetalTheme', 'MetalToggleButtonUI',
+            'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI',
+            'MetaMessage', 'Method', 'MethodDescriptor',
+            'MidiChannel', 'MidiDevice', 'MidiDevice.Info',
+            'MidiDeviceProvider', 'MidiEvent', 'MidiFileFormat',
+            'MidiFileReader', 'MidiFileWriter', 'MidiMessage',
+            'MidiSystem', 'MidiUnavailableException',
+            'MimeTypeParseException', 'MinimalHTMLWriter',
+            'MissingResourceException', 'Mixer', 'Mixer.Info',
+            'MixerProvider', 'ModificationItem', 'Modifier',
+            'MouseAdapter', 'MouseDragGestureRecognizer',
+            'MouseEvent', 'MouseInputAdapter',
+            'MouseInputListener', 'MouseListener',
+            'MouseMotionAdapter', 'MouseMotionListener',
+            'MultiButtonUI', 'MulticastSocket',
+            'MultiColorChooserUI', 'MultiComboBoxUI',
+            'MultiDesktopIconUI', 'MultiDesktopPaneUI',
+            'MultiFileChooserUI', 'MultiInternalFrameUI',
+            'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel',
+            'MultiMenuBarUI', 'MultiMenuItemUI',
+            'MultiOptionPaneUI', 'MultiPanelUI',
+            'MultiPixelPackedSampleModel', 'MultipleMaster',
+            'MultiPopupMenuUI', 'MultiProgressBarUI',
+            'MultiScrollBarUI', 'MultiScrollPaneUI',
+            'MultiSeparatorUI', 'MultiSliderUI',
+            'MultiSplitPaneUI', 'MultiTabbedPaneUI',
+            'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI',
+            'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI',
+            'MultiViewportUI', 'MutableAttributeSet',
+            'MutableComboBoxModel', 'MutableTreeNode', 'Name',
+            'NameAlreadyBoundException', 'NameClassPair',
+            'NameComponent', 'NameComponentHelper',
+            'NameComponentHolder', 'NamedValue', 'NameHelper',
+            'NameHolder', 'NameNotFoundException', 'NameParser',
+            'NamespaceChangeListener', 'NameValuePair',
+            'NameValuePairHelper', 'Naming', 'NamingContext',
+            'NamingContextHelper', 'NamingContextHolder',
+            'NamingContextOperations', 'NamingEnumeration',
+            'NamingEvent', 'NamingException',
+            'NamingExceptionEvent', 'NamingListener',
+            'NamingManager', 'NamingSecurityException',
+            'NegativeArraySizeException', 'NetPermission',
+            'NoClassDefFoundError', 'NoInitialContextException',
+            'NoninvertibleTransformException',
+            'NoPermissionException', 'NoRouteToHostException',
+            'NoSuchAlgorithmException',
+            'NoSuchAttributeException', 'NoSuchElementException',
+            'NoSuchFieldError', 'NoSuchFieldException',
+            'NoSuchMethodError', 'NoSuchMethodException',
+            'NoSuchObjectException', 'NoSuchProviderException',
+            'NotActiveException', 'NotBoundException',
+            'NotContextException', 'NotEmpty', 'NotEmptyHelper',
+            'NotEmptyHolder', 'NotFound', 'NotFoundHelper',
+            'NotFoundHolder', 'NotFoundReason',
+            'NotFoundReasonHelper', 'NotFoundReasonHolder',
+            'NotOwnerException', 'NotSerializableException',
+            'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION',
+            'NO_RESOURCES', 'NO_RESPONSE',
+            'NullPointerException', 'Number', 'NumberFormat',
+            'NumberFormatException', 'NVList', 'Object',
+            'ObjectChangeListener', 'ObjectFactory',
+            'ObjectFactoryBuilder', 'ObjectHelper',
+            'ObjectHolder', 'ObjectImpl', 'ObjectInput',
+            'ObjectInputStream', 'ObjectInputStream.GetField',
+            'ObjectInputValidation', 'ObjectOutput',
+            'ObjectOutputStream', 'ObjectOutputStream.PutField',
+            'ObjectStreamClass', 'ObjectStreamConstants',
+            'ObjectStreamException', 'ObjectStreamField',
+            'ObjectView', 'OBJECT_NOT_EXIST', 'ObjID',
+            'OBJ_ADAPTER', 'Observable', 'Observer',
+            'OctetSeqHelper', 'OctetSeqHolder', 'OMGVMCID',
+            'OpenType', 'Operation',
+            'OperationNotSupportedException', 'Option',
+            'OptionalDataException', 'OptionPaneUI', 'ORB',
+            'OutOfMemoryError', 'OutputStream',
+            'OutputStreamWriter', 'OverlayLayout', 'Owner',
+            'Package', 'PackedColorModel', 'Pageable',
+            'PageAttributes', 'PageAttributes.ColorType',
+            'PageAttributes.MediaType',
+            'PageAttributes.OrientationRequestedType',
+            'PageAttributes.OriginType',
+            'PageAttributes.PrintQualityType', 'PageFormat',
+            'Paint', 'PaintContext', 'PaintEvent', 'Panel',
+            'PanelUI', 'Paper', 'ParagraphView',
+            'ParameterBlock', 'ParameterDescriptor',
+            'ParseException', 'ParsePosition', 'Parser',
+            'ParserDelegator', 'PartialResultException',
+            'PasswordAuthentication', 'PasswordView', 'Patch',
+            'PathIterator', 'Permission', 'PermissionCollection',
+            'Permissions', 'PERSIST_STORE', 'PhantomReference',
+            'PipedInputStream', 'PipedOutputStream',
+            'PipedReader', 'PipedWriter', 'PixelGrabber',
+            'PixelInterleavedSampleModel', 'PKCS8EncodedKeySpec',
+            'PlainDocument', 'PlainView', 'Point', 'Point2D',
+            'Point2D.Double', 'Point2D.Float', 'Policy',
+            'PolicyError', 'PolicyHelper', 'PolicyHolder',
+            'PolicyListHelper', 'PolicyListHolder',
+            'PolicyOperations', 'PolicyTypeHelper', 'Polygon',
+            'PopupMenu', 'PopupMenuEvent', 'PopupMenuListener',
+            'PopupMenuUI', 'Port', 'Port.Info',
+            'PortableRemoteObject',
+            'PortableRemoteObjectDelegate', 'Position',
+            'Position.Bias', 'PreparedStatement', 'Principal',
+            'PrincipalHolder', 'Printable',
+            'PrinterAbortException', 'PrinterException',
+            'PrinterGraphics', 'PrinterIOException',
+            'PrinterJob', 'PrintGraphics', 'PrintJob',
+            'PrintStream', 'PrintWriter', 'PrivateKey',
+            'PRIVATE_MEMBER', 'PrivilegedAction',
+            'PrivilegedActionException',
+            'PrivilegedExceptionAction', 'Process',
+            'ProfileDataException', 'ProgressBarUI',
+            'ProgressMonitor', 'ProgressMonitorInputStream',
+            'Properties', 'PropertyChangeEvent',
+            'PropertyChangeListener', 'PropertyChangeSupport',
+            'PropertyDescriptor', 'PropertyEditor',
+            'PropertyEditorManager', 'PropertyEditorSupport',
+            'PropertyPermission', 'PropertyResourceBundle',
+            'PropertyVetoException', 'ProtectionDomain',
+            'ProtocolException', 'Provider', 'ProviderException',
+            'Proxy', 'PublicKey', 'PUBLIC_MEMBER',
+            'PushbackInputStream', 'PushbackReader',
+            'QuadCurve2D', 'QuadCurve2D.Double',
+            'QuadCurve2D.Float', 'Random', 'RandomAccessFile',
+            'Raster', 'RasterFormatException', 'RasterOp',
+            'Reader', 'Receiver', 'Rectangle', 'Rectangle2D',
+            'Rectangle2D.Double', 'Rectangle2D.Float',
+            'RectangularShape', 'Ref', 'RefAddr', 'Reference',
+            'Referenceable', 'ReferenceQueue',
+            'ReferralException', 'ReflectPermission', 'Registry',
+            'RegistryHandler', 'RemarshalException', 'Remote',
+            'RemoteCall', 'RemoteException', 'RemoteObject',
+            'RemoteRef', 'RemoteServer', 'RemoteStub',
+            'RenderableImage', 'RenderableImageOp',
+            'RenderableImageProducer', 'RenderContext',
+            'RenderedImage', 'RenderedImageFactory', 'Renderer',
+            'RenderingHints', 'RenderingHints.Key',
+            'RepaintManager', 'ReplicateScaleFilter',
+            'Repository', 'RepositoryIdHelper', 'Request',
+            'RescaleOp', 'Resolver', 'ResolveResult',
+            'ResourceBundle', 'ResponseHandler', 'ResultSet',
+            'ResultSetMetaData', 'ReverbType', 'RGBImageFilter',
+            'RMIClassLoader', 'RMIClientSocketFactory',
+            'RMIFailureHandler', 'RMISecurityException',
+            'RMISecurityManager', 'RMIServerSocketFactory',
+            'RMISocketFactory', 'Robot', 'RootPaneContainer',
+            'RootPaneUI', 'RoundRectangle2D',
+            'RoundRectangle2D.Double', 'RoundRectangle2D.Float',
+            'RowMapper', 'RSAKey', 'RSAKeyGenParameterSpec',
+            'RSAPrivateCrtKey', 'RSAPrivateCrtKeySpec',
+            'RSAPrivateKey', 'RSAPrivateKeySpec', 'RSAPublicKey',
+            'RSAPublicKeySpec', 'RTFEditorKit',
+            'RuleBasedCollator', 'Runnable', 'Runtime',
+            'RunTime', 'RuntimeException', 'RunTimeOperations',
+            'RuntimePermission', 'SampleModel',
+            'SchemaViolationException', 'Scrollable',
+            'Scrollbar', 'ScrollBarUI', 'ScrollPane',
+            'ScrollPaneConstants', 'ScrollPaneLayout',
+            'ScrollPaneLayout.UIResource', 'ScrollPaneUI',
+            'SearchControls', 'SearchResult',
+            'SecureClassLoader', 'SecureRandom',
+            'SecureRandomSpi', 'Security', 'SecurityException',
+            'SecurityManager', 'SecurityPermission', 'Segment',
+            'SeparatorUI', 'Sequence', 'SequenceInputStream',
+            'Sequencer', 'Sequencer.SyncMode', 'Serializable',
+            'SerializablePermission', 'ServantObject',
+            'ServerCloneException', 'ServerError',
+            'ServerException', 'ServerNotActiveException',
+            'ServerRef', 'ServerRequest',
+            'ServerRuntimeException', 'ServerSocket',
+            'ServiceDetail', 'ServiceDetailHelper',
+            'ServiceInformation', 'ServiceInformationHelper',
+            'ServiceInformationHolder',
+            'ServiceUnavailableException', 'Set',
+            'SetOverrideType', 'SetOverrideTypeHelper', 'Shape',
+            'ShapeGraphicAttribute', 'Short', 'ShortHolder',
+            'ShortLookupTable', 'ShortMessage', 'ShortSeqHelper',
+            'ShortSeqHolder', 'Signature', 'SignatureException',
+            'SignatureSpi', 'SignedObject', 'Signer',
+            'SimpleAttributeSet', 'SimpleBeanInfo',
+            'SimpleDateFormat', 'SimpleTimeZone',
+            'SinglePixelPackedSampleModel',
+            'SingleSelectionModel', 'SizeLimitExceededException',
+            'SizeRequirements', 'SizeSequence', 'Skeleton',
+            'SkeletonMismatchException',
+            'SkeletonNotFoundException', 'SliderUI', 'Socket',
+            'SocketException', 'SocketImpl', 'SocketImplFactory',
+            'SocketOptions', 'SocketPermission',
+            'SocketSecurityException', 'SoftBevelBorder',
+            'SoftReference', 'SortedMap', 'SortedSet',
+            'Soundbank', 'SoundbankReader', 'SoundbankResource',
+            'SourceDataLine', 'SplitPaneUI', 'SQLData',
+            'SQLException', 'SQLInput', 'SQLOutput',
+            'SQLPermission', 'SQLWarning', 'Stack',
+            'StackOverflowError', 'StateEdit', 'StateEditable',
+            'StateFactory', 'Statement', 'Streamable',
+            'StreamableValue', 'StreamCorruptedException',
+            'StreamTokenizer', 'StrictMath', 'String',
+            'StringBuffer', 'StringBufferInputStream',
+            'StringCharacterIterator', 'StringContent',
+            'StringHolder', 'StringIndexOutOfBoundsException',
+            'StringReader', 'StringRefAddr', 'StringSelection',
+            'StringTokenizer', 'StringValueHelper',
+            'StringWriter', 'Stroke', 'Struct', 'StructMember',
+            'StructMemberHelper', 'Stub', 'StubDelegate',
+            'StubNotFoundException', 'Style', 'StyleConstants',
+            'StyleConstants.CharacterConstants',
+            'StyleConstants.ColorConstants',
+            'StyleConstants.FontConstants',
+            'StyleConstants.ParagraphConstants', 'StyleContext',
+            'StyledDocument', 'StyledEditorKit',
+            'StyledEditorKit.AlignmentAction',
+            'StyledEditorKit.BoldAction',
+            'StyledEditorKit.FontFamilyAction',
+            'StyledEditorKit.FontSizeAction',
+            'StyledEditorKit.ForegroundAction',
+            'StyledEditorKit.ItalicAction',
+            'StyledEditorKit.StyledTextAction',
+            'StyledEditorKit.UnderlineAction', 'StyleSheet',
+            'StyleSheet.BoxPainter', 'StyleSheet.ListPainter',
+            'SwingConstants', 'SwingPropertyChangeSupport',
+            'SwingUtilities', 'SyncFailedException',
+            'Synthesizer', 'SysexMessage', 'System',
+            'SystemColor', 'SystemException', 'SystemFlavorMap',
+            'TabableView', 'TabbedPaneUI', 'TabExpander',
+            'TableCellEditor', 'TableCellRenderer',
+            'TableColumn', 'TableColumnModel',
+            'TableColumnModelEvent', 'TableColumnModelListener',
+            'TableHeaderUI', 'TableModel', 'TableModelEvent',
+            'TableModelListener', 'TableUI', 'TableView',
+            'TabSet', 'TabStop', 'TagElement', 'TargetDataLine',
+            'TCKind', 'TextAction', 'TextArea', 'TextAttribute',
+            'TextComponent', 'TextEvent', 'TextField',
+            'TextHitInfo', 'TextLayout',
+            'TextLayout.CaretPolicy', 'TextListener',
+            'TextMeasurer', 'TextUI', 'TexturePaint', 'Thread',
+            'ThreadDeath', 'ThreadGroup', 'ThreadLocal',
+            'Throwable', 'Tie', 'TileObserver', 'Time',
+            'TimeLimitExceededException', 'Timer', 'TimerTask',
+            'Timestamp', 'TimeZone', 'TitledBorder', 'ToolBarUI',
+            'Toolkit', 'ToolTipManager', 'ToolTipUI',
+            'TooManyListenersException', 'Track',
+            'TransactionRequiredException',
+            'TransactionRolledbackException',
+            'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK',
+            'Transferable', 'TransformAttribute', 'TRANSIENT',
+            'Transmitter', 'Transparency', 'TreeCellEditor',
+            'TreeCellRenderer', 'TreeExpansionEvent',
+            'TreeExpansionListener', 'TreeMap', 'TreeModel',
+            'TreeModelEvent', 'TreeModelListener', 'TreeNode',
+            'TreePath', 'TreeSelectionEvent',
+            'TreeSelectionListener', 'TreeSelectionModel',
+            'TreeSet', 'TreeUI', 'TreeWillExpandListener',
+            'TypeCode', 'TypeCodeHolder', 'TypeMismatch',
+            'Types', 'UID', 'UIDefaults',
+            'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap',
+            'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue',
+            'UIManager', 'UIManager.LookAndFeelInfo',
+            'UIResource', 'ULongLongSeqHelper',
+            'ULongLongSeqHolder', 'ULongSeqHelper',
+            'ULongSeqHolder', 'UndeclaredThrowableException',
+            'UndoableEdit', 'UndoableEditEvent',
+            'UndoableEditListener', 'UndoableEditSupport',
+            'UndoManager', 'UnexpectedException',
+            'UnicastRemoteObject', 'UnionMember',
+            'UnionMemberHelper', 'UNKNOWN', 'UnknownError',
+            'UnknownException', 'UnknownGroupException',
+            'UnknownHostException', 'UnknownObjectException',
+            'UnknownServiceException', 'UnknownUserException',
+            'UnmarshalException', 'UnrecoverableKeyException',
+            'Unreferenced', 'UnresolvedPermission',
+            'UnsatisfiedLinkError', 'UnsolicitedNotification',
+            'UnsolicitedNotificationEvent',
+            'UnsolicitedNotificationListener',
+            'UnsupportedAudioFileException',
+            'UnsupportedClassVersionError',
+            'UnsupportedEncodingException',
+            'UnsupportedFlavorException',
+            'UnsupportedLookAndFeelException',
+            'UnsupportedOperationException',
+            'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE',
+            'URL', 'URLClassLoader', 'URLConnection',
+            'URLDecoder', 'URLEncoder', 'URLStreamHandler',
+            'URLStreamHandlerFactory', 'UserException',
+            'UShortSeqHelper', 'UShortSeqHolder',
+            'UTFDataFormatException', 'Util', 'UtilDelegate',
+            'Utilities', 'ValueBase', 'ValueBaseHelper',
+            'ValueBaseHolder', 'ValueFactory', 'ValueHandler',
+            'ValueMember', 'ValueMemberHelper',
+            'VariableHeightLayoutCache', 'Vector', 'VerifyError',
+            'VersionSpecHelper', 'VetoableChangeListener',
+            'VetoableChangeSupport', 'View', 'ViewFactory',
+            'ViewportLayout', 'ViewportUI',
+            'VirtualMachineError', 'Visibility',
+            'VisibilityHelper', 'VMID', 'VM_ABSTRACT',
+            'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE',
+            'VoiceStatus', 'Void', 'WCharSeqHelper',
+            'WCharSeqHolder', 'WeakHashMap', 'WeakReference',
+            'Window', 'WindowAdapter', 'WindowConstants',
+            'WindowEvent', 'WindowListener', 'WrappedPlainView',
+            'WritableRaster', 'WritableRenderedImage',
+            'WriteAbortedException', 'Writer',
+            'WrongTransaction', 'WStringValueHelper',
+            'X509Certificate', 'X509CRL', 'X509CRLEntry',
+            'X509EncodedKeySpec', 'X509Extension', 'ZipEntry',
+            'ZipException', 'ZipFile', 'ZipInputStream',
+            'ZipOutputStream', 'ZoneView',
+            '_BindingIteratorImplBase', '_BindingIteratorStub',
+            '_IDLTypeStub', '_NamingContextImplBase',
+            '_NamingContextStub', '_PolicyStub', '_Remote_Stub'
+            ),
+        4 => array(
+            'boolean', 'byte', 'char', 'double', 'float', 'int', 'long',
+            'short', 'void'
+            ),
+        5 => array(
+            'allProperties', 'asImmutable', 'asSynchronized', 'collect',
+            'count', 'each', 'eachProperty', 'eachPropertyName',
+            'eachWithIndex', 'find', 'findAll', 'findIndexOf',
+            'flatten', 'get', 'grep', 'inject', 'intersect',
+            'join', 'max', 'min', 'pop', 'reverse',
+            'reverseEach', 'size', 'sort', 'subMap', 'toList'
+            ),
+        6 => array(
+            'center', 'contains', 'eachMatch', 'padLeft', 'padRight',
+            'toCharacter', 'tokenize', 'toLong', 'toURL'
+            ),
+        7 => array(
+            'append', 'eachByte', 'eachFile', 'eachFileRecurse', 'eachLine',
+            'eachLines', 'encodeBase64', 'filterLine', 'getText',
+            'splitEachLine', 'transformChar', 'transformLine',
+            'withOutputStream', 'withPrintWriter', 'withReader',
+            'withStream', 'withStreams', 'withWriter',
+            'withWriterAppend', 'write', 'writeLine'
+            ),
+        8 => array(
+            'dump', 'getLastMatcher', 'inspect', 'invokeMethod', 'print',
+            'println', 'start', 'startDaemon', 'step', 'times',
+            'upto', 'use'
+            ),
+        9 => array(
+            'call', 'close', 'eachRow', 'execute', 'executeUpdate', 'Sql'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?', '|', '=',
+        '=>', '||', '-', '+', '<<', '<<<', '&&'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => true,
+        1 => false,
+        2 => false,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true,
+        9 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #aaaadd; font-weight: bold;',
+            4 => 'color: #993333;',
+            5 => 'color: #663399;',
+            6 => 'color: #CC0099;',
+            7 => 'color: #FFCC33;',
+            8 => 'color: #993399;',
+            9 => 'color: #993399; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1=> 'color: #808080; font-style: italic;',
+            2=> 'color: #a1a100;',
+            3=> 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;'
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAMEL}',
+        2 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAMEL}',
+        3 => 'http://www.google.de/search?as_q={FNAME}&amp;num=100&amp;hl=en&amp;as_occt=url&amp;as_sitesearch=java.sun.com%2Fj2se%2F1.5.0%2Fdocs%2Fapi%2F',
+        4 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+        5 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+        6 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+        7 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+        8 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+        9 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        //Variables
+        0 => '\\$\\{[a-zA-Z_][a-zA-Z0-9_]*\\}'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/haskell.php b/examples/includes/geshi/geshi/haskell.php
new file mode 100644 (file)
index 0000000..a6841dd
--- /dev/null
@@ -0,0 +1,198 @@
+<?php
+/*************************************************************************************
+ * haskell.php
+ * ----------
+ * Author: Jason Dagit (dagit@codersbase.com) based on ocaml.php by Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/08/27
+ *
+ * Haskell language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2005/08/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Haskell',
+    'COMMENT_SINGLE' => array( 1 => '--'),
+    'COMMENT_MULTI' => array('{-' => '-}'),
+    'COMMENT_REGEXP' => array(2 => "/-->/"),
+    'CASE_KEYWORDS' => 0,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => "\\",
+    'KEYWORDS' => array(
+        /* main haskell keywords */
+        1 => array(
+            'as',
+            'case', 'of', 'class', 'data', 'default',
+            'deriving', 'do', 'forall', 'hiding', 'if', 'then',
+            'else', 'import', 'infix', 'infixl', 'infixr',
+            'instance', 'let', 'in', 'module', 'newtype',
+            'qualified', 'type', 'where'
+            ),
+        /* define names of main librarys, so we can link to it */
+        2 => array(
+            'Foreign', 'Numeric', 'Prelude'
+            ),
+        /* just link to Prelude functions, cause it's the default opened library when starting Haskell */
+        3 => array(
+            'not', 'otherwise', 'maybe',
+            'either', 'fst', 'snd', 'curry', 'uncurry',
+            'compare',
+            'max', 'min', 'succ', 'pred', 'toEnum', 'fromEnum',
+            'enumFrom', 'enumFromThen', 'enumFromTo',
+            'enumFromThenTo', 'minBound', 'maxBound',
+            'negate', 'abs', 'signum',
+            'fromInteger', 'toRational', 'quot', 'rem',
+            'div', 'mod', 'quotRem', 'divMod', 'toInteger',
+            'recip', 'fromRational', 'pi', 'exp',
+            'log', 'sqrt', 'logBase', 'sin', 'cos',
+            'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh',
+            'tanh', 'asinh', 'acosh', 'atanh',
+            'properFraction', 'truncate', 'round', 'ceiling',
+            'floor', 'floatRadix', 'floatDigits', 'floatRange',
+            'decodeFloat', 'encodeFloat', 'exponent',
+            'significand', 'scaleFloat', 'isNaN', 'isInfinite',
+            'isDenomalized', 'isNegativeZero', 'isIEEE',
+            'atan2', 'subtract', 'even', 'odd', 'gcd',
+            'lcm', 'fromIntegral', 'realToFrac',
+            'return', 'fail', 'fmap',
+            'mapM', 'mapM_', 'sequence', 'sequence_',
+            'id', 'const','flip',
+            'until', 'asTypeOf', 'error', 'undefined',
+            'seq','map','filter', 'head',
+            'last', 'tail', 'init', 'null', 'length',
+            'reverse', 'foldl', 'foldl1', 'foldr',
+            'foldr1', 'and', 'or', 'any', 'all', 'sum',
+            'product', 'concat', 'concatMap', 'maximum',
+            'minimum', 'scanl', 'scanl1', 'scanr', 'scanr1',
+            'iterate', 'repeat', 'cycle', 'take', 'drop',
+            'splitAt', 'teakWhile', 'dropWhile', 'span',
+            'break', 'elem', 'notElem', 'lookup', 'zip',
+            'zip3', 'zipWith', 'zipWith3', 'unzip', 'unzip3',
+            'lines', 'words', 'unlines',
+            'unwords', 'showPrec', 'show', 'showList',
+            'shows', 'showChar', 'showString', 'showParen',
+            'readsPrec', 'readList', 'reads', 'readParen',
+            'read', 'lex', 'putChar', 'putStr', 'putStrLn',
+            'print', 'getChar', 'getLine', 'getContents',
+            'interact', 'readFile', 'writeFile', 'appendFile',
+            'readIO', 'readLn', 'ioError', 'userError', 'catch'
+            ),
+        /* here Prelude Types */
+        4 => array (
+            'Bool', 'Maybe', 'Either', 'Ord', 'Ordering',
+            'Char', 'String', 'Eq', 'Enum', 'Bounded',
+            'Int', 'Integer', 'Float', 'Double', 'Rational',
+            'Num', 'Real', 'Integral', 'Fractional',
+            'Floating', 'RealFrac', 'RealFloat', 'Monad',
+            'Functor', 'Show', 'ShowS', 'Read', 'ReadS',
+            'IO'
+            ),
+        /* finally Prelude Exceptions */
+        5 => array (
+            'IOError', 'IOException'
+            )
+        ),
+    /* highlighting symbols is really important in Haskell */
+    'SYMBOLS' => array(
+        '|', '->', '<-', '@', '!', '::', '_', '~', '=', '?',
+        '&&', '||', '==', '/=', '<', '<=', '>',
+        '>=','+', '-', '*','/', '%', '**', '^', '^^',
+        '>>=', '>>', '=<<',  '$', '.', ',', '$!',
+        '++', '!!'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true, /* functions name are case seinsitive */
+        3 => true, /* types name too */
+        4 => true, /* finally exceptions too */
+        5 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #06c; font-weight: bold;', /* nice blue */
+            2 => 'color: #06c; font-weight: bold;', /* blue as well */
+            3 => 'font-weight: bold;', /* make the preduled functions bold */
+            4 => 'color: #cccc00; font-weight: bold;', /* give types a different bg */
+            5 => 'color: maroon;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #5d478b; font-style: italic;',
+            2 => 'color: #339933; font-weight: bold;',
+            'MULTI' => 'color: #5d478b; font-style: italic;' /* light purpHle */
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'background-color: #3cb371; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: green;'
+            ),
+        'STRINGS' => array(
+            0 => 'background-color: #3cb371;' /* nice green */
+            ),
+        'NUMBERS' => array(
+            0 => 'color: red;' /* pink */
+            ),
+        'METHODS' => array(
+            1 => 'color: #060;' /* dark green */
+            ),
+        'REGEXPS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933; font-weight: bold;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        /* some of keywords are Prelude functions */
+        1 => '',
+        /* link to the wanted library */
+        2 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/{FNAME}.html',
+        /* link to Prelude functions */
+        3 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:{FNAME}',
+        /* link to Prelude types */
+        4 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:{FNAME}',
+        /* link to Prelude exceptions */
+        5 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:{FNAME}',
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/hq9plus.php b/examples/includes/geshi/geshi/hq9plus.php
new file mode 100644 (file)
index 0000000..89e0434
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+/*************************************************************************************
+ * hq9plus.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/10/31
+ *
+ * HQ9+ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'HQ9+',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        ),
+    'SYMBOLS' => array(
+        'H', 'Q', '9', '+', 'h', 'q'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            ),
+        'COMMENTS' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #a16000;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'KEYWORDS' => GESHI_NEVER,
+            'COMMENTS' => GESHI_NEVER,
+            'STRINGS' => GESHI_NEVER,
+            'REGEXPS' => GESHI_NEVER,
+            'NUMBERS' => GESHI_NEVER
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/html4strict.php b/examples/includes/geshi/geshi/html4strict.php
new file mode 100644 (file)
index 0000000..68a0e51
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+/*************************************************************************************
+ * html4strict.php
+ * ---------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/10
+ *
+ * HTML 4.01 strict language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/28 (1.0.4)
+ *   -  Removed escape character for strings
+ * 2004/11/27 (1.0.3)
+ *   -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.1)
+ *   -  Added INS and DEL
+ *   -  Removed the background colour from tags' styles
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Check that only HTML4 strict attributes are highlighted
+ * * Eliminate empty tags that aren't allowed in HTML4 strict
+ * * Split to several files - html4trans, xhtml1 etc
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'HTML',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        2 => array(
+            'a', 'abbr', 'acronym', 'address', 'applet',
+
+            'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+            'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+            'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+            'em',
+
+            'fieldset', 'font', 'form', 'frame', 'frameset',
+
+            'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+            'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+            'kbd',
+
+            'label', 'legend', 'link', 'li',
+
+            'map', 'meta',
+
+            'noframes', 'noscript',
+
+            'object', 'ol', 'optgroup', 'option',
+
+            'param', 'pre', 'p',
+
+            'q',
+
+            'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+            'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+            'ul', 'u',
+
+            'var',
+            ),
+        3 => array(
+            'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+            'background', 'bgcolor', 'border',
+            'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+            'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+            'enctype',
+            'face', 'for', 'frame', 'frameborder',
+            'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+            'id', 'ismap',
+            'label', 'lang', 'language', 'link', 'longdesc',
+            'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+            'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+            'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+            'profile', 'prompt',
+            'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+            'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+            'tabindex', 'target', 'text', 'title', 'type',
+            'usemap',
+            'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+            'width'
+            )
+        ),
+    'SYMBOLS' => array(
+        '/', '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            -1 => 'color: #808080; font-style: italic;', // comments
+            0 => 'color: #00bbdd;',
+            1 => 'color: #ddbb00;',
+            2 => 'color: #009900;'
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        2 => 'http://december.com/html/4/element/{FNAMEL}.html',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        -1 => array(
+            '<!--' => '-->'
+            ),
+        0 => array(
+            '<!DOCTYPE' => '>'
+            ),
+        1 => array(
+            '&' => ';'
+            ),
+        2 => array(
+            '<' => '>'
+            )
+    ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        -1 => false,
+        0 => false,
+        1 => false,
+        2 => true
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            2 => array(
+                'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+                'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+            )
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/idl.php b/examples/includes/geshi/geshi/idl.php
new file mode 100644 (file)
index 0000000..a641554
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+/*************************************************************************************
+ * idl.php
+ * -------
+ * Author: Cedric Bosdonnat (cedricbosdo@openoffice.org)
+ * Copyright: (c) 2006 Cedric Bosdonnat
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/08/20
+ *
+ * Unoidl language file for GeSHi.
+ *
+ * 2006/08/20 (1.0.0)
+ *  -  First Release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+
+$language_data = array (
+    'LANG_NAME' => 'Uno Idl',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'published', 'get', 'set', 'service', 'singleton', 'type', 'module', 'interface', 'struct',
+            'const', 'constants', 'exception', 'enum', 'raises', 'typedef'
+            ),
+        2 => array(
+            'bound', 'maybeambiguous', 'maybedefault', 'maybevoid', 'oneway', 'optional',
+            'readonly', 'in', 'out', 'inout', 'attribute', 'transient', 'removable'
+            ),
+        3 => array(
+            'True', 'False', 'TRUE', 'FALSE'
+            ),
+        4 => array(
+            'string', 'long', 'byte', 'hyper', 'boolean', 'any', 'char', 'double',
+            'void', 'sequence', 'unsigned'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':', ';', '...'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #990078; font-weight: bold',
+            2 => 'color: #36dd1c;',
+            3 => 'color: #990078; font-weight: bold',
+            4 => 'color: #0000ec;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #3f7f5f;',
+            2 => 'color: #808080;',
+            'MULTI' => 'color: #4080ff; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #666666; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #808080;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000dd;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        1 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/ini.php b/examples/includes/geshi/geshi/ini.php
new file mode 100644 (file)
index 0000000..b6e3a38
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+/*************************************************************************************
+ * ini.php
+ * --------
+ * Author: deguix (cevo_deguix@yahoo.com.br)
+ * Copyright: (c) 2005 deguix
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/03/27
+ *
+ * INI language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2005/12/28 (1.0.1)
+ *   -  Removed unnecessary keyword style index
+ *   -  Added support for " strings
+ * 2005/04/05 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2005/03/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'INI',
+    'COMMENT_SINGLE' => array(0 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            ),
+        'COMMENTS' => array(
+            0 => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => ''
+            ),
+        'STRINGS' => array(
+            0 => 'color: #933;'
+            ),
+        'NUMBERS' => array(
+            0 => ''
+            ),
+        'METHODS' => array(
+            0 => ''
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066; font-weight:bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #000066; font-weight:bold;',
+            1 => 'color: #000099;',
+            2 => 'color: #660066;'
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            )
+        ),
+    'URLS' => array(
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Section names
+        0 => '\[.+\]',
+        //Entry names
+        1 => array(
+            GESHI_SEARCH => '^(\s*)([a-zA-Z0-9_\-]+)(\s*=)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+        //Entry values
+        2 => array(
+            // Evil hackery to get around GeSHi bug: <>" and ; are added so <span>s can be matched
+            // Explicit match on variable names because if a comment is before the first < of the span
+            // gets chewed up...
+            GESHI_SEARCH => '([<>";a-zA-Z0-9_]+\s*)=(.*)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1=',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/inno.php b/examples/includes/geshi/geshi/inno.php
new file mode 100644 (file)
index 0000000..5cead10
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+/*************************************************************************************
+ * Inno.php
+ * ----------
+ * Author: Thomas Klingler (hotline@theratech.de) based on delphi.php from J�rja Norbert (jnorbi@vipmail.hu)
+ * Copyright: (c) 2004 J�rja Norbert, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/07/29
+ *
+ * Inno Script language inkl. Delphi (Object Pascal) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/09/03
+ *   -  First Release
+ *
+ * TODO (updated 2005/07/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Inno',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('(*' => '*)'),
+    'CASE_KEYWORDS' => 0,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'Setup','Types','Components','Tasks','Dirs','Files','Icons','INI',
+            'InstallDelete','Languages','Messages','CustomMessage',
+            'LangOptions','Registry','RUN','UninstallDelete','UninstallRun',
+            'app','win','sys','syswow64','src','sd','pf','pf32','pf64','cf',
+            'cf32','cf64','tmp','fonts','dao','group','localappdata','sendto',
+            'userappdata','commonappdata','userdesktop','commondesktop',
+            'userdocs','commondocs','userfavorites','commonfavorites',
+            'userprograms','commonprograms','userstartmenu','commonstartmenu',
+            'userstartup','commonstartup','usertemplates','commontemplates'
+            ),
+        2 => array(
+            'nil', 'false', 'true', 'var', 'type', 'const','And', 'Array', 'As', 'Begin', 'Case', 'Class', 'Constructor', 'Destructor', 'Div', 'Do', 'DownTo', 'Else',
+            'End', 'Except', 'File', 'Finally', 'For', 'Function', 'Goto', 'If', 'Implementation', 'In', 'Inherited', 'Interface',
+            'Is', 'Mod', 'Not', 'Object', 'Of', 'On', 'Or', 'Packed', 'Procedure', 'Property', 'Raise', 'Record',
+            'Repeat', 'Set', 'Shl', 'Shr', 'Then', 'ThreadVar', 'To', 'Try', 'Unit', 'Until', 'Uses', 'While', 'With', 'Xor',
+
+            'HKCC','HKCR','HKCU','HKLM','HKU','alwaysoverwrite','alwaysskipifsameorolder','append',
+            'binary','classic','closeonexit','comparetimestamp','confirmoverwrite',
+            'createkeyifdoesntexist','createonlyiffileexists','createvalueifdoesntexist',
+            'deleteafterinstall','deletekey','deletevalue','dirifempty','dontcloseonexit',
+            'dontcopy','dontcreatekey','disablenouninstallwarning','dword','exclusive','expandsz',
+            'external','files','filesandordirs','fixed','fontisnttruetype','ignoreversion','iscustom','isreadme',
+            'modern','multisz','new','noerror','none','normal','nowait','onlyifdestfileexists',
+            'onlyifdoesntexist','onlyifnewer','overwrite','overwritereadonly','postinstall',
+            'preservestringtype','promptifolder','regserver','regtypelib','restart','restartreplace',
+            'runhidden','runmaximized','runminimized','sharedfile','shellexec','showcheckbox',
+            'skipifnotsilent','skipifsilent','silent','skipifdoesntexist',
+            'skipifsourcedoesntexist','sortfilesbyextension','unchecked','uninsalwaysuninstall',
+            'uninsclearvalue','uninsdeleteentry','uninsdeletekey','uninsdeletekeyifempty',
+            'uninsdeletesection','uninsdeletesectionifempty','uninsdeletevalue',
+            'uninsneveruninstall','useapppaths','verysilent','waituntilidle'
+            ),
+        3 => array(
+            'Abs', 'Addr', 'AnsiCompareStr', 'AnsiCompareText', 'AnsiContainsStr', 'AnsiEndsStr', 'AnsiIndexStr', 'AnsiLeftStr',
+            'AnsiLowerCase', 'AnsiMatchStr', 'AnsiMidStr', 'AnsiPos', 'AnsiReplaceStr', 'AnsiReverseString', 'AnsiRightStr',
+            'AnsiStartsStr', 'AnsiUpperCase', 'ArcCos', 'ArcSin', 'ArcTan', 'Assigned', 'BeginThread', 'Bounds', 'CelsiusToFahrenheit',
+            'ChangeFileExt', 'Chr', 'CompareStr', 'CompareText', 'Concat', 'Convert', 'Copy', 'Cos', 'CreateDir', 'CurrToStr',
+            'CurrToStrF', 'Date', 'DateTimeToFileDate', 'DateTimeToStr', 'DateToStr', 'DayOfTheMonth', 'DayOfTheWeek', 'DayOfTheYear',
+            'DayOfWeek', 'DaysBetween', 'DaysInAMonth', 'DaysInAYear', 'DaySpan', 'DegToRad', 'DeleteFile', 'DiskFree', 'DiskSize',
+            'DupeString', 'EncodeDate', 'EncodeDateTime', 'EncodeTime', 'EndOfADay', 'EndOfAMonth', 'Eof', 'Eoln', 'Exp', 'ExtractFileDir',
+            'ExtractFileDrive', 'ExtractFileExt', 'ExtractFileName', 'ExtractFilePath', 'FahrenheitToCelsius', 'FileAge',
+            'FileDateToDateTime', 'FileExists', 'FilePos', 'FileSearch', 'FileSetDate', 'FileSize', 'FindClose', 'FindCmdLineSwitch',
+            'FindFirst', 'FindNext', 'FloatToStr', 'FloatToStrF', 'Format', 'FormatCurr', 'FormatDateTime', 'FormatFloat', 'Frac',
+            'GetCurrentDir', 'GetLastError', 'GetMem', 'High', 'IncDay', 'IncMinute', 'IncMonth', 'IncYear', 'InputBox',
+            'InputQuery', 'Int', 'IntToHex', 'IntToStr', 'IOResult', 'IsInfinite', 'IsLeapYear', 'IsMultiThread', 'IsNaN',
+            'LastDelimiter', 'Length', 'Ln', 'Lo', 'Log10', 'Low', 'LowerCase', 'Max', 'Mean', 'MessageDlg', 'MessageDlgPos',
+            'MonthOfTheYear', 'Now', 'Odd', 'Ord', 'ParamCount', 'ParamStr', 'Pi', 'Point', 'PointsEqual', 'Pos', 'Pred',
+            'Printer', 'PromptForFileName', 'PtInRect', 'RadToDeg', 'Random', 'RandomRange', 'RecodeDate', 'RecodeTime', 'Rect',
+            'RemoveDir', 'RenameFile', 'Round', 'SeekEof', 'SeekEoln', 'SelectDirectory', 'SetCurrentDir', 'Sin', 'SizeOf',
+            'Slice', 'Sqr', 'Sqrt', 'StringOfChar', 'StringReplace', 'StringToWideChar', 'StrToCurr', 'StrToDate', 'StrToDateTime',
+            'StrToFloat', 'StrToInt', 'StrToInt64', 'StrToInt64Def', 'StrToIntDef', 'StrToTime', 'StuffString', 'Succ', 'Sum', 'Tan',
+            'Time', 'TimeToStr', 'Tomorrow', 'Trunc', 'UpCase', 'UpperCase', 'VarType', 'WideCharToString', 'WrapText', 'Yesterday',
+            'Append', 'AppendStr', 'Assign', 'AssignFile', 'AssignPrn', 'Beep', 'BlockRead', 'BlockWrite', 'Break',
+            'ChDir', 'Close', 'CloseFile', 'Continue', 'DateTimeToString', 'Dec', 'DecodeDate', 'DecodeDateTime',
+            'DecodeTime', 'Delete', 'Dispose', 'EndThread', 'Erase', 'Exclude', 'Exit', 'FillChar', 'Flush', 'FreeAndNil',
+            'FreeMem', 'GetDir', 'GetLocaleFormatSettings', 'Halt', 'Inc', 'Include', 'Insert', 'MkDir', 'Move', 'New',
+            'ProcessPath', 'Randomize', 'Read', 'ReadLn', 'ReallocMem', 'Rename', 'ReplaceDate', 'ReplaceTime',
+            'Reset', 'ReWrite', 'RmDir', 'RunError', 'Seek', 'SetLength', 'SetString', 'ShowMessage', 'ShowMessageFmt',
+            'ShowMessagePos', 'Str', 'Truncate', 'Val', 'Write', 'WriteLn',
+
+            'AdminPrivilegesRequired','AfterInstall','AllowCancelDuringInstall','AllowNoIcons','AllowRootDirectory','AllowUNCPath','AlwaysRestart','AlwaysShowComponentsList','AlwaysShowDirOnReadyPage','AlwaysShowGroupOnReadyPage ','AlwaysUsePersonalGroup','AppComments','AppContact','AppCopyright','AppendDefaultDirName',
+            'AppendDefaultGroupName','AppId','AppModifyPath','AppMutex','AppName','AppPublisher',
+            'AppPublisherURL','AppReadmeFile','AppSupportURL','AppUpdatesURL','AppVerName','AppVersion',
+            'Attribs','BackColor','BackColor2','BackColorDirection','BackSolid','BeforeInstall',
+            'ChangesAssociations','ChangesEnvironment','Check','CodeFile','Comment','Compression','CopyMode',
+            'CreateAppDir','CreateUninstallRegKey','DefaultDirName','DefaultGroupName',
+            'DefaultUserInfoName','DefaultUserInfoOrg','DefaultUserInfoSerial',
+            'Description','DestDir','DestName','DirExistsWarning',
+            'DisableDirPage','DisableFinishedPage',
+            'DisableProgramGroupPage','DisableReadyMemo','DisableReadyPage',
+            'DisableStartupPrompt','DiskClusterSize','DiskSliceSize','DiskSpaceMBLabel',
+            'DiskSpanning','DontMergeDuplicateFiles','EnableDirDoesntExistWarning','Encryption',
+            'Excludes','ExtraDiskSpaceRequired','Filename','Flags','FlatComponentsList','FontInstall',
+            'GroupDescription','HotKey','IconFilename','IconIndex','InfoAfterFile','InfoBeforeFile',
+            'InternalCompressLevel','Key','LanguageDetectionMethod',
+            'LicenseFile','MergeDuplicateFiles','MessagesFile','MinVersion','Name',
+            'OnlyBelowVersion','OutputBaseFilename','OutputManifestFile','OutputDir',
+            'Parameters','Password','Permissions','PrivilegesRequired','ReserveBytes',
+            'RestartIfNeededByRun','Root','RunOnceId','Section','SetupIconFile',
+            'ShowComponentSizes','ShowLanguageDialog','ShowTasksTreeLines','SlicesPerDisk',
+            'SolidCompression','Source','SourceDir','StatusMsg','Subkey',
+            'TimeStampRounding','TimeStampsInUTC','TouchDate','TouchTime','Type',
+            'UninstallDisplayIcon','UninstallDisplayName','UninstallFilesDir','UninstallIconFile',
+            'UninstallLogMode','UninstallRestartComputer','UninstallStyle','Uninstallable',
+            'UpdateUninstallLogAppName','UsePreviousAppDir','UsePreviousGroup',
+            'UsePreviousTasks','UsePreviousSetupType','UsePreviousUserInfo',
+            'UserInfoPage','UseSetupLdr','ValueData','ValueName','ValueType',
+            'VersionInfoVersion','VersionInfoCompany','VersionInfoDescription','VersionInfoTextVersion',
+            'WindowResizable','WindowShowCaption','WindowStartMaximized',
+            'WindowVisible','WizardImageBackColor','WizardImageFile','WizardImageStretch','WizardSmallImageBackColor','WizardSmallImageFile','WizardStyle','WorkingDir'
+            ),
+        4 => array(
+            'AnsiChar', 'AnsiString', 'Boolean', 'Byte', 'Cardinal', 'Char', 'Comp', 'Currency', 'Double', 'Extended',
+            'Int64', 'Integer', 'LongInt', 'LongWord', 'PAnsiChar', 'PAnsiString', 'PChar', 'PCurrency', 'PDateTime',
+            'PExtended', 'PInt64', 'Pointer', 'PShortString', 'PString', 'PVariant', 'PWideChar', 'PWideString',
+            'Real', 'Real48', 'ShortInt', 'ShortString', 'Single', 'SmallInt', 'String', 'TBits', 'TConvType', 'TDateTime',
+            'Text', 'TextFile', 'TFloatFormat', 'TFormatSettings', 'TList', 'TObject', 'TOpenDialog', 'TPoint',
+            'TPrintDialog', 'TRect', 'TReplaceFlags', 'TSaveDialog', 'TSearchRec', 'TStringList', 'TSysCharSet',
+            'TThreadFunc', 'Variant', 'WideChar', 'WideString', 'Word'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '@', '%', '&', '*', '|', '/', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',/*bold Black*/
+            2 => 'color: #000000;font-style: italic;',/*Black*/
+            3 => 'color: #0000FF;',/*blue*/
+            4 => 'color: #CC0000;'/*red*/
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #33FF00; font-style: italic;',
+            'MULTI' => 'color: #33FF00; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000; font-weight: bold;',
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/intercal.php b/examples/includes/geshi/geshi/intercal.php
new file mode 100644 (file)
index 0000000..b4ad049
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+/*************************************************************************************
+ * intercal.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/10/31
+ *
+ * INTERCAL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'INTERCAL',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        //Politeness
+        1 => array(
+            'DO', 'DOES', 'DONT', 'DON\'T', 'NOT', 'PLEASE', 'PLEASENT', 'PLEASEN\'T', 'MAYBE'
+            ),
+        //Statements
+        2 => array(
+            'STASH', 'RETRIEVE', 'NEXT', 'RESUME', 'FORGET', 'ABSTAIN', 'ABSTAINING',
+            'COME', 'FROM', 'CALCULATING', 'REINSTATE', 'IGNORE', 'REMEMBER',
+            'WRITE', 'IN', 'READ', 'OUT', 'GIVE', 'UP'
+            )
+        ),
+    'SYMBOLS' => array(
+        '.', ',', ':', ';', '#',
+        '~', '$', '&', '?',
+        '\'', '"', '<-'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000080; font-weight: bold;',
+            2 => 'color: #000080; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            1 => 'color: #808080; font-style: italic;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        1 => '^\(\d+\)'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'COMMENTS' => GESHI_NEVER,
+            'STRINGS' => GESHI_NEVER,
+            'NUMBERS' => GESHI_NEVER
+            )
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/io.php b/examples/includes/geshi/geshi/io.php
new file mode 100644 (file)
index 0000000..e9117ab
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+/*************************************************************************************
+ * io.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2006 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/09/23
+ *
+ * Io language file for GeSHi. Thanks to Johnathan Wright for the suggestion and help
+ * with this language :)
+ *
+ * CHANGES
+ * -------
+ * 2006/09/23(1.0.0)
+ *  -  First Release
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Io',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'and', 'break', 'else', 'elseif', 'exit', 'for', 'foreach', 'if', 'ifFalse', 'ifNil',
+            'ifTrue', 'or', 'pass', 'raise', 'return', 'then', 'try', 'wait', 'while', 'yield'
+            ),
+        2 => array(
+            'activate', 'activeCoroCount', 'asString', 'block', 'catch', 'clone', 'collectGarbage',
+            'compileString', 'continue', 'do', 'doFile', 'doMessage', 'doString', 'forward',
+            'getSlot', 'getenv', 'hasSlot', 'isActive', 'isNil', 'isResumable', 'list', 'message',
+            'method', 'parent', 'pause', 'perform', 'performWithArgList', 'print', 'proto',
+            'raiseResumable', 'removeSlot', 'resend', 'resume', 'schedulerSleepSeconds', 'self',
+            'sender', 'setSchedulerSleepSeconds', 'setSlot', 'shallowCopy', 'slotNames', 'super',
+            'system', 'thisBlock', 'thisContext', 'thisMessage', 'type', 'uniqueId', 'updateSlot',
+            'write'
+            ),
+        3 => array(
+            'Array', 'AudioDevice', 'AudioMixer', 'Block', 'Box', 'Buffer', 'CFunction', 'CGI',
+            'Color', 'Curses', 'DBM', 'DNSResolver', 'DOConnection', 'DOProxy', 'DOServer',
+            'Date', 'Directory', 'Duration', 'DynLib', 'Error', 'Exception', 'FFT', 'File',
+            'Fnmatch', 'Font', 'Future', 'GL', 'GLE', 'GLScissor', 'GLU', 'GLUCylinder',
+            'GLUQuadric', 'GLUSphere', 'GLUT', 'Host', 'Image', 'Importer', 'LinkList', 'List',
+            'Lobby', 'Locals', 'MD5', 'MP3Decoder', 'MP3Encoder', 'Map', 'Message', 'Movie',
+            'NULL', 'Nil', 'Nop', 'Notifiction', 'Number', 'Object', 'OpenGL', 'Point', 'Protos',
+            'Regex', 'SGMLTag', 'SQLite', 'Server', 'ShowMessage', 'SleepyCat', 'SleepyCatCursor',
+            'Socket', 'SocketManager', 'Sound', 'Soup', 'Store', 'String', 'Tree', 'UDPSender',
+            'UDPReceiver', 'URL', 'User', 'Warning', 'WeakLink'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/java.php b/examples/includes/geshi/geshi/java.php
new file mode 100644 (file)
index 0000000..7e5dc08
--- /dev/null
@@ -0,0 +1,983 @@
+<?php
+/*************************************************************************************
+ * java.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/10
+ *
+ * Java language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/25 (1.0.7.22)
+ *   -  Added highlighting of import and package directives as non-OOP
+ * 2005/12/28 (1.0.4)
+ *   -  Added instanceof keyword
+ * 2004/11/27 (1.0.3)
+ *   -  Added support for multiple object splitters
+ * 2004/08/05 (1.0.2)
+ *   -  Added URL support
+ *   -  Added keyword "this", as bugs in GeSHi class ironed out
+ * 2004/08/05 (1.0.1)
+ *   -  Added support for symbols
+ *   -  Added extra missed keywords
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Compact the class names like the first few have been
+ *   and eliminate repeats
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Java',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Import and Package directives (Basic Support only)
+        2 => '/(?:(?<=import[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+        // javadoc comments
+        3 => '#/\*\*(?![\*\/]).*\*/#sU'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'for', 'foreach', 'if', 'else', 'while', 'do',
+            'switch', 'case',  'return', 'public',
+            'private', 'protected', 'extends', 'break', 'class',
+            'new', 'try', 'catch', 'throws', 'finally', 'implements',
+            'interface', 'throw', 'final', 'native', 'synchronized', 'this',
+            'abstract', 'transient', 'instanceof', 'assert', 'continue',
+            'default', 'enum', 'package', 'static', 'strictfp', 'super',
+            'volatile', 'const', 'goto', 'import'
+            ),
+        2 => array(
+            'null', 'false', 'true'
+            ),
+        3 => array(
+            'AbstractAction', 'AbstractBorder', 'AbstractButton',
+            'AbstractCellEditor', 'AbstractCollection',
+            'AbstractColorChooserPanel', 'AbstractDocument',
+            'AbstractDocument.AttributeContext',
+            'AbstractDocument.Content',
+            'AbstractDocument.ElementEdit',
+            'AbstractLayoutCache',
+            'AbstractLayoutCache.NodeDimensions', 'AbstractList',
+            'AbstractListModel', 'AbstractMap',
+            'AbstractMethodError', 'AbstractSequentialList',
+            'AbstractSet', 'AbstractTableModel',
+            'AbstractUndoableEdit', 'AbstractWriter',
+            'AccessControlContext', 'AccessControlException',
+            'AccessController', 'AccessException', 'Accessible',
+            'AccessibleAction', 'AccessibleBundle',
+            'AccessibleComponent', 'AccessibleContext',
+            'AccessibleHyperlink', 'AccessibleHypertext',
+            'AccessibleIcon', 'AccessibleObject',
+            'AccessibleRelation', 'AccessibleRelationSet',
+            'AccessibleResourceBundle', 'AccessibleRole',
+            'AccessibleSelection', 'AccessibleState',
+            'AccessibleStateSet', 'AccessibleTable',
+            'AccessibleTableModelChange', 'AccessibleText',
+            'AccessibleValue', 'Acl', 'AclEntry',
+            'AclNotFoundException', 'Action', 'ActionEvent',
+            'ActionListener', 'ActionMap', 'ActionMapUIResource',
+            'Activatable', 'ActivateFailedException',
+            'ActivationDesc', 'ActivationException',
+            'ActivationGroup', 'ActivationGroupDesc',
+            'ActivationGroupDesc.CommandEnvironment',
+            'ActivationGroupID', 'ActivationID',
+            'ActivationInstantiator', 'ActivationMonitor',
+            'ActivationSystem', 'Activator', 'ActiveEvent',
+            'Adjustable', 'AdjustmentEvent',
+            'AdjustmentListener', 'Adler32', 'AffineTransform',
+            'AffineTransformOp', 'AlgorithmParameterGenerator',
+            'AlgorithmParameterGeneratorSpi',
+            'AlgorithmParameters', 'AlgorithmParameterSpec',
+            'AlgorithmParametersSpi', 'AllPermission',
+            'AlphaComposite', 'AlreadyBound',
+            'AlreadyBoundException', 'AlreadyBoundHelper',
+            'AlreadyBoundHolder', 'AncestorEvent',
+            'AncestorListener', 'Annotation', 'Any', 'AnyHolder',
+            'AnySeqHelper', 'AnySeqHolder', 'Applet',
+            'AppletContext', 'AppletInitializer', 'AppletStub',
+            'ApplicationException', 'Arc2D', 'Arc2D.Double',
+            'Arc2D.Float', 'Area', 'AreaAveragingScaleFilter',
+            'ARG_IN', 'ARG_INOUT', 'ARG_OUT',
+            'ArithmeticException', 'Array',
+            'ArrayIndexOutOfBoundsException', 'ArrayList',
+            'Arrays', 'ArrayStoreException', 'AsyncBoxView',
+            'Attribute', 'AttributedCharacterIterator',
+            'AttributedCharacterIterator.Attribute',
+            'AttributedString', 'AttributeInUseException',
+            'AttributeList', 'AttributeModificationException',
+            'Attributes', 'Attributes.Name', 'AttributeSet',
+            'AttributeSet.CharacterAttribute',
+            'AttributeSet.ColorAttribute',
+            'AttributeSet.FontAttribute',
+            'AttributeSet.ParagraphAttribute', 'AudioClip',
+            'AudioFileFormat', 'AudioFileFormat.Type',
+            'AudioFileReader', 'AudioFileWriter', 'AudioFormat',
+            'AudioFormat.Encoding', 'AudioInputStream',
+            'AudioPermission', 'AudioSystem',
+            'AuthenticationException',
+            'AuthenticationNotSupportedException',
+            'Authenticator', 'Autoscroll', 'AWTError',
+            'AWTEvent', 'AWTEventListener',
+            'AWTEventMulticaster', 'AWTException',
+            'AWTPermission', 'BadKind', 'BadLocationException',
+            'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION',
+            'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE',
+            'BAD_POLICY_VALUE', 'BAD_TYPECODE', 'BandCombineOp',
+            'BandedSampleModel', 'BasicArrowButton',
+            'BasicAttribute', 'BasicAttributes', 'BasicBorders',
+            'BasicBorders.ButtonBorder',
+            'BasicBorders.FieldBorder',
+            'BasicBorders.MarginBorder',
+            'BasicBorders.MenuBarBorder',
+            'BasicBorders.RadioButtonBorder',
+            'BasicBorders.SplitPaneBorder',
+            'BasicBorders.ToggleButtonBorder',
+            'BasicButtonListener', 'BasicButtonUI',
+            'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI',
+            'BasicColorChooserUI', 'BasicComboBoxEditor',
+            'BasicComboBoxEditor.UIResource',
+            'BasicComboBoxRenderer',
+            'BasicComboBoxRenderer.UIResource',
+            'BasicComboBoxUI', 'BasicComboPopup',
+            'BasicDesktopIconUI', 'BasicDesktopPaneUI',
+            'BasicDirectoryModel', 'BasicEditorPaneUI',
+            'BasicFileChooserUI', 'BasicGraphicsUtils',
+            'BasicHTML', 'BasicIconFactory',
+            'BasicInternalFrameTitlePane',
+            'BasicInternalFrameUI', 'BasicLabelUI',
+            'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI',
+            'BasicMenuItemUI', 'BasicMenuUI',
+            'BasicOptionPaneUI',
+            'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI',
+            'BasicPasswordFieldUI', 'BasicPermission',
+            'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI',
+            'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI',
+            'BasicRadioButtonUI', 'BasicRootPaneUI',
+            'BasicScrollBarUI', 'BasicScrollPaneUI',
+            'BasicSeparatorUI', 'BasicSliderUI',
+            'BasicSplitPaneDivider', 'BasicSplitPaneUI',
+            'BasicStroke', 'BasicTabbedPaneUI',
+            'BasicTableHeaderUI', 'BasicTableUI',
+            'BasicTextAreaUI', 'BasicTextFieldUI',
+            'BasicTextPaneUI', 'BasicTextUI',
+            'BasicTextUI.BasicCaret',
+            'BasicTextUI.BasicHighlighter',
+            'BasicToggleButtonUI', 'BasicToolBarSeparatorUI',
+            'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI',
+            'BasicViewportUI', 'BatchUpdateException',
+            'BeanContext', 'BeanContextChild',
+            'BeanContextChildComponentProxy',
+            'BeanContextChildSupport',
+            'BeanContextContainerProxy', 'BeanContextEvent',
+            'BeanContextMembershipEvent',
+            'BeanContextMembershipListener', 'BeanContextProxy',
+            'BeanContextServiceAvailableEvent',
+            'BeanContextServiceProvider',
+            'BeanContextServiceProviderBeanInfo',
+            'BeanContextServiceRevokedEvent',
+            'BeanContextServiceRevokedListener',
+            'BeanContextServices', 'BeanContextServicesListener',
+            'BeanContextServicesSupport',
+            'BeanContextServicesSupport.BCSSServiceProvider',
+            'BeanContextSupport',
+            'BeanContextSupport.BCSIterator', 'BeanDescriptor',
+            'BeanInfo', 'Beans', 'BevelBorder', 'BigDecimal',
+            'BigInteger', 'BinaryRefAddr', 'BindException',
+            'Binding', 'BindingHelper', 'BindingHolder',
+            'BindingIterator', 'BindingIteratorHelper',
+            'BindingIteratorHolder', 'BindingIteratorOperations',
+            'BindingListHelper', 'BindingListHolder',
+            'BindingType', 'BindingTypeHelper',
+            'BindingTypeHolder', 'BitSet', 'Blob', 'BlockView',
+            'Book', 'Boolean', 'BooleanControl',
+            'BooleanControl.Type', 'BooleanHolder',
+            'BooleanSeqHelper', 'BooleanSeqHolder', 'Border',
+            'BorderFactory', 'BorderLayout', 'BorderUIResource',
+            'BorderUIResource.BevelBorderUIResource',
+            'BorderUIResource.CompoundBorderUIResource',
+            'BorderUIResource.EmptyBorderUIResource',
+            'BorderUIResource.EtchedBorderUIResource',
+            'BorderUIResource.LineBorderUIResource',
+            'BorderUIResource.MatteBorderUIResource',
+            'BorderUIResource.TitledBorderUIResource',
+            'BoundedRangeModel', 'Bounds', 'Box', 'Box.Filler',
+            'BoxedValueHelper', 'BoxLayout', 'BoxView',
+            'BreakIterator', 'BufferedImage',
+            'BufferedImageFilter', 'BufferedImageOp',
+            'BufferedInputStream', 'BufferedOutputStream',
+            'BufferedReader', 'BufferedWriter', 'Button',
+            'ButtonGroup', 'ButtonModel', 'ButtonUI', 'Byte',
+            'ByteArrayInputStream', 'ByteArrayOutputStream',
+            'ByteHolder', 'ByteLookupTable', 'Calendar',
+            'CallableStatement', 'CannotProceed',
+            'CannotProceedException', 'CannotProceedHelper',
+            'CannotProceedHolder', 'CannotRedoException',
+            'CannotUndoException', 'Canvas', 'CardLayout',
+            'Caret', 'CaretEvent', 'CaretListener', 'CellEditor',
+            'CellEditorListener', 'CellRendererPane',
+            'Certificate', 'Certificate.CertificateRep',
+            'CertificateEncodingException',
+            'CertificateException',
+            'CertificateExpiredException', 'CertificateFactory',
+            'CertificateFactorySpi',
+            'CertificateNotYetValidException',
+            'CertificateParsingException',
+            'ChangedCharSetException', 'ChangeEvent',
+            'ChangeListener', 'Character', 'Character.Subset',
+            'Character.UnicodeBlock', 'CharacterIterator',
+            'CharArrayReader', 'CharArrayWriter',
+            'CharConversionException', 'CharHolder',
+            'CharSeqHelper', 'CharSeqHolder', 'Checkbox',
+            'CheckboxGroup', 'CheckboxMenuItem',
+            'CheckedInputStream', 'CheckedOutputStream',
+            'Checksum', 'Choice', 'ChoiceFormat', 'Class',
+            'ClassCastException', 'ClassCircularityError',
+            'ClassDesc', 'ClassFormatError', 'ClassLoader',
+            'ClassNotFoundException', 'Clip', 'Clipboard',
+            'ClipboardOwner', 'Clob', 'Cloneable',
+            'CloneNotSupportedException', 'CMMException',
+            'CodeSource', 'CollationElementIterator',
+            'CollationKey', 'Collator', 'Collection',
+            'Collections', 'Color',
+            'ColorChooserComponentFactory', 'ColorChooserUI',
+            'ColorConvertOp', 'ColorModel',
+            'ColorSelectionModel', 'ColorSpace',
+            'ColorUIResource', 'ComboBoxEditor', 'ComboBoxModel',
+            'ComboBoxUI', 'ComboPopup', 'CommunicationException',
+            'COMM_FAILURE', 'Comparable', 'Comparator',
+            'Compiler', 'CompletionStatus',
+            'CompletionStatusHelper', 'Component',
+            'ComponentAdapter', 'ComponentColorModel',
+            'ComponentEvent', 'ComponentInputMap',
+            'ComponentInputMapUIResource', 'ComponentListener',
+            'ComponentOrientation', 'ComponentSampleModel',
+            'ComponentUI', 'ComponentView', 'Composite',
+            'CompositeContext', 'CompositeName', 'CompositeView',
+            'CompoundBorder', 'CompoundControl',
+            'CompoundControl.Type', 'CompoundEdit',
+            'CompoundName', 'ConcurrentModificationException',
+            'ConfigurationException', 'ConnectException',
+            'ConnectIOException', 'Connection', 'Constructor', 'Container',
+            'ContainerAdapter', 'ContainerEvent',
+            'ContainerListener', 'ContentHandler',
+            'ContentHandlerFactory', 'ContentModel', 'Context',
+            'ContextList', 'ContextNotEmptyException',
+            'ContextualRenderedImageFactory', 'Control',
+            'Control.Type', 'ControlFactory',
+            'ControllerEventListener', 'ConvolveOp', 'CRC32',
+            'CRL', 'CRLException', 'CropImageFilter', 'CSS',
+            'CSS.Attribute', 'CTX_RESTRICT_SCOPE',
+            'CubicCurve2D', 'CubicCurve2D.Double',
+            'CubicCurve2D.Float', 'Current', 'CurrentHelper',
+            'CurrentHolder', 'CurrentOperations', 'Cursor',
+            'Customizer', 'CustomMarshal', 'CustomValue',
+            'DatabaseMetaData', 'DataBuffer', 'DataBufferByte',
+            'DataBufferInt', 'DataBufferShort',
+            'DataBufferUShort', 'DataFlavor',
+            'DataFormatException', 'DatagramPacket',
+            'DatagramSocket', 'DatagramSocketImpl',
+            'DatagramSocketImplFactory', 'DataInput',
+            'DataInputStream', 'DataLine', 'DataLine.Info',
+            'DataOutput', 'DataOutputStream',
+            'DataTruncation', 'DATA_CONVERSION', 'Date',
+            'DateFormat', 'DateFormatSymbols', 'DebugGraphics',
+            'DecimalFormat', 'DecimalFormatSymbols',
+            'DefaultBoundedRangeModel', 'DefaultButtonModel',
+            'DefaultCaret', 'DefaultCellEditor',
+            'DefaultColorSelectionModel', 'DefaultComboBoxModel',
+            'DefaultDesktopManager', 'DefaultEditorKit',
+            'DefaultEditorKit.BeepAction',
+            'DefaultEditorKit.CopyAction',
+            'DefaultEditorKit.CutAction',
+            'DefaultEditorKit.DefaultKeyTypedAction',
+            'DefaultEditorKit.InsertBreakAction',
+            'DefaultEditorKit.InsertContentAction',
+            'DefaultEditorKit.InsertTabAction',
+            'DefaultEditorKit.PasteAction,',
+            'DefaultFocusManager', 'DefaultHighlighter',
+            'DefaultHighlighter.DefaultHighlightPainter',
+            'DefaultListCellRenderer',
+            'DefaultListCellRenderer.UIResource',
+            'DefaultListModel', 'DefaultListSelectionModel',
+            'DefaultMenuLayout', 'DefaultMetalTheme',
+            'DefaultMutableTreeNode',
+            'DefaultSingleSelectionModel',
+            'DefaultStyledDocument',
+            'DefaultStyledDocument.AttributeUndoableEdit',
+            'DefaultStyledDocument.ElementSpec',
+            'DefaultTableCellRenderer',
+            'DefaultTableCellRenderer.UIResource',
+            'DefaultTableColumnModel', 'DefaultTableModel',
+            'DefaultTextUI', 'DefaultTreeCellEditor',
+            'DefaultTreeCellRenderer', 'DefaultTreeModel',
+            'DefaultTreeSelectionModel', 'DefinitionKind',
+            'DefinitionKindHelper', 'Deflater',
+            'DeflaterOutputStream', 'Delegate', 'DesignMode',
+            'DesktopIconUI', 'DesktopManager', 'DesktopPaneUI',
+            'DGC', 'Dialog', 'Dictionary', 'DigestException',
+            'DigestInputStream', 'DigestOutputStream',
+            'Dimension', 'Dimension2D', 'DimensionUIResource',
+            'DirContext', 'DirectColorModel', 'DirectoryManager',
+            'DirObjectFactory', 'DirStateFactory',
+            'DirStateFactory.Result', 'DnDConstants', 'Document',
+            'DocumentEvent', 'DocumentEvent.ElementChange',
+            'DocumentEvent.EventType', 'DocumentListener',
+            'DocumentParser', 'DomainCombiner', 'DomainManager',
+            'DomainManagerOperations', 'Double', 'DoubleHolder',
+            'DoubleSeqHelper', 'DoubleSeqHolder',
+            'DragGestureEvent', 'DragGestureListener',
+            'DragGestureRecognizer', 'DragSource',
+            'DragSourceContext', 'DragSourceDragEvent',
+            'DragSourceDropEvent', 'DragSourceEvent',
+            'DragSourceListener', 'Driver', 'DriverManager',
+            'DriverPropertyInfo', 'DropTarget',
+            'DropTarget.DropTargetAutoScroller',
+            'DropTargetContext', 'DropTargetDragEvent',
+            'DropTargetDropEvent', 'DropTargetEvent',
+            'DropTargetListener', 'DSAKey',
+            'DSAKeyPairGenerator', 'DSAParameterSpec',
+            'DSAParams', 'DSAPrivateKey', 'DSAPrivateKeySpec',
+            'DSAPublicKey', 'DSAPublicKeySpec', 'DTD',
+            'DTDConstants', 'DynamicImplementation', 'DynAny',
+            'DynArray', 'DynEnum', 'DynFixed', 'DynSequence',
+            'DynStruct', 'DynUnion', 'DynValue', 'EditorKit',
+            'Element', 'ElementIterator', 'Ellipse2D',
+            'Ellipse2D.Double', 'Ellipse2D.Float', 'EmptyBorder',
+            'EmptyStackException', 'EncodedKeySpec', 'Entity',
+            'EnumControl', 'EnumControl.Type', 'Enumeration',
+            'Environment', 'EOFException', 'Error',
+            'EtchedBorder', 'Event', 'EventContext',
+            'EventDirContext', 'EventListener',
+            'EventListenerList', 'EventObject', 'EventQueue',
+            'EventSetDescriptor', 'Exception',
+            'ExceptionInInitializerError', 'ExceptionList',
+            'ExpandVetoException', 'ExportException',
+            'ExtendedRequest', 'ExtendedResponse',
+            'Externalizable', 'FeatureDescriptor', 'Field',
+            'FieldNameHelper', 'FieldPosition', 'FieldView',
+            'File', 'FileChooserUI', 'FileDescriptor',
+            'FileDialog', 'FileFilter',
+            'FileInputStream', 'FilenameFilter', 'FileNameMap',
+            'FileNotFoundException', 'FileOutputStream',
+            'FilePermission', 'FileReader', 'FileSystemView',
+            'FileView', 'FileWriter', 'FilteredImageSource',
+            'FilterInputStream', 'FilterOutputStream',
+            'FilterReader', 'FilterWriter',
+            'FixedHeightLayoutCache', 'FixedHolder',
+            'FlatteningPathIterator', 'FlavorMap', 'Float',
+            'FloatControl', 'FloatControl.Type', 'FloatHolder',
+            'FloatSeqHelper', 'FloatSeqHolder', 'FlowLayout',
+            'FlowView', 'FlowView.FlowStrategy', 'FocusAdapter',
+            'FocusEvent', 'FocusListener', 'FocusManager',
+            'Font', 'FontFormatException', 'FontMetrics',
+            'FontRenderContext', 'FontUIResource', 'Format',
+            'FormatConversionProvider', 'FormView', 'Frame',
+            'FREE_MEM', 'GapContent', 'GeneralPath',
+            'GeneralSecurityException', 'GlyphJustificationInfo',
+            'GlyphMetrics', 'GlyphVector', 'GlyphView',
+            'GlyphView.GlyphPainter', 'GradientPaint',
+            'GraphicAttribute', 'Graphics', 'Graphics2D',
+            'GraphicsConfigTemplate', 'GraphicsConfiguration',
+            'GraphicsDevice', 'GraphicsEnvironment',
+            'GrayFilter', 'GregorianCalendar',
+            'GridBagConstraints', 'GridBagLayout', 'GridLayout',
+            'Group', 'Guard', 'GuardedObject', 'GZIPInputStream',
+            'GZIPOutputStream', 'HasControls', 'HashMap',
+            'HashSet', 'Hashtable', 'HierarchyBoundsAdapter',
+            'HierarchyBoundsListener', 'HierarchyEvent',
+            'HierarchyListener', 'Highlighter',
+            'Highlighter.Highlight',
+            'Highlighter.HighlightPainter', 'HTML',
+            'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag',
+            'HTMLDocument', 'HTMLDocument.Iterator',
+            'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory',
+            'HTMLEditorKit.HTMLTextAction',
+            'HTMLEditorKit.InsertHTMLTextAction',
+            'HTMLEditorKit.LinkController',
+            'HTMLEditorKit.Parser',
+            'HTMLEditorKit.ParserCallback',
+            'HTMLFrameHyperlinkEvent', 'HTMLWriter',
+            'HttpURLConnection', 'HyperlinkEvent',
+            'HyperlinkEvent.EventType', 'HyperlinkListener',
+            'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray',
+            'ICC_ProfileRGB', 'Icon', 'IconUIResource',
+            'IconView', 'IdentifierHelper', 'Identity',
+            'IdentityScope', 'IDLEntity', 'IDLType',
+            'IDLTypeHelper', 'IDLTypeOperations',
+            'IllegalAccessError', 'IllegalAccessException',
+            'IllegalArgumentException',
+            'IllegalComponentStateException',
+            'IllegalMonitorStateException',
+            'IllegalPathStateException', 'IllegalStateException',
+            'IllegalThreadStateException', 'Image',
+            'ImageConsumer', 'ImageFilter',
+            'ImageGraphicAttribute', 'ImageIcon',
+            'ImageObserver', 'ImageProducer',
+            'ImagingOpException', 'IMP_LIMIT',
+            'IncompatibleClassChangeError',
+            'InconsistentTypeCode', 'IndexColorModel',
+            'IndexedPropertyDescriptor',
+            'IndexOutOfBoundsException', 'IndirectionException',
+            'InetAddress', 'Inflater', 'InflaterInputStream',
+            'InheritableThreadLocal', 'InitialContext',
+            'InitialContextFactory',
+            'InitialContextFactoryBuilder', 'InitialDirContext',
+            'INITIALIZE', 'Initializer', 'InitialLdapContext',
+            'InlineView', 'InputContext', 'InputEvent',
+            'InputMap', 'InputMapUIResource', 'InputMethod',
+            'InputMethodContext', 'InputMethodDescriptor',
+            'InputMethodEvent', 'InputMethodHighlight',
+            'InputMethodListener', 'InputMethodRequests',
+            'InputStream',
+            'InputStreamReader', 'InputSubset', 'InputVerifier',
+            'Insets', 'InsetsUIResource', 'InstantiationError',
+            'InstantiationException', 'Instrument',
+            'InsufficientResourcesException', 'Integer',
+            'INTERNAL', 'InternalError', 'InternalFrameAdapter',
+            'InternalFrameEvent', 'InternalFrameListener',
+            'InternalFrameUI', 'InterruptedException',
+            'InterruptedIOException',
+            'InterruptedNamingException', 'INTF_REPOS',
+            'IntHolder', 'IntrospectionException',
+            'Introspector', 'Invalid',
+            'InvalidAlgorithmParameterException',
+            'InvalidAttributeIdentifierException',
+            'InvalidAttributesException',
+            'InvalidAttributeValueException',
+            'InvalidClassException',
+            'InvalidDnDOperationException',
+            'InvalidKeyException', 'InvalidKeySpecException',
+            'InvalidMidiDataException', 'InvalidName',
+            'InvalidNameException',
+            'InvalidNameHelper', 'InvalidNameHolder',
+            'InvalidObjectException',
+            'InvalidParameterException',
+            'InvalidParameterSpecException',
+            'InvalidSearchControlsException',
+            'InvalidSearchFilterException', 'InvalidSeq',
+            'InvalidTransactionException', 'InvalidValue',
+            'INVALID_TRANSACTION', 'InvocationEvent',
+            'InvocationHandler', 'InvocationTargetException',
+            'InvokeHandler', 'INV_FLAG', 'INV_IDENT',
+            'INV_OBJREF', 'INV_POLICY', 'IOException',
+            'IRObject', 'IRObjectOperations', 'IstringHelper',
+            'ItemEvent', 'ItemListener', 'ItemSelectable',
+            'Iterator', 'JApplet', 'JarEntry', 'JarException',
+            'JarFile', 'JarInputStream', 'JarOutputStream',
+            'JarURLConnection', 'JButton', 'JCheckBox',
+            'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox',
+            'JComboBox.KeySelectionManager', 'JComponent',
+            'JDesktopPane', 'JDialog', 'JEditorPane',
+            'JFileChooser', 'JFrame', 'JInternalFrame',
+            'JInternalFrame.JDesktopIcon', 'JLabel',
+            'JLayeredPane', 'JList', 'JMenu', 'JMenuBar',
+            'JMenuItem', 'JobAttributes',
+            'JobAttributes.DefaultSelectionType',
+            'JobAttributes.DestinationType',
+            'JobAttributes.DialogType',
+            'JobAttributes.MultipleDocumentHandlingType',
+            'JobAttributes.SidesType', 'JOptionPane', 'JPanel',
+            'JPasswordField', 'JPopupMenu',
+            'JPopupMenu.Separator', 'JProgressBar',
+            'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane',
+            'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider',
+            'JSplitPane', 'JTabbedPane', 'JTable',
+            'JTableHeader', 'JTextArea', 'JTextComponent',
+            'JTextComponent.KeyBinding', 'JTextField',
+            'JTextPane', 'JToggleButton',
+            'JToggleButton.ToggleButtonModel', 'JToolBar',
+            'JToolBar.Separator', 'JToolTip', 'JTree',
+            'JTree.DynamicUtilTreeNode',
+            'JTree.EmptySelectionModel', 'JViewport', 'JWindow',
+            'Kernel', 'Key', 'KeyAdapter', 'KeyEvent',
+            'KeyException', 'KeyFactory', 'KeyFactorySpi',
+            'KeyListener', 'KeyManagementException', 'Keymap',
+            'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi',
+            'KeySpec', 'KeyStore', 'KeyStoreException',
+            'KeyStoreSpi', 'KeyStroke', 'Label', 'LabelUI',
+            'LabelView', 'LastOwnerException',
+            'LayeredHighlighter',
+            'LayeredHighlighter.LayerPainter', 'LayoutManager',
+            'LayoutManager2', 'LayoutQueue', 'LdapContext',
+            'LdapReferralException', 'Lease',
+            'LimitExceededException', 'Line', 'Line.Info',
+            'Line2D', 'Line2D.Double', 'Line2D.Float',
+            'LineBorder', 'LineBreakMeasurer', 'LineEvent',
+            'LineEvent.Type', 'LineListener', 'LineMetrics',
+            'LineNumberInputStream', 'LineNumberReader',
+            'LineUnavailableException', 'LinkageError',
+            'LinkedList', 'LinkException', 'LinkLoopException',
+            'LinkRef', 'List', 'ListCellRenderer',
+            'ListDataEvent', 'ListDataListener', 'ListIterator',
+            'ListModel', 'ListResourceBundle',
+            'ListSelectionEvent', 'ListSelectionListener',
+            'ListSelectionModel', 'ListUI', 'ListView',
+            'LoaderHandler', 'Locale', 'LocateRegistry',
+            'LogStream', 'Long', 'LongHolder',
+            'LongLongSeqHelper', 'LongLongSeqHolder',
+            'LongSeqHelper', 'LongSeqHolder', 'LookAndFeel',
+            'LookupOp', 'LookupTable', 'MalformedLinkException',
+            'MalformedURLException', 'Manifest', 'Map',
+            'Map.Entry', 'MARSHAL', 'MarshalException',
+            'MarshalledObject', 'Math', 'MatteBorder',
+            'MediaTracker', 'Member', 'MemoryImageSource',
+            'Menu', 'MenuBar', 'MenuBarUI', 'MenuComponent',
+            'MenuContainer', 'MenuDragMouseEvent',
+            'MenuDragMouseListener', 'MenuElement', 'MenuEvent',
+            'MenuItem', 'MenuItemUI', 'MenuKeyEvent',
+            'MenuKeyListener', 'MenuListener',
+            'MenuSelectionManager', 'MenuShortcut',
+            'MessageDigest', 'MessageDigestSpi', 'MessageFormat',
+            'MetaEventListener', 'MetalBorders',
+            'MetalBorders.ButtonBorder',
+            'MetalBorders.Flush3DBorder',
+            'MetalBorders.InternalFrameBorder',
+            'MetalBorders.MenuBarBorder',
+            'MetalBorders.MenuItemBorder',
+            'MetalBorders.OptionDialogBorder',
+            'MetalBorders.PaletteBorder',
+            'MetalBorders.PopupMenuBorder',
+            'MetalBorders.RolloverButtonBorder',
+            'MetalBorders.ScrollPaneBorder',
+            'MetalBorders.TableHeaderBorder',
+            'MetalBorders.TextFieldBorder',
+            'MetalBorders.ToggleButtonBorder',
+            'MetalBorders.ToolBarBorder', 'MetalButtonUI',
+            'MetalCheckBoxIcon', 'MetalCheckBoxUI',
+            'MetalComboBoxButton', 'MetalComboBoxEditor',
+            'MetalComboBoxEditor.UIResource',
+            'MetalComboBoxIcon', 'MetalComboBoxUI',
+            'MetalDesktopIconUI', 'MetalFileChooserUI',
+            'MetalIconFactory', 'MetalIconFactory.FileIcon16',
+            'MetalIconFactory.FolderIcon16',
+            'MetalIconFactory.PaletteCloseIcon',
+            'MetalIconFactory.TreeControlIcon',
+            'MetalIconFactory.TreeFolderIcon',
+            'MetalIconFactory.TreeLeafIcon',
+            'MetalInternalFrameTitlePane',
+            'MetalInternalFrameUI', 'MetalLabelUI',
+            'MetalLookAndFeel', 'MetalPopupMenuSeparatorUI',
+            'MetalProgressBarUI', 'MetalRadioButtonUI',
+            'MetalScrollBarUI', 'MetalScrollButton',
+            'MetalScrollPaneUI', 'MetalSeparatorUI',
+            'MetalSliderUI', 'MetalSplitPaneUI',
+            'MetalTabbedPaneUI', 'MetalTextFieldUI',
+            'MetalTheme', 'MetalToggleButtonUI',
+            'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI',
+            'MetaMessage', 'Method', 'MethodDescriptor',
+            'MidiChannel', 'MidiDevice', 'MidiDevice.Info',
+            'MidiDeviceProvider', 'MidiEvent', 'MidiFileFormat',
+            'MidiFileReader', 'MidiFileWriter', 'MidiMessage',
+            'MidiSystem', 'MidiUnavailableException',
+            'MimeTypeParseException', 'MinimalHTMLWriter',
+            'MissingResourceException', 'Mixer', 'Mixer.Info',
+            'MixerProvider', 'ModificationItem', 'Modifier',
+            'MouseAdapter', 'MouseDragGestureRecognizer',
+            'MouseEvent', 'MouseInputAdapter',
+            'MouseInputListener', 'MouseListener',
+            'MouseMotionAdapter', 'MouseMotionListener',
+            'MultiButtonUI', 'MulticastSocket',
+            'MultiColorChooserUI', 'MultiComboBoxUI',
+            'MultiDesktopIconUI', 'MultiDesktopPaneUI',
+            'MultiFileChooserUI', 'MultiInternalFrameUI',
+            'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel',
+            'MultiMenuBarUI', 'MultiMenuItemUI',
+            'MultiOptionPaneUI', 'MultiPanelUI',
+            'MultiPixelPackedSampleModel', 'MultipleMaster',
+            'MultiPopupMenuUI', 'MultiProgressBarUI',
+            'MultiScrollBarUI', 'MultiScrollPaneUI',
+            'MultiSeparatorUI', 'MultiSliderUI',
+            'MultiSplitPaneUI', 'MultiTabbedPaneUI',
+            'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI',
+            'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI',
+            'MultiViewportUI', 'MutableAttributeSet',
+            'MutableComboBoxModel', 'MutableTreeNode', 'Name',
+            'NameAlreadyBoundException', 'NameClassPair',
+            'NameComponent', 'NameComponentHelper',
+            'NameComponentHolder', 'NamedValue', 'NameHelper',
+            'NameHolder', 'NameNotFoundException', 'NameParser',
+            'NamespaceChangeListener', 'NameValuePair',
+            'NameValuePairHelper', 'Naming', 'NamingContext',
+            'NamingContextHelper', 'NamingContextHolder',
+            'NamingContextOperations', 'NamingEnumeration',
+            'NamingEvent', 'NamingException',
+            'NamingExceptionEvent', 'NamingListener',
+            'NamingManager', 'NamingSecurityException',
+            'NegativeArraySizeException', 'NetPermission',
+            'NoClassDefFoundError', 'NoInitialContextException',
+            'NoninvertibleTransformException',
+            'NoPermissionException', 'NoRouteToHostException',
+            'NoSuchAlgorithmException',
+            'NoSuchAttributeException', 'NoSuchElementException',
+            'NoSuchFieldError', 'NoSuchFieldException',
+            'NoSuchMethodError', 'NoSuchMethodException',
+            'NoSuchObjectException', 'NoSuchProviderException',
+            'NotActiveException', 'NotBoundException',
+            'NotContextException', 'NotEmpty', 'NotEmptyHelper',
+            'NotEmptyHolder', 'NotFound', 'NotFoundHelper',
+            'NotFoundHolder', 'NotFoundReason',
+            'NotFoundReasonHelper', 'NotFoundReasonHolder',
+            'NotOwnerException', 'NotSerializableException',
+            'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION',
+            'NO_RESOURCES', 'NO_RESPONSE',
+            'NullPointerException', 'Number', 'NumberFormat',
+            'NumberFormatException', 'NVList', 'Object',
+            'ObjectChangeListener', 'ObjectFactory',
+            'ObjectFactoryBuilder', 'ObjectHelper',
+            'ObjectHolder', 'ObjectImpl',
+            'ObjectInput', 'ObjectInputStream',
+            'ObjectInputStream.GetField',
+            'ObjectInputValidation', 'ObjectOutput',
+            'ObjectOutputStream', 'ObjectOutputStream.PutField',
+            'ObjectStreamClass', 'ObjectStreamConstants',
+            'ObjectStreamException', 'ObjectStreamField',
+            'ObjectView', 'OBJECT_NOT_EXIST', 'ObjID',
+            'OBJ_ADAPTER', 'Observable', 'Observer',
+            'OctetSeqHelper', 'OctetSeqHolder', 'OMGVMCID',
+            'OpenType', 'Operation',
+            'OperationNotSupportedException', 'Option',
+            'OptionalDataException', 'OptionPaneUI', 'ORB',
+            'OutOfMemoryError', 'OutputStream',
+            'OutputStreamWriter', 'OverlayLayout', 'Owner',
+            'Package', 'PackedColorModel', 'Pageable',
+            'PageAttributes', 'PageAttributes.ColorType',
+            'PageAttributes.MediaType',
+            'PageAttributes.OrientationRequestedType',
+            'PageAttributes.OriginType',
+            'PageAttributes.PrintQualityType', 'PageFormat',
+            'Paint', 'PaintContext', 'PaintEvent', 'Panel',
+            'PanelUI', 'Paper', 'ParagraphView',
+            'ParameterBlock', 'ParameterDescriptor',
+            'ParseException', 'ParsePosition', 'Parser',
+            'ParserDelegator', 'PartialResultException',
+            'PasswordAuthentication', 'PasswordView', 'Patch',
+            'PathIterator', 'Permission',
+            'PermissionCollection', 'Permissions',
+            'PERSIST_STORE', 'PhantomReference',
+            'PipedInputStream', 'PipedOutputStream',
+            'PipedReader', 'PipedWriter', 'PixelGrabber',
+            'PixelInterleavedSampleModel', 'PKCS8EncodedKeySpec',
+            'PlainDocument', 'PlainView', 'Point', 'Point2D',
+            'Point2D.Double', 'Point2D.Float', 'Policy',
+            'PolicyError', 'PolicyHelper',
+            'PolicyHolder', 'PolicyListHelper',
+            'PolicyListHolder', 'PolicyOperations',
+            'PolicyTypeHelper', 'Polygon', 'PopupMenu',
+            'PopupMenuEvent', 'PopupMenuListener', 'PopupMenuUI',
+            'Port', 'Port.Info', 'PortableRemoteObject',
+            'PortableRemoteObjectDelegate', 'Position',
+            'Position.Bias', 'PreparedStatement', 'Principal',
+            'PrincipalHolder', 'Printable',
+            'PrinterAbortException', 'PrinterException',
+            'PrinterGraphics', 'PrinterIOException',
+            'PrinterJob', 'PrintGraphics', 'PrintJob',
+            'PrintStream', 'PrintWriter', 'PrivateKey',
+            'PRIVATE_MEMBER', 'PrivilegedAction',
+            'PrivilegedActionException',
+            'PrivilegedExceptionAction', 'Process',
+            'ProfileDataException', 'ProgressBarUI',
+            'ProgressMonitor', 'ProgressMonitorInputStream',
+            'Properties', 'PropertyChangeEvent',
+            'PropertyChangeListener', 'PropertyChangeSupport',
+            'PropertyDescriptor', 'PropertyEditor',
+            'PropertyEditorManager', 'PropertyEditorSupport',
+            'PropertyPermission', 'PropertyResourceBundle',
+            'PropertyVetoException', 'ProtectionDomain',
+            'ProtocolException', 'Provider', 'ProviderException',
+            'Proxy', 'PublicKey', 'PUBLIC_MEMBER',
+            'PushbackInputStream', 'PushbackReader',
+            'QuadCurve2D', 'QuadCurve2D.Double',
+            'QuadCurve2D.Float', 'Random', 'RandomAccessFile',
+            'Raster', 'RasterFormatException', 'RasterOp',
+            'Reader', 'Receiver', 'Rectangle', 'Rectangle2D',
+            'Rectangle2D.Double', 'Rectangle2D.Float',
+            'RectangularShape', 'Ref', 'RefAddr', 'Reference',
+            'Referenceable', 'ReferenceQueue',
+            'ReferralException', 'ReflectPermission', 'Registry',
+            'RegistryHandler', 'RemarshalException', 'Remote',
+            'RemoteCall', 'RemoteException', 'RemoteObject',
+            'RemoteRef', 'RemoteServer', 'RemoteStub',
+            'RenderableImage', 'RenderableImageOp',
+            'RenderableImageProducer', 'RenderContext',
+            'RenderedImage', 'RenderedImageFactory', 'Renderer',
+            'RenderingHints', 'RenderingHints.Key',
+            'RepaintManager', 'ReplicateScaleFilter',
+            'Repository', 'RepositoryIdHelper', 'Request',
+            'RescaleOp', 'Resolver', 'ResolveResult',
+            'ResourceBundle', 'ResponseHandler', 'ResultSet',
+            'ResultSetMetaData', 'ReverbType', 'RGBImageFilter',
+            'RMIClassLoader', 'RMIClientSocketFactory',
+            'RMIFailureHandler', 'RMISecurityException',
+            'RMISecurityManager', 'RMIServerSocketFactory',
+            'RMISocketFactory', 'Robot', 'RootPaneContainer',
+            'RootPaneUI', 'RoundRectangle2D',
+            'RoundRectangle2D.Double', 'RoundRectangle2D.Float',
+            'RowMapper', 'RSAKey', 'RSAKeyGenParameterSpec',
+            'RSAPrivateCrtKey', 'RSAPrivateCrtKeySpec',
+            'RSAPrivateKey', 'RSAPrivateKeySpec', 'RSAPublicKey',
+            'RSAPublicKeySpec', 'RTFEditorKit',
+            'RuleBasedCollator', 'Runnable', 'RunTime',
+            'Runtime', 'RuntimeException', 'RunTimeOperations',
+            'RuntimePermission', 'SampleModel',
+            'SchemaViolationException', 'Scrollable',
+            'Scrollbar', 'ScrollBarUI', 'ScrollPane',
+            'ScrollPaneConstants', 'ScrollPaneLayout',
+            'ScrollPaneLayout.UIResource', 'ScrollPaneUI',
+            'SearchControls', 'SearchResult',
+            'SecureClassLoader', 'SecureRandom',
+            'SecureRandomSpi', 'Security', 'SecurityException',
+            'SecurityManager', 'SecurityPermission', 'Segment',
+            'SeparatorUI', 'Sequence', 'SequenceInputStream',
+            'Sequencer', 'Sequencer.SyncMode', 'Serializable',
+            'SerializablePermission', 'ServantObject',
+            'ServerCloneException', 'ServerError',
+            'ServerException', 'ServerNotActiveException',
+            'ServerRef', 'ServerRequest',
+            'ServerRuntimeException', 'ServerSocket',
+            'ServiceDetail', 'ServiceDetailHelper',
+            'ServiceInformation', 'ServiceInformationHelper',
+            'ServiceInformationHolder',
+            'ServiceUnavailableException', 'Set',
+            'SetOverrideType', 'SetOverrideTypeHelper', 'Shape',
+            'ShapeGraphicAttribute', 'Short', 'ShortHolder',
+            'ShortLookupTable', 'ShortMessage', 'ShortSeqHelper',
+            'ShortSeqHolder', 'Signature', 'SignatureException',
+            'SignatureSpi', 'SignedObject', 'Signer',
+            'SimpleAttributeSet', 'SimpleBeanInfo',
+            'SimpleDateFormat', 'SimpleTimeZone',
+            'SinglePixelPackedSampleModel',
+            'SingleSelectionModel', 'SizeLimitExceededException',
+            'SizeRequirements', 'SizeSequence', 'Skeleton',
+            'SkeletonMismatchException',
+            'SkeletonNotFoundException', 'SliderUI', 'Socket',
+            'SocketException', 'SocketImpl', 'SocketImplFactory',
+            'SocketOptions', 'SocketPermission',
+            'SocketSecurityException', 'SoftBevelBorder',
+            'SoftReference', 'SortedMap', 'SortedSet',
+            'Soundbank', 'SoundbankReader', 'SoundbankResource',
+            'SourceDataLine', 'SplitPaneUI', 'SQLData',
+            'SQLException', 'SQLInput', 'SQLOutput',
+            'SQLPermission', 'SQLWarning', 'Stack',
+            'StackOverflowError', 'StateEdit', 'StateEditable',
+            'StateFactory', 'Statement', 'Streamable',
+            'StreamableValue', 'StreamCorruptedException',
+            'StreamTokenizer', 'StrictMath', 'String',
+            'StringBuffer', 'StringBufferInputStream',
+            'StringCharacterIterator', 'StringContent',
+            'StringHolder', 'StringIndexOutOfBoundsException',
+            'StringReader', 'StringRefAddr', 'StringSelection',
+            'StringTokenizer', 'StringValueHelper',
+            'StringWriter', 'Stroke', 'Struct', 'StructMember',
+            'StructMemberHelper', 'Stub', 'StubDelegate',
+            'StubNotFoundException', 'Style', 'StyleConstants',
+            'StyleConstants.CharacterConstants',
+            'StyleConstants.ColorConstants',
+            'StyleConstants.FontConstants',
+            'StyleConstants.ParagraphConstants', 'StyleContext',
+            'StyledDocument', 'StyledEditorKit',
+            'StyledEditorKit.AlignmentAction',
+            'StyledEditorKit.BoldAction',
+            'StyledEditorKit.FontFamilyAction',
+            'StyledEditorKit.FontSizeAction',
+            'StyledEditorKit.ForegroundAction',
+            'StyledEditorKit.ItalicAction',
+            'StyledEditorKit.StyledTextAction',
+            'StyledEditorKit.UnderlineAction', 'StyleSheet',
+            'StyleSheet.BoxPainter', 'StyleSheet.ListPainter',
+            'SwingConstants', 'SwingPropertyChangeSupport',
+            'SwingUtilities', 'SyncFailedException',
+            'Synthesizer', 'SysexMessage', 'System',
+            'SystemColor', 'SystemException', 'SystemFlavorMap',
+            'TabableView', 'TabbedPaneUI', 'TabExpander',
+            'TableCellEditor', 'TableCellRenderer',
+            'TableColumn', 'TableColumnModel',
+            'TableColumnModelEvent', 'TableColumnModelListener',
+            'TableHeaderUI', 'TableModel', 'TableModelEvent',
+            'TableModelListener', 'TableUI', 'TableView',
+            'TabSet', 'TabStop', 'TagElement', 'TargetDataLine',
+            'TCKind', 'TextAction', 'TextArea', 'TextAttribute',
+            'TextComponent', 'TextEvent', 'TextField',
+            'TextHitInfo', 'TextLayout',
+            'TextLayout.CaretPolicy', 'TextListener',
+            'TextMeasurer', 'TextUI', 'TexturePaint', 'Thread',
+            'ThreadDeath', 'ThreadGroup', 'ThreadLocal',
+            'Throwable', 'Tie', 'TileObserver', 'Time',
+            'TimeLimitExceededException', 'Timer',
+            'TimerTask', 'Timestamp', 'TimeZone', 'TitledBorder',
+            'ToolBarUI', 'Toolkit', 'ToolTipManager',
+            'ToolTipUI', 'TooManyListenersException', 'Track',
+            'TransactionRequiredException',
+            'TransactionRolledbackException',
+            'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK',
+            'Transferable', 'TransformAttribute', 'TRANSIENT',
+            'Transmitter', 'Transparency', 'TreeCellEditor',
+            'TreeCellRenderer', 'TreeExpansionEvent',
+            'TreeExpansionListener', 'TreeMap', 'TreeModel',
+            'TreeModelEvent', 'TreeModelListener', 'TreeNode',
+            'TreePath', 'TreeSelectionEvent',
+            'TreeSelectionListener', 'TreeSelectionModel',
+            'TreeSet', 'TreeUI', 'TreeWillExpandListener',
+            'TypeCode', 'TypeCodeHolder', 'TypeMismatch',
+            'Types', 'UID', 'UIDefaults',
+            'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap',
+            'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue',
+            'UIManager', 'UIManager.LookAndFeelInfo',
+            'UIResource', 'ULongLongSeqHelper',
+            'ULongLongSeqHolder', 'ULongSeqHelper',
+            'ULongSeqHolder', 'UndeclaredThrowableException',
+            'UndoableEdit', 'UndoableEditEvent',
+            'UndoableEditListener', 'UndoableEditSupport',
+            'UndoManager', 'UnexpectedException',
+            'UnicastRemoteObject', 'UnionMember',
+            'UnionMemberHelper', 'UNKNOWN', 'UnknownError',
+            'UnknownException', 'UnknownGroupException',
+            'UnknownHostException',
+            'UnknownObjectException', 'UnknownServiceException',
+            'UnknownUserException', 'UnmarshalException',
+            'UnrecoverableKeyException', 'Unreferenced',
+            'UnresolvedPermission', 'UnsatisfiedLinkError',
+            'UnsolicitedNotification',
+            'UnsolicitedNotificationEvent',
+            'UnsolicitedNotificationListener',
+            'UnsupportedAudioFileException',
+            'UnsupportedClassVersionError',
+            'UnsupportedEncodingException',
+            'UnsupportedFlavorException',
+            'UnsupportedLookAndFeelException',
+            'UnsupportedOperationException',
+            'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE',
+            'URL', 'URLClassLoader', 'URLConnection',
+            'URLDecoder', 'URLEncoder', 'URLStreamHandler',
+            'URLStreamHandlerFactory', 'UserException',
+            'UShortSeqHelper', 'UShortSeqHolder',
+            'UTFDataFormatException', 'Util', 'UtilDelegate',
+            'Utilities', 'ValueBase', 'ValueBaseHelper',
+            'ValueBaseHolder', 'ValueFactory', 'ValueHandler',
+            'ValueMember', 'ValueMemberHelper',
+            'VariableHeightLayoutCache', 'Vector', 'VerifyError',
+            'VersionSpecHelper', 'VetoableChangeListener',
+            'VetoableChangeSupport', 'View', 'ViewFactory',
+            'ViewportLayout', 'ViewportUI',
+            'VirtualMachineError', 'Visibility',
+            'VisibilityHelper', 'VMID', 'VM_ABSTRACT',
+            'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE',
+            'VoiceStatus', 'Void', 'WCharSeqHelper',
+            'WCharSeqHolder', 'WeakHashMap', 'WeakReference',
+            'Window', 'WindowAdapter', 'WindowConstants',
+            'WindowEvent', 'WindowListener', 'WrappedPlainView',
+            'WritableRaster', 'WritableRenderedImage',
+            'WriteAbortedException', 'Writer',
+            'WrongTransaction', 'WStringValueHelper',
+            'X509Certificate', 'X509CRL', 'X509CRLEntry',
+            'X509EncodedKeySpec', 'X509Extension', 'ZipEntry',
+            'ZipException', 'ZipFile', 'ZipInputStream',
+            'ZipOutputStream', 'ZoneView',
+            '_BindingIteratorImplBase', '_BindingIteratorStub',
+            '_IDLTypeStub', '_NamingContextImplBase',
+            '_NamingContextStub', '_PolicyStub', '_Remote_Stub'
+            ),
+        4 => array(
+            'void', 'double', 'int', 'boolean', 'byte', 'short', 'long', 'char', 'float'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}',
+        '+', '-', '*', '/', '%',
+        '!', '&', '|', '^',
+        '<', '>', '=',
+        '?', ':', ';',
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => true,
+        4 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #000066; font-weight: bold;',
+            3 => 'color: #003399;',
+            4 => 'color: #000066; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #006699;',
+            3 => 'color: #008000; font-style: italic; font-weight: bold;',
+            3 => 'color: #008000; font-style: italic; font-weight: bold;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006633;',
+            2 => 'color: #006633;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.google.com/search?hl=en&amp;q=allinurl%3A{FNAMEL}+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/java5.php b/examples/includes/geshi/geshi/java5.php
new file mode 100644 (file)
index 0000000..1766ef9
--- /dev/null
@@ -0,0 +1,1031 @@
+<?php
+/*************************************************************************************
+ * java.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/10
+ *
+ * Java language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/25 (1.0.7.22)
+ *   -  Added highlighting of import and package directives as non-OOP
+ * 2005/12/28 (1.0.4)
+ *   -  Added instanceof keyword
+ * 2004/11/27 (1.0.3)
+ *   -  Added support for multiple object splitters
+ * 2004/08/05 (1.0.2)
+ *   -  Added URL support
+ *   -  Added keyword "this", as bugs in GeSHi class ironed out
+ * 2004/08/05 (1.0.1)
+ *   -  Added support for symbols
+ *   -  Added extra missed keywords
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Java(TM) 2 Platform Standard Edition 5.0',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Import and Package directives (Basic Support only)
+        2 => '/(?:(?<=import[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+        // javadoc comments
+        3 => '#/\*\*(?![\*\/]).*\*/#sU'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            /* see the authoritative list of all 50 Java keywords at */
+            /* http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#229308 */
+
+            /* java keywords, part 1: control flow */
+            'case', 'default', 'do', 'else', 'for',
+            'goto', 'if', 'switch', 'while'
+
+            /* IMO 'break', 'continue', 'return' and 'throw' */
+                        /* should also be added to this group, as they   */
+            /* also manage the control flow,                 */
+            /* arguably 'try'/'catch'/'finally' as well      */
+            ),
+        2 => array(
+            /* java keywords, part 2 */
+
+            'break', 'continue', 'return', 'throw',
+            'try', 'catch', 'finally',
+
+            'abstract', 'assert', 'class', 'const', 'enum', 'extends',
+            'final', 'implements', 'import', 'instanceof', 'interface',
+            'native', 'new', 'package', 'private', 'protected',
+            'public', 'static', 'strictfp', 'super', 'synchronized',
+            'this', 'throws', 'transient', 'volatile'
+            ),
+        3 => array(
+            /* Java keywords, part 3: primitive data types and 'void' */
+            'boolean', 'byte', 'char', 'double',
+            'float', 'int', 'long', 'short', 'void'
+            ),
+        4 => array(
+            /* other reserved words in Java: literals */
+            /* should be styled to look similar to numbers and Strings */
+            'false', 'null', 'true'
+            ),
+        5 => array (
+            'Applet', 'AppletContext', 'AppletStub', 'AudioClip'
+            ),
+        6 => array (
+            'AWTError', 'AWTEvent', 'AWTEventMulticaster', 'AWTException', 'AWTKeyStroke', 'AWTPermission', 'ActiveEvent', 'Adjustable', 'AlphaComposite', 'BasicStroke', 'BorderLayout', 'BufferCapabilities', 'BufferCapabilities.FlipContents', 'Button', 'Canvas', 'CardLayout', 'Checkbox', 'CheckboxGroup', 'CheckboxMenuItem', 'Choice', 'Color', 'Component', 'ComponentOrientation', 'Composite', 'CompositeContext', 'Container', 'ContainerOrderFocusTraversalPolicy', 'Cursor', 'DefaultFocusTraversalPolicy', 'DefaultKeyboardFocusManager', 'Dialog', 'Dimension', 'DisplayMode', 'EventQueue', 'FileDialog', 'FlowLayout', 'FocusTraversalPolicy', 'Font', 'FontFormatException', 'FontMetrics', 'Frame', 'GradientPaint', 'Graphics', 'Graphics2D', 'GraphicsConfigTemplate', 'GraphicsConfiguration', 'GraphicsDevice', 'GraphicsEnvironment', 'GridBagConstraints', 'GridBagLayout', 'GridLayout', 'HeadlessException', 'IllegalComponentStateException', 'Image', 'ImageCapabilities', 'Insets', 'ItemSelectable', 'JobAttributes',
+            'JobAttributes.DefaultSelectionType', 'JobAttributes.DestinationType', 'JobAttributes.DialogType', 'JobAttributes.MultipleDocumentHandlingType', 'JobAttributes.SidesType', 'KeyEventDispatcher', 'KeyEventPostProcessor', 'KeyboardFocusManager', 'Label', 'LayoutManager', 'LayoutManager2', 'MediaTracker', 'Menu', 'MenuBar', 'MenuComponent', 'MenuContainer', 'MenuItem', 'MenuShortcut', 'MouseInfo', 'PageAttributes', 'PageAttributes.ColorType', 'PageAttributes.MediaType', 'PageAttributes.OrientationRequestedType', 'PageAttributes.OriginType', 'PageAttributes.PrintQualityType', 'Paint', 'PaintContext', 'Panel', 'Point', 'PointerInfo', 'Polygon', 'PopupMenu', 'PrintGraphics', 'PrintJob', 'Rectangle', 'RenderingHints', 'RenderingHints.Key', 'Robot', 'ScrollPane', 'ScrollPaneAdjustable', 'Scrollbar', 'Shape', 'Stroke', 'SystemColor', 'TextArea', 'TextComponent', 'TextField', 'TexturePaint', 'Toolkit', 'Transparency', 'Window'
+            ),
+        7 => array (
+            'CMMException', 'ColorSpace', 'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray', 'ICC_ProfileRGB', 'ProfileDataException'
+            ),
+        8 => array (
+            'Clipboard', 'ClipboardOwner', 'DataFlavor', 'FlavorEvent', 'FlavorListener', 'FlavorMap', 'FlavorTable', 'MimeTypeParseException', 'StringSelection', 'SystemFlavorMap', 'Transferable', 'UnsupportedFlavorException'
+            ),
+        9 => array (
+            'Autoscroll', 'DnDConstants', 'DragGestureEvent', 'DragGestureListener', 'DragGestureRecognizer', 'DragSource', 'DragSourceAdapter', 'DragSourceContext', 'DragSourceDragEvent', 'DragSourceDropEvent', 'DragSourceEvent', 'DragSourceListener', 'DragSourceMotionListener', 'DropTarget', 'DropTarget.DropTargetAutoScroller', 'DropTargetAdapter', 'DropTargetContext', 'DropTargetDragEvent', 'DropTargetDropEvent', 'DropTargetEvent', 'DropTargetListener', 'InvalidDnDOperationException', 'MouseDragGestureRecognizer'
+            ),
+        10 => array (
+            'AWTEventListener', 'AWTEventListenerProxy', 'ActionEvent', 'ActionListener', 'AdjustmentEvent', 'AdjustmentListener', 'ComponentAdapter', 'ComponentEvent', 'ComponentListener', 'ContainerAdapter', 'ContainerEvent', 'ContainerListener', 'FocusAdapter', 'FocusEvent', 'FocusListener', 'HierarchyBoundsAdapter', 'HierarchyBoundsListener', 'HierarchyEvent', 'HierarchyListener', 'InputEvent', 'InputMethodEvent', 'InputMethodListener', 'InvocationEvent', 'ItemEvent', 'ItemListener', 'KeyAdapter', 'KeyEvent', 'KeyListener', 'MouseAdapter', 'MouseListener', 'MouseMotionAdapter', 'MouseMotionListener', 'MouseWheelEvent', 'MouseWheelListener', 'PaintEvent', 'TextEvent', 'TextListener', 'WindowAdapter', 'WindowEvent', 'WindowFocusListener', 'WindowListener', 'WindowStateListener'
+            ),
+        11 => array (
+            'FontRenderContext', 'GlyphJustificationInfo', 'GlyphMetrics', 'GlyphVector', 'GraphicAttribute', 'ImageGraphicAttribute', 'LineBreakMeasurer', 'LineMetrics', 'MultipleMaster', 'NumericShaper', 'ShapeGraphicAttribute', 'TextAttribute', 'TextHitInfo', 'TextLayout', 'TextLayout.CaretPolicy', 'TextMeasurer', 'TransformAttribute'
+            ),
+        12 => array (
+            'AffineTransform', 'Arc2D', 'Arc2D.Double', 'Arc2D.Float', 'Area', 'CubicCurve2D', 'CubicCurve2D.Double', 'CubicCurve2D.Float', 'Dimension2D', 'Ellipse2D', 'Ellipse2D.Double', 'Ellipse2D.Float', 'FlatteningPathIterator', 'GeneralPath', 'IllegalPathStateException', 'Line2D', 'Line2D.Double', 'Line2D.Float', 'NoninvertibleTransformException', 'PathIterator', 'Point2D', 'Point2D.Double', 'Point2D.Float', 'QuadCurve2D', 'QuadCurve2D.Double', 'QuadCurve2D.Float', 'Rectangle2D', 'Rectangle2D.Double', 'Rectangle2D.Float', 'RectangularShape', 'RoundRectangle2D', 'RoundRectangle2D.Double', 'RoundRectangle2D.Float'
+            ),
+        13 => array (
+            'InputContext', 'InputMethodHighlight', 'InputMethodRequests', 'InputSubset'
+            ),
+        14 => array (
+            'InputMethod', 'InputMethodContext', 'InputMethodDescriptor'
+            ),
+        15 => array (
+            'AffineTransformOp', 'AreaAveragingScaleFilter', 'BandCombineOp', 'BandedSampleModel', 'BufferStrategy', 'BufferedImage', 'BufferedImageFilter', 'BufferedImageOp', 'ByteLookupTable', 'ColorConvertOp', 'ColorModel', 'ComponentColorModel', 'ComponentSampleModel', 'ConvolveOp', 'CropImageFilter', 'DataBuffer', 'DataBufferByte', 'DataBufferDouble', 'DataBufferFloat', 'DataBufferInt', 'DataBufferShort', 'DataBufferUShort', 'DirectColorModel', 'FilteredImageSource', 'ImageConsumer', 'ImageFilter', 'ImageObserver', 'ImageProducer', 'ImagingOpException', 'IndexColorModel', 'Kernel', 'LookupOp', 'LookupTable', 'MemoryImageSource', 'MultiPixelPackedSampleModel', 'PackedColorModel', 'PixelGrabber', 'PixelInterleavedSampleModel', 'RGBImageFilter', 'Raster', 'RasterFormatException', 'RasterOp', 'RenderedImage', 'ReplicateScaleFilter', 'RescaleOp', 'SampleModel', 'ShortLookupTable', 'SinglePixelPackedSampleModel', 'TileObserver', 'VolatileImage', 'WritableRaster', 'WritableRenderedImage'
+            ),
+        16 => array (
+            'ContextualRenderedImageFactory', 'ParameterBlock', 'RenderContext', 'RenderableImage', 'RenderableImageOp', 'RenderableImageProducer', 'RenderedImageFactory'
+            ),
+        17 => array (
+            'Book', 'PageFormat', 'Pageable', 'Paper', 'Printable', 'PrinterAbortException', 'PrinterException', 'PrinterGraphics', 'PrinterIOException', 'PrinterJob'
+            ),
+        18 => array (
+            'AppletInitializer', 'BeanDescriptor', 'BeanInfo', 'Beans', 'Customizer', 'DefaultPersistenceDelegate', 'DesignMode', 'Encoder', 'EventHandler', 'EventSetDescriptor', 'ExceptionListener', 'Expression', 'FeatureDescriptor', 'IndexedPropertyChangeEvent', 'IndexedPropertyDescriptor', 'Introspector', 'MethodDescriptor', 'ParameterDescriptor', 'PersistenceDelegate', 'PropertyChangeEvent', 'PropertyChangeListener', 'PropertyChangeListenerProxy', 'PropertyChangeSupport', 'PropertyDescriptor', 'PropertyEditor', 'PropertyEditorManager', 'PropertyEditorSupport', 'PropertyVetoException', 'SimpleBeanInfo', 'VetoableChangeListener', 'VetoableChangeListenerProxy', 'VetoableChangeSupport', 'Visibility', 'XMLDecoder', 'XMLEncoder'
+            ),
+        19 => array (
+            'BeanContext', 'BeanContextChild', 'BeanContextChildComponentProxy', 'BeanContextChildSupport', 'BeanContextContainerProxy', 'BeanContextEvent', 'BeanContextMembershipEvent', 'BeanContextMembershipListener', 'BeanContextProxy', 'BeanContextServiceAvailableEvent', 'BeanContextServiceProvider', 'BeanContextServiceProviderBeanInfo', 'BeanContextServiceRevokedEvent', 'BeanContextServiceRevokedListener', 'BeanContextServices', 'BeanContextServicesListener', 'BeanContextServicesSupport', 'BeanContextServicesSupport.BCSSServiceProvider', 'BeanContextSupport', 'BeanContextSupport.BCSIterator'
+            ),
+        20 => array (
+            'BufferedInputStream', 'BufferedOutputStream', 'BufferedReader', 'BufferedWriter', 'ByteArrayInputStream', 'ByteArrayOutputStream', 'CharArrayReader', 'CharArrayWriter', 'CharConversionException', 'Closeable', 'DataInput', 'DataOutput', 'EOFException', 'Externalizable', 'File', 'FileDescriptor', 'FileInputStream', 'FileNotFoundException', 'FileOutputStream', 'FilePermission', 'FileReader', 'FileWriter', 'FilenameFilter', 'FilterInputStream', 'FilterOutputStream', 'FilterReader', 'FilterWriter', 'Flushable', 'IOException', 'InputStreamReader', 'InterruptedIOException', 'InvalidClassException', 'InvalidObjectException', 'LineNumberInputStream', 'LineNumberReader', 'NotActiveException', 'NotSerializableException', 'ObjectInput', 'ObjectInputStream', 'ObjectInputStream.GetField', 'ObjectInputValidation', 'ObjectOutput', 'ObjectOutputStream', 'ObjectOutputStream.PutField', 'ObjectStreamClass', 'ObjectStreamConstants', 'ObjectStreamException', 'ObjectStreamField', 'OptionalDataException', 'OutputStreamWriter',
+            'PipedInputStream', 'PipedOutputStream', 'PipedReader', 'PipedWriter', 'PrintStream', 'PrintWriter', 'PushbackInputStream', 'PushbackReader', 'RandomAccessFile', 'Reader', 'SequenceInputStream', 'Serializable', 'SerializablePermission', 'StreamCorruptedException', 'StreamTokenizer', 'StringBufferInputStream', 'StringReader', 'StringWriter', 'SyncFailedException', 'UTFDataFormatException', 'UnsupportedEncodingException', 'WriteAbortedException', 'Writer'
+            ),
+        21 => array (
+            'AbstractMethodError', 'Appendable', 'ArithmeticException', 'ArrayIndexOutOfBoundsException', 'ArrayStoreException', 'AssertionError', 'Boolean', 'Byte', 'CharSequence', 'Character', 'Character.Subset', 'Character.UnicodeBlock', 'Class', 'ClassCastException', 'ClassCircularityError', 'ClassFormatError', 'ClassLoader', 'ClassNotFoundException', 'CloneNotSupportedException', 'Cloneable', 'Comparable', 'Compiler', 'Deprecated', 'Double', 'Enum', 'EnumConstantNotPresentException', 'Error', 'Exception', 'ExceptionInInitializerError', 'Float', 'IllegalAccessError', 'IllegalAccessException', 'IllegalArgumentException', 'IllegalMonitorStateException', 'IllegalStateException', 'IllegalThreadStateException', 'IncompatibleClassChangeError', 'IndexOutOfBoundsException', 'InheritableThreadLocal', 'InstantiationError', 'InstantiationException', 'Integer', 'InternalError', 'InterruptedException', 'Iterable', 'LinkageError', 'Long', 'Math', 'NegativeArraySizeException', 'NoClassDefFoundError', 'NoSuchFieldError',
+            'NoSuchFieldException', 'NoSuchMethodError', 'NoSuchMethodException', 'NullPointerException', 'Number', 'NumberFormatException', 'OutOfMemoryError', 'Override', 'Package', 'Process', 'ProcessBuilder', 'Readable', 'Runnable', 'Runtime', 'RuntimeException', 'RuntimePermission', 'SecurityException', 'SecurityManager', 'Short', 'StackOverflowError', 'StackTraceElement', 'StrictMath', 'String', 'StringBuffer', 'StringBuilder', 'StringIndexOutOfBoundsException', 'SuppressWarnings', 'System', 'Thread', 'Thread.State', 'Thread.UncaughtExceptionHandler', 'ThreadDeath', 'ThreadGroup', 'ThreadLocal', 'Throwable', 'TypeNotPresentException', 'UnknownError', 'UnsatisfiedLinkError', 'UnsupportedClassVersionError', 'UnsupportedOperationException', 'VerifyError', 'VirtualMachineError', 'Void'
+            ),
+        22 => array (
+            'AnnotationFormatError', 'AnnotationTypeMismatchException', 'Documented', 'ElementType', 'IncompleteAnnotationException', 'Inherited', 'Retention', 'RetentionPolicy', 'Target'
+            ),
+        23 => array (
+            'ClassDefinition', 'ClassFileTransformer', 'IllegalClassFormatException', 'Instrumentation', 'UnmodifiableClassException'
+            ),
+        24 => array (
+            'ClassLoadingMXBean', 'CompilationMXBean', 'GarbageCollectorMXBean', 'ManagementFactory', 'ManagementPermission', 'MemoryMXBean', 'MemoryManagerMXBean', 'MemoryNotificationInfo', 'MemoryPoolMXBean', 'MemoryType', 'MemoryUsage', 'OperatingSystemMXBean', 'RuntimeMXBean', 'ThreadInfo', 'ThreadMXBean'
+            ),
+        25 => array (
+            'PhantomReference', 'ReferenceQueue', 'SoftReference', 'WeakReference'
+            ),
+        26 => array (
+            'AccessibleObject', 'AnnotatedElement', 'Constructor', 'Field', 'GenericArrayType', 'GenericDeclaration', 'GenericSignatureFormatError', 'InvocationHandler', 'InvocationTargetException', 'MalformedParameterizedTypeException', 'Member', 'Method', 'Modifier', 'ParameterizedType', 'ReflectPermission', 'Type', 'TypeVariable', 'UndeclaredThrowableException', 'WildcardType'
+            ),
+        27 => array (
+            'BigDecimal', 'BigInteger', 'MathContext', 'RoundingMode'
+            ),
+        28 => array (
+            'Authenticator', 'Authenticator.RequestorType', 'BindException', 'CacheRequest', 'CacheResponse', 'ContentHandlerFactory', 'CookieHandler', 'DatagramPacket', 'DatagramSocket', 'DatagramSocketImpl', 'DatagramSocketImplFactory', 'FileNameMap', 'HttpRetryException', 'HttpURLConnection', 'Inet4Address', 'Inet6Address', 'InetAddress', 'InetSocketAddress', 'JarURLConnection', 'MalformedURLException', 'MulticastSocket', 'NetPermission', 'NetworkInterface', 'NoRouteToHostException', 'PasswordAuthentication', 'PortUnreachableException', 'ProtocolException', 'Proxy.Type', 'ProxySelector', 'ResponseCache', 'SecureCacheResponse', 'ServerSocket', 'Socket', 'SocketAddress', 'SocketException', 'SocketImpl', 'SocketImplFactory', 'SocketOptions', 'SocketPermission', 'SocketTimeoutException', 'URI', 'URISyntaxException', 'URL', 'URLClassLoader', 'URLConnection', 'URLDecoder', 'URLEncoder', 'URLStreamHandler', 'URLStreamHandlerFactory', 'UnknownServiceException'
+            ),
+        29 => array (
+            'Buffer', 'BufferOverflowException', 'BufferUnderflowException', 'ByteBuffer', 'ByteOrder', 'CharBuffer', 'DoubleBuffer', 'FloatBuffer', 'IntBuffer', 'InvalidMarkException', 'LongBuffer', 'MappedByteBuffer', 'ReadOnlyBufferException', 'ShortBuffer'
+            ),
+        30 => array (
+            'AlreadyConnectedException', 'AsynchronousCloseException', 'ByteChannel', 'CancelledKeyException', 'Channel', 'Channels', 'ClosedByInterruptException', 'ClosedChannelException', 'ClosedSelectorException', 'ConnectionPendingException', 'DatagramChannel', 'FileChannel', 'FileChannel.MapMode', 'FileLock', 'FileLockInterruptionException', 'GatheringByteChannel', 'IllegalBlockingModeException', 'IllegalSelectorException', 'InterruptibleChannel', 'NoConnectionPendingException', 'NonReadableChannelException', 'NonWritableChannelException', 'NotYetBoundException', 'NotYetConnectedException', 'OverlappingFileLockException', 'Pipe', 'Pipe.SinkChannel', 'Pipe.SourceChannel', 'ReadableByteChannel', 'ScatteringByteChannel', 'SelectableChannel', 'SelectionKey', 'Selector', 'ServerSocketChannel', 'SocketChannel', 'UnresolvedAddressException', 'UnsupportedAddressTypeException', 'WritableByteChannel'
+            ),
+        31 => array (
+            'AbstractInterruptibleChannel', 'AbstractSelectableChannel', 'AbstractSelectionKey', 'AbstractSelector', 'SelectorProvider'
+            ),
+        32 => array (
+            'CharacterCodingException', 'Charset', 'CharsetDecoder', 'CharsetEncoder', 'CoderMalfunctionError', 'CoderResult', 'CodingErrorAction', 'IllegalCharsetNameException', 'MalformedInputException', 'UnmappableCharacterException', 'UnsupportedCharsetException'
+            ),
+        33 => array (
+            'CharsetProvider'
+            ),
+        34 => array (
+            'AccessException', 'AlreadyBoundException', 'ConnectIOException', 'MarshalException', 'MarshalledObject', 'Naming', 'NoSuchObjectException', 'NotBoundException', 'RMISecurityException', 'RMISecurityManager', 'Remote', 'RemoteException', 'ServerError', 'ServerException', 'ServerRuntimeException', 'StubNotFoundException', 'UnexpectedException', 'UnmarshalException'
+            ),
+        35 => array (
+            'Activatable', 'ActivateFailedException', 'ActivationDesc', 'ActivationException', 'ActivationGroup', 'ActivationGroupDesc', 'ActivationGroupDesc.CommandEnvironment', 'ActivationGroupID', 'ActivationGroup_Stub', 'ActivationID', 'ActivationInstantiator', 'ActivationMonitor', 'ActivationSystem', 'Activator', 'UnknownGroupException', 'UnknownObjectException'
+            ),
+        36 => array (
+            'DGC', 'Lease', 'VMID'
+            ),
+        37 => array (
+            'LocateRegistry', 'Registry', 'RegistryHandler'
+            ),
+        38 => array (
+            'ExportException', 'LoaderHandler', 'LogStream', 'ObjID', 'Operation', 'RMIClassLoader', 'RMIClassLoaderSpi', 'RMIClientSocketFactory', 'RMIFailureHandler', 'RMIServerSocketFactory', 'RMISocketFactory', 'RemoteCall', 'RemoteObject', 'RemoteObjectInvocationHandler', 'RemoteRef', 'RemoteServer', 'RemoteStub', 'ServerCloneException', 'ServerNotActiveException', 'ServerRef', 'Skeleton', 'SkeletonMismatchException', 'SkeletonNotFoundException', 'SocketSecurityException', 'UID', 'UnicastRemoteObject', 'Unreferenced'
+            ),
+        39 => array (
+            'AccessControlContext', 'AccessControlException', 'AccessController', 'AlgorithmParameterGenerator', 'AlgorithmParameterGeneratorSpi', 'AlgorithmParameters', 'AlgorithmParametersSpi', 'AllPermission', 'AuthProvider', 'BasicPermission', 'CodeSigner', 'CodeSource', 'DigestException', 'DigestInputStream', 'DigestOutputStream', 'DomainCombiner', 'GeneralSecurityException', 'Guard', 'GuardedObject', 'Identity', 'IdentityScope', 'InvalidAlgorithmParameterException', 'InvalidParameterException', 'Key', 'KeyException', 'KeyFactory', 'KeyFactorySpi', 'KeyManagementException', 'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi', 'KeyRep', 'KeyRep.Type', 'KeyStore', 'KeyStore.Builder', 'KeyStore.CallbackHandlerProtection', 'KeyStore.Entry', 'KeyStore.LoadStoreParameter', 'KeyStore.PasswordProtection', 'KeyStore.PrivateKeyEntry', 'KeyStore.ProtectionParameter', 'KeyStore.SecretKeyEntry', 'KeyStore.TrustedCertificateEntry', 'KeyStoreException', 'KeyStoreSpi', 'MessageDigest', 'MessageDigestSpi',
+            'NoSuchAlgorithmException', 'NoSuchProviderException', 'PermissionCollection', 'Permissions', 'PrivateKey', 'PrivilegedAction', 'PrivilegedActionException', 'PrivilegedExceptionAction', 'ProtectionDomain', 'Provider', 'Provider.Service', 'ProviderException', 'PublicKey', 'SecureClassLoader', 'SecureRandom', 'SecureRandomSpi', 'Security', 'SecurityPermission', 'Signature', 'SignatureException', 'SignatureSpi', 'SignedObject', 'Signer', 'UnrecoverableEntryException', 'UnrecoverableKeyException', 'UnresolvedPermission'
+            ),
+        40 => array (
+            'Acl', 'AclEntry', 'AclNotFoundException', 'Group', 'LastOwnerException', 'NotOwnerException', 'Owner'
+            ),
+        41 => array (
+            'CRL', 'CRLException', 'CRLSelector', 'CertPath', 'CertPath.CertPathRep', 'CertPathBuilder', 'CertPathBuilderException', 'CertPathBuilderResult', 'CertPathBuilderSpi', 'CertPathParameters', 'CertPathValidator', 'CertPathValidatorException', 'CertPathValidatorResult', 'CertPathValidatorSpi', 'CertSelector', 'CertStore', 'CertStoreException', 'CertStoreParameters', 'CertStoreSpi', 'Certificate.CertificateRep', 'CertificateFactory', 'CertificateFactorySpi', 'CollectionCertStoreParameters', 'LDAPCertStoreParameters', 'PKIXBuilderParameters', 'PKIXCertPathBuilderResult', 'PKIXCertPathChecker', 'PKIXCertPathValidatorResult', 'PKIXParameters', 'PolicyNode', 'PolicyQualifierInfo', 'TrustAnchor', 'X509CRL', 'X509CRLEntry', 'X509CRLSelector', 'X509CertSelector', 'X509Extension'
+            ),
+        42 => array (
+            'DSAKey', 'DSAKeyPairGenerator', 'DSAParams', 'DSAPrivateKey', 'DSAPublicKey', 'ECKey', 'ECPrivateKey', 'ECPublicKey', 'RSAKey', 'RSAMultiPrimePrivateCrtKey', 'RSAPrivateCrtKey', 'RSAPrivateKey', 'RSAPublicKey'
+            ),
+        43 => array (
+            'AlgorithmParameterSpec', 'DSAParameterSpec', 'DSAPrivateKeySpec', 'DSAPublicKeySpec', 'ECField', 'ECFieldF2m', 'ECFieldFp', 'ECGenParameterSpec', 'ECParameterSpec', 'ECPoint', 'ECPrivateKeySpec', 'ECPublicKeySpec', 'EllipticCurve', 'EncodedKeySpec', 'InvalidKeySpecException', 'InvalidParameterSpecException', 'KeySpec', 'MGF1ParameterSpec', 'PKCS8EncodedKeySpec', 'PSSParameterSpec', 'RSAKeyGenParameterSpec', 'RSAMultiPrimePrivateCrtKeySpec', 'RSAOtherPrimeInfo', 'RSAPrivateCrtKeySpec', 'RSAPrivateKeySpec', 'RSAPublicKeySpec', 'X509EncodedKeySpec'
+            ),
+        44 => array (
+            'BatchUpdateException', 'Blob', 'CallableStatement', 'Clob', 'Connection', 'DataTruncation', 'DatabaseMetaData', 'Driver', 'DriverManager', 'DriverPropertyInfo', 'ParameterMetaData', 'PreparedStatement', 'Ref', 'ResultSet', 'ResultSetMetaData', 'SQLData', 'SQLException', 'SQLInput', 'SQLOutput', 'SQLPermission', 'SQLWarning', 'Savepoint', 'Struct', 'Time', 'Types'
+            ),
+        45 => array (
+            'AttributedCharacterIterator', 'AttributedCharacterIterator.Attribute', 'AttributedString', 'Bidi', 'BreakIterator', 'CharacterIterator', 'ChoiceFormat', 'CollationElementIterator', 'CollationKey', 'Collator', 'DateFormat', 'DateFormat.Field', 'DateFormatSymbols', 'DecimalFormat', 'DecimalFormatSymbols', 'FieldPosition', 'Format', 'Format.Field', 'MessageFormat', 'MessageFormat.Field', 'NumberFormat', 'NumberFormat.Field', 'ParseException', 'ParsePosition', 'RuleBasedCollator', 'SimpleDateFormat', 'StringCharacterIterator'
+            ),
+        46 => array (
+            'AbstractCollection', 'AbstractList', 'AbstractMap', 'AbstractQueue', 'AbstractSequentialList', 'AbstractSet', 'ArrayList', 'Arrays', 'BitSet', 'Calendar', 'Collection', 'Collections', 'Comparator', 'ConcurrentModificationException', 'Currency', 'Dictionary', 'DuplicateFormatFlagsException', 'EmptyStackException', 'EnumMap', 'EnumSet', 'Enumeration', 'EventListenerProxy', 'EventObject', 'FormatFlagsConversionMismatchException', 'Formattable', 'FormattableFlags', 'Formatter.BigDecimalLayoutForm', 'FormatterClosedException', 'GregorianCalendar', 'HashMap', 'HashSet', 'Hashtable', 'IdentityHashMap', 'IllegalFormatCodePointException', 'IllegalFormatConversionException', 'IllegalFormatException', 'IllegalFormatFlagsException', 'IllegalFormatPrecisionException', 'IllegalFormatWidthException', 'InputMismatchException', 'InvalidPropertiesFormatException', 'Iterator', 'LinkedHashMap', 'LinkedHashSet', 'LinkedList', 'ListIterator', 'ListResourceBundle', 'Locale', 'Map', 'Map.Entry', 'MissingFormatArgumentException',
+            'MissingFormatWidthException', 'MissingResourceException', 'NoSuchElementException', 'Observable', 'Observer', 'PriorityQueue', 'Properties', 'PropertyPermission', 'PropertyResourceBundle', 'Queue', 'Random', 'RandomAccess', 'ResourceBundle', 'Scanner', 'Set', 'SimpleTimeZone', 'SortedMap', 'SortedSet', 'Stack', 'StringTokenizer', 'TimeZone', 'TimerTask', 'TooManyListenersException', 'TreeMap', 'TreeSet', 'UUID', 'UnknownFormatConversionException', 'UnknownFormatFlagsException', 'Vector', 'WeakHashMap'
+            ),
+        47 => array (
+            'AbstractExecutorService', 'ArrayBlockingQueue', 'BlockingQueue', 'BrokenBarrierException', 'Callable', 'CancellationException', 'CompletionService', 'ConcurrentHashMap', 'ConcurrentLinkedQueue', 'ConcurrentMap', 'CopyOnWriteArrayList', 'CopyOnWriteArraySet', 'CountDownLatch', 'CyclicBarrier', 'DelayQueue', 'Delayed', 'Exchanger', 'ExecutionException', 'Executor', 'ExecutorCompletionService', 'ExecutorService', 'Executors', 'Future', 'FutureTask', 'LinkedBlockingQueue', 'PriorityBlockingQueue', 'RejectedExecutionException', 'RejectedExecutionHandler', 'ScheduledExecutorService', 'ScheduledFuture', 'ScheduledThreadPoolExecutor', 'Semaphore', 'SynchronousQueue', 'ThreadFactory', 'ThreadPoolExecutor', 'ThreadPoolExecutor.AbortPolicy', 'ThreadPoolExecutor.CallerRunsPolicy', 'ThreadPoolExecutor.DiscardOldestPolicy', 'ThreadPoolExecutor.DiscardPolicy', 'TimeUnit', 'TimeoutException'
+            ),
+        48 => array (
+            'AtomicBoolean', 'AtomicInteger', 'AtomicIntegerArray', 'AtomicIntegerFieldUpdater', 'AtomicLong', 'AtomicLongArray', 'AtomicLongFieldUpdater', 'AtomicMarkableReference', 'AtomicReference', 'AtomicReferenceArray', 'AtomicReferenceFieldUpdater', 'AtomicStampedReference'
+            ),
+        49 => array (
+            'AbstractQueuedSynchronizer', 'Condition', 'Lock', 'LockSupport', 'ReadWriteLock', 'ReentrantLock', 'ReentrantReadWriteLock', 'ReentrantReadWriteLock.ReadLock', 'ReentrantReadWriteLock.WriteLock'
+            ),
+        50 => array (
+            'Attributes.Name', 'JarEntry', 'JarException', 'JarFile', 'JarInputStream', 'JarOutputStream', 'Manifest', 'Pack200', 'Pack200.Packer', 'Pack200.Unpacker'
+            ),
+        51 => array (
+            'ConsoleHandler', 'ErrorManager', 'FileHandler', 'Filter', 'Handler', 'Level', 'LogManager', 'LogRecord', 'Logger', 'LoggingMXBean', 'LoggingPermission', 'MemoryHandler', 'SimpleFormatter', 'SocketHandler', 'StreamHandler', 'XMLFormatter'
+            ),
+        52 => array (
+            'AbstractPreferences', 'BackingStoreException', 'InvalidPreferencesFormatException', 'NodeChangeEvent', 'NodeChangeListener', 'PreferenceChangeEvent', 'PreferenceChangeListener', 'Preferences', 'PreferencesFactory'
+            ),
+        53 => array (
+            'MatchResult', 'Matcher', 'Pattern', 'PatternSyntaxException'
+            ),
+        54 => array (
+            'Adler32', 'CRC32', 'CheckedInputStream', 'CheckedOutputStream', 'Checksum', 'DataFormatException', 'Deflater', 'DeflaterOutputStream', 'GZIPInputStream', 'GZIPOutputStream', 'Inflater', 'InflaterInputStream', 'ZipEntry', 'ZipException', 'ZipFile', 'ZipInputStream', 'ZipOutputStream'
+            ),
+        55 => array (
+            'Accessible', 'AccessibleAction', 'AccessibleAttributeSequence', 'AccessibleBundle', 'AccessibleComponent', 'AccessibleContext', 'AccessibleEditableText', 'AccessibleExtendedComponent', 'AccessibleExtendedTable', 'AccessibleExtendedText', 'AccessibleHyperlink', 'AccessibleHypertext', 'AccessibleIcon', 'AccessibleKeyBinding', 'AccessibleRelation', 'AccessibleRelationSet', 'AccessibleResourceBundle', 'AccessibleRole', 'AccessibleSelection', 'AccessibleState', 'AccessibleStateSet', 'AccessibleStreamable', 'AccessibleTable', 'AccessibleTableModelChange', 'AccessibleText', 'AccessibleTextSequence', 'AccessibleValue'
+            ),
+        56 => array (
+            'ActivityCompletedException', 'ActivityRequiredException', 'InvalidActivityException'
+            ),
+        57 => array (
+            'BadPaddingException', 'Cipher', 'CipherInputStream', 'CipherOutputStream', 'CipherSpi', 'EncryptedPrivateKeyInfo', 'ExemptionMechanism', 'ExemptionMechanismException', 'ExemptionMechanismSpi', 'IllegalBlockSizeException', 'KeyAgreement', 'KeyAgreementSpi', 'KeyGenerator', 'KeyGeneratorSpi', 'Mac', 'MacSpi', 'NoSuchPaddingException', 'NullCipher', 'SealedObject', 'SecretKey', 'SecretKeyFactory', 'SecretKeyFactorySpi', 'ShortBufferException'
+            ),
+        58 => array (
+            'DHKey', 'DHPrivateKey', 'DHPublicKey', 'PBEKey'
+            ),
+        59 => array (
+            'DESKeySpec', 'DESedeKeySpec', 'DHGenParameterSpec', 'DHParameterSpec', 'DHPrivateKeySpec', 'DHPublicKeySpec', 'IvParameterSpec', 'OAEPParameterSpec', 'PBEKeySpec', 'PBEParameterSpec', 'PSource', 'PSource.PSpecified', 'RC2ParameterSpec', 'RC5ParameterSpec', 'SecretKeySpec'
+            ),
+        60 => array (
+            'IIOException', 'IIOImage', 'IIOParam', 'IIOParamController', 'ImageIO', 'ImageReadParam', 'ImageReader', 'ImageTranscoder', 'ImageTypeSpecifier', 'ImageWriteParam', 'ImageWriter'
+            ),
+        61 => array (
+            'IIOReadProgressListener', 'IIOReadUpdateListener', 'IIOReadWarningListener', 'IIOWriteProgressListener', 'IIOWriteWarningListener'
+            ),
+        62 => array (
+            'IIOInvalidTreeException', 'IIOMetadata', 'IIOMetadataController', 'IIOMetadataFormat', 'IIOMetadataFormatImpl', 'IIOMetadataNode'
+            ),
+        63 => array (
+            'BMPImageWriteParam'
+            ),
+        64 => array (
+            'JPEGHuffmanTable', 'JPEGImageReadParam', 'JPEGImageWriteParam', 'JPEGQTable'
+            ),
+        65 => array (
+            'IIORegistry', 'IIOServiceProvider', 'ImageInputStreamSpi', 'ImageOutputStreamSpi', 'ImageReaderSpi', 'ImageReaderWriterSpi', 'ImageTranscoderSpi', 'ImageWriterSpi', 'RegisterableService', 'ServiceRegistry', 'ServiceRegistry.Filter'
+            ),
+        66 => array (
+            'FileCacheImageInputStream', 'FileCacheImageOutputStream', 'FileImageInputStream', 'FileImageOutputStream', 'IIOByteBuffer', 'ImageInputStream', 'ImageInputStreamImpl', 'ImageOutputStream', 'ImageOutputStreamImpl', 'MemoryCacheImageInputStream', 'MemoryCacheImageOutputStream'
+            ),
+        67 => array (
+            'AttributeChangeNotification', 'AttributeChangeNotificationFilter', 'AttributeNotFoundException', 'AttributeValueExp', 'BadAttributeValueExpException', 'BadBinaryOpValueExpException', 'BadStringOperationException', 'Descriptor', 'DescriptorAccess', 'DynamicMBean', 'InstanceAlreadyExistsException', 'InstanceNotFoundException', 'InvalidApplicationException', 'JMException', 'JMRuntimeException', 'ListenerNotFoundException', 'MBeanAttributeInfo', 'MBeanConstructorInfo', 'MBeanException', 'MBeanFeatureInfo', 'MBeanInfo', 'MBeanNotificationInfo', 'MBeanOperationInfo', 'MBeanParameterInfo', 'MBeanPermission', 'MBeanRegistration', 'MBeanRegistrationException', 'MBeanServer', 'MBeanServerBuilder', 'MBeanServerConnection', 'MBeanServerDelegate', 'MBeanServerDelegateMBean', 'MBeanServerFactory', 'MBeanServerInvocationHandler', 'MBeanServerNotification', 'MBeanServerPermission', 'MBeanTrustPermission', 'MalformedObjectNameException', 'NotCompliantMBeanException', 'Notification', 'NotificationBroadcaster',
+            'NotificationBroadcasterSupport', 'NotificationEmitter', 'NotificationFilter', 'NotificationFilterSupport', 'NotificationListener', 'ObjectInstance', 'ObjectName', 'OperationsException', 'PersistentMBean', 'Query', 'QueryEval', 'QueryExp', 'ReflectionException', 'RuntimeErrorException', 'RuntimeMBeanException', 'RuntimeOperationsException', 'ServiceNotFoundException', 'StandardMBean', 'StringValueExp', 'ValueExp'
+            ),
+        68 => array (
+            'ClassLoaderRepository', 'MLet', 'MLetMBean', 'PrivateClassLoader', 'PrivateMLet'
+            ),
+        69 => array (
+            'DescriptorSupport', 'InvalidTargetObjectTypeException', 'ModelMBean', 'ModelMBeanAttributeInfo', 'ModelMBeanConstructorInfo', 'ModelMBeanInfo', 'ModelMBeanInfoSupport', 'ModelMBeanNotificationBroadcaster', 'ModelMBeanNotificationInfo', 'ModelMBeanOperationInfo', 'RequiredModelMBean', 'XMLParseException'
+            ),
+        70 => array (
+            'CounterMonitor', 'CounterMonitorMBean', 'GaugeMonitor', 'GaugeMonitorMBean', 'Monitor', 'MonitorMBean', 'MonitorNotification', 'MonitorSettingException', 'StringMonitor', 'StringMonitorMBean'
+            ),
+        71 => array (
+            'ArrayType', 'CompositeData', 'CompositeDataSupport', 'CompositeType', 'InvalidOpenTypeException', 'KeyAlreadyExistsException', 'OpenDataException', 'OpenMBeanAttributeInfo', 'OpenMBeanAttributeInfoSupport', 'OpenMBeanConstructorInfo', 'OpenMBeanConstructorInfoSupport', 'OpenMBeanInfo', 'OpenMBeanInfoSupport', 'OpenMBeanOperationInfo', 'OpenMBeanOperationInfoSupport', 'OpenMBeanParameterInfo', 'OpenMBeanParameterInfoSupport', 'SimpleType', 'TabularData', 'TabularDataSupport', 'TabularType'
+            ),
+        72 => array (
+            'InvalidRelationIdException', 'InvalidRelationServiceException', 'InvalidRelationTypeException', 'InvalidRoleInfoException', 'InvalidRoleValueException', 'MBeanServerNotificationFilter', 'Relation', 'RelationException', 'RelationNotFoundException', 'RelationNotification', 'RelationService', 'RelationServiceMBean', 'RelationServiceNotRegisteredException', 'RelationSupport', 'RelationSupportMBean', 'RelationType', 'RelationTypeNotFoundException', 'RelationTypeSupport', 'Role', 'RoleInfo', 'RoleInfoNotFoundException', 'RoleList', 'RoleNotFoundException', 'RoleResult', 'RoleStatus', 'RoleUnresolved', 'RoleUnresolvedList'
+            ),
+        73 => array (
+            'JMXAuthenticator', 'JMXConnectionNotification', 'JMXConnector', 'JMXConnectorFactory', 'JMXConnectorProvider', 'JMXConnectorServer', 'JMXConnectorServerFactory', 'JMXConnectorServerMBean', 'JMXConnectorServerProvider', 'JMXPrincipal', 'JMXProviderException', 'JMXServerErrorException', 'JMXServiceURL', 'MBeanServerForwarder', 'NotificationResult', 'SubjectDelegationPermission', 'TargetedNotification'
+            ),
+        74 => array (
+            'RMIConnection', 'RMIConnectionImpl', 'RMIConnectionImpl_Stub', 'RMIConnector', 'RMIConnectorServer', 'RMIIIOPServerImpl', 'RMIJRMPServerImpl', 'RMIServer', 'RMIServerImpl', 'RMIServerImpl_Stub'
+            ),
+        75 => array (
+            'TimerAlarmClockNotification', 'TimerMBean', 'TimerNotification'
+            ),
+        76 => array (
+            'AuthenticationNotSupportedException', 'BinaryRefAddr', 'CannotProceedException', 'CommunicationException', 'CompositeName', 'CompoundName', 'ConfigurationException', 'ContextNotEmptyException', 'InitialContext', 'InsufficientResourcesException', 'InterruptedNamingException', 'InvalidNameException', 'LimitExceededException', 'LinkException', 'LinkLoopException', 'LinkRef', 'MalformedLinkException', 'Name', 'NameAlreadyBoundException', 'NameClassPair', 'NameNotFoundException', 'NameParser', 'NamingEnumeration', 'NamingException', 'NamingSecurityException', 'NoInitialContextException', 'NoPermissionException', 'NotContextException', 'OperationNotSupportedException', 'PartialResultException', 'RefAddr', 'Referenceable', 'ReferralException', 'ServiceUnavailableException', 'SizeLimitExceededException', 'StringRefAddr', 'TimeLimitExceededException'
+            ),
+        77 => array (
+            'AttributeInUseException', 'AttributeModificationException', 'BasicAttribute', 'BasicAttributes', 'DirContext', 'InitialDirContext', 'InvalidAttributeIdentifierException', 'InvalidAttributesException', 'InvalidSearchControlsException', 'InvalidSearchFilterException', 'ModificationItem', 'NoSuchAttributeException', 'SchemaViolationException', 'SearchControls', 'SearchResult'
+            ),
+        78 => array (
+            'EventContext', 'EventDirContext', 'NamespaceChangeListener', 'NamingEvent', 'NamingExceptionEvent', 'NamingListener', 'ObjectChangeListener'
+            ),
+        79 => array (
+            'BasicControl', 'ControlFactory', 'ExtendedRequest', 'ExtendedResponse', 'HasControls', 'InitialLdapContext', 'LdapContext', 'LdapName', 'LdapReferralException', 'ManageReferralControl', 'PagedResultsControl', 'PagedResultsResponseControl', 'Rdn', 'SortControl', 'SortKey', 'SortResponseControl', 'StartTlsRequest', 'StartTlsResponse', 'UnsolicitedNotification', 'UnsolicitedNotificationEvent', 'UnsolicitedNotificationListener'
+            ),
+        80 => array (
+            'DirObjectFactory', 'DirStateFactory', 'DirStateFactory.Result', 'DirectoryManager', 'InitialContextFactory', 'InitialContextFactoryBuilder', 'NamingManager', 'ObjectFactory', 'ObjectFactoryBuilder', 'ResolveResult', 'Resolver', 'StateFactory'
+            ),
+        81 => array (
+            'ServerSocketFactory', 'SocketFactory'
+            ),
+        82 => array (
+            'CertPathTrustManagerParameters', 'HandshakeCompletedEvent', 'HandshakeCompletedListener', 'HostnameVerifier', 'HttpsURLConnection', 'KeyManager', 'KeyManagerFactory', 'KeyManagerFactorySpi', 'KeyStoreBuilderParameters', 'ManagerFactoryParameters', 'SSLContext', 'SSLContextSpi', 'SSLEngine', 'SSLEngineResult', 'SSLEngineResult.HandshakeStatus', 'SSLEngineResult.Status', 'SSLException', 'SSLHandshakeException', 'SSLKeyException', 'SSLPeerUnverifiedException', 'SSLPermission', 'SSLProtocolException', 'SSLServerSocket', 'SSLServerSocketFactory', 'SSLSession', 'SSLSessionBindingEvent', 'SSLSessionBindingListener', 'SSLSessionContext', 'SSLSocket', 'SSLSocketFactory', 'TrustManager', 'TrustManagerFactory', 'TrustManagerFactorySpi', 'X509ExtendedKeyManager', 'X509KeyManager', 'X509TrustManager'
+            ),
+        83 => array (
+            'AttributeException', 'CancelablePrintJob', 'Doc', 'DocFlavor', 'DocFlavor.BYTE_ARRAY', 'DocFlavor.CHAR_ARRAY', 'DocFlavor.INPUT_STREAM', 'DocFlavor.READER', 'DocFlavor.SERVICE_FORMATTED', 'DocFlavor.STRING', 'DocFlavor.URL', 'DocPrintJob', 'FlavorException', 'MultiDoc', 'MultiDocPrintJob', 'MultiDocPrintService', 'PrintException', 'PrintService', 'PrintServiceLookup', 'ServiceUI', 'ServiceUIFactory', 'SimpleDoc', 'StreamPrintService', 'StreamPrintServiceFactory', 'URIException'
+            ),
+        84 => array (
+            'AttributeSetUtilities', 'DateTimeSyntax', 'DocAttribute', 'DocAttributeSet', 'EnumSyntax', 'HashAttributeSet', 'HashDocAttributeSet', 'HashPrintJobAttributeSet', 'HashPrintRequestAttributeSet', 'HashPrintServiceAttributeSet', 'IntegerSyntax', 'PrintJobAttribute', 'PrintJobAttributeSet', 'PrintRequestAttribute', 'PrintRequestAttributeSet', 'PrintServiceAttribute', 'PrintServiceAttributeSet', 'ResolutionSyntax', 'SetOfIntegerSyntax', 'Size2DSyntax', 'SupportedValuesAttribute', 'TextSyntax', 'URISyntax', 'UnmodifiableSetException'
+            ),
+        85 => array (
+            'Chromaticity', 'ColorSupported', 'Compression', 'Copies', 'CopiesSupported', 'DateTimeAtCompleted', 'DateTimeAtCreation', 'DateTimeAtProcessing', 'Destination', 'DocumentName', 'Fidelity', 'Finishings', 'JobHoldUntil', 'JobImpressions', 'JobImpressionsCompleted', 'JobImpressionsSupported', 'JobKOctets', 'JobKOctetsProcessed', 'JobKOctetsSupported', 'JobMediaSheets', 'JobMediaSheetsCompleted', 'JobMediaSheetsSupported', 'JobMessageFromOperator', 'JobName', 'JobOriginatingUserName', 'JobPriority', 'JobPrioritySupported', 'JobSheets', 'JobState', 'JobStateReason', 'JobStateReasons', 'Media', 'MediaName', 'MediaPrintableArea', 'MediaSize', 'MediaSize.Engineering', 'MediaSize.ISO', 'MediaSize.JIS', 'MediaSize.NA', 'MediaSize.Other', 'MediaSizeName', 'MediaTray', 'MultipleDocumentHandling', 'NumberOfDocuments', 'NumberOfInterveningJobs', 'NumberUp', 'NumberUpSupported', 'OrientationRequested', 'OutputDeviceAssigned', 'PDLOverrideSupported', 'PageRanges', 'PagesPerMinute', 'PagesPerMinuteColor',
+            'PresentationDirection', 'PrintQuality', 'PrinterInfo', 'PrinterIsAcceptingJobs', 'PrinterLocation', 'PrinterMakeAndModel', 'PrinterMessageFromOperator', 'PrinterMoreInfo', 'PrinterMoreInfoManufacturer', 'PrinterName', 'PrinterResolution', 'PrinterState', 'PrinterStateReason', 'PrinterStateReasons', 'PrinterURI', 'QueuedJobCount', 'ReferenceUriSchemesSupported', 'RequestingUserName', 'Severity', 'SheetCollate', 'Sides'
+            ),
+        86 => array (
+            'PrintEvent', 'PrintJobAdapter', 'PrintJobAttributeEvent', 'PrintJobAttributeListener', 'PrintJobEvent', 'PrintJobListener', 'PrintServiceAttributeEvent', 'PrintServiceAttributeListener'
+            ),
+        87 => array (
+            'PortableRemoteObject'
+            ),
+        88 => array (
+            'ClassDesc', 'PortableRemoteObjectDelegate', 'Stub', 'StubDelegate', 'Tie', 'Util', 'UtilDelegate', 'ValueHandler', 'ValueHandlerMultiFormat'
+            ),
+        89 => array (
+            'SslRMIClientSocketFactory', 'SslRMIServerSocketFactory'
+            ),
+        90 => array (
+            'AuthPermission', 'DestroyFailedException', 'Destroyable', 'PrivateCredentialPermission', 'RefreshFailedException', 'Refreshable', 'Subject', 'SubjectDomainCombiner'
+            ),
+        91 => array (
+            'Callback', 'CallbackHandler', 'ChoiceCallback', 'ConfirmationCallback', 'LanguageCallback', 'NameCallback', 'PasswordCallback', 'TextInputCallback', 'TextOutputCallback', 'UnsupportedCallbackException'
+            ),
+        92 => array (
+            'DelegationPermission', 'KerberosKey', 'KerberosPrincipal', 'KerberosTicket', 'ServicePermission'
+            ),
+        93 => array (
+            'AccountException', 'AccountExpiredException', 'AccountLockedException', 'AccountNotFoundException', 'AppConfigurationEntry', 'AppConfigurationEntry.LoginModuleControlFlag', 'Configuration', 'CredentialException', 'CredentialExpiredException', 'CredentialNotFoundException', 'FailedLoginException', 'LoginContext', 'LoginException'
+            ),
+        94 => array (
+            'LoginModule'
+            ),
+        95 => array (
+            'X500Principal', 'X500PrivateCredential'
+            ),
+        96 => array (
+            'AuthorizeCallback', 'RealmCallback', 'RealmChoiceCallback', 'Sasl', 'SaslClient', 'SaslClientFactory', 'SaslException', 'SaslServer', 'SaslServerFactory'
+            ),
+        97 => array (
+            'ControllerEventListener', 'Instrument', 'InvalidMidiDataException', 'MetaEventListener', 'MetaMessage', 'MidiChannel', 'MidiDevice', 'MidiDevice.Info', 'MidiEvent', 'MidiFileFormat', 'MidiMessage', 'MidiSystem', 'MidiUnavailableException', 'Patch', 'Receiver', 'Sequence', 'Sequencer', 'Sequencer.SyncMode', 'ShortMessage', 'Soundbank', 'SoundbankResource', 'Synthesizer', 'SysexMessage', 'Track', 'Transmitter', 'VoiceStatus'
+            ),
+        98 => array (
+            'MidiDeviceProvider', 'MidiFileReader', 'MidiFileWriter', 'SoundbankReader'
+            ),
+        99 => array (
+            'AudioFileFormat', 'AudioFileFormat.Type', 'AudioFormat', 'AudioFormat.Encoding', 'AudioInputStream', 'AudioPermission', 'AudioSystem', 'BooleanControl', 'BooleanControl.Type', 'Clip', 'CompoundControl', 'CompoundControl.Type', 'Control.Type', 'DataLine', 'DataLine.Info', 'EnumControl', 'EnumControl.Type', 'FloatControl', 'FloatControl.Type', 'Line', 'Line.Info', 'LineEvent', 'LineEvent.Type', 'LineListener', 'LineUnavailableException', 'Mixer', 'Mixer.Info', 'Port', 'Port.Info', 'ReverbType', 'SourceDataLine', 'TargetDataLine', 'UnsupportedAudioFileException'
+            ),
+        100 => array (
+            'AudioFileReader', 'AudioFileWriter', 'FormatConversionProvider', 'MixerProvider'
+            ),
+        101 => array (
+            'ConnectionEvent', 'ConnectionEventListener', 'ConnectionPoolDataSource', 'DataSource', 'PooledConnection', 'RowSet', 'RowSetEvent', 'RowSetInternal', 'RowSetListener', 'RowSetMetaData', 'RowSetReader', 'RowSetWriter', 'XAConnection', 'XADataSource'
+            ),
+        102 => array (
+            'BaseRowSet', 'CachedRowSet', 'FilteredRowSet', 'JdbcRowSet', 'JoinRowSet', 'Joinable', 'Predicate', 'RowSetMetaDataImpl', 'RowSetWarning', 'WebRowSet'
+            ),
+        103 => array (
+            'SQLInputImpl', 'SQLOutputImpl', 'SerialArray', 'SerialBlob', 'SerialClob', 'SerialDatalink', 'SerialException', 'SerialJavaObject', 'SerialRef', 'SerialStruct'
+            ),
+        104 => array (
+            'SyncFactory', 'SyncFactoryException', 'SyncProvider', 'SyncProviderException', 'SyncResolver', 'TransactionalWriter', 'XmlReader', 'XmlWriter'
+            ),
+        105 => array (
+            'AbstractAction', 'AbstractButton', 'AbstractCellEditor', 'AbstractListModel', 'AbstractSpinnerModel', 'Action', 'ActionMap', 'BorderFactory', 'BoundedRangeModel', 'Box', 'Box.Filler', 'BoxLayout', 'ButtonGroup', 'ButtonModel', 'CellEditor', 'CellRendererPane', 'ComboBoxEditor', 'ComboBoxModel', 'ComponentInputMap', 'DebugGraphics', 'DefaultBoundedRangeModel', 'DefaultButtonModel', 'DefaultCellEditor', 'DefaultComboBoxModel', 'DefaultDesktopManager', 'DefaultFocusManager', 'DefaultListCellRenderer', 'DefaultListCellRenderer.UIResource', 'DefaultListModel', 'DefaultListSelectionModel', 'DefaultSingleSelectionModel', 'DesktopManager', 'FocusManager', 'GrayFilter', 'Icon', 'ImageIcon', 'InputMap', 'InputVerifier', 'InternalFrameFocusTraversalPolicy', 'JApplet', 'JButton', 'JCheckBox', 'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox', 'JComboBox.KeySelectionManager', 'JComponent', 'JDesktopPane', 'JDialog', 'JEditorPane', 'JFileChooser', 'JFormattedTextField', 'JFormattedTextField.AbstractFormatter',
+            'JFormattedTextField.AbstractFormatterFactory', 'JFrame', 'JInternalFrame', 'JInternalFrame.JDesktopIcon', 'JLabel', 'JLayeredPane', 'JList', 'JMenu', 'JMenuBar', 'JMenuItem', 'JOptionPane', 'JPanel', 'JPasswordField', 'JPopupMenu', 'JPopupMenu.Separator', 'JProgressBar', 'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane', 'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider', 'JSpinner', 'JSpinner.DateEditor', 'JSpinner.DefaultEditor', 'JSpinner.ListEditor', 'JSpinner.NumberEditor', 'JSplitPane', 'JTabbedPane', 'JTable', 'JTable.PrintMode', 'JTextArea', 'JTextField', 'JTextPane', 'JToggleButton', 'JToggleButton.ToggleButtonModel', 'JToolBar', 'JToolBar.Separator', 'JToolTip', 'JTree', 'JTree.DynamicUtilTreeNode', 'JTree.EmptySelectionModel', 'JViewport', 'JWindow', 'KeyStroke', 'LayoutFocusTraversalPolicy', 'ListCellRenderer', 'ListModel', 'ListSelectionModel', 'LookAndFeel', 'MenuElement', 'MenuSelectionManager', 'MutableComboBoxModel', 'OverlayLayout', 'Popup', 'PopupFactory', 'ProgressMonitor',
+            'ProgressMonitorInputStream', 'Renderer', 'RepaintManager', 'RootPaneContainer', 'ScrollPaneConstants', 'ScrollPaneLayout', 'ScrollPaneLayout.UIResource', 'Scrollable', 'SingleSelectionModel', 'SizeRequirements', 'SizeSequence', 'SortingFocusTraversalPolicy', 'SpinnerDateModel', 'SpinnerListModel', 'SpinnerModel', 'SpinnerNumberModel', 'Spring', 'SpringLayout', 'SpringLayout.Constraints', 'SwingConstants', 'SwingUtilities', 'ToolTipManager', 'TransferHandler', 'UIDefaults', 'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap', 'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue', 'UIManager', 'UIManager.LookAndFeelInfo', 'UnsupportedLookAndFeelException', 'ViewportLayout', 'WindowConstants'
+            ),
+        106 => array (
+            'AbstractBorder', 'BevelBorder', 'Border', 'CompoundBorder', 'EmptyBorder', 'EtchedBorder', 'LineBorder', 'MatteBorder', 'SoftBevelBorder', 'TitledBorder'
+            ),
+        107 => array (
+            'AbstractColorChooserPanel', 'ColorChooserComponentFactory', 'ColorSelectionModel', 'DefaultColorSelectionModel'
+            ),
+        108 => array (
+            'AncestorEvent', 'AncestorListener', 'CaretEvent', 'CaretListener', 'CellEditorListener', 'ChangeEvent', 'ChangeListener', 'DocumentEvent.ElementChange', 'DocumentEvent.EventType', 'DocumentListener', 'EventListenerList', 'HyperlinkEvent', 'HyperlinkEvent.EventType', 'HyperlinkListener', 'InternalFrameAdapter', 'InternalFrameEvent', 'InternalFrameListener', 'ListDataEvent', 'ListDataListener', 'ListSelectionEvent', 'ListSelectionListener', 'MenuDragMouseEvent', 'MenuDragMouseListener', 'MenuEvent', 'MenuKeyEvent', 'MenuKeyListener', 'MenuListener', 'MouseInputAdapter', 'MouseInputListener', 'PopupMenuEvent', 'PopupMenuListener', 'SwingPropertyChangeSupport', 'TableColumnModelEvent', 'TableColumnModelListener', 'TableModelEvent', 'TableModelListener', 'TreeExpansionEvent', 'TreeExpansionListener', 'TreeModelEvent', 'TreeModelListener', 'TreeSelectionEvent', 'TreeSelectionListener', 'TreeWillExpandListener', 'UndoableEditEvent', 'UndoableEditListener'
+            ),
+        109 => array (
+            'FileSystemView', 'FileView'
+            ),
+        110 => array (
+            'ActionMapUIResource', 'BorderUIResource', 'BorderUIResource.BevelBorderUIResource', 'BorderUIResource.CompoundBorderUIResource', 'BorderUIResource.EmptyBorderUIResource', 'BorderUIResource.EtchedBorderUIResource', 'BorderUIResource.LineBorderUIResource', 'BorderUIResource.MatteBorderUIResource', 'BorderUIResource.TitledBorderUIResource', 'ButtonUI', 'ColorChooserUI', 'ColorUIResource', 'ComboBoxUI', 'ComponentInputMapUIResource', 'ComponentUI', 'DesktopIconUI', 'DesktopPaneUI', 'DimensionUIResource', 'FileChooserUI', 'FontUIResource', 'IconUIResource', 'InputMapUIResource', 'InsetsUIResource', 'InternalFrameUI', 'LabelUI', 'ListUI', 'MenuBarUI', 'MenuItemUI', 'OptionPaneUI', 'PanelUI', 'PopupMenuUI', 'ProgressBarUI', 'RootPaneUI', 'ScrollBarUI', 'ScrollPaneUI', 'SeparatorUI', 'SliderUI', 'SpinnerUI', 'SplitPaneUI', 'TabbedPaneUI', 'TableHeaderUI', 'TableUI', 'TextUI', 'ToolBarUI', 'ToolTipUI', 'TreeUI', 'UIResource', 'ViewportUI'
+            ),
+        111 => array (
+            'BasicArrowButton', 'BasicBorders', 'BasicBorders.ButtonBorder', 'BasicBorders.FieldBorder', 'BasicBorders.MarginBorder', 'BasicBorders.MenuBarBorder', 'BasicBorders.RadioButtonBorder', 'BasicBorders.RolloverButtonBorder', 'BasicBorders.SplitPaneBorder', 'BasicBorders.ToggleButtonBorder', 'BasicButtonListener', 'BasicButtonUI', 'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI', 'BasicColorChooserUI', 'BasicComboBoxEditor', 'BasicComboBoxEditor.UIResource', 'BasicComboBoxRenderer', 'BasicComboBoxRenderer.UIResource', 'BasicComboBoxUI', 'BasicComboPopup', 'BasicDesktopIconUI', 'BasicDesktopPaneUI', 'BasicDirectoryModel', 'BasicEditorPaneUI', 'BasicFileChooserUI', 'BasicFormattedTextFieldUI', 'BasicGraphicsUtils', 'BasicHTML', 'BasicIconFactory', 'BasicInternalFrameTitlePane', 'BasicInternalFrameUI', 'BasicLabelUI', 'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI', 'BasicMenuItemUI', 'BasicMenuUI', 'BasicOptionPaneUI', 'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI', 'BasicPasswordFieldUI',
+            'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI', 'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI', 'BasicRadioButtonUI', 'BasicRootPaneUI', 'BasicScrollBarUI', 'BasicScrollPaneUI', 'BasicSeparatorUI', 'BasicSliderUI', 'BasicSpinnerUI', 'BasicSplitPaneDivider', 'BasicSplitPaneUI', 'BasicTabbedPaneUI', 'BasicTableHeaderUI', 'BasicTableUI', 'BasicTextAreaUI', 'BasicTextFieldUI', 'BasicTextPaneUI', 'BasicTextUI', 'BasicTextUI.BasicCaret', 'BasicTextUI.BasicHighlighter', 'BasicToggleButtonUI', 'BasicToolBarSeparatorUI', 'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI', 'BasicViewportUI', 'ComboPopup', 'DefaultMenuLayout'
+            ),
+        112 => array (
+            'DefaultMetalTheme', 'MetalBorders', 'MetalBorders.ButtonBorder', 'MetalBorders.Flush3DBorder', 'MetalBorders.InternalFrameBorder', 'MetalBorders.MenuBarBorder', 'MetalBorders.MenuItemBorder', 'MetalBorders.OptionDialogBorder', 'MetalBorders.PaletteBorder', 'MetalBorders.PopupMenuBorder', 'MetalBorders.RolloverButtonBorder', 'MetalBorders.ScrollPaneBorder', 'MetalBorders.TableHeaderBorder', 'MetalBorders.TextFieldBorder', 'MetalBorders.ToggleButtonBorder', 'MetalBorders.ToolBarBorder', 'MetalButtonUI', 'MetalCheckBoxIcon', 'MetalCheckBoxUI', 'MetalComboBoxButton', 'MetalComboBoxEditor', 'MetalComboBoxEditor.UIResource', 'MetalComboBoxIcon', 'MetalComboBoxUI', 'MetalDesktopIconUI', 'MetalFileChooserUI', 'MetalIconFactory', 'MetalIconFactory.FileIcon16', 'MetalIconFactory.FolderIcon16', 'MetalIconFactory.PaletteCloseIcon', 'MetalIconFactory.TreeControlIcon', 'MetalIconFactory.TreeFolderIcon', 'MetalIconFactory.TreeLeafIcon', 'MetalInternalFrameTitlePane', 'MetalInternalFrameUI', 'MetalLabelUI',
+            'MetalLookAndFeel', 'MetalMenuBarUI', 'MetalPopupMenuSeparatorUI', 'MetalProgressBarUI', 'MetalRadioButtonUI', 'MetalRootPaneUI', 'MetalScrollBarUI', 'MetalScrollButton', 'MetalScrollPaneUI', 'MetalSeparatorUI', 'MetalSliderUI', 'MetalSplitPaneUI', 'MetalTabbedPaneUI', 'MetalTextFieldUI', 'MetalTheme', 'MetalToggleButtonUI', 'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI', 'OceanTheme'
+            ),
+        113 => array (
+            'MultiButtonUI', 'MultiColorChooserUI', 'MultiComboBoxUI', 'MultiDesktopIconUI', 'MultiDesktopPaneUI', 'MultiFileChooserUI', 'MultiInternalFrameUI', 'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel', 'MultiMenuBarUI', 'MultiMenuItemUI', 'MultiOptionPaneUI', 'MultiPanelUI', 'MultiPopupMenuUI', 'MultiProgressBarUI', 'MultiRootPaneUI', 'MultiScrollBarUI', 'MultiScrollPaneUI', 'MultiSeparatorUI', 'MultiSliderUI', 'MultiSpinnerUI', 'MultiSplitPaneUI', 'MultiTabbedPaneUI', 'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI', 'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI', 'MultiViewportUI'
+            ),
+        114 => array (
+            'ColorType', 'Region', 'SynthConstants', 'SynthContext', 'SynthGraphicsUtils', 'SynthLookAndFeel', 'SynthPainter', 'SynthStyle', 'SynthStyleFactory'
+            ),
+        115 => array (
+            'AbstractTableModel', 'DefaultTableCellRenderer', 'DefaultTableCellRenderer.UIResource', 'DefaultTableColumnModel', 'DefaultTableModel', 'JTableHeader', 'TableCellEditor', 'TableCellRenderer', 'TableColumn', 'TableColumnModel', 'TableModel'
+            ),
+        116 => array (
+            'AbstractDocument', 'AbstractDocument.AttributeContext', 'AbstractDocument.Content', 'AbstractDocument.ElementEdit', 'AbstractWriter', 'AsyncBoxView', 'AttributeSet.CharacterAttribute', 'AttributeSet.ColorAttribute', 'AttributeSet.FontAttribute', 'AttributeSet.ParagraphAttribute', 'BadLocationException', 'BoxView', 'Caret', 'ChangedCharSetException', 'ComponentView', 'CompositeView', 'DateFormatter', 'DefaultCaret', 'DefaultEditorKit', 'DefaultEditorKit.BeepAction', 'DefaultEditorKit.CopyAction', 'DefaultEditorKit.CutAction', 'DefaultEditorKit.DefaultKeyTypedAction', 'DefaultEditorKit.InsertBreakAction', 'DefaultEditorKit.InsertContentAction', 'DefaultEditorKit.InsertTabAction', 'DefaultEditorKit.PasteAction', 'DefaultFormatter', 'DefaultFormatterFactory', 'DefaultHighlighter', 'DefaultHighlighter.DefaultHighlightPainter', 'DefaultStyledDocument', 'DefaultStyledDocument.AttributeUndoableEdit', 'DefaultStyledDocument.ElementSpec', 'DefaultTextUI', 'DocumentFilter', 'DocumentFilter.FilterBypass',
+            'EditorKit', 'ElementIterator', 'FieldView', 'FlowView', 'FlowView.FlowStrategy', 'GapContent', 'GlyphView', 'GlyphView.GlyphPainter', 'Highlighter', 'Highlighter.Highlight', 'Highlighter.HighlightPainter', 'IconView', 'InternationalFormatter', 'JTextComponent', 'JTextComponent.KeyBinding', 'Keymap', 'LabelView', 'LayeredHighlighter', 'LayeredHighlighter.LayerPainter', 'LayoutQueue', 'MaskFormatter', 'MutableAttributeSet', 'NavigationFilter', 'NavigationFilter.FilterBypass', 'NumberFormatter', 'PasswordView', 'PlainDocument', 'PlainView', 'Position', 'Position.Bias', 'Segment', 'SimpleAttributeSet', 'StringContent', 'Style', 'StyleConstants', 'StyleConstants.CharacterConstants', 'StyleConstants.ColorConstants', 'StyleConstants.FontConstants', 'StyleConstants.ParagraphConstants', 'StyleContext', 'StyledDocument', 'StyledEditorKit', 'StyledEditorKit.AlignmentAction', 'StyledEditorKit.BoldAction', 'StyledEditorKit.FontFamilyAction', 'StyledEditorKit.FontSizeAction', 'StyledEditorKit.ForegroundAction',
+            'StyledEditorKit.ItalicAction', 'StyledEditorKit.StyledTextAction', 'StyledEditorKit.UnderlineAction', 'TabExpander', 'TabSet', 'TabStop', 'TabableView', 'TableView', 'TextAction', 'Utilities', 'View', 'ViewFactory', 'WrappedPlainView', 'ZoneView'
+            ),
+        117 => array (
+            'BlockView', 'CSS', 'CSS.Attribute', 'FormSubmitEvent', 'FormSubmitEvent.MethodType', 'FormView', 'HTML', 'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag', 'HTMLDocument', 'HTMLDocument.Iterator', 'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory', 'HTMLEditorKit.HTMLTextAction', 'HTMLEditorKit.InsertHTMLTextAction', 'HTMLEditorKit.LinkController', 'HTMLEditorKit.Parser', 'HTMLEditorKit.ParserCallback', 'HTMLFrameHyperlinkEvent', 'HTMLWriter', 'ImageView', 'InlineView', 'ListView', 'MinimalHTMLWriter', 'ObjectView', 'Option', 'StyleSheet', 'StyleSheet.BoxPainter', 'StyleSheet.ListPainter'
+            ),
+        118 => array (
+            'ContentModel', 'DTD', 'DTDConstants', 'DocumentParser', 'ParserDelegator', 'TagElement'
+            ),
+        119 => array (
+            'RTFEditorKit'
+            ),
+        120 => array (
+            'AbstractLayoutCache', 'AbstractLayoutCache.NodeDimensions', 'DefaultMutableTreeNode', 'DefaultTreeCellEditor', 'DefaultTreeCellRenderer', 'DefaultTreeModel', 'DefaultTreeSelectionModel', 'ExpandVetoException', 'FixedHeightLayoutCache', 'MutableTreeNode', 'RowMapper', 'TreeCellEditor', 'TreeCellRenderer', 'TreeModel', 'TreeNode', 'TreePath', 'TreeSelectionModel', 'VariableHeightLayoutCache'
+            ),
+        121 => array (
+            'AbstractUndoableEdit', 'CannotRedoException', 'CannotUndoException', 'CompoundEdit', 'StateEdit', 'StateEditable', 'UndoManager', 'UndoableEdit', 'UndoableEditSupport'
+            ),
+        122 => array (
+            'InvalidTransactionException', 'TransactionRequiredException', 'TransactionRolledbackException'
+            ),
+        123 => array (
+            'XAException', 'XAResource', 'Xid'
+            ),
+        124 => array (
+            'XMLConstants'
+            ),
+        125 => array (
+            'DatatypeConfigurationException', 'DatatypeConstants', 'DatatypeConstants.Field', 'DatatypeFactory', 'Duration', 'XMLGregorianCalendar'
+            ),
+        126 => array (
+            'NamespaceContext', 'QName'
+            ),
+        127 => array (
+            'DocumentBuilder', 'DocumentBuilderFactory', 'FactoryConfigurationError', 'ParserConfigurationException', 'SAXParser', 'SAXParserFactory'
+            ),
+        128 => array (
+            'ErrorListener', 'OutputKeys', 'Result', 'Source', 'SourceLocator', 'Templates', 'Transformer', 'TransformerConfigurationException', 'TransformerException', 'TransformerFactory', 'TransformerFactoryConfigurationError', 'URIResolver'
+            ),
+        129 => array (
+            'DOMResult', 'DOMSource'
+            ),
+        130 => array (
+            'SAXResult', 'SAXSource', 'SAXTransformerFactory', 'TemplatesHandler', 'TransformerHandler'
+            ),
+        131 => array (
+            'StreamResult', 'StreamSource'
+            ),
+        132 => array (
+            'Schema', 'SchemaFactory', 'SchemaFactoryLoader', 'TypeInfoProvider', 'Validator', 'ValidatorHandler'
+            ),
+        133 => array (
+            'XPath', 'XPathConstants', 'XPathException', 'XPathExpression', 'XPathExpressionException', 'XPathFactory', 'XPathFactoryConfigurationException', 'XPathFunction', 'XPathFunctionException', 'XPathFunctionResolver', 'XPathVariableResolver'
+            ),
+        134 => array (
+            'ChannelBinding', 'GSSContext', 'GSSCredential', 'GSSException', 'GSSManager', 'GSSName', 'MessageProp', 'Oid'
+            ),
+        135 => array (
+            'ACTIVITY_COMPLETED', 'ACTIVITY_REQUIRED', 'ARG_IN', 'ARG_INOUT', 'ARG_OUT', 'Any', 'AnyHolder', 'AnySeqHolder', 'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION', 'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE', 'BAD_POLICY_VALUE', 'BAD_QOS', 'BAD_TYPECODE', 'BooleanHolder', 'BooleanSeqHelper', 'BooleanSeqHolder', 'ByteHolder', 'CODESET_INCOMPATIBLE', 'COMM_FAILURE', 'CTX_RESTRICT_SCOPE', 'CharHolder', 'CharSeqHelper', 'CharSeqHolder', 'CompletionStatus', 'CompletionStatusHelper', 'ContextList', 'CurrentHolder', 'CustomMarshal', 'DATA_CONVERSION', 'DefinitionKind', 'DefinitionKindHelper', 'DomainManager', 'DomainManagerOperations', 'DoubleHolder', 'DoubleSeqHelper', 'DoubleSeqHolder', 'Environment', 'ExceptionList', 'FREE_MEM', 'FixedHolder', 'FloatHolder', 'FloatSeqHelper', 'FloatSeqHolder', 'IDLType', 'IDLTypeHelper', 'IDLTypeOperations', 'IMP_LIMIT', 'INITIALIZE', 'INTERNAL', 'INTF_REPOS', 'INVALID_ACTIVITY', 'INVALID_TRANSACTION', 'INV_FLAG', 'INV_IDENT', 'INV_OBJREF', 'INV_POLICY', 'IRObject',
+            'IRObjectOperations', 'IdentifierHelper', 'IntHolder', 'LocalObject', 'LongHolder', 'LongLongSeqHelper', 'LongLongSeqHolder', 'LongSeqHelper', 'LongSeqHolder', 'MARSHAL', 'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION', 'NO_RESOURCES', 'NO_RESPONSE', 'NVList', 'NamedValue', 'OBJECT_NOT_EXIST', 'OBJ_ADAPTER', 'OMGVMCID', 'ObjectHelper', 'ObjectHolder', 'OctetSeqHelper', 'OctetSeqHolder', 'PERSIST_STORE', 'PRIVATE_MEMBER', 'PUBLIC_MEMBER', 'ParameterMode', 'ParameterModeHelper', 'ParameterModeHolder', 'PolicyError', 'PolicyErrorCodeHelper', 'PolicyErrorHelper', 'PolicyErrorHolder', 'PolicyHelper', 'PolicyHolder', 'PolicyListHelper', 'PolicyListHolder', 'PolicyOperations', 'PolicyTypeHelper', 'PrincipalHolder', 'REBIND', 'RepositoryIdHelper', 'Request', 'ServerRequest', 'ServiceDetail', 'ServiceDetailHelper', 'ServiceInformation', 'ServiceInformationHelper', 'ServiceInformationHolder', 'SetOverrideType', 'SetOverrideTypeHelper', 'ShortHolder', 'ShortSeqHelper', 'ShortSeqHolder', 'StringHolder',
+            'StringSeqHelper', 'StringSeqHolder', 'StringValueHelper', 'StructMember', 'StructMemberHelper', 'SystemException', 'TCKind', 'TIMEOUT', 'TRANSACTION_MODE', 'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK', 'TRANSACTION_UNAVAILABLE', 'TRANSIENT', 'TypeCode', 'TypeCodeHolder', 'ULongLongSeqHelper', 'ULongLongSeqHolder', 'ULongSeqHelper', 'ULongSeqHolder', 'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE', 'UShortSeqHelper', 'UShortSeqHolder', 'UnionMember', 'UnionMemberHelper', 'UnknownUserException', 'UnknownUserExceptionHelper', 'UnknownUserExceptionHolder', 'UserException', 'VM_ABSTRACT', 'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE', 'ValueBaseHelper', 'ValueBaseHolder', 'ValueMember', 'ValueMemberHelper', 'VersionSpecHelper', 'VisibilityHelper', 'WCharSeqHelper', 'WCharSeqHolder', 'WStringSeqHelper', 'WStringSeqHolder', 'WStringValueHelper', 'WrongTransaction', 'WrongTransactionHelper', 'WrongTransactionHolder', '_IDLTypeStub', '_PolicyStub'
+            ),
+        136 => array (
+            'Invalid', 'InvalidSeq'
+            ),
+        137 => array (
+            'BadKind'
+            ),
+        138 => array (
+            'ApplicationException', 'BoxedValueHelper', 'CustomValue', 'IDLEntity', 'IndirectionException', 'InvokeHandler', 'RemarshalException', 'ResponseHandler', 'ServantObject', 'Streamable', 'StreamableValue', 'UnknownException', 'ValueBase', 'ValueFactory', 'ValueInputStream', 'ValueOutputStream'
+            ),
+        139 => array (
+            'BindingHelper', 'BindingHolder', 'BindingIterator', 'BindingIteratorHelper', 'BindingIteratorHolder', 'BindingIteratorOperations', 'BindingIteratorPOA', 'BindingListHelper', 'BindingListHolder', 'BindingType', 'BindingTypeHelper', 'BindingTypeHolder', 'IstringHelper', 'NameComponent', 'NameComponentHelper', 'NameComponentHolder', 'NameHelper', 'NameHolder', 'NamingContext', 'NamingContextExt', 'NamingContextExtHelper', 'NamingContextExtHolder', 'NamingContextExtOperations', 'NamingContextExtPOA', 'NamingContextHelper', 'NamingContextHolder', 'NamingContextOperations', 'NamingContextPOA', '_BindingIteratorImplBase', '_BindingIteratorStub', '_NamingContextExtStub', '_NamingContextImplBase', '_NamingContextStub'
+            ),
+        140 => array (
+            'AddressHelper', 'InvalidAddress', 'InvalidAddressHelper', 'InvalidAddressHolder', 'StringNameHelper', 'URLStringHelper'
+            ),
+        141 => array (
+            'AlreadyBound', 'AlreadyBoundHelper', 'AlreadyBoundHolder', 'CannotProceed', 'CannotProceedHelper', 'CannotProceedHolder', 'InvalidNameHolder', 'NotEmpty', 'NotEmptyHelper', 'NotEmptyHolder', 'NotFound', 'NotFoundHelper', 'NotFoundHolder', 'NotFoundReason', 'NotFoundReasonHelper', 'NotFoundReasonHolder'
+            ),
+        142 => array (
+            'Parameter'
+            ),
+        143 => array (
+            'DynAnyFactory', 'DynAnyFactoryHelper', 'DynAnyFactoryOperations', 'DynAnyHelper', 'DynAnyOperations', 'DynAnySeqHelper', 'DynArrayHelper', 'DynArrayOperations', 'DynEnumHelper', 'DynEnumOperations', 'DynFixedHelper', 'DynFixedOperations', 'DynSequenceHelper', 'DynSequenceOperations', 'DynStructHelper', 'DynStructOperations', 'DynUnionHelper', 'DynUnionOperations', 'DynValueBox', 'DynValueBoxOperations', 'DynValueCommon', 'DynValueCommonOperations', 'DynValueHelper', 'DynValueOperations', 'NameDynAnyPair', 'NameDynAnyPairHelper', 'NameDynAnyPairSeqHelper', 'NameValuePairSeqHelper', '_DynAnyFactoryStub', '_DynAnyStub', '_DynArrayStub', '_DynEnumStub', '_DynFixedStub', '_DynSequenceStub', '_DynStructStub', '_DynUnionStub', '_DynValueStub'
+            ),
+        144 => array (
+            'InconsistentTypeCodeHelper'
+            ),
+        145 => array (
+            'InvalidValueHelper'
+            ),
+        146 => array (
+            'CodeSets', 'Codec', 'CodecFactory', 'CodecFactoryHelper', 'CodecFactoryOperations', 'CodecOperations', 'ComponentIdHelper', 'ENCODING_CDR_ENCAPS', 'Encoding', 'ExceptionDetailMessage', 'IOR', 'IORHelper', 'IORHolder', 'MultipleComponentProfileHelper', 'MultipleComponentProfileHolder', 'ProfileIdHelper', 'RMICustomMaxStreamFormat', 'ServiceContext', 'ServiceContextHelper', 'ServiceContextHolder', 'ServiceContextListHelper', 'ServiceContextListHolder', 'ServiceIdHelper', 'TAG_ALTERNATE_IIOP_ADDRESS', 'TAG_CODE_SETS', 'TAG_INTERNET_IOP', 'TAG_JAVA_CODEBASE', 'TAG_MULTIPLE_COMPONENTS', 'TAG_ORB_TYPE', 'TAG_POLICIES', 'TAG_RMI_CUSTOM_MAX_STREAM_FORMAT', 'TaggedComponent', 'TaggedComponentHelper', 'TaggedComponentHolder', 'TaggedProfile', 'TaggedProfileHelper', 'TaggedProfileHolder', 'TransactionService'
+            ),
+        147 => array (
+            'UnknownEncoding', 'UnknownEncodingHelper'
+            ),
+        148 => array (
+            'FormatMismatch', 'FormatMismatchHelper', 'InvalidTypeForEncoding', 'InvalidTypeForEncodingHelper'
+            ),
+        149 => array (
+            'SYNC_WITH_TRANSPORT', 'SyncScopeHelper'
+            ),
+        150 => array (
+            'ACTIVE', 'AdapterManagerIdHelper', 'AdapterNameHelper', 'AdapterStateHelper', 'ClientRequestInfo', 'ClientRequestInfoOperations', 'ClientRequestInterceptor', 'ClientRequestInterceptorOperations', 'DISCARDING', 'HOLDING', 'INACTIVE', 'IORInfo', 'IORInfoOperations', 'IORInterceptor', 'IORInterceptorOperations', 'IORInterceptor_3_0', 'IORInterceptor_3_0Helper', 'IORInterceptor_3_0Holder', 'IORInterceptor_3_0Operations', 'Interceptor', 'InterceptorOperations', 'InvalidSlot', 'InvalidSlotHelper', 'LOCATION_FORWARD', 'NON_EXISTENT', 'ORBIdHelper', 'ORBInitInfo', 'ORBInitInfoOperations', 'ORBInitializer', 'ORBInitializerOperations', 'ObjectReferenceFactory', 'ObjectReferenceFactoryHelper', 'ObjectReferenceFactoryHolder', 'ObjectReferenceTemplate', 'ObjectReferenceTemplateHelper', 'ObjectReferenceTemplateHolder', 'ObjectReferenceTemplateSeqHelper', 'ObjectReferenceTemplateSeqHolder', 'PolicyFactory', 'PolicyFactoryOperations', 'RequestInfo', 'RequestInfoOperations', 'SUCCESSFUL', 'SYSTEM_EXCEPTION',
+            'ServerIdHelper', 'ServerRequestInfo', 'ServerRequestInfoOperations', 'ServerRequestInterceptor', 'ServerRequestInterceptorOperations', 'TRANSPORT_RETRY', 'USER_EXCEPTION'
+            ),
+        151 => array (
+            'DuplicateName', 'DuplicateNameHelper'
+            ),
+        152 => array (
+            'AdapterActivator', 'AdapterActivatorOperations', 'ID_ASSIGNMENT_POLICY_ID', 'ID_UNIQUENESS_POLICY_ID', 'IMPLICIT_ACTIVATION_POLICY_ID', 'IdAssignmentPolicy', 'IdAssignmentPolicyOperations', 'IdAssignmentPolicyValue', 'IdUniquenessPolicy', 'IdUniquenessPolicyOperations', 'IdUniquenessPolicyValue', 'ImplicitActivationPolicy', 'ImplicitActivationPolicyOperations', 'ImplicitActivationPolicyValue', 'LIFESPAN_POLICY_ID', 'LifespanPolicy', 'LifespanPolicyOperations', 'LifespanPolicyValue', 'POA', 'POAHelper', 'POAManager', 'POAManagerOperations', 'POAOperations', 'REQUEST_PROCESSING_POLICY_ID', 'RequestProcessingPolicy', 'RequestProcessingPolicyOperations', 'RequestProcessingPolicyValue', 'SERVANT_RETENTION_POLICY_ID', 'Servant', 'ServantActivator', 'ServantActivatorHelper', 'ServantActivatorOperations', 'ServantActivatorPOA', 'ServantLocator', 'ServantLocatorHelper', 'ServantLocatorOperations', 'ServantLocatorPOA', 'ServantManager', 'ServantManagerOperations', 'ServantRetentionPolicy',
+            'ServantRetentionPolicyOperations', 'ServantRetentionPolicyValue', 'THREAD_POLICY_ID', 'ThreadPolicy', 'ThreadPolicyOperations', 'ThreadPolicyValue', '_ServantActivatorStub', '_ServantLocatorStub'
+            ),
+        153 => array (
+            'NoContext', 'NoContextHelper'
+            ),
+        154 => array (
+            'AdapterInactive', 'AdapterInactiveHelper', 'State'
+            ),
+        155 => array (
+            'AdapterAlreadyExists', 'AdapterAlreadyExistsHelper', 'AdapterNonExistent', 'AdapterNonExistentHelper', 'InvalidPolicy', 'InvalidPolicyHelper', 'NoServant', 'NoServantHelper', 'ObjectAlreadyActive', 'ObjectAlreadyActiveHelper', 'ObjectNotActive', 'ObjectNotActiveHelper', 'ServantAlreadyActive', 'ServantAlreadyActiveHelper', 'ServantNotActive', 'ServantNotActiveHelper', 'WrongAdapter', 'WrongAdapterHelper', 'WrongPolicy', 'WrongPolicyHelper'
+            ),
+        156 => array (
+            'CookieHolder'
+            ),
+        157 => array (
+            'RunTime', 'RunTimeOperations'
+            ),
+        158 => array (
+            '_Remote_Stub'
+            ),
+        159 => array (
+            'Attr', 'CDATASection', 'CharacterData', 'Comment', 'DOMConfiguration', 'DOMError', 'DOMErrorHandler', 'DOMException', 'DOMImplementation', 'DOMImplementationList', 'DOMImplementationSource', 'DOMStringList', 'DocumentFragment', 'DocumentType', 'EntityReference', 'NameList', 'NamedNodeMap', 'Node', 'NodeList', 'Notation', 'ProcessingInstruction', 'Text', 'TypeInfo', 'UserDataHandler'
+            ),
+        160 => array (
+            'DOMImplementationRegistry'
+            ),
+        161 => array (
+            'EventException', 'EventTarget', 'MutationEvent', 'UIEvent'
+            ),
+        162 => array (
+            'DOMImplementationLS', 'LSException', 'LSInput', 'LSLoadEvent', 'LSOutput', 'LSParser', 'LSParserFilter', 'LSProgressEvent', 'LSResourceResolver', 'LSSerializer', 'LSSerializerFilter'
+            ),
+        163 => array (
+            'DTDHandler', 'DocumentHandler', 'EntityResolver', 'ErrorHandler', 'HandlerBase', 'InputSource', 'Locator', 'SAXException', 'SAXNotRecognizedException', 'SAXNotSupportedException', 'SAXParseException', 'XMLFilter', 'XMLReader'
+            ),
+        164 => array (
+            'Attributes2', 'Attributes2Impl', 'DeclHandler', 'DefaultHandler2', 'EntityResolver2', 'LexicalHandler', 'Locator2', 'Locator2Impl'
+            ),
+        165 => array (
+            'AttributeListImpl', 'AttributesImpl', 'DefaultHandler', 'LocatorImpl', 'NamespaceSupport', 'ParserAdapter', 'ParserFactory', 'XMLFilterImpl', 'XMLReaderAdapter', 'XMLReaderFactory'
+            ),
+        /* ambiguous class names (appear in more than one package) */
+        166 => array (
+            'Annotation', 'AnySeqHelper', 'Array', 'Attribute', 'AttributeList', 'AttributeSet', 'Attributes', 'AuthenticationException', 'Binding', 'Bounds', 'Certificate', 'CertificateEncodingException', 'CertificateException', 'CertificateExpiredException', 'CertificateNotYetValidException', 'CertificateParsingException', 'ConnectException', 'ContentHandler', 'Context', 'Control', 'Current', 'CurrentHelper', 'CurrentOperations', 'DOMLocator', 'DataInputStream', 'DataOutputStream', 'Date', 'DefaultLoaderRepository', 'Delegate', 'Document', 'DocumentEvent', 'DynAny', 'DynArray', 'DynEnum', 'DynFixed', 'DynSequence', 'DynStruct', 'DynUnion', 'DynValue', 'DynamicImplementation', 'Element', 'Entity', 'Event', 'EventListener', 'FieldNameHelper', 'FileFilter', 'Formatter', 'ForwardRequest', 'ForwardRequestHelper', 'InconsistentTypeCode', 'InputStream', 'IntrospectionException', 'InvalidAttributeValueException', 'InvalidKeyException', 'InvalidName', 'InvalidNameHelper', 'InvalidValue', 'List', 'MouseEvent',
+            'NameValuePair', 'NameValuePairHelper', 'ORB', 'Object', 'ObjectIdHelper', 'ObjectImpl', 'OpenType', 'OutputStream', 'ParagraphView', 'Parser', 'Permission', 'Policy', 'Principal', 'Proxy', 'Reference', 'Statement', 'Timer', 'Timestamp', 'TypeMismatch', 'TypeMismatchHelper', 'UNKNOWN', 'UnknownHostException', 'X509Certificate'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        /* all Java keywords are case sensitive */
+        1 => true, 2 => true, 3 => true, 4 => true,
+        5 => true, 6 => true, 7 => true, 8 => true, 9 => true,
+        10 => true, 11 => true, 12 => true, 13 => true, 14 => true,
+        15 => true, 16 => true, 17 => true, 18 => true, 19 => true,
+        20 => true, 21 => true, 22 => true, 23 => true, 24 => true,
+        25 => true, 26 => true, 27 => true, 28 => true, 29 => true,
+        30 => true, 31 => true, 32 => true, 33 => true, 34 => true,
+        35 => true, 36 => true, 37 => true, 38 => true, 39 => true,
+        40 => true, 41 => true, 42 => true, 43 => true, 44 => true,
+        45 => true, 46 => true, 47 => true, 48 => true, 49 => true,
+        50 => true, 51 => true, 52 => true, 53 => true, 54 => true,
+        55 => true, 56 => true, 57 => true, 58 => true, 59 => true,
+        60 => true, 61 => true, 62 => true, 63 => true, 64 => true,
+        65 => true, 66 => true, 67 => true, 68 => true, 69 => true,
+        70 => true, 71 => true, 72 => true, 73 => true, 74 => true,
+        75 => true, 76 => true, 77 => true, 78 => true, 79 => true,
+        80 => true, 81 => true, 82 => true, 83 => true, 84 => true,
+        85 => true, 86 => true, 87 => true, 88 => true, 89 => true,
+        90 => true, 91 => true, 92 => true, 93 => true, 94 => true,
+        95 => true, 96 => true, 97 => true, 98 => true, 99 => true,
+        100 => true, 101 => true, 102 => true, 103 => true, 104 => true,
+        105 => true, 106 => true, 107 => true, 108 => true, 109 => true,
+        110 => true, 111 => true, 112 => true, 113 => true, 114 => true,
+        115 => true, 116 => true, 117 => true, 118 => true, 119 => true,
+        120 => true, 121 => true, 122 => true, 123 => true, 124 => true,
+        125 => true, 126 => true, 127 => true, 128 => true, 129 => true,
+        130 => true, 131 => true, 132 => true, 133 => true, 134 => true,
+        135 => true, 136 => true, 137 => true, 138 => true, 139 => true,
+        140 => true, 141 => true, 142 => true, 143 => true, 144 => true,
+        145 => true, 146 => true, 147 => true, 148 => true, 149 => true,
+        150 => true, 151 => true, 152 => true, 153 => true, 154 => true,
+        155 => true, 156 => true, 157 => true, 158 => true, 159 => true,
+        160 => true, 161 => true, 162 => true, 163 => true, 164 => true,
+        165 => true, 166 => true
+    ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000;  font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #006600; font-weight: bold;',
+            4 => 'color: #006600; font-weight: bold;',
+            5 => 'color: #003399; font-weight: bold;',
+            6 => 'color: #003399; font-weight: bold;',
+            7 => 'color: #003399; font-weight: bold;',
+            8 => 'color: #003399; font-weight: bold;',
+            9 => 'color: #003399; font-weight: bold;',
+            10 => 'color: #003399; font-weight: bold;',
+            11 => 'color: #003399; font-weight: bold;',
+            12 => 'color: #003399; font-weight: bold;',
+            13 => 'color: #003399; font-weight: bold;',
+            14 => 'color: #003399; font-weight: bold;',
+            15 => 'color: #003399; font-weight: bold;',
+            16 => 'color: #003399; font-weight: bold;',
+            17 => 'color: #003399; font-weight: bold;',
+            18 => 'color: #003399; font-weight: bold;',
+            19 => 'color: #003399; font-weight: bold;',
+            20 => 'color: #003399; font-weight: bold;',
+            21 => 'color: #003399; font-weight: bold;',
+            22 => 'color: #003399; font-weight: bold;',
+            23 => 'color: #003399; font-weight: bold;',
+            24 => 'color: #003399; font-weight: bold;',
+            25 => 'color: #003399; font-weight: bold;',
+            26 => 'color: #003399; font-weight: bold;',
+            27 => 'color: #003399; font-weight: bold;',
+            28 => 'color: #003399; font-weight: bold;',
+            29 => 'color: #003399; font-weight: bold;',
+            30 => 'color: #003399; font-weight: bold;',
+            31 => 'color: #003399; font-weight: bold;',
+            32 => 'color: #003399; font-weight: bold;',
+            33 => 'color: #003399; font-weight: bold;',
+            34 => 'color: #003399; font-weight: bold;',
+            35 => 'color: #003399; font-weight: bold;',
+            36 => 'color: #003399; font-weight: bold;',
+            37 => 'color: #003399; font-weight: bold;',
+            38 => 'color: #003399; font-weight: bold;',
+            39 => 'color: #003399; font-weight: bold;',
+            40 => 'color: #003399; font-weight: bold;',
+            41 => 'color: #003399; font-weight: bold;',
+            42 => 'color: #003399; font-weight: bold;',
+            43 => 'color: #003399; font-weight: bold;',
+            44 => 'color: #003399; font-weight: bold;',
+            45 => 'color: #003399; font-weight: bold;',
+            46 => 'color: #003399; font-weight: bold;',
+            47 => 'color: #003399; font-weight: bold;',
+            48 => 'color: #003399; font-weight: bold;',
+            49 => 'color: #003399; font-weight: bold;',
+            50 => 'color: #003399; font-weight: bold;',
+            51 => 'color: #003399; font-weight: bold;',
+            52 => 'color: #003399; font-weight: bold;',
+            53 => 'color: #003399; font-weight: bold;',
+            54 => 'color: #003399; font-weight: bold;',
+            55 => 'color: #003399; font-weight: bold;',
+            56 => 'color: #003399; font-weight: bold;',
+            57 => 'color: #003399; font-weight: bold;',
+            58 => 'color: #003399; font-weight: bold;',
+            59 => 'color: #003399; font-weight: bold;',
+            60 => 'color: #003399; font-weight: bold;',
+            61 => 'color: #003399; font-weight: bold;',
+            62 => 'color: #003399; font-weight: bold;',
+            63 => 'color: #003399; font-weight: bold;',
+            64 => 'color: #003399; font-weight: bold;',
+            65 => 'color: #003399; font-weight: bold;',
+            66 => 'color: #003399; font-weight: bold;',
+            67 => 'color: #003399; font-weight: bold;',
+            68 => 'color: #003399; font-weight: bold;',
+            69 => 'color: #003399; font-weight: bold;',
+            70 => 'color: #003399; font-weight: bold;',
+            71 => 'color: #003399; font-weight: bold;',
+            72 => 'color: #003399; font-weight: bold;',
+            73 => 'color: #003399; font-weight: bold;',
+            74 => 'color: #003399; font-weight: bold;',
+            75 => 'color: #003399; font-weight: bold;',
+            76 => 'color: #003399; font-weight: bold;',
+            77 => 'color: #003399; font-weight: bold;',
+            78 => 'color: #003399; font-weight: bold;',
+            79 => 'color: #003399; font-weight: bold;',
+            80 => 'color: #003399; font-weight: bold;',
+            81 => 'color: #003399; font-weight: bold;',
+            82 => 'color: #003399; font-weight: bold;',
+            83 => 'color: #003399; font-weight: bold;',
+            84 => 'color: #003399; font-weight: bold;',
+            85 => 'color: #003399; font-weight: bold;',
+            86 => 'color: #003399; font-weight: bold;',
+            87 => 'color: #003399; font-weight: bold;',
+            88 => 'color: #003399; font-weight: bold;',
+            89 => 'color: #003399; font-weight: bold;',
+            90 => 'color: #003399; font-weight: bold;',
+            91 => 'color: #003399; font-weight: bold;',
+            92 => 'color: #003399; font-weight: bold;',
+            93 => 'color: #003399; font-weight: bold;',
+            94 => 'color: #003399; font-weight: bold;',
+            95 => 'color: #003399; font-weight: bold;',
+            96 => 'color: #003399; font-weight: bold;',
+            97 => 'color: #003399; font-weight: bold;',
+            98 => 'color: #003399; font-weight: bold;',
+            99 => 'color: #003399; font-weight: bold;',
+            100 => 'color: #003399; font-weight: bold;',
+            101 => 'color: #003399; font-weight: bold;',
+            102 => 'color: #003399; font-weight: bold;',
+            103 => 'color: #003399; font-weight: bold;',
+            104 => 'color: #003399; font-weight: bold;',
+            105 => 'color: #003399; font-weight: bold;',
+            106 => 'color: #003399; font-weight: bold;',
+            107 => 'color: #003399; font-weight: bold;',
+            108 => 'color: #003399; font-weight: bold;',
+            109 => 'color: #003399; font-weight: bold;',
+            110 => 'color: #003399; font-weight: bold;',
+            111 => 'color: #003399; font-weight: bold;',
+            112 => 'color: #003399; font-weight: bold;',
+            113 => 'color: #003399; font-weight: bold;',
+            114 => 'color: #003399; font-weight: bold;',
+            115 => 'color: #003399; font-weight: bold;',
+            116 => 'color: #003399; font-weight: bold;',
+            117 => 'color: #003399; font-weight: bold;',
+            118 => 'color: #003399; font-weight: bold;',
+            119 => 'color: #003399; font-weight: bold;',
+            120 => 'color: #003399; font-weight: bold;',
+            121 => 'color: #003399; font-weight: bold;',
+            122 => 'color: #003399; font-weight: bold;',
+            123 => 'color: #003399; font-weight: bold;',
+            124 => 'color: #003399; font-weight: bold;',
+            125 => 'color: #003399; font-weight: bold;',
+            126 => 'color: #003399; font-weight: bold;',
+            127 => 'color: #003399; font-weight: bold;',
+            128 => 'color: #003399; font-weight: bold;',
+            129 => 'color: #003399; font-weight: bold;',
+            130 => 'color: #003399; font-weight: bold;',
+            131 => 'color: #003399; font-weight: bold;',
+            132 => 'color: #003399; font-weight: bold;',
+            133 => 'color: #003399; font-weight: bold;',
+            134 => 'color: #003399; font-weight: bold;',
+            135 => 'color: #003399; font-weight: bold;',
+            136 => 'color: #003399; font-weight: bold;',
+            137 => 'color: #003399; font-weight: bold;',
+            138 => 'color: #003399; font-weight: bold;',
+            139 => 'color: #003399; font-weight: bold;',
+            140 => 'color: #003399; font-weight: bold;',
+            141 => 'color: #003399; font-weight: bold;',
+            142 => 'color: #003399; font-weight: bold;',
+            143 => 'color: #003399; font-weight: bold;',
+            144 => 'color: #003399; font-weight: bold;',
+            145 => 'color: #003399; font-weight: bold;',
+            146 => 'color: #003399; font-weight: bold;',
+            147 => 'color: #003399; font-weight: bold;',
+            148 => 'color: #003399; font-weight: bold;',
+            149 => 'color: #003399; font-weight: bold;',
+            150 => 'color: #003399; font-weight: bold;',
+            151 => 'color: #003399; font-weight: bold;',
+            152 => 'color: #003399; font-weight: bold;',
+            153 => 'color: #003399; font-weight: bold;',
+            154 => 'color: #003399; font-weight: bold;',
+            155 => 'color: #003399; font-weight: bold;',
+            156 => 'color: #003399; font-weight: bold;',
+            157 => 'color: #003399; font-weight: bold;',
+            158 => 'color: #003399; font-weight: bold;',
+            159 => 'color: #003399; font-weight: bold;',
+            160 => 'color: #003399; font-weight: bold;',
+            161 => 'color: #003399; font-weight: bold;',
+            162 => 'color: #003399; font-weight: bold;',
+            163 => 'color: #003399; font-weight: bold;',
+            164 => 'color: #003399; font-weight: bold;',
+            165 => 'color: #003399; font-weight: bold;',
+            166 => 'color: #003399; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #006699;',
+            3 => 'color: #008000; font-style: italic; font-weight: bold;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006633;',
+            2 => 'color: #006633;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/applet/{FNAME}.html',
+        6 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/{FNAME}.html',
+        7 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/color/{FNAME}.html',
+        8 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/datatransfer/{FNAME}.html',
+        9 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/dnd/{FNAME}.html',
+        10 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/event/{FNAME}.html',
+        11 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/font/{FNAME}.html',
+        12 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/{FNAME}.html',
+        13 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/im/{FNAME}.html',
+        14 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/im/spi/{FNAME}.html',
+        15 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/{FNAME}.html',
+        16 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/renderable/{FNAME}.html',
+        17 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/awt/print/{FNAME}.html',
+        18 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/beans/{FNAME}.html',
+        19 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/beans/beancontext/{FNAME}.html',
+        20 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/io/{FNAME}.html',
+        21 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/lang/{FNAME}.html',
+        22 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/{FNAME}.html',
+        23 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/{FNAME}.html',
+        24 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/{FNAME}.html',
+        25 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ref/{FNAME}.html',
+        26 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/{FNAME}.html',
+        27 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/math/{FNAME}.html',
+        28 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/net/{FNAME}.html',
+        29 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/nio/{FNAME}.html',
+        30 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/{FNAME}.html',
+        31 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/spi/{FNAME}.html',
+        32 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/{FNAME}.html',
+        33 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/nio/charset/spi/{FNAME}.html',
+        34 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/{FNAME}.html',
+        35 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/activation/{FNAME}.html',
+        36 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/dgc/{FNAME}.html',
+        37 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/registry/{FNAME}.html',
+        38 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/server/{FNAME}.html',
+        39 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/security/{FNAME}.html',
+        40 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/security/acl/{FNAME}.html',
+        41 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/security/cert/{FNAME}.html',
+        42 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/security/interfaces/{FNAME}.html',
+        43 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/security/spec/{FNAME}.html',
+        44 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/sql/{FNAME}.html',
+        45 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/text/{FNAME}.html',
+        46 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/{FNAME}.html',
+        47 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/{FNAME}.html',
+        48 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/{FNAME}.html',
+        49 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/{FNAME}.html',
+        50 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/jar/{FNAME}.html',
+        51 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/logging/{FNAME}.html',
+        52 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/prefs/{FNAME}.html',
+        53 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/{FNAME}.html',
+        54 => 'http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/{FNAME}.html',
+        55 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/accessibility/{FNAME}.html',
+        56 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/activity/{FNAME}.html',
+        57 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/crypto/{FNAME}.html',
+        58 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/crypto/interfaces/{FNAME}.html',
+        59 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/crypto/spec/{FNAME}.html',
+        60 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/{FNAME}.html',
+        61 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/event/{FNAME}.html',
+        62 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/metadata/{FNAME}.html',
+        63 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/plugins/bmp/{FNAME}.html',
+        64 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/plugins/jpeg/{FNAME}.html',
+        65 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/spi/{FNAME}.html',
+        66 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/stream/{FNAME}.html',
+        67 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/{FNAME}.html',
+        68 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/loading/{FNAME}.html',
+        69 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/modelmbean/{FNAME}.html',
+        70 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/monitor/{FNAME}.html',
+        71 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/openmbean/{FNAME}.html',
+        72 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/relation/{FNAME}.html',
+        73 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/{FNAME}.html',
+        74 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/remote/rmi/{FNAME}.html',
+        75 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/management/timer/{FNAME}.html',
+        76 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/{FNAME}.html',
+        77 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/directory/{FNAME}.html',
+        78 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/event/{FNAME}.html',
+        79 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/ldap/{FNAME}.html',
+        80 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/naming/spi/{FNAME}.html',
+        81 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/net/{FNAME}.html',
+        82 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/{FNAME}.html',
+        83 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/print/{FNAME}.html',
+        84 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/print/attribute/{FNAME}.html',
+        85 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/print/attribute/standard/{FNAME}.html',
+        86 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/print/event/{FNAME}.html',
+        87 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/rmi/{FNAME}.html',
+        88 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/rmi/CORBA/{FNAME}.html',
+        89 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/rmi/ssl/{FNAME}.html',
+        90 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/{FNAME}.html',
+        91 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/callback/{FNAME}.html',
+        92 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/kerberos/{FNAME}.html',
+        93 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/{FNAME}.html',
+        94 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/spi/{FNAME}.html',
+        95 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/x500/{FNAME}.html',
+        96 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/security/sasl/{FNAME}.html',
+        97 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/midi/{FNAME}.html',
+        98 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/midi/spi/{FNAME}.html',
+        99 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/sampled/{FNAME}.html',
+        100 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sound/sampled/spi/{FNAME}.html',
+        101 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/{FNAME}.html',
+        102 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/rowset/{FNAME}.html',
+        103 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/rowset/serial/{FNAME}.html',
+        104 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/rowset/spi/{FNAME}.html',
+        105 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/{FNAME}.html',
+        106 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/border/{FNAME}.html',
+        107 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/colorchooser/{FNAME}.html',
+        108 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/event/{FNAME}.html',
+        109 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/filechooser/{FNAME}.html',
+        110 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/plaf/{FNAME}.html',
+        111 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/plaf/basic/{FNAME}.html',
+        112 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/plaf/metal/{FNAME}.html',
+        113 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/plaf/multi/{FNAME}.html',
+        114 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/plaf/synth/{FNAME}.html',
+        115 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/{FNAME}.html',
+        116 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/{FNAME}.html',
+        117 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/{FNAME}.html',
+        118 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/parser/{FNAME}.html',
+        119 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/rtf/{FNAME}.html',
+        120 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/tree/{FNAME}.html',
+        121 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/undo/{FNAME}.html',
+        122 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/transaction/{FNAME}.html',
+        123 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/transaction/xa/{FNAME}.html',
+        124 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/{FNAME}.html',
+        125 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/datatype/{FNAME}.html',
+        126 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/namespace/{FNAME}.html',
+        127 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/parsers/{FNAME}.html',
+        128 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/transform/{FNAME}.html',
+        129 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/transform/dom/{FNAME}.html',
+        130 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/transform/sax/{FNAME}.html',
+        131 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/transform/stream/{FNAME}.html',
+        132 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/validation/{FNAME}.html',
+        133 => 'http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/{FNAME}.html',
+        134 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/ietf/jgss/{FNAME}.html',
+        135 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CORBA/{FNAME}.html',
+        136 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CORBA/DynAnyPackage/{FNAME}.html',
+        137 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CORBA/TypeCodePackage/{FNAME}.html',
+        138 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CORBA/portable/{FNAME}.html',
+        139 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CosNaming/{FNAME}.html',
+        140 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CosNaming/NamingContextExtPackage/{FNAME}.html',
+        141 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/CosNaming/NamingContextPackage/{FNAME}.html',
+        142 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/Dynamic/{FNAME}.html',
+        143 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/DynamicAny/{FNAME}.html',
+        144 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/DynamicAny/DynAnyFactoryPackage/{FNAME}.html',
+        145 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/DynamicAny/DynAnyPackage/{FNAME}.html',
+        146 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/IOP/{FNAME}.html',
+        147 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/IOP/CodecFactoryPackage/{FNAME}.html',
+        148 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/IOP/CodecPackage/{FNAME}.html',
+        149 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/Messaging/{FNAME}.html',
+        150 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableInterceptor/{FNAME}.html',
+        151 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableInterceptor/ORBInitInfoPackage/{FNAME}.html',
+        152 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableServer/{FNAME}.html',
+        153 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableServer/CurrentPackage/{FNAME}.html',
+        154 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableServer/POAManagerPackage/{FNAME}.html',
+        155 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableServer/POAPackage/{FNAME}.html',
+        156 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/PortableServer/ServantLocatorPackage/{FNAME}.html',
+        157 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/SendingContext/{FNAME}.html',
+        158 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/omg/stub/java/rmi/{FNAME}.html',
+        159 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/{FNAME}.html',
+        160 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/bootstrap/{FNAME}.html',
+        161 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/events/{FNAME}.html',
+        162 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/ls/{FNAME}.html',
+        163 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/{FNAME}.html',
+        164 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/ext/{FNAME}.html',
+        165 => 'http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/helpers/{FNAME}.html',
+        /* ambiguous class names (appear in more than one package) */
+        166 => 'http://www.google.com/search?sitesearch=java.sun.com&amp;q=allinurl%3Aj2se%2F1+5+0%2Fdocs%2Fapi+{FNAME}'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        /* Java does not use '::' */
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/javascript.php b/examples/includes/geshi/geshi/javascript.php
new file mode 100644 (file)
index 0000000..1232a8a
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+/*************************************************************************************
+ * javascript.php
+ * --------------
+ * Author: Ben Keen (ben.keen@gmail.com)
+ * Copyright: (c) 2004 Ben Keen (ben.keen@gmail.com), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/20
+ *
+ * JavaScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Javascript',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    //Regular Expressions
+    'COMMENT_REGEXP' => array(2 => "/(?<=[\\s^])s\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])m?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\,\\;\\)])/iU"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'as', 'break', 'case', 'catch', 'continue', 'decodeURI', 'delete', 'do',
+            'else', 'encodeURI', 'eval', 'finally', 'for', 'if', 'in', 'is', 'item',
+            'instanceof', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'void',
+            'while', 'write', 'with'
+            ),
+        2 => array(
+            'class', 'const', 'default', 'debugger', 'export', 'extends', 'false',
+            'function', 'import', 'namespace', 'new', 'null', 'package', 'private',
+            'protected', 'public', 'super', 'true', 'use', 'var'
+            ),
+        3 => array(
+            // common functions for Window object
+            'alert', 'back', 'blur', 'close', 'confirm', 'focus', 'forward', 'home',
+            'name', 'navigate', 'onblur', 'onerror', 'onfocus', 'onload', 'onmove',
+            'onresize', 'onunload', 'open', 'print', 'prompt', 'scroll', 'status',
+            'stop',
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}',
+        '+', '-', '*', '/', '%',
+        '!', '@', '&', '|', '^',
+        '<', '>', '=',
+        ',', ';', '?', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000066; font-weight: bold;',
+            2 => 'color: #003366; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #006600; font-style: italic;',
+            2 => 'color: #009966; font-style: italic;',
+            'MULTI' => 'color: #006600; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #3366CC;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #CC0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #660066;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<script type="text/javascript">' => '</script>'
+            ),
+        1 => array(
+            '<script language="javascript">' => '</script>'
+            )
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/kixtart.php b/examples/includes/geshi/geshi/kixtart.php
new file mode 100644 (file)
index 0000000..3b4dc4c
--- /dev/null
@@ -0,0 +1,329 @@
+<?php
+/*************************************************************************************
+ * kixtart.php
+ * --------
+ * Author: Riley McArdle (riley@glyff.net)
+ * Copyright: (c) 2007 Riley McArdle (http://www.glyff.net/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/08/31
+ *
+ * PHP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/08/31 (1.0.7.22)
+ *  -  First Release
+ *
+ * TODO (updated 2007/08/31)
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'KiXtart',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'While', 'Loop',
+            'Use',
+            'Small',
+            'Sleep',
+            'Shell',
+            'SetTime',
+            'SetM',
+            'SetL',
+            'Set',
+            'Select', 'Case',
+            'Run',
+            'Return',
+            'Redim',
+            'RD',
+            'Quit',
+            'Play',
+            'Move',
+            'MD',
+            'Include',
+            'If', 'Else', 'Endif',
+            'GoTo',
+            'GoSub',
+            'Go',
+            'Global',
+            'GetS',
+            'Get',
+            'Function', 'Endfunction',
+            'For', 'Next',
+            'Each',
+            'FlushKb',
+            'Exit',
+            'Do', 'Until',
+            'Display',
+            'Dim',
+            'Del',
+            'Debug',
+            'Copy',
+            'Cookie1',
+            'Color',
+            'CLS',
+            'CD',
+            'Call',
+            'Break',
+            'Big',
+            'Beep',
+            ),
+        2 => array(
+            '@Address',
+            '@Build',
+            '@Color',
+            '@Comment',
+            '@CPU',
+            '@CRLF',
+            '@CSD',
+            '@CurDir',
+            '@Date',
+            '@Day',
+            '@Domain',
+            '@DOS',
+            '@Error',
+            '@FullName',
+            '@HomeDir',
+            '@HomeDrive',
+            '@HomeShr',
+            '@HostName',
+            '@InWin',
+            '@IPaddressX',
+            '@KiX',
+            '@LanRoot',
+            '@LDomain',
+            '@LDrive',
+            '@LM',
+            '@LogonMode',
+            '@LongHomeDir',
+            '@LServer',
+            '@MaxPWAge',
+            '@MDayNo',
+            '@MHz',
+            '@MonthNo',
+            '@Month',
+            '@MSecs',
+            '@OnWoW64',
+            '@PID',
+            '@PrimaryGroup',
+            '@Priv',
+            '@ProductSuite',
+            '@ProductType',
+            '@PWAge',
+            '@RAS',
+            '@Result',
+            '@RServer',
+            '@ScriptDir',
+            '@ScriptExe',
+            '@ScriptName',
+            '@SError',
+            '@SID',
+            '@Site',
+            '@StartDir',
+            '@SysLang',
+            '@Ticks',
+            '@Time',
+            '@TsSession',
+            '@UserID',
+            '@UserLang',
+            '@WDayNo',
+            '@Wksta',
+            '@WUserID',
+            '@YDayNo',
+            '@Year',
+            ),
+        3 => array(
+            'WriteValue',
+            'WriteProfileString',
+            'WriteLine',
+            'VarTypeName',
+            'VarType',
+            'Val',
+            'UnloadHive',
+            'UCase',
+            'Ubound',
+            'Trim',
+            'Substr',
+            'SRnd',
+            'Split',
+            'SidToName',
+            'ShutDown',
+            'ShowProgramGroup',
+            'SetWallpaper',
+            'SetTitle',
+            'SetSystemState',
+            'SetOption',
+            'SetFocus',
+            'SetFileAttr',
+            'SetDefaultPrinter',
+            'SetConsole',
+            'SetAscii',
+            'SendMessage',
+            'SendKeys',
+            'SaveKey',
+            'RTrim',
+            'Round',
+            'Rnd',
+            'Right',
+            'RedirectOutput',
+            'ReadValue',
+            'ReadType',
+            'ReadProfileString',
+            'ReadLine',
+            'Open',
+            'MessageBox',
+            'MemorySize',
+            'LTrim',
+            'Logoff',
+            'LogEvent',
+            'LoadKey',
+            'LoadHive',
+            'Len',
+            'Left',
+            'LCase',
+            'KeyExist',
+            'KbHit',
+            'Join',
+            'IsDeclared',
+            'Int',
+            'InStrRev',
+            'InStr',
+            'InGroup',
+            'IIF',
+            'GetObject',
+            'GetFileVersion',
+            'GetFileTime',
+            'GetFileSize',
+            'GetFileAttr',
+            'GetDiskSpace',
+            'FreeFileHandle',
+            'FormatNumber',
+            'Fix',
+            'ExpandEnvironmentVars',
+            'Exist',
+            'Execute',
+            'EnumValue',
+            'EnumLocalGroup',
+            'EnumKey',
+            'EnumIpInfo',
+            'EnumGroup',
+            'Dir',
+            'DelValue',
+            'DelTree',
+            'DelProgramItem',
+            'DelProgramGroup',
+            'DelPrinterConnection',
+            'DelKey',
+            'DecToHex',
+            'CStr',
+            'CreateObject',
+            'CompareFileTimes',
+            'Close',
+            'ClearEventLog',
+            'CInt',
+            'Chr',
+            'CDbl',
+            'Box',
+            'BackupEventLog',
+            'At',
+            'AScan',
+            'Asc',
+            'AddProgramItem',
+            'AddProgramGroup',
+            'AddPrinterConnection',
+            'AddKey',
+            'Abs'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '?', ':', '+', '-', '*', '/', '&', '|', '^', '~', '<', '>', '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.kixtart.org/manual/Commands/{FNAMEL}.htm',
+        2 => '',
+        3 => 'http://www.kixtart.org/manual/Functions/{FNAMEL}.htm'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/klonec.php b/examples/includes/geshi/geshi/klonec.php
new file mode 100644 (file)
index 0000000..599f56b
--- /dev/null
@@ -0,0 +1,282 @@
+<?php
+/*************************************************************************************
+ * klonec.php
+ * --------
+ * Author: AUGER Mickael
+ * Copyright: Synchronic
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/04/16
+ *
+ * KLone with C language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/16 (1.0.8)
+ *  -  First Release
+ *
+ * TODO (updated 2008/04/16)
+ * -------------------------
+ * A tester et a completer si besoin
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'KLone C',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),//#pour precede les include de C
+    'COMMENT_MULTI' => array('/*' => '*/', '<!--' => '-->' ),//comentaires C et KLone suivi de ceux pour HTML
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(//mots-cles C
+            'if', 'return', 'while', 'case', 'class', 'continue', 'default',
+            'do', 'else', 'for', 'switch', 'goto',
+            'null', 'break', 'true', 'enum', 'extern', 'inline', 'false'
+            ),
+        2 => array(//mots-cles KLone
+            'out', 'request', 'response',
+            ),
+        3 => array(//fonctions C usuelles
+            'printf', 'malloc', 'fopen', 'fclose', 'free', 'fputs', 'fgets', 'feof', 'fwrite',
+            'perror', 'ferror', 'qsort', 'stats', 'sscanf', 'scanf',
+            'strdup', 'strcpy', 'strcmp', 'strncpy', 'strcasecmp', 'cat', 'strcat', 'strstr',
+            'strlen', 'strtof', 'strtod', 'strtok', 'towlower', 'towupper',
+            'cd', 'system', 'exit', 'exec', 'fork', 'vfork', 'kill', 'signal', 'syslog',
+            'usleep', 'utime', 'wait', 'waitpid', 'waitid',
+            'ceil', 'eval', 'round', 'floor',
+            'atoi', 'atol', 'abs', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'exp',
+            'time', 'ctime', 'localtime', 'asctime', 'gmtime', 'difftime', 'date'
+            ),
+        4 => array(//fonctions KLone usuelles
+            'request_get_cookies', 'request_get_cookie', 'request_get_args', 'request_get_arg',
+            'request_io', 'request_get_uri', 'request_get_filename', 'request_get_query_string', 'request_get_path_info',
+            'request_get_if_modified_since', 'request_get_http', 'request_get_client_request',
+            'request_get_content_length', 'request_get_uploads', 'request_get_uploaded_file',
+            'request_get_method', 'request_get_protocol', 'request_get_resolved_filename',
+            'request_get_resolved_path_info', 'request_get_addr', 'request_get_peer_addr',
+            'request_get_header', 'request_get_field', 'request_get_field_value',
+            'response_set_content_encoding', 'response_disable_caching', 'response_enable_caching',
+            'response_set_cookie', 'response_set_method', 'response_get_method',
+            'response_print_header', 'response_set_field', 'response_del_field',
+            'response_set_content_type', 'response_set_date', 'response_set_last_modified',
+            'response_set_content_length', 'response_get_status', 'response_get_header',
+            'response_io', 'response_redirect', 'response_set_status',
+            'session_get_vars', 'session_get', 'session_set', 'session_age', 'session_clean', 'session_del',
+            'io_type', 'io_pipe', 'io_dup', 'io_copy', 'io_seek', 'io_tell', 'io_close',
+            'io_free', 'io_read', 'io_printf', 'io_flush', 'io_write', 'io_putc', 'io_getc',
+            'io_get_until', 'io_gets', 'io_codec_add_head', 'io_codec_add_tail',
+            'io_codecs_remove', 'io_name_set', 'io_name_get'
+            ),
+        5 => array(//types C
+            'auto', 'char', 'const', 'double',  'float', 'int', 'long',
+            'register', 'short', 'signed', 'sizeof', 'static', 'string', 'struct',
+            'typedef', 'union', 'unsigned', 'void', 'volatile',
+            'wchar_t', 'time_t', 'FILE'
+            ),
+        6 => array(//mots-cles HTML
+            'a', 'abbr', 'acronym', 'address', 'applet',
+
+            'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+            'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+            'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+            'em',
+
+            'fieldset', 'font', 'form', 'frame', 'frameset',
+
+            'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+            'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+            'kbd',
+
+            'label', 'legend', 'link', 'li',
+
+            'map', 'meta',
+
+            'noframes', 'noscript',
+
+            'object', 'ol', 'optgroup', 'option',
+
+            'param', 'pre', 'p',
+
+            'q',
+
+            'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+            'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+            'ul', 'u',
+
+            'var',
+            ),
+        7 => array(//autres mots-cles HTML
+            'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+            'background', 'bgcolor', 'border',
+            'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+            'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+            'enctype',
+            'face', 'for', 'frame', 'frameborder',
+            'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+            'id', 'ismap',
+            'label', 'lang', 'language', 'link', 'longdesc',
+            'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+            'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+            'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+            'profile', 'prompt',
+            'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+            'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+            'tabindex', 'target', 'text', 'title', 'type',
+            'usemap',
+            'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+            'width'
+            )
+        ),
+    'SYMBOLS' => array(
+        1 => array(
+            '<%=', '<%!', '<%', '%>'
+            ),
+        0 => array(
+            '(', ')', '[', ']', '{', '}',
+            '!', '%', '&', '|', '/',
+            '<', '>',
+            '=', '-', '+', '*',
+            '.', ':', ',', ';', '^'
+            )
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100; font-weight: bold;',//pour les mots-cles C
+            2 => 'color: #000000; font-weight: bold;',//pour les mots-cles KLone
+            3 => 'color: #6600FF;',//pour les fonctions C
+            4 => 'color: #6600FF;',//pour les fonctions Klone
+            5 => 'color: #0099FF; font-weight: bold;',//pour les types C
+            6 => 'color: #990099; font-weight: bold;',//pour les mots-cles HTML
+            7 => 'color: #000066;'//pour les autres mots-cles HTML
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',//commentaire sur une ligne C et KLone
+            2 => 'color: #339933;',//pour les #... en C
+            'MULTI' => 'color: #808080; font-style: italic;'//commentaire sur plusieurs lignes C et KLone
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;',
+            1 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(),
+        'SCRIPT' => array(
+            0 => 'background-color:#ffccff; font-weight: bold; color:#000000;',
+            1 => '',
+            2 => '',
+            3 => 'color: #00bbdd; font-weight: bold;',
+            4 => 'color: #ddbb00;',
+            5 => 'color: #009900;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+        4 => 'http://www.koanlogic.com/klone/api/html/globals.html',
+        5 => '',
+        6 => 'http://december.com/html/4/element/{FNAMEL}.html',
+        7 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        //delimiteurs pour KLone
+        0 => array(
+            '<%=' => '%>'
+            ),
+        1 => array(
+            '<%!' => '%>'
+            ),
+        2 => array(
+            '<%' => '%>'
+            ),
+        //delimiteur pour HTML
+        3 => array(
+            '<!DOCTYPE' => '>'
+            ),
+        4 => array(
+            '&' => ';'
+            ),
+        5 => array(
+            '<' => '>'
+            )
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => false,
+        1 => true,
+        2 => true,
+        3 => false,
+        4 => false,
+        5 => true
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            6 => array(
+                'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+                'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+            ),
+            7 => array(
+                'DISALLOWED_AFTER' => '(?=\s*=)',
+            )
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/klonecpp.php b/examples/includes/geshi/geshi/klonecpp.php
new file mode 100644 (file)
index 0000000..7be4f40
--- /dev/null
@@ -0,0 +1,310 @@
+<?php
+/*************************************************************************************
+ * klonecpp.php
+ * --------
+ * Author: AUGER Mickael
+ * Copyright: Synchronic
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/04/16
+ *
+ * KLone with C++ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/16 (1.0.8)
+ *  -  First Release
+ *
+ * TODO (updated 2008/04/16)
+ * -------------------------
+ * A tester et a completer si besoin
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'KLone C++',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),//#pour precede les include de C
+    'COMMENT_MULTI' => array('/*' => '*/', '<!--' => '-->' ),//comentaires C et KLone suivi de ceux pour HTML
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(//mots-cles C++
+            'if', 'return', 'while', 'case', 'continue', 'default',
+            'do', 'else', 'for', 'switch', 'goto',
+            'break', 'true', 'enum', 'extern', 'inline', 'false',
+            'errno', 'stdin', 'stdout', 'stderr',
+            'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+            'try', 'catch', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+            'static_cast', 'explicit', 'friend', 'typename', 'typeid', 'class',
+            'EDOM', 'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+            'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+            'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+            'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+            'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+            'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+            'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+            'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+            'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam', 'NULL',
+            'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX',
+            'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC'
+            ),
+        2 => array(//mots-cles KLone
+            'out', 'request', 'response',
+            ),
+        3 => array(//fonctions C++ usuelles
+            'cin', 'cerr', 'clog', 'cout', 'delete', 'new', 'this',
+            'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+            'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+            'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+            'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+            'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+            'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+            'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+            'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+            'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+            'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+            'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+            'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+            'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+            'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+            'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+            'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+            'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+            'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+            'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+            ),
+        4 => array(//fonctions KLone usuelles
+            'request_get_cookies', 'request_get_cookie', 'request_get_args', 'request_get_arg',
+            'request_io', 'request_get_uri', 'request_get_filename', 'request_get_query_string', 'request_get_path_info',
+            'request_get_if_modified_since', 'request_get_http', 'request_get_client_request',
+            'request_get_content_length', 'request_get_uploads', 'request_get_uploaded_file',
+            'request_get_method', 'request_get_protocol', 'request_get_resolved_filename',
+            'request_get_resolved_path_info', 'request_get_addr', 'request_get_peer_addr',
+            'request_get_header', 'request_get_field', 'request_get_field_value',
+            'response_set_content_encoding', 'response_disable_caching', 'response_enable_caching',
+            'response_set_cookie', 'response_set_method', 'response_get_method',
+            'response_print_header', 'response_set_field', 'response_del_field',
+            'response_set_content_type', 'response_set_date', 'response_set_last_modified',
+            'response_set_content_length', 'response_get_status', 'response_get_header',
+            'response_io', 'response_redirect', 'response_set_status',
+            'session_get_vars', 'session_get', 'session_set', 'session_age', 'session_clean', 'session_del',
+            'io_type', 'io_pipe', 'io_dup', 'io_copy', 'io_seek', 'io_tell', 'io_close',
+            'io_free', 'io_read', 'io_printf', 'io_flush', 'io_write', 'io_putc', 'io_getc',
+            'io_get_until', 'io_gets', 'io_codec_add_head', 'io_codec_add_tail',
+            'io_codecs_remove', 'io_name_set', 'io_name_get'
+            ),
+        5 => array(//types C++
+            'auto', 'bool', 'char', 'const', 'double', 'float', 'int', 'long', 'longint',
+            'register', 'short', 'shortint', 'signed', 'static', 'struct',
+            'typedef', 'union', 'unsigned', 'void', 'volatile', 'jmp_buf',
+            'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+            'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm',
+            'string', 'wchar_t'
+            ),
+        6 => array(//mots-cles HTML
+            'a', 'abbr', 'acronym', 'address', 'applet',
+
+            'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+            'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+            'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+            'em',
+
+            'fieldset', 'font', 'form', 'frame', 'frameset',
+
+            'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+            'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+            'kbd',
+
+            'label', 'legend', 'link', 'li',
+
+            'map', 'meta',
+
+            'noframes', 'noscript',
+
+            'object', 'ol', 'optgroup', 'option',
+
+            'param', 'pre', 'p',
+
+            'q',
+
+            'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+            'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+            'ul', 'u',
+
+            'var',
+            ),
+        7 => array(//autres mots-cles HTML
+            'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+            'background', 'bgcolor', 'border',
+            'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+            'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+            'enctype',
+            'face', 'for', 'frame', 'frameborder',
+            'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+            'id', 'ismap',
+            'label', 'lang', 'language', 'link', 'longdesc',
+            'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+            'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+            'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+            'profile', 'prompt',
+            'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+            'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+            'tabindex', 'target', 'text', 'title', 'type',
+            'usemap',
+            'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+            'width'
+            )
+        ),
+    'SYMBOLS' => array(
+        1 => array(
+            '<%=', '<%!', '<%', '%>'
+            ),
+        0 => array(
+            '(', ')', '[', ']', '{', '}',
+            '!', '%', '&', '|', '/',
+            '<', '>',
+            '=', '-', '+', '*',
+            '.', ':', ',', ';', '^'
+            )
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100; font-weight: bold;',//pour les mots-cles C++
+            2 => 'color: #000000; font-weight: bold;',//pour les mots-cles KLone
+            3 => 'color: #6600FF;',//pour les fonctions C++
+            4 => 'color: #6600FF;',//pour les fonctions Klone
+            5 => 'color: #0099FF; font-weight: bold;',//pour les types C++
+            6 => 'color: #990099; font-weight: bold;',//pour les mots-cles HTML
+            7 => 'color: #000066;'//pour les autres mots-cles HTML
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',//commentaire sur une ligne C++ et KLone
+            2 => 'color: #339933;',//pour les #... en C++
+            'MULTI' => 'color: #808080; font-style: italic;'//commentaire sur plusieurs lignes C++ et KLone
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;',
+            1 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(),
+        'SCRIPT' => array(
+            0 => 'background-color:#ffccff; font-weight: bold; color:#000000;',
+            1 => '',
+            2 => '',
+            3 => 'color: #00bbdd; font-weight: bold;',
+            4 => 'color: #ddbb00;',
+            5 => 'color: #009900;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+        4 => 'http://www.koanlogic.com/klone/api/html/globals.html',
+        5 => '',
+        6 => 'http://december.com/html/4/element/{FNAMEL}.html',
+        7 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        //delimiteurs pour KLone
+        0 => array(
+            '<%=' => '%>'
+            ),
+        1 => array(
+            '<%!' => '%>'
+            ),
+        2 => array(
+            '<%' => '%>'
+            ),
+        //delimiteur pour HTML
+        3 => array(
+            '<!DOCTYPE' => '>'
+            ),
+        4 => array(
+            '&' => ';'
+            ),
+        5 => array(
+            '<' => '>'
+            )
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => false,
+        1 => true,
+        2 => true,
+        3 => false,
+        4 => false,
+        5 => true
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            6 => array(
+                'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+                'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+            ),
+            7 => array(
+                'DISALLOWED_AFTER' => '(?=\s*=)',
+            )
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/latex.php b/examples/includes/geshi/geshi/latex.php
new file mode 100644 (file)
index 0000000..e4926d9
--- /dev/null
@@ -0,0 +1,209 @@
+<?php
+/*************************************************************************************
+ * latex.php
+ * -----
+ * Author: efi, Matthias Pospiech (matthias@pospiech.eu)
+ * Copyright: (c) 2006 efi, Matthias Pospiech (matthias@pospiech.eu), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/09/23
+ *
+ * LaTeX language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/18 (1.0.8.1)
+ *  - Changes in color and some additional command recognition
+ *  - No special Color for Brackets, it is only distracting
+ *    if color should be reintroduced it should be less bright
+ *  - Math color changed from green to violett, since green is now used for comments
+ *  - Comments are now colored and the only green. The reason for coloring the comments
+ *    is that often important information is in the comments und was merely unvisible before.
+ *  - New Color for [Options]
+ *  - color for labels not specialised anymore. It makes sence in large documents but less in
+ *    small web examples.
+ *  - \@keyword introduced
+ *  - Fixed \& escaped ampersand
+ * 2006/09/23 (1.0.0)
+ *  -  First Release
+ *
+ * TODO
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'LaTeX',
+    'COMMENT_SINGLE' => array(
+        1 => '%'
+        ),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'appendix','backmatter','caption','captionabove','captionbelow',
+            'def','documentclass','edef','equation','flushleft','flushright',
+            'footnote','frontmatter','hline','include','input','item','label',
+            'let','listfiles','listoffigures','listoftables','mainmatter',
+            'makeatletter','makeatother','makebox','mbox','par','raggedleft',
+            'raggedright','raisebox','ref','rule','table','tableofcontents',
+            'textbf','textit','texttt','today'
+            )
+        ),
+    'SYMBOLS' => array(
+        "&", "\\", "{", "}", "[", "]"
+        ),
+    'CASE_SENSITIVE' => array(
+        1 => true,
+        GESHI_COMMENTS => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #800000; font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #2C922C; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 =>  'color: #000000; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            ),
+        'STRINGS' => array(
+            0 =>  'color: #000000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 =>  'color: #E02020; '
+            ),
+        'REGEXPS' => array(
+            1 => 'color: #8020E0; font-weight: normal;',  // Math inner
+            2 => 'color: #C08020; font-weight: normal;', // [Option]
+            3 => 'color: #8020E0; font-weight: normal;', // Maths
+            4 => 'color: #800000; font-weight: normal;', // Structure: Labels
+            5 => 'color: #00008B; font-weight: bold;',  // Structure (\section{->x<-})
+            6 => 'color: #800000; font-weight: normal;', // Structure (\section)
+            7 => 'color: #0000D0; font-weight: normal;', // Environment \end or \begin{->x<-} (brighter blue)
+            8 => 'color: #C00000; font-weight: normal;', // Structure \end or \begin
+            9 => 'color: #2020C0; font-weight: normal;', // {...}
+            10 => 'color: #800000; font-weight: normal;', // \%, \& etc.
+            11 => 'color: #E00000; font-weight: normal;', // \@keyword
+            12 => 'color: #800000; font-weight: normal;', // \keyword
+        ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.golatex.de/wiki/index.php?title=\\{FNAME}',
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        // Math inner
+        1 => array(
+            GESHI_SEARCH => "(\\\\begin\\{(equation|displaymath|eqnarray|subeqnarray|math|multline|gather|align|alignat|flalign)\\})(.*)(\\\\end\\{\\2\\})",
+            GESHI_REPLACE => '\3',
+            GESHI_MODIFIERS => 'Us',
+            GESHI_BEFORE => '\1',
+            GESHI_AFTER => '\4'
+            ),
+        // [options]
+        2 => array(
+            GESHI_SEARCH => "(?<=\[).+(?=\])",
+            GESHI_REPLACE => '\0',
+            GESHI_MODIFIERS => 'Us',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        // Math mode with $ ... $
+        3 => array(
+            GESHI_SEARCH => "\\$.+\\$",
+            GESHI_REPLACE => '\0',
+            GESHI_MODIFIERS => 'Us',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        // Structure: Label
+        4 => "\\\\(?:label|pageref|ref|cite)(?=[^a-zA-Z])",
+        // Structure: sections
+        5 => array(
+            GESHI_SEARCH => "(\\\\(?:part|chapter|(?:sub){0,2}section|(?:sub)?paragraph|addpart|addchap|addsec)\*?\\{)(.*)(?=\\})",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'U',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        // Structure: sections
+        6 => "\\\\(?:part|chapter|(?:sub){0,2}section|(?:sub)?paragraph|addpart|addchap|addsec)\*?(?=[^a-zA-Z])",
+        // environment \begin{} and \end{} (i.e. the things inside the {})
+        7 => array(
+            GESHI_SEARCH => "(\\\\(?:begin|end)\\{)(.*)(?=\\})",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'U',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        // Structure \begin and \end
+        8 => "\\\\(?:end|begin)(?=[^a-zA-Z])",
+        // {parameters}
+        9 => array(
+            GESHI_SEARCH => "(?<=\\{)(?!<\|!REG3XP5!>).*(?=\\})",
+            GESHI_REPLACE => '\0',
+            GESHI_MODIFIERS => 'Us',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        // \%, \& usw.
+        10 => "\\\\(?:[_$%]|&amp;)",
+        //  \@keywords
+        11 => "(?<!<\|!REG3XP[8]!>)\\\\@[a-zA-Z]+\*?",
+        // \keywords
+        12 => "(?<!<\|!REG3XP[468]!>)\\\\[a-zA-Z]+\*?",
+
+// ---------------------------------------------
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'COMMENTS' => array(
+            'DISALLOWED_BEFORE' => '\\'
+        ),
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<=\\\\)",
+            'DISALLOWED_AFTER' => "(?=\b)(?!\w)"
+        ),
+        'ENABLE_FLAGS' => array(
+            'NUMBERS' => GESHI_NEVER,
+            'BRACKETS' => GESHI_NEVER
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/lisp.php b/examples/includes/geshi/geshi/lisp.php
new file mode 100644 (file)
index 0000000..de08d9c
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * lisp.php
+ * --------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * Generic Lisp language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/9  (1.0.2)
+ *  -  Added support for :keywords and ::access (Denis Mashkevich)
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Lisp',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(';|' => '|;'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'not','defun','princ','when',
+            'eval','apply','funcall','quote','identity','function',
+            'complement','backquote','lambda','set','setq','setf',
+            'defmacro','gensym','make','symbol','intern',
+            'name','value','plist','get',
+            'getf','putprop','remprop','hash','array','aref',
+            'car','cdr','caar','cadr','cdar','cddr','caaar','caadr','cadar',
+            'caddr','cdaar','cdadr','cddar','cdddr','caaaar','caaadr',
+            'caadar','caaddr','cadaar','cadadr','caddar','cadddr',
+            'cdaaar','cdaadr','cdadar','cdaddr','cddaar','cddadr',
+            'cdddar','cddddr','cons','list','append','reverse','last','nth',
+            'nthcdr','member','assoc','subst','sublis','nsubst',
+            'nsublis','remove','length',
+            'mapc','mapcar','mapl','maplist','mapcan','mapcon','rplaca',
+            'rplacd','nconc','delete','atom','symbolp','numberp',
+            'boundp','null','listp','consp','minusp','zerop','plusp',
+            'evenp','oddp','eq','eql','equal','cond','case','and','or',
+            'let','l','if','prog','prog1','prog2','progn','go','return',
+            'do','dolist','dotimes','catch','throw','error','cerror','break',
+            'continue','errset','baktrace','evalhook','truncate','float',
+            'rem','min','max','abs','sin','cos','tan','expt','exp','sqrt',
+            'random','logand','logior','logxor','lognot','bignums','logeqv',
+            'lognand','lognor','logorc2','logtest','logbitp','logcount',
+            'integer','nil','parse-integer'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']',
+        '!', '%', '^', '&',
+        ' + ',' - ',' * ',' / ',
+        '=','<','>',
+        '.',':',',',';',
+        '|'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #555;',
+            1 => 'color: #555;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        '::', ':'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'OOLANG' => array(
+            'MATCH_AFTER' => '[a-zA-Z][a-zA-Z0-9_\-]*'
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/locobasic.php b/examples/includes/geshi/geshi/locobasic.php
new file mode 100644 (file)
index 0000000..02e6a7a
--- /dev/null
@@ -0,0 +1,130 @@
+<?php
+/*************************************************************************************
+ * locobasic.php
+ * -------------
+ * Author: Nacho Cabanes
+ * Copyright: (c) 2009 Nacho Cabanes (http://www.nachocabanes.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/03/22
+ *
+ * Locomotive Basic (Amstrad CPC series) language file for GeSHi.
+ *
+ * More details at http://en.wikipedia.org/wiki/Locomotive_BASIC
+ *
+ * CHANGES
+ * -------
+ * 2009/03/22 (1.0.8.3)
+ *  -  First Release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Locomotive Basic',
+    'COMMENT_SINGLE' => array(1 => "'", 2 => 'REM'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            "AFTER", "AND", "AUTO", "BORDER", "BREAK", "CALL", "CAT", "CHAIN",
+            "CLEAR", "CLG", "CLS", "CLOSEIN", "CLOSEOUT", "CONT", "CURSOR",
+            "DATA", "DEF", "DEFINT", "DEFREAL", "DEFSTR", "DEG", "DELETE",
+            "DERR", "DI", "DIM", "DRAW", "DRAWR", "EDIT", "EI", "ELSE", "END",
+            "ENV", "ENT", "EOF", "ERASE", "ERL", "ERR", "ERROR", "EVERY",
+            "FILL", "FN", "FOR", "FRAME", "GOSUB", "GOTO", "GRAPHICS", "HIMEM",
+            "IF", "INK", "INPUT", "KEY", "LET", "LINE", "LIST", "LOAD",
+            "LOCATE", "MASK", "MEMORY", "MERGE", "MODE", "MOVE", "MOVER", "NEW",
+            "NEXT", "NOT", "ON", "OPENIN", "OPENOUT", "OR", "ORIGIN", "PAPER",
+            "PEEK", "PEN", "PLOT", "PLOTR", "POKE", "PRINT", "RAD", "RANDOMIZE",
+            "READ", "RELEASE", "REMAIN", "RENUM", "RESTORE", "RESUME", "RETURN",
+            "RUN", "SAVE", "SPEED", "SOUND", "SPC", "SQ", "STEP", "STOP", "SWAP",
+            "SYMBOL", "TAB", "TAG", "TAGOFF", "TEST", "TESTR", "TIME", "TO",
+            "THEN", "TRON", "TROFF", "USING", "WAIT", "WEND", "WHILE", "WIDTH",
+            "WINDOW", "WRITE", "XOR", "ZONE"
+            ),
+        2 => array(
+            "ABS", "ASC", "ATN", "BIN", "CHR", "CINT", "COPYCHR", "COS",
+            "CREAL", "DEC", "FIX", "FRE", "EXP", "HEX", "INKEY", "INP", "INSTR",
+            "INT", "JOY", "LEFT", "LEN", "LOG", "LOG10", "LOWER", "MAX", "MID",
+            "MIN", "MOD", "OUT", "PI", "POS", "RIGHT", "RND", "ROUND", "SGN",
+            "SIN", "SPACE", "SQR", "STR", "STRING", "TAN", "UNT", "UPPER",
+            "VAL", "VPOS", "XPOS", "YPOS"
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff; font-weight: bold;',
+            2 => 'color: #008888; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080;',
+            2 => 'color: #808080;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0044ff;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/lolcode.php b/examples/includes/geshi/geshi/lolcode.php
new file mode 100644 (file)
index 0000000..19b42f5
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+/*************************************************************************************
+ * lolcode.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/10/31
+ *
+ * LOLcode language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'LOLcode',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        1 => "/\bBTW\b.*$/im",
+        2 => "/(^|\b)(?:OBTW\b.+?\bTLDR|LOL\b.+?\/LOL)(\b|$)/si"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        1 => '/:[)>o":]/',
+        2 => '/:\([\da-f]+\)/i',
+        3 => '/:\{\w+\}/i',
+        4 => '/:\[\w+\]/i',
+        ),
+    'KEYWORDS' => array(
+        //Statements
+        1 => array(
+            'VISIBLE', 'HAI', 'KTHX', 'KTHXBYE', 'SMOOSH', 'GIMMEH', 'PLZ',
+            'ON', 'INVISIBLE', 'R', 'ITZ', 'GTFO', 'COMPLAIN', 'GIMME',
+
+            'OPEN', 'FILE', 'I HAS A', 'AWSUM THX', 'O NOES', 'CAN', 'HAS', 'HAZ',
+            'HOW DOES I', 'IF U SAY SO', 'FOUND YR', 'BORROW', 'OWN', 'ALONG',
+            'WITH', 'WIT', 'LOOK', 'AT', 'AWSUM', 'THX'
+            ),
+        //Conditionals
+        2 => array(
+            'IZ', 'YARLY', 'NOWAI', 'WTF?', 'MEBBE', 'OMG', 'OMGWTF',
+            'ORLY?', 'OF', 'NOPE', 'SO', 'IM', 'MAI',
+
+            'O RLY?', 'SUM', 'BOTH SAEM', 'DIFFRINT', 'BOTH', 'EITHER', 'WON',
+            'DIFF', 'PRODUKT', 'QUOSHUNT', 'MOD', 'MKAY', 'OK', 'THING',
+            'BIGNESS'
+            ),
+        //Repetition
+        3 => array(
+            'IN', 'OUTTA', 'LOOP', 'WHILE'
+            ),
+        //Operators \Math
+        4 => array(
+            'AN', 'AND', 'NOT', 'UP', 'YR', 'UPPIN', 'NERF', 'NERFIN', 'NERFZ',
+            'SMASHING', 'UR', 'KINDA', 'LIKE', 'SAEM', 'BIG', 'SMALL',
+            'BIGGR', 'SMALLR', 'BIGGER', 'SMALLER', 'GOOD', 'CUTE', 'THAN'
+            )
+        ),
+    'SYMBOLS' => array(
+        '.', ',', '?',
+        '!!'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #008000;',
+            2 => 'color: #000080;',
+            3 => 'color: #000080;',
+            4 => 'color: #800000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; style: italic;',
+            2 => 'color: #666666; style: italic;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'SPACE_AS_WHITESPACE' => true
+            )
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/lotusformulas.php b/examples/includes/geshi/geshi/lotusformulas.php
new file mode 100644 (file)
index 0000000..010fb22
--- /dev/null
@@ -0,0 +1,318 @@
+<?php
+/*************************************************************************************
+ * lotusformulas.php
+ * ------------------------
+ * Author: Richard Civil (info@richardcivil.net)
+ * Copyright: (c) 2008 Richard Civil (info@richardcivil.net), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/04/12
+ *
+ * @Formula/@Command language file for GeSHi.
+ *
+ * @Formula/@Command source: IBM Lotus Notes/Domino 8 Designer Help
+ *
+ * CHANGES
+ * -------
+ * 2008/04/12 (1.0.7.22)
+ *  -  First Release
+ *
+ * TODO (updated 2008/04/12)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Lotus Notes @Formulas',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array('REM' => ';'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array (
+            '[ZoomPreview]', '[WorkspaceStackReplicaIcons]',
+            '[WorkspaceProperties]', '[WindowWorkspace]',
+            '[WindowTile]', '[WindowRestore]', '[WindowNext]',
+            '[WindowMinimizeAll]', '[WindowMinimize]', '[WindowMaximizeAll]',
+            '[WindowMaximize]', '[WindowCascade]', '[ViewSwitchForm]',
+            '[ViewShowUnread]', '[ViewShowServerNames]', '[ViewShowSearchBar]',
+            '[ViewShowRuler]', '[ViewShowPageBreaks]', '[ViewShowOnlyUnread]',
+            '[ViewShowOnlySelected]', '[ViewShowOnlySearchResults]',
+            '[ViewShowOnlyCategories]', '[ViewShowObject]',
+            '[ViewShowFieldHelp]', '[ViewRenamePerson]', '[ViewRefreshUnread]',
+            '[ViewRefreshFields]', '[ViewNavigatorsNone]',
+            '[ViewNavigatorsFolders]', '[ViewMoveName]', '[ViewHorizScrollbar]',
+            '[ViewExpandWithChildren]', '[ViewExpandAll]', '[ViewExpand]',
+            '[ViewCollapseAll]', '[ViewCollapse]', '[ViewChange]',
+            '[ViewCertify]', '[ViewBesideFolders]', '[ViewBelowFolders]',
+            '[ViewArrangeIcons]', '[V3EditPrevField]', '[V3EditNextField]',
+            '[UserIDSwitch]', '[UserIDSetPassword]', '[UserIDMergeCopy]',
+            '[UserIDInfo]', '[UserIDEncryptionKeys]', '[UserIDCreateSafeCopy]',
+            '[UserIDClearPassword]', '[UserIDCertificates]',
+            '[ToolsUserLogoff]', '[ToolsSpellCheck]', '[ToolsSmartIcons]',
+            '[ToolsSetupUserSetup]', '[ToolsSetupPorts]', '[ToolsSetupMail]',
+            '[ToolsSetupLocation]', '[ToolsScanUnreadSelected]',
+            '[ToolsScanUnreadPreferred]', '[ToolsScanUnreadChoose]',
+            '[ToolsRunMacro]', '[ToolsRunBackgroundMacros]', '[ToolsReplicate]',
+            '[ToolsRefreshSelectedDocs]', '[ToolsRefreshAllDocs]',
+            '[ToolsMarkSelectedUnread]', '[ToolsMarkSelectedRead]',
+            '[ToolsMarkAllUnread]', '[ToolsMarkAllRead]', '[ToolsHangUp]',
+            '[ToolsCategorize]', '[ToolsCall]', '[TextUnderline]',
+            '[TextSpacingSingle]', '[TextSpacingOneAndaHalf]',
+            '[TextSpacingDouble]', '[TextSetFontSize]', '[TextSetFontFace]',
+            '[TextSetFontColor]', '[TextReduceFont]', '[TextPermanentPen]',
+            '[TextParagraphStyles]', '[TextParagraph]', '[TextOutdent]',
+            '[TextNumbers]', '[TextNormal]', '[TextItalic]', '[TextFont]',
+            '[TextEnlargeFont]', '[TextCycleSpacing]', '[TextBullet]',
+            '[TextBold]', '[TextAlignRight]', '[TextAlignNone]',
+            '[TextAlignLeft]', '[TextAlignFull]', '[TextAlignCenter]',
+            '[SwitchView]', '[SwitchForm]', '[StyleCycleKey]',
+            '[SmartIconsNextSet]', '[SmartIconsFloating]', '[ShowProperties]',
+            '[ShowHidePreviewPane]', '[ShowHideParentPreview]',
+            '[ShowHideLinkPreview]', '[ShowHideIMContactList]',
+            '[SetCurrentLocation]', '[SendInstantMessage]',
+            '[SectionRemoveHeader]', '[SectionProperties]',
+            '[SectionExpandAll]', '[SectionExpand]', '[SectionDefineEditors]',
+            '[SectionCollapseAll]', '[SectionCollapse]', '[RunScheduledAgents]',
+            '[RunAgent]', '[ReplicatorStop]', '[ReplicatorStart]',
+            '[ReplicatorSendReceiveMail]', '[ReplicatorSendMail]',
+            '[ReplicatorReplicateWithServer]', '[ReplicatorReplicateSelected]',
+            '[ReplicatorReplicateNext]', '[ReplicatorReplicateHigh]',
+            '[Replicator]', '[RenameDatabase]', '[RemoveFromFolder]',
+            '[RemoteDebugLotusScript]', '[ReloadWindow]', '[RefreshWindow]',
+            '[RefreshParentNote]', '[RefreshHideFormulas]', '[RefreshFrame]',
+            '[PublishDatabase]', '[PictureProperties]', '[PasteBitmapAsObject]',
+            '[PasteBitmapAsBackground]', '[OpenView]', '[OpenPage]',
+            '[OpenNavigator]', '[OpenInNewWindow]', '[OpenHelpDocument]',
+            '[OpenFrameset]', '[OpenDocument]', '[OpenCalendar]',
+            '[ObjectProperties]', '[ObjectOpen]', '[ObjectDisplayAs]',
+            '[NavPrevUnread]', '[NavPrevSelected]', '[NavPrevMain]',
+            '[NavPrev]', '[NavNextUnread]', '[NavNextSelected]',
+            '[NavNextMain]', '[NavNext]', '[NavigatorTest]',
+            '[NavigatorProperties]', '[NavigateToBacklink]',
+            '[NavigatePrevUnread]', '[NavigatePrevSelected]',
+            '[NavigatePrevMain]', '[NavigatePrevHighlight]', '[NavigatePrev]',
+            '[NavigateNextUnread]', '[NavigateNextSelected]',
+            '[NavigateNextMain]', '[NavigateNextHighlight]', '[NavigateNext]',
+            '[MoveToTrash]', '[MailSendPublicKey]', '[MailSendEncryptionKey]',
+            '[MailSendCertificateRequest]', '[MailSend]', '[MailScanUnread]',
+            '[MailRequestNewPublicKey]', '[MailRequestNewName]',
+            '[MailRequestCrossCert]', '[MailOpen]', '[MailForwardAsAttachment]',
+            '[MailForward]', '[MailComposeMemo]', '[MailAddress]',
+            '[LayoutProperties]', '[LayoutElementSendToBack]',
+            '[LayoutElementProperties]', '[LayoutElementBringToFront]',
+            '[LayoutAddText]', '[LayoutAddGraphic]', '[InsertSubform]',
+            '[HotspotProperties]', '[HotspotClear]', '[HelpUsingDatabase]',
+            '[HelpAboutNotes]', '[HelpAboutDatabase]', '[GoUpLevel]',
+            '[FormTestDocument]', '[FormActions]', '[FolderRename]',
+            '[FolderProperties]', '[FolderMove]', '[FolderExpandWithChildren]',
+            '[FolderExpandAll]', '[FolderExpand]', '[FolderDocuments]',
+            '[FolderCustomize]', '[FolderCollapse]', '[Folder]',
+            '[FindFreeTimeDialog]', '[FileSaveNewVersion]', '[FileSave]',
+            '[FilePrintSetup]', '[FilePrint]', '[FilePageSetup]',
+            '[FileOpenDBRepID]', '[FileOpenDatabase]', '[FileNewReplica]',
+            '[FileNewDatabase]', '[FileImport]', '[FileFullTextUpdate]',
+            '[FileFullTextInfo]', '[FileFullTextDelete]',
+            '[FileFullTextCreate]', '[FileExport]', '[FileExit]',
+            '[FileDatabaseUseServer]', '[FileDatabaseRemove]',
+            '[FileDatabaseInfo]', '[FileDatabaseDelete]', '[FileDatabaseCopy]',
+            '[FileDatabaseCompact]', '[FileDatabaseACL]', '[FileCloseWindow]',
+            '[ExitNotes]', '[Execute]', '[ExchangeUnreadMarks]', '[EmptyTrash]',
+            '[EditUp]', '[EditUntruncate]', '[EditUndo]', '[EditTop]',
+            '[EditTableInsertRowColumn]', '[EditTableFormat]',
+            '[EditTableDeleteRowColumn]', '[EditShowHideHiddenChars]',
+            '[EditSelectByDate]', '[EditSelectAll]', '[EditRight]',
+            '[EditRestoreDocument]', '[EditResizePicture]',
+            '[EditQuoteSelection]', '[EditProfileDocument]', '[EditProfile]',
+            '[EditPrevField]', '[EditPhoneNumbers]', '[EditPasteSpecial]',
+            '[EditPaste]', '[EditOpenLink]', '[EditNextField]',
+            '[EditMakeDocLink]', '[EditLocations]', '[EditLinks]', '[EditLeft]',
+            '[EditInsertText]', '[EditInsertTable]', '[EditInsertPopup]',
+            '[EditInsertPageBreak]', '[EditInsertObject]',
+            '[EditInsertFileAttachment]', '[EditInsertButton]',
+            '[EditIndentFirstLine]', '[EditIndent]', '[EditHorizScrollbar]',
+            '[EditHeaderFooter]', '[EditGotoField]', '[EditFindNext]',
+            '[EditFindInPreview]', '[EditFind]', '[EditEncryptionKeys]',
+            '[EditDown]', '[EditDocument]', '[EditDetach]', '[EditDeselectAll]',
+            '[EditCut]', '[EditCopy]', '[EditClear]', '[EditButton]',
+            '[EditBottom]', '[DiscoverFolders]', '[Directories]',
+            '[DialingRules]', '[DesignViewSelectFormula]', '[DesignViews]',
+            '[DesignViewNewColumn]', '[DesignViewFormFormula]',
+            '[DesignViewEditActions]', '[DesignViewColumnDef]',
+            '[DesignViewAttributes]', '[DesignViewAppendColumn]',
+            '[DesignSynopsis]', '[DesignSharedFields]', '[DesignReplace]',
+            '[DesignRefresh]', '[DesignMacros]', '[DesignIcon]',
+            '[DesignHelpUsingDocument]', '[DesignHelpAboutDocument]',
+            '[DesignFormWindowTitle]', '[DesignFormUseField]',
+            '[DesignFormShareField]', '[DesignForms]', '[DesignFormNewField]',
+            '[DesignFormFieldDef]', '[DesignFormAttributes]',
+            '[DesignDocumentInfo]', '[DebugLotusScript]',
+            '[DatabaseReplSettings]', '[DatabaseDelete]', '[CreateView]',
+            '[CreateTextbox]', '[CreateSubForm]', '[CreateSection]',
+            '[CreateRectangularHotspot]', '[CreateRectangle]',
+            '[CreatePolyline]', '[CreatePolygon]', '[CreateNavigator]',
+            '[CreateLayoutRegion]', '[CreateForm]', '[CreateFolder]',
+            '[CreateEllipse]', '[CreateControlledAccessSection]',
+            '[CreateAgent]', '[CreateAction]', '[CopySelectedAsTable]',
+            '[ComposeWithReference]', '[Compose]', '[CloseWindow]', '[Clear]',
+            '[ChooseFolders]', '[CalendarGoTo]', '[CalendarFormat]',
+            '[AttachmentView]', '[AttachmentProperties]', '[AttachmentLaunch]',
+            '[AttachmentDetachAll]', '[AgentTestRun]', '[AgentSetServerName]',
+            '[AgentRun]', '[AgentLog]', '[AgentEnableDisable]', '[AgentEdit]',
+            '[AdminTraceConnection]', '[AdminStatisticsConfig]',
+            '[AdminSendMailTrace]', '[AdminRemoteConsole]',
+            '[AdminRegisterUser]', '[AdminRegisterServer]',
+            '[AdminRegisterFromFile]', '[AdminOutgoingMail]',
+            '[AdminOpenUsersView]', '[AdminOpenStatistics]',
+            '[AdminOpenServersView]', '[AdminOpenServerLog]',
+            '[AdminOpenGroupsView]', '[AdminOpenCertLog]', '[AdminOpenCatalog]',
+            '[AdminOpenAddressBook]', '[AdminNewOrgUnit]',
+            '[AdminNewOrganization]', '[Administration]',
+            '[AdminIDFileSetPassword]', '[AdminIDFileExamine]',
+            '[AdminIDFileClearPassword]', '[AdminDatabaseQuotas]',
+            '[AdminDatabaseAnalysis]', '[AdminCrossCertifyKey]',
+            '[AdminCrossCertifyIDFile]', '[AdminCreateGroup]', '[AdminCertify]',
+            '[AddToIMContactList]', '[AddDatabaseRepID]', '[AddDatabase]',
+            '[AddBookmark]'
+            ),
+        2 => array(
+            'SELECT', 'FIELD', 'ENVIRONMENT', 'DEFAULT', '@Zone ', '@Yesterday',
+            '@Yes', '@Year', '@Word', '@Wide', '@While', '@Weekday',
+            '@WebDbName', '@ViewTitle', '@ViewShowThisUnread', '@Version',
+            '@VerifyPassword', '@ValidateInternetAddress', '@V4UserAccess',
+            '@V3UserName', '@V2If', '@UserRoles', '@UserPrivileges',
+            '@UserNamesList', '@UserNameLanguage', '@UserName', '@UserAccess',
+            '@UrlQueryString', '@URLOpen', '@URLHistory', '@URLGetHeader',
+            '@URLEncode', '@URLDecode', '@UpperCase', '@UpdateFormulaContext',
+            '@Unique', '@UndeleteDocument', '@Unavailable', '@True', '@Trim',
+            '@Transform', '@ToTime', '@ToNumber', '@Tomorrow', '@Today',
+            '@TimeZoneToText', '@TimeToTextInZone', '@TimeMerge', '@Time',
+            '@ThisValue', '@ThisName', '@TextToTime', '@TextToNumber', '@Text',
+            '@TemplateVersion', '@Tan', '@Sum', '@Success', '@Subset',
+            '@StatusBar', '@Sqrt', '@Soundex', '@Sort', '@Sin', '@Sign',
+            '@SetViewInfo', '@SetTargetFrame', '@SetProfileField',
+            '@SetHTTPHeader', '@SetField', '@SetEnvironment', '@SetDocField',
+            '@Set', '@ServerName', '@ServerAccess', '@Select', '@Second',
+            '@Round', '@RightBack', '@Right', '@Return', '@Responses',
+            '@ReplicaID', '@ReplaceSubstring', '@Replace', '@Repeat',
+            '@RegQueryValue', '@RefreshECL', '@Random', '@ProperCase',
+            '@Prompt', '@Power', '@PostedCommand', '@PolicyIsFieldLocked',
+            '@Platform', '@PickList', '@Pi', '@PasswordQuality', '@Password',
+            '@OrgDir', '@OptimizeMailAddress', '@OpenInNewWindow', '@Now',
+            '@Nothing', '@NoteID', '@No', '@NewLine', '@Narrow', '@NameLookup',
+            '@Name', '@Month', '@Modulo', '@Modified', '@Minute', '@Min',
+            '@MiddleBack', '@Middle', '@Member', '@Max', '@Matches',
+            '@MailSignPreference', '@MailSend', '@MailSavePreference',
+            '@MailEncryptSentPreference', '@MailEncryptSavedPreference',
+            '@MailDbName', '@LowerCase', '@Log', '@Locale', '@Ln', '@Like',
+            '@Length', '@LeftBack', '@Left', '@LDAPServer', '@LaunchApp',
+            '@LanguagePreference', '@Keywords', '@IsVirtualizedDirectory',
+            '@IsValid', '@IsUsingJavaElement', '@IsUnavailable', '@IsTime',
+            '@IsText', '@IsResponseDoc', '@IsNumber', '@IsNull', '@IsNotMember',
+            '@IsNewDoc', '@IsModalHelp', '@IsMember', '@IsExpandable',
+            '@IsError', '@IsEmbeddedInsideWCT', '@IsDocTruncated',
+            '@IsDocBeingSaved', '@IsDocBeingRecalculated', '@IsDocBeingMailed',
+            '@IsDocBeingLoaded', '@IsDocBeingEdited', '@IsDB2', '@IsCategory',
+            '@IsAvailable', '@IsAppInstalled', '@IsAgentEnabled', '@Integer',
+            '@InheritedDocumentUniqueID', '@Implode', '@IfError', '@If',
+            '@Hour', '@HashPassword', '@HardDeleteDocument', '@GetViewInfo',
+            '@GetProfileField', '@GetPortsList', '@GetIMContactListGroupNames',
+            '@GetHTTPHeader', '@GetFocusTable', '@GetField', '@GetDocField',
+            '@GetCurrentTimeZone', '@GetAddressBooks', '@FormLanguage', '@For',
+            '@FontList', '@FloatEq', '@FileDir', '@False', '@Failure',
+            '@Explode', '@Exp', '@Eval', '@Error', '@Environment', '@Ends',
+            '@EnableAlarms', '@Elements', '@EditUserECL', '@EditECL',
+            '@DoWhile', '@Domain', '@DocumentUniqueID', '@DocSiblings',
+            '@DocParentNumber', '@DocOmmittedLength', '@DocNumber', '@DocMark',
+            '@DocLock', '@DocLevel', '@DocLength', '@DocFields',
+            '@DocDescendants', '@DocChildren', '@Do', '@DialogBox',
+            '@DeleteField', '@DeleteDocument', '@DDETerminate', '@DDEPoke',
+            '@DDEInitiate', '@DDEExecute', '@DbTitle', '@DbName', '@DbManager',
+            '@DbLookup', '@DbExists', '@DbCommand', '@DbColumn', '@DB2Schema',
+            '@Day', '@Date', '@Created', '@Count', '@Cos', '@Contains',
+            '@ConfigFile', '@Compare', '@Command', '@ClientType',
+            '@CheckFormulaSyntax', '@CheckAlarms', '@Char', '@Certificate',
+            '@BusinessDays', '@BrowserInfo', '@Begins', '@Author',
+            '@Attachments', '@AttachmentNames', '@AttachmentModifiedTimes',
+            '@AttachmentLengths', '@ATan2', '@ATan', '@ASin', '@Ascii',
+            '@AllDescendants', '@AllChildren', '@All', '@AdminECLIsLocked',
+            '@Adjust', '@AddToFolder', '@ACos', '@Accessed', '@AbstractSimple',
+            '@Abstract', '@Abs'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #800000;',
+            2 => 'color: #0000FF;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #FF00FF;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF00FF;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000AA;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 2
+    );
+
+?>
diff --git a/examples/includes/geshi/geshi/lotusscript.php b/examples/includes/geshi/geshi/lotusscript.php
new file mode 100644 (file)
index 0000000..598da3b
--- /dev/null
@@ -0,0 +1,191 @@
+<?php
+/**
+ * lotusscript.php
+ * ------------------------
+ * Author: Richard Civil (info@richardcivil.net)
+ * Copyright: (c) 2008 Richard Civil (info@richardcivil.net), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/04/12
+ *
+ * LotusScript language file for GeSHi.
+ *
+ * LotusScript source: IBM Lotus Notes/Domino 8 Designer Help
+ *
+ * CHANGES
+ * -------
+ * 2008/04/12 (1.0.7.22)
+ *     -  First Release
+ *
+ * TODO (2008/04/12)
+ * -----------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'LotusScript',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array('%REM' => '%END REM'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"' , "|"),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array (
+            'Yield', 'Year', 'Xor', 'Write', 'With', 'Width', 'While', 'Wend',
+            'Weekday', 'VarType', 'Variant', 'Val', 'UString', 'UString$',
+            'UseLSX', 'Use', 'Until', 'Unlock', 'Unicode', 'Uni', 'UChr',
+            'UChr$', 'UCase', 'UCase$', 'UBound', 'TypeName', 'Type', 'TRUE',
+            'Trim', 'Trim$', 'Today', 'To', 'TimeValue', 'TimeSerial', 'Timer',
+            'TimeNumber', 'Time', 'Time$', 'Then', 'Text', 'Tan', 'Tab', 'Sub',
+            'StrToken', 'StrToken$', 'StrRightBack', 'StrRightBack$',
+            'StrRight', 'StrRight$', 'StrLeftBack', 'StrLeftBack$', 'StrLeft',
+            'StrLeft$', 'String', 'String$', 'StrConv', 'StrCompare', 'StrComp',
+            'Str', 'Str$', 'Stop', 'Step', 'Static', 'Sqr', 'Split', 'Spc',
+            'Space', 'Space$', 'Sleep', 'Single', 'Sin', 'Shell', 'Shared',
+            'Sgn', 'SetFileAttr', 'SetAttr', 'Set', 'SendKeys', 'Select',
+            'Seek', 'Second', 'RTrim', 'RTrim$', 'RSet', 'Round', 'Rnd',
+            'RmDir', 'RightC', 'RightC$', 'RightBP', 'RightBP$', 'RightB',
+            'RightB$', 'Right', 'Right$', 'Return', 'Resume', 'Reset',
+            'Replace', 'Remove', 'Rem', 'ReDim', 'Read', 'Randomize',
+            'Random', 'Put', 'Public', 'Property', 'Private', 'Print',
+            'Preserve', 'Pitch', 'PI', 'Output', 'Or', 'Option', 'Open', 'On',
+            'Oct', 'Oct$', 'NULL', 'Now', 'NOTHING', 'Not', 'NoPitch', 'NoCase',
+            'Next', 'New', 'Name', 'MsgBox', 'Month', 'Mod', 'MkDir', 'Minute',
+            'MidC', 'MidC$', 'MidBP', 'MidBP$', 'MidB', 'MidB$', 'Mid', 'Mid$',
+            'MessageBox', 'Me', 'LTrim', 'LTrim$', 'LSServer', 'LSI_Info',
+            'LSet', 'Loop', 'Long', 'Log', 'LOF', 'Lock', 'LOC', 'LMBCS',
+            'ListTag', 'List', 'Line', 'Like', 'Lib', 'Let', 'LenC', 'LenBP',
+            'LenB', 'Len', 'LeftC', 'LeftC$', 'LeftBP', 'LeftBP$', 'LeftB',
+            'LeftB$', 'Left', 'Left$', 'LCase', 'LCase$', 'LBound', 'Kill',
+            'Join', 'IsUnknown', 'IsScalar', 'IsObject', 'IsNumeric', 'IsNull',
+            'IsList', 'IsEmpty', 'IsElement', 'IsDate', 'IsArray', 'IsA', 'Is',
+            'Integer', 'Int', 'InStrC', 'InStrBP', 'InStrB', 'InStr', 'InputBP',
+            'InputBP$', 'InputBox', 'InputBox$', 'InputB', 'InputB$', 'Input',
+            'Input$', 'In', 'IMSetMode', 'Implode', 'Implode$', 'Imp',
+            'IMEStatus', 'If', 'Hour', 'Hex', 'Hex$', 'Goto', 'GoSub',
+            'GetThreadInfo', 'GetFileAttr', 'GetAttr', 'Get', 'Function',
+            'FullTrim', 'From', 'FreeFile', 'Fraction', 'Format', 'Format$',
+            'ForAll', 'For', 'Fix', 'FileLen', 'FileDateTime', 'FileCopy',
+            'FileAttr', 'FALSE', 'Explicit', 'Exp', 'Exit', 'Execute', 'Event',
+            'Evaluate', 'Error', 'Error$', 'Err', 'Erl', 'Erase', 'Eqv', 'EOF',
+            'Environ', 'Environ$', 'End', 'ElseIf', 'Else', 'Double', 'DoEvents',
+            'Do', 'Dir', 'Dir$', 'Dim', 'DestroyLock', 'Delete', 'DefVar',
+            'DefStr', 'DefSng', 'DefLng', 'DefInt', 'DefDbl', 'DefCur',
+            'DefByte', 'DefBool', 'Declare', 'Day', 'DateValue', 'DateSerial',
+            'DateNumber', 'Date', 'Date$', 'DataType', 'CVDate', 'CVar',
+            'Currency', 'CurDrive', 'CurDrive$', 'CurDir', 'CurDir$', 'CStr',
+            'CSng', 'CreateLock', 'Cos', 'Const', 'Compare', 'Command',
+            'Command$', 'CodeUnlock', 'CodeLockCheck', 'CodeLock', 'Close',
+            'CLng', 'Class', 'CInt', 'Chr', 'Chr$', 'ChDrive', 'ChDir', 'CDbl',
+            'CDat', 'CCur', 'CByte', 'CBool', 'Case', 'Call', 'ByVal', 'Byte',
+            'Boolean', 'Bind', 'Binary', 'Bin', 'Bin$', 'Beep', 'Base', 'Atn2',
+            'Atn', 'ASin', 'Asc', 'As', 'ArrayUnique', 'ArrayReplace',
+            'ArrayGetIndex', 'ArrayAppend', 'Append', 'AppActivate', 'Any',
+            'And', 'Alias', 'ActivateApp', 'ACos', 'Access', 'Abs', '%Include',
+            '%If', '%END', '%ElseIf', '%Else'
+            ),
+        2 => array (
+            'NotesXSLTransformer', 'NotesXMLProcessor', 'NotesViewNavigator',
+            'NotesViewEntryCollection', 'NotesViewEntry', 'NotesViewColumn',
+            'NotesView', 'NotesUIWorkspace', 'NotesUIView', 'NotesUIScheduler',
+            'NotesUIDocument', 'NotesUIDatabase', 'NotesTimer', 'NotesStream',
+            'NotesSession', 'NotesSAXParser', 'NotesSAXException',
+            'NotesSAXAttributeList', 'NotesRichTextTable', 'NotesRichTextTab',
+            'NotesRichTextStyle', 'NotesRichTextSection', 'NotesRichTextRange',
+            'NotesRichTextParagraphStyle', 'NotesRichTextNavigator',
+            'NotesRichTextItem', 'NotesRichTextDocLink',
+            'NotesReplicationEntry', 'NotesReplication', 'NotesRegistration',
+            'NotesOutlineEntry', 'NotesOutline', 'NotesNoteCollection',
+            'NotesNewsLetter', 'NotesName', 'NotesMIMEHeader',
+            'NotesMIMEEntity', 'NotesLog', 'NotesItem', 'NotesInternational',
+            'NotesForm', 'NotesEmbeddedObject', 'NotesDXLImporter',
+            'NotesDXLExporter', 'NotesDOMXMLDeclNode', 'NotesDOMTextNode',
+            'NotesDOMProcessingInstructionNode', 'NotesDOMParser',
+            'NotesDOMNotationNode', 'NotesDOMNodeList', 'NotesDOMNode',
+            'NotesDOMNamedNodeMap', 'NotesDOMEntityReferenceNode',
+            'NotesDOMEntityNode', 'NotesDOMElementNode',
+            'NotesDOMDocumentTypeNode', 'NotesDOMDocumentNode',
+            'NotesDOMDocumentFragmentNode', 'NotesDOMCommentNode',
+            'NotesDOMCharacterDataNote', 'NotesDOMCDATASectionNode',
+            'NotesDOMAttributeNode', 'NotesDocumentCollection', 'NotesDocument',
+            'NotesDbDirectory', 'NotesDateTime', 'NotesDateRange',
+            'NotesDatabase', 'NotesColorObject', 'NotesAgent',
+            'NotesAdministrationProcess', 'NotesACLEntry', 'NotesACL',
+            'Navigator', 'Field', 'Button'
+            )
+        ) ,
+    'SYMBOLS' => array(
+        '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000FF;',
+            2 => 'color: #0000EE;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #000000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF00FF;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000AA;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #006600;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 2
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/lscript.php b/examples/includes/geshi/geshi/lscript.php
new file mode 100644 (file)
index 0000000..57bb2ba
--- /dev/null
@@ -0,0 +1,387 @@
+<?php
+/*************************************************************************************
+ * lscript.php
+ * ---------
+ * Author: Arendedwinter (admin@arendedwinter.com)
+ * Copyright: (c) 2008 Beau McGuigan (http://www.arendedwinter.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 15/11/2008
+ *
+ * Lightwave Script language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'LScript',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+    //Yes, I'm aware these are out of order,
+    //I had to rearrange and couldn't be bothered changing the numbers...
+        7 => array(
+            '@data', '@define', '@else', '@end', '@fpdepth', '@if', '@include',
+            '@insert', '@library', '@localipc', '@name', '@save', '@script',
+            '@sequence', '@version', '@warnings'
+            ),
+        1 => array(
+            'break', 'case', 'continue', 'else', 'end', 'false', 'for',
+            'foreach', 'if', 'return', 'switch', 'true', 'while',
+            ),
+        3 => array(
+            'active', 'alertlevel', 'alpha', 'alphaprefix', 'animfilename', 'autokeycreate',
+            'backdroptype', 'blue', 'boxthreshold', 'button',
+            'channelsvisible', 'childrenvisible', 'compfg', 'compbg', 'compfgalpha',
+            'coneangles', 'cosine', 'count', 'ctl', 'curFilename', 'curFrame',
+            'currenttime', 'curTime', 'curType',
+            'depth', 'diffshade', 'diffuse', 'dimensions', 'displayopts', 'dynamicupdate',
+            'end', 'eta',
+            'filename', 'flags', 'fogtype', 'fps', 'frame', 'frameend', 'frameheight',
+            'framestart', 'framestep', 'framewidth',
+            'generalopts', 'genus', 'geometry', 'gNorm', 'goal', 'green',
+            'h', 'hasAlpha', 'height',
+            'id', 'innerlimit', 'isColor',
+            'keyCount', 'keys',
+            'limiteregion', 'locked', 'luminous',
+            'maxsamplesperpixel', 'minsamplesperpixel', 'mirror', 'motionx', 'motiony',
+            'name', 'newFilename', 'newFrame', 'newTime', 'newType', 'null', 'numthreads',
+            'objID', 'oPos', 'outerlimit', 'oXfrm',
+            'parent', 'pixel', 'pixelaspect', 'point', 'points', 'pointcount', 'polNum',
+            'polycount', 'polygon', 'polygons', 'postBehavior', 'preBehavior', 'previewend',
+            'previewstart', 'previewstep',
+            'range', 'rawblue', 'rawgreen', 'rawred', 'rayLength', 'raySource', 'red',
+            'reflectblue', 'reflectgreen', 'reflectred', 'recursiondepth', 'renderend',
+            'renderopts', 'renderstart', 'renderstep', 'rendertype', 'restlength',
+            'rgbprefix', 'roughness',
+            'selected', 'setColor', 'setPattern', 'shading', 'shadow', 'shadows',
+            'shadowtype', 'size', 'source', 'special', 'specshade', 'specular',
+            'spotsize', 'start', 'sx', 'sy', 'sz',
+            'target', 'totallayers', 'totalpoints', 'totalpolygons', 'trans', 'transparency',
+            'type',
+            'value', 'view', 'visible', 'visibility',
+            'w', 'width', 'wNorm', 'wPos', 'wXfrm',
+            'x', 'xoffset',
+            'y', 'yoffset',
+            'z'
+            ),
+        4 => array(
+            'addLayer', 'addParticle', 'alphaspot', 'ambient', 'asAsc', 'asBin',
+            'asInt', 'asNum', 'asStr', 'asVec', 'attach', 'axislocks',
+            'backdropColor', 'backdropRay', 'backdropSqueeze', 'bone', 'blurLength',
+            'close', 'color', 'contains', 'copy', 'createKey',
+            'deleteKey', 'detach', 'drawCircle', 'drawLine', 'drawPoint', 'drawText',
+            'drawTriangle',
+            'edit', 'eof', 'event',
+            'firstChannel', 'firstLayer', 'firstSelect', 'focalLength', 'fogColor',
+            'fogMaxAmount', 'fogMaxDist', 'fogMinAmount', 'fogMinDist',
+            'fovAngles', 'fStop', 'firstChild', 'focalDistance',
+            'get', 'getChannelGroup', 'getEnvelope', 'getForward', 'getKeyBias',
+            'getKeyContinuity', 'getKeyCurve', 'getKeyHermite', 'getKeyTension',
+            'getKeyTime', 'getKeyValue', 'getParticle', 'getPivot', 'getPosition',
+            'getRight', 'getRotation', 'getSelect', 'getScaling', 'getTag', 'getTexture',
+            'getUp', 'getValue', 'getWorldPosition', 'getWorldForward', 'getWorldRight',
+            'getWorldRotation', 'getWorldUp', 'globalBlur', 'globalMask', 'globalResolution',
+            'hasCCEnd', 'hasCCStart',
+            'illuminate', 'indexOf', 'isAscii', 'isAlnum', 'isAlpha', 'isBone',
+            'isCamera', 'isChannel', 'isChannelGroup', 'isCntrl', 'isCurve', 'isDigit',
+            'isEnvelope', 'isImage', 'isInt', 'isLight', 'isLower', 'isMapped', 'isMesh',
+            'isNil', 'isNum', 'IsOpen', 'isOriginal', 'isPrint', 'isPunct', 'isScene',
+            'isSpace', 'isStr', 'isUpper', 'isValid', 'isVMap', 'isVec', 'isXDigit',
+            'keyExists',
+            'layer', 'layerName', 'layerVisible', 'limits', 'line', 'linecount', 'load', 'luma',
+            'next', 'nextLayer', 'nextSelect', 'nextChannel', 'nextChild', 'nl',
+            'offset', 'open',
+            'pack', 'param', 'parse', 'paste', 'persist', 'polygonCount', 'position',
+            'rayCast', 'rayTrace', 'read', 'readByte', 'readInt', 'readNumber',
+            'readDouble', 'readShort', 'readString', 'readVector', 'reduce',
+            'remParticle', 'renderCamera', 'reopen', 'replace', 'reset', 'restParam',
+            'rewind', 'rgb', 'rgbambient', 'rgbcolor', 'rgbspot',
+            'save', 'schemaPosition', 'select', 'set', 'setChannelGroup', 'setKeyBias',
+            'setKeyContinuity', 'setKeyCurve',
+            'setKeyHermite', 'setKeyTension', 'setKeyValue', 'setParticle', 'setPoints',
+            'setTag', 'setValue', 'server', 'serverFlags', 'sortA', 'sortD', 'surface',
+            'trunc',
+            'write', 'writeln', 'writeByte', 'writeData', 'writeNumber', 'writeDouble',
+            'writeShort', 'writeString', 'writeVector',
+            'vertex', 'vertexCount',
+            'zoomFactor'
+            ),
+        2 => array(
+            'abs', 'acos', 'angle', 'append', 'ascii', 'asin', 'atan',
+            'binary',
+            'ceil', 'center', 'chdir', 'clearimage', 'cloned', 'comringattach',
+            'comringdecode', 'comringdetach', 'comringencode', 'comringmsg', 'cos',
+            'cosh', 'cot', 'cross2d', 'cross3d', 'csc', 'ctlstring', 'ctlinteger',
+            'ctlnumber', 'ctlvector', 'ctldistance', 'ctlchoice', 'ctltext',
+            'ctlcolor', 'ctlsurface', 'ctlfont', 'ctlpopup', 'ctledit', 'ctlpercent',
+            'ctlangle', 'ctlrgb', 'ctlhsv', 'ctlcheckbox', 'ctlstate', 'ctlfilename',
+            'ctlbutton', 'ctllistbox', 'ctlslider', 'ctlminislider', 'ctlsep', 'ctlimage',
+            'ctltab', 'ctlallitems', 'ctlmeshitems', 'ctlcameraitems', 'ctllightitems',
+            'ctlboneitems', 'ctlimageitems', 'ctlchannel', 'ctlviewport', 'Control_Management',
+            'ctlpage', 'ctlgroup', 'ctlposition', 'ctlactive', 'ctlvisible', 'ctlalign',
+            'ctlrefresh', 'ctlmenu', 'ctlinfo',
+            'date', 'debug', 'deg', 'dot2d', 'dot3d', 'drawborder', 'drawbox', 'drawcircle',
+            'drawelipse', 'drawerase', 'drawfillcircle', 'drawfillelipse', 'drawline',
+            'drawpixel', 'drawtext', 'drawtextwidth', 'drawtextheight', 'dump',
+            'error', 'exp', 'expose', 'extent',
+            'fac', 'filecrc', 'filedelete', 'fileexists', 'filefind', 'filerename',
+            'filestat', 'floor', 'format', 'frac', 'fullpath',
+            'gamma', 'getdir', 'getenv', 'getfile', 'getfirstitem', 'getsep', 'getvalue',
+            'globalrecall', 'globalstore',
+            'hash', 'hex', 'hostBuild', 'hostVersion', 'hypot',
+            'info', 'integer',
+            'library', 'licenseId', 'lscriptVersion', 'load', 'loadimage', 'log', 'log10',
+            'matchdirs', 'matchfiles', 'max', 'min', 'mkdir', 'mod', 'monend', 'moninit', 'monstep',
+            'nil', 'normalize', 'number',
+            'octal', 'overlayglyph',
+            'parse', 'platform', 'pow',
+            'rad', 'random', 'randu', 'range', 'read', 'readdouble', 'readInt', 'readNumber',
+            'readShort', 'recall', 'regexp', 'reqabort', 'reqbegin', 'reqend', 'reqisopen',
+            'reqkeyboard', 'reqopen', 'reqposition', 'reqpost', 'reqredraw',
+            'reqsize', 'reqresize', 'requpdate', 'rmdir', 'round', 'runningUnder',
+            'save', 'sec', 'select', 'selector', 'setdesc', 'setvalue', 'sin', 'sinh', 'size',
+            'sizeof', 'sleep', 'spawn', 'split', 'sqrt', 'step', 'store', 'string', 'strleft',
+            'strlower', 'strright', 'strsub', 'strupper',
+            'tan', 'tanh', 'targetobject', 'terminate', 'text', 'time',
+            'wait', 'warn', 'when', 'write', 'writeDouble', 'writeInt', 'writeNumber', 'writeShort',
+            'var', 'vector', 'visitnodes', 'vmag',
+            ),
+        5 => array(
+            'addcurve', 'addpoint', 'addpolygon', 'addquad', 'addtriangle', 'alignpols',
+            'autoflex', 'axisdrill',
+            'bend', 'bevel', 'boolean', 'boundingbox',
+            'changepart', 'changesurface', 'close', 'closeall', 'cmdseq', 'copy', 'copysurface',
+            'createsurface', 'cut',
+            'deformregion', 'delete',
+            'editbegin', 'editend', 'exit', 'extrude',
+            'fixedflex', 'flip', 'fontclear', 'fontcount', 'fontindex', 'fontload',
+            'fontname', 'fracsubdivide', 'freezecurves',
+            'getdefaultsurface',
+            'jitter',
+            'lathe', 'layerName', 'layerVisible', 'lyrbg', 'lyrdata', 'lyrempty', 'lyremptybg',
+            'lyremptyfg', 'lyrfg', 'lyrsetbg', 'lyrsetfg', 'lyrswap',
+            'magnet', 'make4patch', 'makeball', 'makebox', 'makecone', 'makedisc',
+            'maketesball', 'maketext', 'mergepoints', 'mergepols', 'meshedit', 'mirror',
+            'morphpols', 'move',
+            'new', 'nextsurface',
+            'paste', 'pathclone', 'pathextrude', 'pixel', 'pointcount', 'pointinfo',
+            'pointmove', 'pole', 'polycount', 'polyinfo', 'polynormal', 'polypointcount',
+            'polypoints', 'polysurface',
+            'quantize',
+            'railclone', 'railextrude', 'redo', 'removepols', 'rempoint', 'rempoly',
+            'renamesurface', 'revert', 'rotate',
+            'scale', 'selhide', 'selinvert', 'selmode', 'selpoint', 'selpolygon', 'selunhide',
+            'selectvmap', 'setlayername', 'setobject', 'setpivot', 'setsurface', 'shapebevel',
+            'shear', 'skinpols', 'smooth', 'smoothcurves', 'smoothscale', 'smoothshift',
+            'soliddrill', 'splitpols', 'subdivide', 'swaphidden',
+            'taper', 'triple', 'toggleCCend', 'toggleCCstart', 'togglepatches', 'twist',
+            'undo', 'undogroupend', 'undogroupbegin', 'unifypols', 'unweld',
+            'vortex',
+            'weldaverage', 'weldpoints'
+            ),
+        6 => array(
+            'About', 'AboutOpenGL', 'AdaptiveSampling', 'AdaptiveThreshold',
+            'AddAreaLight', 'AddBone', 'AddButton', 'AddCamera', 'AddChildBone',
+            'AddDistantLight', 'AddEnvelope', 'AddLinearLight', 'AddNull',
+            'AddPartigon', 'AddPlugins', 'AddPointLight', 'AddPosition',
+            'AddRotation', 'AddScale', 'AddSpotlight', 'AddToSelection',
+            'AdjustRegionTool', 'AffectCaustics', 'AffectDiffuse', 'AffectOpenGL',
+            'AffectSpecular', 'AlertLevel', 'AmbientColor', 'AmbientIntensity',
+            'Antialiasing', 'ApertureHeight', 'ApplyServer', 'AreaLight',
+            'AutoConfirm', 'AutoFrameAdvance', 'AutoKey',
+            'BackdropColor', 'BackView', 'BController', 'BLimits', 'BLurLength', 'BoneActive',
+            'BoneFalloffType', 'BoneJointComp', 'BoneJointCompAmounts', 'BoneJointCompParent',
+            'BoneLimitedRange', 'BoneMaxRange', 'BoneMinRange', 'BoneMuscleFlex',
+            'BoneMuscleFlexAmounts', 'BoneMuscleFlexParent', 'BoneNormalization',
+            'BoneRestLength', 'BoneRestPosition', 'BoneRestRotation', 'BoneSource',
+            'BoneStrength', 'BoneStrengthMultiply', 'BoneWeightMapName', 'BoneWeightMapOnly',
+            'BoneWeightShade', 'BoneXRay', 'BottomView', 'BoundingBoxThreshold',
+            'BStiffness',
+            'CacheCaustics', 'CacheRadiosity', 'CacheShadowMap',
+            'CameraMask', 'CameraView', 'CameraZoomTool', 'CastShadow', 'CausticIntensity',
+            'CenterItem', 'CenterMouse', 'ChangeTool', 'ClearAllBones', 'ClearAllCameras',
+            'ClearAllLights', 'ClearAllObjects', 'ClearAudio', 'ClearScene', 'ClearSelected',
+            'Clone', 'CommandHistory', 'CommandInput', 'Compositing', 'ConeAngleTool',
+            'ContentDirectory', 'CreateKey',
+            'DecreaseGrid', 'DeleteKey', 'DepthBufferAA', 'DepthOfField', 'DisplayOptions',
+            'DistantLight', 'DrawAntialiasing', 'DrawBones', 'DrawChildBones', 'DynamicUpdate',
+            'EditBones', 'EditCameras', 'EditKeys', 'EditLights',
+            'EditMenus', 'EditObjects', 'EditPlugins', 'EditServer', 'EnableCaustics',
+            'EnableDeformations', 'EnableIK', 'EnableLensFlares', 'EnableRadiosity', 'EnableServer',
+            'EnableShadowMaps', 'EnableVIPER', 'EnableVolumetricLights', 'EnableXH',
+            'EnableYP', 'EnableZB', 'EnahancedAA', 'ExcludeLight', 'ExcludeObject',
+            'EyeSeparation',
+            'FasterBones', 'FirstFrame', 'FirstItem', 'FitAll', 'FitSelected',
+            'FlareIntensity', 'FlareOptions', 'FocalDistance', 'FogColor', 'FogMaxAmount',
+            'FogMaxDistance', 'FogMinAmount', 'FogMinDistance', 'FogType', 'FractionalFrames',
+            'FrameSize', 'FramesPerSecond', 'FrameStep', 'FreePreview', 'FrontView', 'FullTimeIK',
+            'GeneralOptions', 'Generics', 'GlobalApertureHeight', 'GlobalBlurLength',
+            'GlobalFrameSize', 'GlobalIllumination', 'GlobalMaskPosition', 'GlobalMotionBlur',
+            'GlobalParticleBlur', 'GlobalPixelAspect', 'GlobalResolutionMulitplier', 'GoalItem',
+            'GoalStrength', 'GoToFrame', 'GradientBackdrop', 'GraphEditor', 'GridSize', 'GroundColor',
+            'HController', 'HideToolbar', 'HideWindows', 'HLimits', 'HStiffness',
+            'ImageEditor', 'ImageProcessing', 'IncludeLight', 'IncludeObject', 'IncreaseGrid',
+            'IndirectBounces', 'Item_SetWindowPos', 'ItemActive', 'ItemColor', 'ItemLock',
+            'ItemProperties', 'ItemVisibilty',
+            'KeepGoalWithinReach',
+            'LastFrame', 'LastItem', 'LastPluginInterface', 'Layout_SetWindowPos',
+            'Layout_SetWindowSize', 'LeftView', 'LensFlare', 'LensFStop', 'LightColor',
+            'LightConeAngle', 'LightEdgeAngle', 'LightFalloffType', 'LightIntensity',
+            'LightIntensityTool', 'LightQuality', 'LightRange', 'LightView', 'LimitB',
+            'LimitDynamicRange', 'LimitedRegion', 'LimitH', 'LimitP', 'LinearLight',
+            'LoadAudio', 'LoadFromScene', 'LoadMotion', 'LoadObject', 'LoadObjectLayer',
+            'LoadPreview', 'LoadScene', 'LocalCoordinateSystem',
+            'MakePreview', 'MaskColor', 'MaskPosition', 'MasterPlugins', 'MatchGoalOrientation',
+            'MatteColor', 'MatteObject', 'MetaballResolution', 'Model', 'MorphAmount',
+            'MorphAmountTool', 'MorphMTSE', 'MorphSurfaces', 'MorphTarget', 'MotionBlur',
+            'MotionBlurDOFPreview', 'MotionOptions', 'MovePathTool', 'MovePivotTool', 'MoveTool',
+            'NadirColor', 'NetRender', 'NextFrame', 'NextItem', 'NextKey', 'NextSibling',
+            'NextViewLayout', 'NoiseReduction', 'Numeric',
+            'ObjectDissolve',
+            'ParentCoordinateSystem', 'ParentInPlace', 'ParentItem',
+            'ParticleBlur', 'PathAlignLookAhead', 'PathAlignMaxLookSteps', 'PathAlignReliableDist',
+            'Pause', 'PController', 'PerspectiveView',
+            'PivotPosition', 'PivotRotation', 'PixelAspect', 'PlayAudio', 'PlayBackward',
+            'PlayForward', 'PlayPreview', 'PLimits', 'PointLight', 'PolygonEdgeColor',
+            'PolygonEdgeFlags', 'PolygonEdgeThickness', 'PolygonEdgeZScale', 'PolygonSize',
+            'Position', 'Presets', 'PreviewFirstFrame', 'PreviewFrameStep', 'PreviewLastFrame',
+            'PreviewOptions', 'PreviousFrame', 'PreviousItem', 'PreviousKey', 'PreviousSibling',
+            'PreviousViewLayout', 'PStiffness',
+            'Quit',
+            'RadiosityIntensity', 'RadiosityTolerance', 'RadiosityType', 'RayRecursionLimit',
+            'RayTraceReflection', 'RayTraceShadows',
+            'RayTraceTransparency', 'ReceiveShadow', 'RecentContentDirs', 'RecentScenes',
+            'ReconstructionFilter', 'RecordMaxAngles', 'RecordMinAngles', 'RecordPivotRotation',
+            'RecordRestPosition', 'Redraw', 'RedrawNow', 'Refresh', 'RefreshNow', 'RegionPosition',
+            'RemoveEnvelope', 'RemoveFromSelection', 'RemoveServer', 'Rename', 'RenderFrame',
+            'RenderOptions', 'RenderScene', 'RenderSelected', 'RenderThreads',
+            'ReplaceObjectLayer', 'ReplaceWithNull', 'ReplaceWithObject', 'Reset',
+            'ResolutionMultiplier', 'RestLengthTool', 'RightView', 'RotatePivotTool',
+            'RotateTool', 'Rotation',
+            'SaveAllObjects', 'SaveCommandList', 'SaveCommandMessages',
+            'SaveEndomorph', 'SaveLight', 'SaveLWSC1', 'SaveMotion', 'SaveObject', 'SaveObjectCopy',
+            'SavePreview', 'SaveScene', 'SaveSceneAs', 'SaveSceneCopy', 'SaveTransformed',
+            'SaveViewLayout', 'Scale', 'Scene_SetWindowPos', 'Scene_SetWindowSize',
+            'SceneEditor', 'SchematicPosition', 'SchematicView', 'SelectAllBones',
+            'SelectAllCameras', 'SelectAllLights', 'SelectAllObjects', 'SelectByName',
+            'SelectChild', 'SelectItem', 'SelectParent', 'SelfShadow', 'ShadowColor',
+            'ShadowExclusion', 'ShadowMapAngle', 'ShadowMapFitCone', 'ShadowMapFuzziness',
+            'ShadowMapSize', 'ShadowType', 'ShowCages', 'ShowFieldChart', 'ShowHandles',
+            'ShowIKChains', 'ShowMotionPaths', 'ShowSafeAreas', 'ShowTargetLines',
+            'ShrinkEdgesWithDistance', 'SingleView', 'SizeTool', 'SkelegonsToBones', 'SkyColor',
+            'Spotlight', 'SquashTool', 'Statistics', 'StatusMsg', 'Stereoscopic', 'StretchTool',
+            'SubdivisionOrder', 'SubPatchLevel', 'SurfaceEditor', 'Synchronize',
+            'TargetItem', 'TopView',
+            'UnaffectedByFog', 'UnaffectedByIK', 'Undo', 'UnseenByAlphaChannel', 'UnseenByCamera',
+            'UnseenByRays', 'UseGlobalResolution', 'UseGlobalBlur', 'UseGlobalMask',
+            'UseMorphedPositions',
+            'ViewLayout', 'VIPER', 'VolumetricLighting',
+            'VolumetricLightingOptions', 'VolumetricRadiosity', 'Volumetrics',
+            'WorldCoordinateSystem',
+            'XYView', 'XZView',
+            'ZenithColor', 'ZoomFactor', 'ZoomIn', 'ZoomInX2', 'ZoomOut', 'ZoomOutX2', 'ZYView',
+            'Camera', 'Channel', 'ChannelGroup', 'Envelope', 'File', 'Glyph', 'Icon', 'Image',
+            'Light', 'Mesh', 'Scene', 'Surface', 'VMap'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '<', '>', '+', '-', '*', '/', '!', '%', '&', '@'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => true,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #FF6820; font-weight: bold;', //LS_COMMANDS
+            3 => 'color: #007F7F; font-weight: bold;', //LS_MEMBERS
+            4 => 'color: #800080; font-weight: bold;', //LS_METHODS
+            5 => 'color: #51BD95; font-weight: bold;', //LS_MODELER
+            6 => 'color: #416F85; font-weight: bold;', //LS_GENERAL
+            7 => 'color: #C92929; font-weight: bold;'  //LS_COMMANDS (cont)
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #7F7F7F;',
+            'MULTI' => 'color: #7F7F7F;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #0040A0;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #00C800;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #6953AC;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #0040A0;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            3 => array(
+                'DISALLOWED_BEFORE' => '(?<=\.)'
+                ),
+            4 => array(
+                'DISALLOWED_BEFORE' => '(?<=\.)'
+                )
+            )
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/lsl2.php b/examples/includes/geshi/geshi/lsl2.php
new file mode 100644 (file)
index 0000000..27c5580
--- /dev/null
@@ -0,0 +1,898 @@
+<?php
+/*************************************************************************************
+ * lsl2.php
+ * --------
+ * Author: William Fry (william.fry@nyu.edu)
+ * Copyright: (c) 2009 William Fry
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/02/04
+ *
+ * Linden Scripting Language (LSL2) language file for GeSHi.
+ *
+ *   Data derived and validated against the following:
+ *      http://wiki.secondlife.com/wiki/LSL_Portal
+ *      http://www.lslwiki.net/lslwiki/wakka.php?wakka=HomePage
+ *      http://rpgstats.com/wiki/index.php?title=Main_Page
+ *
+ * CHANGES
+ * -------
+ * 2009/02/05 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2009/02/05)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'LSL2',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array( // flow control
+            'do',
+            'else',
+            'for',
+            'if',
+            'jump',
+            'return',
+            'state',
+            'while',
+            ),
+        2 => array( // manifest constants
+            'ACTIVE',
+            'AGENT',
+            'AGENT_ALWAYS_RUN',
+            'AGENT_ATTACHMENTS',
+            'AGENT_AWAY',
+            'AGENT_BUSY',
+            'AGENT_CROUCHING',
+            'AGENT_FLYING',
+            'AGENT_IN_AIR',
+            'AGENT_MOUSELOOK',
+            'AGENT_ON_OBJECT',
+            'AGENT_SCRIPTED',
+            'AGENT_SITTING',
+            'AGENT_TYPING',
+            'AGENT_WALKING',
+            'ALL_SIDES',
+            'ANIM_ON',
+            'ATTACH_BACK',
+            'ATTACH_BELLY',
+            'ATTACH_CHEST',
+            'ATTACH_CHIN',
+            'ATTACH_HEAD',
+            'ATTACH_HUD_BOTTOM',
+            'ATTACH_HUD_BOTTOM_LEFT',
+            'ATTACH_HUD_BOTTOM_RIGHT',
+            'ATTACH_HUD_CENTER_1',
+            'ATTACH_HUD_CENTER_2',
+            'ATTACH_HUD_TOP_CENTER',
+            'ATTACH_HUD_TOP_LEFT',
+            'ATTACH_HUD_TOP_RIGHT',
+            'ATTACH_LEAR',
+            'ATTACH_LEYE',
+            'ATTACH_LFOOT',
+            'ATTACH_LHAND',
+            'ATTACH_LHIP',
+            'ATTACH_LLARM',
+            'ATTACH_LLLEG',
+            'ATTACH_LPEC',
+            'ATTACH_LSHOULDER',
+            'ATTACH_LUARM',
+            'ATTACH_LULEG',
+            'ATTACH_MOUTH',
+            'ATTACH_NOSE',
+            'ATTACH_PELVIS',
+            'ATTACH_REAR',
+            'ATTACH_REYE',
+            'ATTACH_RFOOT',
+            'ATTACH_RHAND',
+            'ATTACH_RHIP',
+            'ATTACH_RLARM',
+            'ATTACH_RLLEG',
+            'ATTACH_RPEC',
+            'ATTACH_RSHOULDER',
+            'ATTACH_RUARM',
+            'ATTACH_RULEG',
+            'CAMERA_ACTIVE',
+            'CAMERA_BEHINDNESS_ANGLE',
+            'CAMERA_BEHINDNESS_LAG',
+            'CAMERA_DISTANCE',
+            'CAMERA_FOCUS',
+            'CAMERA_FOCUS_LAG',
+            'CAMERA_FOCUS_LOCKED',
+            'CAMERA_FOCUS_OFFSET',
+            'CAMERA_FOCUS_THRESHOLD',
+            'CAMERA_PITCH',
+            'CAMERA_POSITION',
+            'CAMERA_POSITION_LAG',
+            'CAMERA_POSITION_LOCKED',
+            'CAMERA_POSITION_THRESHOLD',
+            'CHANGED_ALLOWED_DROP',
+            'CHANGED_COLOR',
+            'CHANGED_INVENTORY',
+            'CHANGED_LINK',
+            'CHANGED_OWNER',
+            'CHANGED_REGION',
+            'CHANGED_SCALE',
+            'CHANGED_SHAPE',
+            'CHANGED_TELEPORT',
+            'CHANGED_TEXTURE',
+            'CLICK_ACTION_NONE',
+            'CLICK_ACTION_OPEN',
+            'CLICK_ACTION_OPEN_MEDIA',
+            'CLICK_ACTION_PAY',
+            'CLICK_ACTION_SIT',
+            'CLICK_ACTION_TOUCH',
+            'CONTROL_BACK',
+            'CONTROL_DOWN',
+            'CONTROL_FWD',
+            'CONTROL_LBUTTON',
+            'CONTROL_LEFT',
+            'CONTROL_ML_LBUTTON',
+            'CONTROL_RIGHT',
+            'CONTROL_ROT_LEFT',
+            'CONTROL_ROT_RIGHT',
+            'CONTROL_UP',
+            'DATA_BORN',
+            'DATA_NAME',
+            'DATA_ONLINE',
+            'DATA_PAYINFO',
+            'DATA_RATING',
+            'DATA_SIM_POS',
+            'DATA_SIM_RATING',
+            'DATA_SIM_STATUS',
+            'DEBUG_CHANNEL',
+            'DEG_TO_RAD',
+            'EOF',
+            'FALSE',
+            'HTTP_BODY_MAXLENGTH',
+            'HTTP_BODY_TRUNCATED',
+            'HTTP_METHOD',
+            'HTTP_MIMETYPE',
+            'HTTP_VERIFY_CERT',
+            'INVENTORY_ALL',
+            'INVENTORY_ANIMATION',
+            'INVENTORY_BODYPART',
+            'INVENTORY_CLOTHING',
+            'INVENTORY_GESTURE',
+            'INVENTORY_LANDMARK',
+            'INVENTORY_NONE',
+            'INVENTORY_NOTECARD',
+            'INVENTORY_OBJECT',
+            'INVENTORY_SCRIPT',
+            'INVENTORY_SOUND',
+            'INVENTORY_TEXTURE',
+            'LAND_LEVEL',
+            'LAND_LOWER',
+            'LAND_NOISE',
+            'LAND_RAISE',
+            'LAND_REVERT',
+            'LAND_SMOOTH',
+            'LINK_ALL_CHILDREN',
+            'LINK_ALL_OTHERS',
+            'LINK_ROOT',
+            'LINK_SET',
+            'LINK_THIS',
+            'LIST_STAT_GEOMETRIC_MEAN',
+            'LIST_STAT_MAX',
+            'LIST_STAT_MEAN',
+            'LIST_STAT_MEDIAN',
+            'LIST_STAT_MIN',
+            'LIST_STAT_NUM_COUNT',
+            'LIST_STAT_RANGE',
+            'LIST_STAT_STD_DEV',
+            'LIST_STAT_SUM',
+            'LIST_STAT_SUM_SQUARES',
+            'LOOP',
+            'MASK_BASE',
+            'MASK_EVERYONE',
+            'MASK_GROUP',
+            'MASK_NEXT',
+            'MASK_OWNER',
+            'NULL_KEY',
+            'OBJECT_CREATOR',
+            'OBJECT_DESC',
+            'OBJECT_GROUP',
+            'OBJECT_NAME',
+            'OBJECT_OWNER',
+            'OBJECT_POS',
+            'OBJECT_ROT',
+            'OBJECT_UNKNOWN_DETAIL',
+            'OBJECT_VELOCITY',
+            'PARCEL_DETAILS_AREA',
+            'PARCEL_DETAILS_DESC',
+            'PARCEL_DETAILS_GROUP',
+            'PARCEL_DETAILS_NAME',
+            'PARCEL_DETAILS_OWNER',
+            'PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY',
+            'PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS',
+            'PARCEL_FLAG_ALLOW_CREATE_OBJECTS',
+            'PARCEL_FLAG_ALLOW_DAMAGE',
+            'PARCEL_FLAG_ALLOW_FLY',
+            'PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY',
+            'PARCEL_FLAG_ALLOW_GROUP_SCRIPTS',
+            'PARCEL_FLAG_ALLOW_LANDMARK',
+            'PARCEL_FLAG_ALLOW_SCRIPTS',
+            'PARCEL_FLAG_ALLOW_TERRAFORM',
+            'PARCEL_FLAG_LOCAL_SOUND_ONLY',
+            'PARCEL_FLAG_RESTRICT_PUSHOBJECT',
+            'PARCEL_FLAG_USE_ACCESS_GROUP',
+            'PARCEL_FLAG_USE_ACCESS_LIST',
+            'PARCEL_FLAG_USE_BAN_LIST',
+            'PARCEL_FLAG_USE_LAND_PASS_LIST',
+            'PARCEL_MEDIA_COMMAND_AGENT',
+            'PARCEL_MEDIA_COMMAND_AUTO_ALIGN',
+            'PARCEL_MEDIA_COMMAND_DESC',
+            'PARCEL_MEDIA_COMMAND_LOOP_SET',
+            'PARCEL_MEDIA_COMMAND_PAUSE',
+            'PARCEL_MEDIA_COMMAND_PLAY',
+            'PARCEL_MEDIA_COMMAND_SIZE',
+            'PARCEL_MEDIA_COMMAND_STOP',
+            'PARCEL_MEDIA_COMMAND_TEXTURE',
+            'PARCEL_MEDIA_COMMAND_TIME',
+            'PARCEL_MEDIA_COMMAND_TYPE',
+            'PARCEL_MEDIA_COMMAND_URL',
+            'PASSIVE',
+            'PAYMENT_INFO_ON_FILE',
+            'PAYMENT_INFO_USED',
+            'PAY_DEFAULT',
+            'PAY_HIDE',
+            'PERMISSION_ATTACH',
+            'PERMISSION_CHANGE_LINKS',
+            'PERMISSION_CONTROL_CAMERA',
+            'PERMISSION_DEBIT',
+            'PERMISSION_TAKE_CONTROLS',
+            'PERMISSION_TRACK_CAMERA',
+            'PERMISSION_TRIGGER_ANIMATION',
+            'PERM_ALL',
+            'PERM_COPY',
+            'PERM_MODIFY',
+            'PERM_MOVE',
+            'PERM_TRANSFER',
+            'PI',
+            'PI_BY_TWO',
+            'PRIM_BUMP_BARK',
+            'PRIM_BUMP_BLOBS',
+            'PRIM_BUMP_BRICKS',
+            'PRIM_BUMP_BRIGHT',
+            'PRIM_BUMP_CHECKER',
+            'PRIM_BUMP_CONCRETE',
+            'PRIM_BUMP_DARK',
+            'PRIM_BUMP_DISKS',
+            'PRIM_BUMP_GRAVEL',
+            'PRIM_BUMP_LARGETILE',
+            'PRIM_BUMP_NONE',
+            'PRIM_BUMP_SHINY',
+            'PRIM_BUMP_SIDING',
+            'PRIM_BUMP_STONE',
+            'PRIM_BUMP_STUCCO',
+            'PRIM_BUMP_SUCTION',
+            'PRIM_BUMP_TILE',
+            'PRIM_BUMP_WEAVE',
+            'PRIM_BUMP_WOOD',
+            'PRIM_COLOR',
+            'PRIM_FULLBRIGHT',
+            'PRIM_HOLE_CIRCLE',
+            'PRIM_HOLE_DEFAULT',
+            'PRIM_HOLE_SQUARE',
+            'PRIM_HOLE_TRIANGLE',
+            'PRIM_MATERIAL',
+            'PRIM_MATERIAL_FLESH',
+            'PRIM_MATERIAL_GLASS',
+            'PRIM_MATERIAL_LIGHT',
+            'PRIM_MATERIAL_METAL',
+            'PRIM_MATERIAL_PLASTIC',
+            'PRIM_MATERIAL_RUBBER',
+            'PRIM_MATERIAL_STONE',
+            'PRIM_MATERIAL_WOOD',
+            'PRIM_PHANTOM',
+            'PRIM_PHYSICS',
+            'PRIM_POSITION',
+            'PRIM_ROTATION',
+            'PRIM_SHINY_HIGH',
+            'PRIM_SHINY_LOW',
+            'PRIM_SHINY_MEDIUM',
+            'PRIM_SHINY_NONE',
+            'PRIM_SIZE',
+            'PRIM_TEMP_ON_REZ',
+            'PRIM_TEXTURE',
+            'PRIM_TYPE',
+            'PRIM_TYPE_BOX',
+            'PRIM_TYPE_CYLINDER',
+            'PRIM_TYPE_PRISM',
+            'PRIM_TYPE_RING',
+            'PRIM_TYPE_SPHERE',
+            'PRIM_TYPE_TORUS',
+            'PRIM_TYPE_TUBE',
+            'PSYS_PART_BOUNCE_MASK',
+            'PSYS_PART_EMISSIVE_MASK',
+            'PSYS_PART_END_ALPHA',
+            'PSYS_PART_END_COLOR',
+            'PSYS_PART_END_SCALE',
+            'PSYS_PART_FLAGS',
+            'PSYS_PART_FOLLOW_SRC_MASK',
+            'PSYS_PART_FOLLOW_VELOCITY_MASK',
+            'PSYS_PART_INTERP_COLOR_MASK',
+            'PSYS_PART_INTERP_SCALE_MASK',
+            'PSYS_PART_MAX_AGE',
+            'PSYS_PART_START_ALPHA',
+            'PSYS_PART_START_COLOR',
+            'PSYS_PART_START_SCALE',
+            'PSYS_PART_TARGET_LINEAR_MASK',
+            'PSYS_PART_TARGET_POS_MASK',
+            'PSYS_PART_WIND_MASK',
+            'PSYS_SRC_ACCEL',
+            'PSYS_SRC_ANGLE_BEGIN',
+            'PSYS_SRC_ANGLE_END',
+            'PSYS_SRC_BURST_PART_COUNT',
+            'PSYS_SRC_BURST_RADIUS',
+            'PSYS_SRC_BURST_RATE',
+            'PSYS_SRC_BURST_SPEED_MAX',
+            'PSYS_SRC_BURST_SPEED_MIN',
+            'PSYS_SRC_INNERANGLE',
+            'PSYS_SRC_MAX_AGE',
+            'PSYS_SRC_OMEGA',
+            'PSYS_SRC_OUTERANGLE',
+            'PSYS_SRC_PATTERN',
+            'PSYS_SRC_PATTERN_ANGLE',
+            'PSYS_SRC_PATTERN_ANGLE_CONE',
+            'PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY',
+            'PSYS_SRC_PATTERN_DROP',
+            'PSYS_SRC_PATTERN_EXPLODE',
+            'PSYS_SRC_TARGET_KEY',
+            'PSYS_SRC_TEXTURE',
+            'RAD_TO_DEG',
+            'REMOTE_DATA_CHANNEL',
+            'REMOTE_DATA_REQUEST',
+            'SCRIPTED',
+            'SQRT2',
+            'STATUS_BLOCK_GRAB',
+            'STATUS_DIE_AT_EDGE',
+            'STATUS_PHANTOM',
+            'STATUS_PHYSICS',
+            'STATUS_RETURN_AT_EDGE',
+            'STATUS_ROTATE_X',
+            'STATUS_ROTATE_Y',
+            'STATUS_ROTATE_Z',
+            'STATUS_SANDBOX',
+            'TRUE',
+            'TWO_PI',
+            'VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY',
+            'VEHICLE_ANGULAR_DEFLECTION_TIMESCALE',
+            'VEHICLE_ANGULAR_FRICTION_TIMESCALE',
+            'VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE',
+            'VEHICLE_ANGULAR_MOTOR_DIRECTION',
+            'VEHICLE_ANGULAR_MOTOR_TIMESCALE',
+            'VEHICLE_BANKING_EFFICIENCY',
+            'VEHICLE_BANKING_MIX',
+            'VEHICLE_BANKING_TIMESCALE',
+            'VEHICLE_BUOYANCY',
+            'VEHICLE_FLAG_CAMERA_DECOUPLED',
+            'VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT',
+            'VEHICLE_FLAG_HOVER_TERRAIN_ONLY',
+            'VEHICLE_FLAG_HOVER_UP_ONLY',
+            'VEHICLE_FLAG_HOVER_WATER_ONLY',
+            'VEHICLE_FLAG_LIMIT_MOTOR_UP',
+            'VEHICLE_FLAG_LIMIT_ROLL_ONLY',
+            'VEHICLE_FLAG_MOUSELOOK_BANK',
+            'VEHICLE_FLAG_MOUSELOOK_STEER',
+            'VEHICLE_FLAG_NO_DEFLECTION_UP',
+            'VEHICLE_HOVER_EFFICIENCY',
+            'VEHICLE_HOVER_HEIGHT',
+            'VEHICLE_HOVER_TIMESCALE',
+            'VEHICLE_LINEAR_DEFLECTION_EFFICIENCY',
+            'VEHICLE_LINEAR_DEFLECTION_TIMESCALE',
+            'VEHICLE_LINEAR_FRICTION_TIMESCALE',
+            'VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE',
+            'VEHICLE_LINEAR_MOTOR_DIRECTION',
+            'VEHICLE_LINEAR_MOTOR_OFFSET',
+            'VEHICLE_LINEAR_MOTOR_TIMESCALE',
+            'VEHICLE_REFERENCE_FRAME',
+            'VEHICLE_TYPE_AIRPLANE',
+            'VEHICLE_TYPE_BALLOON',
+            'VEHICLE_TYPE_BOAT',
+            'VEHICLE_TYPE_CAR',
+            'VEHICLE_TYPE_NONE',
+            'VEHICLE_TYPE_SLED',
+            'VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY',
+            'VEHICLE_VERTICAL_ATTRACTION_TIMESCALE',
+            'ZERO_ROTATION',
+            'ZERO_VECTOR',
+            ),
+        3 => array( // handlers
+            'at_rot_target',
+            'at_target',
+            'attached',
+            'changed',
+            'collision',
+            'collision_end',
+            'collision_start',
+            'control',
+            'dataserver',
+            'email',
+            'http_response',
+            'land_collision',
+            'land_collision_end',
+            'land_collision_start',
+            'link_message',
+            'listen',
+            'money',
+            'moving_end',
+            'moving_start',
+            'no_sensor',
+            'not_at_rot_target',
+            'not_at_target',
+            'object_rez',
+            'on_rez',
+            'remote_data',
+            'run_time_permissions',
+            'sensor',
+            'state_entry',
+            'state_exit',
+            'timer',
+            'touch',
+            'touch_end',
+            'touch_start',
+            ),
+        4 => array( // data types
+            'float',
+            'integer',
+            'key',
+            'list',
+            'rotation',
+            'string',
+            'vector',
+            ),
+        5 => array( // library
+            'default',
+            'llAbs',
+            'llAcos',
+            'llAddToLandBanList',
+            'llAddToLandPassList',
+            'llAdjustSoundVolume',
+            'llAllowInventoryDrop',
+            'llAngleBetween',
+            'llApplyImpulse',
+            'llApplyRotationalImpulse',
+            'llAsin',
+            'llAtan2',
+            'llAttachToAvatar',
+            'llAvatarOnSitTarget',
+            'llAxes2Rot',
+            'llAxisAngle2Rot',
+            'llBase64ToInteger',
+            'llBase64ToString',
+            'llBreakAllLinks',
+            'llBreakLink',
+            'llCeil',
+            'llClearCameraParams',
+            'llCloseRemoteDataChannel',
+            'llCloud',
+            'llCollisionFilter',
+            'llCollisionSound',
+            'llCollisionSprite',
+            'llCos',
+            'llCreateLink',
+            'llCSV2List',
+            'llDeleteSubList',
+            'llDeleteSubString',
+            'llDetachFromAvatar',
+            'llDetectedGrab',
+            'llDetectedGroup',
+            'llDetectedKey',
+            'llDetectedLinkNumber',
+            'llDetectedName',
+            'llDetectedOwner',
+            'llDetectedPos',
+            'llDetectedRot',
+            'llDetectedTouchBinormal',
+            'llDetectedTouchFace',
+            'llDetectedTouchNormal',
+            'llDetectedTouchPos',
+            'llDetectedTouchST',
+            'llDetectedTouchUV',
+            'llDetectedType',
+            'llDetectedVel',
+            'llDialog',
+            'llDie',
+            'llDumpList2String',
+            'llEdgeOfWorld',
+            'llEjectFromLand',
+            'llEmail',
+            'llEscapeURL',
+            'llEuler2Rot',
+            'llFabs',
+            'llFloor',
+            'llForceMouselook',
+            'llFrand',
+            'llGetAccel',
+            'llGetAgentInfo',
+            'llGetAgentLanguage',
+            'llGetAgentSize',
+            'llGetAlpha',
+            'llGetAndResetTime',
+            'llGetAnimation',
+            'llGetAnimationList',
+            'llGetAttached',
+            'llGetBoundingBox',
+            'llGetCameraPos',
+            'llGetCameraRot',
+            'llGetCenterOfMass',
+            'llGetColor',
+            'llGetCreator',
+            'llGetDate',
+            'llGetEnergy',
+            'llGetForce',
+            'llGetFreeMemory',
+            'llGetGeometricCenter',
+            'llGetGMTclock',
+            'llGetInventoryCreator',
+            'llGetInventoryKey',
+            'llGetInventoryName',
+            'llGetInventoryNumber',
+            'llGetInventoryPermMask',
+            'llGetInventoryType',
+            'llGetKey',
+            'llGetLandOwnerAt',
+            'llGetLinkKey',
+            'llGetLinkName',
+            'llGetLinkNumber',
+            'llGetListEntryType',
+            'llGetListLength',
+            'llGetLocalPos',
+            'llGetLocalRot',
+            'llGetMass',
+            'llGetNextEmail',
+            'llGetNotecardLine',
+            'llGetNumberOfNotecardLines',
+            'llGetNumberOfPrims',
+            'llGetNumberOfSides',
+            'llGetObjectDesc',
+            'llGetObjectDetails',
+            'llGetObjectMass',
+            'llGetObjectName',
+            'llGetObjectPermMask',
+            'llGetObjectPrimCount',
+            'llGetOmega',
+            'llGetOwner',
+            'llGetOwnerKey',
+            'llGetParcelDetails',
+            'llGetParcelFlags',
+            'llGetParcelMaxPrims',
+            'llGetParcelPrimCount',
+            'llGetParcelPrimOwners',
+            'llGetPermissions',
+            'llGetPermissionsKey',
+            'llGetPos',
+            'llGetPrimitiveParams',
+            'llGetRegionAgentCount',
+            'llGetRegionCorner',
+            'llGetRegionFlags',
+            'llGetRegionFPS',
+            'llGetRegionName',
+            'llGetRegionTimeDilation',
+            'llGetRootPosition',
+            'llGetRootRotation',
+            'llGetRot',
+            'llGetScale',
+            'llGetScriptName',
+            'llGetScriptState',
+            'llGetSimulatorHostname',
+            'llGetStartParameter',
+            'llGetStatus',
+            'llGetSubString',
+            'llGetSunDirection',
+            'llGetTexture',
+            'llGetTextureOffset',
+            'llGetTextureRot',
+            'llGetTextureScale',
+            'llGetTime',
+            'llGetTimeOfDay',
+            'llGetTimestamp',
+            'llGetTorque',
+            'llGetUnixTime',
+            'llGetVel',
+            'llGetWallclock',
+            'llGiveInventory',
+            'llGiveInventoryList',
+            'llGiveMoney',
+            'llGround',
+            'llGroundContour',
+            'llGroundNormal',
+            'llGroundRepel',
+            'llGroundSlope',
+            'llHTTPRequest',
+            'llInsertString',
+            'llInstantMessage',
+            'llIntegerToBase64',
+            'llKey2Name',
+            'llList2CSV',
+            'llList2Float',
+            'llList2Integer',
+            'llList2Key',
+            'llList2List',
+            'llList2ListStrided',
+            'llList2Rot',
+            'llList2String',
+            'llList2Vector',
+            'llListen',
+            'llListenControl',
+            'llListenRemove',
+            'llListFindList',
+            'llListInsertList',
+            'llListRandomize',
+            'llListReplaceList',
+            'llListSort',
+            'llListStatistics',
+            'llLoadURL',
+            'llLog',
+            'llLog10',
+            'llLookAt',
+            'llLoopSound',
+            'llLoopSoundMaster',
+            'llLoopSoundSlave',
+            'llMapDestination',
+            'llMD5String',
+            'llMessageLinked',
+            'llMinEventDelay',
+            'llModifyLand',
+            'llModPow',
+            'llMoveToTarget',
+            'llOffsetTexture',
+            'llOpenRemoteDataChannel',
+            'llOverMyLand',
+            'llOwnerSay',
+            'llParcelMediaCommandList',
+            'llParcelMediaQuery',
+            'llParseString2List',
+            'llParseStringKeepNulls',
+            'llParticleSystem',
+            'llPassCollisions',
+            'llPassTouches',
+            'llPlaySound',
+            'llPlaySoundSlave',
+            'llPow',
+            'llPreloadSound',
+            'llPushObject',
+            'llRegionSay',
+            'llReleaseControls',
+            'llRemoteDataReply',
+            'llRemoteDataSetRegion',
+            'llRemoteLoadScriptPin',
+            'llRemoveFromLandBanList',
+            'llRemoveFromLandPassList',
+            'llRemoveInventory',
+            'llRemoveVehicleFlags',
+            'llRequestAgentData',
+            'llRequestInventoryData',
+            'llRequestPermissions',
+            'llRequestSimulatorData',
+            'llResetLandBanList',
+            'llResetLandPassList',
+            'llResetOtherScript',
+            'llResetScript',
+            'llResetTime',
+            'llRezAtRoot',
+            'llRezObject',
+            'llRot2Angle',
+            'llRot2Axis',
+            'llRot2Euler',
+            'llRot2Fwd',
+            'llRot2Left',
+            'llRot2Up',
+            'llRotateTexture',
+            'llRotBetween',
+            'llRotLookAt',
+            'llRotTarget',
+            'llRotTargetRemove',
+            'llRound',
+            'llSameGroup',
+            'llSay',
+            'llScaleTexture',
+            'llScriptDanger',
+            'llSendRemoteData',
+            'llSensor',
+            'llSensorRemove',
+            'llSensorRepeat',
+            'llSetAlpha',
+            'llSetBuoyancy',
+            'llSetCameraAtOffset',
+            'llSetCameraEyeOffset',
+            'llSetCameraParams',
+            'llSetClickAction',
+            'llSetColor',
+            'llSetDamage',
+            'llSetForce',
+            'llSetForceAndTorque',
+            'llSetHoverHeight',
+            'llSetLinkAlpha',
+            'llSetLinkColor',
+            'llSetLinkPrimitiveParams',
+            'llSetLinkTexture',
+            'llSetLocalRot',
+            'llSetObjectDesc',
+            'llSetObjectName',
+            'llSetParcelMusicURL',
+            'llSetPayPrice',
+            'llSetPos',
+            'llSetPrimitiveParams',
+            'llSetRemoteScriptAccessPin',
+            'llSetRot',
+            'llSetScale',
+            'llSetScriptState',
+            'llSetSitText',
+            'llSetSoundQueueing',
+            'llSetSoundRadius',
+            'llSetStatus',
+            'llSetText',
+            'llSetTexture',
+            'llSetTextureAnim',
+            'llSetTimerEvent',
+            'llSetTorque',
+            'llSetTouchText',
+            'llSetVehicleFlags',
+            'llSetVehicleFloatParam',
+            'llSetVehicleRotationParam',
+            'llSetVehicleType',
+            'llSetVehicleVectorParam',
+            'llSHA1String',
+            'llShout',
+            'llSin',
+            'llSitTarget',
+            'llSleep',
+            'llSqrt',
+            'llStartAnimation',
+            'llStopAnimation',
+            'llStopHover',
+            'llStopLookAt',
+            'llStopMoveToTarget',
+            'llStopSound',
+            'llStringLength',
+            'llStringToBase64',
+            'llStringTrim',
+            'llSubStringIndex',
+            'llTakeControls',
+            'llTan',
+            'llTarget',
+            'llTargetOmega',
+            'llTargetRemove',
+            'llTeleportAgentHome',
+            'llToLower',
+            'llToUpper',
+            'llTriggerSound',
+            'llTriggerSoundLimited',
+            'llUnescapeURL',
+            'llUnSit',
+            'llVecDist',
+            'llVecMag',
+            'llVecNorm',
+            'llVolumeDetect',
+            'llWater',
+            'llWhisper',
+            'llWind',
+            'llXorBase64StringsCorrect',
+            ),
+        6 => array( // deprecated
+            'llMakeExplosion',
+            'llMakeFire',
+            'llMakeFountain',
+            'llMakeSmoke',
+            'llSound',
+            'llSoundPreload',
+            'llXorBase64Strings',
+            ),
+        7 => array( // unimplemented
+            'llPointAt',
+            'llRefreshPrimURL',
+            'llReleaseCamera',
+            'llRemoteLoadScript',
+            'llSetPrimURL',
+            'llStopPointAt',
+            'llTakeCamera',
+            'llTextBox',
+            ),
+        8 => array( // God mode
+            'llGodLikeRezObject',
+            'llSetInventoryPermMask',
+            'llSetObjectPermMask',
+            ),
+        ),
+    'SYMBOLS' => array(
+        '{', '}', '(', ')', '[', ']',
+        '=', '+', '-', '*', '/',
+        '+=', '-=', '*=', '/=', '++', '--',
+        '!', '%', '&amp;', '|', '&amp;&amp;', '||',
+        '==', '!=', '&lt;', '&gt;', '&lt;=', '&gt;=',
+        '~', '&lt;&lt;', '&gt;&gt;', '^', ':',
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => true,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff;',
+            2 => 'color: #000080;',
+            3 => 'color: #008080;',
+            4 => 'color: #228b22;',
+            5 => 'color: #b22222;',
+            6 => 'color: #8b0000; background-color: #ffff00;',
+            7 => 'color: #8b0000; background-color: #fa8072;',
+            8 => 'color: #000000; background-color: #ba55d3;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #ff7f50; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #006400;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+        4 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+        5 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+        6 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+        7 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+        8 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/lua.php b/examples/includes/geshi/geshi/lua.php
new file mode 100644 (file)
index 0000000..58ed30a
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+/*************************************************************************************
+ * lua.php
+ * -------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/10
+ *
+ * LUA language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/26 (1.0.2)
+ *  -  Added support for objects and methods
+ *  -  Removed unusable keywords
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Lua',
+    'COMMENT_SINGLE' => array(1 => "--"),
+    'COMMENT_MULTI' => array('--[[' => ']]'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'and','break','do','else','elseif','end','false','for','function','if',
+            'in','local','nil','not','or','repeat','return','then','true','until','while',
+            '_VERSION','assert','collectgarbage','dofile','error','gcinfo','loadfile','loadstring',
+            'print','tonumber','tostring','type','unpack',
+            '_ALERT','_ERRORMESSAGE','_INPUT','_PROMPT','_OUTPUT',
+            '_STDERR','_STDIN','_STDOUT','call','dostring','foreach','foreachi','getn','globals','newtype',
+            'rawget','rawset','require','sort','tinsert','tremove',
+            'abs','acos','asin','atan','atan2','ceil','cos','deg','exp',
+            'floor','format','frexp','gsub','ldexp','log','log10','max','min','mod','rad','random','randomseed',
+            'sin','sqrt','strbyte','strchar','strfind','strlen','strlower','strrep','strsub','strupper','tan',
+            'openfile','closefile','readfrom','writeto','appendto',
+            'remove','rename','flush','seek','tmpfile','tmpname','read','write',
+            'clock','date','difftime','execute','exit','getenv','setlocale','time',
+            '_G','getfenv','getmetatable','ipairs','loadlib','next','pairs','pcall',
+            'rawegal','setfenv','setmetatable','xpcall',
+            'string.byte','string.char','string.dump','string.find','string.len',
+            'string.lower','string.rep','string.sub','string.upper','string.format','string.gfind','string.gsub',
+            'table.concat','table.foreach','table.foreachi','table.getn','table.sort','table.insert','table.remove','table.setn',
+            'math.abs','math.acos','math.asin','math.atan','math.atan2','math.ceil','math.cos','math.deg','math.exp',
+            'math.floor','math.frexp','math.ldexp','math.log','math.log10','math.max','math.min','math.mod',
+            'math.pi','math.rad','math.random','math.randomseed','math.sin','math.sqrt','math.tan',
+            'coroutine.create','coroutine.resume','coroutine.status',
+            'coroutine.wrap','coroutine.yield',
+            'io.close','io.flush','io.input','io.lines','io.open','io.output','io.read','io.tmpfile','io.type','io.write',
+            'io.stdin','io.stdout','io.stderr',
+            'os.clock','os.date','os.difftime','os.execute','os.exit','os.getenv','os.remove','os.rename',
+            'os.setlocale','os.time','os.tmpname',
+            'string','table','math','coroutine','io','os','debug'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>', '=', ';'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #b1b100;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/m68k.php b/examples/includes/geshi/geshi/m68k.php
new file mode 100644 (file)
index 0000000..9c16d7d
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+/*************************************************************************************
+ * m68k.php
+ * --------
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2007 Benny Baumann (http://www.omorphia.de/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/02/06
+ *
+ * Motorola 68000 Assembler language file for GeSHi.
+ *
+ * Syntax definition as commonly used by the motorola documentation for the
+ * MC68HC908GP32 Microcontroller (and maybe others).
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2007/06/02 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2007/06/02)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Motorola 68000 Assembler',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /*CPU*/
+        1 => array(
+            'adc','add','ais','aix','and','asl','asr','bcc','bclr','bcs','beq',
+            'bge','bgt','bhcc','bhcs','bhi','bhs','bih','bil','bit','ble','blo',
+            'bls','blt','bmc','bmi','bms','bne','bpl','bra','brclr','brn',
+            'brset','bset','bsr','cbeq','clc','cli','clr','cmp','com','cphx',
+            'cpx','daa','dbnz','dec','div','eor','inc','jmp','jsr','lda','ldhx',
+            'ldx','lsl','lsr','mov','mul','neg','nop','nsa','ora','psha','pshh',
+            'pshx','pula','pulh','pulx','rol','ror','rsp','rti','rts','sbc',
+            'sec','sei','sta','sthx','stop','stx','sub','swi','tap','tax','tpa',
+            'tst','tsx','txa','txs','wait'
+        ),
+        /*registers*/
+        2 => array(
+            'a','h','x',
+            'hx','sp'
+            ),
+        /*Directive*/
+        3 => array(
+            '#define','#endif','#else','#ifdef','#ifndef','#include','#undef',
+            '.db','.dd','.df','.dq','.dt','.dw','.end','.org','equ'
+            ),
+        ),
+    'SYMBOLS' => array(
+        ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff; font-weight:bold;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #46aa03; font-weight:bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #dd22dd;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #22bbff;',
+            1 => 'color: #22bbff;',
+            2 => 'color: #993333;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Hex numbers
+        0 => '#?0[0-9a-fA-F]{1,32}[hH]',
+        //Binary numbers
+        1 => '\%[01]{1,64}[bB]',
+        //Labels
+        2 => '^[_a-zA-Z][_a-zA-Z0-9]*?\:'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 8
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/make.php b/examples/includes/geshi/geshi/make.php
new file mode 100644 (file)
index 0000000..b15f459
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+/*************************************************************************************
+ * make.php
+ * --------
+ * Author: Neil Bird <phoenix@fnxweb.com>
+ * Copyright: (c) 2008 Neil Bird
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/08/26
+ *
+ * make language file for GeSHi.
+ *
+ * (GNU make specific)
+ *
+ * CHANGES
+ * -------
+ * 2008/09/05 (1.0.0)
+ *  -  First Release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'GNU make',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_REGEXP' => array(
+        //Escaped String Starters
+        2 => "/\\\\['\"]/siU"
+        ),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            // core
+            'ifeq', 'else', 'endif', 'ifneq', 'ifdef', 'ifndef',
+            'include', 'vpath', 'export', 'unexport', 'override',
+            'info', 'warning', 'error'
+            ),
+        2 => array(
+            // macros, literals
+            '.SUFFIXES', '.PHONY', '.DEFAULT', '.PRECIOUS', '.IGNORE', '.SILENT', '.EXPORT_ALL_VARIABLES', '.KEEP_STATE',
+            '.LIBPATTERNS', '.NOTPARALLEL', '.DELETE_ON_ERROR', '.INTERMEDIATE', '.POSIX', '.SECONDARY'
+            ),
+        /*
+        3 => array(
+            // funcs - see regex
+            //'subst', 'addprefix', 'addsuffix', 'basename', 'call', 'dir', 'error', 'eval', 'filter-out', 'filter',
+            //'findstring', 'firstword', 'foreach', 'if', 'join', 'notdir', 'origin', 'patsubst', 'shell', 'sort', 'strip',
+            //'suffix', 'warning', 'wildcard', 'word', 'wordlist', 'words'
+            )*/
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}',
+        '!', '@', '%', '&', '|', '/',
+        '<', '>',
+        '=', '-', '+', '*',
+        '.', ':', ',', ';',
+        '$'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        //3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #666622; font-weight: bold;',
+            2 => 'color: #990000;',
+            //3 => 'color: #000000; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #339900; font-style: italic;',
+            2 => 'color: #000099; font-weight: bold;',
+            'MULTI' => ''
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(  # keep same as symbols so as to make ${} and $() equiv.
+            0 => 'color: #004400;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #CC2200;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #CC2200;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #004400;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #000088; font-weight: bold;',
+            1 => 'color: #0000CC; font-weight: bold;',
+            2 => 'color: #000088;'
+            ),
+        'SCRIPT' => array(),
+        'METHODS' => array()
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        //3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        //Simple variables
+        0 => "\\$(?:[^{(&]|&(?:amp|lt|gt);)",
+        //Complex variables/functions [built-ins]
+        1 => array(
+            GESHI_SEARCH => '(\\$[({])(subst|addprefix|addsuffix|basename|call|dir|error|eval|filter-out|filter,|findstring|firstword|foreach|if|join|notdir|origin|patsubst|shell|sort|strip,|suffix|warning|wildcard|word|wordlist|words)([ })])',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+            //Complex variables/functions [others]
+        2 => array(
+            GESHI_SEARCH => '(\\$[({])([A-Za-z_][A-Za-z_0-9]*)([ })])',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array(),
+    'TAB_WIDTH' => 8
+// vim: set sw=4 sts=4 :
+);
+?>
diff --git a/examples/includes/geshi/geshi/matlab.php b/examples/includes/geshi/geshi/matlab.php
new file mode 100644 (file)
index 0000000..d3963ef
--- /dev/null
@@ -0,0 +1,227 @@
+<?php
+/*************************************************************************************
+ * matlab.php
+ * -----------
+ * Author: Florian Knorn (floz@gmx.de)
+ * Copyright: (c) 2004 Florian Knorn (http://www.florian-knorn.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/02/09
+ *
+ * Matlab M-file language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006-03-25 (1.0.7.22)
+ *   - support for the transpose operator
+ *   - many keywords added
+ *   - links to the matlab documentation at mathworks
+ *      by: Olivier Verdier (olivier.verdier@free.fr)
+ * 2005/05/07 (1.0.0)
+ *   -  First Release
+ *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Matlab M',
+    'COMMENT_SINGLE' => array(1 => '%'),
+    'COMMENT_MULTI' => array(),
+    //Matlab Strings
+    'COMMENT_REGEXP' => array(
+        2 => "/(?<![\\w\\)\\]\\}\\.])('[^\\n']*?')/"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'break', 'case', 'catch', 'continue', 'elseif', 'else', 'end', 'for',
+            'function', 'global', 'if', 'otherwise', 'persistent', 'return',
+            'switch', 'try', 'while'
+            ),
+        2 => array(
+            'all','any','exist','is','logical','mislocked',
+
+            'abs','acos','acosh','acot','acoth','acsc','acsch','airy','angle',
+            'ans','area','asec','asech','asin','asinh','atan','atan2','atanh',
+            'auread','autumn','auwrite','axes','axis','balance','bar','bar3',
+            'bar3h','barh','besselh','besseli','besselj','besselk','Bessely',
+            'beta','betainc','betaln','bicg','bicgstab','bin2dec','bitand',
+            'bitcmp','bitget','bitmax','bitor','bitset','bitshift','bitxor',
+            'blkdiag','bone','box','brighten','builtin','bwcontr','calendar',
+            'camdolly','camlight','camlookat','camorbit','campan','campos',
+            'camproj','camroll','camtarget','camup','camva','camzoom','capture',
+            'cart2pol','cart2sph','cat','caxis','cdf2rdf','ceil','cell',
+            'cell2struct','celldisp','cellfun','cellplot','cellstr','cgs',
+            'char','chol','cholinc','cholupdate','cla','clabel','class','clc',
+            'clf','clg','clock','close','colmmd','colorbar','colorcube',
+            'colordef','colormap','colperm','comet','comet3','compan','compass',
+            'complex','computer','cond','condeig','condest','coneplot','conj',
+            'contour','contourc','contourf','contourslice','contrast','conv',
+            'conv2','convhull','cool','copper','copyobj','corrcoef','cos',
+            'cosh','cot','coth','cov','cplxpair','cputime','cross','csc','csch',
+            'cumprod','cumsum','cumtrapz','cylinder','daspect','date','datenum',
+            'datestr','datetick','datevec','dbclear','dbcont','dbdown',
+            'dblquad','dbmex','dbquit','dbstack','dbstatus','dbstep','dbstop',
+            'dbtype','dbup','deblank','dec2bin','dec2hex','deconv','del2',
+            'delaunay','det','diag','dialog','diff','diffuse','dlmread',
+            'dlmwrite','dmperm','double','dragrect','drawnow','dsearch','eig',
+            'eigs','ellipj','ellipke','eomday','eps','erf','erfc','erfcx',
+            'erfiny','error','errorbar','errordlg','etime','eval','evalc',
+            'evalin','exp','expint','expm','eye','ezcontour','ezcontourf',
+            'ezmesh','ezmeshc','ezplot','ezplot3','ezpolar','ezsurf','ezsurfc',
+            'factor','factorial','fclose','feather','feof','ferror','feval',
+            'fft','fft2','fftshift','fgetl','fgets','fieldnames','figure',
+            'fill','fill3','filter','filter2','find','findfigs','findobj',
+            'findstr','fix','flag','flipdim','fliplr','flipud','floor','flops',
+            'fmin','fmins','fopen','fplot','fprintf','fread','frewind','fscanf',
+            'fseek','ftell','full','funm','fwrite','fzero','gallery','gamma',
+            'gammainc','gammaln','gca','gcbo','gcd','gcf','gco','get',
+            'getfield','ginput','gmres','gradient','gray','graymon','grid',
+            'griddata','gsvd','gtext','hadamard','hankel','hdf','helpdlg',
+            'hess','hex2dec','hex2num','hidden','hilb','hist','hold','hot',
+            'hsv','hsv2rgb','i','ifft','ifft2','ifftn','ifftshift','imag',
+            'image','imfinfo','imread','imwrite','ind2sub','Inf','inferiorto',
+            'inline','inpolygon','input','inputdlg','inputname','int16',
+            'int2str','int32','int8','interp1','interp2','interp3','interpft',
+            'interpn','intersect','inv','invhilb','ipermute','isa','ishandle',
+            'ismember','isocaps','isonormals','isosurface','j','jet','keyboard',
+            'lcm','legend','legendre','light','lighting','lightingangle',
+            'lin2mu','line','lines','linspace','listdlg','loadobj','log',
+            'log10','log2','loglog','logm','logspace','lower','lscov','lu',
+            'luinc','magic','mat2str','material','max','mean','median','menu',
+            'menuedit','mesh','meshc','meshgrid','min','mod','msgbox','mu2lin',
+            'NaN','nargchk','nargin','nargout','nchoosek','ndgrid','ndims',
+            'newplot','nextpow2','nnls','nnz','nonzeros','norm','normest','now',
+            'null','num2cell','num2str','nzmax','ode113,','ode15s,','ode23s,',
+            'ode23t,','ode23tb','ode45,','odefile','odeget','odeset','ones',
+            'orient','orth','pagedlg','pareto','pascal','patch','pause',
+            'pbaspect','pcg','pcolor','peaks','perms','permute','pi','pie',
+            'pie3','pinv','plot','plot3','plotmatrix','plotyy','pol2cart',
+            'polar','poly','polyarea','polyder','polyeig','polyfit','polyval',
+            'polyvalm','pow2','primes','print','printdlg','printopt','prism',
+            'prod','propedit','qmr','qr','qrdelete','qrinsert','qrupdate',
+            'quad','questdlg','quiver','quiver3','qz','rand','randn','randperm',
+            'rank','rat','rats','rbbox','rcond','real','realmax','realmin',
+            'rectangle','reducepatch','reducevolume','refresh','rem','repmat',
+            'reset','reshape','residue','rgb2hsv','rgbplot','ribbon','rmfield',
+            'roots','rose','rot90','rotate','rotate3d','round','rref',
+            'rrefmovie','rsf2csf','saveobj','scatter','scatter3','schur',
+            'script','sec','sech','selectmoveresize','semilogx','semilogy',
+            'set','setdiff','setfield','setxor','shading','shg','shiftdim',
+            'shrinkfaces','sign','sin','single','sinh','slice','smooth3','sort',
+            'sortrows','sound','soundsc','spalloc','sparse','spconvert',
+            'spdiags','specular','speye','spfun','sph2cart','sphere','spinmap',
+            'spline','spones','spparms','sprand','sprandn','sprandsym','spring',
+            'sprintf','sqrt','sqrtm','squeeze','sscanf','stairs','std','stem',
+            'stem3','str2double','str2num','strcat','strcmp','strcmpi',
+            'stream2','stream3','streamline','strings','strjust','strmatch',
+            'strncmp','strrep','strtok','struct','struct2cell','strvcat',
+            'sub2ind','subplot','subspace','subvolume','sum','summer',
+            'superiorto','surf','surf2patch','surface','surfc','surfl',
+            'surfnorm','svd','svds','symmmd','symrcm','symvar','tan','tanh',
+            'texlabel','text Create','textread','textwrap','tic','title','toc',
+            'toeplitz','trace','trapz','tril','trimesh','trisurf','triu',
+            'tsearch','uicontext Create','uicontextmenu','uicontrol',
+            'uigetfile','uimenu','uint32','uint8','uiputfile','uiresume',
+            'uisetcolor','uisetfont','uiwait Used','union','unique','unwrap',
+            'upper','var','varargin','varargout','vectorize','view','viewmtx',
+            'voronoi','waitbar','waitforbuttonpress','warndlg','warning',
+            'waterfall','wavread','wavwrite','weekday','whitebg','wilkinson',
+            'winter','wk1read','wk1write','xlabel','xlim','ylabel','ylim',
+            'zeros','zlabel','zlim','zoom',
+            //'[Keywords 6]',
+            'addpath','cd','clear','copyfile','delete','diary','dir','disp',
+            'doc','docopt','echo','edit','fileparts','format','fullfile','help',
+            'helpdesk','helpwin','home','inmem','lasterr','lastwarn','length',
+            'load','lookfor','ls','matlabrc','matlabroot','mkdir','mlock',
+            'more','munlock','open','openvar','pack','partialpath','path',
+            'pathtool','profile','profreport','pwd','quit','rmpath','save',
+            'saveas','size','tempdir','tempname','type','ver','version','web',
+            'what','whatsnew','which','who','whos','workspace'
+            )
+        ),
+    'SYMBOLS' => array(
+        '...'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        //3 => false,
+        //4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000FF;',
+            2 => 'color: #0000FF;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #228B22;',
+            2 => 'color:#A020F0;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #080;'
+            ),
+        'STRINGS' => array(
+            //0 => 'color: #A020F0;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #33f;'
+            ),
+        'METHODS' => array(
+            1 => '',
+            2 => ''
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #080;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #33f;'
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => 'http://www.mathworks.com/access/helpdesk/help/techdoc/ref/{FNAMEL}.html'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        //Complex numbers
+        0 => '(?<![\\w])[+-]?[\\d]*([\\d]\\.|\\.[\\d])?[\\d]*[ij](?![\\w])'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/mirc.php b/examples/includes/geshi/geshi/mirc.php
new file mode 100644 (file)
index 0000000..1547ff4
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+/*************************************************************************************
+ * mirc.php
+ * -----
+ * Author: Alberto 'Birckin' de Areba (Birckin@hotmail.com)
+ * Copyright: (c) 2006 Alberto de Areba
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/05/29
+ *
+ * mIRC Scripting language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2006/05/29 (1.0.0)
+ *   -  First Release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'mIRC Scripting',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'alias', 'menu', 'dialog',
+            ),
+        2 => array(
+            'if', 'elseif', 'else', 'while', 'return', 'goto','var'
+            ),
+        3 => array(
+            'action','ajinvite','amsg','ame','anick','aop','auser',
+            'avoice','auto','autojoin','away','background','ban','beep',
+            'channel','clear','clearall','clipboard','close','closemsg','color',
+            'copy','creq','ctcp','ctcpreply','ctcps','dcc','dde','ddeserver',
+            'debug','describe','disable','disconnect','dlevel','dll','dns',
+            'dqwindow','ebeeps','echo','editbox','emailaddr','enable','events',
+            'exit','filter','findtext','finger','flash','flood','flush',
+            'flushini','font','fsend','fserve','fullname','ghide','gload',
+            'gmove','gopts','gplay','gpoint','gqreq','groups','gshow','gsize',
+            'gstop','gtalk','gunload','guser','help','hop','ignore','invite',
+            'join','kick','linesep','links','list','load','loadbuf','localinfo',
+            'log','me','mdi','mkdir','mnick','mode','msg','names','nick','noop',
+            'notice','notify','omsg','onotice','part','partall','pdcc',
+            'perform','ping','play','pop','protect','pvoice','qmsg','qme',
+            'query','queryrn','quit','raw','remini','remote','remove','rename',
+            'enwin','resetidle','rlevel','rmdir','run','ruser','save','savebuf',
+            'saveini','say','server','showmirc','sline','sound','speak','splay',
+            'sreq','strip','time',
+            //'timer[N/name]', //Handled as a regular expression below ...
+            'timers','timestamp','titlebar','tnick','tokenize','topic','ulist',
+            'unload','updatenl','url','uwho','window','winhelp','write',
+            'writeini','who','whois','whowas'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #994444;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #990000; font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #FF0000;',
+            ),
+        'STRINGS' => array(
+            ),
+        'NUMBERS' => array(
+            0 => '',
+            ),
+        'METHODS' => array(
+            0 => 'color: #008000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #FF0000;',
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #000099;',
+            1 => 'color: #990000;',
+            2 => 'color: #000099;',
+            3 => 'color: #888800;',
+            4 => 'color: #888800;',
+            5 => 'color: #000099;',
+            6 => 'color: #990000; font-weight: bold;',
+            7 => 'color: #990000; font-weight: bold;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.mirc.com/{FNAMEL}'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array('.'),
+    'REGEXPS' => array(
+        //Variable names
+        0 => '\$[a-zA-Z0-9]+',
+        //Variable names
+        1 => '(%|&amp;)[a-zA-Z0-9äöü]+',
+        //Client to Client Protocol handling
+        2 => '(on|ctcp) (!|@|&amp;)?(\d|\*):[a-zA-Z]+:',
+        /*4 => array(
+            GESHI_SEARCH => '((on|ctcp) (!|@|&)?(\d|\*):(Action|Active|Agent|AppActive|Ban|Chat|Close|Connect|Ctcp|CtcpReply|DccServer|DeHelp|DeOp|DeVoice|Dialog|Dns|Error|Exit|FileRcvd|FileSent|GetFail|Help|Hotlink|Input|Invite|Join|KeyDown|KeyUp|Kick|Load|Logon|MidiEnd|Mode|Mp3End|Nick|NoSound|Notice|Notify|Op|Open|Part|Ping|Pong|PlayEnd|Quit|Raw|RawMode|SendFail|Serv|ServerMode|ServerOp|Signal|Snotice|Start|Text|Topic|UnBan|Unload|Unotify|User|Mode|Voice|Wallops|WaveEnd):)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),*/
+        //Channel names
+        3 => '(#|@)[a-zA-Z0-9]+',
+        4 => '-[a-z\d]+',
+        //Raw protocol handling
+        5 => 'raw (\d|\*):',
+        //Timer handling
+        6 => '\/timer(?!s\b)[0-9a-zA-Z_]+',
+        // /...
+        7 => '\/[a-zA-Z0-9]+'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'NUMBERS' => GESHI_NEVER
+            ),
+        'KEYWORDS' => array(
+            2 => array(
+                'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#;>^&\/])'
+            )
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/modula3.php b/examples/includes/geshi/geshi/modula3.php
new file mode 100644 (file)
index 0000000..a136442
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+/*************************************************************************************
+ * modula3.php
+ * ----------
+ * Author: mbishop (mbishop@esoteriq.org)
+ * Copyright: (c) 2009 mbishop (mbishop@esoteriq.org)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/01/21
+ *
+ * Modula-3 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Modula-3',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('(*' => '*)'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array("''"),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'AND', 'ANY', 'ARRAY', 'AS', 'BEGIN', 'BITS', 'BRANDED', 'BY', 'CASE',
+            'CONST', 'DIV', 'DO', 'ELSE', 'ELSIF', 'END', 'EVAL', 'EXCEPT', 'EXCEPTION',
+            'EXIT', 'EXPORTS', 'FINALLY', 'FOR', 'FROM', 'GENERIC', 'IF', 'IMPORT', 'IN',
+            'INTERFACE', 'LOCK', 'LOOP', 'METHODS', 'MOD', 'MODULE', 'NOT', 'OBJECT', 'OF',
+            'OR', 'OVERRIDE', 'PROCEDURE', 'RAISE', 'RAISES', 'READONLY', 'RECORD', 'REF',
+            'REPEAT', 'RETURN', 'REVEAL', 'ROOT', 'SET', 'THEN', 'TO', 'TRY', 'TYPE', 'TYPECASE',
+            'UNSAFE', 'UNTIL', 'UNTRACED', 'VALUE', 'VAR', 'WHILE', 'WITH'
+            ),
+        2 => array(
+            'NIL', 'NULL', 'FALSE', 'TRUE',
+            ),
+        3 => array(
+            'ABS','ADR','ADRSIZE','BITSIZE','BYTESIZE','CEILING','DEC','DISPOSE',
+            'EXTENDED','FIRST','FLOAT','FLOOR','INC','ISTYPE','LAST','LOOPHOLE','MAX','MIN',
+            'NARROW','NEW','NUMBER','ORD','ROUND','SUBARRAY','TRUNC','TYPECODE', 'VAL'
+            ),
+        4 => array(
+            'ADDRESS', 'BOOLEAN', 'CARDINAL', 'CHAR', 'INTEGER',
+            'LONGREAL', 'MUTEX', 'REAL', 'REFANY', 'TEXT'
+            ),
+        ),
+    'SYMBOLS' => array(
+        ',', ':', '=', '+', '-', '*', '/', '#'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;',
+            4 => 'color: #000066; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;',
+            'HARD' => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0066ee;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/mpasm.php b/examples/includes/geshi/geshi/mpasm.php
new file mode 100644 (file)
index 0000000..30b192c
--- /dev/null
@@ -0,0 +1,164 @@
+<?php
+/*************************************************************************************
+ * mpasm.php
+ * ---------
+ * Author: Bakalex (bakalex@gmail.com)
+ * Copyright: (c) 2004 Bakalex, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/12/6
+ *
+ * Microchip Assembler language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  - Added description of extra language features (SF#1970248)
+ * 2005/01/29 (1.0.0)
+ *  - First Release
+ *
+ * TODO (updated 2005/12/6)
+ * -------------------------
+ *
+ * For the moment, i've only added PIC16C6X registers. We need more (PIC16F/C7x/8x,
+ * PIC10, PIC18 and dsPIC registers).
+ * Must take a look to dsPIC instructions.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Microchip Assembler',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /*Directive Language*/
+        4 => array(
+            'CONSTANT', '#DEFINE', 'END', 'EQU', 'ERROR', 'ERROR-LEVEL', '#INCLUDE', 'LIST',
+            'MESSG', 'NOLIST', 'ORG', 'PAGE', 'PROCESSOR', 'RADIX', 'SET', 'SPACE', 'SUBTITLE',
+            'TITLE', '#UNDEFINE', 'VARIABLE', 'ELSE', 'ENDIF', 'ENDW', 'IF', 'IFDEF', 'IFNDEF',
+            'WHILE', '__BADRAM', 'CBLOCK', '__CONFIG', 'DA', 'DATA', 'DB', 'DE', 'DT', 'DW',
+            'ENDC', 'FILL', '__IDLOCS', '__MAXRAM', 'RES', 'ENDM', 'EXITM', 'EXPAND', 'LOCAL',
+            'MACRO', 'NOEXPAND', 'BANKISEL', 'BANKSEL', 'CODE', 'EXTERN', 'GLOBAL', 'IDATA',
+            'PAGESEL', 'UDATA', 'UDATA_ACS', 'UDATA_OVR', 'UDATA_SHR'
+            ),
+        /* 12&14-bit Specific Instruction Set*/
+        1 => array(
+            'andlw', 'call', 'clrwdt', 'goto', 'iorlw', 'movlw', 'option', 'retlw', 'sleep',
+            'tris', 'xorlw', 'addwf', 'andwf', 'clrf', 'clrw', 'comf', 'decf', 'decfsz', 'incf',
+            'incfsz', 'iorwf', 'movf', 'nop', 'rlf', 'rrf', 'subwf', 'swapf', 'xorwf',
+            'bcf', 'bsf', 'btfsc', 'btfss',
+            'addlw', 'retfie', 'return', 'sublw', 'addcf', 'adddcf', 'b', 'bc', 'bdc',
+            'bnc', 'bndc', 'bnz', 'bz', 'clrc', 'clrdc', 'clrz', 'lcall', 'lgoto', 'movfw',
+            'negf', 'setc', 'setdc', 'setz', 'skpc', 'skpdc', 'skpnc', 'skpndc', 'skpnz', 'skpz',
+            'subcf', 'subdcf', 'tstf'
+            ),
+        /* 16-bit Specific Instructiob Set */
+        2 => array (
+            'movfp', 'movlb', 'movlp', 'movpf', 'movwf', 'tablrd', 'tablwt', 'tlrd', 'tlwt',
+            'addwfc', 'daw', 'mullw', 'negw', 'rlcf', 'rlncf', 'rrcf', 'rrncf', 'setf', 'subwfb',
+            'btg', 'cpfseq', 'cpfsgt', 'cpfslt', 'dcfsnz', 'infsnz', 'tstfsz', 'lfsr', 'bnn',
+            'bnov', 'bra', 'pop', 'push', 'rcall', 'reset'
+            ),
+        /* Registers */
+        3 => array(
+            'INDF', 'TMR0', 'PCL', 'STATUS', 'FSR', 'PORTA', 'PORTB', 'PORTC', 'PORTD', 'PORTE',
+            'PCLATH', 'INTCON', 'PIR1', 'PIR2', 'TMR1L', 'TMR1H', 'T1CON', 'TMR2', 'T2CON', 'TMR2L',
+            'TMR2H', 'TMR0H', 'TMR0L', 'SSPBUF', 'SSPCON', 'CCPR1L', 'CCPR1H', 'CCP1CON', 'RCSTA',
+            'TXREG', 'RCREG', 'CCPR2L', 'CCPR2H', 'CCP2CON', 'OPTION', 'TRISA', 'TRISB', 'TRISC',
+            'TRISD', 'TRISE', 'PIE2', 'PIE1', 'PR2', 'SSPADD', 'SSPSTAT', 'TXSTA', 'SPBRG'
+            ),
+        /*Operands*/
+        5 => array(
+            'high','low'
+            )
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00007f;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #007f00;',
+            4 => 'color: #46aa03; font-weight:bold;',
+            5 => 'color: #7f0000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #ff0000;',
+            1 => 'color: #ff0000;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Hex numbers
+        0 => '[0-9a-fA-F]{1,32}[hH]',
+        //Binary numbers
+        1 => '[01]{1,64}[bB]'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/mxml.php b/examples/includes/geshi/geshi/mxml.php
new file mode 100644 (file)
index 0000000..939632b
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/*************************************************************************************
+ * mxml.php
+ * -------
+ * Author: David Spurr
+ * Copyright: (c) 2007 David Spurr (http://www.defusion.org.uk/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/10/04
+ *
+ * MXML language file for GeSHi. Based on the XML file by Nigel McNie
+ *
+ * CHANGES
+ * -------
+ * 2007/10/04 (1.0.7.22)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'MXML',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('<!--' => '-->'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            0 => 'color: #00bbdd;',
+            1 => 'color: #ddbb00;',
+            2 => 'color: #339933;',
+            3 => 'color: #000000;'
+            ),
+        'REGEXPS' => array(
+            0 => 'font-weight: bold; color: black;',
+            1 => 'color: #7400FF;',
+            2 => 'color: #7400FF;'
+            )
+        ),
+    'URLS' => array(
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        // xml declaration
+        0 => array(
+            GESHI_SEARCH => '(&lt;[\/?|(\?xml)]?[a-z0-9_\-:]*(\?&gt;))',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        // opening tags
+        1 => array(
+            GESHI_SEARCH => '(&lt;\/?[a-z]+:[a-z]+)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        // closing tags
+        2 => array(
+            GESHI_SEARCH => '(\/?&gt;)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<!DOCTYPE' => '>'
+            ),
+        1 => array(
+            '&' => ';'
+            ),
+        2 => array(
+            //'<![CDATA[' => ']]>'
+            '<mx:Script>' => '</mx:Script>'
+            ),
+        3 => array(
+            '<' => '>'
+            )
+    ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => false,
+        1 => false,
+        2 => false,
+        3 => true
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/mysql.php b/examples/includes/geshi/geshi/mysql.php
new file mode 100644 (file)
index 0000000..0017eef
--- /dev/null
@@ -0,0 +1,475 @@
+<?php
+/*************************************************************************************
+ * mysql.php
+ * ---------
+ * Author: Marjolein Katsma (marjolein.is.back@gmail.com)
+ * Copyright: (c) 2008 Marjolein Katsma (http://blog.marjoleinkatsma.com/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008-12-12
+ *
+ * MySQL language file for GeSHi.
+ *
+ * Based on original MySQL language file by Carl Fürstenberg (2004); brought
+ * up-to-date for current MySQL versions, and with more classes for different
+ * types of keywords; several minor errors were corrected as well.
+ *
+ * Some "classes" have two groups here: this is to allow for the fact that some
+ * keywords in MySQL have a double function: many of those are either a function
+ * (must be immediately followed by an opening bracket) or some other keyword:
+ * so they can be distinguished by the presence (or not) of that opening bracket.
+ * (An immediately following opening bracket is a default rule for functions in
+ * MySQL, though this may be overridden; because it's only a default, we use a
+ * regex lookahead only where necessary to distinguish homonyms, not generally
+ * to match any function.)
+ * Other keywords with double usage cannot be distinguished and are classified
+ * in the "Mix" category.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GeSHi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'MySQL',
+    //'COMMENT_SINGLE' => array(1 =>'--', 2 => '#'),    // '--' MUST be folowed by whitespace,not necessarily a space
+    'COMMENT_SINGLE' => array(
+        1 =>'-- ',
+        2 => '#'
+        ),
+    'COMMENT_REGEXP' => array(
+        1 => "/(?:--\s).*?$/",                          // double dash followed by any whitespace
+        ),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,            // @@@ would be nice if this could be defined per group!
+    'QUOTEMARKS' => array("'", '"', '`'),
+    'ESCAPE_CHAR' => '\\',                              // by default only, can be specified
+    'ESCAPE_REGEXP' => array(
+        1 => "/[_%]/",                                  // search wildcards
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC |
+        GESHI_NUMBER_OCT_PREFIX |
+        GESHI_NUMBER_HEX_PREFIX |
+        GESHI_NUMBER_FLT_NONSCI |
+        GESHI_NUMBER_FLT_SCI_SHORT |
+        GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            // Mix: statement keywords and keywords that don't fit in any other
+            // category, or have multiple usage/meanings
+            'ACTION','ADD','AFTER','ALGORITHM','ALL','ALTER','ANALYZE','ANY',
+            'ASC','AS','BDB','BEGIN','BERKELEYDB','BINARY','BTREE','CALL',
+            'CASCADED','CASCADE','CHAIN','CHECK','COLUMNS','COLUMN','COMMENT',
+            'COMMIT','COMMITTED','CONSTRAINT','CONTAINS SQL','CONSISTENT',
+            'CONVERT','CREATE','CROSS','DATA','DATABASES',
+            'DECLARE','DEFINER','DELAYED','DELETE','DESCRIBE','DESC',
+            'DETERMINISTIC','DISABLE','DISCARD','DISTINCTROW','DISTINCT','DO',
+            'DROP','DUMPFILE','DUPLICATE KEY','ENABLE','ENCLOSED BY','ENGINE',
+            'ERRORS','ESCAPED BY','EXISTS','EXPLAIN','EXTENDED','FIELDS',
+            'FIRST','FOR EACH ROW','FORCE','FOREIGN KEY','FROM','FULL',
+            'FUNCTION','GLOBAL','GRANT','GROUP BY','HANDLER','HASH','HAVING',
+            'HELP','HIGH_PRIORITY','IF NOT EXISTS','IGNORE','IMPORT','INDEX',
+            'INFILE','INNER','INNODB','INOUT','INTO','INVOKER',
+            'ISOLATION LEVEL','JOIN','KEYS','KEY','KILL','LANGUAGE SQL','LAST',
+            'LIMIT','LINES','LOAD','LOCAL','LOCK','LOW_PRIORITY',
+            'MASTER_SERVER_ID','MATCH','MERGE','MIDDLEINT','MODIFIES SQL DATA',
+            'MODIFY','MRG_MYISAM','NATURAL','NEXT','NO SQL','NO','ON',
+            'OPTIMIZE','OPTIONALLY','OPTION','ORDER BY','OUTER','OUTFILE','OUT',
+            'PARTIAL','PREV','PRIMARY KEY','PRIVILEGES','PROCEDURE','PURGE',
+            'QUICK','READS SQL DATA','READ','REFERENCES','RELEASE','RENAME',
+            'REPEATABLE','REQUIRE','RESTRICT','RETURNS','REVOKE',
+            'ROLLBACK','ROUTINE','RTREE','SAVEPOINT','SELECT',
+            'SERIALIZABLE','SESSION','SET','SHARE MODE','SHOW','SIMPLE',
+            'SNAPSHOT','SOME','SONAME','SQL SECURITY','SQL_BIG_RESULT',
+            'SQL_BUFFER_RESULT','SQL_CACHE','SQL_CALC_FOUND_ROWS',
+            'SQL_NO_CACHE','SQL_SMALL_RESULT','SSL','START','STARTING BY',
+            'STATUS','STRAIGHT_JOIN','STRIPED','TABLESPACE','TABLES','TABLE',
+            'TEMPORARY','TEMPTABLE','TERMINATED BY','TO','TRANSACTIONS',
+            'TRANSACTION','TRIGGER','TYPES','TYPE','UNCOMMITTED','UNDEFINED',
+            'UNION','UNLOCK_TABLES','UPDATE','USAGE','USE','USER_RESOURCES',
+            'USING','VALUES','VALUE','VIEW','WARNINGS','WHERE','WITH ROLLUP',
+            'WITH','WORK','WRITE',
+            ),
+        2 => array(     //No ( must follow
+            // Mix: statement keywords distinguished from functions by the same name
+            "CURRENT_USER", "DATABASE", "IN", "INSERT", "DEFAULT", "REPLACE", "SCHEMA", "TRUNCATE"
+            ),
+        3 => array(
+            // Values (Constants)
+            'FALSE','NULL','TRUE',
+            ),
+        4 => array(
+            // Column Data Types
+            'BIGINT','BIT','BLOB','BOOLEAN','BOOL','CHARACTER VARYING',
+            'CHAR VARYING','DATETIME','DECIMAL','DEC','DOUBLE PRECISION',
+            'DOUBLE','ENUM','FIXED','FLOAT','GEOMETRYCOLLECTION','GEOMETRY',
+            'INTEGER','INT','LINESTRING','LONGBLOB','LONGTEXT','MEDIUMBLOB',
+            'MEDIUMINT','MEDIUMTEXT','MULTIPOINT','MULTILINESTRING',
+            'MULTIPOLYGON','NATIONAL CHARACTER','NATIONAL CHARACTER VARYING',
+            'NATIONAL CHAR VARYING','NATIONAL VARCHAR','NCHAR VARCHAR','NCHAR',
+            'NUMERIC','POINT','POLYGON','REAL','SERIAL',
+            'SMALLINT','TEXT','TIMESTAMP','TINYBLOB','TINYINT',
+            'TINYTEXT','VARBINARY','VARCHARACTER','VARCHAR',
+            ),
+        5 => array(     //No ( must follow
+            // Column data types distinguished from functions by the same name
+            "CHAR", "DATE", "TIME"
+            ),
+        6 => array(
+            // Table, Column & Index Attributes
+            'AUTO_INCREMENT','AVG_ROW_LENGTH','BOTH','CHECKSUM','CONNECTION',
+            'DATA DIRECTORY','DEFAULT NULL','DELAY_KEY_WRITE','FULLTEXT',
+            'INDEX DIRECTORY','INSERT_METHOD','LEADING','MAX_ROWS','MIN_ROWS',
+            'NOT NULL','PACK_KEYS','ROW_FORMAT','SERIAL DEFAULT VALUE','SIGNED',
+            'SPATIAL','TRAILING','UNIQUE','UNSIGNED','ZEROFILL'
+            ),
+        7 => array(     //No ( must follow
+            // Column attribute distinguished from function by the same name
+            "CHARSET"
+            ),
+        8 => array(
+            // Date and Time Unit Specifiers
+            'DAY_HOUR','DAY_MICROSECOND','DAY_MINUTE','DAY_SECOND',
+            'HOUR_MICROSECOND','HOUR_MINUTE','HOUR_SECOND',
+            'MINUTE_MICROSECOND','MINUTE_SECOND',
+            'SECOND_MICROSECOND','YEAR_MONTH'
+            ),
+        9 => array(     //No ( must follow
+            // Date-time unit specifiers distinguished from functions by the same name
+            "DAY", "HOUR", "MICROSECOND", "MINUTE", "MONTH", "QUARTER", "SECOND", "WEEK", "YEAR"
+            ),
+        10 => array(
+            // Operators (see also Symbols)
+            'AND','BETWEEN','CHARACTER SET','COLLATE','DIV','IS NOT NULL',
+            'IS NOT','IS NULL','IS','LIKE','NOT','OFFSET','OR','REGEXP','RLIKE',
+            'SOUNDS LIKE','XOR'
+            ),
+        11 => array(     //No ( must follow
+            // Operator distinghuished from function by the same name
+            "INTERVAL"
+            ),
+        12 => array(
+            // Control Flow (functions)
+            'CASE','ELSE','END','IFNULL','IF','NULLIF','THEN','WHEN',
+            ),
+        13 => array(
+            // String Functions
+            'ASCII','BIN','BIT_LENGTH','CHAR_LENGTH','CHARACTER_LENGTH',
+            'CONCAT_WS','CONCAT','ELT','EXPORT_SET','FIELD',
+            'FIND_IN_SET','FORMAT','HEX','INSTR','LCASE','LEFT','LENGTH',
+            'LOAD_FILE','LOCATE','LOWER','LPAD','LTRIM','MAKE_SET','MID',
+            'OCTET_LENGTH','ORD','POSITION','QUOTE','REPEAT','REVERSE',
+            'RIGHT','RPAD','RTRIM','SOUNDEX','SPACE','STRCMP','SUBSTRING_INDEX',
+            'SUBSTRING','TRIM','UCASE','UNHEX','UPPER',
+            ),
+        14 => array(     //A ( must follow
+            // String functions distinguished from other keywords by the same name
+            "INSERT", "REPLACE", "CHAR"
+            ),
+        15 => array(
+            // Numeric Functions
+            'ABS','ACOS','ASIN','ATAN2','ATAN','CEILING','CEIL',
+            'CONV','COS','COT','CRC32','DEGREES','EXP','FLOOR','LN','LOG10',
+            'LOG2','LOG','MOD','OCT','PI','POWER','POW','RADIANS','RAND',
+            'ROUND','SIGN','SIN','SQRT','TAN',
+            ),
+        16 => array(     //A ( must follow
+            // Numeric function distinguished from other keyword by the same name
+            "TRUNCATE"
+            ),
+        17 => array(
+            // Date and Time Functions
+            'ADDDATE','ADDTIME','CONVERT_TZ','CURDATE','CURRENT_DATE',
+            'CURRENT_TIME','CURRENT_TIMESTAMP','CURTIME','DATE_ADD',
+            'DATE_FORMAT','DATE_SUB','DATEDIFF','DAYNAME','DAYOFMONTH',
+            'DAYOFWEEK','DAYOFYEAR','EXTRACT','FROM_DAYS','FROM_UNIXTIME',
+            'GET_FORMAT','LAST_DAY','LOCALTIME','LOCALTIMESTAMP','MAKEDATE',
+            'MAKETIME','MONTHNAME','NOW','PERIOD_ADD',
+            'PERIOD_DIFF','SEC_TO_TIME','STR_TO_DATE','SUBDATE','SUBTIME',
+            'SYSDATE','TIME_FORMAT','TIME_TO_SEC',
+            'TIMESTAMPADD','TIMESTAMPDIFF','TO_DAYS',
+            'UNIX_TIMESTAMP','UTC_DATE','UTC_TIME','UTC_TIMESTAMP','WEEKDAY',
+            'WEEKOFYEAR','YEARWEEK',
+            ),
+        18 => array(     //A ( must follow
+            // Date-time functions distinguished from other keywords by the same name
+            "DATE", "DAY", "HOUR", "MICROSECOND", "MINUTE", "MONTH", "QUARTER",
+            "SECOND", "TIME", "WEEK", "YEAR"
+            ),
+        19 => array(
+            // Comparison Functions
+            'COALESCE','GREATEST','ISNULL','LEAST',
+            ),
+        20 => array(     //A ( must follow
+            // Comparison functions distinguished from other keywords by the same name
+            "IN", "INTERVAL"
+            ),
+        21 => array(
+            // Encryption and Compression Functions
+            'AES_DECRYPT','AES_ENCRYPT','COMPRESS','DECODE','DES_DECRYPT',
+            'DES_ENCRYPT','ENCODE','ENCRYPT','MD5','OLD_PASSWORD','PASSWORD',
+            'SHA1','SHA','UNCOMPRESS','UNCOMPRESSED_LENGTH',
+            ),
+        22 => array(
+            // GROUP BY (aggregate) Functions
+            'AVG','BIT_AND','BIT_OR','BIT_XOR','COUNT','GROUP_CONCAT',
+            'MAX','MIN','STDDEV_POP','STDDEV_SAMP','STDDEV','STD','SUM',
+            'VAR_POP','VAR_SAMP','VARIANCE',
+            ),
+        23 => array(
+            // Information Functions
+            'BENCHMARK','COERCIBILITY','COLLATION','CONNECTION_ID',
+            'FOUND_ROWS','LAST_INSERT_ID','ROW_COUNT',
+            'SESSION_USER','SYSTEM_USER','USER','VERSION',
+            ),
+        24 => array(     //A ( must follow
+            // Information functions distinguished from other keywords by the same name
+            "CURRENT_USER", "DATABASE", "SCHEMA", "CHARSET"
+            ),
+        25 => array(
+            // Miscellaneous Functions
+            'ExtractValue','BIT_COUNT','GET_LOCK','INET_ATON','INET_NTOA',
+            'IS_FREE_LOCK','IS_USED_LOCK','MASTER_POS_WAIT','NAME_CONST',
+            'RELEASE_LOCK','SLEEP','UpdateXML','UUID',
+            ),
+        26 => array(     //A ( must follow
+            // Miscellaneous function distinguished from other keyword by the same name
+            "DEFAULT"
+            ),
+        27 => array(
+            // Geometry Functions
+            'Area','AsBinary','AsText','AsWKB','AsWKT','Boundary','Buffer',
+            'Centroid','Contains','ConvexHull','Crosses',
+            'Difference','Dimension','Disjoint','Distance',
+            'EndPoint','Envelope','Equals','ExteriorRing',
+            'GLength','GeomCollFromText','GeomCollFromWKB','GeomFromText',
+            'GeomFromWKB','GeometryCollectionFromText',
+            'GeometryCollectionFromWKB','GeometryFromText','GeometryFromWKB',
+            'GeometryN','GeometryType',
+            'InteriorRingN','Intersection','Intersects','IsClosed','IsEmpty',
+            'IsRing','IsSimple',
+            'LineFromText','LineFromWKB','LineStringFromText',
+            'LineStringFromWKB',
+            'MBRContains','MBRDisjoint','MBREqual','MBRIntersects',
+            'MBROverlaps','MBRTouches','MBRWithin','MLineFromText',
+            'MLineFromWKB','MPointFromText','MPointFromWKB','MPolyFromText',
+            'MPolyFromWKB','MultiLineStringFromText','MultiLineStringFromWKB',
+            'MultiPointFromText','MultiPointFromWKB','MultiPolygonFromText',
+            'MultiPolygonFromWKB',
+            'NumGeometries','NumInteriorRings','NumPoints',
+            'Overlaps',
+            'PointFromText','PointFromWKB','PointN','PointOnSurface',
+            'PolyFromText','PolyFromWKB','PolygonFromText','PolygonFromWKB',
+            'Related','SRID','StartPoint','SymDifference',
+            'Touches',
+            'Union',
+            'Within',
+            'X',
+            'Y',
+            ),
+        ),
+    'SYMBOLS' => array(
+        1 => array(
+            /* Operators */
+            '=', ':=',                                      // assignment operators
+            '||', '&&', '!',                                // locical operators
+            '=', '<=>', '>=', '>', '<=', '<', '<>', '!=',   // comparison operators
+            '|', '&', '^', '~', '<<', '>>',                 // bitwise operators
+            '-', '+', '*', '/', '%',                        // numerical operators
+            ),
+        2 => array(
+            /* Other syntactical symbols */
+            '(', ')',
+            ',', ';',
+            ),
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false,
+        8 => false,
+        9 => false,
+        10 => false,
+        11 => false,
+        12 => false,
+        13 => false,
+        13 => false,
+        14 => false,
+        15 => false,
+        16 => false,
+        17 => false,
+        18 => false,
+        19 => false,
+        20 => false,
+        21 => false,
+        22 => false,
+        23 => false,
+        24 => false,
+        25 => false,
+        26 => false,
+        27 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #990099; font-weight: bold;',      // mix
+            2 => 'color: #990099; font-weight: bold;',      // mix
+            3 => 'color: #9900FF; font-weight: bold;',      // constants
+            4 => 'color: #999900; font-weight: bold;',      // column data types
+            5 => 'color: #999900; font-weight: bold;',      // column data types
+            6 => 'color: #FF9900; font-weight: bold;',      // attributes
+            7 => 'color: #FF9900; font-weight: bold;',      // attributes
+            8 => 'color: #9900FF; font-weight: bold;',      // date-time units
+            9 => 'color: #9900FF; font-weight: bold;',      // date-time units
+
+            10 => 'color: #CC0099; font-weight: bold;',      // operators
+            11 => 'color: #CC0099; font-weight: bold;',      // operators
+
+            12 => 'color: #009900;',     // control flow (functions)
+            13 => 'color: #000099;',     // string functions
+            14 => 'color: #000099;',     // string functions
+            15 => 'color: #000099;',     // numeric functions
+            16 => 'color: #000099;',     // numeric functions
+            17 => 'color: #000099;',     // date-time functions
+            18 => 'color: #000099;',     // date-time functions
+            19 => 'color: #000099;',     // comparison functions
+            20 => 'color: #000099;',     // comparison functions
+            21 => 'color: #000099;',     // encryption functions
+            22 => 'color: #000099;',     // aggregate functions
+            23 => 'color: #000099;',     // information functions
+            24 => 'color: #000099;',     // information functions
+            25 => 'color: #000099;',     // miscellaneous functions
+            26 => 'color: #000099;',     // miscellaneous functions
+            27 => 'color: #00CC00;',     // geometry functions
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #808000; font-style: italic;',
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #004000; font-weight: bold;',
+            1 => 'color: #008080; font-weight: bold;'       // search wildcards
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #FF00FF;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #008000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #008080;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            1 => 'color: #CC0099;',         // operators
+            2 => 'color: #000033;',         // syntax
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        2 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        3 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        4 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        5 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        6 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        7 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        8 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+        9 => 'http://search.mysql.com/search?site=refman-51&amp;q={FNAME}&amp;lr=lang_en',
+
+        10 => 'http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html',
+        11 => 'http://dev.mysql.com/doc/refman/5.1/en/non-typed-operators.html',
+
+        12 => 'http://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html',
+        13 => 'http://dev.mysql.com/doc/refman/5.1/en/string-functions.html',
+        14 => 'http://dev.mysql.com/doc/refman/5.1/en/string-functions.html',
+        15 => 'http://dev.mysql.com/doc/refman/5.1/en/numeric-functions.html',
+        16 => 'http://dev.mysql.com/doc/refman/5.1/en/numeric-functions.html',
+        17 => 'http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html',
+        18 => 'http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html',
+        19 => 'http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html',
+        20 => 'http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html',
+        21 => 'http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html',
+        22 => 'http://dev.mysql.com/doc/refman/5.1/en/group-by-functions-and-modifiers.html',
+        23 => 'http://dev.mysql.com/doc/refman/5.1/en/information-functions.html',
+        24 => 'http://dev.mysql.com/doc/refman/5.1/en/information-functions.html',
+        25 => 'http://dev.mysql.com/doc/refman/5.1/en/func-op-summary-ref.html',
+        26 => 'http://dev.mysql.com/doc/refman/5.1/en/func-op-summary-ref.html',
+        27 => 'http://dev.mysql.com/doc/refman/5.1/en/analysing-spatial-information.html',
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            2 => array(
+                'DISALLOWED_AFTER' => '(?![\(\w])'
+                ),
+            5 => array(
+                'DISALLOWED_AFTER' => '(?![\(\w])'
+                ),
+            7 => array(
+                'DISALLOWED_AFTER' => '(?![\(\w])'
+                ),
+            9 => array(
+                'DISALLOWED_AFTER' => '(?![\(\w])'
+                ),
+            11 => array(
+                'DISALLOWED_AFTER' => '(?![\(\w])'
+                ),
+
+            14 => array(
+                'DISALLOWED_AFTER' => '(?=\()'
+                ),
+            16 => array(
+                'DISALLOWED_AFTER' => '(?=\()'
+                ),
+            18 => array(
+                'DISALLOWED_AFTER' => '(?=\()'
+                ),
+            20 => array(
+                'DISALLOWED_AFTER' => '(?=\()'
+                ),
+            24 => array(
+                'DISALLOWED_AFTER' => '(?=\()'
+                ),
+            26 => array(
+                'DISALLOWED_AFTER' => '(?=\()'
+                )
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/nsis.php b/examples/includes/geshi/geshi/nsis.php
new file mode 100644 (file)
index 0000000..9f3e1cc
--- /dev/null
@@ -0,0 +1,351 @@
+<?php
+/*************************************************************************************
+ * nsis.php
+ * --------
+ * Author: deguix (cevo_deguix@yahoo.com.br), Tux (http://tux.a4.cz/)
+ * Copyright: (c) 2005 deguix, 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/12/03
+ *
+ * Nullsoft Scriptable Install System language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/03 (2.0.2)
+ *   - Updated to NSIS 2.11.
+ * 2005/06/17 (2.0.1)
+ *   - Updated to NSIS 2.07b0.
+ * 2005/04/05 (2.0.0)
+ *   - Updated to NSIS 2.06.
+ * 2004/11/27 (1.0.2)
+ *   - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   - Added support for URLs
+ * 2004/08/05 (1.0.0)
+ *   - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'NSIS',
+    'COMMENT_SINGLE' => array(1 => ';', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'",'"','`'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            '!appendfile', '!addIncludeDir', '!addplugindir', '!cd', '!define', '!delfile', '!echo', '!else',
+            '!endif', '!error', '!execute', '!ifdef', '!ifmacrodef', '!ifmacrondef', '!ifndef', '!include',
+            '!insertmacro', '!macro', '!macroend', '!packhdr', '!tempfile', '!system', '!undef', '!verbose',
+            '!warning'
+            ),
+        2 => array(
+            'AddBrandingImage', 'AllowRootDirInstall', 'AutoCloseWindow', 'BGFont',
+            'BGGradient', 'BrandingText', 'Caption', 'ChangeUI', 'CheckBitmap', 'CompletedText', 'ComponentText',
+            'CRCCheck', 'DetailsButtonText', 'DirShow', 'DirText', 'DirVar', 'DirVerify', 'FileErrorText',
+            'Function', 'FunctionEnd', 'Icon', 'InstallButtonText', 'InstallColors', 'InstallDir',
+            'InstallDirRegKey', 'InstProgressFlags', 'InstType', 'LangString', 'LangStringUP', 'LicenseBkColor',
+            'LicenseData', 'LicenseForceSelection', 'LicenseLangString', 'LicenseText', 'LoadLanguageFile',
+            'MiscButtonText', 'Name', 'OutFile', 'Page', 'PageEx', 'PageExEnd', 'Section',
+            'SectionEnd', 'SectionGroup', 'SectionGroupEnd', 'SetCompressor', 'SetFont', 'ShowInstDetails',
+            'ShowUninstDetails', 'SilentInstall', 'SilentUnInstall', 'SpaceTexts', 'SubCaption', 'SubSection',
+            'SubSectionEnd', 'UninstallButtonText', 'UninstallCaption', 'UninstallIcon', 'UninstallSubCaption',
+            'UninstallText', 'UninstPage', 'Var', 'VIAddVersionKey', 'VIProductVersion', 'WindowIcon', 'XPStyle'
+            ),
+        3 => array(
+            'AddSize', 'AllowSkipFiles', 'FileBufSize', 'GetInstDirError', 'PageCallbacks',
+            'SectionIn', 'SetCompress', 'SetCompressionLevel', 'SetCompressorDictSize',
+            'SetDatablockOptimize', 'SetDateSave', 'SetOverwrite', 'SetPluginUnload'
+            ),
+        4 => array(
+            'Abort', 'BringToFront', 'Call', 'CallInstDLL', 'ClearErrors', 'CopyFiles','CreateDirectory',
+            'CreateFont', 'CreateShortCut', 'Delete', 'DeleteINISec', 'DeleteINIStr', 'DeleteRegKey',
+            'DeleteRegValue', 'DetailPrint', 'EnableWindow', 'EnumRegKey', 'EnumRegValue', 'Exch', 'Exec',
+            'ExecShell', 'ExecWait', 'ExpandEnvStrings', 'File', 'FileClose', 'FileOpen', 'FileRead',
+            'FileReadByte', 'FileSeek', 'FileWrite', 'FileWriteByte', 'FindClose', 'FindFirst', 'FindNext',
+            'FindWindow', 'FlushINI', 'GetCurInstType', 'GetCurrentAddress', 'GetDlgItem', 'GetDLLVersion',
+            'GetDLLVersionLocal', 'GetErrorLevel', 'GetFileTime', 'GetFileTimeLocal', 'GetFullPathName',
+            'GetFunctionAddress', 'GetLabelAddress', 'GetTempFileName', 'GetWindowText', 'Goto', 'HideWindow',
+            'IfAbort', 'IfErrors', 'IfFileExists', 'IfRebootFlag', 'IfSilent', 'InitPluginsDir', 'InstTypeGetText',
+            'InstTypeSetText', 'IntCmp', 'IntCmpU', 'IntFmt', 'IntOp', 'IsWindow', 'LockWindow', 'LogSet', 'LogText',
+            'MessageBox', 'Nop', 'Pop', 'Push', 'Quit', 'ReadEnvStr', 'ReadIniStr', 'ReadRegDWORD', 'ReadRegStr',
+            'Reboot', 'RegDLL', 'Rename', 'ReserveFile', 'Return', 'RMDir', 'SearchPath', 'SectionGetFlags',
+            'SectionGetInstTypes', 'SectionGetSize', 'SectionGetText', 'SectionSetFlags', 'SectionSetInstTypes',
+            'SectionSetSize', 'SectionSetText', 'SendMessage', 'SetAutoClose', 'SetBrandingImage', 'SetCtlColors',
+            'SetCurInstType', 'SetDetailsPrint', 'SetDetailsView', 'SetErrorLevel', 'SetErrors', 'SetFileAttributes',
+            'SetOutPath', 'SetRebootFlag', 'SetShellVarContext', 'SetSilent', 'ShowWindow', 'Sleep', 'StrCmp',
+            'StrCpy', 'StrLen', 'UnRegDLL', 'WriteINIStr', 'WriteRegBin', 'WriteRegDWORD', 'WriteRegExpandStr',
+            'WriteRegStr', 'WriteUninstaller'
+            ),
+        5 => array(
+            'all', 'alwaysoff', 'ARCHIVE', 'auto', 'both', 'bzip2', 'checkbox', 'components', 'current',
+            'custom', 'directory', 'false', 'FILE_ATTRIBUTE_ARCHIVE', 'FILE_ATTRIBUTE_HIDDEN', 'FILE_ATTRIBUTE_NORMAL',
+            'FILE_ATTRIBUTE_OFFLINE', 'FILE_ATTRIBUTE_READONLY', 'FILE_ATTRIBUTE_SYSTEM,TEMPORARY',
+            'FILE_ATTRIBUTE_TEMPORARY', 'force', 'HIDDEN', 'hide', 'HKCC', 'HKCR', 'HKCU', 'HKDD', 'HKEY_CLASSES_ROOT',
+            'HKEY_CURRENT_CONFIG', 'HKEY_CURRENT_USER', 'HKEY_DYN_DATA', 'HKEY_LOCAL_MACHINE', 'HKEY_PERFORMANCE_DATA',
+            'HKEY_USERS', 'HKLM', 'HKPD', 'HKU', 'IDABORT', 'IDCANCEL', 'IDIGNORE', 'IDNO', 'IDOK', 'IDRETRY', 'IDYES',
+            'ifdiff', 'ifnewer', 'instfiles', 'lastused', 'leave', 'license', 'listonly', 'lzma', 'manual',
+            'MB_ABORTRETRYIGNORE', 'MB_DEFBUTTON1', 'MB_DEFBUTTON2', 'MB_DEFBUTTON3', 'MB_DEFBUTTON4',
+            'MB_ICONEXCLAMATION', 'MB_ICONINFORMATION', 'MB_ICONQUESTION', 'MB_ICONSTOP', 'MB_OK', 'MB_OKCANCEL',
+            'MB_RETRYCANCEL', 'MB_RIGHT', 'MB_SETFOREGROUND', 'MB_TOPMOST', 'MB_YESNO', 'MB_YESNOCANCEL', 'nevershow',
+            'none', 'normal', 'off', 'OFFLINE', 'on', 'radiobuttons', 'READONLY', 'RO', 'SHCTX', 'SHELL_CONTEXT', 'show',
+            'silent', 'silentlog', 'SW_HIDE', 'SW_SHOWMAXIMIZED', 'SW_SHOWMINIMIZED', 'SW_SHOWNORMAL', 'SYSTEM',
+            'textonly', 'true', 'try', 'uninstConfirm', 'zlib'
+            ),
+        6 => array(
+            '/a', '/components', '/COMPONENTSONLYONCUSTOM', '/CUSTOMSTRING', '/e', '/FILESONLY', '/FINAL', '/gray', '/GLOBAL',
+            '/ifempty', '/IMGID', '/ITALIC', '/lang', '/NOCUSTOM', '/nonfatal', '/NOUNLOAD', '/oname', '/r', '/REBOOTOK',
+            '/RESIZETOFIT', '/SOLID', '/SD', '/SHORT', '/silent', '/STRIKE', '/TIMEOUT', '/TRIMCENTER', '/TRIMLEFT',
+            '/TRIMRIGHT', '/UNDERLINE', '/windows', '/x'
+            ),
+        7 => array(
+            '.onGUIEnd', '.onGUIInit', '.onInit', '.onInstFailed', '.onInstSuccess', '.onMouseOverSection',
+            '.onRebootFailed', '.onSelChange', '.onUserAbort', '.onVerifyInstDir', 'un.onGUIEnd', 'un.onGUIInit',
+            'un.onInit', 'un.onRebootFailed', 'un.onUninstFailed', 'un.onUninstSuccess', 'un.onUserAbort'
+            ),
+        8 => array(
+            'MUI.nsh', '"${NSISDIR}\Contrib\Modern UI\System.nsh"', 'MUI_SYSVERSION', 'MUI_ICON', 'MUI_UNICON',
+            'MUI_HEADERIMAGE', 'MUI_HEADERIMAGE_BITMAP', 'MUI_HEADERIMAGE_BITMAP_NOSTRETCH', 'MUI_HEADERIMAGE_BITMAP_RTL',
+            'MUI_HEADERIMAGE_BITMAP_RTL_NOSTRETCH', 'MUI_HEADERIMAGE_UNBITMAP', 'MUI_HEADERIMAGE_UNBITMAP_NOSTRETCH',
+            'MUI_HEADERIMAGE_UNBITMAP_RTL', 'MUI_HEADERIMAGE_UNBITMAP_RTL_NOSTRETCH', 'MUI_HEADERIMAGE_RIGHT', 'MUI_BGCOLOR',
+            'MUI_UI', 'MUI_UI_HEADERIMAGE', 'MUI_UI_HEADERIMAGE_RIGHT', 'MUI_UI_COMPONENTSPAGE_SMALLDESC',
+            'MUI_UI_COMPONENTSPAGE_NODESC', 'MUI_WELCOMEFINISHPAGE_BITMAP', 'MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH',
+            'MUI_WELCOMEFINISHPAGE_INI', 'MUI_UNWELCOMEFINISHPAGE_BITMAP', 'MUI_UNWELCOMEFINISHPAGE_BITMAP_NOSTRETCH',
+            'MUI_UNWELCOMEFINISHPAGE_INI', 'MUI_LICENSEPAGE_BGCOLOR', 'MUI_COMPONENTSPAGE_CHECKBITMAP',
+            'MUI_COMPONENTSPAGE_SMALLDESC', 'MUI_COMPONENTSPAGE_NODESC', 'MUI_INSTFILESPAGE_COLORS',
+            'MUI_INSTFILESPAGE_PROGRESSBAR', 'MUI_FINISHPAGE_NOAUTOCLOSE', 'MUI_UNFINISHPAGE_NOAUTOCLOSE',
+            'MUI_ABORTWARNING', 'MUI_ABORTWARNING_TEXT', 'MUI_UNABORTWARNING', 'MUI_UNABORTWARNING_TEXT',
+            'MUI_PAGE_WELCOME', 'MUI_PAGE_LICENSE', 'MUI_PAGE_COMPONENTS', 'MUI_PAGE_DIRECTORY',
+            'MUI_PAGE_STARTMENU', 'MUI_PAGE_INSTFILES', 'MUI_PAGE_FINISH', 'MUI_UNPAGE_WELCOME',
+            'MUI_UNPAGE_CONFIRM', 'MUI_UNPAGE_LICENSE', 'MUI_UNPAGE_COMPONENTS', 'MUI_UNPAGE_DIRECTORY',
+            'MUI_UNPAGE_INSTFILES', 'MUI_UNPAGE_FINISH', 'MUI_PAGE_HEADER_TEXT', 'MUI_PAGE_HEADER_SUBTEXT',
+            'MUI_WELCOMEPAGE_TITLE', 'MUI_WELCOMEPAGE_TITLE_3LINES', 'MUI_WELCOMEPAGE_TEXT',
+            'MUI_LICENSEPAGE_TEXT_TOP', 'MUI_LICENSEPAGE_TEXT_BOTTOM', 'MUI_LICENSEPAGE_BUTTON',
+            'MUI_LICENSEPAGE_CHECKBOX', 'MUI_LICENSEPAGE_CHECKBOX_TEXT', 'MUI_LICENSEPAGE_RADIOBUTTONS',
+            'MUI_LICENSEPAGE_RADIOBUTTONS_TEXT_ACCEPT', 'MUI_LICENSEPAGE_RADIOBUTTONS_TEXT_DECLINE',
+            'MUI_COMPONENTSPAGE_TEXT_TOP', 'MUI_COMPONENTSPAGE_TEXT_COMPLIST', 'MUI_COMPONENTSPAGE_TEXT_INSTTYPE',
+            'MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE', 'MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO',
+            'MUI_DIRECTORYPAGE_TEXT_TOP', 'MUI_DIRECTORYPAGE_TEXT_DESTINATION', 'MUI_DIRECTORYPAGE_VARIABLE',
+            'MUI_DIRECTORYPAGE_VERIFYONLEAVE', 'MUI_STARTMENU_WRITE_BEGIN', 'MUI_STARTMENU_WRITE_END',
+            'MUI_STARTMENUPAGE_TEXT_TOP', 'MUI_STARTMENUPAGE_TEXT_CHECKBOX', 'MUI_STARTMENUPAGE_DEFAULTFOLDER',
+            'MUI_STARTMENUPAGE_NODISABLE', 'MUI_STARTMENUPAGE_REGISTRY_ROOT', 'MUI_STARTMENUPAGE_REGISTRY_KEY',
+            'MUI_STARTMENUPAGE_REGISTRY_VALUENAME', 'MUI_INSTFILESPAGE_FINISHHEADER_TEXT',
+            'MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT', 'MUI_INSTFILESPAGE_ABORTHEADER_TEXT',
+            'MUI_INSTFILESPAGE_ABORTHEADER_SUBTEXT', 'MUI_FINISHPAGE_TITLE', 'MUI_FINISHPAGE_TITLE_3LINES',
+            'MUI_FINISHPAGE_TEXT', 'MUI_FINISHPAGE_TEXT_LARGE', 'MUI_FINISHPAGE_BUTTON',
+            'MUI_FINISHPAGE_TEXT_REBOOT', 'MUI_FINISHPAGE_TEXT_REBOOTNOW', 'MUI_FINISHPAGE_TEXT_REBOOTLATER',
+            'MUI_FINISHPAGE_RUN', 'MUI_FINISHPAGE_RUN_TEXT', 'MUI_FINISHPAGE_RUN_PARAMETERS',
+            'MUI_FINISHPAGE_RUN_NOTCHECKED', 'MUI_FINISHPAGE_RUN_FUNCTION', 'MUI_FINISHPAGE_SHOWREADME',
+            'MUI_FINISHPAGE_SHOWREADME_TEXT', 'MUI_FINISHPAGE_SHOWREADME_NOTCHECKED',
+            'MUI_FINISHPAGE_SHOWREADME_FUNCTION', 'MUI_FINISHPAGE_LINK', 'MUI_FINISHPAGE_LINK_LOCATION',
+            'MUI_FINISHPAGE_LINK_COLOR', 'MUI_FINISHPAGE_NOREBOOTSUPPORT', 'MUI_UNCONFIRMPAGE_TEXT_TOP',
+            'MUI_UNCONFIRMPAGE_TEXT_LOCATION', 'MUI_LANGUAGE', 'MUI_LANGDLL_DISPLAY',
+            'MUI_LANGDLL_REGISTRY_ROOT', 'MUI_LANGDLL_REGISTRY_KEY', 'MUI_LANGDLL_REGISTRY_VALUENAME',
+            'MUI_LANGDLL_WINDOWTITLE', 'MUI_LANGDLL_INFO', 'MUI_LANGDLL_ALWAYSSHOW',
+            'MUI_RESERVEFILE_INSTALLOPTIONS', 'MUI_RESERVEFILE_LANGDLL', 'MUI_FUNCTION_DESCRIPTION_BEGIN',
+            'MUI_DESCRIPTION_TEXT', 'MUI_FUNCTION_DESCRIPTION_END', 'MUI_INSTALLOPTIONS_EXTRACT',
+            'MUI_INSTALLOPTIONS_EXTRACT_AS', 'MUI_HEADER_TEXT', 'MUI_INSTALLOPTIONS_DISPLAY',
+            'MUI_INSTALLOPTIONS_INITDIALOG', 'MUI_INSTALLOPTIONS_SHOW',
+            'MUI_INSTALLOPTIONS_DISPLAY_RETURN', 'MUI_INSTALLOPTIONS_SHOW_RETURN',
+            'MUI_INSTALLOPTIONS_READ', 'MUI_INSTALLOPTIONS_WRITE',
+            'MUI_CUSTOMFUNCTION_GUIINIT', 'MUI_CUSTOMFUNCTION_UNGUIINIT',
+            'MUI_CUSTOMFUNCTION_ABORT', 'MUI_CUSTOMFUNCTION_UNABORT',
+            'MUI_PAGE_CUSTOMFUNCTION_PRE', 'MUI_PAGE_CUSTOMFUNCTION_SHOW', 'MUI_PAGE_CUSTOMFUNCTION_LEAVE',
+            'MUI_WELCOMEFINISHPAGE_CUSTOMFUNCTION_INIT'
+            ),
+        9 => array(
+            'LogicLib.nsh', '${LOGICLIB}', 'LOGICLIB_STRCMP', 'LOGICLIB_INT64CMP', 'LOGICLIB_SECTIONCMP', '${If}', '${Unless}',
+            '${ElseIf}', '${ElseUnless}', '${Else}', '${EndIf}', '${EndUnless}', '${AndIf}', '${AndUnless}',
+            '${OrIf}', '${OrUnless}', '${IfThen}', '${IfCmd}', '${Select}', '${Case2}', '${Case3}',
+            '${Case4}', '${Case5}', '${CaseElse}', '${Default}', '${EndSelect}', '${Switch}',
+            '${Case}', '${EndSwitch}', '${Do}', '${DoWhile}', '${UntilWhile}', '${Continue}', '${Break}',
+            '${Loop}', '${LoopWhile}', '${LoopUntil}', '${While}', '${ExitWhile}', '${EndWhile}', '${For}',
+            '${ForEach}', '${ExitFor}', '${Next}', '${Abort}', '${Errors}', '${RebootFlag}', '${Silent}',
+            '${FileExists}', '${Cmd}', '${SectionIsSelected}', '${SectionIsSectionGroup}',
+            '${SectionIsSectionGroupEnd}', '${SectionIsBold}', '${SectionIsReadOnly}',
+            '${SectionIsExpanded}', '${SectionIsPartiallySelected}'
+            ),
+        10 => array(
+            'StrFunc.nsh', '${STRFUNC}', '${StrCase}', '${StrClb}', '${StrIOToNSIS}', '${StrLoc}', '${StrNSISToIO}', '${StrRep}',
+            '${StrSort}', '${StrStr}', '${StrStrAdv}', '${StrTok}', '${StrTrimNewLines}'
+            ),
+        11 => array(
+            'UpgradeDLL.nsh', 'UPGRADEDLL_INCLUDED', 'UpgradeDLL'
+            ),
+        12 => array(
+            'Sections.nsh', 'SECTIONS_INCLUDED', '${SF_SELECTED}', '${SF_SECGRP}', '${SF_SUBSEC}', '${SF_SECGRPEND}',
+            '${SF_SUBSECEND}', '${SF_BOLD}', '${SF_RO}', '${SF_EXPAND}', '${SF_PSELECTED}', '${SF_TOGGLED}',
+            '${SF_NAMECHG}', '${SECTION_OFF}', 'SelectSection', 'UnselectSection', 'ReverseSection',
+            'StartRadioButtons', 'RadioButton', 'EndRadioButtons', '${INSTTYPE_0}', '${INSTTYPE_1}', '${INSTTYPE_2}',
+            '${INSTTYPE_3}', '${INSTTYPE_4}', '${INSTTYPE_5}', '${INSTTYPE_6}', '${INSTTYPE_7}', '${INSTTYPE_8}',
+            '${INSTTYPE_9}', '${INSTTYPE_10}', '${INSTTYPE_11}', '${INSTTYPE_12}', '${INSTTYPE_13}', '${INSTTYPE_14}',
+            '${INSTTYPE_15}', '${INSTTYPE_16}', '${INSTTYPE_17}', '${INSTTYPE_18}', '${INSTTYPE_19}', '${INSTTYPE_20}',
+            '${INSTTYPE_21}', '${INSTTYPE_22}', '${INSTTYPE_23}', '${INSTTYPE_24}', '${INSTTYPE_25}', '${INSTTYPE_26}',
+            '${INSTTYPE_27}', '${INSTTYPE_28}', '${INSTTYPE_29}', '${INSTTYPE_30}', '${INSTTYPE_31}', '${INSTTYPE_32}',
+            'SetSectionInInstType', 'ClearSectionInInstType', 'SetSectionFlag', 'ClearSectionFlag', 'SectionFlagIsSet'
+            ),
+        13 => array(
+            'Colors.nsh', 'WHITE', 'BLACK', 'YELLOW', 'RED', 'GREEN', 'BLUE', 'MAGENTA', 'CYAN', 'rgb2hex'
+            ),
+        14 => array(
+            'FileFunc.nsh', '${Locate}', '${GetSize}', '${DriveSpace}', '${GetDrives}', '${GetTime}', '${GetFileAttributes}', '${GetFileVersion}', '${GetExeName}', '${GetExePath}', '${GetParameters}', '${GetOptions}', '${GetRoot}', '${GetParent}', '${GetFileName}', '${GetBaseName}', '${GetFileExt}', '${BannerTrimPath}', '${DirState}', '${RefreshShellIcons}'
+            ),
+        15 => array(
+            'TextFunc.nsh', '${LineFind}', '${LineRead}', '${FileReadFromEnd}', '${LineSum}', '${FileJoin}', '${TextCompare}', '${ConfigRead}', '${ConfigWrite}', '${FileRecode}', '${TrimNewLines}'
+            ),
+        16 => array(
+            'WordFunc.nsh', '${WordFind}', '${WordFind2X}', '${WordFind3X}', '${WordReplace}', '${WordAdd}', '${WordInsert}', '${StrFilter}', '${VersionCompare}', '${VersionConvert}'
+            )
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false,
+        8 => false,
+        9 => false,
+        10 => false,
+        11 => false,
+        12 => false,
+        13 => false,
+        14 => false,
+        15 => false,
+        16 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000066; font-weight:bold;',
+            2 => 'color: #000066;',
+            3 => 'color: #003366;',
+            4 => 'color: #000099;',
+            5 => 'color: #ff6600;',
+            6 => 'color: #ff6600;',
+            7 => 'color: #006600;',
+            8 => 'color: #006600;',
+            9 => 'color: #006600;',
+            10 => 'color: #006600;',
+            11 => 'color: #006600;',
+            12 => 'color: #006600;',
+            13 => 'color: #006600;',
+            14 => 'color: #006600;',
+            15 => 'color: #006600;',
+            16 => 'color: #006600;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #666666; font-style: italic;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #660066; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => ''
+            ),
+        'STRINGS' => array(
+            0 => 'color: #660066;'
+            ),
+        'NUMBERS' => array(
+            0 => ''
+            ),
+        'METHODS' => array(
+            0 => ''
+            ),
+        'SYMBOLS' => array(
+            0 => ''
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #660000;',
+            1 => 'color: #660000;',
+            2 => 'color: #660000;',
+            3 => 'color: #660000;',
+            4 => 'color: #660000;',
+            5 => 'color: #660000;',
+            6 => 'color: #660000;',
+            7 => 'color: #000099;',
+            8 => 'color: #003399;'
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => '',
+        8 => '',
+        9 => '',
+        10 => '',
+        11 => '',
+        12 => '',
+        13 => '',
+        14 => '',
+        15 => '',
+        16 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        0 => '\$\$',
+        1 => '\$\\r',
+        2 => '\$\\n',
+        3 => '\$\\t',
+        4 => '\$[a-zA-Z0-9_]+',
+        5 => '\$\{.{1,256}\}',
+        6 => '\$\\\(.{1,256}\\\)',
+        7 => array(
+            GESHI_SEARCH => '([^:\/\\\*\?\"\<\>(?:<PIPE>)\s]*?)(::)([^:\/\\\*\?\"\<\>(?:<PIPE>)\s]*?)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => '\\2\\3'
+            ),
+        8 => array(
+            GESHI_SEARCH => '([^:\/\\\*\?\"\<\>(?:<PIPE>)\s]*?)(::)([^:\/\\\*\?\"\<\>(?:<PIPE>)]*?\s)',
+            GESHI_REPLACE => '\\3',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1\\2',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/objc.php b/examples/includes/geshi/geshi/objc.php
new file mode 100644 (file)
index 0000000..668f14b
--- /dev/null
@@ -0,0 +1,358 @@
+<?php
+/*************************************************************************************
+ * objc.php
+ * --------
+ * Author: M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ * Contributors: Quinn Taylor (quinntaylor@mac.com)
+ * Copyright: (c) 2008 Quinn Taylor, 2004 M. Uli Kusterer, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * Objective-C language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ *   -  Added support for @ before strings being highlighted
+ * 2008/06/10 (1.0.7.22)
+ *   -  Added keywords for Objective-C 2.0 (Leopard+).
+ *   -  Changed colors to match Xcode 3 highlighting more closely.
+ *   -  Updated API for AppKit and Foundation; added CoreData classes.
+ *   -  Updated URLs for AppKit and Foundation; split classes and protocols.
+ *   -  Sorted all keyword group in reverse-alpha order for correct matching.
+ *   -  Changed all keyword groups to be case-sensitive.
+ * 2004/11/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Objective-C',
+    'COMMENT_SINGLE' => array(
+        //Compiler directives
+        1 => '#',
+        //Single line C-Comments
+        2 => '//'
+        ),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        //Multiline Continuation for single-line comment
+        2 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        //Pseudo-Highlighting of the @-sign before strings
+        3 => "/@(?=\")/"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', "'"),
+    'ESCAPE_CHAR' => '\\',
+
+    'KEYWORDS' => array(
+        // Objective-C keywords
+        1 => array(
+            'while', 'switch', 'return', 'in', 'if', 'goto', 'foreach', 'for',
+            'else', 'do', 'default', 'continue', 'case', '@try', '@throw',
+            '@synthesize', '@synchronized', '@selector', '@public', '@protocol',
+            '@protected', '@property', '@private', '@interface',
+            '@implementation', '@finally', '@end', '@encode', '@defs', '@class',
+            '@catch'
+            ),
+        // Macros and constants
+        2 => array(
+            'YES', 'USHRT_MAX', 'ULONG_MAX', 'UINT_MAX', 'UCHAR_MAX', 'true',
+            'TMP_MAX', 'stdout', 'stdin', 'stderr', 'SIGTERM', 'SIGSEGV',
+            'SIGINT', 'SIGILL', 'SIG_IGN', 'SIGFPE', 'SIG_ERR', 'SIG_DFL',
+            'SIGABRT', 'SHRT_MIN', 'SHRT_MAX', 'SEEK_SET', 'SEEK_END',
+            'SEEK_CUR', 'SCHAR_MIN', 'SCHAR_MAX', 'RAND_MAX', 'NULL',
+            'NO', 'nil', 'Nil', 'L_tmpnam', 'LONG_MIN', 'LONG_MAX',
+            'LDBL_MIN_EXP', 'LDBL_MIN', 'LDBL_MAX_EXP', 'LDBL_MAX',
+            'LDBL_MANT_DIG', 'LDBL_EPSILON', 'LDBL_DIG', 'INT_MIN', 'INT_MAX',
+            'HUGE_VAL', 'FOPEN_MAX', 'FLT_ROUNDS', 'FLT_RADIX', 'FLT_MIN_EXP',
+            'FLT_MIN', 'FLT_MAX_EXP', 'FLT_MAX', 'FLT_MANT_DIG', 'FLT_EPSILON',
+            'FLT_DIG', 'FILENAME_MAX', 'false', 'EXIT_SUCCESS', 'EXIT_FAILURE',
+            'errno', 'ERANGE', 'EOF', 'enum', 'EDOM', 'DBL_MIN_EXP', 'DBL_MIN',
+            'DBL_MAX_EXP', 'DBL_MAX', 'DBL_MANT_DIG', 'DBL_EPSILON', 'DBL_DIG',
+            'CLOCKS_PER_SEC', 'CHAR_MIN', 'CHAR_MAX', 'CHAR_BIT', 'BUFSIZ',
+            'break'
+            ),
+        // C standard library functions
+        3 => array(
+            'vsprintf', 'vprintf', 'vfprintf', 'va_start', 'va_end', 'va_arg',
+            'ungetc', 'toupper', 'tolower', 'tmpname', 'tmpfile', 'time',
+            'tanh', 'tan', 'system', 'strxfrm', 'strtoul', 'strtol', 'strtok',
+            'strtod', 'strstr', 'strspn', 'strrchr', 'strpbrk', 'strncpy',
+            'strncmp', 'strncat', 'strlen', 'strftime', 'strerror', 'strcspn',
+            'strcpy', 'strcoll', 'strcmp', 'strchr', 'strcat', 'sscanf',
+            'srand', 'sqrt', 'sprintf', 'snprintf', 'sizeof', 'sinh', 'sin',
+            'setvbuf', 'setjmp', 'setbuf', 'scanf', 'rewind', 'rename',
+            'remove', 'realloc', 'rand', 'qsort', 'puts', 'putchar', 'putc',
+            'printf', 'pow', 'perror', 'offsetof', 'modf', 'mktime', 'memset',
+            'memmove', 'memcpy', 'memcmp', 'memchr', 'malloc', 'longjmp',
+            'log10', 'log', 'localtime', 'ldiv', 'ldexp', 'labs', 'isxdigit',
+            'isupper', 'isspace', 'ispunct', 'isprint', 'islower',
+            'isgraph', 'isdigit', 'iscntrl', 'isalpha', 'isalnum', 'gmtime',
+            'gets', 'getenv', 'getchar', 'getc', 'fwrite', 'ftell', 'fsetpos',
+            'fseek', 'fscanf', 'frexp', 'freopen', 'free', 'fread', 'fputs',
+            'fputc', 'fprintf', 'fopen', 'fmod', 'floor', 'fgets', 'fgetpos',
+            'fgetc', 'fflush', 'ferror', 'feof', 'fclose', 'fabs', 'exp',
+            'exit', 'div', 'difftime', 'ctime', 'cosh', 'cos', 'clock',
+            'clearerr', 'ceil', 'calloc', 'bsearch', 'atol', 'atoi', 'atof',
+            'atexit', 'atan2', 'atan', 'assert', 'asin', 'asctime', 'acos',
+            'abs', 'abort'
+            ),
+        // Data types (C, Objective-C, Cocoa)
+        4 => array(
+            'volatile', 'void', 'va_list', 'unsigned', 'union', 'typedef', 'tm',
+            'time_t', 'struct', 'string', 'static', 'size_t',
+            'signed', 'signal', 'short', 'SEL', 'register', 'raise',
+            'ptrdiff_t', 'NSZone', 'NSRect', 'NSRange', 'NSPoint', 'long',
+            'ldiv_t', 'jmp_buf', 'int', 'IMP', 'id', 'fpos_t', 'float', 'FILE',
+            'extern', 'double', 'div_t', 'const', 'clock_t', 'Class', 'char',
+            'BOOL', 'auto'
+            ),
+        // Foundation classes
+        5 => array(
+            'NSXMLParser', 'NSXMLNode', 'NSXMLElement', 'NSXMLDTDNode',
+            'NSXMLDTD', 'NSXMLDocument', 'NSWhoseSpecifier',
+            'NSValueTransformer', 'NSValue', 'NSUserDefaults', 'NSURLResponse',
+            'NSURLRequest', 'NSURLProtocol', 'NSURLProtectionSpace',
+            'NSURLHandle', 'NSURLDownload', 'NSURLCredentialStorage',
+            'NSURLCredential', 'NSURLConnection', 'NSURLCache',
+            'NSURLAuthenticationChallenge', 'NSURL', 'NSUniqueIDSpecifier',
+            'NSUndoManager', 'NSUnarchiver', 'NSTimeZone', 'NSTimer',
+            'NSThread', 'NSTask', 'NSString', 'NSStream', 'NSSpellServer',
+            'NSSpecifierTest', 'NSSortDescriptor', 'NSSocketPortNameServer',
+            'NSSocketPort', 'NSSetCommand', 'NSSet', 'NSSerializer',
+            'NSScriptWhoseTest', 'NSScriptSuiteRegistry',
+            'NSScriptObjectSpecifier', 'NSScriptExecutionContext',
+            'NSScriptCommandDescription', 'NSScriptCommand',
+            'NSScriptCoercionHandler', 'NSScriptClassDescription', 'NSScanner',
+            'NSRunLoop', 'NSRelativeSpecifier', 'NSRecursiveLock',
+            'NSRangeSpecifier', 'NSRandomSpecifier', 'NSQuitCommand', 'NSProxy',
+            'NSProtocolChecker', 'NSPropertySpecifier',
+            'NSPropertyListSerialization', 'NSProcessInfo', 'NSPredicate',
+            'NSPositionalSpecifier', 'NSPortNameServer', 'NSPortMessage',
+            'NSPortCoder', 'NSPort', 'NSPointerFunctions', 'NSPointerArray',
+            'NSPipe', 'NSOutputStream', 'NSOperationQueue', 'NSOperation',
+            'NSObject', 'NSNumberFormatter', 'NSNumber', 'NSNull',
+            'NSNotificationQueue', 'NSNotificationCenter', 'NSNotification',
+            'NSNetServiceBrowser', 'NSNetService', 'NSNameSpecifier',
+            'NSMutableURLRequest', 'NSMutableString', 'NSMutableSet',
+            'NSMutableIndexSet', 'NSMutableDictionary', 'NSMutableData',
+            'NSMutableCharacterSet', 'NSMutableAttributedString',
+            'NSMutableArray', 'NSMoveCommand', 'NSMiddleSpecifier',
+            'NSMethodSignature', 'NSMetadataQueryResultGroup',
+            'NSMetadataQueryAttributeValueTuple', 'NSMetadataQuery',
+            'NSMetadataItem', 'NSMessagePortNameServer', 'NSMessagePort',
+            'NSMapTable', 'NSMachPort', 'NSMachBootstrapServer',
+            'NSLogicalTest', 'NSLock', 'NSLocale', 'NSKeyedUnarchiver',
+            'NSKeyedArchiver', 'NSInvocationOperation', 'NSInvocation',
+            'NSInputStream', 'NSIndexSpecifier', 'NSIndexSet', 'NSIndexPath',
+            'NSHTTPURLResponse', 'NSHTTPCookieStorage', 'NSHTTPCookie',
+            'NSHost', 'NSHashTable', 'NSGetCommand', 'NSGarbageCollector',
+            'NSFormatter', 'NSFileManager', 'NSFileHandle', 'NSExpression',
+            'NSExistsCommand', 'NSException', 'NSError', 'NSEnumerator',
+            'NSDistributedNotificationCenter', 'NSDistributedLock',
+            'NSDistantObjectRequest', 'NSDistantObject',
+            'NSDirectoryEnumerator', 'NSDictionary', 'NSDeserializer',
+            'NSDeleteCommand', 'NSDecimalNumberHandler', 'NSDecimalNumber',
+            'NSDateFormatter', 'NSDateComponents', 'NSDate', 'NSData',
+            'NSCreateCommand', 'NSCountedSet', 'NSCountCommand', 'NSConnection',
+            'NSConditionLock', 'NSCondition', 'NSCompoundPredicate',
+            'NSComparisonPredicate', 'NSCoder', 'NSCloseCommand',
+            'NSCloneCommand', 'NSClassDescription', 'NSCharacterSet',
+            'NSCalendarDate', 'NSCalendar', 'NSCachedURLResponse', 'NSBundle',
+            'NSAutoreleasePool', 'NSAttributedString', 'NSAssertionHandler',
+            'NSArray', 'NSArchiver', 'NSAppleScript', 'NSAppleEventManager',
+            'NSAppleEventDescriptor', 'NSAffineTransform'
+            ),
+        // Foundation protocols
+        6 => array(
+            'NSURLProtocolClient', 'NSURLHandleClient', 'NSURLClient',
+            'NSURLAuthenticationChallengeSender', 'NSScriptObjectSpecifiers',
+            'NSScriptKeyValueCoding', 'NSScriptingComparisonMethods',
+            'NSObjCTypeSerializationCallBack', 'NSMutableCopying',
+            'NSLocking', 'NSKeyValueObserving', 'NSKeyValueCoding',
+            'NSFastEnumeration', 'NSErrorRecoveryAttempting',
+            'NSDecimalNumberBehaviors', 'NSCopying', 'NSComparisonMethods',
+            'NSCoding'
+            ),
+        // AppKit classes
+        7 => array(
+            'NSWorkspace', 'NSWindowController', 'NSWindow', 'NSViewController',
+            'NSViewAnimation', 'NSView', 'NSUserDefaultsController',
+            'NSTypesetter', 'NSTreeNode', 'NSTreeController', 'NSTrackingArea',
+            'NSToolbarItemGroup', 'NSToolbarItem', 'NSToolbar',
+            'NSTokenFieldCell', 'NSTokenField', 'NSTextView',
+            'NSTextTableBlock', 'NSTextTable', 'NSTextTab', 'NSTextStorage',
+            'NSTextList', 'NSTextFieldCell', 'NSTextField', 'NSTextContainer',
+            'NSTextBlock', 'NSTextAttachmentCell', 'NSTextAttachment', 'NSText',
+            'NSTabViewItem', 'NSTabView', 'NSTableView', 'NSTableHeaderView',
+            'NSTableHeaderCell', 'NSTableColumn', 'NSStepperCell', 'NSStepper',
+            'NSStatusItem', 'NSStatusBar', 'NSSplitView', 'NSSpellChecker',
+            'NSSpeechSynthesizer', 'NSSpeechRecognizer', 'NSSound',
+            'NSSliderCell', 'NSSlider', 'NSSimpleHorizontalTypesetter',
+            'NSShadow', 'NSSegmentedControl', 'NSSegmentedCell',
+            'NSSecureTextFieldCell', 'NSSecureTextField', 'NSSearchFieldCell',
+            'NSSearchField', 'NSScrollView', 'NSScroller', 'NSScreen',
+            'NSSavePanel', 'NSRulerView', 'NSRulerMarker', 'NSRuleEditor',
+            'NSResponder', 'NSQuickDrawView', 'NSProgressIndicator',
+            'NSPrintPanel', 'NSPrintOperation', 'NSPrintInfo', 'NSPrinter',
+            'NSPredicateEditorRowTemplate', 'NSPredicateEditor',
+            'NSPopUpButtonCell', 'NSPopUpButton', 'NSPICTImageRep',
+            'NSPersistentDocument', 'NSPDFImageRep', 'NSPathControl',
+            'NSPathComponentCell', 'NSPathCell', 'NSPasteboard',
+            'NSParagraphStyle', 'NSPanel', 'NSPageLayout', 'NSOutlineView',
+            'NSOpenPanel', 'NSOpenGLView', 'NSOpenGLPixelFormat',
+            'NSOpenGLPixelBuffer', 'NSOpenGLContext', 'NSObjectController',
+            'NSNibOutletConnector', 'NSNibControlConnector', 'NSNibConnector',
+            'NSNib', 'NSMutableParagraphStyle', 'NSMovieView', 'NSMovie',
+            'NSMenuView', 'NSMenuItemCell', 'NSMenuItem', 'NSMenu', 'NSMatrix',
+            'NSLevelIndicatorCell', 'NSLevelIndicator', 'NSLayoutManager',
+            'NSInputServer', 'NSInputManager', 'NSImageView', 'NSImageRep',
+            'NSImageCell', 'NSImage', 'NSHelpManager', 'NSGraphicsContext',
+            'NSGradient', 'NSGlyphInfo', 'NSGlyphGenerator', 'NSFormCell',
+            'NSForm', 'NSFontPanel', 'NSFontManager', 'NSFontDescriptor',
+            'NSFont', 'NSFileWrapper', 'NSEvent', 'NSEPSImageRep', 'NSDrawer',
+            'NSDocumentController', 'NSDocument', 'NSDockTile',
+            'NSDictionaryController', 'NSDatePickerCell', 'NSDatePicker',
+            'NSCustomImageRep', 'NSCursor', 'NSController', 'NSControl',
+            'NSComboBoxCell', 'NSComboBox', 'NSColorWell', 'NSColorSpace',
+            'NSColorPicker', 'NSColorPanel', 'NSColorList', 'NSColor',
+            'NSCollectionViewItem', 'NSCollectionView', 'NSClipView',
+            'NSCIImageRep', 'NSCell', 'NSCachedImageRep', 'NSButtonCell',
+            'NSButton', 'NSBrowserCell', 'NSBrowser', 'NSBox',
+            'NSBitmapImageRep', 'NSBezierPath', 'NSATSTypesetter',
+            'NSArrayController', 'NSApplication', 'NSAnimationContext',
+            'NSAnimation', 'NSAlert', 'NSActionCell'
+            ),
+        // AppKit protocols
+        8 => array(
+            'NSWindowScripting', 'NSValidatedUserInterfaceItem',
+            'NSUserInterfaceValidations', 'NSToolTipOwner',
+            'NSToolbarItemValidation', 'NSTextInput',
+            'NSTableDataSource', 'NSServicesRequests',
+            'NSPrintPanelAccessorizing', 'NSPlaceholders',
+            'NSPathControlDelegate', 'NSPathCellDelegate',
+            'NSOutlineViewDataSource', 'NSNibAwaking', 'NSMenuValidation',
+            'NSKeyValueBindingCreation', 'NSInputServiceProvider',
+            'NSInputServerMouseTracker', 'NSIgnoreMisspelledWords',
+            'NSGlyphStorage', 'NSFontPanelValidation', 'NSEditorRegistration',
+            'NSEditor', 'NSDraggingSource', 'NSDraggingInfo',
+            'NSDraggingDestination', 'NSDictionaryControllerKeyValuePair',
+            'NSComboBoxDataSource', 'NSComboBoxCellDataSource',
+            'NSColorPickingDefault', 'NSColorPickingCustom', 'NSChangeSpelling',
+            'NSAnimatablePropertyContainer', 'NSAccessibility'
+            ),
+        // CoreData classes
+        9 => array(
+            'NSRelationshipDescription', 'NSPropertyMapping',
+            'NSPropertyDescription', 'NSPersistentStoreCoordinator',
+            'NSPersistentStore', 'NSMigrationManager', 'NSMappingModel',
+            'NSManagedObjectModel', 'NSManagedObjectID',
+            'NSManagedObjectContext', 'NSManagedObject',
+            'NSFetchRequestExpression', 'NSFetchRequest',
+            'NSFetchedPropertyDescription', 'NSEntityMigrationPolicy',
+            'NSEntityMapping', 'NSEntityDescription', 'NSAttributeDescription',
+            'NSAtomicStoreCacheNode', 'NSAtomicStore'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => true,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true,
+        9 => true
+        ),
+    // Define the colors for the groups listed above
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #a61390;', // Objective-C keywords
+            2 => 'color: #a61390;', // Macros and constants
+            3 => 'color: #a61390;', // C standard library functions
+            4 => 'color: #a61390;', // data types
+            5 => 'color: #400080;', // Foundation classes
+            6 => 'color: #2a6f76;', // Foundation protocols
+            7 => 'color: #400080;', // AppKit classes
+            8 => 'color: #2a6f76;', // AppKit protocols
+            9 => 'color: #400080;' // CoreData classes
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #6e371a;', // Preprocessor directives
+            2 => 'color: #11740a; font-style: italic;', // Normal C single-line comments
+            3 => 'color: #bf1d1a;', // Q-sign in front of Strings
+            'MULTI' => 'color: #11740a; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #2400d9;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #002200;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #bf1d1a;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #2400d9;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #002200;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAME}.html',
+        4 => '',
+        5 => 'http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/{FNAME}_Class/',
+        6 => 'http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/{FNAME}_Protocol/',
+        7 => 'http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/{FNAME}_Class/',
+        8 => 'http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Protocols/{FNAME}_Protocol/',
+        9 => 'http://developer.apple.com/documentation/Cocoa/Reference/CoreDataFramework/Classes/{FNAME}_Class/'
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/ocaml-brief.php b/examples/includes/geshi/geshi/ocaml-brief.php
new file mode 100644 (file)
index 0000000..8c15519
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+/*************************************************************************************
+ * ocaml.php
+ * ----------
+ * Author: Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/08/27
+ *
+ * OCaml (Objective Caml) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2005/08/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'OCaml (brief)',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('(*' => '*)'),
+    'CASE_KEYWORDS' => 0,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => "",
+    'KEYWORDS' => array(
+        /* main OCaml keywords */
+        1 => array(
+            'and', 'as', 'asr', 'begin', 'class', 'closed', 'constraint', 'do', 'done', 'downto', 'else',
+            'end', 'exception', 'external', 'failwith', 'false', 'flush', 'for', 'fun', 'function', 'functor',
+            'if', 'in', 'include', 'inherit',  'incr', 'land', 'let', 'load', 'los', 'lsl', 'lsr', 'lxor',
+            'match', 'method', 'mod', 'module', 'mutable', 'new', 'not', 'of', 'open', 'option', 'or', 'parser',
+            'private', 'ref', 'rec', 'raise', 'regexp', 'sig', 'struct', 'stdout', 'stdin', 'stderr', 'then',
+            'to', 'true', 'try', 'type', 'val', 'virtual', 'when', 'while', 'with'
+            )
+        ),
+    /* highlighting symbols is really important in OCaml */
+    'SYMBOLS' => array(
+        ';', '!', ':', '.', '=', '%', '^', '*', '-', '/', '+',
+        '>', '<', '(', ')', '[', ']', '&', '|', '#', "'"
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #06c; font-weight: bold;' /* nice blue */
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #5d478b; font-style: italic;' /* light purple */
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #6c6;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #3cb371;' /* nice green */
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #c6c;' /* pink */
+            ),
+        'METHODS' => array(
+            1 => 'color: #060;' /* dark green */
+            ),
+        'REGEXPS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #a52a2a;' /* maroon */
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/ocaml.php b/examples/includes/geshi/geshi/ocaml.php
new file mode 100644 (file)
index 0000000..e21ca7f
--- /dev/null
@@ -0,0 +1,174 @@
+<?php
+/*************************************************************************************
+ * ocaml.php
+ * ----------
+ * Author: Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/08/27
+ *
+ * OCaml (Objective Caml) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/03/29 (1.0.7.22)
+ *   -  Fixed warnings resulting from missing style information
+ * 2005/08/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2005/08/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'OCaml',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('(*' => '*)'),
+    'CASE_KEYWORDS' => 0,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => "",
+    'KEYWORDS' => array(
+        /* main OCaml keywords */
+        1 => array(
+            'and', 'as', 'asr', 'begin', 'class', 'closed', 'constraint', 'do', 'done', 'downto', 'else',
+            'end', 'exception', 'external', 'failwith', 'false', 'for', 'fun', 'function', 'functor',
+            'if', 'in', 'include', 'inherit',  'incr', 'land', 'let', 'load', 'los', 'lsl', 'lsr', 'lxor',
+            'match', 'method', 'mod', 'module', 'mutable', 'new', 'not', 'of', 'open', 'option', 'or', 'parser',
+            'private', 'ref', 'rec', 'raise', 'regexp', 'sig', 'struct', 'stdout', 'stdin', 'stderr', 'then',
+            'to', 'true', 'try', 'type', 'val', 'virtual', 'when', 'while', 'with'
+            ),
+        /* define names of main librarys, so we can link to it */
+        2 => array(
+            'Arg', 'Arith_status', 'Array', 'ArrayLabels', 'Big_int', 'Bigarray', 'Buffer', 'Callback',
+            'CamlinternalOO', 'Char', 'Complex', 'Condition', 'Dbm', 'Digest', 'Dynlink', 'Event',
+            'Filename', 'Format', 'Gc', 'Genlex', 'Graphics', 'GraphicsX11', 'Hashtbl', 'Int32', 'Int64',
+            'Lazy', 'Lexing', 'List', 'ListLabels', 'Map', 'Marshal', 'MoreLabels', 'Mutex', 'Nativeint',
+            'Num', 'Obj', 'Oo', 'Parsing', 'Pervasives', 'Printexc', 'Printf', 'Queue', 'Random', 'Scanf',
+            'Set', 'Sort', 'Stack', 'StdLabels', 'Str', 'Stream', 'String', 'StringLabels', 'Sys', 'Thread',
+            'ThreadUnix', 'Tk'
+            ),
+        /* just link to the Pervasives functions library, cause it's the default opened library when starting OCaml */
+        3 => array(
+            'abs', 'abs_float', 'acos', 'asin', 'at_exit', 'atan', 'atan2',
+            'bool_of_string', 'ceil', 'char_of_int', 'classify_float',
+            'close_in', 'close_in_noerr', 'close_out', 'close_out_noerr',
+            'compare', 'cos', 'cosh', 'decr', 'epsilon_float', 'exit', 'exp',
+            'float', 'float_of_int', 'float_of_string', 'floor', 'flush',
+            'flush_all', 'format_of_string', 'frexp', 'fst', 'ignore',
+            'in_channel_length', 'infinity', 'input', 'input_binary_int',
+            'input_byte', 'input_char', 'input_line', 'input_value',
+            'int_of_char', 'int_of_float', 'int_of_string', 'invalid_arg',
+            'ldexp', 'log', 'log10', 'max', 'max_float', 'max_int', 'min',
+            'min_float', 'min_int', 'mod_float', 'modf', 'nan', 'open_in',
+            'open_in_bin', 'open_in_gen', 'open_out', 'open_out_bin',
+            'open_out_gen', 'out_channel_length', 'output', 'output_binary_int',
+            'output_byte', 'output_char', 'output_string', 'output_value',
+            'pos_in', 'pos_out',  'pred', 'prerr_char', 'prerr_endline',
+            'prerr_float', 'prerr_int', 'prerr_newline', 'prerr_string',
+            'print_char', 'print_endline', 'print_float', 'print_int',
+            'print_newline', 'print_string', 'read_float', 'read_int',
+            'read_line', 'really_input', 'seek_in', 'seek_out',
+            'set_binary_mode_in', 'set_binary_mode_out', 'sin', 'sinh', 'snd',
+            'sqrt', 'string_of_bool', 'string_of_float', 'string_of_format',
+            'string_of_int', 'succ', 'tan', 'tanh', 'truncate'
+            ),
+        /* here Pervasives Types */
+        4 => array (
+            'fpclass', 'in_channel', 'out_channel', 'open_flag', 'Sys_error', 'format'
+            ),
+        /* finally Pervasives Exceptions */
+        5 => array (
+            'Exit', 'Invalid_Argument', 'Failure', 'Division_by_zero'
+            )
+        ),
+    /* highlighting symbols is really important in OCaml */
+    'SYMBOLS' => array(
+        ';', '!', ':', '.', '=', '%', '^', '*', '-', '/', '+',
+        '>', '<', '(', ')', '[', ']', '&', '|', '#', "'"
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => true, /* functions name are case sensitive */
+        3 => true, /* types name too */
+        4 => true, /* pervasives types */
+        5 => true  /* pervasives exceptions */
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #06c; font-weight: bold;', /* nice blue */
+            2 => 'color: #06c; font-weight: bold;', /* nice blue */
+            3 => 'color: #06c; font-weight: bold;', /* nice blue */
+            4 => 'color: #06c; font-weight: bold;', /* nice blue */
+            5 => 'color: #06c; font-weight: bold;' /* nice blue */
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #5d478b; font-style: italic;' /* light purple */
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #6c6;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #3cb371;' /* nice green */
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #c6c;' /* pink */
+            ),
+        'METHODS' => array(
+            1 => 'color: #060;' /* dark green */
+            ),
+        'REGEXPS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #a52a2a;' /* maroon */
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        /* some of keywords are Pervasives functions (land, lxor, asr, ...) */
+        1 => '',
+        /* link to the wanted library */
+        2 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/{FNAME}.html',
+        /* link to Pervasives functions */
+        3 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VAL{FNAME}',
+        /* link to Pervasives type */
+        4 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#TYPE{FNAME}',
+        /* link to Pervasives exceptions */
+        5 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#EXCEPTION{FNAME}'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/oobas.php b/examples/includes/geshi/geshi/oobas.php
new file mode 100644 (file)
index 0000000..5ca65cd
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+/*************************************************************************************
+ * oobas.php
+ * ---------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * OpenOffice.org Basic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'OpenOffice.org Basic',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array(),
+    //Single-Line comments using REM keyword
+    'COMMENT_REGEXP' => array(2 => '/\bREM.*?$/i'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'dim','private','public','global','as','if','redim','true','set','byval',
+            'false','bool','double','integer','long','object','single','variant',
+            'msgbox','print','inputbox','green','blue','red','qbcolor',
+            'rgb','open','close','reset','freefile','get','input','line',
+            'put','write','loc','seek','eof','lof','chdir','chdrive',
+            'curdir','dir','fileattr','filecopy','filedatetime','fileexists',
+            'filelen','getattr','kill','mkdir','name','rmdir','setattr',
+            'dateserial','datevalue','day','month','weekday','year','cdatetoiso',
+            'cdatefromiso','hour','minute','second','timeserial','timevalue',
+            'date','now','time','timer','erl','err','error','on','goto','resume',
+            'and','eqv','imp','not','or','xor','mod','atn','cos','sin','tan','log',
+            'exp','rnd','randomize','sqr','fix','int','abs','sgn','hex','oct',
+            'it','then','else','select','case','iif','do','loop','for','next','to',
+            'while','wend','gosub','return','call','choose','declare',
+            'end','exit','freelibrary','function','rem','stop','sub','switch','with',
+            'cbool','cdate','cdbl','cint','clng','const','csng','cstr','defbool',
+            'defdate','defdbl','defint','deflng','asc','chr','str','val','cbyte',
+            'space','string','format','lcase','left','lset','ltrim','mid','right',
+            'rset','rtrim','trim','ucase','split','join','converttourl','convertfromurl',
+            'instr','len','strcomp','beep','shell','wait','getsystemticks','environ',
+            'getsolarversion','getguitype','twipsperpixelx','twipsperpixely',
+            'createunostruct','createunoservice','getprocessservicemanager',
+            'createunodialog','createunolistener','createunovalue','thiscomponent',
+            'globalscope'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080;',
+            2 => 'color: #808080;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/oracle11.php b/examples/includes/geshi/geshi/oracle11.php
new file mode 100644 (file)
index 0000000..7d267b1
--- /dev/null
@@ -0,0 +1,614 @@
+<?php
+/*************************************************************************************
+ * oracle11.php
+ * -----------
+ * Author: Guy Wicks (Guy.Wicks@rbs.co.uk)
+ * Contributions:
+ * - Updated for 11i by Simon Redhead
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * Oracle 11i language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/08 (1.0.8)
+ *  -  SR changes to oracle8.php to support Oracle 11i reserved words.
+ * 2005/01/29 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Oracle 11 SQL',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array("'", '"', '`'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+//Put your package names here - e.g. select distinct ''''|| lower(name) || ''',' from user_source;
+//        6 => array(
+//            ),
+
+//Put your table names here - e.g. select distinct ''''|| lower(table_name) || ''',' from user_tables;
+//        5 => array(
+//            ),
+
+//Put your view names here - e.g. select distinct ''''|| lower(view_name) || ''',' from user_views;
+//        4 => array(
+//            ),
+
+//Put your table field names here - e.g. select distinct ''''|| lower(column_name) || ''',' from user_tab_columns;
+//        3 => array(
+//            ),
+
+        //Put ORACLE reserved keywords here (11i).  I like mine uppercase.
+        1 => array(
+            'ABS',
+            'ACCESS',
+            'ACOS',
+            'ADD',
+            'ADD_MONTHS',
+            'ALL',
+            'ALTER',
+            'ANALYZE',
+            'AND',
+            'ANY',
+            'APPENDCHILDXML',
+            'ARRAY',
+            'AS',
+            'ASC',
+            'ASCII',
+            'ASCIISTR',
+            'ASIN',
+            'ASSOCIATE',
+            'AT',
+            'ATAN',
+            'ATAN2',
+            'AUDIT',
+            'AUTHID',
+            'AVG',
+            'BEGIN',
+            'BETWEEN',
+            'BFILENAME',
+            'BIN_TO_NUM',
+            'BINARY_INTEGER',
+            'BITAND',
+            'BODY',
+            'BOOLEAN',
+            'BULK',
+            'BY',
+            'CALL',
+            'CARDINALITY',
+            'CASCADE',
+            'CASE',
+            'CAST',
+            'CEIL',
+            'CHAR',
+            'CHAR_BASE',
+            'CHARTOROWID',
+            'CHECK',
+            'CHR',
+            'CLOSE',
+            'CLUSTER',
+            'CLUSTER_ID',
+            'CLUSTER_PROBABILITY',
+            'CLUSTER_SET',
+            'COALESCE',
+            'COLLECT',
+            'COLUMN',
+            'COMMENT',
+            'COMMIT',
+            'COMPOSE',
+            'COMPRESS',
+            'CONCAT',
+            'CONNECT',
+            'CONSTANT',
+            'CONSTRAINT',
+            'CONSTRAINTS',
+            'CONTEXT',
+            'CONTROLFILE',
+            'CONVERT',
+            'CORR',
+            'CORR_K',
+            'CORR_S',
+            'COS',
+            'COSH',
+            'COST',
+            'COUNT',
+            'COVAR_POP',
+            'COVAR_SAMP',
+            'CREATE',
+            'CUBE_TABLE',
+            'CUME_DIST',
+            'CURRENT',
+            'CURRENT_DATE',
+            'CURRENT_TIMESTAMP',
+            'CURRVAL',
+            'CURSOR',
+            'CV',
+            'DATABASE',
+            'DATAOBJ_TO_PARTITION',
+            'DATE',
+            'DAY',
+            'DBTIMEZONE',
+            'DECIMAL',
+            'DECLARE',
+            'DECODE',
+            'DECOMPOSE',
+            'DEFAULT',
+            'DELETE',
+            'DELETEXML',
+            'DENSE_RANK',
+            'DEPTH',
+            'DEREF',
+            'DESC',
+            'DIMENSION',
+            'DIRECTORY',
+            'DISASSOCIATE',
+            'DISTINCT',
+            'DO',
+            'DROP',
+            'DUMP',
+            'ELSE',
+            'ELSIF',
+            'EMPTY_BLOB',
+            'EMPTY_CLOB',
+            'END',
+            'EXCEPTION',
+            'EXCLUSIVE',
+            'EXEC',
+            'EXECUTE',
+            'EXISTS',
+            'EXISTSNODE',
+            'EXIT',
+            'EXP',
+            'EXPLAIN',
+            'EXTENDS',
+            'EXTRACT',
+            'EXTRACTVALUE',
+            'FALSE',
+            'FEATURE_ID',
+            'FEATURE_SET',
+            'FEATURE_VALUE',
+            'FETCH',
+            'FILE',
+            'FIRST',
+            'FIRST_VALUE',
+            'FLOAT',
+            'FLOOR',
+            'FOR',
+            'FORALL',
+            'FROM',
+            'FROM_TZ',
+            'FUNCTION',
+            'GOTO',
+            'GRANT',
+            'GREATEST',
+            'GROUP',
+            'GROUP_ID',
+            'GROUPING',
+            'GROUPING_ID',
+            'HAVING',
+            'HEAP',
+            'HEXTORAW',
+            'HOUR',
+            'IDENTIFIED',
+            'IF',
+            'IMMEDIATE',
+            'IN',
+            'INCREMENT',
+            'INDEX',
+            'INDEXTYPE',
+            'INDICATOR',
+            'INITCAP',
+            'INITIAL',
+            'INSERT',
+            'INSERTCHILDXML',
+            'INSERTXMLBEFORE',
+            'INSTR',
+            'INSTRB',
+            'INTEGER',
+            'INTERFACE',
+            'INTERSECT',
+            'INTERVAL',
+            'INTO',
+            'IS',
+            'ISOLATION',
+            'ITERATION_NUMBER',
+            'JAVA',
+            'KEY',
+            'LAG',
+            'LAST',
+            'LAST_DAY',
+            'LAST_VALUE',
+            'LEAD',
+            'LEAST',
+            'LENGTH',
+            'LENGTHB',
+            'LEVEL',
+            'LIBRARY',
+            'LIKE',
+            'LIMITED',
+            'LINK',
+            'LN',
+            'LNNVL',
+            'LOCALTIMESTAMP',
+            'LOCK',
+            'LOG',
+            'LONG',
+            'LOOP',
+            'LOWER',
+            'LPAD',
+            'LTRIM',
+            'MAKE_REF',
+            'MATERIALIZED',
+            'MAX',
+            'MAXEXTENTS',
+            'MEDIAN',
+            'MIN',
+            'MINUS',
+            'MINUTE',
+            'MLSLABEL',
+            'MOD',
+            'MODE',
+            'MODIFY',
+            'MONTH',
+            'MONTHS_BETWEEN',
+            'NANVL',
+            'NATURAL',
+            'NATURALN',
+            'NCHR',
+            'NEW',
+            'NEW_TIME',
+            'NEXT_DAY',
+            'NEXTVAL',
+            'NLS_CHARSET_DECL_LEN',
+            'NLS_CHARSET_ID',
+            'NLS_CHARSET_NAME',
+            'NLS_INITCAP',
+            'NLS_LOWER',
+            'NLS_UPPER',
+            'NLSSORT',
+            'NOAUDIT',
+            'NOCOMPRESS',
+            'NOCOPY',
+            'NOT',
+            'NOWAIT',
+            'NTILE',
+            'NULL',
+            'NULLIF',
+            'NUMBER',
+            'NUMBER_BASE',
+            'NUMTODSINTERVAL',
+            'NUMTOYMINTERVAL',
+            'NVL',
+            'NVL2',
+            'OCIROWID',
+            'OF',
+            'OFFLINE',
+            'ON',
+            'ONLINE',
+            'OPAQUE',
+            'OPEN',
+            'OPERATOR',
+            'OPTION',
+            'OR',
+            'ORA_HASH',
+            'ORDER',
+            'ORGANIZATION',
+            'OTHERS',
+            'OUT',
+            'OUTLINE',
+            'PACKAGE',
+            'PARTITION',
+            'PATH',
+            'PCTFREE',
+            'PERCENT_RANK',
+            'PERCENTILE_CONT',
+            'PERCENTILE_DISC',
+            'PLAN',
+            'PLS_INTEGER',
+            'POSITIVE',
+            'POSITIVEN',
+            'POWER',
+            'POWERMULTISET',
+            'POWERMULTISET_BY_CARDINALITY',
+            'PRAGMA',
+            'PREDICTION',
+            'PREDICTION_BOUNDS',
+            'PREDICTION_COST',
+            'PREDICTION_DETAILS',
+            'PREDICTION_PROBABILITY',
+            'PREDICTION_SET',
+            'PRESENTNNV',
+            'PRESENTV',
+            'PREVIOUS',
+            'PRIMARY',
+            'PRIOR',
+            'PRIVATE',
+            'PRIVILEGES',
+            'PROCEDURE',
+            'PROFILE',
+            'PUBLIC',
+            'RAISE',
+            'RANGE',
+            'RANK',
+            'RATIO_TO_REPORT',
+            'RAW',
+            'RAWTOHEX',
+            'RAWTONHEX',
+            'REAL',
+            'RECORD',
+            'REF',
+            'REFTOHEX',
+            'REGEXP_COUNT',
+            'REGEXP_INSTR',
+            'REGEXP_REPLACE',
+            'REGEXP_SUBSTR',
+            'REGR_AVGX',
+            'REGR_AVGY',
+            'REGR_COUNT',
+            'REGR_INTERCEPT',
+            'REGR_R2',
+            'REGR_SLOPE',
+            'REGR_SXX',
+            'REGR_SXY',
+            'REGR_SYY',
+            'RELEASE',
+            'REMAINDER',
+            'RENAME',
+            'REPLACE',
+            'RESOURCE',
+            'RETURN',
+            'RETURNING',
+            'REVERSE',
+            'REVOKE',
+            'ROLE',
+            'ROLLBACK',
+            'ROUND',
+            'ROW',
+            'ROW_NUMBER',
+            'ROWID',
+            'ROWIDTOCHAR',
+            'ROWIDTONCHAR',
+            'ROWNUM',
+            'ROWS',
+            'ROWTYPE',
+            'RPAD',
+            'RTRIM',
+            'SAVEPOINT',
+            'SCHEMA',
+            'SCN_TO_TIMESTAMP',
+            'SECOND',
+            'SEGMENT',
+            'SELECT',
+            'SEPERATE',
+            'SEQUENCE',
+            'SESSION',
+            'SESSIONTIMEZONE',
+            'SET',
+            'SHARE',
+            'SIGN',
+            'SIN',
+            'SINH',
+            'SIZE',
+            'SMALLINT',
+            'SOUNDEX',
+            'SPACE',
+            'SQL',
+            'SQLCODE',
+            'SQLERRM',
+            'SQRT',
+            'START',
+            'STATISTICS',
+            'STATS_BINOMIAL_TEST',
+            'STATS_CROSSTAB',
+            'STATS_F_TEST',
+            'STATS_KS_TEST',
+            'STATS_MODE',
+            'STATS_MW_TEST',
+            'STATS_ONE_WAY_ANOVA',
+            'STATS_T_TEST_INDEP',
+            'STATS_T_TEST_INDEPU',
+            'STATS_T_TEST_ONE',
+            'STATS_T_TEST_PAIRED',
+            'STATS_WSR_TEST',
+            'STDDEV',
+            'STDDEV_POP',
+            'STDDEV_SAMP',
+            'STOP',
+            'SUBSTR',
+            'SUBSTRB',
+            'SUBTYPE',
+            'SUCCESSFUL',
+            'SUM',
+            'SYNONYM',
+            'SYS_CONNECT_BY_PATH',
+            'SYS_CONTEXT',
+            'SYS_DBURIGEN',
+            'SYS_EXTRACT_UTC',
+            'SYS_GUID',
+            'SYS_TYPEID',
+            'SYS_XMLAGG',
+            'SYS_XMLGEN',
+            'SYSDATE',
+            'SYSTEM',
+            'SYSTIMESTAMP',
+            'TABLE',
+            'TABLESPACE',
+            'TAN',
+            'TANH',
+            'TEMPORARY',
+            'THEN',
+            'TIME',
+            'TIMESTAMP',
+            'TIMESTAMP_TO_SCN',
+            'TIMEZONE_ABBR',
+            'TIMEZONE_HOUR',
+            'TIMEZONE_MINUTE',
+            'TIMEZONE_REGION',
+            'TIMING',
+            'TO',
+            'TO_BINARY_DOUBLE',
+            'TO_BINARY_FLOAT',
+            'TO_CHAR',
+            'TO_CLOB',
+            'TO_DATE',
+            'TO_DSINTERVAL',
+            'TO_LOB',
+            'TO_MULTI_BYTE',
+            'TO_NCHAR',
+            'TO_NCLOB',
+            'TO_NUMBER',
+            'TO_SINGLE_BYTE',
+            'TO_TIMESTAMP',
+            'TO_TIMESTAMP_TZ',
+            'TO_YMINTERVAL',
+            'TRANSACTION',
+            'TRANSLATE',
+            'TREAT',
+            'TRIGGER',
+            'TRIM',
+            'TRUE',
+            'TRUNC',
+            'TRUNCATE',
+            'TYPE',
+            'TZ_OFFSET',
+            'UI',
+            'UID',
+            'UNION',
+            'UNIQUE',
+            'UNISTR',
+            'UPDATE',
+            'UPDATEXML',
+            'UPPER',
+            'USE',
+            'USER',
+            'USERENV',
+            'USING',
+            'VALIDATE',
+            'VALUE',
+            'VALUES',
+            'VAR_POP',
+            'VAR_SAMP',
+            'VARCHAR',
+            'VARCHAR2',
+            'VARIANCE',
+            'VIEW',
+            'VSIZE',
+            'WHEN',
+            'WHENEVER',
+            'WHERE',
+            'WHILE',
+            'WIDTH_BUCKET',
+            'WITH',
+            'WORK',
+            'WRITE',
+            'XMLAGG',
+            'XMLCAST',
+            'XMLCDATA',
+            'XMLCOLATTVAL',
+            'XMLCOMMENT',
+            'XMLCONCAT',
+            'XMLDIFF',
+            'XMLELEMENT',
+            'XMLEXISTS',
+            'XMLFOREST',
+            'XMLPARSE',
+            'XMLPATCH',
+            'XMLPI',
+            'XMLQUERY',
+            'XMLROOT',
+            'XMLSEQUENCE',
+            'XMLSERIALIZE',
+            'XMLTABLE',
+            'XMLTRANSFORM',
+            'YEAR',
+            'ZONE'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '=', '<', '>', '|', '+', '-', '*', '/', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+//        3 => false,
+//        4 => false,
+//        5 => false,
+//        6 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #993333; font-weight: bold; text-transform: uppercase;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #ff0000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+//        3 => '',
+//        4 => '',
+//        5 => '',
+//        6 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/oracle8.php b/examples/includes/geshi/geshi/oracle8.php
new file mode 100644 (file)
index 0000000..d54b1e3
--- /dev/null
@@ -0,0 +1,496 @@
+<?php
+/*************************************************************************************
+ * oracle8.php
+ * -----------
+ * Author: Guy Wicks (Guy.Wicks@rbs.co.uk)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * Oracle 8 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/01/29 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Oracle 8 SQL',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array("'", '"', '`'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+//Put your package names here - e.g. select distinct ''''|| lower(name) || ''',' from user_source;
+//        6 => array(
+//            ),
+
+//Put your table names here - e.g. select distinct ''''|| lower(table_name) || ''',' from user_tables;
+//        5 => array(
+//            ),
+
+//Put your view names here - e.g. select distinct ''''|| lower(view_name) || ''',' from user_views;
+//        4 => array(
+//            ),
+
+//Put your table field names here - e.g. select distinct ''''|| lower(column_name) || ''',' from user_tab_columns;
+//        3 => array(
+//            ),
+
+//Put ORACLE reserved keywords here (8.1.7).  I like mine uppercase.
+        1 => array(
+            'ABS',
+            'ACCESS',
+            'ACOS',
+            'ADD',
+            'ADD_MONTHS',
+            'ALL',
+            'ALTER',
+            'ANALYZE',
+            'AND',
+            'ANY',
+            'ARRAY',
+            'AS',
+            'ASC',
+            'ASCII',
+            'ASIN',
+            'ASSOCIATE',
+            'AT',
+            'ATAN',
+            'ATAN2',
+            'AUDIT',
+            'AUTHID',
+            'AVG',
+            'BEGIN',
+            'BETWEEN',
+            'BFILENAME',
+            'BINARY_INTEGER',
+            'BITAND',
+            'BODY',
+            'BOOLEAN',
+            'BULK',
+            'BY',
+            'CALL',
+            'CASCADE',
+            'CASE',
+            'CEIL',
+            'CHAR',
+            'CHAR_BASE',
+            'CHARTOROWID',
+            'CHECK',
+            'CHR',
+            'CLOSE',
+            'CLUSTER',
+            'COALESCE',
+            'COLLECT',
+            'COLUMN',
+            'COMMENT',
+            'COMMIT',
+            'COMPRESS',
+            'CONCAT',
+            'CONNECT',
+            'CONSTANT',
+            'CONSTRAINT',
+            'CONSTRAINTS',
+            'CONTEXT',
+            'CONTROLFILE',
+            'CONVERT',
+            'CORR',
+            'COS',
+            'COSH',
+            'COST',
+            'COUNT',
+            'COVAR_POP',
+            'COVAR_SAMP',
+            'CREATE',
+            'CUME_DIST',
+            'CURRENT',
+            'CURRVAL',
+            'CURSOR',
+            'DATABASE',
+            'DATE',
+            'DAY',
+            'DECIMAL',
+            'DECLARE',
+            'DECODE',
+            'DEFAULT',
+            'DELETE',
+            'DENSE_RANK',
+            'DEREF',
+            'DESC',
+            'DIMENSION',
+            'DIRECTORY',
+            'DISASSOCIATE',
+            'DISTINCT',
+            'DO',
+            'DROP',
+            'DUMP',
+            'ELSE',
+            'ELSIF',
+            'EMPTY_BLOB',
+            'EMPTY_CLOB',
+            'END',
+            'EXCEPTION',
+            'EXCLUSIVE',
+            'EXEC',
+            'EXECUTE',
+            'EXISTS',
+            'EXIT',
+            'EXP',
+            'EXPLAIN',
+            'EXTENDS',
+            'EXTRACT',
+            'FALSE',
+            'FETCH',
+            'FILE',
+            'FIRST_VALUE',
+            'FLOAT',
+            'FLOOR',
+            'FOR',
+            'FORALL',
+            'FROM',
+            'FUNCTION',
+            'GOTO',
+            'GRANT',
+            'GREATEST',
+            'GROUP',
+            'GROUPING',
+            'HAVING',
+            'HEAP',
+            'HEXTORAW',
+            'HOUR',
+            'IDENTIFIED',
+            'IF',
+            'IMMEDIATE',
+            'IN',
+            'INCREMENT',
+            'INDEX',
+            'INDEXTYPE',
+            'INDICATOR',
+            'INITCAP',
+            'INITIAL',
+            'INSERT',
+            'INSTR',
+            'INSTRB',
+            'INTEGER',
+            'INTERFACE',
+            'INTERSECT',
+            'INTERVAL',
+            'INTO',
+            'IS',
+            'ISOLATION',
+            'JAVA',
+            'KEY',
+            'LAG',
+            'LAST_DAY',
+            'LAST_VALUE',
+            'LEAD',
+            'LEAST',
+            'LENGTH',
+            'LENGTHB',
+            'LEVEL',
+            'LIBRARY',
+            'LIKE',
+            'LIMITED',
+            'LINK',
+            'LN',
+            'LOCK',
+            'LOG',
+            'LONG',
+            'LOOP',
+            'LOWER',
+            'LPAD',
+            'LTRIM',
+            'MAKE_REF',
+            'MATERIALIZED',
+            'MAX',
+            'MAXEXTENTS',
+            'MIN',
+            'MINUS',
+            'MINUTE',
+            'MLSLABEL',
+            'MOD',
+            'MODE',
+            'MODIFY',
+            'MONTH',
+            'MONTHS_BETWEEN',
+            'NATURAL',
+            'NATURALN',
+            'NEW',
+            'NEW_TIME',
+            'NEXT_DAY',
+            'NEXTVAL',
+            'NLS_CHARSET_DECL_LEN',
+            'NLS_CHARSET_ID',
+            'NLS_CHARSET_NAME',
+            'NLS_INITCAP',
+            'NLS_LOWER',
+            'NLS_UPPER',
+            'NLSSORT',
+            'NOAUDIT',
+            'NOCOMPRESS',
+            'NOCOPY',
+            'NOT',
+            'NOWAIT',
+            'NTILE',
+            'NULL',
+            'NULLIF',
+            'NUMBER',
+            'NUMBER_BASE',
+            'NUMTODSINTERVAL',
+            'NUMTOYMINTERVAL',
+            'NVL',
+            'NVL2',
+            'OCIROWID',
+            'OF',
+            'OFFLINE',
+            'ON',
+            'ONLINE',
+            'OPAQUE',
+            'OPEN',
+            'OPERATOR',
+            'OPTION',
+            'OR',
+            'ORDER',
+            'ORGANIZATION',
+            'OTHERS',
+            'OUT',
+            'OUTLINE',
+            'PACKAGE',
+            'PARTITION',
+            'PCTFREE',
+            'PERCENT_RANK',
+            'PLAN',
+            'PLS_INTEGER',
+            'POSITIVE',
+            'POSITIVEN',
+            'POWER',
+            'PRAGMA',
+            'PRIMARY',
+            'PRIOR',
+            'PRIVATE',
+            'PRIVILEGES',
+            'PROCEDURE',
+            'PROFILE',
+            'PUBLIC',
+            'RAISE',
+            'RANGE',
+            'RANK',
+            'RATIO_TO_REPORT',
+            'RAW',
+            'RAWTOHEX',
+            'REAL',
+            'RECORD',
+            'REF',
+            'REFTOHEX',
+            'REGR_AVGX',
+            'REGR_AVGY',
+            'REGR_COUNT',
+            'REGR_INTERCEPT',
+            'REGR_R2',
+            'REGR_SLOPE',
+            'REGR_SXX',
+            'REGR_SXY',
+            'REGR_SYY',
+            'RELEASE',
+            'RENAME',
+            'REPLACE',
+            'RESOURCE',
+            'RETURN',
+            'RETURNING',
+            'REVERSE',
+            'REVOKE',
+            'ROLE',
+            'ROLLBACK',
+            'ROUND',
+            'ROW',
+            'ROW_NUMBER',
+            'ROWID',
+            'ROWIDTOCHAR',
+            'ROWNUM',
+            'ROWS',
+            'ROWTYPE',
+            'RPAD',
+            'RTRIM',
+            'SAVEPOINT',
+            'SCHEMA',
+            'SECOND',
+            'SEGMENT',
+            'SELECT',
+            'SEPERATE',
+            'SEQUENCE',
+            'SESSION',
+            'SET',
+            'SHARE',
+            'SIGN',
+            'SIN',
+            'SINH',
+            'SIZE',
+            'SMALLINT',
+            'SOUNDEX',
+            'SPACE',
+            'SQL',
+            'SQLCODE',
+            'SQLERRM',
+            'SQRT',
+            'START',
+            'STATISTICS',
+            'STDDEV',
+            'STDDEV_POP',
+            'STDDEV_SAMP',
+            'STOP',
+            'SUBSTR',
+            'SUBSTRB',
+            'SUBTYPE',
+            'SUCCESSFUL',
+            'SUM',
+            'SYNONYM',
+            'SYS_CONTEXT',
+            'SYS_GUID',
+            'SYSDATE',
+            'SYSTEM',
+            'TABLE',
+            'TABLESPACE',
+            'TAN',
+            'TANH',
+            'TEMPORARY',
+            'THEN',
+            'TIME',
+            'TIMESTAMP',
+            'TIMEZONE_ABBR',
+            'TIMEZONE_HOUR',
+            'TIMEZONE_MINUTE',
+            'TIMEZONE_REGION',
+            'TIMING',
+            'TO',
+            'TO_CHAR',
+            'TO_DATE',
+            'TO_LOB',
+            'TO_MULTI_BYTE',
+            'TO_NUMBER',
+            'TO_SINGLE_BYTE',
+            'TRANSACTION',
+            'TRANSLATE',
+            'TRIGGER',
+            'TRIM',
+            'TRUE',
+            'TRUNC',
+            'TRUNCATE',
+            'TYPE',
+            'UI',
+            'UID',
+            'UNION',
+            'UNIQUE',
+            'UPDATE',
+            'UPPER',
+            'USE',
+            'USER',
+            'USERENV',
+            'USING',
+            'VALIDATE',
+            'VALUE',
+            'VALUES',
+            'VAR_POP',
+            'VAR_SAMP',
+            'VARCHAR',
+            'VARCHAR2',
+            'VARIANCE',
+            'VIEW',
+            'VSIZE',
+            'WHEN',
+            'WHENEVER',
+            'WHERE',
+            'WHILE',
+            'WITH',
+            'WORK',
+            'WRITE',
+            'YEAR',
+            'ZONE'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '=', '<', '>', '|', '+', '-', '*', '/', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+//        3 => false,
+//        4 => false,
+//        5 => false,
+//        6 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #993333; font-weight: bold; text-transform: uppercase;'
+//Add the styles for groups 3-6 here when used
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #ff0000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+//        3 => '',
+//        4 => '',
+//        5 => '',
+//        6 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/pascal.php b/examples/includes/geshi/geshi/pascal.php
new file mode 100644 (file)
index 0000000..d2acd0f
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+/*************************************************************************************
+ * pascal.php
+ * ----------
+ * Author: Tux (tux@inamil.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/26
+ *
+ * Pascal language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.2)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.0)
+ *   -  Added support for symbols
+ * 2004/07/27 (0.9.1)
+ *   -  Pascal is OO language. Some new words.
+ * 2004/07/26 (0.9.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Pascal',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('{' => '}','(*' => '*)'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array("''"),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'absolute','asm','assembler','begin','break','case','catch','cdecl',
+            'const','constructor','default','destructor','div','do','downto',
+            'else','end','except','export','exports','external','far',
+            'finalization','finally','for','forward','function','goto','if',
+            'implementation','in','index','inherited','initialization','inline',
+            'interface','interrupt','label','library','mod','name','not','of',
+            'or','overload','override','private','procedure','program',
+            'property','protected','public','published','raise','repeat',
+            'resourcestring','shl','shr','stdcall','stored','switch','then',
+            'to','try','type','unit','until','uses','var','while','xor'
+            ),
+        2 => array(
+            'nil', 'false', 'true',
+            ),
+        3 => array(
+            'abs','and','arc','arctan','blockread','blockwrite','chr','dispose',
+            'cos','eof','eoln','exp','get','ln','new','odd','ord','ordinal',
+            'pred','read','readln','sin','sqrt','succ','write','writeln'
+            ),
+        4 => array(
+            'ansistring','array','boolean','byte','bytebool','char','file',
+            'integer','longbool','longint','object','packed','pointer','real',
+            'record','set','shortint','smallint','string','union','word'
+            ),
+        ),
+    'SYMBOLS' => array(
+        ',', ':', '=', '+', '-', '*', '/'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;',
+            4 => 'color: #000066; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;',
+            'HARD' => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0066ee;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/per.php b/examples/includes/geshi/geshi/per.php
new file mode 100644 (file)
index 0000000..092aae0
--- /dev/null
@@ -0,0 +1,302 @@
+<?php
+/*************************************************************************************
+ * per.php
+ * --------
+ * Author: Lars Gersmann (lars.gersmann@gmail.com)
+ * Copyright: (c) 2007 Lars Gersmann
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/06/03
+ *
+ * Per (forms) (FOURJ's Genero 4GL) language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'per',
+    'COMMENT_SINGLE' => array(1 => '--', 2 => '#'),
+    'COMMENT_MULTI' => array('{' => '}'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            "ACCELERATOR",
+            "ACCELERATOR2",
+            "ACTION",
+            "ALT",
+            "AND",
+            "AUTO",
+            "AUTONEXT",
+            "AUTOSCALE",
+            "BETWEEN",
+            "BOTH",
+            "BUTTON",
+            "BUTTONEDIT",
+            "BUTTONTEXTHIDDEN",
+            "BY",
+            "BYTE",
+            "CANVAS",
+            "CENTER",
+            "CHECKBOX",
+            "CLASS",
+            "COLOR",
+            "COLUMNS",
+            "COMBOBOX",
+            "COMMAND",
+            "COMMENT",
+            "COMMENTS",
+            "COMPACT",
+            "COMPRESS",
+            "CONFIG",
+            "CONTROL",
+            "CURRENT",
+            "DATABASE",
+            "DATEEDIT",
+            "DEC",
+            "DEFAULT",
+            "DEFAULTS",
+            "DELIMITERS",
+            "DISPLAY",
+            "DISPLAYONLY",
+            "DOWNSHIFT",
+            "DYNAMIC",
+            "EDIT",
+            "FIXED",
+            "FOLDER",
+            "FONTPITCH",
+            "FORMAT",
+            "FORMONLY",
+            "GRID",
+            "GRIDCHILDRENINPARENT",
+            "GROUP",
+            "HBOX",
+            "HEIGHT",
+            "HIDDEN",
+            "HORIZONTAL",
+            "INCLUDE",
+            "INITIAL",
+            "INITIALIZER",
+            "INPUT",
+            "INSTRUCTIONS",
+            "INTERVAL",
+            "INVISIBLE",
+            "IS",
+            "ITEM",
+            "ITEMS",
+            "JUSTIFY",
+            "KEY",
+            "KEYS",
+            "LABEL",
+            "LEFT",
+            "LIKE",
+            "LINES",
+            "MATCHES",
+            "NAME",
+            "NOENTRY",
+            "NONCOMPRESS",
+            "NORMAL",
+            "NOT",
+            "NOUPDATE",
+            "OPTIONS",
+            "OR",
+            "ORIENTATION",
+            "PACKED",
+            "PAGE",
+            "PICTURE",
+            "PIXELHEIGHT",
+            "PIXELS",
+            "PIXELWIDTH",
+            "POINTS",
+            "PROGRAM",
+            "PROGRESSBAR",
+            "QUERYCLEAR",
+            "QUERYEDITABLE",
+            "RADIOGROUP",
+            "RECORD",
+            "REQUIRED",
+            "REVERSE",
+            "RIGHT",
+            "SAMPLE",
+            "SCREEN",
+            "SCROLL",
+            "SCROLLBARS",
+            "SCROLLGRID",
+            "SECOND",
+            "SEPARATOR",
+            "SHIFT",
+            "SIZE",
+            "SIZEPOLICY",
+            "SMALLFLOAT",
+            "SMALLINT",
+            "SPACING",
+            "STRETCH",
+            "STYLE",
+            "TABINDEX",
+            "TABLE",
+            "TAG",
+            "TEXT",
+            "TEXTEDIT",
+            "THROUGH",
+            "THRU",
+            "TITLE",
+            "TO",
+            "TOOLBAR",
+            "TOPMENU",
+            "TYPE",
+            "UNHIDABLE",
+            "UNHIDABLECOLUMNS",
+            "UNMOVABLE",
+            "UNMOVABLECOLUMNS",
+            "UNSIZABLE",
+            "UNSIZABLECOLUMNS",
+            "UNSORTABLE",
+            "UNSORTABLECOLUMNS",
+            "UPSHIFT",
+            "USER",
+            "VALIDATE",
+            "VALUECHECKED",
+            "VALUEMAX",
+            "VALUEMIN",
+            "VALUEUNCHECKED",
+            "VARCHAR",
+            "VARIABLE",
+            "VBOX",
+            "VERIFY",
+            "VERSION",
+            "VERTICAL",
+            "TIMESTAMP",
+            "WANTCOLUMNSANCHORED", /* to be removed! */
+            "WANTFIXEDPAGESIZE",
+            "WANTNORETURNS",
+            "WANTTABS",
+            "WHERE",
+            "WIDGET",
+            "WIDTH",
+            "WINDOWSTYLE",
+            "WITHOUT",
+            "WORDWRAP",
+            "X",
+            "Y",
+            "ZEROFILL",
+            "SCHEMA",
+            "ATTRIBUTES",
+            "TABLES",
+            "LAYOUT",
+            "END"
+            ),
+        2 => array(
+            "YEAR",
+            "BLACK",
+            "BLINK",
+            "BLUE",
+            "YELLOW",
+            "WHITE",
+            "UNDERLINE",
+            "CENTURY",
+            "FRACTION",
+            "CHAR",
+            "CHARACTER",
+            "CHARACTERS",
+            "CYAN",
+            "DATE",
+            "DATETIME",
+            "DAY",
+            "DECIMAL",
+            "FALSE",
+            "FLOAT",
+            "GREEN",
+            "HOUR",
+            "INT",
+            "INTEGER",
+            "MAGENTA",
+            "MINUTE",
+            "MONEY",
+            "NONE",
+            "NULL",
+            "REAL",
+            "RED",
+            "TRUE",
+            "TODAY",
+            "MONTH",
+            "IMAGE"
+            ),
+        ),
+    'SYMBOLS' => array(
+        '+', '-', '*', '?', '=', '/', '%', '>', '<', '^', '!', '|', ':',
+        '(', ')', '[', ']'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0600FF;',
+            2 => 'color: #0000FF; font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008080; font-style: italic;',
+            2 => 'color: #008080;',
+            'MULTI' => 'color: green'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008080; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #808080;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000FF;',
+            2 => 'color: #0000FF;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/perl.php b/examples/includes/geshi/geshi/perl.php
new file mode 100644 (file)
index 0000000..f8ac096
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+/*************************************************************************************
+ * perl.php
+ * --------
+ * Author: Andreas Gohr (andi@splitbrain.org), Ben Keen (ben.keen@gmail.com)
+ * Copyright: (c) 2004 Andreas Gohr, Ben Keen (http://www.benjaminkeen.org/), Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/20
+ *
+ * Perl language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/22 (1.0.8)
+ *   -  Added support for system calls in backticks (Corley Kinnane)
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ *   -  Added comment_regexp for predefined variables
+ * 2008/02/15 (1.003)
+ *   -  Fixed SF#1891630 with placebo patch
+ * 2006/01/05 (1.0.2)
+ *   -  Used hardescape feature for ' strings (Cliff Stanford)
+ * 2004/11/27 (1.0.1)
+ *   -  Added support for multiple object splitters
+ * 2004/08/20 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * LABEL:
+ * * string comparison operators
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Perl',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(
+        '=back' => '=cut',
+        '=head' => '=cut',
+        '=item' => '=cut',
+        '=over' => '=cut',
+        '=begin' => '=cut',
+        '=end' => '=cut',
+        '=for' => '=cut',
+        '=encoding' => '=cut',
+        '=pod' => '=cut'
+        ),
+    'COMMENT_REGEXP' => array(
+        //Regular expressions
+        2 => "/(?<=[\\s^])(s|tr|y)\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])*\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU",
+        //Regular expression match variables
+        3 => '/\$\d+/',
+        //Heredoc
+        4 => '/<<\s*?([\'"]?)([a-zA-Z0-9]+)\1;[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+        //Predefined variables
+        5 => '/\$(\^[a-zA-Z]?|[\*\$`\'&_\.,+\-~:;\\\\\/"\|%=\?!@#<>\(\)\[\]])(?!\w)|@[_+\-]|%[!]|\$(?=\{)/',
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"','`'),
+    'HARDQUOTE' => array("'", "'"),            // An optional 2-element array defining the beginning and end of a hard-quoted string
+    'HARDESCAPE' => array('\\\'',),
+        // Things that must still be escaped inside a hard-quoted string
+        // If HARDQUOTE is defined, HARDESCAPE must be defined
+        // This will not work unless the first character of each element is either in the
+        // QUOTEMARKS array or is the ESCAPE_CHAR
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'case', 'do', 'else', 'elsif', 'for', 'if', 'then', 'until', 'while', 'foreach', 'my',
+            'xor', 'or', 'and', 'unless', 'next', 'last', 'redo', 'not', 'our',
+            'reset', 'continue', 'cmp', 'ne', 'eq', 'lt', 'gt', 'le', 'ge',
+            ),
+        2 => array(
+            'use', 'sub', 'new', '__END__', '__DATA__', '__DIE__', '__WARN__', 'BEGIN',
+            'STDIN', 'STDOUT', 'STDERR', 'ARGV', 'ARGVOUT'
+            ),
+        3 => array(
+            'abs', 'accept', 'alarm', 'atan2', 'bind', 'binmode', 'bless',
+            'caller', 'chdir', 'chmod', 'chomp', 'chop', 'chown', 'chr',
+            'chroot', 'close', 'closedir', 'connect', 'cos',
+            'crypt', 'dbmclose', 'dbmopen', 'defined', 'delete', 'die',
+            'dump', 'each', 'endgrent', 'endhostent', 'endnetent', 'endprotoent',
+            'endpwent', 'endservent', 'eof', 'eval', 'exec', 'exists', 'exit',
+            'exp', 'fcntl', 'fileno', 'flock', 'fork', 'format', 'formline',
+            'getc', 'getgrent', 'getgrgid', 'getgrnam', 'gethostbyaddr',
+            'gethostbyname', 'gethostent', 'getlogin', 'getnetbyaddr', 'getnetbyname',
+            'getnetent', 'getpeername', 'getpgrp', 'getppid', 'getpriority',
+            'getprotobyname', 'getprotobynumber', 'getprotoent', 'getpwent',
+            'getpwnam', 'getpwuid', 'getservbyname', 'getservbyport', 'getservent',
+            'getsockname', 'getsockopt', 'glob', 'gmtime', 'goto', 'grep',
+            'hex', 'import', 'index', 'int', 'ioctl', 'join', 'keys', 'kill',
+            'lc', 'lcfirst', 'length', 'link', 'listen', 'local',
+            'localtime', 'log', 'lstat', 'm', 'map', 'mkdir', 'msgctl', 'msgget',
+            'msgrcv', 'msgsnd', 'no', 'oct', 'open', 'opendir',
+            'ord', 'pack', 'package', 'pipe', 'pop', 'pos', 'print',
+            'printf', 'prototype', 'push', 'qq', 'qr', 'quotemeta', 'qw',
+            'qx', 'q', 'rand', 'read', 'readdir', 'readline', 'readlink', 'readpipe',
+            'recv', 'ref', 'rename', 'require', 'return',
+            'reverse', 'rewinddir', 'rindex', 'rmdir', 's', 'scalar', 'seek',
+            'seekdir', 'select', 'semctl', 'semget', 'semop', 'send', 'setgrent',
+            'sethostent', 'setnetent', 'setpgrp', 'setpriority', 'setprotoent',
+            'setpwent', 'setservent', 'setsockopt', 'shift', 'shmctl', 'shmget',
+            'shmread', 'shmwrite', 'shutdown', 'sin', 'sleep', 'socket', 'socketpair',
+            'sort', 'splice', 'split', 'sprintf', 'sqrt', 'srand', 'stat',
+            'study', 'substr', 'symlink', 'syscall', 'sysopen', 'sysread',
+            'sysseek', 'system', 'syswrite', 'tell', 'telldir', 'tie', 'tied',
+            'time', 'times', 'tr', 'truncate', 'uc', 'ucfirst', 'umask', 'undef',
+            'unlink', 'unpack', 'unshift', 'untie', 'utime', 'values',
+            'vec', 'wait', 'waitpid', 'wantarray', 'warn', 'write', 'y'
+            )
+        ),
+    'SYMBOLS' => array(
+        '<', '>', '=',
+        '!', '@', '~', '&', '|', '^',
+        '+','-', '*', '/', '%',
+        ',', ';', '?', '.', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #009966; font-style: italic;',
+            3 => 'color: #0000ff;',
+            4 => 'color: #cc0000; font-style: italic;',
+            5 => 'color: #0000ff;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;',
+            'HARD' => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;',
+            4 => 'color: #009999;',
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://perldoc.perl.org/functions/{FNAMEL}.html'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '-&gt;',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        //Variable
+        0 => '(?:\$[\$#]?|\\\\(?:[@%*]?|\\\\*\$|&amp;)|%[$]?|@[$]?|\*[$]?|&amp;[$]?)[a-zA-Z_][a-zA-Z0-9_]*',
+        //File Descriptor
+        4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'COMMENTS' => array(
+            'DISALLOWED_BEFORE' => '$'
+        )
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/php-brief.php b/examples/includes/geshi/geshi/php-brief.php
new file mode 100644 (file)
index 0000000..dd6781d
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+/*************************************************************************************
+ * php-brief.php
+ * -------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/02
+ *
+ * PHP (brief version) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.3)
+ *  -  Added support for multiple object splitters
+ *  -  Fixed &new problem
+ * 2004/10/27 (1.0.2)
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.1)
+ *   -  Added support for symbols
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Remove more functions that are hardly used
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'PHP (brief)',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    //Heredoc and Nowdoc syntax
+    'COMMENT_REGEXP' => array(3 => '/<<<\s*?(\'?)([a-zA-Z0-9]+)\1[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array("\'"),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC |  GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX |
+        GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'include', 'require', 'include_once', 'require_once',
+            'for', 'as', 'foreach', 'if', 'elseif', 'else', 'while', 'do', 'endwhile', 'endif', 'switch', 'case', 'endswitch',
+            'return', 'break'
+            ),
+        2 => array(
+            'null', '__LINE__', '__FILE__',
+            'false', '&lt;?php',
+            'true', 'var', 'default',
+            'function', 'class', 'new', '&amp;new', 'public', 'private', 'interface', 'extends',
+            'const', 'self'
+            ),
+        3 => array(
+            'func_num_args', 'func_get_arg', 'func_get_args', 'strlen', 'strcmp', 'strncmp', 'strcasecmp', 'strncasecmp', 'each', 'error_reporting', 'define', 'defined',
+            'trigger_error', 'user_error', 'set_error_handler', 'restore_error_handler', 'get_declared_classes', 'get_loaded_extensions',
+            'extension_loaded', 'get_extension_funcs', 'debug_backtrace',
+            'constant', 'bin2hex', 'sleep', 'usleep', 'time', 'mktime', 'gmmktime', 'strftime', 'gmstrftime', 'strtotime', 'date', 'gmdate', 'getdate', 'localtime', 'checkdate', 'flush', 'wordwrap', 'htmlspecialchars', 'htmlentities', 'html_entity_decode', 'md5', 'md5_file', 'crc32', 'getimagesize', 'image_type_to_mime_type', 'phpinfo', 'phpversion', 'phpcredits', 'strnatcmp', 'strnatcasecmp', 'substr_count', 'strspn', 'strcspn', 'strtok', 'strtoupper', 'strtolower', 'strpos', 'strrpos', 'strrev', 'hebrev', 'hebrevc', 'nl2br', 'basename', 'dirname', 'pathinfo', 'stripslashes', 'stripcslashes', 'strstr', 'stristr', 'strrchr', 'str_shuffle', 'str_word_count', 'strcoll', 'substr', 'substr_replace', 'quotemeta', 'ucfirst', 'ucwords', 'strtr', 'addslashes', 'addcslashes', 'rtrim', 'str_replace', 'str_repeat', 'count_chars', 'chunk_split', 'trim', 'ltrim', 'strip_tags', 'similar_text', 'explode', 'implode', 'setlocale', 'localeconv',
+            'parse_str', 'str_pad', 'chop', 'strchr', 'sprintf', 'printf', 'vprintf', 'vsprintf', 'sscanf', 'fscanf', 'parse_url', 'urlencode', 'urldecode', 'rawurlencode', 'rawurldecode', 'readlink', 'linkinfo', 'link', 'unlink', 'exec', 'system', 'escapeshellcmd', 'escapeshellarg', 'passthru', 'shell_exec', 'proc_open', 'proc_close', 'rand', 'srand', 'getrandmax', 'mt_rand', 'mt_srand', 'mt_getrandmax', 'base64_decode', 'base64_encode', 'abs', 'ceil', 'floor', 'round', 'is_finite', 'is_nan', 'is_infinite', 'bindec', 'hexdec', 'octdec', 'decbin', 'decoct', 'dechex', 'base_convert', 'number_format', 'fmod', 'ip2long', 'long2ip', 'getenv', 'putenv', 'getopt', 'microtime', 'gettimeofday', 'getrusage', 'uniqid', 'quoted_printable_decode', 'set_time_limit', 'get_cfg_var', 'magic_quotes_runtime', 'set_magic_quotes_runtime', 'get_magic_quotes_gpc', 'get_magic_quotes_runtime',
+            'import_request_variables', 'error_log', 'serialize', 'unserialize', 'memory_get_usage', 'var_dump', 'var_export', 'debug_zval_dump', 'print_r','highlight_file', 'show_source', 'highlight_string', 'ini_get', 'ini_get_all', 'ini_set', 'ini_alter', 'ini_restore', 'get_include_path', 'set_include_path', 'restore_include_path', 'setcookie', 'header', 'headers_sent', 'connection_aborted', 'connection_status', 'ignore_user_abort', 'parse_ini_file', 'is_uploaded_file', 'move_uploaded_file', 'intval', 'floatval', 'doubleval', 'strval', 'gettype', 'settype', 'is_null', 'is_resource', 'is_bool', 'is_long', 'is_float', 'is_int', 'is_integer', 'is_double', 'is_real', 'is_numeric', 'is_string', 'is_array', 'is_object', 'is_scalar',
+            'ereg', 'ereg_replace', 'eregi', 'eregi_replace', 'split', 'spliti', 'join', 'sql_regcase', 'dl', 'pclose', 'popen', 'readfile', 'rewind', 'rmdir', 'umask', 'fclose', 'feof', 'fgetc', 'fgets', 'fgetss', 'fread', 'fopen', 'fpassthru', 'ftruncate', 'fstat', 'fseek', 'ftell', 'fflush', 'fwrite', 'fputs', 'mkdir', 'rename', 'copy', 'tempnam', 'tmpfile', 'file', 'file_get_contents', 'stream_select', 'stream_context_create', 'stream_context_set_params', 'stream_context_set_option', 'stream_context_get_options', 'stream_filter_prepend', 'stream_filter_append', 'fgetcsv', 'flock', 'get_meta_tags', 'stream_set_write_buffer', 'set_file_buffer', 'set_socket_blocking', 'stream_set_blocking', 'socket_set_blocking', 'stream_get_meta_data', 'stream_register_wrapper', 'stream_wrapper_register', 'stream_set_timeout', 'socket_set_timeout', 'socket_get_status', 'realpath', 'fnmatch', 'fsockopen', 'pfsockopen', 'pack', 'unpack', 'get_browser', 'crypt', 'opendir', 'closedir', 'chdir', 'getcwd', 'rewinddir', 'readdir', 'dir', 'glob', 'fileatime', 'filectime', 'filegroup', 'fileinode', 'filemtime', 'fileowner', 'fileperms', 'filesize', 'filetype', 'file_exists', 'is_writable', 'is_writeable', 'is_readable', 'is_executable', 'is_file', 'is_dir', 'is_link', 'stat', 'lstat', 'chown',
+            'touch', 'clearstatcache', 'mail', 'ob_start', 'ob_flush', 'ob_clean', 'ob_end_flush', 'ob_end_clean', 'ob_get_flush', 'ob_get_clean', 'ob_get_length', 'ob_get_level', 'ob_get_status', 'ob_get_contents', 'ob_implicit_flush', 'ob_list_handlers', 'ksort', 'krsort', 'natsort', 'natcasesort', 'asort', 'arsort', 'sort', 'rsort', 'usort', 'uasort', 'uksort', 'shuffle', 'array_walk', 'count', 'end', 'prev', 'next', 'reset', 'current', 'key', 'min', 'max', 'in_array', 'array_search', 'extract', 'compact', 'array_fill', 'range', 'array_multisort', 'array_push', 'array_pop', 'array_shift', 'array_unshift', 'array_splice', 'array_slice', 'array_merge', 'array_merge_recursive', 'array_keys', 'array_values', 'array_count_values', 'array_reverse', 'array_reduce', 'array_pad', 'array_flip', 'array_change_key_case', 'array_rand', 'array_unique', 'array_intersect', 'array_intersect_assoc', 'array_diff', 'array_diff_assoc', 'array_sum', 'array_filter', 'array_map', 'array_chunk', 'array_key_exists', 'pos', 'sizeof', 'key_exists', 'assert', 'assert_options', 'version_compare', 'ftok', 'str_rot13', 'aggregate',
+            'session_name', 'session_module_name', 'session_save_path', 'session_id', 'session_regenerate_id', 'session_decode', 'session_register', 'session_unregister', 'session_is_registered', 'session_encode',
+            'session_start', 'session_destroy', 'session_unset', 'session_set_save_handler', 'session_cache_limiter', 'session_cache_expire', 'session_set_cookie_params', 'session_get_cookie_params', 'session_write_close', 'preg_match', 'preg_match_all', 'preg_replace', 'preg_replace_callback', 'preg_split', 'preg_quote', 'preg_grep', 'overload', 'ctype_alnum', 'ctype_alpha', 'ctype_cntrl', 'ctype_digit', 'ctype_lower', 'ctype_graph', 'ctype_print', 'ctype_punct', 'ctype_space', 'ctype_upper', 'ctype_xdigit', 'virtual', 'apache_request_headers', 'apache_note', 'apache_lookup_uri', 'apache_child_terminate', 'apache_setenv', 'apache_response_headers', 'apache_get_version', 'getallheaders', 'mysql_connect', 'mysql_pconnect', 'mysql_close', 'mysql_select_db', 'mysql_create_db', 'mysql_drop_db', 'mysql_query', 'mysql_unbuffered_query', 'mysql_db_query', 'mysql_list_dbs', 'mysql_list_tables', 'mysql_list_fields', 'mysql_list_processes', 'mysql_error', 'mysql_errno', 'mysql_affected_rows', 'mysql_insert_id', 'mysql_result', 'mysql_num_rows', 'mysql_num_fields', 'mysql_fetch_row', 'mysql_fetch_array', 'mysql_fetch_assoc', 'mysql_fetch_object', 'mysql_data_seek', 'mysql_fetch_lengths', 'mysql_fetch_field', 'mysql_field_seek', 'mysql_free_result', 'mysql_field_name', 'mysql_field_table', 'mysql_field_len', 'mysql_field_type', 'mysql_field_flags', 'mysql_escape_string', 'mysql_real_escape_string', 'mysql_stat',
+            'mysql_thread_id', 'mysql_client_encoding', 'mysql_get_client_info', 'mysql_get_host_info', 'mysql_get_proto_info', 'mysql_get_server_info', 'mysql_info', 'mysql', 'mysql_fieldname', 'mysql_fieldtable', 'mysql_fieldlen', 'mysql_fieldtype', 'mysql_fieldflags', 'mysql_selectdb', 'mysql_createdb', 'mysql_dropdb', 'mysql_freeresult', 'mysql_numfields', 'mysql_numrows', 'mysql_listdbs', 'mysql_listtables', 'mysql_listfields', 'mysql_db_name', 'mysql_dbname', 'mysql_tablename', 'mysql_table_name', 'pg_connect', 'pg_pconnect', 'pg_close', 'pg_connection_status', 'pg_connection_busy', 'pg_connection_reset', 'pg_host', 'pg_dbname', 'pg_port', 'pg_tty', 'pg_options', 'pg_ping', 'pg_query', 'pg_send_query', 'pg_cancel_query', 'pg_fetch_result', 'pg_fetch_row', 'pg_fetch_assoc', 'pg_fetch_array', 'pg_fetch_object', 'pg_fetch_all', 'pg_affected_rows', 'pg_get_result', 'pg_result_seek', 'pg_result_status', 'pg_free_result', 'pg_last_oid', 'pg_num_rows', 'pg_num_fields', 'pg_field_name', 'pg_field_num', 'pg_field_size', 'pg_field_type', 'pg_field_prtlen', 'pg_field_is_null', 'pg_get_notify', 'pg_get_pid', 'pg_result_error', 'pg_last_error', 'pg_last_notice', 'pg_put_line', 'pg_end_copy', 'pg_copy_to', 'pg_copy_from',
+            'pg_trace', 'pg_untrace', 'pg_lo_create', 'pg_lo_unlink', 'pg_lo_open', 'pg_lo_close', 'pg_lo_read', 'pg_lo_write', 'pg_lo_read_all', 'pg_lo_import', 'pg_lo_export', 'pg_lo_seek', 'pg_lo_tell', 'pg_escape_string', 'pg_escape_bytea', 'pg_unescape_bytea', 'pg_client_encoding', 'pg_set_client_encoding', 'pg_meta_data', 'pg_convert', 'pg_insert', 'pg_update', 'pg_delete', 'pg_select', 'pg_exec', 'pg_getlastoid', 'pg_cmdtuples', 'pg_errormessage', 'pg_numrows', 'pg_numfields', 'pg_fieldname', 'pg_fieldsize', 'pg_fieldtype', 'pg_fieldnum', 'pg_fieldprtlen', 'pg_fieldisnull', 'pg_freeresult', 'pg_result', 'pg_loreadall', 'pg_locreate', 'pg_lounlink', 'pg_loopen', 'pg_loclose', 'pg_loread', 'pg_lowrite', 'pg_loimport', 'pg_loexport',
+            'echo', 'print', 'global', 'static', 'exit', 'array', 'empty', 'eval', 'isset', 'unset', 'die'
+            )
+        ),
+    'SYMBOLS' => array(
+        1 => array(
+            '<%', '<%=', '%>', '<?', '<?=', '?>'
+            ),
+        0 => array(
+            '(', ')', '[', ']', '{', '}',
+            '!', '@', '%', '&', '|', '/',
+            '<', '>',
+            '=', '-', '+', '*',
+            '.', ':', ',', ';'
+            )
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #990000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #666666; font-style: italic;',
+            3 => 'color: #0000cc; font-style: italic;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;',
+            'HARD' => 'color: #0000ff;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            ),
+        'METHODS' => array(
+            1 => 'color: #004000;',
+            2 => 'color: #004000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;',
+            1 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => '',
+            4 => '',
+            5 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.php.net/{FNAMEL}'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '-&gt;',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        //Variables
+        0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<?php' => '?>'
+            ),
+        1 => array(
+            '<?' => '?>'
+            ),
+        2 => array(
+            '<%' => '%>'
+            ),
+        3 => array(
+            '<script language="php">' => '</script>'
+            ),
+        4 => "/(<\?(?:php)?)(?:'(?:[^'\\\\]|\\\\.)*?'|\"(?:[^\"\\\\]|\\\\.)*?\"|\/\*(?!\*\/).*?\*\/|.)*?(\?>|\Z)/sm",
+        5 => "/(<%)(?:'(?:[^'\\\\]|\\\\.)*?'|\"(?:[^\"\\\\]|\\\\.)*?\"|\/\*(?!\*\/).*?\*\/|.)*?(%>|\Z)/sm"
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/php.php b/examples/includes/geshi/geshi/php.php
new file mode 100644 (file)
index 0000000..fc6be6c
--- /dev/null
@@ -0,0 +1,1094 @@
+<?php
+/*************************************************************************************
+ * php.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/20
+ *
+ * PHP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/11/25 (1.0.3)
+ *  -  Added support for multiple object splitters
+ *  -  Fixed &new problem
+ * 2004/10/27 (1.0.2)
+ *  -  Added URL support
+ *  -  Added extra constants
+ * 2004/08/05 (1.0.1)
+ *  -  Added support for symbols
+ * 2004/07/14 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Make sure the last few function I may have missed
+ *   (like eval()) are included for highlighting
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+    'LANG_NAME' => 'PHP',
+    'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array("'", "\\"),
+    'HARDCHAR' => "\\",
+    'COMMENT_REGEXP' => array(
+        //Heredoc and Nowdoc syntax
+        3 => '/<<<\s*?(\'?)([a-zA-Z0-9]+?)\1[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+        // phpdoc comments
+        4 => '#/\*\*(?![\*\/]).*\*/#sU',
+        // Advanced # handling
+        2 => "/#.*?(?:(?=\?\>)|^)/smi"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'ESCAPE_REGEXP' => array(
+        //Simple Single Char Escapes
+        1 => "#\\\\[nfrtv\$\"\n\\\\]#i",
+        //Hexadecimal Char Specs
+        2 => "#\\\\x[\da-fA-F]{1,2}#i",
+        //Octal Char Specs
+        3 => "#\\\\[0-7]{1,3}#",
+        //String Parsing of Variable Names
+        4 => "#\\$[a-z0-9_]+(?:\\[[a-z0-9_]+\\]|->[a-z0-9_]+)?|(?:\\{\\$|\\$\\{)[a-z0-9_]+(?:\\[('?)[a-z0-9_]*\\1\\]|->[a-z0-9_]+)*\\}#i",
+        //Experimental extension supporting cascaded {${$var}} syntax
+        5 => "#\$[a-z0-9_]+(?:\[[a-z0-9_]+\]|->[a-z0-9_]+)?|(?:\{\$|\$\{)[a-z0-9_]+(?:\[('?)[a-z0-9_]*\\1\]|->[a-z0-9_]+)*\}|\{\$(?R)\}#i",
+        //Format String support in ""-Strings
+        6 => "#%(?:%|(?:\d+\\\\\\\$)?\\+?(?:\x20|0|'.)?-?(?:\d+|\\*)?(?:\.\d+)?[bcdefFosuxX])#"
+        ),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC |  GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX |
+        GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'as','break','case','continue','default','do','else','elseif',
+            'endfor','endforeach','endif','endswitch','endwhile','for',
+            'foreach','if','include','include_once','require','require_once',
+            'return','switch','while',
+
+            'echo','print'
+            ),
+        2 => array(
+            '&amp;new','&lt;/script&gt;','&lt;?php','&lt;script language',
+            'class','const','declare','extends','function','global','interface',
+            'namespace','new','private','public','self','var'
+            ),
+        3 => array(
+            'abs','acos','acosh','addcslashes','addslashes','aggregate',
+            'aggregate_methods','aggregate_methods_by_list',
+            'aggregate_methods_by_regexp','aggregate_properties',
+            'aggregate_properties_by_list','aggregate_properties_by_regexp',
+            'aggregation_info','apache_child_terminate','apache_get_modules',
+            'apache_get_version','apache_getenv','apache_lookup_uri',
+            'apache_note','apache_request_headers','apache_response_headers',
+            'apache_setenv','array','array_change_key_case','array_chunk',
+            'array_combine','array_count_values','array_diff',
+            'array_diff_assoc','array_diff_key','array_diff_uassoc',
+            'array_diff_ukey','array_fill','array_fill_keys','array_filter',
+            'array_flip','array_intersect','array_intersect_assoc',
+            'array_intersect_key','array_intersect_uassoc',
+            'array_intersect_ukey','array_key_exists','array_keys','array_map',
+            'array_merge','array_merge_recursive','array_multisort','array_pad',
+            'array_pop','array_product','array_push','array_rand',
+            'array_reduce','array_reverse','array_search','array_shift',
+            'array_slice','array_splice','array_sum','array_udiff',
+            'array_udiff_assoc','array_udiff_uassoc','array_uintersect',
+            'array_uintersect_assoc','array_uintersect_uassoc','array_unique',
+            'array_unshift','array_values','array_walk','array_walk_recursive',
+            'arsort','asin','asinh','asort','assert','assert_options','atan',
+            'atan2','atanh','base_convert','base64_decode','base64_encode',
+            'basename','bcadd','bccomp','bcdiv','bcmod','bcmul',
+            'bcompiler_load','bcompiler_load_exe','bcompiler_parse_class',
+            'bcompiler_read','bcompiler_write_class','bcompiler_write_constant',
+            'bcompiler_write_exe_footer','bcompiler_write_file',
+            'bcompiler_write_footer','bcompiler_write_function',
+            'bcompiler_write_functions_from_file','bcompiler_write_header',
+            'bcompiler_write_included_filename','bcpow','bcpowmod','bcscale',
+            'bcsqrt','bcsub','bin2hex','bindec','bindtextdomain',
+            'bind_textdomain_codeset','bitset_empty','bitset_equal',
+            'bitset_excl','bitset_fill','bitset_from_array','bitset_from_hash',
+            'bitset_from_string','bitset_in','bitset_incl',
+            'bitset_intersection','bitset_invert','bitset_is_empty',
+            'bitset_subset','bitset_to_array','bitset_to_hash',
+            'bitset_to_string','bitset_union','blenc_encrypt','bzclose',
+            'bzcompress','bzdecompress','bzerrno','bzerror','bzerrstr',
+            'bzflush','bzopen','bzread','bzwrite','cal_days_in_month',
+            'cal_from_jd','cal_info','cal_to_jd','call_user_func',
+            'call_user_func_array','call_user_method','call_user_method_array',
+            'ceil','chdir','checkdate','checkdnsrr','chgrp','chmod','chop',
+            'chown','chr','chunk_split','class_exists','class_implements',
+            'class_parents','classkit_aggregate_methods',
+            'classkit_doc_comments','classkit_import','classkit_method_add',
+            'classkit_method_copy','classkit_method_redefine',
+            'classkit_method_remove','classkit_method_rename','clearstatcache',
+            'closedir','closelog','com_create_guid','com_event_sink',
+            'com_get_active_object','com_load_typelib','com_message_pump',
+            'com_print_typeinfo','compact','confirm_phpdoc_compiled',
+            'connection_aborted','connection_status','constant',
+            'convert_cyr_string','convert_uudecode','convert_uuencode','copy',
+            'cos','cosh','count','count_chars','cpdf_add_annotation',
+            'cpdf_add_outline','cpdf_arc','cpdf_begin_text','cpdf_circle',
+            'cpdf_clip','cpdf_close','cpdf_closepath',
+            'cpdf_closepath_fill_stroke','cpdf_closepath_stroke',
+            'cpdf_continue_text','cpdf_curveto','cpdf_end_text','cpdf_fill',
+            'cpdf_fill_stroke','cpdf_finalize','cpdf_finalize_page',
+            'cpdf_global_set_document_limits','cpdf_import_jpeg','cpdf_lineto',
+            'cpdf_moveto','cpdf_newpath','cpdf_open','cpdf_output_buffer',
+            'cpdf_page_init','cpdf_rect','cpdf_restore','cpdf_rlineto',
+            'cpdf_rmoveto','cpdf_rotate','cpdf_rotate_text','cpdf_save',
+            'cpdf_save_to_file','cpdf_scale','cpdf_set_action_url',
+            'cpdf_set_char_spacing','cpdf_set_creator','cpdf_set_current_page',
+            'cpdf_set_font','cpdf_set_font_directories',
+            'cpdf_set_font_map_file','cpdf_set_horiz_scaling',
+            'cpdf_set_keywords','cpdf_set_leading','cpdf_set_page_animation',
+            'cpdf_set_subject','cpdf_set_text_matrix','cpdf_set_text_pos',
+            'cpdf_set_text_rendering','cpdf_set_text_rise','cpdf_set_title',
+            'cpdf_set_viewer_preferences','cpdf_set_word_spacing',
+            'cpdf_setdash','cpdf_setflat','cpdf_setgray','cpdf_setgray_fill',
+            'cpdf_setgray_stroke','cpdf_setlinecap','cpdf_setlinejoin',
+            'cpdf_setlinewidth','cpdf_setmiterlimit','cpdf_setrgbcolor',
+            'cpdf_setrgbcolor_fill','cpdf_setrgbcolor_stroke','cpdf_show',
+            'cpdf_show_xy','cpdf_stringwidth','cpdf_stroke','cpdf_text',
+            'cpdf_translate','crack_check','crack_closedict',
+            'crack_getlastmessage','crack_opendict','crc32','create_function',
+            'crypt','ctype_alnum','ctype_alpha','ctype_cntrl','ctype_digit',
+            'ctype_graph','ctype_lower','ctype_print','ctype_punct',
+            'ctype_space','ctype_upper','ctype_xdigit','curl_close',
+            'curl_copy_handle','curl_errno','curl_error','curl_exec',
+            'curl_getinfo','curl_init','curl_multi_add_handle',
+            'curl_multi_close','curl_multi_exec','curl_multi_getcontent',
+            'curl_multi_info_read','curl_multi_init','curl_multi_remove_handle',
+            'curl_multi_select','curl_setopt','curl_setopt_array',
+            'curl_version','current','cvsclient_connect','cvsclient_log',
+            'cvsclient_login','cvsclient_retrieve','date','date_create',
+            'date_date_set','date_default_timezone_get',
+            'date_default_timezone_set','date_format','date_isodate_set',
+            'date_modify','date_offset_get','date_parse','date_sun_info',
+            'date_sunrise','date_sunset','date_time_set','date_timezone_get',
+            'date_timezone_set','db_id_list','dba_close','dba_delete',
+            'dba_exists','dba_fetch','dba_firstkey','dba_handlers','dba_insert',
+            'dba_key_split','dba_list','dba_nextkey','dba_open','dba_optimize',
+            'dba_popen','dba_replace','dba_sync','dbase_add_record',
+            'dbase_close','dbase_create','dbase_delete_record',
+            'dbase_get_header_info','dbase_get_record',
+            'dbase_get_record_with_names','dbase_numfields','dbase_numrecords',
+            'dbase_open','dbase_pack','dbase_replace_record',
+            'dbg_get_all_contexts','dbg_get_all_module_names',
+            'dbg_get_all_source_lines','dbg_get_context_name',
+            'dbg_get_module_name','dbg_get_profiler_results',
+            'dbg_get_source_context','dblist','dbmclose','dbmdelete',
+            'dbmexists','dbmfetch','dbmfirstkey','dbminsert','dbmnextkey',
+            'dbmopen','dbmreplace','dbx_close','dbx_compare','dbx_connect',
+            'dbx_error','dbx_escape_string','dbx_fetch_row','dbx_query',
+            'dbx_sort','dcgettext','dcngettext','deaggregate','debug_backtrace',
+            'debug_zval_dump','debugbreak','decbin','dechex','decoct','define',
+            'defined','define_syslog_variables','deg2rad','dgettext','die',
+            'dio_close','dio_open','dio_read','dio_seek','dio_stat','dio_write',
+            'dir','dirname','disk_free_space','disk_total_space',
+            'diskfreespace','dl','dngettext','docblock_token_name',
+            'docblock_tokenize','dom_import_simplexml','domxml_add_root',
+            'domxml_attributes','domxml_children','domxml_doc_add_root',
+            'domxml_doc_document_element','domxml_doc_get_element_by_id',
+            'domxml_doc_get_elements_by_tagname','domxml_doc_get_root',
+            'domxml_doc_set_root','domxml_doc_validate','domxml_doc_xinclude',
+            'domxml_dump_mem','domxml_dump_mem_file','domxml_dump_node',
+            'domxml_dumpmem','domxml_elem_get_attribute',
+            'domxml_elem_set_attribute','domxml_get_attribute','domxml_getattr',
+            'domxml_html_dump_mem','domxml_new_child','domxml_new_doc',
+            'domxml_new_xmldoc','domxml_node','domxml_node_add_namespace',
+            'domxml_node_attributes','domxml_node_children',
+            'domxml_node_get_content','domxml_node_has_attributes',
+            'domxml_node_new_child','domxml_node_set_content',
+            'domxml_node_set_namespace','domxml_node_unlink_node',
+            'domxml_open_file','domxml_open_mem','domxml_parser',
+            'domxml_parser_add_chunk','domxml_parser_cdata_section',
+            'domxml_parser_characters','domxml_parser_comment',
+            'domxml_parser_end','domxml_parser_end_document',
+            'domxml_parser_end_element','domxml_parser_entity_reference',
+            'domxml_parser_get_document','domxml_parser_namespace_decl',
+            'domxml_parser_processing_instruction',
+            'domxml_parser_start_document','domxml_parser_start_element',
+            'domxml_root','domxml_set_attribute','domxml_setattr',
+            'domxml_substitute_entities_default','domxml_unlink_node',
+            'domxml_version','domxml_xmltree','doubleval','each','easter_date',
+            'easter_days','empty','end','ereg','ereg_replace','eregi',
+            'eregi_replace','error_get_last','error_log','error_reporting',
+            'escapeshellarg','escapeshellcmd','eval','event_deschedule',
+            'event_dispatch','event_free','event_handle_signal',
+            'event_have_events','event_init','event_new','event_pending',
+            'event_priority_set','event_schedule','event_set','event_timeout',
+            'exec','exif_imagetype','exif_read_data','exif_tagname',
+            'exif_thumbnail','exit','exp','explode','expm1','extension_loaded',
+            'extract','ezmlm_hash','fbird_add_user','fbird_affected_rows',
+            'fbird_backup','fbird_blob_add','fbird_blob_cancel',
+            'fbird_blob_close','fbird_blob_create','fbird_blob_echo',
+            'fbird_blob_get','fbird_blob_import','fbird_blob_info',
+            'fbird_blob_open','fbird_close','fbird_commit','fbird_commit_ret',
+            'fbird_connect','fbird_db_info','fbird_delete_user','fbird_drop_db',
+            'fbird_errcode','fbird_errmsg','fbird_execute','fbird_fetch_assoc',
+            'fbird_fetch_object','fbird_fetch_row','fbird_field_info',
+            'fbird_free_event_handler','fbird_free_query','fbird_free_result',
+            'fbird_gen_id','fbird_maintain_db','fbird_modify_user',
+            'fbird_name_result','fbird_num_fields','fbird_num_params',
+            'fbird_param_info','fbird_pconnect','fbird_prepare','fbird_query',
+            'fbird_restore','fbird_rollback','fbird_rollback_ret',
+            'fbird_server_info','fbird_service_attach','fbird_service_detach',
+            'fbird_set_event_handler','fbird_trans','fbird_wait_event','fclose',
+            'fdf_add_doc_javascript','fdf_add_template','fdf_close',
+            'fdf_create','fdf_enum_values','fdf_errno','fdf_error','fdf_get_ap',
+            'fdf_get_attachment','fdf_get_encoding','fdf_get_file',
+            'fdf_get_flags','fdf_get_opt','fdf_get_status','fdf_get_value',
+            'fdf_get_version','fdf_header','fdf_next_field_name','fdf_open',
+            'fdf_open_string','fdf_remove_item','fdf_save','fdf_save_string',
+            'fdf_set_ap','fdf_set_encoding','fdf_set_file','fdf_set_flags',
+            'fdf_set_javascript_action','fdf_set_on_import_javascript',
+            'fdf_set_opt','fdf_set_status','fdf_set_submit_form_action',
+            'fdf_set_target_frame','fdf_set_value','fdf_set_version','feof',
+            'fflush','fgetc','fgetcsv','fgets','fgetss','file','file_exists',
+            'file_get_contents','file_put_contents','fileatime','filectime',
+            'filegroup','fileinode','filemtime','fileowner','fileperms',
+            'filepro','filepro_fieldcount','filepro_fieldname',
+            'filepro_fieldtype','filepro_fieldwidth','filepro_retrieve',
+            'filepro_rowcount','filesize','filetype','filter_has_var',
+            'filter_id','filter_input','filter_input_array','filter_list',
+            'filter_var','filter_var_array','finfo_buffer','finfo_close',
+            'finfo_file','finfo_open','finfo_set_flags','floatval','flock',
+            'floor','flush','fmod','fnmatch','fopen','fpassthru','fprintf',
+            'fputcsv','fputs','fread','frenchtojd','fribidi_charset_info',
+            'fribidi_get_charsets','fribidi_log2vis','fscanf','fseek',
+            'fsockopen','fstat','ftell','ftok','ftp_alloc','ftp_cdup',
+            'ftp_chdir','ftp_chmod','ftp_close','ftp_connect','ftp_delete',
+            'ftp_exec','ftp_fget','ftp_fput','ftp_get','ftp_get_option',
+            'ftp_login','ftp_mdtm','ftp_mkdir','ftp_nb_continue','ftp_nb_fget',
+            'ftp_nb_fput','ftp_nb_get','ftp_nb_put','ftp_nlist','ftp_pasv',
+            'ftp_put','ftp_pwd','ftp_quit','ftp_raw','ftp_rawlist','ftp_rename',
+            'ftp_rmdir','ftp_set_option','ftp_site','ftp_size',
+            'ftp_ssl_connect','ftp_systype','ftruncate','function_exists',
+            'func_get_arg','func_get_args','func_num_args','fwrite','gd_info',
+            'getallheaders','getcwd','getdate','getenv','gethostbyaddr',
+            'gethostbyname','gethostbynamel','getimagesize','getlastmod',
+            'getmxrr','getmygid','getmyinode','getmypid','getmyuid','getopt',
+            'getprotobyname','getprotobynumber','getrandmax','getrusage',
+            'getservbyname','getservbyport','gettext','gettimeofday','gettype',
+            'get_browser','get_cfg_var','get_class','get_class_methods',
+            'get_class_vars','get_current_user','get_declared_classes',
+            'get_defined_constants','get_defined_functions','get_defined_vars',
+            'get_extension_funcs','get_headers','get_html_translation_table',
+            'get_included_files','get_include_path','get_loaded_extensions',
+            'get_magic_quotes_gpc','get_magic_quotes_runtime','get_meta_tags',
+            'get_object_vars','get_parent_class','get_required_files',
+            'get_resource_type','glob','gmdate','gmmktime','gmp_abs','gmp_add',
+            'gmp_and','gmp_clrbit','gmp_cmp','gmp_com','gmp_div','gmp_div_q',
+            'gmp_div_qr','gmp_div_r','gmp_divexact','gmp_fact','gmp_gcd',
+            'gmp_gcdext','gmp_hamdist','gmp_init','gmp_intval','gmp_invert',
+            'gmp_jacobi','gmp_legendre','gmp_mod','gmp_mul','gmp_neg',
+            'gmp_nextprime','gmp_or','gmp_perfect_square','gmp_popcount',
+            'gmp_pow','gmp_powm','gmp_prob_prime','gmp_random','gmp_scan0',
+            'gmp_scan1','gmp_setbit','gmp_sign','gmp_sqrt','gmp_sqrtrem',
+            'gmp_strval','gmp_sub','gmp_xor','gmstrftime','gopher_parsedir',
+            'gregoriantojd','gzclose','gzcompress','gzdeflate','gzencode',
+            'gzeof','gzfile','gzgetc','gzgets','gzgetss','gzinflate','gzopen',
+            'gzpassthru','gzputs','gzread','gzrewind','gzseek','gztell',
+            'gzuncompress','gzwrite','hash','hash_algos','hash_file',
+            'hash_final','hash_hmac','hash_hmac_file','hash_init','hash_update',
+            'hash_update_file','hash_update_stream','header','headers_list',
+            'headers_sent','hebrev','hebrevc','hexdec','highlight_file',
+            'highlight_string','html_doc','html_doc_file','html_entity_decode',
+            'htmlentities','htmlspecialchars','htmlspecialchars_decode',
+            'http_build_cookie','http_build_query','http_build_str',
+            'http_build_url','http_cache_etag','http_cache_last_modified',
+            'http_chunked_decode','http_date','http_deflate','http_get',
+            'http_get_request_body','http_get_request_body_stream',
+            'http_get_request_headers','http_head','http_inflate',
+            'http_match_etag','http_match_modified','http_match_request_header',
+            'http_negotiate_charset','http_negotiate_content_type',
+            'http_negotiate_language','http_parse_cookie','http_parse_headers',
+            'http_parse_message','http_parse_params',
+            'http_persistent_handles_clean','http_persistent_handles_count',
+            'http_persistent_handles_ident','http_post_data','http_post_fields',
+            'http_put_data','http_put_file','http_put_stream','http_redirect',
+            'http_request','http_request_body_encode',
+            'http_request_method_exists','http_request_method_name',
+            'http_request_method_register','http_request_method_unregister',
+            'http_send_content_disposition','http_send_content_type',
+            'http_send_data','http_send_file','http_send_last_modified',
+            'http_send_status','http_send_stream','http_support',
+            'http_throttle','hypot','i18n_convert','i18n_discover_encoding',
+            'i18n_http_input','i18n_http_output','i18n_internal_encoding',
+            'i18n_ja_jp_hantozen','i18n_mime_header_decode',
+            'i18n_mime_header_encode','ibase_add_user','ibase_affected_rows',
+            'ibase_backup','ibase_blob_add','ibase_blob_cancel',
+            'ibase_blob_close','ibase_blob_create','ibase_blob_echo',
+            'ibase_blob_get','ibase_blob_import','ibase_blob_info',
+            'ibase_blob_open','ibase_close','ibase_commit','ibase_commit_ret',
+            'ibase_connect','ibase_db_info','ibase_delete_user','ibase_drop_db',
+            'ibase_errcode','ibase_errmsg','ibase_execute','ibase_fetch_assoc',
+            'ibase_fetch_object','ibase_fetch_row','ibase_field_info',
+            'ibase_free_event_handler','ibase_free_query','ibase_free_result',
+            'ibase_gen_id','ibase_maintain_db','ibase_modify_user',
+            'ibase_name_result','ibase_num_fields','ibase_num_params',
+            'ibase_param_info','ibase_pconnect','ibase_prepare','ibase_query',
+            'ibase_restore','ibase_rollback','ibase_rollback_ret',
+            'ibase_server_info','ibase_service_attach','ibase_service_detach',
+            'ibase_set_event_handler','ibase_trans','ibase_wait_event','iconv',
+            'iconv_get_encoding','iconv_mime_decode',
+            'iconv_mime_decode_headers','iconv_mime_encode',
+            'iconv_set_encoding','iconv_strlen','iconv_strpos','iconv_strrpos',
+            'iconv_substr','id3_get_frame_long_name','id3_get_frame_short_name',
+            'id3_get_genre_id','id3_get_genre_list','id3_get_genre_name',
+            'id3_get_tag','id3_get_version','id3_remove_tag','id3_set_tag',
+            'idate','ignore_user_abort','image_type_to_extension',
+            'image_type_to_mime_type','image2wbmp','imagealphablending',
+            'imageantialias','imagearc','imagechar','imagecharup',
+            'imagecolorallocate','imagecolorallocatealpha','imagecolorat',
+            'imagecolorclosest','imagecolorclosestalpha','imagecolordeallocate',
+            'imagecolorexact','imagecolorexactalpha','imagecolormatch',
+            'imagecolorresolve','imagecolorresolvealpha','imagecolorset',
+            'imagecolorsforindex','imagecolorstotal','imagecolortransparent',
+            'imageconvolution','imagecopy','imagecopymerge',
+            'imagecopymergegray','imagecopyresampled','imagecopyresized',
+            'imagecreate','imagecreatefromgd','imagecreatefromgd2',
+            'imagecreatefromgd2part','imagecreatefromgif','imagecreatefromjpeg',
+            'imagecreatefrompng','imagecreatefromstring','imagecreatefromwbmp',
+            'imagecreatefromxbm','imagecreatetruecolor','imagedashedline',
+            'imagedestroy','imageellipse','imagefill','imagefilledarc',
+            'imagefilledellipse','imagefilledpolygon','imagefilledrectangle',
+            'imagefilltoborder','imagefilter','imagefontheight',
+            'imagefontwidth','imageftbbox','imagefttext','imagegammacorrect',
+            'imagegd','imagegd2','imagegif','imagegrabscreen','imagegrabwindow',
+            'imageinterlace','imageistruecolor','imagejpeg','imagelayereffect',
+            'imageline','imageloadfont','imagepalettecopy','imagepng',
+            'imagepolygon','imagepsbbox','imagepsencodefont',
+            'imagepsextendfont','imagepsfreefont','imagepsloadfont',
+            'imagepsslantfont','imagepstext','imagerectangle','imagerotate',
+            'imagesavealpha','imagesetbrush','imagesetpixel','imagesetstyle',
+            'imagesetthickness','imagesettile','imagestring','imagestringup',
+            'imagesx','imagesy','imagetruecolortopalette','imagettfbbox',
+            'imagettftext','imagetypes','imagewbmp','imagexbm','imap_8bit',
+            'imap_alerts','imap_append','imap_base64','imap_binary','imap_body',
+            'imap_bodystruct','imap_check','imap_clearflag_full','imap_close',
+            'imap_create','imap_createmailbox','imap_delete',
+            'imap_deletemailbox','imap_errors','imap_expunge',
+            'imap_fetch_overview','imap_fetchbody','imap_fetchheader',
+            'imap_fetchstructure','imap_fetchtext','imap_get_quota',
+            'imap_get_quotaroot','imap_getacl','imap_getmailboxes',
+            'imap_getsubscribed','imap_header','imap_headerinfo','imap_headers',
+            'imap_last_error','imap_list','imap_listmailbox',
+            'imap_listsubscribed','imap_lsub','imap_mail','imap_mail_compose',
+            'imap_mail_copy','imap_mail_move','imap_mailboxmsginfo',
+            'imap_mime_header_decode','imap_msgno','imap_num_msg',
+            'imap_num_recent','imap_open','imap_ping','imap_qprint',
+            'imap_rename','imap_renamemailbox','imap_reopen',
+            'imap_rfc822_parse_adrlist','imap_rfc822_parse_headers',
+            'imap_rfc822_write_address','imap_savebody','imap_scan',
+            'imap_scanmailbox','imap_search','imap_set_quota','imap_setacl',
+            'imap_setflag_full','imap_sort','imap_status','imap_subscribe',
+            'imap_thread','imap_timeout','imap_uid','imap_undelete',
+            'imap_unsubscribe','imap_utf7_decode','imap_utf7_encode',
+            'imap_utf8','implode','import_request_variables','in_array',
+            'ini_alter','ini_get','ini_get_all','ini_restore','ini_set',
+            'intval','ip2long','iptcembed','iptcparse','isset','is_a',
+            'is_array','is_bool','is_callable','is_dir','is_double',
+            'is_executable','is_file','is_finite','is_float','is_infinite',
+            'is_int','is_integer','is_link','is_long','is_nan','is_null',
+            'is_numeric','is_object','is_readable','is_real','is_resource',
+            'is_scalar','is_soap_fault','is_string','is_subclass_of',
+            'is_uploaded_file','is_writable','is_writeable','iterator_apply',
+            'iterator_count','iterator_to_array','java_last_exception_clear',
+            'java_last_exception_get','jddayofweek','jdmonthname','jdtofrench',
+            'jdtogregorian','jdtojewish','jdtojulian','jdtounix','jewishtojd',
+            'join','jpeg2wbmp','json_decode','json_encode','juliantojd','key',
+            'key_exists','krsort','ksort','lcg_value','ldap_add','ldap_bind',
+            'ldap_close','ldap_compare','ldap_connect','ldap_count_entries',
+            'ldap_delete','ldap_dn2ufn','ldap_err2str','ldap_errno',
+            'ldap_error','ldap_explode_dn','ldap_first_attribute',
+            'ldap_first_entry','ldap_first_reference','ldap_free_result',
+            'ldap_get_attributes','ldap_get_dn','ldap_get_entries',
+            'ldap_get_option','ldap_get_values','ldap_get_values_len',
+            'ldap_list','ldap_mod_add','ldap_mod_del','ldap_mod_replace',
+            'ldap_modify','ldap_next_attribute','ldap_next_entry',
+            'ldap_next_reference','ldap_parse_reference','ldap_parse_result',
+            'ldap_read','ldap_rename','ldap_search','ldap_set_option',
+            'ldap_sort','ldap_start_tls','ldap_unbind','levenshtein',
+            'libxml_clear_errors','libxml_get_errors','libxml_get_last_error',
+            'libxml_set_streams_context','libxml_use_internal_errors','link',
+            'linkinfo','list','localeconv','localtime','log','log1p','log10',
+            'long2ip','lstat','ltrim','lzf_compress','lzf_decompress',
+            'lzf_optimized_for','magic_quotes_runtime','mail','max','mbereg',
+            'mberegi','mberegi_replace','mbereg_match','mbereg_replace',
+            'mbereg_search','mbereg_search_getpos','mbereg_search_getregs',
+            'mbereg_search_init','mbereg_search_pos','mbereg_search_regs',
+            'mbereg_search_setpos','mbregex_encoding','mbsplit','mbstrcut',
+            'mbstrlen','mbstrpos','mbstrrpos','mbsubstr','mb_check_encoding',
+            'mb_convert_case','mb_convert_encoding','mb_convert_kana',
+            'mb_convert_variables','mb_decode_mimeheader',
+            'mb_decode_numericentity','mb_detect_encoding','mb_detect_order',
+            'mb_encode_mimeheader','mb_encode_numericentity','mb_ereg',
+            'mb_eregi','mb_eregi_replace','mb_ereg_match','mb_ereg_replace',
+            'mb_ereg_search','mb_ereg_search_getpos','mb_ereg_search_getregs',
+            'mb_ereg_search_init','mb_ereg_search_pos','mb_ereg_search_regs',
+            'mb_ereg_search_setpos','mb_get_info','mb_http_input',
+            'mb_http_output','mb_internal_encoding','mb_language',
+            'mb_list_encodings','mb_output_handler','mb_parse_str',
+            'mb_preferred_mime_name','mb_regex_encoding','mb_regex_set_options',
+            'mb_send_mail','mb_split','mb_strcut','mb_strimwidth','mb_stripos',
+            'mb_stristr','mb_strlen','mb_strpos','mb_strrchr','mb_strrichr',
+            'mb_strripos','mb_strrpos','mb_strstr','mb_strtolower',
+            'mb_strtoupper','mb_strwidth','mb_substitute_character','mb_substr',
+            'mb_substr_count','mcrypt_cbc','mcrypt_cfb','mcrypt_create_iv',
+            'mcrypt_decrypt','mcrypt_ecb','mcrypt_enc_get_algorithms_name',
+            'mcrypt_enc_get_block_size','mcrypt_enc_get_iv_size',
+            'mcrypt_enc_get_key_size','mcrypt_enc_get_modes_name',
+            'mcrypt_enc_get_supported_key_sizes',
+            'mcrypt_enc_is_block_algorithm',
+            'mcrypt_enc_is_block_algorithm_mode','mcrypt_enc_is_block_mode',
+            'mcrypt_enc_self_test','mcrypt_encrypt','mcrypt_generic',
+            'mcrypt_generic_deinit','mcrypt_generic_end','mcrypt_generic_init',
+            'mcrypt_get_block_size','mcrypt_get_cipher_name',
+            'mcrypt_get_iv_size','mcrypt_get_key_size','mcrypt_list_algorithms',
+            'mcrypt_list_modes','mcrypt_module_close',
+            'mcrypt_module_get_algo_block_size',
+            'mcrypt_module_get_algo_key_size',
+            'mcrypt_module_get_supported_key_sizes',
+            'mcrypt_module_is_block_algorithm',
+            'mcrypt_module_is_block_algorithm_mode',
+            'mcrypt_module_is_block_mode','mcrypt_module_open',
+            'mcrypt_module_self_test','mcrypt_ofb','md5','md5_file',
+            'mdecrypt_generic','memcache_add','memcache_add_server',
+            'memcache_close','memcache_connect','memcache_debug',
+            'memcache_decrement','memcache_delete','memcache_flush',
+            'memcache_get','memcache_get_extended_stats',
+            'memcache_get_server_status','memcache_get_stats',
+            'memcache_get_version','memcache_increment','memcache_pconnect',
+            'memcache_replace','memcache_set','memcache_set_compress_threshold',
+            'memcache_set_server_params','memory_get_peak_usage',
+            'memory_get_usage','metaphone','mhash','mhash_count',
+            'mhash_get_block_size','mhash_get_hash_name','mhash_keygen_s2k',
+            'method_exists','microtime','mime_content_type','min',
+            'ming_keypress','ming_setcubicthreshold','ming_setscale',
+            'ming_useconstants','ming_useswfversion','mkdir','mktime',
+            'money_format','move_uploaded_file','msql','msql_affected_rows',
+            'msql_close','msql_connect','msql_create_db','msql_createdb',
+            'msql_data_seek','msql_db_query','msql_dbname','msql_drop_db',
+            'msql_dropdb','msql_error','msql_fetch_array','msql_fetch_field',
+            'msql_fetch_object','msql_fetch_row','msql_field_flags',
+            'msql_field_len','msql_field_name','msql_field_seek',
+            'msql_field_table','msql_field_type','msql_fieldflags',
+            'msql_fieldlen','msql_fieldname','msql_fieldtable','msql_fieldtype',
+            'msql_free_result','msql_freeresult','msql_list_dbs',
+            'msql_list_fields','msql_list_tables','msql_listdbs',
+            'msql_listfields','msql_listtables','msql_num_fields',
+            'msql_num_rows','msql_numfields','msql_numrows','msql_pconnect',
+            'msql_query','msql_regcase','msql_result','msql_select_db',
+            'msql_selectdb','msql_tablename','mssql_bind','mssql_close',
+            'mssql_connect','mssql_data_seek','mssql_execute',
+            'mssql_fetch_array','mssql_fetch_assoc','mssql_fetch_batch',
+            'mssql_fetch_field','mssql_fetch_object','mssql_fetch_row',
+            'mssql_field_length','mssql_field_name','mssql_field_seek',
+            'mssql_field_type','mssql_free_result','mssql_free_statement',
+            'mssql_get_last_message','mssql_guid_string','mssql_init',
+            'mssql_min_error_severity','mssql_min_message_severity',
+            'mssql_next_result','mssql_num_fields','mssql_num_rows',
+            'mssql_pconnect','mssql_query','mssql_result','mssql_rows_affected',
+            'mssql_select_db','mt_getrandmax','mt_rand','mt_srand','mysql',
+            'mysql_affected_rows','mysql_client_encoding','mysql_close',
+            'mysql_connect','mysql_createdb','mysql_create_db',
+            'mysql_data_seek','mysql_dbname','mysql_db_name','mysql_db_query',
+            'mysql_dropdb','mysql_drop_db','mysql_errno','mysql_error',
+            'mysql_escape_string','mysql_fetch_array','mysql_fetch_assoc',
+            'mysql_fetch_field','mysql_fetch_lengths','mysql_fetch_object',
+            'mysql_fetch_row','mysql_fieldflags','mysql_fieldlen',
+            'mysql_fieldname','mysql_fieldtable','mysql_fieldtype',
+            'mysql_field_flags','mysql_field_len','mysql_field_name',
+            'mysql_field_seek','mysql_field_table','mysql_field_type',
+            'mysql_freeresult','mysql_free_result','mysql_get_client_info',
+            'mysql_get_host_info','mysql_get_proto_info',
+            'mysql_get_server_info','mysql_info','mysql_insert_id',
+            'mysql_listdbs','mysql_listfields','mysql_listtables',
+            'mysql_list_dbs','mysql_list_fields','mysql_list_processes',
+            'mysql_list_tables','mysql_numfields','mysql_numrows',
+            'mysql_num_fields','mysql_num_rows','mysql_pconnect','mysql_ping',
+            'mysql_query','mysql_real_escape_string','mysql_result',
+            'mysql_selectdb','mysql_select_db','mysql_set_charset','mysql_stat',
+            'mysql_tablename','mysql_table_name','mysql_thread_id',
+            'mysql_unbuffered_query','mysqli_affected_rows','mysqli_autocommit',
+            'mysqli_bind_param','mysqli_bind_result','mysqli_change_user',
+            'mysqli_character_set_name','mysqli_client_encoding','mysqli_close',
+            'mysqli_commit','mysqli_connect','mysqli_connect_errno',
+            'mysqli_connect_error','mysqli_data_seek','mysqli_debug',
+            'mysqli_disable_reads_from_master','mysqli_disable_rpl_parse',
+            'mysqli_dump_debug_info','mysqli_embedded_server_end',
+            'mysqli_embedded_server_start','mysqli_enable_reads_from_master',
+            'mysqli_enable_rpl_parse','mysqli_errno','mysqli_error',
+            'mysqli_escape_string','mysqli_execute','mysqli_fetch',
+            'mysqli_fetch_array','mysqli_fetch_assoc','mysqli_fetch_field',
+            'mysqli_fetch_field_direct','mysqli_fetch_fields',
+            'mysqli_fetch_lengths','mysqli_fetch_object','mysqli_fetch_row',
+            'mysqli_field_count','mysqli_field_seek','mysqli_field_tell',
+            'mysqli_free_result','mysqli_get_charset','mysqli_get_client_info',
+            'mysqli_get_client_version','mysqli_get_host_info',
+            'mysqli_get_metadata','mysqli_get_proto_info',
+            'mysqli_get_server_info','mysqli_get_server_version',
+            'mysqli_get_warnings','mysqli_info','mysqli_init',
+            'mysqli_insert_id','mysqli_kill','mysqli_master_query',
+            'mysqli_more_results','mysqli_multi_query','mysqli_next_result',
+            'mysqli_num_fields','mysqli_num_rows','mysqli_options',
+            'mysqli_param_count','mysqli_ping','mysqli_prepare','mysqli_query',
+            'mysqli_real_connect','mysqli_real_escape_string',
+            'mysqli_real_query','mysqli_report','mysqli_rollback',
+            'mysqli_rpl_parse_enabled','mysqli_rpl_probe',
+            'mysqli_rpl_query_type','mysqli_select_db','mysqli_send_long_data',
+            'mysqli_send_query','mysqli_set_charset',
+            'mysqli_set_local_infile_default','mysqli_set_local_infile_handler',
+            'mysqli_set_opt','mysqli_slave_query','mysqli_sqlstate',
+            'mysqli_ssl_set','mysqli_stat','mysqli_stmt_affected_rows',
+            'mysqli_stmt_attr_get','mysqli_stmt_attr_set',
+            'mysqli_stmt_bind_param','mysqli_stmt_bind_result',
+            'mysqli_stmt_close','mysqli_stmt_data_seek','mysqli_stmt_errno',
+            'mysqli_stmt_error','mysqli_stmt_execute','mysqli_stmt_fetch',
+            'mysqli_stmt_field_count','mysqli_stmt_free_result',
+            'mysqli_stmt_get_warnings','mysqli_stmt_init',
+            'mysqli_stmt_insert_id','mysqli_stmt_num_rows',
+            'mysqli_stmt_param_count','mysqli_stmt_prepare','mysqli_stmt_reset',
+            'mysqli_stmt_result_metadata','mysqli_stmt_send_long_data',
+            'mysqli_stmt_sqlstate','mysqli_stmt_store_result',
+            'mysqli_store_result','mysqli_thread_id','mysqli_thread_safe',
+            'mysqli_use_result','mysqli_warning_count','natcasesort','natsort',
+            'new_xmldoc','next','ngettext','nl2br','nl_langinfo',
+            'ntuser_getdomaincontroller','ntuser_getusergroups',
+            'ntuser_getuserinfo','ntuser_getuserlist','number_format',
+            'ob_clean','ob_deflatehandler','ob_end_clean','ob_end_flush',
+            'ob_etaghandler','ob_flush','ob_get_clean','ob_get_contents',
+            'ob_get_flush','ob_get_length','ob_get_level','ob_get_status',
+            'ob_gzhandler','ob_iconv_handler','ob_implicit_flush',
+            'ob_inflatehandler','ob_list_handlers','ob_start','ob_tidyhandler',
+            'octdec','odbc_autocommit','odbc_binmode','odbc_close',
+            'odbc_close_all','odbc_columnprivileges','odbc_columns',
+            'odbc_commit','odbc_connect','odbc_cursor','odbc_data_source',
+            'odbc_do','odbc_error','odbc_errormsg','odbc_exec','odbc_execute',
+            'odbc_fetch_array','odbc_fetch_into','odbc_fetch_object',
+            'odbc_fetch_row','odbc_field_len','odbc_field_name',
+            'odbc_field_num','odbc_field_precision','odbc_field_scale',
+            'odbc_field_type','odbc_foreignkeys','odbc_free_result',
+            'odbc_gettypeinfo','odbc_longreadlen','odbc_next_result',
+            'odbc_num_fields','odbc_num_rows','odbc_pconnect','odbc_prepare',
+            'odbc_primarykeys','odbc_procedurecolumns','odbc_procedures',
+            'odbc_result','odbc_result_all','odbc_rollback','odbc_setoption',
+            'odbc_specialcolumns','odbc_statistics','odbc_tableprivileges',
+            'odbc_tables','opendir','openlog','openssl_csr_export',
+            'openssl_csr_export_to_file','openssl_csr_get_public_key',
+            'openssl_csr_get_subject','openssl_csr_new','openssl_csr_sign',
+            'openssl_error_string','openssl_free_key','openssl_get_privatekey',
+            'openssl_get_publickey','openssl_open','openssl_pkcs12_export',
+            'openssl_pkcs12_export_to_file','openssl_pkcs12_read',
+            'openssl_pkcs7_decrypt','openssl_pkcs7_encrypt',
+            'openssl_pkcs7_sign','openssl_pkcs7_verify','openssl_pkey_export',
+            'openssl_pkey_export_to_file','openssl_pkey_free',
+            'openssl_pkey_get_details','openssl_pkey_get_private',
+            'openssl_pkey_get_public','openssl_pkey_new',
+            'openssl_private_decrypt','openssl_private_encrypt',
+            'openssl_public_decrypt','openssl_public_encrypt','openssl_seal',
+            'openssl_sign','openssl_verify','openssl_x509_checkpurpose',
+            'openssl_x509_check_private_key','openssl_x509_export',
+            'openssl_x509_export_to_file','openssl_x509_free',
+            'openssl_x509_parse','openssl_x509_read','ord',
+            'output_add_rewrite_var','output_reset_rewrite_vars','overload',
+            'outputdebugstring','pack','parse_ini_file','parse_str','parse_url',
+            'parsekit_compile_file','parsekit_compile_string',
+            'parsekit_func_arginfo','parsekit_opcode_flags',
+            'parsekit_opcode_name','passthru','pathinfo','pclose',
+            'pdf_add_bookmark','pdf_add_launchlink','pdf_add_locallink',
+            'pdf_add_nameddest','pdf_add_note','pdf_add_pdflink',
+            'pdf_add_thumbnail','pdf_add_weblink','pdf_arc','pdf_arcn',
+            'pdf_attach_file','pdf_begin_font','pdf_begin_glyph',
+            'pdf_begin_page','pdf_begin_pattern','pdf_begin_template',
+            'pdf_circle','pdf_clip','pdf_close','pdf_close_image',
+            'pdf_close_pdi','pdf_close_pdi_page','pdf_closepath',
+            'pdf_closepath_fill_stroke','pdf_closepath_stroke','pdf_concat',
+            'pdf_continue_text','pdf_create_gstate','pdf_create_pvf',
+            'pdf_curveto','pdf_delete','pdf_delete_pvf','pdf_encoding_set_char',
+            'pdf_end_font','pdf_end_glyph','pdf_end_page','pdf_end_pattern',
+            'pdf_end_template','pdf_endpath','pdf_fill','pdf_fill_imageblock',
+            'pdf_fill_pdfblock','pdf_fill_stroke','pdf_fill_textblock',
+            'pdf_findfont','pdf_fit_image','pdf_fit_pdi_page',
+            'pdf_fit_textline','pdf_get_apiname','pdf_get_buffer',
+            'pdf_get_errmsg','pdf_get_errnum','pdf_get_parameter',
+            'pdf_get_pdi_parameter','pdf_get_pdi_value','pdf_get_value',
+            'pdf_initgraphics','pdf_lineto','pdf_load_font',
+            'pdf_load_iccprofile','pdf_load_image','pdf_makespotcolor',
+            'pdf_moveto','pdf_new','pdf_open_ccitt','pdf_open_file',
+            'pdf_open_image','pdf_open_image_file','pdf_open_pdi',
+            'pdf_open_pdi_page','pdf_place_image','pdf_place_pdi_page',
+            'pdf_process_pdi','pdf_rect','pdf_restore','pdf_rotate','pdf_save',
+            'pdf_scale','pdf_set_border_color','pdf_set_border_dash',
+            'pdf_set_border_style','pdf_set_gstate','pdf_set_info',
+            'pdf_set_parameter','pdf_set_text_pos','pdf_set_value',
+            'pdf_setcolor','pdf_setdash','pdf_setdashpattern','pdf_setflat',
+            'pdf_setfont','pdf_setlinecap','pdf_setlinejoin','pdf_setlinewidth',
+            'pdf_setmatrix','pdf_setmiterlimit','pdf_setpolydash','pdf_shading',
+            'pdf_shading_pattern','pdf_shfill','pdf_show','pdf_show_boxed',
+            'pdf_show_xy','pdf_skew','pdf_stringwidth','pdf_stroke',
+            'pdf_translate','pdo_drivers','pfsockopen','pg_affected_rows',
+            'pg_cancel_query','pg_clientencoding','pg_client_encoding',
+            'pg_close','pg_cmdtuples','pg_connect','pg_connection_busy',
+            'pg_connection_reset','pg_connection_status','pg_convert',
+            'pg_copy_from','pg_copy_to','pg_dbname','pg_delete','pg_end_copy',
+            'pg_errormessage','pg_escape_bytea','pg_escape_string','pg_exec',
+            'pg_execute','pg_fetch_all','pg_fetch_all_columns','pg_fetch_array',
+            'pg_fetch_assoc','pg_fetch_object','pg_fetch_result','pg_fetch_row',
+            'pg_fieldisnull','pg_fieldname','pg_fieldnum','pg_fieldprtlen',
+            'pg_fieldsize','pg_fieldtype','pg_field_is_null','pg_field_name',
+            'pg_field_num','pg_field_prtlen','pg_field_size','pg_field_table',
+            'pg_field_type','pg_field_type_oid','pg_free_result',
+            'pg_freeresult','pg_get_notify','pg_get_pid','pg_get_result',
+            'pg_getlastoid','pg_host','pg_insert','pg_last_error',
+            'pg_last_notice','pg_last_oid','pg_loclose','pg_locreate',
+            'pg_loexport','pg_loimport','pg_loopen','pg_loread','pg_loreadall',
+            'pg_lounlink','pg_lowrite','pg_lo_close','pg_lo_create',
+            'pg_lo_export','pg_lo_import','pg_lo_open','pg_lo_read',
+            'pg_lo_read_all','pg_lo_seek','pg_lo_tell','pg_lo_unlink',
+            'pg_lo_write','pg_meta_data','pg_numfields','pg_numrows',
+            'pg_num_fields','pg_num_rows','pg_options','pg_parameter_status',
+            'pg_pconnect','pg_ping','pg_port','pg_prepare','pg_put_line',
+            'pg_query','pg_query_params','pg_result','pg_result_error',
+            'pg_result_error_field','pg_result_seek','pg_result_status',
+            'pg_select','pg_send_execute','pg_send_prepare','pg_send_query',
+            'pg_send_query_params','pg_set_client_encoding',
+            'pg_set_error_verbosity','pg_setclientencoding','pg_trace',
+            'pg_transaction_status','pg_tty','pg_unescape_bytea','pg_untrace',
+            'pg_update','pg_version','php_egg_logo_guid','php_ini_loaded_file',
+            'php_ini_scanned_files','php_logo_guid','php_real_logo_guid',
+            'php_sapi_name','php_strip_whitespace','php_uname','phpcredits',
+            'phpdoc_xml_from_string','phpinfo','phpversion','pi','png2wbmp',
+            'pop3_close','pop3_delete_message','pop3_get_account_size',
+            'pop3_get_message','pop3_get_message_count',
+            'pop3_get_message_header','pop3_get_message_ids',
+            'pop3_get_message_size','pop3_get_message_sizes','pop3_open',
+            'pop3_undelete','popen','pos','posix_ctermid','posix_errno',
+            'posix_getcwd','posix_getegid','posix_geteuid','posix_getgid',
+            'posix_getgrgid','posix_getgrnam','posix_getgroups',
+            'posix_getlogin','posix_getpgid','posix_getpgrp','posix_getpid',
+            'posix_getppid','posix_getpwnam','posix_getpwuid','posix_getrlimit',
+            'posix_getsid','posix_getuid','posix_get_last_error','posix_isatty',
+            'posix_kill','posix_mkfifo','posix_setegid','posix_seteuid',
+            'posix_setgid','posix_setpgid','posix_setsid','posix_setuid',
+            'posix_strerror','posix_times','posix_ttyname','posix_uname','pow',
+            'preg_grep','preg_last_error','preg_match','preg_match_all',
+            'preg_quote','preg_replace','preg_replace_callback','preg_split',
+            'prev','print_r','printf','proc_close','proc_get_status',
+            'proc_open','proc_terminate','putenv','quoted_printable_decode',
+            'quotemeta','rad2deg','radius_acct_open','radius_add_server',
+            'radius_auth_open','radius_close','radius_config',
+            'radius_create_request','radius_cvt_addr','radius_cvt_int',
+            'radius_cvt_string','radius_demangle','radius_demangle_mppe_key',
+            'radius_get_attr','radius_get_vendor_attr','radius_put_addr',
+            'radius_put_attr','radius_put_int','radius_put_string',
+            'radius_put_vendor_addr','radius_put_vendor_attr',
+            'radius_put_vendor_int','radius_put_vendor_string',
+            'radius_request_authenticator','radius_send_request',
+            'radius_server_secret','radius_strerror','rand','range',
+            'rawurldecode','rawurlencode','read_exif_data','readdir','readfile',
+            'readgzfile','readlink','realpath','reg_close_key','reg_create_key',
+            'reg_enum_key','reg_enum_value','reg_get_value','reg_open_key',
+            'reg_set_value','register_shutdown_function',
+            'register_tick_function','rename','res_close','res_get','res_list',
+            'res_list_type','res_open','res_set','reset',
+            'restore_error_handler','restore_include_path','rewind','rewinddir',
+            'rmdir','round','rsort','rtrim','runkit_class_adopt',
+            'runkit_class_emancipate','runkit_constant_add',
+            'runkit_constant_redefine','runkit_constant_remove',
+            'runkit_default_property_add','runkit_function_add',
+            'runkit_function_copy','runkit_function_redefine',
+            'runkit_function_remove','runkit_function_rename','runkit_import',
+            'runkit_lint','runkit_lint_file','runkit_method_add',
+            'runkit_method_copy','runkit_method_redefine',
+            'runkit_method_remove','runkit_method_rename','runkit_object_id',
+            'runkit_return_value_used','runkit_sandbox_output_handler',
+            'runkit_superglobals','runkit_zval_inspect','scandir','sem_acquire',
+            'sem_get','sem_release','sem_remove','serialize',
+            'session_cache_expire','session_cache_limiter','session_commit',
+            'session_decode','session_destroy','session_encode',
+            'session_get_cookie_params','session_id','session_is_registered',
+            'session_module_name','session_name','session_regenerate_id',
+            'session_register','session_save_path','session_set_cookie_params',
+            'session_set_save_handler','session_start','session_unregister',
+            'session_unset','session_write_close','set_content',
+            'set_error_handler','set_file_buffer','set_include_path',
+            'set_magic_quotes_runtime','set_socket_blocking','set_time_limit',
+            'setcookie','setlocale','setrawcookie','settype','sha1','sha1_file',
+            'shell_exec','shmop_close','shmop_delete','shmop_open','shmop_read',
+            'shmop_size','shmop_write','shm_attach','shm_detach','shm_get_var',
+            'shm_put_var','shm_remove','shm_remove_var','show_source','shuffle',
+            'similar_text','simplexml_import_dom','simplexml_load_file',
+            'simplexml_load_string','sin','sinh','sizeof','sleep','smtp_close',
+            'smtp_cmd_data','smtp_cmd_mail','smtp_cmd_rcpt','smtp_connect',
+            'snmp_get_quick_print','snmp_get_valueretrieval','snmp_read_mib',
+            'snmp_set_quick_print','snmp_set_valueretrieval','snmp2_get',
+            'snmp2_getnext','snmp2_real_walk','snmp2_set','snmp2_walk',
+            'snmp3_get','snmp3_getnext','snmp3_real_walk','snmp3_set',
+            'snmp3_walk','snmpget','snmpgetnext','snmprealwalk','snmpset',
+            'snmpwalk','snmpwalkoid','socket_accept','socket_bind',
+            'socket_clear_error','socket_close','socket_connect',
+            'socket_create','socket_create_listen','socket_create_pair',
+            'socket_getopt','socket_getpeername','socket_getsockname',
+            'socket_get_option','socket_get_status','socket_iovec_add',
+            'socket_iovec_alloc','socket_iovec_delete','socket_iovec_fetch',
+            'socket_iovec_free','socket_iovec_set','socket_last_error',
+            'socket_listen','socket_read','socket_readv','socket_recv',
+            'socket_recvfrom','socket_recvmsg','socket_select','socket_send',
+            'socket_sendmsg','socket_sendto','socket_setopt','socket_set_block',
+            'socket_set_blocking','socket_set_nonblock','socket_set_option',
+            'socket_set_timeout','socket_shutdown','socket_strerror',
+            'socket_write','socket_writev','sort','soundex','spl_autoload',
+            'spl_autoload_call','spl_autoload_extensions',
+            'spl_autoload_functions','spl_autoload_register',
+            'spl_autoload_unregister','spl_classes','spl_object_hash','split',
+            'spliti','sprintf','sql_regcase','sqlite_array_query',
+            'sqlite_busy_timeout','sqlite_changes','sqlite_close',
+            'sqlite_column','sqlite_create_aggregate','sqlite_create_function',
+            'sqlite_current','sqlite_error_string','sqlite_escape_string',
+            'sqlite_exec','sqlite_factory','sqlite_fetch_all',
+            'sqlite_fetch_array','sqlite_fetch_column_types',
+            'sqlite_fetch_object','sqlite_fetch_single','sqlite_fetch_string',
+            'sqlite_field_name','sqlite_has_more','sqlite_has_prev',
+            'sqlite_last_error','sqlite_last_insert_rowid','sqlite_libencoding',
+            'sqlite_libversion','sqlite_next','sqlite_num_fields',
+            'sqlite_num_rows','sqlite_open','sqlite_popen','sqlite_prev',
+            'sqlite_query','sqlite_rewind','sqlite_seek','sqlite_single_query',
+            'sqlite_udf_decode_binary','sqlite_udf_encode_binary',
+            'sqlite_unbuffered_query','sqlite_valid','sqrt','srand','sscanf',
+            'ssh2_auth_hostbased_file','ssh2_auth_none','ssh2_auth_password',
+            'ssh2_auth_pubkey_file','ssh2_connect','ssh2_exec',
+            'ssh2_fetch_stream','ssh2_fingerprint','ssh2_forward_accept',
+            'ssh2_forward_listen','ssh2_methods_negotiated','ssh2_poll',
+            'ssh2_publickey_add','ssh2_publickey_init','ssh2_publickey_list',
+            'ssh2_publickey_remove','ssh2_scp_recv','ssh2_scp_send','ssh2_sftp',
+            'ssh2_sftp_lstat','ssh2_sftp_mkdir','ssh2_sftp_readlink',
+            'ssh2_sftp_realpath','ssh2_sftp_rename','ssh2_sftp_rmdir',
+            'ssh2_sftp_stat','ssh2_sftp_symlink','ssh2_sftp_unlink',
+            'ssh2_shell','ssh2_tunnel','stat','stats_absolute_deviation',
+            'stats_cdf_beta','stats_cdf_binomial','stats_cdf_cauchy',
+            'stats_cdf_chisquare','stats_cdf_exponential','stats_cdf_f',
+            'stats_cdf_gamma','stats_cdf_laplace','stats_cdf_logistic',
+            'stats_cdf_negative_binomial','stats_cdf_noncentral_chisquare',
+            'stats_cdf_noncentral_f','stats_cdf_noncentral_t',
+            'stats_cdf_normal','stats_cdf_poisson','stats_cdf_t',
+            'stats_cdf_uniform','stats_cdf_weibull','stats_covariance',
+            'stats_dens_beta','stats_dens_cauchy','stats_dens_chisquare',
+            'stats_dens_exponential','stats_dens_f','stats_dens_gamma',
+            'stats_dens_laplace','stats_dens_logistic','stats_dens_normal',
+            'stats_dens_pmf_binomial','stats_dens_pmf_hypergeometric',
+            'stats_dens_pmf_negative_binomial','stats_dens_pmf_poisson',
+            'stats_dens_t','stats_dens_uniform','stats_dens_weibull',
+            'stats_harmonic_mean','stats_kurtosis','stats_rand_gen_beta',
+            'stats_rand_gen_chisquare','stats_rand_gen_exponential',
+            'stats_rand_gen_f','stats_rand_gen_funiform','stats_rand_gen_gamma',
+            'stats_rand_gen_ipoisson','stats_rand_gen_iuniform',
+            'stats_rand_gen_noncenral_f','stats_rand_gen_noncentral_chisquare',
+            'stats_rand_gen_noncentral_t','stats_rand_gen_normal',
+            'stats_rand_gen_t','stats_rand_getsd','stats_rand_ibinomial',
+            'stats_rand_ibinomial_negative','stats_rand_ignlgi',
+            'stats_rand_phrase_to_seeds','stats_rand_ranf','stats_rand_setall',
+            'stats_skew','stats_standard_deviation','stats_stat_binomial_coef',
+            'stats_stat_correlation','stats_stat_factorial',
+            'stats_stat_independent_t','stats_stat_innerproduct',
+            'stats_stat_paired_t','stats_stat_percentile','stats_stat_powersum',
+            'stats_variance','strcasecmp','strchr','strcmp','strcoll','strcspn',
+            'stream_bucket_append','stream_bucket_make_writeable',
+            'stream_bucket_new','stream_bucket_prepend','stream_context_create',
+            'stream_context_get_default','stream_context_get_options',
+            'stream_context_set_default','stream_context_set_option',
+            'stream_context_set_params','stream_copy_to_stream',
+            'stream_encoding','stream_filter_append','stream_filter_prepend',
+            'stream_filter_register','stream_filter_remove',
+            'stream_get_contents','stream_get_filters','stream_get_line',
+            'stream_get_meta_data','stream_get_transports',
+            'stream_get_wrappers','stream_is_local',
+            'stream_notification_callback','stream_register_wrapper',
+            'stream_resolve_include_path','stream_select','stream_set_blocking',
+            'stream_set_timeout','stream_set_write_buffer',
+            'stream_socket_accept','stream_socket_client',
+            'stream_socket_enable_crypto','stream_socket_get_name',
+            'stream_socket_pair','stream_socket_recvfrom',
+            'stream_socket_sendto','stream_socket_server',
+            'stream_socket_shutdown','stream_supports_lock',
+            'stream_wrapper_register','stream_wrapper_restore',
+            'stream_wrapper_unregister','strftime','stripcslashes','stripos',
+            'stripslashes','strip_tags','stristr','strlen','strnatcasecmp',
+            'strnatcmp','strpbrk','strncasecmp','strncmp','strpos','strrchr',
+            'strrev','strripos','strrpos','strspn','strstr','strtok',
+            'strtolower','strtotime','strtoupper','strtr','strval',
+            'str_ireplace','str_pad','str_repeat','str_replace','str_rot13',
+            'str_split','str_shuffle','str_word_count','substr',
+            'substr_compare','substr_count','substr_replace','svn_add',
+            'svn_auth_get_parameter','svn_auth_set_parameter','svn_cat',
+            'svn_checkout','svn_cleanup','svn_client_version','svn_commit',
+            'svn_diff','svn_export','svn_fs_abort_txn','svn_fs_apply_text',
+            'svn_fs_begin_txn2','svn_fs_change_node_prop','svn_fs_check_path',
+            'svn_fs_contents_changed','svn_fs_copy','svn_fs_delete',
+            'svn_fs_dir_entries','svn_fs_file_contents','svn_fs_file_length',
+            'svn_fs_is_dir','svn_fs_is_file','svn_fs_make_dir',
+            'svn_fs_make_file','svn_fs_node_created_rev','svn_fs_node_prop',
+            'svn_fs_props_changed','svn_fs_revision_prop',
+            'svn_fs_revision_root','svn_fs_txn_root','svn_fs_youngest_rev',
+            'svn_import','svn_info','svn_log','svn_ls','svn_repos_create',
+            'svn_repos_fs','svn_repos_fs_begin_txn_for_commit',
+            'svn_repos_fs_commit_txn','svn_repos_hotcopy','svn_repos_open',
+            'svn_repos_recover','svn_status','svn_update','symlink',
+            'sys_get_temp_dir','syslog','system','tan','tanh','tempnam',
+            'textdomain','thread_get','thread_include','thread_lock',
+            'thread_lock_try','thread_mutex_destroy','thread_mutex_init',
+            'thread_set','thread_start','thread_unlock','tidy_access_count',
+            'tidy_clean_repair','tidy_config_count','tidy_diagnose',
+            'tidy_error_count','tidy_get_body','tidy_get_config',
+            'tidy_get_error_buffer','tidy_get_head','tidy_get_html',
+            'tidy_get_html_ver','tidy_get_output','tidy_get_release',
+            'tidy_get_root','tidy_get_status','tidy_getopt','tidy_is_xhtml',
+            'tidy_is_xml','tidy_parse_file','tidy_parse_string',
+            'tidy_repair_file','tidy_repair_string','tidy_warning_count','time',
+            'timezone_abbreviations_list','timezone_identifiers_list',
+            'timezone_name_from_abbr','timezone_name_get','timezone_offset_get',
+            'timezone_open','timezone_transitions_get','tmpfile',
+            'token_get_all','token_name','touch','trigger_error',
+            'transliterate','transliterate_filters_get','trim','uasort',
+            'ucfirst','ucwords','uksort','umask','uniqid','unixtojd','unlink',
+            'unpack','unregister_tick_function','unserialize','unset',
+            'urldecode','urlencode','user_error','use_soap_error_handler',
+            'usleep','usort','utf8_decode','utf8_encode','var_dump',
+            'var_export','variant_abs','variant_add','variant_and',
+            'variant_cast','variant_cat','variant_cmp',
+            'variant_date_from_timestamp','variant_date_to_timestamp',
+            'variant_div','variant_eqv','variant_fix','variant_get_type',
+            'variant_idiv','variant_imp','variant_int','variant_mod',
+            'variant_mul','variant_neg','variant_not','variant_or',
+            'variant_pow','variant_round','variant_set','variant_set_type',
+            'variant_sub','variant_xor','version_compare','virtual','vfprintf',
+            'vprintf','vsprintf','wddx_add_vars','wddx_deserialize',
+            'wddx_packet_end','wddx_packet_start','wddx_serialize_value',
+            'wddx_serialize_vars','win_beep','win_browse_file',
+            'win_browse_folder','win_create_link','win_message_box',
+            'win_play_wav','win_shell_execute','win32_create_service',
+            'win32_delete_service','win32_get_last_control_message',
+            'win32_ps_list_procs','win32_ps_stat_mem','win32_ps_stat_proc',
+            'win32_query_service_status','win32_scheduler_delete_task',
+            'win32_scheduler_enum_tasks','win32_scheduler_get_task_info',
+            'win32_scheduler_run','win32_scheduler_set_task_info',
+            'win32_set_service_status','win32_start_service',
+            'win32_start_service_ctrl_dispatcher','win32_stop_service',
+            'wordwrap','xml_error_string','xml_get_current_byte_index',
+            'xml_get_current_column_number','xml_get_current_line_number',
+            'xml_get_error_code','xml_parse','xml_parser_create',
+            'xml_parser_create_ns','xml_parser_free','xml_parser_get_option',
+            'xml_parser_set_option','xml_parse_into_struct',
+            'xml_set_character_data_handler','xml_set_default_handler',
+            'xml_set_element_handler','xml_set_end_namespace_decl_handler',
+            'xml_set_external_entity_ref_handler',
+            'xml_set_notation_decl_handler','xml_set_object',
+            'xml_set_processing_instruction_handler',
+            'xml_set_start_namespace_decl_handler',
+            'xml_set_unparsed_entity_decl_handler','xmldoc','xmldocfile',
+            'xmlrpc_decode','xmlrpc_decode_request','xmlrpc_encode',
+            'xmlrpc_encode_request','xmlrpc_get_type','xmlrpc_is_fault',
+            'xmlrpc_parse_method_descriptions',
+            'xmlrpc_server_add_introspection_data','xmlrpc_server_call_method',
+            'xmlrpc_server_create','xmlrpc_server_destroy',
+            'xmlrpc_server_register_introspection_callback',
+            'xmlrpc_server_register_method','xmlrpc_set_type','xmltree',
+            'xmlwriter_end_attribute','xmlwriter_end_cdata',
+            'xmlwriter_end_comment','xmlwriter_end_document',
+            'xmlwriter_end_dtd','xmlwriter_end_dtd_attlist',
+            'xmlwriter_end_dtd_element','xmlwriter_end_dtd_entity',
+            'xmlwriter_end_element','xmlwriter_end_pi','xmlwriter_flush',
+            'xmlwriter_full_end_element','xmlwriter_open_memory',
+            'xmlwriter_open_uri','xmlwriter_output_memory',
+            'xmlwriter_set_indent','xmlwriter_set_indent_string',
+            'xmlwriter_start_attribute','xmlwriter_start_attribute_ns',
+            'xmlwriter_start_cdata','xmlwriter_start_comment',
+            'xmlwriter_start_document','xmlwriter_start_dtd',
+            'xmlwriter_start_dtd_attlist','xmlwriter_start_dtd_element',
+            'xmlwriter_start_dtd_entity','xmlwriter_start_element',
+            'xmlwriter_start_element_ns','xmlwriter_start_pi','xmlwriter_text',
+            'xmlwriter_write_attribute','xmlwriter_write_attribute_ns',
+            'xmlwriter_write_cdata','xmlwriter_write_comment',
+            'xmlwriter_write_dtd','xmlwriter_write_dtd_attlist',
+            'xmlwriter_write_dtd_element','xmlwriter_write_dtd_entity',
+            'xmlwriter_write_element','xmlwriter_write_element_ns',
+            'xmlwriter_write_pi','xmlwriter_write_raw','xpath_eval',
+            'xpath_eval_expression','xpath_new_context','xpath_register_ns',
+            'xpath_register_ns_auto','xptr_eval','xptr_new_context','yp_all',
+            'yp_cat','yp_errno','yp_err_string','yp_first',
+            'yp_get_default_domain','yp_master','yp_match','yp_next','yp_order',
+            'zend_current_obfuscation_level','zend_get_cfg_var','zend_get_id',
+            'zend_loader_current_file','zend_loader_enabled',
+            'zend_loader_file_encoded','zend_loader_file_licensed',
+            'zend_loader_install_license','zend_loader_version',
+            'zend_logo_guid','zend_match_hostmasks','zend_obfuscate_class_name',
+            'zend_obfuscate_function_name','zend_optimizer_version',
+            'zend_runtime_obfuscate','zend_version','zip_close',
+            'zip_entry_close','zip_entry_compressedsize',
+            'zip_entry_compressionmethod','zip_entry_filesize','zip_entry_name',
+            'zip_entry_open','zip_entry_read','zip_open','zip_read',
+            'zlib_get_coding_type'
+            ),
+        4 => array(
+            'DEFAULT_INCLUDE_PATH', 'DIRECTORY_SEPARATOR', 'E_ALL',
+            'E_COMPILE_ERROR', 'E_COMPILE_WARNING', 'E_CORE_ERROR',
+            'E_CORE_WARNING', 'E_ERROR', 'E_NOTICE', 'E_PARSE', 'E_STRICT',
+            'E_USER_ERROR', 'E_USER_NOTICE', 'E_USER_WARNING', 'E_WARNING',
+            'ENT_COMPAT','ENT_QUOTES','ENT_NOQUOTES',
+            'false', 'null', 'PEAR_EXTENSION_DIR', 'PEAR_INSTALL_DIR',
+            'PHP_BINDIR', 'PHP_CONFIG_FILE_PATH', 'PHP_DATADIR',
+            'PHP_EXTENSION_DIR', 'PHP_LIBDIR',
+            'PHP_LOCALSTATEDIR', 'PHP_OS',
+            'PHP_OUTPUT_HANDLER_CONT', 'PHP_OUTPUT_HANDLER_END',
+            'PHP_OUTPUT_HANDLER_START', 'PHP_SYSCONFDIR',
+            'PHP_VERSION', 'true', '__CLASS__', '__FILE__', '__FUNCTION__',
+            '__LINE__', '__METHOD__'
+            )
+        ),
+    'SYMBOLS' => array(
+        1 => array(
+            '<%', '<%=', '%>', '<?', '<?=', '?>'
+            ),
+        0 => array(
+            '(', ')', '[', ']', '{', '}',
+            '!', '@', '%', '&', '|', '/',
+            '<', '>',
+            '=', '-', '+', '*',
+            '.', ':', ',', ';'
+            )
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #990000;',
+            4 => 'color: #009900; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => 'color: #666666; font-style: italic;',
+            3 => 'color: #0000cc; font-style: italic;',
+            4 => 'color: #009933; font-style: italic;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            1 => 'color: #000099; font-weight: bold;',
+            2 => 'color: #660099; font-weight: bold;',
+            3 => 'color: #660099; font-weight: bold;',
+            4 => 'color: #006699; font-weight: bold;',
+            5 => 'color: #006699; font-weight: bold; font-style: italic;',
+            6 => 'color: #009933; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;',
+            'HARD' => 'color: #0000ff;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;',
+            GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+            GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+            ),
+        'METHODS' => array(
+            1 => 'color: #004000;',
+            2 => 'color: #004000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;',
+            1 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #000088;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => '',
+            4 => '',
+            5 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.php.net/{FNAMEL}',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '-&gt;',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        //Variables
+        0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<?php' => '?>'
+            ),
+        1 => array(
+            '<?' => '?>'
+            ),
+        2 => array(
+            '<%' => '%>'
+            ),
+        3 => array(
+            '<script language="php">' => '</script>'
+            ),
+        4 => "/(<\?(?:php)?)(?:'(?:[^'\\\\]|\\\\.)*?'|\"(?:[^\"\\\\]|\\\\.)*?\"|\/\*(?!\*\/).*?\*\/|.)*?(\?>|\Z)/sm",
+        5 => "/(<%)(?:'(?:[^'\\\\]|\\\\.)*?'|\"(?:[^\"\\\\]|\\\\.)*?\"|\/\*(?!\*\/).*?\*\/|.)*?(%>|\Z)/sm"
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/pic16.php b/examples/includes/geshi/geshi/pic16.php
new file mode 100644 (file)
index 0000000..2679788
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * pic16.php
+ * -------
+ * Author: Phil Mattison (mattison@ohmikron.com)
+ * Copyright: (c) 2008 Ohmikron Corp. (http://www.ohmikron.com/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/07/30
+ *
+ * PIC16 Assembler language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/30 (1.0.8)
+ *   -  First Release
+ *
+ * TODO (updated 2008/07/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'PIC16',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        /*Instructions*/
+        1 => array(
+            'addcf','adddcf','addlw','addwf','andlw','andwf','bc','bcf','bdc',
+            'bnc','bndc','bnz','bsf','btfsc','btfss','bz','call','clrc','clrdc',
+            'clrf','clrw','clrwdt','clrz','comf','decf','goto','incf','incfsz',
+            'iorlw','iorwf','lcall','lgoto','movf','movfw','movlw','movwf',
+            'option','negf','nop','retfie','retlw','return','rlf','rrf','setc',
+            'setdc','setz','skpc','skpdc','skpnc','skpndc','skpnz','skpz',
+            'sleep','subcf','subdcf','sublw','subwf','swapf','tris','tstf',
+            'xorlw','xorwf'
+            ),
+        /*Registers*/
+        2 => array(
+            'INDF','TMR0','OPTION','PCL','STATUS','FSR','PORTA','PORTB','PORTC',
+            'PORTD','PORTE','PORTF','TRISA','TRISB','TRISC','TRISD','TRISE',
+            'TRISF','PCLATH','INTCON','PIR1','PIE1','PCON','CMCON','VRCON',
+            'F','W'
+            ),
+        /*Directives*/
+        3 => array(
+            '_BADRAM','BANKISEL','BANKSEL','CBLOCK','CODE','_CONFIG','CONSTANT',
+            'DA','DATA','DB','DE','#DEFINE','DT','DW','ELSE','END','ENDC',
+            'ENDIF','ENDM','ENDW','EQU','ERROR','ERRORLEVEL','EXITM','EXPAND',
+            'EXTERN','FILL','GLOBAL','IDATA','_IDLOCS','IF','IFDEF','IFNDEF',
+            'INCLUDE','#INCLUDE','LIST','LOCAL','MACRO','_MAXRAM','MESSG',
+            'NOEXPAND','NOLIST','ORG','PAGE','PAGESEL','PROCESSOR','RADIX',
+            'RES','SET','SPACE','SUBTITLE','TITLE','UDATA','UDATA_ACS',
+            'UDATA_OVR','UDATA_SHR','#UNDEFINE','VARIABLE','WHILE',
+            'D','H','O','B','A'
+            ),
+        ),
+    'SYMBOLS' => array('=','.',',',':'),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000a0; font-weight: bold;',
+            2 => 'color: #aa3300; font-weight: bold;',
+            3 => 'color: #0000ff;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #00a000;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff7700;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff7700;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #7777ff;'
+            ),
+        'REGEXPS' => array(),
+        'SCRIPT' => array()
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC |
+        GESHI_NUMBER_BIN_SUFFIX |
+        GESHI_NUMBER_HEX_PREFIX |
+        GESHI_NUMBER_HEX_SUFFIX,
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array(),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "a-zA-Z0-9\$_\|\#>|^",
+            'DISALLOWED_AFTER' => "a-zA-Z0-9_<\|%"
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/pixelbender.php b/examples/includes/geshi/geshi/pixelbender.php
new file mode 100644 (file)
index 0000000..93da0df
--- /dev/null
@@ -0,0 +1,176 @@
+<?php
+/*************************************************************************************
+ * pixelbender.php
+ * ----------------
+ * Author: Richard Olsson (r@richardolsson.se)
+ * Copyright: (c) 2008 Richard Olsson (richardolsson.se)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/11/16
+ *
+ * Pixel Bender 1.0 language file for GeSHi.
+ *
+ *
+ * Please feel free to modify this file, although I would greatly appreciate
+ * it if you would then send some feedback on why the file needed to be
+ * changed, using the e-mail address above.
+ *
+ *
+ * The colors are inspired by those used in the Pixel Bender Toolkit, with
+ * some slight modifications.
+ *
+ * For more info on Pixel Bender, see the Adobe Labs Wiki article at
+ * http://labs.adobe.com/wiki/index.php/Pixel_Bender_Toolkit.
+ *
+ * Keyword groups are defined as follows (groups marked with an asterisk
+ * inherit their names from terminology used in the language specification
+ * included with the Pixel Bender Toolkit, see URL above.)
+ *
+ *  1. languageVersion & kernel keywords
+ *  2. Kernel Members *
+ *  3. Types *
+ *  4. Statements * & qualifiers (in, out, inout)
+ *  5. Built-in functions *
+ *  6. Meta-data names
+ *  7. Preprocessor & Pre-defined symbols *
+ *
+ *
+ * CHANGES
+ * -------
+ * 2008/11/16 (1.0.8.2)
+ *  - Initial release
+ *
+ * TODO (updated 2008/11/16)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+    'LANG_NAME' => 'Pixel Bender 1.0',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'languageVersion', 'kernel'
+            ),
+        2 => array(
+            'import', 'parameter', 'dependent', 'const', 'input', 'output',
+            'evaluatePixel', 'evaluateDependents', 'needed', 'changed', 'generated'
+            ),
+        3 => array(
+            'bool', 'bool2', 'bool3', 'bool4', 'int', 'int2', 'int3', 'int4',
+            'float', 'float2', 'float3', 'float4', 'float2x2', 'float3x3', 'float4x4',
+            'pixel2', 'pixel3', 'pixel4', 'region', 'image1', 'image2', 'image3', 'image4',
+            'imageRef', 'void'
+            ),
+        4 => array(
+            'in', 'out', 'inout', 'if', 'else', 'for', 'while', 'do', 'break',
+            'continue', 'return'
+            ),
+        5 => array(
+            'radians', 'degrees', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'pow',
+            'exp', 'exp2', 'log', 'log2', 'sqrt', 'inverseSqrt', 'abs', 'sign', 'floor',
+            'ceil', 'fract', 'mod', 'min', 'max', 'step', 'clamp', 'mix', 'smoothStep',
+            'length', 'distance', 'dot', 'cross', 'normalize', 'matrixCompMult', 'lessThan',
+            'lessThanEqual', 'greaterThan', 'greaterThanEqual', 'equal', 'notEqual', 'any',
+            'all', 'not', 'nowhere', 'everywhere', 'transform', 'union', 'intersect',
+            'outset', 'inset', 'bounds', 'isEmpty', 'sample', 'sampleLinear', 'sampleNearest',
+            'outCoord', 'dod', 'pixelSize', 'pixelAspectRatio'
+            ),
+        6 => array(
+            'namespace', 'vendor', 'version', 'minValue', 'maxValue', 'defaultValue', 'description'
+            ),
+        7 => array(
+            '#if', '#endif', '#ifdef', '#elif', 'defined', '#define',
+            'AIF_ATI', 'AIF_NVIDIA', 'AIF_FLASH_TARGET'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '%', '&', '|', '+', '-', '*', '/', '=', '<', '>', '?', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0033ff;',
+            2 => 'color: #0033ff; font-weight: bold;',
+            3 => 'color: #0033ff;',
+            4 => 'color: #9900cc; font-weight: bold;',
+            5 => 'color: #333333;',
+            6 => 'color: #666666;',
+            7 => 'color: #990000;',
+        ),
+        'COMMENTS' => array(
+            1 => 'color: #009900;',
+            'MULTI' => 'color: #3f5fbf;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #990000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000; font-weight:bold;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #000000;',
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array('.'),
+    'REGEXPS' => array(),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+
+?>
diff --git a/examples/includes/geshi/geshi/plsql.php b/examples/includes/geshi/geshi/plsql.php
new file mode 100644 (file)
index 0000000..2f3a2b6
--- /dev/null
@@ -0,0 +1,256 @@
+<?php
+/*************************************************************************************
+ * plsql.php
+ * -------
+ * Author: Victor Engmark <victor.engmark@gmail.com>
+ * Copyright: (c) 2006 Victor Engmark (http://l0b0.net/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/10/26
+ *
+ * Oracle 9.2 PL/SQL language file for GeSHi.
+ * Formatting is based on the default setup of TOAD 8.6.
+ *
+ * CHANGES
+ * -------
+ * 2006/10/27 (1.0.0)
+ *    -    First Release
+ *
+ * TODO (updated 2006/10/27)
+ * -------------------------
+ * * Add < and > to brackets
+ * * Remove symbols which are also comment delimiters / quote marks?
+ *
+ *************************************************************************************
+ *
+ *         This file is part of GeSHi.
+ *
+ *     GeSHi is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU General Public License as published by
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     GeSHi is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public License
+ *     along with GeSHi; if not, write to the Free Software
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA    02111-1307    USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'PL/SQL',
+    'COMMENT_SINGLE' => array(1 =>'--'), //http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#2930
+    'COMMENT_MULTI' => array('/*' => '*/'), //http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#2950
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array("'", '"'), //http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        //PL/SQL reserved keywords (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/f_words.htm#LNPLS019)
+        1 => array('ZONE', 'YEAR', 'WRITE', 'WORK', 'WITH', 'WHILE', 'WHERE',
+        'WHENEVER', 'WHEN', 'VIEW', 'VARCHAR2', 'VARCHAR', 'VALUES',
+        'VALIDATE', 'USE', 'UPDATE', 'UNIQUE', 'UNION', 'TYPE', 'TRUE',
+        'TRIGGER', 'TO', 'TIMEZONE_REGION', 'TIMEZONE_MINUTE', 'TIMEZONE_HOUR',
+        'TIMEZONE_ABBR', 'TIMESTAMP', 'TIME', 'THEN', 'TABLE', 'SYNONYM',
+        'SUCCESSFUL', 'SUBTYPE', 'START', 'SQLERRM', 'SQLCODE', 'SQL', 'SPACE',
+        'SMALLINT', 'SHARE', 'SET', 'SEPARATE', 'SELECT', 'SECOND',
+        'SAVEPOINT', 'ROWTYPE', 'ROWNUM', 'ROWID', 'ROW', 'ROLLBACK',
+        'REVERSE', 'RETURN', 'RELEASE', 'RECORD', 'REAL', 'RAW', 'RANGE',
+        'RAISE', 'PUBLIC', 'PROCEDURE', 'PRIVATE', 'PRIOR', 'PRAGMA',
+        'POSITIVEN', 'POSITIVE', 'PLS_INTEGER', 'PCTFREE', 'PARTITION',
+        'PACKAGE', 'OUT', 'OTHERS', 'ORGANIZATION', 'ORDER', 'OR', 'OPTION',
+        'OPERATOR', 'OPEN', 'OPAQUE', 'ON', 'OF', 'OCIROWID', 'NUMBER_BASE',
+        'NUMBER', 'NULL', 'NOWAIT', 'NOT', 'NOCOPY', 'NEXTVAL', 'NEW',
+        'NATURALN', 'NATURAL', 'MONTH', 'MODE', 'MLSLABEL', 'MINUTE', 'MINUS',
+        'LOOP', 'LONG', 'LOCK', 'LIMITED', 'LIKE', 'LEVEL', 'JAVA',
+        'ISOLATION', 'IS', 'INTO', 'INTERVAL', 'INTERSECT', 'INTERFACE',
+        'INTEGER', 'INSERT', 'INDICATOR', 'INDEX', 'IN', 'IMMEDIATE', 'IF',
+        'HOUR', 'HEAP', 'HAVING', 'GROUP', 'GOTO', 'FUNCTION', 'FROM',
+        'FORALL', 'FOR', 'FLOAT', 'FETCH', 'FALSE', 'EXTENDS', 'EXIT',
+        'EXISTS', 'EXECUTE', 'EXCLUSIVE', 'EXCEPTION', 'END', 'ELSIF', 'ELSE',
+        'DROP', 'DO', 'DISTINCT', 'DESC', 'DELETE', 'DEFAULT', 'DECLARE',
+        'DECIMAL', 'DAY', 'DATE', 'CURSOR', 'CURRVAL', 'CURRENT', 'CREATE',
+        'CONSTANT', 'CONNECT', 'COMPRESS', 'COMMIT', 'COMMENT', 'COLLECT',
+        'CLUSTER', 'CLOSE', 'CHECK', 'CHAR_BASE', 'CHAR', 'CASE', 'BY', 'BULK',
+        'BOOLEAN', 'BODY', 'BINARY_INTEGER', 'BETWEEN', 'BEGIN', 'AUTHID',
+        'AT', 'ASC', 'AS', 'ARRAY', 'ANY', 'AND', 'ALTER', 'ALL'),
+        //SQL functions (http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96540/toc.htm & http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96540/functions101a.htm#85925)
+        2 => array('XMLTRANSFORM', 'XMLSEQUENCE', 'XMLFOREST', 'XMLELEMENT',
+        'XMLCONCAT', 'XMLCOLATTVAL', 'XMLAGG', 'WIDTH_BUCKET', 'VSIZE',
+        'VARIANCE', 'VAR_SAMP', 'VAR_POP', 'VALUE', 'USERENV', 'USER', 'UPPER',
+        'UPDATEXML', 'UNISTR', 'UID', 'TZ_OFFSET', 'TRUNC', 'TRIM', 'TREAT',
+        'TRANSLATE', 'TO_YMINTERVAL', 'TO_TIMESTAMP_TZ', 'TO_TIMESTAMP',
+        'TO_SINGLE_BYTE', 'TO_NUMBER', 'TO_NCLOB', 'TO_NCHAR', 'TO_MULTI_BYTE',
+        'TO_LOB', 'TO_DSINTERVAL', 'TO_DATE', 'TO_CLOB', 'TO_CHAR', 'TANH',
+        'TAN', 'SYSTIMESTAMP', 'SYSDATE', 'SYS_XMLGEN', 'SYS_XMLAGG',
+        'SYS_TYPEID', 'SYS_GUID', 'SYS_EXTRACT_UTC', 'SYS_DBURIGEN',
+        'SYS_CONTEXT', 'SYS_CONNECT_BY_PATH', 'SUM', 'SUBSTR', 'STDDEV_SAMP',
+        'STDDEV_POP', 'STDDEV', 'SQRT', 'SOUNDEX', 'SINH', 'SIN', 'SIGN',
+        'SESSIONTIMEZONE', 'RTRIM', 'RPAD', 'ROWIDTONCHAR', 'ROWIDTOCHAR',
+        'ROW_NUMBER', 'ROUND', 'REPLACE', 'REGR_SYY', 'REGR_SXY', 'REGR_SXX',
+        'REGR_SLOPE', 'REGR_R2', 'REGR_INTERCEPT', 'REGR_COUNT', 'REGR_AVGY',
+        'REGR_AVGX', 'REFTOHEX', 'REF', 'RAWTONHEX', 'RAWTOHEX',
+        'RATIO_TO_REPORT', 'RANK', 'POWER', 'PERCENTILE_DISC',
+        'PERCENTILE_CONT', 'PERCENT_RANK', 'PATH', 'NVL2', 'NVL',
+        'NUMTOYMINTERVAL', 'NUMTODSINTERVAL', 'NULLIF', 'NTILE', 'NLSSORT',
+        'NLS_UPPER', 'NLS_LOWER', 'NLS_INITCAP', 'NLS_CHARSET_NAME',
+        'NLS_CHARSET_ID', 'NLS_CHARSET_DECL_LEN', 'NEXT_DAY', 'NEW_TIME',
+        'NCHR', 'MONTHS_BETWEEN', 'MOD', 'MIN', 'MAX', 'MAKE_REF', 'LTRIM',
+        'LPAD', 'LOWER', 'LOG', 'LOCALTIMESTAMP', 'LN', 'LENGTH', 'LEAST',
+        'LEAD', 'LAST_VALUE', 'LAST_DAY', 'LAST', 'LAG', 'INSTR', 'INITCAP',
+        'HEXTORAW', 'GROUPING_ID', 'GROUPING', 'GROUP_ID', 'GREATEST',
+        'FROM_TZ', 'FLOOR', 'FIRST_VALUE', 'FIRST', 'EXTRACTVALUE', 'EXTRACT',
+        'EXP', 'EXISTSNODE', 'EMPTY_CLOB', 'EMPTY_BLOB', 'DUMP', 'DEREF',
+        'DEPTH', 'DENSE_RANK', 'DECOMPOSE', 'DECODE', 'DBTIMEZONE',
+        'CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CUME_DIST', 'COVAR_SAMP',
+        'COVAR_POP', 'COUNT', 'COSH', 'COS', 'CORR', 'CONVERT', 'CONCAT',
+        'COMPOSE', 'COALESCE', 'CHR', 'CHARTOROWID', 'CEIL', 'CAST', 'BITAND',
+        'BIN_TO_NUM', 'BFILENAME', 'AVG', 'ATAN2', 'ATAN', 'ASIN', 'ASCIISTR',
+        'ASCII', 'ADD_MONTHS', 'ACOS', 'ABS'),
+        //PL/SQL packages (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96612/intro2.htm#1025672)
+        3 => array('UTL_URL', 'UTL_TCP', 'UTL_SMTP', 'UTL_REF', 'UTL_RAW',
+        'UTL_PG', 'UTL_INADDR', 'UTL_HTTP', 'UTL_FILE', 'UTL_ENCODE',
+        'UTL_COLL', 'SDO_UTIL', 'SDO_TUNE', 'SDO_MIGRATE', 'SDO_LRS',
+        'SDO_GEOM', 'SDO_CS', 'DMBS_XMLQUERY', 'DMBS_FLASHBACK',
+        'DMBS_DEFER_SYS', 'DEBUG_EXTPROC', 'DBMS_XSLPROCESSOR', 'DBMS_XPLAN',
+        'DBMS_XMLSCHEMA', 'DBMS_XMLSAVE', 'DBMS_XMLPARSER', 'DBMS_XMLGEN',
+        'DBMS_XMLDOM', 'DBMS_XDBT', 'DBMS_XDB_VERSION', 'DBMS_XDB', 'DBMS_WM',
+        'DBMS_UTILITY', 'DBMS_TYPES', 'DBMS_TTS', 'DBMS_TRANSFORM',
+        'DBMS_TRANSACTION', 'DBMS_TRACE', 'DBMS_STRM_A', 'DBMS_STRM',
+        'DBMS_STORAGE_MAP', 'DBMS_STATS', 'DBMS_SQL', 'DBMS_SPACE_ADMIN',
+        'DBMS_SPACE', 'DBMS_SHARED_POOL', 'DBMS_SESSION', 'DBMS_RULE_ADM',
+        'DBMS_RULE', 'DBMS_ROWID', 'DBMS_RLS', 'DBMS_RESUMABLE',
+        'DBMS_RESOURCE_MANAGER_PRIVS', 'DBMS_RESOURCE_MANAGER', 'DBMS_REPUTIL',
+        'DBMS_REPCAT_RGT', 'DBMS_REPCAT_INSTATIATE', 'DBMS_REPCAT_ADMIN',
+        'DBMS_REPCAT', 'DBMS_REPAIR', 'DBMS_REFRESH', 'DBMS_REDEFINITION',
+        'DBMS_RECTIFIER_DIFF', 'DBMS_RANDOM', 'DBMS_PROPAGATION_ADM',
+        'DBMS_PROFILER', 'DBMS_PIPE', 'DBMS_PCLXUTIL', 'DBMS_OUTPUT',
+        'DBMS_OUTLN_EDIT', 'DBMS_OUTLN', 'DBMS_ORACLE_TRACE_USER',
+        'DBMS_ORACLE_TRACE_AGENT', 'DBMS_OLAP', 'DBMS_OFFLINE_SNAPSHOT',
+        'DBMS_OFFLINE_OG', 'DBMS_ODCI', 'DBMS_OBFUSCATION_TOOLKIT',
+        'DBMS_MVIEW', 'DBMS_MGWMSG', 'DBMS_MGWADM', 'DBMS_METADATA',
+        'DBMS_LOGSTDBY', 'DBMS_LOGMNR_D', 'DBMS_LOGMNR_CDC_SUBSCRIBE',
+        'DBMS_LOGMNR_CDC_PUBLISH', 'DBMS_LOGMNR', 'DBMS_LOCK', 'DBMS_LOB',
+        'DBMS_LIBCACHE', 'DBMS_LDAP', 'DBMS_JOB', 'DBMS_IOT',
+        'DBMS_HS_PASSTHROUGH', 'DBMS_FGA', 'DBMS_DISTRIBUTED_TRUST_ADMIN',
+        'DBMS_DESCRIBE', 'DBMS_DEFER_QUERY', 'DBMS_DEFER', 'DBMS_DEBUG',
+        'DBMS_DDL', 'DBMS_CAPTURE_ADM', 'DBMS_AW', 'DBMS_AQELM', 'DBMS_AQADM',
+        'DBMS_AQ', 'DBMS_APPLY_ADM', 'DBMS_APPLICATION_INFO', 'DBMS_ALERT',
+        'CWM2_OLAP_AW_ACCESS'),
+        //PL/SQL predefined exceptions (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/07_errs.htm#784)
+        4 => array('ZERO_DIVIDE', 'VALUE_ERROR', 'TOO_MANY_ROWS',
+        'TIMEOUT_ON_RESOURCE', 'SYS_INVALID_ROWID', 'SUBSCRIPT_OUTSIDE_LIMIT',
+        'SUBSCRIPT_BEYOND_COUNT', 'STORAGE_ERROR', 'SELF_IS_NULL',
+        'ROWTYPE_MISMATCH', 'PROGRAM_ERROR', 'NOT_LOGGED_ON', 'NO_DATA_FOUND',
+        'LOGIN_DENIED', 'INVALID_NUMBER', 'INVALID_CURSOR', 'DUP_VAL_ON_INDEX',
+        'CURSOR_ALREADY_OPEN', 'COLLECTION_IS_NULL', 'CASE_NOT_FOUND',
+        'ACCESS_INTO_NULL'),
+        //Static data dictionary views (http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96536/ch2.htm)
+        5 => array('USER_REPSITES', 'USER_REPSCHEMA',
+        'USER_REPRESOLUTION_STATISTICS', 'USER_REPRESOLUTION_METHOD',
+        'USER_REPRESOLUTION', 'USER_REPRESOL_STATS_CONTROL', 'USER_REPPROP',
+        'USER_REPPRIORITY_GROUP', 'USER_REPPRIORITY',
+        'USER_REPPARAMETER_COLUMN', 'USER_REPOBJECT', 'USER_REPKEY_COLUMNS',
+        'USER_REPGROUPED_COLUMN', 'USER_REPGROUP_PRIVILEGES', 'USER_REPGROUP',
+        'USER_REPGENOBJECTS', 'USER_REPGENERATED', 'USER_REPFLAVORS',
+        'USER_REPFLAVOR_OBJECTS', 'USER_REPFLAVOR_COLUMNS', 'USER_REPDDL',
+        'USER_REPCONFLICT', 'USER_REPCOLUMN_GROUP', 'USER_REPCOLUMN',
+        'USER_REPCATLOG', 'USER_REPCAT_USER_PARM_VALUES',
+        'USER_REPCAT_USER_AUTHORIZATIONS', 'USER_REPCAT_TEMPLATE_SITES',
+        'USER_REPCAT_TEMPLATE_PARMS', 'USER_REPCAT_TEMPLATE_OBJECTS',
+        'USER_REPCAT_REFRESH_TEMPLATES', 'USER_REPCAT', 'USER_REPAUDIT_COLUMN',
+        'USER_REPAUDIT_ATTRIBUTE', 'DBA_REPSITES_NEW', 'DBA_REPSITES',
+        'DBA_REPSCHEMA', 'DBA_REPRESOLUTION_STATISTICS',
+        'DBA_REPRESOLUTION_METHOD', 'DBA_REPRESOLUTION',
+        'DBA_REPRESOL_STATS_CONTROL', 'DBA_REPPROP', 'DBA_REPPRIORITY_GROUP',
+        'DBA_REPPRIORITY', 'DBA_REPPARAMETER_COLUMN', 'DBA_REPOBJECT',
+        'DBA_REPKEY_COLUMNS', 'DBA_REPGROUPED_COLUMN',
+        'DBA_REPGROUP_PRIVILEGES', 'DBA_REPGROUP', 'DBA_REPGENOBJECTS',
+        'DBA_REPGENERATED', 'DBA_REPFLAVORS', 'DBA_REPFLAVOR_OBJECTS',
+        'DBA_REPFLAVOR_COLUMNS', 'DBA_REPEXTENSIONS', 'DBA_REPDDL',
+        'DBA_REPCONFLICT', 'DBA_REPCOLUMN_GROUP', 'DBA_REPCOLUMN',
+        'DBA_REPCATLOG', 'DBA_REPCAT_USER_PARM_VALUES',
+        'DBA_REPCAT_USER_AUTHORIZATIONS', 'DBA_REPCAT_TEMPLATE_SITES',
+        'DBA_REPCAT_TEMPLATE_PARMS', 'DBA_REPCAT_TEMPLATE_OBJECTS',
+        'DBA_REPCAT_REFRESH_TEMPLATES', 'DBA_REPCAT_EXCEPTIONS', 'DBA_REPCAT',
+        'DBA_REPAUDIT_COLUMN', 'DBA_REPAUDIT_ATTRIBUTE', 'ALL_REPSITES',
+        'ALL_REPSCHEMA', 'ALL_REPRESOLUTION_STATISTICS',
+        'ALL_REPRESOLUTION_METHOD', 'ALL_REPRESOLUTION',
+        'ALL_REPRESOL_STATS_CONTROL', 'ALL_REPPROP', 'ALL_REPPRIORITY_GROUP',
+        'ALL_REPPRIORITY', 'ALL_REPPARAMETER_COLUMN', 'ALL_REPOBJECT',
+        'ALL_REPKEY_COLUMNS', 'ALL_REPGROUPED_COLUMN',
+        'ALL_REPGROUP_PRIVILEGES', 'ALL_REPGROUP', 'ALL_REPGENOBJECTS',
+        'ALL_REPGENERATED', 'ALL_REPFLAVORS', 'ALL_REPFLAVOR_OBJECTS',
+        'ALL_REPFLAVOR_COLUMNS', 'ALL_REPDDL', 'ALL_REPCONFLICT',
+        'ALL_REPCOLUMN_GROUP', 'ALL_REPCOLUMN', 'ALL_REPCATLOG',
+        'ALL_REPCAT_USER_PARM_VALUES', 'ALL_REPCAT_USER_AUTHORIZATIONS',
+        'ALL_REPCAT_TEMPLATE_SITES', 'ALL_REPCAT_TEMPLATE_PARMS',
+        'ALL_REPCAT_TEMPLATE_OBJECTS', 'ALL_REPCAT_REFRESH_TEMPLATES',
+        'ALL_REPCAT', 'ALL_REPAUDIT_COLUMN', 'ALL_REPAUDIT_ATTRIBUTE')
+        ),
+    'SYMBOLS' => array(
+        //PL/SQL delimiters (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#2732)
+        '+', '%', "'", '.', '/', '(', ')', ':', ',', '*', '"', '=', '<', '>', '@', ';', '-', ':=', '=>', '||', '**', '<<', '>>', '/*', '*/', '..', '<>', '!=', '~=', '^=', '<=', '>='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #00F;',
+            2 => 'color: #000;',
+            3 => 'color: #00F;',
+            4 => 'color: #F00;',
+            5 => 'color: #800;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #080; font-style: italic;',
+            'MULTI' => 'color: #080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #00F;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #F00;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #800;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #0F0;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #00F;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            0 => 'color: #0F0;'
+            )
+        ),
+        'URLS' => array(
+            1 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+            2 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+            3 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+            4 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+            5 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}'
+            ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/povray.php b/examples/includes/geshi/geshi/povray.php
new file mode 100644 (file)
index 0000000..09a8b01
--- /dev/null
@@ -0,0 +1,199 @@
+<?php
+/*************************************************************************************
+ * povray.php
+ * --------
+ * Author: Carl Fürstenberg (azatoth@gmail.com)
+ * Copyright: © 2007 Carl Fürstenberg
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/07/11
+ *
+ * Povray language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ *   -  initial import to GeSHi SVN
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'POVRAY',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'yes', 'wrinkles', 'wood', 'width', 'waves', 'water_level', 'warp', 'vturbulence',
+            'vstr', 'vrotate', 'vnormalize', 'vlength', 'vcross', 'vaxis_rotate', 'variance', 'v_steps',
+            'uv_mapping', 'utf8', 'use_index', 'use_colour', 'use_color', 'use_alpha', 'up', 'undef',
+            'ultra_wide_angle', 'u_steps', 'type', 'turbulence', 'turb_depth', 'ttf', 'true', 'triangle_wave',
+            'translate', 'transform', 'trace', 'toroidal', 'tolerance', 'tiles', 'tile2', 'tightness',
+            'tiff', 'threshold', 'thickness', 'tga', 'texture_map', 'target', 'sys', 'sum',
+            'substr', 'sturm', 'strupr', 'strlwr', 'strength', 'str', 'statistics', 'sqr',
+            'spotted', 'spotlight', 'split_union', 'spline', 'spiral2', 'spiral1', 'spherical', 'specular',
+            'spacing', 'solid', 'smooth', 'slope', 'slice', 'sky', 'size', 'sine_wave',
+            'shadowless', 'scattering', 'scallop_wave', 'scale', 'save_file', 'samples', 'roughness', 'rotate',
+            'ripples', 'right', 'rgbt', 'rgbft', 'rgbf', 'rgb', 'repeat', 'render',
+            'refraction', 'reflection_exponent', 'recursion_limit', 'reciprocal', 'ratio', 'ramp_wave', 'radius', 'radial',
+            'quilted', 'quick_colour', 'quick_color', 'quaternion', 'quadratic_spline', 'pwr', 'projected_through', 'prod',
+            'pretrace_start', 'pretrace_end', 'precompute', 'precision', 'ppm', 'pow', 'pot', 'poly_wave',
+            'point_at', 'png', 'planar', 'pigment_pattern', 'pi', 'phong_size', 'phong', 'phase',
+            'pgm', 'perspective', 'pattern', 'pass_through', 'parallel', 'panoramic', 'orthographic', 'orientation',
+            'orient', 'open', 'onion', 'once', 'on', 'omnimax', 'omega', 'offset',
+            'off', 'octaves', 'number_of_waves', 'noise_generator', 'no_shadow', 'no_reflection', 'no_image', 'no_bump_scale',
+            'no', 'nearest_count', 'natural_spline', 'mortar', 'minimum_reuse', 'min_extent', 'metric', 'method',
+            'metallic', 'media_interaction', 'media_attenuation', 'media', 'max_trace_level', 'max_trace', 'max_sample', 'max_iteration',
+            'max_intersections', 'max_gradient', 'max_extent', 'matrix', 'material_map', 'marble', 'map_type', 'mandel',
+            'major_radius', 'magnet', 'low_error_factor', 'look_at', 'location', 'load_file', 'linear_sweep', 'linear_spline',
+            'leopard', 'lambda', 'julia', 'jpeg', 'jitter', 'irid_wavelength', 'ior', 'inverse',
+            'intervals', 'interpolate', 'internal', 'inside_vector', 'inside', 'initial_frame', 'initial_clock', 'image_width',
+            'image_pattern', 'image_height', 'iff', 'hypercomplex', 'hollow', 'hierarchy', 'hf_gray_16', 'hexagon',
+            'gray_threshold', 'granite', 'gradient', 'global_lights', 'gif', 'gather', 'fresnel', 'frequency',
+            'frame_number', 'form', 'fog_type', 'fog_offset', 'fog_alt', 'focal_point', 'flip', 'flatness',
+            'fisheye', 'final_frame', 'final_clock', 'false', 'falloff_angle', 'falloff', 'fade_power', 'fade_distance',
+            'fade_colour', 'fade_color', 'facets', 'extinction', 'exterior', 'exponent', 'expand_thresholds', 'evaluate',
+            'error_bound', 'emission', 'eccentricity', 'double_illuminate', 'distance', 'dist_exp', 'dispersion_samples', 'dispersion',
+            'direction', 'diffuse', 'df3', 'dents', 'density_map', 'density_file', 'density', 'cylindrical',
+            'cutaway_textures', 'cubic_wave', 'cubic_spline', 'cube', 'crand', 'crackle', 'count', 'coords',
+            'control1', 'control0', 'conserve_energy', 'conic_sweep', 'confidence', 'concat', 'composite', 'component',
+            'colour_map', 'colour', 'color', 'collect', 'clock_on', 'clock_delta', 'clock', 'circular',
+            'chr', 'checker', 'charset', 'cells', 'caustics', 'bumps', 'bump_size', 'brilliance',
+            'brightness', 'brick_size', 'brick', 'bozo', 'boxed', 'blur_samples', 'black_hole', 'bezier_spline',
+            'b_spline', 'average', 'autostop', 'assumed_gamma', 'ascii', 'array', 'area_light', 'arc_angle',
+            'append', 'aperture', 'angle', 'ambient_light', 'ambient', 'always_sample', 'altitude', 'alpha',
+            'all_intersections', 'all', 'agate_turb', 'agate', 'adc_bailout', 'adaptive', 'accuracy', 'absorption',
+            'aa_threshold', 'aa_level', 'reflection'
+            ),
+        2 => array(
+            'abs', 'acos', 'acosh', 'asc', 'asin', 'asinh', 'atan', 'atanh',
+            'atan2', 'ceil', 'cos', 'cosh', 'defined', 'degrees', 'dimensions', 'dimension_size',
+            'div', 'exp', 'file_exists', 'floor', 'int', 'ln', 'log', 'max',
+            'min', 'mod', 'pov', 'radians', 'rand', 'seed', 'select', 'sin',
+            'sinh', 'sqrt', 'strcmp', 'strlen', 'tan', 'tanh', 'val', 'vdot',
+            'vlenght',
+            ),
+        3 => array (
+            'x', 'y', 'z', 't', 'u', 'v', 'red', 'blue',
+            'green', 'filter', 'transmit', 'gray', 'e',
+            ),
+        4 => array (
+            'camera', 'background', 'fog', 'sky_sphere', 'rainbow', 'global_settings', 'radiosity', 'photon',
+            'object', 'blob', 'sphere', 'cylinder', 'box', 'cone', 'height_field', 'julia_fractal',
+            'lathe', 'prism', 'sphere_sweep', 'superellipsoid', 'sor', 'text', 'torus', 'bicubic_patch',
+            'disc', 'mesh', 'triangle', 'smooth_triangle', 'mesh2', 'vertex_vectors', 'normal_vectors', 'uv_vectors',
+            'texture_list', 'face_indices', 'normal_indices', 'uv_indices', 'texture', 'polygon', 'plane', 'poly',
+            'cubic', 'quartic', 'quadric', 'isosurface', 'function', 'contained_by', 'parametric', 'pigment',
+            'union', 'intersection', 'difference', 'merge', 'light_source', 'looks_like', 'light_group', 'clipped_by',
+            'bounded_by', 'interior', 'material', 'interior_texture', 'normal', 'finish', 'color_map', 'pigment_map',
+            'image_map', 'bump_map', 'slope_map', 'normal_map', 'irid', 'photons',
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!',
+        '@', '%', '&', '*', '|', '/', '<',
+        '>', '+', '-', '.', '=', '<=', '>=',
+        '!=',
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #a63123;',
+            2 => 'color: #2312bc;',
+            3 => 'color: #cc1122; font-weight: bold;',
+            4 => 'color: #116688; font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+//            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66aa;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #6666cc; font-weight: bold;',
+            1 => 'color: #66cc66; font-weight: bold;',
+            2 => 'color: #66cc66; font-weight: bold;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        # normal hash lines
+        0 => '\#(?!(include|declare|local|fopen|fclose|read|write|default|version|if|else|end|ifdef|ifndef|switch|case|range|break|while|debug|error|warning|macro) )[[:word:]]*',
+        # syntax functions hash thingis
+        1 => "\#(include|declare|local|fopen|fclose|read|write|default|version|if|else|end|ifdef|ifndef|switch|case|range|break|while|debug|error|warning|macro)",
+        2 => array(
+            GESHI_SEARCH  => "([a-zA-Z]+)(\n)(.*)(\n)(\\1;?)",
+            GESHI_REPLACE => '\3',
+            GESHI_BEFORE => '\1\2',
+            GESHI_AFTER => '\4\5',
+            GESHI_MODIFIERS => 'siU'
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'TAB_WIDTH' => 4
+);
+?>
diff --git a/examples/includes/geshi/geshi/powershell.php b/examples/includes/geshi/geshi/powershell.php
new file mode 100644 (file)
index 0000000..5b9e16b
--- /dev/null
@@ -0,0 +1,279 @@
+<?php
+/*************************************************************************************
+ * powershell.php
+ * ---------------------------------
+ * Author: Frode Aarebrot (frode@aarebrot.net)
+ * Copyright: (c) 2008 Frode Aarebrot (http://www.aarebrot.net)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/06/20
+ *
+ * PowerShell language file for GeSHi.
+ *
+ * I've tried to make this language file as true to the highlighting in PowerGUI as
+ * possible. Unfortunately it's not 100% complete, although it is pretty close.
+ *
+ * I've included some classes and their members, but there's tons and tons of these.
+ * I suggest you add the ones you need yourself. I've included a few Sharepoint ones
+ * in this language file.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/20 (1.0.8)
+ *  -  First Release
+ *
+ * TODO (updated 2008/06/20)
+ * -------------------------
+ * - Color text between Cmdlets/Aliases and pipe/end-of-line
+ * - Try and get -- and ++ to work in the KEYWORDS array with the other operators
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'posh',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '`',
+    'KEYWORDS' => array(
+        1 => array(
+            // Cmdlets
+            'Add-Content', 'Add-History', 'Add-Member', 'Add-PSSnapin', 'Clear-Content', 'Clear-Item',
+            'Clear-ItemProperty', 'Clear-Variable', 'Compare-Object', 'ConvertFrom-SecureString',
+            'Convert-Path', 'ConvertTo-Html', 'ConvertTo-SecureString', 'Copy-Item', 'Copy-ItemProperty',
+            'Export-Alias', 'Export-Clixml', 'Export-Console', 'Export-Csv', 'ForEach-Object',
+            'Format-Custom', 'Format-List', 'Format-Table', 'Format-Wide', 'Get-Acl', 'Get-Alias',
+            'Get-AuthenticodeSignature', 'Get-ChildItem', 'Get-Command', 'Get-Content', 'Get-Credential',
+            'Get-Culture', 'Get-Date', 'Get-EventLog', 'Get-ExecutionPolicy', 'Get-Help', 'Get-History',
+            'Get-Host', 'Get-Item', 'Get-ItemProperty', 'Get-Location', 'Get-Member',
+            'Get-PfxCertificate', 'Get-Process', 'Get-PSDrive', 'Get-PSProvider', 'Get-PSSnapin',
+            'Get-Service', 'Get-TraceSource', 'Get-UICulture', 'Get-Unique', 'Get-Variable',
+            'Get-WmiObject', 'Group-Object', 'Import-Alias', 'Import-Clixml', 'Import-Csv',
+            'Invoke-Expression', 'Invoke-History', 'Invoke-Item', 'Join-Path', 'Measure-Command',
+            'Measure-Object', 'Move-Item', 'Move-ItemProperty', 'New-Alias', 'New-Item',
+            'New-ItemProperty', 'New-Object', 'New-PSDrive', 'New-Service', 'New-TimeSpan',
+            'New-Variable', 'Out-Default', 'Out-File', 'Out-Host', 'Out-Null', 'Out-Printer',
+            'Out-String', 'Pop-Location', 'Push-Location', 'Read-Host', 'Remove-Item',
+            'Remove-ItemProperty', 'Remove-PSDrive', 'Remove-PSSnapin', 'Remove-Variable', 'Rename-Item',
+            'Rename-ItemProperty', 'Resolve-Path', 'Restart-Service', 'Resume-Service', 'Select-Object',
+            'Select-String', 'Set-Acl', 'Set-Alias', 'Set-AuthenticodeSignature', 'Set-Content',
+            'Set-Date', 'Set-ExecutionPolicy', 'Set-Item', 'Set-ItemProperty', 'Set-Location',
+            'Set-PSDebug', 'Set-Service', 'Set-TraceSource', 'Set-Variable', 'Sort-Object', 'Split-Path',
+            'Start-Service', 'Start-Sleep', 'Start-Transcript', 'Stop-Process', 'Stop-Service',
+            'Stop-Transcript', 'Suspend-Service', 'Tee-Object', 'Test-Path', 'Trace-Command',
+            'Update-FormatData', 'Update-TypeData', 'Where-Object', 'Write-Debug', 'Write-Error',
+            'Write-Host', 'Write-Output', 'Write-Progress', 'Write-Verbose', 'Write-Warning'
+            ),
+        2 => array(
+            // Aliases
+            'ac', 'asnp', 'clc', 'cli', 'clp', 'clv', 'cpi', 'cpp', 'cvpa', 'diff', 'epal', 'epcsv', 'fc',
+            'fl', 'ft', 'fw', 'gal', 'gc', 'gci', 'gcm', 'gdr', 'ghy', 'gi', 'gl', 'gm',
+            'gp', 'gps', 'group', 'gsv', 'gsnp', 'gu', 'gv', 'gwmi', 'iex', 'ihy', 'ii', 'ipal', 'ipcsv',
+            'mi', 'mp', 'nal', 'ndr', 'ni', 'nv', 'oh', 'rdr', 'ri', 'rni', 'rnp', 'rp', 'rsnp', 'rv',
+            'rvpa', 'sal', 'sasv', 'sc', 'select', 'si', 'sl', 'sleep', 'sort', 'sp', 'spps', 'spsv', 'sv',
+            'tee', 'write', 'cat', 'cd', 'clear', 'cp', 'h', 'history', 'kill', 'lp', 'ls',
+            'mount', 'mv', 'popd', 'ps', 'pushd', 'pwd', 'r', 'rm', 'rmdir', 'echo', 'cls', 'chdir',
+            'copy', 'del', 'dir', 'erase', 'move', 'rd', 'ren', 'set', 'type'
+            ),
+        3 => array(
+            // Reserved words
+            'break', 'continue', 'do', 'for', 'foreach', 'while', 'if', 'switch', 'until', 'where',
+            'function', 'filter', 'else', 'elseif', 'in', 'return', 'param', 'throw', 'trap'
+            ),
+        4 => array(
+            // Operators
+            '-eq', '-ne', '-gt', '-ge', '-lt', '-le', '-ieq', '-ine', '-igt', '-ige', '-ilt', '-ile',
+            '-ceq', '-cne', '-cgt', '-cge', '-clt', '-cle', '-like', '-notlike', '-match', '-notmatch',
+            '-ilike', '-inotlike', '-imatch', '-inotmatch', '-clike', '-cnotlike', '-cmatch', '-cnotmatch',
+            '-contains', '-notcontains', '-icontains', '-inotcontains', '-ccontains', '-cnotcontains',
+            '-isnot', '-is', '-as', '-replace', '-ireplace', '-creplace', '-and', '-or', '-band', '-bor',
+            '-not', '-bnot', '-f', '-casesensitive', '-exact', '-file', '-regex', '-wildcard'
+            ),
+        5 => array(
+            // Options
+            '-Year', '-Wrap', '-Word', '-Width', '-WhatIf', '-Wait', '-View', '-Verbose', '-Verb',
+            '-Variable', '-ValueOnly', '-Value', '-Unique', '-UFormat', '-TypeName', '-Trace', '-TotalCount',
+            '-Title', '-TimestampServer', '-TargetObject', '-Syntax', '-SyncWindow', '-Sum', '-String',
+            '-Strict', '-Stream', '-Step', '-Status', '-Static', '-StartupType', '-Start', '-StackName',
+            '-Stack', '-SourceId', '-SimpleMatch', '-ShowError', '-Separator', '-SecureString', '-SecureKey',
+            '-SecondValue', '-SecondsRemaining', '-Seconds', '-Second', '-Scope', '-Root', '-Role',
+            '-Resolve', '-RemoveListener', '-RemoveFileListener', '-Registered', '-ReferenceObject',
+            '-Recurse', '-RecommendedAction', '-ReadCount', '-Quiet', '-Query', '-Qualifier', '-PSSnapin',
+            '-PSProvider', '-PSHost', '-PSDrive', '-PropertyType', '-Property', '-Prompt', '-Process',
+            '-PrependPath', '-PercentComplete', '-Pattern', '-PathType', '-Path', '-PassThru', '-ParentId',
+            '-Parent', '-Parameter', '-Paging', '-OutVariable', '-OutBuffer', '-Option', '-OnType', '-Off',
+            '-Object', '-Noun', '-NoTypeInformation', '-NoQualifier', '-NoNewline', '-NoElement',
+            '-NoClobber', '-NewName', '-Newest', '-Namespace', '-Name', '-Month', '-Minutes', '-Minute',
+            '-Minimum', '-Milliseconds', '-Message', '-MemberType', '-Maximum', '-LogName', '-LiteralPath',
+            '-LiteralName', '-ListenerOption', '-List', '-Line', '-Leaf', '-Last', '-Key', '-ItemType',
+            '-IsValid', '-IsAbsolute', '-InputObject', '-IncludeEqual', '-IncludeChain', '-Include',
+            '-IgnoreWhiteSpace', '-Id', '-Hours', '-Hour', '-HideTableHeaders', '-Head', '-GroupBy',
+            '-Functionality', '-Full', '-Format', '-ForegroundColor', '-Force', '-First', '-FilterScript',
+            '-Filter', '-FilePath', '-Expression', '-ExpandProperty', '-Expand', '-ExecutionPolicy',
+            '-ExcludeProperty', '-ExcludeDifferent', '-Exclude', '-Exception', '-Examples', '-ErrorVariable',
+            '-ErrorRecord', '-ErrorId', '-ErrorAction', '-End', '-Encoding', '-DisplayName', '-DisplayHint',
+            '-DisplayError', '-DifferenceObject', '-Detailed', '-Destination', '-Description', '-Descending',
+            '-Depth', '-DependsOn', '-Delimiter', '-Debugger', '-Debug', '-Days', '-Day', '-Date',
+            '-CurrentOperation', '-Culture', '-Credential', '-Count', '-Container', '-Confirm',
+            '-ComputerName', '-Component', '-Completed', '-ComObject', '-CommandType', '-Command',
+            '-Column', '-Class', '-ChildPath', '-Character', '-Certificate', '-CategoryTargetType',
+            '-CategoryTargetName', '-CategoryReason', '-CategoryActivity', '-Category', '-CaseSensitive',
+            '-Body', '-BinaryPathName', '-Begin', '-BackgroundColor', '-Average', '-AutoSize', '-Audit',
+            '-AsString', '-AsSecureString', '-AsPlainText', '-As', '-ArgumentList', '-AppendPath', '-Append',
+            '-Adjust', '-Activity', '-AclObject'
+            ),
+        6 => array(
+            '_','args','DebugPreference','Error','ErrorActionPreference',
+            'foreach','Home','Host','Input','LASTEXITCODE','MaximumAliasCount',
+            'MaximumDriveCount','MaximumFunctionCount','MaximumHistoryCount',
+            'MaximumVariableCount','OFS','PsHome',
+            'ReportErrorShowExceptionClass','ReportErrorShowInnerException',
+            'ReportErrorShowSource','ReportErrorShowStackTrace',
+            'ShouldProcessPreference','ShouldProcessReturnPreference',
+            'StackTrace','VerbosePreference','WarningPreference','PWD'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '=', '<', '>', '@', '|', '&', ',', '?',
+        '+=', '-=', '*=', '/=', '%=', '*', '/', '%', '!', '+', '-', '++', '--'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #008080; font-weight: bold;',
+            2 => 'color: #008080; font-weight: bold;',
+            3 => 'color: #0000FF;',
+            4 => 'color: #FF0000;',
+            5 => 'color: #008080; font-style: italic;',
+            6 => 'color: #000080;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000;',
+            'MULTI' => 'color: #008000;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008080; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #800000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000;'
+            ),
+        'METHODS' => array(
+            0 => 'color: pink;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: pink;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #800080;',
+            3 => 'color: #008080;',
+            4 => 'color: #008080;',
+            5 => 'color: #800000;',
+            6 => 'color: #000080;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        // special after pipe
+        3 => array(
+            GESHI_SEARCH => '(\[)(int|long|string|char|bool|byte|double|decimal|float|single|regex|array|xml|scriptblock|switch|hashtable|type|ref|psobject|wmi|wmisearcher|wmiclass|object)((\[.*\])?\])',
+            GESHI_REPLACE => '\2',
+            GESHI_MODIFIERS => 'si',
+            GESHI_BEFORE => '\1',
+            GESHI_AFTER => '\3'
+            ),
+        // Classes
+        4 => array(
+            GESHI_SEARCH => '(\[)(System\.Reflection\.Assembly|System\.Net\.CredentialCache|Microsoft\.SharePoint\.SPFileLevel|Microsoft\.SharePoint\.Publishing\.PublishingWeb|Microsoft\.SharePoint\.Publishing|Microsoft\.SharePoint\.SPWeb)(\])',
+            GESHI_REPLACE => '\2',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '\1',
+            GESHI_AFTER => '\3'
+            ),
+        // Members
+        // There's about a hundred million of these, add the ones you need as you need them
+        5 => array (
+            GESHI_SEARCH => '(::)(ReflectionOnlyLoadFrom|ReflectionOnlyLoad|ReferenceEquals|LoadWithPartialName|LoadFrom|LoadFile|Load|GetExecutingAssembly|GetEntryAssembly|GetCallingAssembly|GetAssembly|Equals|DefaultNetworkCredentials|DefaultCredentials|CreateQualifiedName|Checkout|Draft|Published|IsPublishingWeb)',
+            GESHI_REPLACE => '\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\1',
+            GESHI_AFTER => ''
+            ),
+        // Special variables
+        6 => array(
+            GESHI_SEARCH => '(\$)(\$[_\^]?|\?)(?!\w)',
+            GESHI_REPLACE => '\1\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        // variables
+        //BenBE: Please note that changes here and in Keyword group 6 have to be synchronized in order to work properly.
+        //This Regexp must only match, if keyword group 6 doesn't. If this assumption fails
+        //Highlighting of the keywords will be incomplete or incorrect!
+        0 => "(?<!\\\$|>)[\\\$](?!(?:DebugPreference|Error(?:ActionPreference)?|".
+            "Ho(?:me|st)|Input|LASTEXITCODE|Maximum(?:AliasCount|DriveCount|".
+            "FunctionCount|HistoryCount|VariableCount)|OFS|P(?:WD|sHome)|".
+            "ReportErrorShow(?:ExceptionClass|InnerException|S(?:ource|".
+            "tackTrace))|S(?:houldProcess(?:Preference|ReturnPreference)|".
+            "tackTrace)|VerbosePreference|WarningPreference|_|args|foreach)\W)".
+            "(\w+)(?=[^|\w])",
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            6 => array(
+                'DISALLOWED_BEFORE' => '(?<!\$)\$'
+                )
+            )
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/progress.php b/examples/includes/geshi/geshi/progress.php
new file mode 100644 (file)
index 0000000..abd5bcb
--- /dev/null
@@ -0,0 +1,479 @@
+<?php
+/*************************************************************************************
+ * progress.php
+ * --------
+ * Author: Marco Aurelio de Pasqual (marcop@hdi.com.br)
+ * Copyright: (c) 2008 Marco Aurelio de Pasqual, Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/07/11
+ *
+ * Progress language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ *   -  First Release
+ *
+ * TODO (updated 2008/07/11)
+ * -------------------------
+ * * Clean up the keyword list
+ * * Sort Keyword lists by Control Structures, Predefined functions and other important keywords
+ * * Complete language support
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+    'LANG_NAME' => 'Progress',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array (
+        1 => array(
+            'ACCUMULATE','APPLY','ASSIGN','BELL','QUERY',
+            'BUFFER-COMPARE','BUFFER-COPY','CALL','CASE',
+            'CHOOSE','CLASS','CLEAR','CLOSE QUERY','each','WHERE',
+            'CLOSE STORED-PROCEDURE','COLOR','COMPILE','CONNECT',
+            'CONSTRUCTOR','COPY-LOB','CREATE','CREATE ALIAS',
+            'CREATE BROWSE','CREATE BUFFER','CREATE CALL','CREATE CLIENT-PRINCIPAL',
+            'CREATE DATABASE','CREATE DATASET','CREATE DATA-SOURCE','CREATE QUERY',
+            'CREATE SAX-attributeS','CREATE SAX-READER','CREATE SAX-WRITER','CREATE SERVER',
+            'CREATE SERVER-SOCKET','CREATE SOAP-HEADER','CREATE SOAP-HEADER-ENTRYREF','CREATE SOCKET',
+            'CREATE TEMP-TABLE','CREATE WIDGET','CREATE widget-POOL','CREATE X-DOCUMENT',
+            'CREATE X-NODEREF','CURRENT-LANGUAGE','CURRENT-VALUE','DDE ADVISE',
+            'DDE EXECUTE','DDE GET','DDE INITIATE','DDE REQUEST',
+            'DDE SEND','DDE TERMINATE','DEFINE BROWSE','DEFINE BUFFER','DEFINE',
+            'DEFINE BUTTON','DEFINE DATASET','DEFINE DATA-SOURCE','DEFINE FRAME','DEF','VAR',
+            'DEFINE IMAGE','DEFINE MENU','DEFINE PARAMETER','DEFINE property','PARAM',
+            'DEFINE QUERY','DEFINE RECTANGLE','DEFINE STREAM','DEFINE SUB-MENU',
+            'DEFINE TEMP-TABLE','DEFINE WORKFILE','DEFINE WORK-TABLE',
+            'DELETE','DELETE ALIAS','DELETE object','DELETE PROCEDURE',
+            'DELETE widget','DELETE widget-POOL','DESTRUCTOR','DICTIONARY',
+            'DISABLE','DISABLE TRIGGERS','DISCONNECT','DISPLAY',
+            'DO','DOS','DOWN','DYNAMIC-CURRENT-VALUE',
+            'ELSE','EMPTY TEMP-TABLE','ENABLE','END',
+            'ENTRY','EXPORT','FIND','AND',
+            'FIX-CODEPAGE','FOR','FORM','FRAME-VALUE',
+            'GET','GET-KEY-VALUE','HIDE','IF',
+            'IMPORT','INPUT CLEAR','INPUT CLOSE','INPUT FROM','input',
+            'INPUT THROUGH','INPUT-OUTPUT CLOSE','INPUT-OUTPUT THROUGH','INSERT',
+            'INTERFACE','LEAVE','LOAD','BREAK',
+            'LOAD-PICTURE','MESSAGE','method','NEXT','prev',
+            'NEXT-PROMPT','ON','OPEN QUERY','OS-APPEND',
+            'OS-COMMAND','OS-COPY','OS-CREATE-DIR','OS-DELETE',
+            'OS-RENAME','OUTPUT CLOSE','OUTPUT THROUGH','OUTPUT TO',
+            'OVERLAY','PAGE','PAUSE','PROCEDURE',
+            'PROCESS EVENTS','PROMPT-FOR','PROMSGS','PROPATH',
+            'PUBLISH','PUT','PUT CURSOR','PUT SCREEN',
+            'PUT-BITS','PUT-BYTE','PUT-BYTES','PUT-DOUBLE',
+            'PUT-FLOAT','PUT-INT64','PUT-KEY-VALUE','PUT-LONG',
+            'PUT-SHORT','PUT-STRING','PUT-UNSIGNED-LONG','PUT-UNSIGNED-SHORT',
+            'QUIT','RAW-TRANSFER','READKEY','RELEASE',
+            'RELEASE EXTERNAL','RELEASE object','REPEAT','REPOSITION',
+            'RUN','RUN STORED-PROCEDURE','RUN SUPER',
+            'SAVE CACHE','SCROLL','SEEK','SET',
+            'SET-BYTE-ORDER','SET-POINTER-VALUE','SET-SIZE','SHOW-STATS',
+            'STATUS','STOP','SUBSCRIBE','SUBSTRING',
+            'system-DIALOG COLOR','system-DIALOG FONT','system-DIALOG GET-DIR','system-DIALOG GET-FILE',
+            'system-DIALOG PRINTER-SETUP','system-HELP','THEN','THIS-object',
+            'TRANSACTION-MODE AUTOMATIC','TRIGGER PROCEDURE','UNDERLINE','UNDO',
+            'UNIX','UNLOAD','UNSUBSCRIBE','UP','STRING',
+            'UPDATE','USE','USING','VALIDATE','substr','SKIP','CLOSE',
+            'VIEW','WAIT-FOR','MODULO','NE','AVAIL',
+            'NOT','OR','&GLOBAL-DEFINE','&IF','UNFORMATTED','NO-PAUSE',
+            '&THEN','&ELSEIF','&ELSE','&ENDIF','OPEN','NO-WAIT',
+            '&MESSAGE','&SCOPED-DEFINE','&UNDEFINE','DEFINED',
+            'BROWSE','BUTTON','COMBO-BOX','CONTROL-FRAME',
+            'DIALOG-BOX','EDITOR','FIELD-GROUP','FILL-IN',
+            'FRAME','IMAGE','LITERAL','MENU',
+            'MENU-ITEM','RADIO-SET','RECTANGLE','SELECTION-LIST',
+            'SLIDER','SUB-MENU','TEXT','TOGGLE-BOX',
+            'WINDOW','WITH','AT','OF','EDITING','ON ENDKEY','output',
+            'ON ERROR','ON QUIT','ON STOP','PRESELECT',
+            'QUERY-TUNING','SIZE','Trigger','VIEW-AS','ALERT-BOX',
+            'Buffer','Data-relation','ProDataSet','SAX-attributes',
+            'SAX-reader','SAX-writer','Server socket','SOAP-fault',
+            'SOAP-header','SOAP-header-entryref','Socket','Temp-table',
+            'X-noderef','Height','Left','Top','TO',
+            'Width','ACTIVE-WINDOW','AUDIT-CONTROL','FIRST','LAST',
+            'AUDIT-POLICY','CLIPBOARD','CODEBASE-LOCATOR','COLOR-TABLE',
+            'COMPILER','COM-SELF','DEBUGGER','DEFAULT-WINDOW',
+            'ERROR-STATUS','FILE-INFO','FOCUS','FONT-TABLE',
+            'LAST-EVENT','LOG-MANAGER','RCODE-INFO','SECURITY-POLICY',
+            'SELF','SESSION','SOURCE-PROCEDURE','TARGET-PROCEDURE','NO-LOCK','NO-error',
+            'THIS-PROCEDURE','WEB-CONTEXT','FUNCTION','RETURNS','NO-UNDO'
+            ),
+        2 => array(
+            'ACCEPT-CHANGES','ACCEPT-ROW-CHANGES','ADD-BUFFER','ADD-CALC-COLUMN',
+            'ADD-COLUMNS-FROM','ADD-EVENTS-PROCEDURE','ADD-FIELDS-FROM','ADD-FIRST',
+            'ADD-HEADER-ENTRY','ADD-INDEX-FIELD','ADD-LAST','ADD-LIKE-COLUMN',
+            'ADD-LIKE-FIELD','ADD-LIKE-INDEX','ADD-NEW-FIELD','ADD-NEW-INDEX',
+            'ADD-RELATION','ADD-SCHEMA-LOCATION','ADD-SOURCE-BUFFER','ADD-SUPER-PROCEDURE',
+            'APPEND-CHILD','APPLY-CALLBACK','ATTACH-DATA-SOURCE','AUTHENTICATION-FAILED',
+            'BEGIN-EVENT-GROUP','BUFFER-COMPARE','BUFFER-COPY','BUFFER-CREATE',
+            'BUFFER-DELETE','BUFFER-FIELD','BUFFER-RELEASE','BUFFER-VALIDATE',
+            'CANCEL-BREAK','CANCEL-REQUESTS','CLEAR','CLEAR-APPL-CONTEXT',
+            'CLEAR-LOG','CLEAR-SELECTION','CLEAR-SORT-ARROWS','CLONE-NODE',
+            'CLOSE-LOG','CONNECT','CONNECTED','CONVERT-TO-OFFSET',
+            'COPY-DATASET','COPY-SAX-attributeS','COPY-TEMP-TABLE','CREATE-LIKE',
+            'CREATE-NODE','CREATE-NODE-NAMESPACE','CREATE-RESULT-LIST-ENTRY','DEBUG',
+            'DECLARE-NAMESPACE','DELETE-CHAR','DELETE-CURRENT-ROW',
+            'DELETE-HEADER-ENTRY','DELETE-LINE','DELETE-NODE','DELETE-RESULT-LIST-ENTRY',
+            'DELETE-SELECTED-ROW','DELETE-SELECTED-ROWS','DESELECT-FOCUSED-ROW','DESELECT-ROWS',
+            'DESELECT-SELECTED-ROW','DETACH-DATA-SOURCE','DISABLE','DISABLE-CONNECTIONS',
+            'DISABLE-DUMP-TRIGGERS','DISABLE-LOAD-TRIGGERS','DISCONNECT','DISPLAY-MESSAGE',
+            'DUMP-LOGGING-NOW','EDIT-CLEAR','EDIT-COPY','EDIT-CUT',
+            'EDIT-PASTE','EDIT-UNDO','EMPTY-DATASET','EMPTY-TEMP-TABLE',
+            'ENABLE','ENABLE-CONNECTIONS','ENABLE-EVENTS','ENCRYPT-AUDIT-MAC-KEY',
+            'END-DOCUMENT','END-ELEMENT','END-EVENT-GROUP','END-FILE-DROP',
+            'EXPORT','EXPORT-PRINCIPAL','FETCH-SELECTED-ROW',
+            'FILL','FIND-BY-ROWID','FIND-CURRENT','FIND-FIRST',
+            'FIND-LAST','FIND-UNIQUE','GET-attribute','GET-attribute-NODE',
+            'GET-BINARY-DATA','GET-BLUE-VALUE','GET-BROWSE-COLUMN','GET-BUFFER-HANDLE',
+            'GET-BYTES-AVAILABLE','GET-CALLBACK-PROC-CONTEXT','GET-CALLBACK-PROC-NAME','GET-CGI-LIST',
+            'GET-CGI-LONG-VALUE','GET-CGI-VALUE','GET-CHANGES','GET-CHILD',
+            'GET-CHILD-RELATION','GET-CONFIG-VALUE','GET-CURRENT','GET-DATASET-BUFFER',
+            'GET-DOCUMENT-ELEMENT','GET-DROPPED-FILE','GET-DYNAMIC','GET-ERROR-COLUMN ',
+            'GET-ERROR-ROW ','GET-FILE-NAME ','GET-FILE-OFFSET ','GET-FIRST',
+            'GET-GREEN-VALUE','GET-HEADER-ENTRY','GET-INDEX-BY-NAMESPACE-NAME','GET-INDEX-BY-QNAME',
+            'GET-ITERATION','GET-LAST','GET-LOCALNAME-BY-INDEX','GET-MESSAGE',
+            'GET-NEXT','GET-NODE','GET-NUMBER','GET-PARENT',
+            'GET-PREV','GET-PRINTERS','GET-property','GET-QNAME-BY-INDEX',
+            'GET-RED-VALUE','GET-RELATION','GET-REPOSITIONED-ROW','GET-RGB-VALUE',
+            'GET-SELECTED-widget','GET-SERIALIZED','GET-SIGNATURE','GET-SOCKET-OPTION',
+            'GET-SOURCE-BUFFER','GET-TAB-ITEM','GET-TEXT-HEIGHT-CHARS','GET-TEXT-HEIGHT-PIXELS',
+            'GET-TEXT-WIDTH-CHARS','GET-TEXT-WIDTH-PIXELS','GET-TOP-BUFFER','GET-TYPE-BY-INDEX',
+            'GET-TYPE-BY-NAMESPACE-NAME','GET-TYPE-BY-QNAME','GET-URI-BY-INDEX','GET-VALUE-BY-INDEX',
+            'GET-VALUE-BY-NAMESPACE-NAME','GET-VALUE-BY-QNAME','GET-WAIT-STATE','IMPORT-NODE',
+            'IMPORT-PRINCIPAL','INCREMENT-EXCLUSIVE-ID','INDEX-INFORMATION','INITIALIZE-DOCUMENT-TYPE',
+            'INITIATE','INSERT','INSERT-attribute','INSERT-BACKTAB',
+            'INSERT-BEFORE','INSERT-FILE','INSERT-ROW','INSERT-STRING',
+            'INSERT-TAB','INVOKE','IS-ROW-SELECTED','IS-SELECTED',
+            'LIST-property-NAMES','LOAD','LoadControls','LOAD-DOMAINS',
+            'LOAD-ICON','LOAD-IMAGE','LOAD-IMAGE-DOWN','LOAD-IMAGE-INSENSITIVE',
+            'LOAD-IMAGE-UP','LOAD-MOUSE-POINTER','LOAD-SMALL-ICON','LOCK-REGISTRATION',
+            'LOG-AUDIT-EVENT','LOGOUT','LONGCHAR-TO-NODE-VALUE','LOOKUP',
+            'MEMPTR-TO-NODE-VALUE','MERGE-CHANGES','MERGE-ROW-CHANGES','MOVE-AFTER-TAB-ITEM',
+            'MOVE-BEFORE-TAB-ITEM','MOVE-COLUMN','MOVE-TO-BOTTOM','MOVE-TO-EOF',
+            'MOVE-TO-TOP','NODE-VALUE-TO-LONGCHAR','NODE-VALUE-TO-MEMPTR','NORMALIZE',
+            'QUERY-CLOSE','QUERY-OPEN','QUERY-PREPARE','RAW-TRANSFER',
+            'READ','READ-FILE','READ-XML','READ-XMLSCHEMA',
+            'REFRESH','REFRESH-AUDIT-POLICY','REGISTER-DOMAIN','REJECT-CHANGES',
+            'REJECT-ROW-CHANGES','REMOVE-attribute','REMOVE-CHILD','REMOVE-EVENTS-PROCEDURE',
+            'REMOVE-SUPER-PROCEDURE','REPLACE','REPLACE-CHILD','REPLACE-SELECTION-TEXT',
+            'REPOSITION-BACKWARD','REPOSITION-FORWARD','REPOSITION-TO-ROW','REPOSITION-TO-ROWID',
+            'RESET','SAVE','SAVE-FILE','SAVE-ROW-CHANGES',
+            'SAX-PARSE','SAX-PARSE-FIRST','SAX-PARSE-NEXT','SCROLL-TO-CURRENT-ROW',
+            'SCROLL-TO-ITEM','SCROLL-TO-SELECTED-ROW','SEAL','SEARCH',
+            'SELECT-ALL','SELECT-FOCUSED-ROW','SELECT-NEXT-ROW','SELECT-PREV-ROW',
+            'SELECT-ROW','SET-ACTOR','SET-APPL-CONTEXT','SET-attribute',
+            'SET-attribute-NODE','SET-BLUE-VALUE','SET-BREAK','SET-BUFFERS',
+            'SET-CALLBACK','SET-CALLBACK-PROCEDURE','SET-CLIENT','SET-COMMIT',
+            'SET-CONNECT-PROCEDURE','SET-DYNAMIC','SET-GREEN-VALUE','SET-INPUT-SOURCE',
+            'SET-MUST-UNDERSTAND','SET-NODE','SET-NUMERIC-FORMAT','SET-OUTPUT-DESTINATION',
+            'SET-PARAMETER','SET-property','SET-READ-RESPONSE-PROCEDURE','SET-RED-VALUE',
+            'SET-REPOSITIONED-ROW','SET-RGB-VALUE','SET-ROLLBACK','SET-SELECTION',
+            'SET-SERIALIZED','SET-SOCKET-OPTION','SET-SORT-ARROW','SET-WAIT-STATE',
+            'START-DOCUMENT','START-ELEMENT','STOP-PARSING','SYNCHRONIZE',
+            'TEMP-TABLE-PREPARE','UPDATE-attribute','URL-DECODE','URL-ENCODE',
+            'VALIDATE','VALIDATE-SEAL','WRITE','WRITE-CDATA','USE-INDEX',
+            'WRITE-CHARACTERS','WRITE-COMMENT','WRITE-DATA-ELEMENT','WRITE-EMPTY-ELEMENT',
+            'WRITE-ENTITY-REF','WRITE-EXTERNAL-DTD','WRITE-FRAGMENT','WRITE-MESSAGE',
+            'WRITE-PROCESSING-INSTRUCTION','WRITE-XML','WRITE-XMLSCHEMA','FALSE','true'
+            ),
+        3 => array(
+            'ABSOLUTE','ACCUM','ADD-INTERVAL','ALIAS','mod',
+            'AMBIGUOUS','ASC','AUDIT-ENABLED','AVAILABLE',
+            'BASE64-DECODE','BASE64-ENCODE','CAN-DO','CAN-FIND',
+            'CAN-QUERY','CAN-SET','CAPS','CAST','OS-DIR',
+            'CHR','CODEPAGE-CONVERT','COMPARE','CONNECTED',
+            'COUNT-OF','CURRENT-CHANGED','CURRENT-RESULT-ROW','DATASERVERS',
+            'DATA-SOURCE-MODIFIED','DATETIME','DATETIME-TZ',
+            'DAY','DBCODEPAGE','DBCOLLATION','DBNAME',
+            'DBPARAM','DBRESTRICTIONS','DBTASKID','DBTYPE',
+            'DBVERSION','DECIMAL','DECRYPT','DYNAMIC-function',
+            'DYNAMIC-NEXT-VALUE','ENCODE','ENCRYPT','ENTERED',
+            'ERROR','ETIME','EXP','FILL','ENDKEY','END-error',
+            'FIRST-OF','FRAME-DB','FRAME-DOWN',
+            'FRAME-FIELD','FRAME-FILE','FRAME-INDEX','FRAME-LINE',
+            'GATEWAYS','GENERATE-PBE-KEY','GENERATE-PBE-SALT','GENERATE-RANDOM-KEY',
+            'GENERATE-UUID','GET-BITS','GET-BYTE','GET-BYTE-ORDER',
+            'GET-BYTES','GET-CODEPAGE','GET-CODEPAGES','GET-COLLATION',
+            'GET-COLLATIONS','GET-DOUBLE','GET-FLOAT','GET-INT64',
+            'GET-LONG','GET-POINTER-VALUE','GET-SHORT','GET-SIZE',
+            'GET-STRING','GET-UNSIGNED-LONG','GET-UNSIGNED-SHORT','GO-PENDING',
+            'GUID','HEX-DECODE','INDEX',
+            'INT64','INTEGER','INTERVAL','IS-ATTR-SPACE',
+            'IS-CODEPAGE-FIXED','IS-COLUMN-CODEPAGE','IS-LEAD-BYTE','ISO-DATE',
+            'KBLABEL','KEYCODE','KEYFUNCTION','KEYLABEL',
+            'KEYWORD','KEYWORD-ALL','LASTKEY',
+            'LAST-OF','LC','LDBNAME','LEFT-TRIM',
+            'LIBRARY','LINE-COUNTER','LIST-EVENTS','LIST-QUERY-ATTRS',
+            'LIST-SET-ATTRS','LIST-widgetS','LOCKED','LOG',
+            'LOGICAL','LOOKUP','MAXIMUM','MD5-DIGEST',
+            'MEMBER','MESSAGE-LINES','MINIMUM','MONTH',
+            'MTIME','NEW','NEXT-VALUE','NORMALIZE','SHARED',
+            'NOT ENTERED','NOW','NUM-ALIASES','NUM-DBS',
+            'NUM-ENTRIES','NUM-RESULTS','OPSYS','OS-DRIVES',
+            'OS-ERROR','OS-GETENV','PAGE-NUMBER','PAGE-SIZE',
+            'PDBNAME','PROC-HANDLE','PROC-STATUS','PROGRAM-NAME',
+            'PROGRESS','PROVERSION','QUERY-OFF-END','QUOTER',
+            'RANDOM','RAW','RECID','REJECTED',
+            'REPLACE','RETRY','RETURN-VALUE','RGB-VALUE',
+            'RIGHT-TRIM','R-INDEX','ROUND','ROWID','LENGTH',
+            'SDBNAME','SEARCH','SET-DB-CLIENT','SETUSERID',
+            'SHA1-DIGEST','SQRT','SUBSTITUTE','VARIABLE',
+            'SUPER','TERMINAL','TIME','TIMEZONE','external','ENTRY',
+            'TODAY','TO-ROWID','TRIM','TRUNCATE','return',
+            'TYPE-OF','USERID','VALID-EVENT','VALID-HANDLE',
+            'VALID-object','WEEKDAY','YEAR','BEGINS','VALUE',
+            'EQ','GE','GT','LE','LT','MATCHES','AS','BY','LIKE'
+            ),
+        4 => array(
+            'ACCELERATOR','ACTIVE','ACTOR','ADM-DATA',
+            'AFTER-BUFFER','AFTER-ROWID','AFTER-TABLE','ALLOW-COLUMN-SEARCHING',
+            'ALWAYS-ON-TOP','APPL-ALERT-BOXES','APPL-CONTEXT-ID','APPSERVER-INFO',
+            'APPSERVER-PASSWORD','APPSERVER-USERID','ASYNCHRONOUS','ASYNC-REQUEST-COUNT',
+            'ASYNC-REQUEST-HANDLE','ATTACHED-PAIRLIST','attribute-NAMES','ATTR-SPACE',
+            'AUDIT-EVENT-CONTEXT','AUTO-COMPLETION','AUTO-DELETE','AUTO-DELETE-XML',
+            'AUTO-END-KEY','AUTO-GO','AUTO-INDENT','AUTO-RESIZE',
+            'AUTO-RETURN','AUTO-SYNCHRONIZE','AUTO-VALIDATE','AUTO-ZAP',
+            'AVAILABLE-FORMATS','BACKGROUND','BASE-ADE','BASIC-LOGGING',
+            'BATCH-MODE','BATCH-SIZE','BEFORE-BUFFER','BEFORE-ROWID',
+            'BEFORE-TABLE','BGCOLOR','BLANK','BLOCK-ITERATION-DISPLAY',
+            'BORDER-BOTTOM-CHARS','BORDER-BOTTOM-PIXELS','BORDER-LEFT-CHARS','BORDER-LEFT-PIXELS',
+            'BORDER-RIGHT-CHARS','BORDER-RIGHT-PIXELS','BORDER-TOP-CHARS','BORDER-TOP-PIXELS',
+            'BOX','BOX-SELECTABLE','BUFFER-CHARS','BUFFER-FIELD',
+            'BUFFER-HANDLE','BUFFER-LINES','BUFFER-NAME','BUFFER-VALUE',
+            'BYTES-READ','BYTES-WRITTEN','CACHE','CALL-NAME',
+            'CALL-TYPE','CANCEL-BUTTON','CANCELLED','CAN-CREATE',
+            'CAN-DELETE','CAN-READ','CAN-WRITE','CAREFUL-PAINT',
+            'CASE-SENSITIVE','CENTERED','CHARSET','CHECKED',
+            'CHILD-BUFFER','CHILD-NUM','CLASS-TYPE','CLIENT-CONNECTION-ID',
+            'CLIENT-TTY','CLIENT-TYPE','CLIENT-WORKSTATION','CODE',
+            'CODEPAGE','COLUMN','COLUMN-BGCOLOR','COLUMN-DCOLOR',
+            'COLUMN-FGCOLOR','COLUMN-FONT','COLUMN-LABEL','COLUMN-MOVABLE',
+            'COLUMN-PFCOLOR','COLUMN-READ-ONLY','COLUMN-RESIZABLE','COLUMN-SCROLLING',
+            'COM-HANDLE','COMPLETE','CONFIG-NAME','CONTEXT-HELP',
+            'CONTEXT-HELP-FILE','CONTEXT-HELP-ID','CONTROL-BOX','CONVERT-3D-COLORS',
+            'CPCASE','CPCOLL','CPINTERNAL','CPLOG',
+            'CPPRINT','CPRCODEIN','CPRCODEOUT','CPSTREAM',
+            'CPTERM','CRC-VALUE','CURRENT-COLUMN','CURRENT-ENVIRONMENT',
+            'CURRENT-ITERATION','CURRENT-ROW-MODIFIED','CURRENT-WINDOW','CURSOR-CHAR',
+            'CURSOR-LINE','CURSOR-OFFSET','DATA-ENTRY-RETURN','DATASET',
+            'DATA-SOURCE','DATA-SOURCE-COMPLETE-MAP','DATA-TYPE','DATE-FORMAT',
+            'DB-REFERENCES','DCOLOR','DDE-ERROR','DDE-ID',
+            'DDE-ITEM','DDE-NAME','DDE-TOPIC','DEBLANK',
+            'DEBUG-ALERT','DECIMALS','DEFAULT','DEFAULT-BUFFER-HANDLE',
+            'DEFAULT-BUTTON','DEFAULT-COMMIT','DELIMITER','DISABLE-AUTO-ZAP',
+            'DISPLAY-TIMEZONE','DISPLAY-TYPE','DOMAIN-DESCRIPTION','DOMAIN-NAME',
+            'DOMAIN-TYPE','DRAG-ENABLED','DROP-TARGET','DYNAMIC',
+            'EDGE-CHARS','EDGE-PIXELS','EDIT-CAN-PASTE','EDIT-CAN-UNDO',
+            'EMPTY','ENCODING','ENCRYPTION-SALT','END-USER-PROMPT',
+            'ENTRY-TYPES-LIST','ERROR-COLUMN','ERROR-object-DETAIL','ERROR-ROW',
+            'ERROR-STRING','EVENT-GROUP-ID','EVENT-PROCEDURE','EVENT-PROCEDURE-CONTEXT',
+            'EVENT-TYPE','EXCLUSIVE-ID','EXECUTION-LOG','EXPAND',
+            'EXPANDABLE','FGCOLOR','FILE-CREATE-DATE','FILE-CREATE-TIME',
+            'FILE-MOD-DATE','FILE-MOD-TIME','FILE-NAME','FILE-OFFSET',
+            'FILE-SIZE','FILE-TYPE','FILLED','FILL-MODE',
+            'FILL-WHERE-STRING','FIRST-ASYNC-REQUEST','FIRST-BUFFER','FIRST-CHILD',
+            'FIRST-COLUMN','FIRST-DATASET','FIRST-DATA-SOURCE','FIRST-object',
+            'FIRST-PROCEDURE','FIRST-QUERY','FIRST-SERVER','FIRST-SERVER-SOCKET',
+            'FIRST-SOCKET','FIRST-TAB-ITEM','FIT-LAST-COLUMN','FLAT-BUTTON',
+            'FOCUSED-ROW','FOCUSED-ROW-SELECTED','FONT','FOREGROUND',
+            'FORMAT','FORMATTED','FORM-INPUT','FORM-LONG-INPUT',
+            'FORWARD-ONLY','FRAGMENT','FRAME-COL','FRAME-NAME',
+            'FRAME-ROW','FRAME-SPACING','FRAME-X','FRAME-Y',
+            'FREQUENCY','FULL-HEIGHT-CHARS','FULL-HEIGHT-PIXELS','FULL-PATHNAME',
+            'FULL-WIDTH-CHARS','FULL-WIDTH-PIXELS','GRAPHIC-EDGE',
+            'GRID-FACTOR-HORIZONTAL','GRID-FACTOR-VERTICAL','GRID-SNAP','GRID-UNIT-HEIGHT-CHARS',
+            'GRID-UNIT-HEIGHT-PIXELS','GRID-UNIT-WIDTH-CHARS','GRID-UNIT-WIDTH-PIXELS','GRID-VISIBLE',
+            'GROUP-BOX','HANDLE','HANDLER','HAS-LOBS',
+            'HAS-RECORDS','HEIGHT-CHARS','HEIGHT-PIXELS','HELP',
+            'HIDDEN','HORIZONTAL','HTML-CHARSET','HTML-END-OF-LINE',
+            'HTML-END-OF-PAGE','HTML-FRAME-BEGIN','HTML-FRAME-END','HTML-HEADER-BEGIN',
+            'HTML-HEADER-END','HTML-TITLE-BEGIN','HTML-TITLE-END','HWND',
+            'ICFPARAMETER','ICON','IGNORE-CURRENT-MODIFIED','IMAGE-DOWN',
+            'IMAGE-INSENSITIVE','IMAGE-UP','IMMEDIATE-DISPLAY','INDEX-INFORMATION',
+            'IN-HANDLE','INHERIT-BGCOLOR','INHERIT-FGCOLOR','INITIAL','INIT',
+            'INNER-CHARS','INNER-LINES','INPUT-VALUE','INSTANTIATING-PROCEDURE',
+            'INTERNAL-ENTRIES','IS-CLASS','IS-OPEN','IS-PARAMETER-SET',
+            'IS-XML','ITEMS-PER-ROW','KEEP-CONNECTION-OPEN','KEEP-FRAME-Z-ORDER',
+            'KEEP-SECURITY-CACHE','KEY','KEYS','LABEL',
+            'LABEL-BGCOLOR','LABEL-DCOLOR','LABEL-FGCOLOR','LABEL-FONT',
+            'LABELS','LANGUAGES','LARGE','LARGE-TO-SMALL',
+            'LAST-ASYNC-REQUEST','LAST-BATCH','LAST-CHILD','LAST-object',
+            'LAST-PROCEDURE','LAST-SERVER','LAST-SERVER-SOCKET','LAST-SOCKET',
+            'LAST-TAB-ITEM','LINE','LIST-ITEM-PAIRS','LIST-ITEMS',
+            'LITERAL-QUESTION','LOCAL-HOST','LOCAL-NAME','LOCAL-PORT',
+            'LOCATOR-COLUMN-NUMBER','LOCATOR-LINE-NUMBER','LOCATOR-PUBLIC-ID','LOCATOR-system-ID',
+            'LOCATOR-TYPE','LOG-ENTRY-TYPES','LOGFILE-NAME','LOGGING-LEVEL',
+            'LOGIN-EXPIRATION-TIMESTAMP','LOGIN-HOST','LOGIN-STATE','LOG-THRESHOLD',
+            'MANDATORY','MANUAL-HIGHLIGHT','MAX-BUTTON','MAX-CHARS',
+            'MAX-DATA-GUESS','MAX-HEIGHT-CHARS','MAX-HEIGHT-PIXELS','MAX-VALUE',
+            'MAX-WIDTH-CHARS','MAX-WIDTH-PIXELS','MD5-VALUE','MENU-BAR',
+            'MENU-KEY','MENU-MOUSE','MERGE-BY-FIELD','MESSAGE-AREA',
+            'MESSAGE-AREA-FONT','MIN-BUTTON','MIN-COLUMN-WIDTH-CHARS','MIN-COLUMN-WIDTH-PIXELS',
+            'MIN-HEIGHT-CHARS','MIN-HEIGHT-PIXELS','MIN-SCHEMA-MARSHAL','MIN-VALUE',
+            'MIN-WIDTH-CHARS','MIN-WIDTH-PIXELS','MODIFIED','MOUSE-POINTER',
+            'MOVABLE','MULTI-COMPILE','MULTIPLE','MULTITASKING-INTERVAL',
+            'MUST-UNDERSTAND','NAME','NAMESPACE-PREFIX','NAMESPACE-URI',
+            'NEEDS-APPSERVER-PROMPT','NEEDS-PROMPT','NESTED','NEW-ROW',
+            'NEXT-COLUMN','NEXT-ROWID','NEXT-SIBLING','NEXT-TAB-ITEM', 'NO-BOX',
+            'NO-CURRENT-VALUE','NODE-VALUE','NO-EMPTY-SPACE','NO-FOCUS',
+            'NONAMESPACE-SCHEMA-LOCATION','NO-SCHEMA-MARSHAL','NO-VALIDATE','NUM-BUFFERS',
+            'NUM-BUTTONS','NUM-CHILD-RELATIONS','NUM-CHILDREN','NUM-COLUMNS',
+            'NUM-DROPPED-FILES','NUMERIC-DECIMAL-POINT','NUMERIC-FORMAT','NUMERIC-SEPARATOR',
+            'NUM-FIELDS','NUM-FORMATS','NUM-HEADER-ENTRIES','NUM-ITEMS',
+            'NUM-ITERATIONS','NUM-LINES','NUM-LOCKED-COLUMNS','NUM-LOG-FILES',
+            'NUM-MESSAGES','NUM-PARAMETERS','NUM-REFERENCES','NUM-RELATIONS',
+            'NUM-REPLACED','NUM-SELECTED-ROWS','NUM-SELECTED-WIDGETS','NUM-SOURCE-BUFFERS',
+            'NUM-TABS','NUM-TOP-BUFFERS','NUM-TO-RETAIN','NUM-VISIBLE-COLUMNS',
+            'ON-FRAME-BORDER','ORIGIN-HANDLE','ORIGIN-ROWID','OWNER',
+            'OWNER-DOCUMENT','PAGE-BOTTOM','PAGE-TOP','PARAMETER',
+            'PARENT','PARENT-BUFFER','PARENT-RELATION','PARSE-STATUS',
+            'PASSWORD-FIELD','PATHNAME','PBE-HASH-ALGORITHM','PBE-KEY-ROUNDS',
+            'PERSISTENT','PERSISTENT-CACHE-DISABLED','PERSISTENT-PROCEDURE','PFCOLOR',
+            'PIXELS-PER-COLUMN','PIXELS-PER-ROW','POPUP-MENU','POPUP-ONLY',
+            'POSITION','PREFER-DATASET','PREPARED','PREPARE-STRING',
+            'PREV-COLUMN','PREV-SIBLING','PREV-TAB-ITEM','PRIMARY',
+            'PRINTER-CONTROL-HANDLE','PRINTER-HDC','PRINTER-NAME','PRINTER-PORT',
+            'PRIVATE-DATA','PROCEDURE-NAME','PROGRESS-SOURCE','PROXY',
+            'PROXY-PASSWORD','PROXY-USERID','PUBLIC-ID','PUBLISHED-EVENTS',
+            'RADIO-BUTTONS','READ-ONLY','RECORD-LENGTH',
+            'REFRESHABLE','RELATION-FIELDS','RELATIONS-ACTIVE','REMOTE',
+            'REMOTE-HOST','REMOTE-PORT','RESIZABLE','RESIZE',
+            'RESTART-ROWID','RETAIN-SHAPE','RETURN-INSERTED','RETURN-VALUE-DATA-TYPE',
+            'ROLES','ROUNDED','COL','ROW','ROW-HEIGHT-CHARS',
+            'ROW-HEIGHT-PIXELS','ROW-MARKERS','ROW-RESIZABLE','ROW-STATE',
+            'SAVE-WHERE-STRING','SCHEMA-CHANGE','SCHEMA-LOCATION','SCHEMA-MARSHAL',
+            'SCHEMA-PATH','SCREEN-LINES','SCREEN-VALUE','SCROLLABLE',
+            'SCROLLBAR-HORIZONTAL','SCROLL-BARS','SCROLLBAR-VERTICAL','SEAL-TIMESTAMP',
+            'SELECTABLE','SELECTED','SELECTION-END','SELECTION-START',
+            'SELECTION-TEXT','SENSITIVE','SEPARATOR-FGCOLOR','SEPARATORS',
+            'SERVER','SERVER-CONNECTION-BOUND','SERVER-CONNECTION-BOUND-REQUEST','SERVER-CONNECTION-CONTEXT',
+            'SERVER-CONNECTION-ID','SERVER-OPERATING-MODE','SESSION-END','SESSION-ID',
+            'SHOW-IN-TASKBAR','SIDE-LABEL-HANDLE','SIDE-LABELS','SKIP-DELETED-RECORD',
+            'SMALL-ICON','SMALL-TITLE','SOAP-FAULT-ACTOR','SOAP-FAULT-CODE',
+            'SOAP-FAULT-DETAIL','SOAP-FAULT-STRING','SORT','SORT-ASCENDING',
+            'SORT-NUMBER','SSL-SERVER-NAME','STANDALONE','STARTUP-PARAMETERS',
+            'STATE-DETAIL','STATUS-AREA','STATUS-AREA-FONT','STOPPED',
+            'STREAM','STRETCH-TO-FIT','STRICT','STRING-VALUE',
+            'SUBTYPE','SUPER-PROCEDURES','SUPPRESS-NAMESPACE-PROCESSING','SUPPRESS-WARNINGS',
+            'SYMMETRIC-ENCRYPTION-ALGORITHM','SYMMETRIC-ENCRYPTION-IV','SYMMETRIC-ENCRYPTION-KEY','SYMMETRIC-SUPPORT',
+            'system-ALERT-BOXES','system-ID','TABLE','TABLE-CRC-LIST',
+            'TABLE-HANDLE','TABLE-LIST','TABLE-NUMBER','TAB-POSITION',
+            'TAB-STOP','TEMP-DIRECTORY','TEXT-SELECTED','THREE-D',
+            'TIC-MARKS','TIME-SOURCE','TITLE','TITLE-BGCOLOR','FIELD',
+            'TITLE-DCOLOR','TITLE-FGCOLOR','TITLE-FONT','TOOLTIP',
+            'TOOLTIPS','TOP-ONLY','TRACKING-CHANGES','TRANSACTION',
+            'TRANS-INIT-PROCEDURE','TRANSPARENT','TYPE','UNIQUE-ID',
+            'UNIQUE-MATCH','URL','URL-PASSWORD','URL-USERID','EXTENT',
+            'USER-ID','V6DISPLAY','VALIDATE-EXPRESSION','VALIDATE-MESSAGE',
+            'VALIDATE-XML','VALIDATION-ENABLED','VIEW-FIRST-COLUMN-ON-REOPEN',
+            'VIRTUAL-HEIGHT-CHARS','VIRTUAL-HEIGHT-PIXELS','VIRTUAL-WIDTH-CHARS','VIRTUAL-WIDTH-PIXELS',
+            'VISIBLE','WARNING','WHERE-STRING','widget-ENTER','DATE',
+            'widget-LEAVE','WIDTH-CHARS','WIDTH-PIXELS','WINDOW-STATE',
+            'WINDOW-system','WORD-WRAP','WORK-AREA-HEIGHT-PIXELS','WORK-AREA-WIDTH-PIXELS',
+            'WORK-AREA-X','WORK-AREA-Y','WRITE-STATUS','X','widget-Handle',
+            'X-DOCUMENT','XML-DATA-TYPE','XML-NODE-TYPE','XML-SCHEMA-PATH',
+            'XML-SUPPRESS-NAMESPACE-PROCESSING','Y','YEAR-OFFSET','CHARACTER','INTEGER','LOGICAL',
+            'LONGCHAR','MEMPTR','DECIMAL','CHAR','DEC','INT','LOG','DECI','INTE','LOGI','long'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}',
+        '<', '>', '=',
+        '+', '-', '*', '/',
+        '!', '@', '%', '|', '$',
+        ':', '.', ';', ',',
+        '?', '<=','<>','>=', '\\'
+        ),
+    'CASE_SENSITIVE' => array (
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array (
+        'KEYWORDS' => array (
+            1 => 'color: #0000ff; font-weight: bold;',
+            2 => 'color: #1D16B2;',
+            3 => 'color: #993333;',
+            4 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array (
+//            1 => 'color: #808080; font-style: italic;',
+//            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array (
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array (
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array (
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array (
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array (
+            0 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array (
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array (
+            ),
+        'SCRIPT' => array (
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        0 => ':'
+        ),
+    'REGEXPS' => array (
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array (
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array (
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#&])",
+            'DISALLOWED_AFTER' =>  "(?![\-a-zA-Z0-9_%])"
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/prolog.php b/examples/includes/geshi/geshi/prolog.php
new file mode 100644 (file)
index 0000000..e3a07c1
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+/*************************************************************************************
+ * prolog.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/10/02
+ *
+ * Prolog language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/02 (1.0.8.1)
+ *  -  First Release
+ *
+ * TODO (updated 2008/10/02)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Prolog',
+    'COMMENT_SINGLE' => array(1 => '%'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array("\'"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'NUMBERS' =>
+        GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+    'KEYWORDS' => array(
+        1 => array(
+            'abolish','abs','arg','asserta','assertz','at_end_of_stream','atan',
+            'atom','atom_chars','atom_codes','atom_concat','atom_length',
+            'atomic','bagof','call','catch','ceiling','char_code',
+            'char_conversion','clause','close','compound','consult','copy_term',
+            'cos','current_char_conversion','current_input','current_op',
+            'current_output','current_predicate','current_prolog_flag',
+            'discontiguous','dynamic','ensure_loaded','exp','fail','findall',
+            'float','float_fractional_part','float_integer_part','floor',
+            'flush_output','functor','get_byte','get_char','get_code','halt',
+            'include','initialization','integer','is','listing','log','mod',
+            'multifile','nl','nonvar','notrace','number','number_chars',
+            'number_codes','once','op','open','peek_byte','peek_char',
+            'peek_code','put_byte','put_char','put_code','read','read_term',
+            'rem','repeat','retract','round','set_input','set_output',
+            'set_prolog_flag','set_stream_position','setof','sign','sin','sqrt',
+            'stream_property','sub_atom','throw','trace','true','truncate',
+            'unify_with_occurs_check','univ','var','write','write_canonical',
+            'write_term','writeq'
+            )
+        ),
+    'SYMBOLS' => array(
+        0 => array('(', ')', '[', ']', '{', '}',),
+        1 => array('?-', ':-', '=:='),
+        2 => array('\-', '\+', '\*', '\/'),
+        3 => array('-', '+', '*', '/'),
+        4 => array('.', ':', ',', ';'),
+        5 => array('!', '@', '&', '|'),
+        6 => array('<', '>', '=')
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #990000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;',
+            'HARD' => 'color: #0000ff;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #800080;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;',
+            1 => 'color: #339933;',
+            2 => 'color: #339933;',
+            3 => 'color: #339933;',
+            4 => 'color: #339933;',
+            5 => 'color: #339933;',
+            6 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #008080;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://pauillac.inria.fr/~deransar/prolog/bips.html'
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Variables
+        0 => "(?<![A-Z_])(?!(?:PIPE|SEMI)[^a-zA-Z0-9_])[A-Z_][a-zA-Z0-9_]*(?![a-zA-Z0-9_])"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/providex.php b/examples/includes/geshi/geshi/providex.php
new file mode 100644 (file)
index 0000000..d8b918e
--- /dev/null
@@ -0,0 +1,299 @@
+<?php
+/******************************************************************************
+ * providex.php
+ * ----------
+ * Author: Jeff Wilder (jeff@coastallogix.com)
+ * Copyright:  (c) 2008 Coastal Logix (http://www.coastallogix.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/10/18
+ *
+ * ProvideX language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/21 (1.0.0)
+ *  - First Release
+ *
+ * TODO
+ * -------------------------
+ * 1. Create a regexp for numeric global variables (ex: %VarName = 3)
+ * 2. Add standard object control properties
+ *
+ ******************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *****************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'ProvideX',
+    'COMMENT_SINGLE' => array(1 => '!'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(
+        // Single-Line Comments using REM command
+        2 => "/\bREM\b.*?$/i"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            // Directives
+            '*break', '*continue', '*end', '*escape', '*next', '*proceed',
+            '*retry', '*return', '*same', 'accept', 'add index', 'addr',
+            'auto', 'begin', 'break', 'button', 'bye', 'call', 'case',
+            'chart', 'check_box', 'class', 'clear', 'clip_board', 'close',
+            'continue', 'control', 'create required', 'create table',
+            'cwdir', 'data', 'day_format', 'def', 'default', 'defctl',
+            'defprt', 'deftty', 'delete required', 'dictionary', 'dim', 'direct',
+            'directory', 'disable', 'drop', 'drop_box', 'dump', 'edit',
+            'else', 'enable', 'end switch', 'end', 'end_if', 'endtrace',
+            'enter', 'erase', 'error_handler', 'escape', 'event', 'execute',
+            'exit', 'exitto', 'extract', 'file', 'find', 'floating point',
+            'for', 'function', 'get_file_box', 'gosub', 'goto', 'grid',
+            'h_scrollbar', 'hide', 'if', 'index', 'indexed', 'input',
+            'insert', 'invoke', 'iolist', 'keyed', 'let', 'like',
+            'line_switch', 'list', 'list_box', 'load', 'local', 'lock',
+            'long_form', 'menu_bar', 'merge', 'message_lib', 'mnemonic',
+            'msgbox', 'multi_line', 'multi_media', 'next', 'object', 'obtain',
+            'on', 'open', 'password', 'perform', 'pop', 'popup_menu',
+            'precision', 'prefix', 'preinput', 'print', 'process', 'program',
+            'property', 'purge', 'quit', 'radio_button', 'randomize',
+            'read', 'record', 'redim', 'refile', 'release', 'rem', 'remove',
+            'rename', 'renumber', 'repeat', 'reset', 'restore', 'retry',
+            'return', 'round', 'run', 'save', 'select', 'serial', 'server',
+            'set_focus', 'set_nbf', 'set_param', 'setctl', 'setday', 'setdev',
+            'setdrive', 'seterr', 'setesc', 'setfid', 'setmouse', 'settime',
+            'settrace', 'short_form', 'show', 'sort', 'start', 'static',
+            'step', 'stop', 'switch', 'system_help', 'system_jrnl', 'table',
+            'then', 'to', 'translate', 'tristate_box', 'unlock', 'until',
+            'update', 'user_lex', 'v_scrollbar', 'vardrop_box', 'varlist_box',
+            'via', 'video_palette', 'wait', 'wend', 'while', 'winprt_setup',
+            'with', 'write'
+            ),
+        2 => array(
+            // System Functions
+            '@x', '@y', 'abs', 'acs', 'and', 'arg', 'asc', 'asn', 'ath',
+            'atn', 'bin', 'bsz', 'chg', 'chr', 'cmp', 'cos', 'cpl',
+            'crc', 'cse', 'ctl', 'cvs', 'dec', 'dir', 'dll', 'dsk',
+            'dte', 'env', 'ept', 'err', 'evn', 'evs', 'exp', 'ffn',
+            'fib', 'fid', 'fin', 'fpt', 'gap', 'gbl', 'gep', 'hsa',
+            'hsh', 'hta', 'hwn', 'i3e', 'ind', 'int', 'iol', 'ior',
+            'jul', 'jst', 'kec', 'kef', 'kel', 'ken', 'kep', 'key',
+            'kgn', 'lcs', 'len', 'lno', 'log', 'lrc', 'lst', 'max',
+            'mem', 'mid', 'min', 'mnm', 'mod', 'msg', 'msk', 'mxc',
+            'mxl', 'new', 'not', 'nul', 'num', 'obj', 'opt', 'pad',
+            'pck', 'pfx', 'pgm', 'pos', 'prc', 'prm', 'pth', 'pub',
+            'rcd', 'rdx', 'rec', 'ref', 'rnd', 'rno', 'sep', 'sgn',
+            'sin', 'sqr', 'srt', 'ssz', 'stk', 'stp', 'str', 'sub',
+            'swp', 'sys', 'tan', 'tbl', 'tcb', 'tmr', 'trx', 'tsk',
+            'txh', 'txw', 'ucp', 'ucs', 'upk', 'vin', 'vis', 'xeq',
+            'xfa', 'xor', '_obj'
+            ),
+        3 => array(
+            // System Variables
+            // Vars that are duplicates of functions
+            // 'ctl', 'err', 'pfx', 'prm', 'rnd', 'sep', 'sys',
+            'bkg', 'chn', 'day', 'dlm', 'dsz', 'eom', 'ers', 'esc',
+            'gfn', 'gid', 'hfn', 'hlp', 'hwd', 'lfa', 'lfo', 'lip',
+            'lpg', 'lwd', 'mse', 'msl', 'nar', 'nid', 'pgn', 'psz',
+            'quo', 'ret', 'sid', 'ssn', 'tim', 'tme', 'tms', 'tsm',
+            'uid', 'unt', 'who'
+
+            ),
+        4 => array(
+            // Nomads Variables
+            '%Flmaint_Lib$', '%Flmaint_Msg$', '%Nomads_Activation_Ok',
+            '%Nomads_Auto_Qry', '%Nomads_Disable_Debug',
+            '%Nomads_Disable_Trace', '%Nomads_Fkey_Handler$',
+            '%Nomads_Fkey_Tbl$', '%Nomads_Notest', '%Nomads_Onexit$',
+            '%Nomads_Post_Display', '%Nomads_Pre_Display$',
+            '%Nomads_Process$', '%Nomads_Trace_File$',
+            '%Nomad_Actv_Folder_Colors$', '%Nomad_Automation_Enabled',
+            '%Nomad_Auto_Close', '%Nomad_Center_Wdw', '%Nomad_Concurrent_Wdw',
+            '%Nomad_Custom_Define', '%Nomad_Custom_Dir$',
+            '%Nomad_Custom_Genmtc', '%Nomad_Custom_Skip_Definition',
+            '%Nomad_Def_Sfx$', '%Nomad_Enter_Tab', '%Nomad_Esc_Sel',
+            '%Nomad_Isjavx', '%Nomad_Iswindx', '%Nomad_Iswindx$',
+            '%Nomad_Menu$', '%Nomad_Menu_Leftedge_Clr$',
+            '%Nomad_Menu_Textbackground_Clr$', '%Nomad_Mln_Sep$',
+            '%Nomad_Msgmnt$', '%Nomad_Noplusw', '%Nomad_No_Customize',
+            '%Nomad_Object_Persistence', '%Nomad_Object_Resize',
+            '%Nomad_Open_Load', '%Nomad_Override_Font$',
+            '%Nomad_Palette_Loaded', '%Nomad_Panel_Info_Force',
+            '%Nomad_Panel_Info_Prog$', '%Nomad_Pnl_Def_Colour$',
+            '%Nomad_Pnl_Def_Font$', '%Nomad_Prg_Cache', '%Nomad_Qry_Attr$',
+            '%Nomad_Qry_Btn$', '%Nomad_Qry_Clear_Start', '%Nomad_Qry_Tip$',
+            '%Nomad_Qry_Wide', '%Nomad_Query_Clear_Status', '%Nomad_Query_Kno',
+            '%Nomad_Query_No_Gray', '%Nomad_Query_Odb_Ignore',
+            '%Nomad_Query_Retkno', '%Nomad_Query_Sbar_Max',
+            '%Nomad_Relative_Wdw', '%Nomad_Save_Qry_Path', '%Nomad_Script_Fn',
+            '%Nomad_Script_Log', '%Nomad_Script_Wdw',
+            '%Nomad_Skip_Change_Logic', '%Nomad_Skip_Onselect_Logic',
+            '%Nomad_Stk$', '%Nomad_Tab_Dir', '%Nomad_Timeout',
+            '%Nomad_Turbo_Off', '%Nomad_Visual_Effect',
+            '%Nomad_Visual_Override', '%Nomad_Win_Ver', '%Nomad_Xchar',
+            '%Nomad_Xmax', '%Nomad_Ychar', '%Nomad_Ymax', '%Scr_Def_Attr$',
+            '%Scr_Def_H_Fl$', '%Scr_Def_H_Id$', '%Scr_Lib', '%Scr_Lib$',
+            '%Z__Usr_Sec$', 'Alternate_Panel$', 'Alternate_Panel_Type$',
+            'Arg_1$', 'Arg_10$', 'Arg_11$', 'Arg_12$', 'Arg_13$', 'Arg_14$',
+            'Arg_15$', 'Arg_16$', 'Arg_17$', 'Arg_18$', 'Arg_19$', 'Arg_2$',
+            'Arg_20$', 'Arg_3$', 'Arg_4$', 'Arg_5$', 'Arg_6$', 'Arg_7$',
+            'Arg_8$', 'Arg_9$', 'Change_Flg', 'Cmd_Str$', 'Default_Prog$',
+            'Disp_Cmd$', 'Entire_Record$', 'Exit_Cmd$', 'Fldr_Default_Prog$',
+            'Folder_Id$', 'Id', 'Id$', 'Ignore_Exit', 'Initialize_Flg',
+            'Init_Text$', 'Init_Val$', 'Main_Scrn_K$', 'Mnu_Ln$',
+            'Next_Folder', 'Next_Id', 'Next_Id$', 'No_Flush', 'Prime_Key$',
+            'Prior_Val', 'Prior_Val$', 'Qry_Val$', 'Refresh_Flg',
+            'Replacement_Folder$', 'Replacement_Lib$', 'Replacement_Scrn$',
+            'Scrn_Id$', 'Scrn_K$', 'Scrn_Lib$', 'Tab_Table$', '_Eom$'
+            ),
+        5 => array(
+            // Mnemonics
+            "'!w'", "'*c'", "'*h'", "'*i'", "'*o'", "'*r'", "'*x'",
+            "'+b'", "'+d'", "'+e'", "'+f'", "'+i'", "'+n'",
+            "'+p'", "'+s'", "'+t'", "'+u'", "'+v'", "'+w'", "'+x'",
+            "'+z'", "'-b'", "'-d'", "'-e'", "'-f'", "'-i'",
+            "'-n'", "'-p'", "'-s'", "'-t'", "'-u'", "'-v'", "'-w'",
+            "'-x'", "'-z'", "'2d'", "'3d'", "'4d'", "'@@'", "'ab'",
+            "'arc'", "'at'", "'backgr'", "'bb'", "'be'", "'beep'",
+            "'bg'", "'bi'", "'bj'", "'bk'", "'black'", "'blue'",
+            "'bm'", "'bo'", "'box'", "'br'", "'bs'", "'bt'", "'bu'",
+            "'bw'", "'bx'", "'caption'", "'ce'", "'cf'", "'ch'",
+            "'ci'", "'circle'", "'cl'", "'colour'", "'cp'", "'cpi'",
+            "'cr'", "'cs'", "'cursor'", "'cyan''_cyan'", "'dc'",
+            "'default'", "'df'", "'dialogue'", "'dn'", "'do'",
+            "'drop'", "'eb'", "'ee'", "'ef'", "'eg'", "'ei'", "'ej'",
+            "'el'", "'em'", "'eo'", "'ep'", "'er'", "'es'", "'et'",
+            "'eu'", "'ew'", "'ff'", "'fill'", "'fl'", "'font'",
+            "'frame'", "'gd'", "'ge'", "'gf'", "'goto'", "'green'",
+            "'gs'", "'hide'", "'ic'", "'image'", "'jc'",
+            "'jd'", "'jl'", "'jn'", "'jr'", "'js'", "'l6'", "'l8'",
+            "'lc'", "'ld'", "'lf'", "'li'", "'line'", "'lm'",
+            "'lpi'", "'lt'", "'magenta'", "'maxsize'", "'me'",
+            "'message'", "'minsize'", "'mn'", "'mode'",
+            "'move'", "'mp'", "'ms'", "'ni'", "'offset'", "'option'",
+            "'pe'", "'pen'", "'picture'", "'pie'", "'pm'", "'polygon'",
+            "'pop'", "'ps'", "'push'", "'rb'", "'rc'", "'rectangle'",
+            "'red'", "'rl'", "'rm'", "'rp'", "'rs'", "'rt'", "'sb'",
+            "'scroll'", "'sd'", "'se'", "'sf'", "'show'", "'size'",
+            "'sl'", "'sn'", "'sp'", "'sr'", "'swap'", "'sx'", "'text'",
+            "'textwdw'", "'tr'", "'tw'", "'uc'", "'up'", "'vt'", "'wa'",
+            "'wc'", "'wd'", "'wg'", "'white'", "'window'", "'wm'",
+            "'wp'", "'wr'", "'wrap'", "'ws'", "'wx'", "'xp'", "'yellow'",
+            "'zx'", "'_black'", "'_blue'", "'_colour'", "'_green'",
+            "'_magenta'", "'_red'", "'_white'", "'_yellow'"
+            ),
+        ),
+    'SYMBOLS' => array(
+        0 => array('+', '-', '*', '/', '^', '|'),
+        1 => array('++', '--', '+=', '-=', '*=', '/=', '^=', '|='),
+        2 => array('&lt;', '&gt;', '='),
+        3 => array('(', ')', '[', ']', '{', '}'),
+        4 => array(',', '@', ';', '\\')
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: navy;', // Directives
+            2 => 'color: blue;', // System Functions
+            3 => 'color: blue;', // System Variables
+            4 => 'color: #6A5ACD; font-style: italic;', // Nomads Global Variables
+            5 => 'color: #BDB76B;', // Mnemonics
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008080; font-style: italic;',
+            2 => 'color: #008080;',
+            'MULTI' => 'color: #008080; font-style: italic;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000066;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: green;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #00008B;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;',
+            1 => 'color: #000099;',
+            2 => 'color: #000099;',
+            3 => 'color: #0000C9;',
+            4 => 'color: #000099;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            1 => 'color: #006400; font-weight: bold',
+            2 => 'color: #6A5ACD;'
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.allbasic.info./wiki/index.php/PX:Directive_{FNAME}',
+        2 => 'http://www.allbasic.info./wiki/index.php/PX:System_function_{FNAME}',
+        3 => 'http://www.allbasic.info./wiki/index.php/PX:System_variable_{FNAME}',
+        4 => 'http://www.allbasic.info./wiki/index.php/PX:Nomads_{FNAME}',
+        5 => 'http://www.allbasic.info./wiki/index.php/PX:Mnemonic_{FNAMEU}'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => "'"
+        ),
+    'REGEXPS' => array(
+        1 => array(
+            // Line Labels
+            GESHI_SEARCH => '([[:space:]])([a-zA-Z_][a-zA-Z0-9_]+)(:)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+        2 => array(
+            // Global String Variables
+            GESHI_SEARCH => '(\%)([a-zA-Z_][a-zA-Z0-9_]+)(\$)',
+            GESHI_REPLACE => '\\1\\2\\3',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'NUMBERS' => GESHI_NEVER
+            )
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/python.php b/examples/includes/geshi/geshi/python.php
new file mode 100644 (file)
index 0000000..fbc6cab
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+/*************************************************************************************
+ * python.php
+ * ----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * Python language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/12/18
+ *  -  Added missing functions and keywords. Also added two new Python 3.0 types. SF#2441839
+ * 2005/05/26
+ *  -  Modifications by Tim (tim@skreak.com): added more keyword categories, tweaked colors
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Python',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    //Longest quotemarks ALWAYS first
+    'QUOTEMARKS' => array('"""', '"', "'"),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+
+        /*
+        ** Set 1: reserved words
+        ** http://python.org/doc/current/ref/keywords.html
+        */
+        1 => array(
+            'and', 'del', 'for', 'is', 'raise', 'assert', 'elif', 'from', 'lambda', 'return', 'break',
+            'else', 'global', 'not', 'try', 'class', 'except', 'if', 'or', 'while', 'continue', 'exec',
+            'import', 'pass', 'yield', 'def', 'finally', 'in', 'print', 'with', 'as'
+            ),
+
+        /*
+        ** Set 2: builtins
+        ** http://python.org/doc/current/lib/built-in-funcs.html
+        */
+        2 => array(
+            '__import__', 'abs', 'basestring', 'bool', 'callable', 'chr', 'classmethod', 'cmp',
+            'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile',
+            'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help',
+            'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'list', 'locals',
+            'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'range',
+            'raw_input', 'reduce', 'reload', 'reversed', 'round', 'set', 'setattr', 'slice',
+            'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode',
+            'vars', 'xrange', 'zip',
+            // Built-in constants: http://python.org/doc/current/lib/node35.html
+            'False', 'True', 'None', 'NotImplemented', 'Ellipsis',
+            // Built-in Exceptions: http://python.org/doc/current/lib/module-exceptions.html
+            'Exception', 'StandardError', 'ArithmeticError', 'LookupError', 'EnvironmentError',
+            'AssertionError', 'AttributeError', 'EOFError', 'FloatingPointError', 'IOError',
+            'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'MemoryError', 'NameError',
+            'NotImplementedError', 'OSError', 'OverflowError', 'ReferenceError', 'RuntimeError',
+            'StopIteration', 'SyntaxError', 'SystemError', 'SystemExit', 'TypeError',
+            'UnboundlocalError', 'UnicodeError', 'UnicodeEncodeError', 'UnicodeDecodeError',
+            'UnicodeTranslateError', 'ValueError', 'WindowsError', 'ZeroDivisionError', 'Warning',
+            'UserWarning', 'DeprecationWarning', 'PendingDeprecationWarning', 'SyntaxWarning',
+            'RuntimeWarning', 'FutureWarning',
+            // self: this is a common python convention (but not a reserved word)
+            'self',
+            // other
+            'any', 'all'
+            ),
+
+        /*
+        ** Set 3: standard library
+        ** http://python.org/doc/current/lib/modindex.html
+        */
+        3 => array(
+            '__builtin__', '__future__', '__main__', '_winreg', 'aifc', 'AL', 'al', 'anydbm',
+            'array', 'asynchat', 'asyncore', 'atexit', 'audioop', 'base64', 'BaseHTTPServer',
+            'Bastion', 'binascii', 'binhex', 'bisect', 'bsddb', 'bz2', 'calendar', 'cd', 'cgi',
+            'CGIHTTPServer', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop',
+            'collections', 'colorsys', 'commands', 'compileall', 'compiler',
+            'ConfigParser', 'Cookie', 'cookielib', 'copy', 'copy_reg', 'cPickle', 'crypt',
+            'cStringIO', 'csv', 'curses', 'datetime', 'dbhash', 'dbm', 'decimal', 'DEVICE',
+            'difflib', 'dircache', 'dis', 'distutils', 'dl', 'doctest', 'DocXMLRPCServer', 'dumbdbm',
+            'dummy_thread', 'dummy_threading', 'email', 'encodings', 'errno', 'exceptions', 'fcntl',
+            'filecmp', 'fileinput', 'FL', 'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl',
+            'fpformat', 'ftplib', 'gc', 'gdbm', 'getopt', 'getpass', 'gettext', 'GL', 'gl', 'glob',
+            'gopherlib', 'grp', 'gzip', 'heapq', 'hmac', 'hotshot', 'htmlentitydefs', 'htmllib',
+            'HTMLParser', 'httplib', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp', 'inspect',
+            'itertools', 'jpeg', 'keyword', 'linecache', 'locale', 'logging', 'mailbox', 'mailcap',
+            'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'MimeWriter', 'mimify',
+            'mmap', 'msvcrt', 'multifile', 'mutex', 'netrc', 'new', 'nis', 'nntplib', 'operator',
+            'optparse', 'os', 'ossaudiodev', 'parser', 'pdb', 'pickle', 'pickletools', 'pipes',
+            'pkgutil', 'platform', 'popen2', 'poplib', 'posix', 'posixfile', 'pprint', 'profile',
+            'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'Queue', 'quopri', 'random',
+            're', 'readline', 'repr', 'resource', 'rexec', 'rfc822', 'rgbimg', 'rlcompleter',
+            'robotparser', 'sched', 'ScrolledText', 'select', 'sets', 'sgmllib', 'sha', 'shelve',
+            'shlex', 'shutil', 'signal', 'SimpleHTTPServer', 'SimpleXMLRPCServer', 'site', 'smtpd',
+            'smtplib', 'sndhdr', 'socket', 'SocketServer', 'stat', 'statcache', 'statvfs', 'string',
+            'StringIO', 'stringprep', 'struct', 'subprocess', 'sunau', 'SUNAUDIODEV', 'sunaudiodev',
+            'symbol', 'sys', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios',
+            'test', 'textwrap', 'thread', 'threading', 'time', 'timeit', 'Tix', 'Tkinter', 'token',
+            'tokenize', 'traceback', 'tty', 'turtle', 'types', 'unicodedata', 'unittest', 'urllib2',
+            'urllib', 'urlparse', 'user', 'UserDict', 'UserList', 'UserString', 'uu', 'warnings',
+            'wave', 'weakref', 'webbrowser', 'whichdb', 'whrandom', 'winsound', 'xdrlib', 'xml',
+            'xmllib', 'xmlrpclib', 'zipfile', 'zipimport', 'zlib',
+            // Python 3.0
+            'bytes', 'bytearray'
+            ),
+
+        /*
+        ** Set 4: special methods
+        ** http://python.org/doc/current/ref/specialnames.html
+        */
+        4 => array(
+            /*
+            // Iterator types: http://python.org/doc/current/lib/typeiter.html
+            '__iter__', 'next',
+            // String types: http://python.org/doc/current/lib/string-methods.html
+            'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
+            'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle',
+            'isupper', 'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust',
+            'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
+            'translate', 'upper', 'zfill',
+            */
+            // Basic customization: http://python.org/doc/current/ref/customization.html
+            '__new__', '__init__', '__del__', '__repr__', '__str__',
+            '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__cmp__', '__rcmp__',
+            '__hash__', '__nonzero__', '__unicode__', '__dict__',
+            // Attribute access: http://python.org/doc/current/ref/attribute-access.html
+            '__setattr__', '__delattr__', '__getattr__', '__getattribute__', '__get__', '__set__',
+            '__delete__', '__slots__',
+            // Class creation, callable objects
+            '__metaclass__', '__call__',
+            // Container types: http://python.org/doc/current/ref/sequence-types.html
+            '__len__', '__getitem__', '__setitem__', '__delitem__', '__iter__', '__contains__',
+            '__getslice__', '__setslice__', '__delslice__',
+            // Numeric types: http://python.org/doc/current/ref/numeric-types.html
+            '__abs__','__add__','__and__','__coerce__','__div__','__divmod__','__float__',
+            '__hex__','__iadd__','__isub__','__imod__','__idiv__','__ipow__','__iand__',
+            '__ior__','__ixor__', '__ilshift__','__irshift__','__invert__','__int__',
+            '__long__','__lshift__',
+            '__mod__','__mul__','__neg__','__oct__','__or__','__pos__','__pow__',
+            '__radd__','__rdiv__','__rdivmod__','__rmod__','__rpow__','__rlshift__','__rrshift__',
+            '__rshift__','__rsub__','__rmul__','__rand__','__rxor__','__ror__',
+            '__sub__','__xor__'
+            )
+        ),
+    'SYMBOLS' => array(
+            '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?', '`'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #ff7700;font-weight:bold;',    // Reserved
+            2 => 'color: #008000;',                        // Built-ins + self
+            3 => 'color: #dc143c;',                        // Standard lib
+            4 => 'color: #0000cd;'                        // Special methods
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: black;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #483d8b;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff4500;'
+            ),
+        'METHODS' => array(
+            1 => 'color: black;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/qbasic.php b/examples/includes/geshi/geshi/qbasic.php
new file mode 100644 (file)
index 0000000..f6531f7
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+/*************************************************************************************
+ * qbasic.php
+ * ----------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/20
+ *
+ * QBasic/QuickBASIC language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.3)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ *   -  Added support for URLs
+ * 2004/08/05 (1.0.1)
+ *   -  Added support for symbols
+ *   -  Removed unnessecary slashes from some keywords
+ * 2004/07/14 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Make sure all possible combinations of keywords with
+ *   a space in them (EXIT FOR, END SELECT) are added
+ *   to the first keyword group
+ * * Update colours, especially for the first keyword group
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'QBasic/QuickBASIC',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        //Single-Line Comments using REM command
+        2 => "/\bREM.*?$/i"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'DO', 'LOOP', 'WHILE', 'WEND', 'THEN', 'ELSE', 'ELSEIF', 'IF',
+            'FOR', 'TO', 'NEXT', 'STEP', 'GOTO', 'GOSUB', 'CALL', 'CALLS',
+            'SUB', 'FUNCTION', 'RETURN', 'RESUME', 'SELECT', 'CASE', 'UNTIL'
+            ),
+        3 => array(
+            'ABS', 'ABSOLUTE', 'ACCESS', 'ALIAS', 'AND', 'ANY', 'APPEND', 'AS', 'ASC', 'ATN',
+            'BASE', 'BEEP', 'BINARY', 'BLOAD', 'BSAVE', 'BYVAL',
+            'CDBL', 'CDECL', 'CHAIN', 'CHDIR', 'CHR$', 'CINT', 'CIRCLE', 'CLEAR',
+            'CLNG', 'CLOSE', 'CLS', 'COM', 'COMMAND$', 'COMMON', 'CONST', 'COS', 'CSNG',
+            'CSRLIN', 'CVD', 'CVDMBF', 'CVI', 'CVL', 'CVS', 'CVSMDF', 'DATA', 'DATE$',
+            'DECLARE', 'DEF', 'FN', 'SEG', 'DEFDBL', 'DEFINT', 'DEFLNG', 'DEFSNG', 'DEFSTR',
+            'DIM', 'DOUBLE', 'DRAW', 'END', 'ENVIRON', 'ENVIRON$', 'EOF', 'EQV', 'ERASE',
+            'ERDEV', 'ERDEV$', 'ERL', 'ERR', 'ERROR', 'EXIT', 'EXP', 'FIELD', 'FILEATTR',
+            'FILES', 'FIX', 'FRE', 'FREEFILE', 'GET', 'HEX$', 'IMP', 'INKEY$',
+            'INP', 'INPUT', 'INPUT$', 'INSTR', 'INT', 'INTEGER', 'IOCTL', 'IOCTL$', 'IS',
+            'KEY', 'KILL', 'LBOUND', 'LCASE$', 'LEFT$', 'LEN', 'LET', 'LINE', 'LIST', 'LOC',
+            'LOCAL', 'LOCATE', 'LOCK', 'LOF', 'LOG', 'LONG', 'LPOS', 'LPRINT',
+            'LSET', 'LTRIM$', 'MID$', 'MKD$', 'MKDIR', 'MKDMBF$', 'MKI$', 'MKL$',
+            'MKS$', 'MKSMBF$', 'MOD', 'NAME', 'NOT', 'OCT$', 'OFF', 'ON', 'PEN', 'PLAY',
+            'OPEN', 'OPTION', 'OR', 'OUT', 'OUTPUT',
+            'PAINT', 'PALETTE', 'PCOPY', 'PEEK', 'PMAP', 'POINT', 'POKE', 'POS', 'PRESET',
+            'PRINT', 'PSET', 'PUT', 'RANDOM', 'RANDOMIZE', 'READ', 'REDIM', 'RESET',
+            'RESTORE', 'RIGHT$', 'RMDIR', 'RND', 'RSET', 'RTRIM$', 'RUN', 'SADD', 'SCREEN',
+            'SEEK', 'SETMEM', 'SGN', 'SHARED', 'SHELL', 'SIGNAL', 'SIN', 'SINGLE', 'SLEEP',
+            'SOUND', 'SPACE$', 'SPC', 'SQR', 'STATIC', 'STICK', 'STOP', 'STR$', 'STRIG',
+            'STRING', 'STRING$', 'SWAP', 'SYSTEM', 'TAB', 'TAN', 'TIME$', 'TIMER',
+            'TROFF', 'TRON', 'TYPE', 'UBOUND', 'UCASE$', 'UEVENT', 'UNLOCK', 'USING', 'VAL',
+            'VARPTR', 'VARPTR$', 'VARSEG', 'VIEW', 'WAIT', 'WIDTH', 'WINDOW', 'WRITE', 'XOR'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', ',', '+', '-', '*', '/', '=', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #a1a100;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080;',
+            2 => 'color: #808080;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        3 => 'http://www.qbasicnews.com/qboho/qck{FNAMEL}.shtml'
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 8
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/rails.php b/examples/includes/geshi/geshi/rails.php
new file mode 100644 (file)
index 0000000..52c70a6
--- /dev/null
@@ -0,0 +1,406 @@
+<?php
+/*************************************************************************************
+ * rails.php
+ * ---------
+ * Author: Moises Deniz
+ * Copyright: (c) 2005 Moises Deniz
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/03/21
+ *
+ * Ruby (with Ruby on Rails Framework) language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Rails',
+    'COMMENT_SINGLE' => array(1 => "#"),
+    'COMMENT_MULTI' => array("=begin" => "=end"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', '`','\''),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'alias', 'and', 'begin', 'break', 'case', 'class',
+            'def', 'defined', 'do', 'else', 'elsif', 'end',
+            'ensure', 'for', 'if', 'in', 'module', 'while',
+            'next', 'not', 'or', 'redo', 'rescue', 'yield',
+            'retry', 'super', 'then', 'undef', 'unless',
+            'until', 'when', 'BEGIN', 'END', 'include'
+            ),
+        2 => array(
+            '__FILE__', '__LINE__', 'false', 'nil', 'self', 'true',
+            'return'
+            ),
+        3 => array(
+            'Array', 'Float', 'Integer', 'String', 'at_exit',
+            'autoload', 'binding', 'caller', 'catch', 'chop', 'chop!',
+            'chomp', 'chomp!', 'eval', 'exec', 'exit', 'exit!', 'fail',
+            'fork', 'format', 'gets', 'global_variables', 'gsub', 'gsub!',
+            'iterator?', 'lambda', 'load', 'local_variables', 'loop',
+            'open', 'p', 'print', 'printf', 'proc', 'putc', 'puts',
+            'raise', 'rand', 'readline', 'readlines', 'require', 'select',
+            'sleep', 'split', 'sprintf', 'srand', 'sub', 'sub!', 'syscall',
+            'system', 'trace_var', 'trap', 'untrace_var'
+            ),
+        4 => array(
+            'Abbrev', 'ArgumentError', 'Base64', 'Benchmark',
+            'Benchmark::Tms', 'Bignum', 'Binding', 'CGI', 'CGI::Cookie',
+            'CGI::HtmlExtension', 'CGI::QueryExtension',
+            'CGI::Session', 'CGI::Session::FileStore',
+            'CGI::Session::MemoryStore', 'Class', 'Comparable', 'Complex',
+            'ConditionVariable', 'Continuation', 'Data',
+            'Date', 'DateTime', 'Delegator', 'Dir', 'EOFError', 'ERB',
+            'ERB::Util', 'Enumerable', 'Enumerable::Enumerator', 'Errno',
+            'Exception', 'FalseClass', 'File',
+            'File::Constants', 'File::Stat', 'FileTest', 'FileUtils',
+            'FileUtils::DryRun', 'FileUtils::NoWrite',
+            'FileUtils::StreamUtils_', 'FileUtils::Verbose', 'Find',
+            'Fixnum', 'FloatDomainError', 'Forwardable', 'GC', 'Generator',
+            'Hash', 'IO', 'IOError', 'Iconv', 'Iconv::BrokenLibrary',
+            'Iconv::Failure', 'Iconv::IllegalSequence',
+            'Iconv::InvalidCharacter', 'Iconv::InvalidEncoding',
+            'Iconv::OutOfRange', 'IndexError', 'Interrupt', 'Kernel',
+            'LoadError', 'LocalJumpError', 'Logger', 'Logger::Application',
+            'Logger::Error', 'Logger::Formatter', 'Logger::LogDevice',
+            'Logger::LogDevice::LogDeviceMutex', 'Logger::Severity',
+            'Logger::ShiftingError', 'Marshal', 'MatchData',
+            'Math', 'Matrix', 'Method', 'Module', 'Mutex', 'NameError',
+            'NameError::message', 'NilClass', 'NoMemoryError',
+            'NoMethodError', 'NotImplementedError', 'Numeric', 'Object',
+            'ObjectSpace', 'Observable', 'PStore', 'PStore::Error',
+            'Pathname', 'Precision', 'Proc', 'Process', 'Process::GID',
+            'Process::Status', 'Process::Sys', 'Process::UID', 'Queue',
+            'Range', 'RangeError', 'Rational', 'Regexp', 'RegexpError',
+            'RuntimeError', 'ScriptError', 'SecurityError', 'Set',
+            'Shellwords', 'Signal', 'SignalException', 'SimpleDelegator',
+            'SingleForwardable', 'Singleton', 'SingletonClassMethods',
+            'SizedQueue', 'SortedSet', 'StandardError', 'StringIO',
+            'StringScanner', 'StringScanner::Error', 'Struct', 'Symbol',
+            'SyncEnumerator', 'SyntaxError', 'SystemCallError',
+            'SystemExit', 'SystemStackError', 'Tempfile',
+            'Test::Unit::TestCase', 'Test::Unit', 'Test', 'Thread',
+            'ThreadError', 'ThreadGroup',
+            'ThreadsWait', 'Time', 'TrueClass', 'TypeError', 'URI',
+            'URI::BadURIError', 'URI::Error', 'URI::Escape', 'URI::FTP',
+            'URI::Generic', 'URI::HTTP', 'URI::HTTPS',
+            'URI::InvalidComponentError', 'URI::InvalidURIError',
+            'URI::LDAP', 'URI::MailTo', 'URI::REGEXP',
+            'URI::REGEXP::PATTERN', 'UnboundMethod', 'Vector', 'YAML',
+            'ZeroDivisionError', 'Zlib',
+            'Zlib::BufError', 'Zlib::DataError', 'Zlib::Deflate',
+            'Zlib::Error', 'Zlib::GzipFile', 'Zlib::GzipFile::CRCError',
+            'Zlib::GzipFile::Error', 'Zlib::GzipFile::LengthError',
+            'Zlib::GzipFile::NoFooter', 'Zlib::GzipReader',
+            'Zlib::GzipWriter', 'Zlib::Inflate', 'Zlib::MemError',
+            'Zlib::NeedDict', 'Zlib::StreamEnd', 'Zlib::StreamError',
+            'Zlib::VersionError',
+            'Zlib::ZStream',
+            'ActionController::AbstractRequest',
+            'ActionController::Assertions::DomAssertions',
+            'ActionController::Assertions::ModelAssertions',
+            'ActionController::Assertions::ResponseAssertions',
+            'ActionController::Assertions::RoutingAssertions',
+            'ActionController::Assertions::SelectorAssertions',
+            'ActionController::Assertions::TagAssertions',
+            'ActionController::Base',
+            'ActionController::Benchmarking::ClassMethods',
+            'ActionController::Caching',
+            'ActionController::Caching::Actions',
+            'ActionController::Caching::Actions::ActionCachePath',
+            'ActionController::Caching::Fragments',
+            'ActionController::Caching::Pages',
+            'ActionController::Caching::Pages::ClassMethods',
+            'ActionController::Caching::Sweeping',
+            'ActionController::Components',
+            'ActionController::Components::ClassMethods',
+            'ActionController::Components::InstanceMethods',
+            'ActionController::Cookies',
+            'ActionController::Filters::ClassMethods',
+            'ActionController::Flash',
+            'ActionController::Flash::FlashHash',
+            'ActionController::Helpers::ClassMethods',
+            'ActionController::Integration::Session',
+            'ActionController::IntegrationTest',
+            'ActionController::Layout::ClassMethods',
+            'ActionController::Macros',
+            'ActionController::Macros::AutoComplete::ClassMethods',
+            'ActionController::Macros::InPlaceEditing::ClassMethods',
+            'ActionController::MimeResponds::InstanceMethods',
+            'ActionController::Pagination',
+            'ActionController::Pagination::ClassMethods',
+            'ActionController::Pagination::Paginator',
+            'ActionController::Pagination::Paginator::Page',
+            'ActionController::Pagination::Paginator::Window',
+            'ActionController::Rescue', 'ActionController::Resources',
+            'ActionController::Routing',
+            'ActionController::Scaffolding::ClassMethods',
+            'ActionController::SessionManagement::ClassMethods',
+            'ActionController::Streaming', 'ActionController::TestProcess',
+            'ActionController::TestUploadedFile',
+            'ActionController::UrlWriter',
+            'ActionController::Verification::ClassMethods',
+            'ActionMailer::Base', 'ActionView::Base',
+            'ActionView::Helpers::ActiveRecordHelper',
+            'ActionView::Helpers::AssetTagHelper',
+            'ActionView::Helpers::BenchmarkHelper',
+            'ActionView::Helpers::CacheHelper',
+            'ActionView::Helpers::CaptureHelper',
+            'ActionView::Helpers::DateHelper',
+            'ActionView::Helpers::DebugHelper',
+            'ActionView::Helpers::FormHelper',
+            'ActionView::Helpers::FormOptionsHelper',
+            'ActionView::Helpers::FormTagHelper',
+            'ActionView::Helpers::JavaScriptHelper',
+            'ActionView::Helpers::JavaScriptMacrosHelper',
+            'ActionView::Helpers::NumberHelper',
+            'ActionView::Helpers::PaginationHelper',
+            'ActionView::Helpers::PrototypeHelper',
+            'ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods',
+            'ActionView::Helpers::ScriptaculousHelper',
+            'ActionView::Helpers::TagHelper',
+            'ActionView::Helpers::TextHelper',
+            'ActionView::Helpers::UrlHelper', 'ActionView::Partials',
+            'ActionWebService::API::Method', 'ActionWebService::Base',
+            'ActionWebService::Client::Soap',
+            'ActionWebService::Client::XmlRpc',
+            'ActionWebService::Container::ActionController::ClassMethods',
+            'ActionWebService::Container::Delegated::ClassMethods',
+            'ActionWebService::Container::Direct::ClassMethods',
+            'ActionWebService::Invocation::ClassMethods',
+            'ActionWebService::Scaffolding::ClassMethods',
+            'ActionWebService::SignatureTypes', 'ActionWebService::Struct',
+            'ActiveRecord::Acts::List::ClassMethods',
+            'ActiveRecord::Acts::List::InstanceMethods',
+            'ActiveRecord::Acts::NestedSet::ClassMethods',
+            'ActiveRecord::Acts::NestedSet::InstanceMethods',
+            'ActiveRecord::Acts::Tree::ClassMethods',
+            'ActiveRecord::Acts::Tree::InstanceMethods',
+            'ActiveRecord::Aggregations::ClassMethods',
+            'ActiveRecord::Associations::ClassMethods',
+            'ActiveRecord::AttributeMethods::ClassMethods',
+            'ActiveRecord::Base',
+            'ActiveRecord::Calculations::ClassMethods',
+            'ActiveRecord::Callbacks',
+            'ActiveRecord::ConnectionAdapters::AbstractAdapter',
+            'ActiveRecord::ConnectionAdapters::Column',
+            'ActiveRecord::ConnectionAdapters::DB2Adapter',
+            'ActiveRecord::ConnectionAdapters::DatabaseStatements',
+            'ActiveRecord::ConnectionAdapters::FirebirdAdapter',
+            'ActiveRecord::ConnectionAdapters::FrontBaseAdapter',
+            'ActiveRecord::ConnectionAdapters::MysqlAdapter',
+            'ActiveRecord::ConnectionAdapters::OpenBaseAdapter',
+            'ActiveRecord::ConnectionAdapters::OracleAdapter',
+            'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter',
+            'ActiveRecord::ConnectionAdapters::Quoting',
+            'ActiveRecord::ConnectionAdapters::SQLServerAdapter',
+            'ActiveRecord::ConnectionAdapters::SQLiteAdapter',
+            'ActiveRecord::ConnectionAdapters::SchemaStatements',
+            'ActiveRecord::ConnectionAdapters::SybaseAdapter::ColumnWithIdentity',
+            'ActiveRecord::ConnectionAdapters::SybaseAdapterContext',
+            'ActiveRecord::ConnectionAdapters::TableDefinition',
+            'ActiveRecord::Errors', 'ActiveRecord::Locking',
+            'ActiveRecord::Locking::Optimistic',
+            'ActiveRecord::Locking::Optimistic::ClassMethods',
+            'ActiveRecord::Locking::Pessimistic',
+            'ActiveRecord::Migration', 'ActiveRecord::Observer',
+            'ActiveRecord::Observing::ClassMethods',
+            'ActiveRecord::Reflection::ClassMethods',
+            'ActiveRecord::Reflection::MacroReflection',
+            'ActiveRecord::Schema', 'ActiveRecord::Timestamp',
+            'ActiveRecord::Transactions::ClassMethods',
+            'ActiveRecord::Validations',
+            'ActiveRecord::Validations::ClassMethods',
+            'ActiveRecord::XmlSerialization',
+            'ActiveSupport::CachingTools::HashCaching',
+            'ActiveSupport::CoreExtensions::Array::Conversions',
+            'ActiveSupport::CoreExtensions::Array::Grouping',
+            'ActiveSupport::CoreExtensions::Date::Conversions',
+            'ActiveSupport::CoreExtensions::Hash::Conversions',
+            'ActiveSupport::CoreExtensions::Hash::Conversions::ClassMethods',
+            'ActiveSupport::CoreExtensions::Hash::Diff',
+            'ActiveSupport::CoreExtensions::Hash::Keys',
+            'ActiveSupport::CoreExtensions::Hash::ReverseMerge',
+            'ActiveSupport::CoreExtensions::Integer::EvenOdd',
+            'ActiveSupport::CoreExtensions::Integer::Inflections',
+            'ActiveSupport::CoreExtensions::Numeric::Bytes',
+            'ActiveSupport::CoreExtensions::Numeric::Time',
+            'ActiveSupport::CoreExtensions::Pathname::CleanWithin',
+            'ActiveSupport::CoreExtensions::Range::Conversions',
+            'ActiveSupport::CoreExtensions::String::Access',
+            'ActiveSupport::CoreExtensions::String::Conversions',
+            'ActiveSupport::CoreExtensions::String::Inflections',
+            'ActiveSupport::CoreExtensions::String::Iterators',
+            'ActiveSupport::CoreExtensions::String::StartsEndsWith',
+            'ActiveSupport::CoreExtensions::String::Unicode',
+            'ActiveSupport::CoreExtensions::Time::Calculations',
+            'ActiveSupport::CoreExtensions::Time::Calculations::ClassMethods',
+            'ActiveSupport::CoreExtensions::Time::Conversions',
+            'ActiveSupport::Multibyte::Chars',
+            'ActiveSupport::Multibyte::Handlers::UTF8Handler',
+            'Breakpoint', 'Builder::BlankSlate', 'Builder::XmlMarkup',
+            'Fixtures',
+            'HTML::Selector', 'HashWithIndifferentAccess', 'Inflector',
+            'Inflector::Inflections', 'Mime', 'Mime::Type',
+            'OCI8AutoRecover', 'TimeZone', 'XmlSimple'
+            ),
+        5 => array(
+            'image_tag', 'link_to', 'link_to_remote', 'javascript_include_tag',
+            'assert_equal', 'assert_not_equal', 'before_filter',
+            'after_filter', 'render', 'redirect_to', 'hide_action',
+            'render_to_string', 'url_for', 'controller_name',
+            'controller_class_name', 'controller_path', 'session',
+            'render_component', 'render_component_as_string', 'cookie',
+            'layout', 'flash', 'auto_complete_for', 'in_place_editor_for',
+            'respond_to', 'paginate', 'current_page', 'each', 'first',
+            'first_page', 'last_page', 'last', 'length', 'new', 'page_count',
+            'previous', 'scaffold', 'send_data',
+            'send_file', 'deliver', 'receive', 'error_messages_for',
+            'error_message_on', 'form', 'input', 'stylesheet_link_tag',
+            'stylesheet_path', 'content_for', 'select_date', 'ago',
+            'month', 'day', 'check_box', 'fields_for', 'file_field',
+            'form_for', 'hidden_field', 'text_area', 'password_field',
+            'collection_select', 'options_for_select',
+            'options_from_collection_for_select', 'file_field_tag',
+            'form_for_tag', 'hidden_field_tag', 'text_area_tag',
+            'password_field_tag', 'link_to_function', 'javascript_tag',
+            'human_size', 'number_to_currency', 'pagination_links',
+            'form_remote_tag', 'form_remote_for',
+            'submit_to_remote', 'remote_function', 'observe_form',
+            'observe_field', 'remote_form_for', 'options_for_ajax', 'alert',
+            'call', 'assign', 'show', 'hide', 'insert_html', 'sortable',
+            'toggle', 'visual_effect', 'replace', 'replace_html', 'remove',
+            'save', 'save!', 'draggable', 'drop_receiving', 'literal',
+            'draggable_element', 'drop_receiving_element', 'sortable_element',
+            'content_tag', 'tag', 'link_to_image', 'link_to_if',
+            'link_to_unless', 'mail_to', 'link_image_to', 'button_to',
+            'current_page?', 'act_as_list', 'act_as_nested', 'act_as_tree',
+            'has_many', 'has_one', 'belongs_to', 'has_many_and_belogns_to',
+            'delete', 'destroy', 'destroy_all', 'clone', 'deep_clone', 'copy',
+            'update', 'table_name', 'primary_key', 'sum', 'maximun', 'minimum',
+            'count', 'size', 'after_save', 'after_create', 'before_save',
+            'before_create', 'add_to_base', 'errors', 'add', 'validate',
+            'validates_presence_of', 'validates_numericality_of',
+            'validates_uniqueness_of', 'validates_length_of',
+            'validates_format_of', 'validates_size_of', 'to_a', 'to_s',
+            'to_xml', 'to_i'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '%', '&', '*', '|', '/', '<', '>',
+        '+', '-', '=>', '<<'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color:#9966CC; font-weight:bold;',
+            2 => 'color:#0000FF; font-weight:bold;',
+            3 => 'color:#CC0066; font-weight:bold;',
+            4 => 'color:#CC00FF; font-weight:bold;',
+            5 => 'color:#5A0A0A; font-weight:bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color:#008000; font-style:italic;',
+                    'MULTI' => 'color:#000080; font-style:italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color:#000099;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color:#006600; font-weight:bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color:#996600;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color:#006666;'
+            ),
+        'METHODS' => array(
+            1 => 'color:#9900CC;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color:#006600; font-weight:bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color:#ff6633; font-weight:bold;',
+            1 => 'color:#0066ff; font-weight:bold;',
+            2 => 'color:#6666ff; font-weight:bold;',
+            3 => 'color:#ff3333; font-weight:bold;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        0 => array(
+            GESHI_SEARCH => "([[:space:]])(\\$[a-zA-Z_][a-zA-Z0-9_]*)",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        1 => array(
+            GESHI_SEARCH => "([[:space:]])(@[a-zA-Z_][a-zA-Z0-9_]*)",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        2 => "([A-Z][a-zA-Z0-9_]*::)+[A-Z][a-zA-Z0-9_]*", //Static OOP References
+        3 => array(
+            GESHI_SEARCH => "([[:space:]]|\[|\()(:[a-zA-Z_][a-zA-Z0-9_]*)",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<%' => '%>'
+            )
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/rebol.php b/examples/includes/geshi/geshi/rebol.php
new file mode 100644 (file)
index 0000000..6f57137
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/*************************************************************************************
+ * rebol.php
+ * --------
+ * Author: Lecanu Guillaume (Guillaume@LyA.fr)
+ * Copyright: (c) 2004-2005 Lecanu Guillaume (Guillaume@LyA.fr)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/12/22
+ *
+ * Rebol language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/01/26 (1.0.8.3)
+ *  -  Adapted language file to comply to GeSHi language file guidelines
+ * 2004/11/25 (1.0.3)
+ *  -  Added support for multiple object splitters
+ *  -  Fixed &new problem
+ * 2004/10/27 (1.0.2)
+ *  -  Added URL support
+ *  -  Added extra constants
+ * 2004/08/05 (1.0.1)
+ *  -  Added support for symbols
+ * 2004/07/14 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Make sure the last few function I may have missed
+ *   (like eval()) are included for highlighting
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'REBOL',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array('rebol [' => ']', 'comment [' => ']'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'binary!','block!','char!','date!','decimal!','email!','file!',
+            'hash!','integer!','issue!','list!','logic!','money!','none!',
+            'object!','paren!','pair!','path!','string!','tag!','time!',
+            'tuple!','url!',
+            ),
+        2 => array(
+            'all','any','attempt','break','catch','compose','disarm','dispatch',
+            'do','do-events','does','either','else','exit','for','forall',
+            'foreach','forever','forskip','func','function','halt','has','if',
+            'launch','loop','next','quit','reduce','remove-each','repeat',
+            'return','secure','switch','throw','try','until','wait','while',
+            ),
+        3 => array(
+            'about','abs','absolute','add','alert','alias','alter','and',
+            'any-block?','any-function?','any-string?','any-type?','any-word?',
+            'append','arccosine','arcsine','arctangent','array','as-pair',
+            'ask','at','back','binary?','bind','bitset?','block?','brightness?',
+            'browse','build-tag','caret-to-offset','center-face','change',
+            'change-dir','char?','charset','checksum','choose','clean-path',
+            'clear','clear-fields','close','comment','complement','component?',
+            'compress','confirm','connected?','construct','context','copy',
+            'cosine','datatype?','date?','debase','decimal?','decode-cgi',
+            'decompress','dehex','delete','detab','difference','dir?','dirize',
+            'divide','dump-face','dump-obj','echo','email?','empty?','enbase',
+            'entab','equal?','error?','even?','event?','exclude','exists?',
+            'exp','extract','fifth','file?','find','first','flash','focus',
+            'form','found?','fourth','free','function?','get','get-modes',
+            'get-word?','greater-or-equal?','greater?','hash?','head','head?',
+            'help','hide','hide-popup','image?','import-email','in',
+            'in-window?','index?','info?','inform','input','input?','insert',
+            'integer?','intersect','issue?','join','last','layout','length?',
+            'lesser-or-equal?','lesser?','library?','license','link?',
+            'list-dir','list?','lit-path?','lit-word?','load','load-image',
+            'log-10','log-2','log-e','logic?','lowercase','make','make-dir',
+            'make-face','max','maximum','maximum-of','min','minimum',
+            'minimum-of','modified?','mold','money?','multiply','native?',
+            'negate','negative?','none?','not','not-equal?','now','number?',
+            'object?','odd?','offset-to-caret','offset?','op?','open','or',
+            'pair?','paren?','parse','parse-xml','path?','pick','poke','port?',
+            'positive?','power','prin','print','probe','protect',
+            'protect-system','query','random','read','read-io','recycle',
+            'refinement?','reform','rejoin','remainder','remold','remove',
+            'rename',
+            //'repeat',
+            'repend','replace','request','request-color','request-date',
+            'request-download','request-file','request-list','request-pass',
+            'request-text','resend','reverse','routine?','same?','save',
+            'script?','second','select','send','series?','set','set-modes',
+            'set-net','set-path?','set-word?','show','show-popup','sign?',
+            'sine','size-text','size?','skip','sort','source','span?',
+            'split-path','square-root','strict-equal?','strict-not-equal?',
+            'string?','struct?','stylize','subtract','suffix?','tag?','tail',
+            'tail?','tangent','third','time?','to','to-binary','to-bitset',
+            'to-block','to-char','to-date','to-decimal','to-email','to-file',
+            'to-get-word','to-hash','to-hex','to-idate','to-image','to-integer',
+            'to-issue','to-list','to-lit-path','to-lit-word','to-local-file',
+            'to-logic','to-money','to-pair','to-paren','to-path',
+            'to-rebol-file','to-refinement','to-set-path','to-set-word',
+            'to-string','to-tag','to-time','to-tuple','to-url','to-word',
+            'trace','trim','tuple?','type?','unfocus','union','unique',
+            'unprotect','unset','unset?','unview','update','upgrade',
+            'uppercase','url?','usage','use','value?','view','viewed?','what',
+            'what-dir','within?','word?','write','write-io','xor','zero?',
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+//            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+//        2 => 'includes/dico_rebol.php?word={FNAME}',
+//        3 => 'includes/dico_rebol.php?word={FNAME}'
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*",
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/reg.php b/examples/includes/geshi/geshi/reg.php
new file mode 100644 (file)
index 0000000..9c85a15
--- /dev/null
@@ -0,0 +1,233 @@
+<?php
+/*************************************************************************************
+ * reg.php
+ * -------
+ * Author: Sean Hanna (smokingrope@gmail.com)
+ * Copyright: (c) 2006 Sean Hanna
+ * Release Version: 1.0.8.3
+ * Date Started: 03/15/2006
+ *
+ * Microsoft Registry Editor language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ *  -  Updated and optimized most regular expressions
+ * 03/15/2006 (0.5.0)
+ *  -  Syntax File Created
+ * 04/27/2006 (0.9.5)
+ *  -  Syntax Coloring Cleaned Up
+ *  -  First Release
+ * 04/29/2006 (1.0.0)
+ *  -  Updated a few coloring settings
+ *
+ * TODO (updated 4/27/2006)
+ * -------------------------
+ * - Add a verification to the multi-line portion of the hex field regex
+ *    for a '\' character on the line preceding the line of the multi-line
+ *    hex field.
+ *
+ * KNOWN ISSUES (updated 4/27/2006)
+ * ---------------------------------
+ *
+ * - There are two regexes for the multiline hex value regex. The regex for
+ *        all lines after the first does not verify that the previous line contains
+ *        a line continuation character '\'. This regex also does not check for
+ *        end of line as it should.
+ *
+ * - If number_highlighting is enabled during processing of this syntax file
+ *    many of the regexps used will appear slightly incorrect.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'Microsoft Registry',
+    'COMMENT_SINGLE' => array(1 =>';'),
+    'COMMENT_MULTI' => array( ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+//        1 => array(),
+//        2 => array(),
+        /* Registry Key Constants Not Used */
+        3 => array(
+            'HKEY_LOCAL_MACHINE',
+            'HKEY_CLASSES_ROOT',
+            'HKEY_CURRENT_USER',
+            'HKEY_USERS',
+            'HKEY_CURRENT_CONFIG',
+            'HKEY_DYN_DATA',
+            'HKLM', 'HKCR', 'HKCU', 'HKU', 'HKCC', 'HKDD'
+            )
+        ),
+    'SYMBOLS' => array(
+        '='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+//        1 => false,
+//        2 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+//            1 => 'color: #00CCFF;',
+//            2 => 'color: #0000FF;',
+            3 => 'color: #800000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #009900;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #009900;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #00CCFF;',
+            1 => 'color: #0000FF;',
+            2 => '',
+            3 => 'color: #0000FF;',
+            4 => 'color: #0000FF;',
+            5 => '',
+            6 => '',
+            7 => '',
+            8 => 'color: #FF6600;',
+            )
+        ),
+    'URLS' => array(
+//        1 => '',
+//        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        // Highlight Key Delimiters
+        0 => array(
+            GESHI_SEARCH => '((^|\\n)\\s*)(\\\\\\[(.*)\\\\\\])(\\s*(\\n|$))',
+            GESHI_REPLACE => '\\3',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\5'
+//            GESHI_CLASS => 'kw1'
+            ),
+        // Highlight File Format Header Version 5
+        1 => array(
+            GESHI_SEARCH => '(^\s*)(Windows Registry Editor Version \d+\.\d+)(\s*$)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3',
+            GESHI_CLASS => 'geshi_registry_header'
+            ),
+        // Highlight File Format Header Version 4
+        2 => array(
+            GESHI_SEARCH => '(^\\s*)(REGEDIT\s?\d+)(\s*$)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3',
+            GESHI_CLASS => 'geshi_registry_header'
+            ),
+        // Highlight dword: 32 bit integer values
+        3 => array(
+            GESHI_SEARCH => '(=\s*)(dword:[0-9a-fA-F]{8})(\s*$)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+//            GESHI_CLASS => 'kw2'
+            ),
+        // Highlight variable names
+        4 => array(
+            GESHI_SEARCH => '(^\s*)(\&quot;.*?\&quot;)(\s*=)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3',
+            GESHI_CLASS => 'geshi_variable'
+            ),
+        // Highlight String Values
+        5 => array(
+            GESHI_SEARCH => '(=\s*)(\&quot;.*?\&quot;)(\s*$)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3',
+            GESHI_CLASS => 'st0'
+            ),
+        // Highlight Hexadecimal Values (Single-Line and Multi-Line)
+        6 => array(
+            GESHI_SEARCH => '(=\s*\n?\s*)(hex:[0-9a-fA-F]{2}(,(\\\s*\n\s*)?[0-9a-fA-F]{2})*)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '',
+            GESHI_CLASS => 'kw2'
+            ),
+        // Highlight Default Variable
+        7 => array(
+            GESHI_SEARCH => '(^\s*)(@)(\s*=)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'm',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3',
+            GESHI_CLASS => 'geshi_variable'
+            ),
+        // Highlight GUID's found anywhere.
+        8 => array(
+            GESHI_SEARCH => '(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\})',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => '',
+            GESHI_CLASS => 'geshi_guid'
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'NUMBERS' => GESHI_NEVER,
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/robots.php b/examples/includes/geshi/geshi/robots.php
new file mode 100644 (file)
index 0000000..7bb2b20
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+/*************************************************************************************
+ * robots.php
+ * --------
+ * Author: Christian Lescuyer (cl@goelette.net)
+ * Copyright: (c) 2006 Christian Lescuyer http://xtian.goelette.info
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/02/17
+ *
+ * robots.txt language file for GeSHi.
+ *
+ * 2006/02/17 (1.0.0)
+ *   -  First Release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'robots.txt',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'User-agent', 'Disallow'
+            )
+        ),
+    'SYMBOLS' => array(
+        ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.robotstxt.org/wc/norobots.html'
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/ruby.php b/examples/includes/geshi/geshi/ruby.php
new file mode 100644 (file)
index 0000000..8928557
--- /dev/null
@@ -0,0 +1,226 @@
+<?php
+/*************************************************************************************
+ * ruby.php
+ * --------
+ * Author: Moises Deniz
+ * Copyright: (c) 2007 Moises Deniz
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/03/21
+ *
+ * Ruby language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2007/03/21 (1.0.7.19)
+ *   -  Initial release
+ *
+ *************************************************************************************
+ *
+ *   This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Ruby',
+    'COMMENT_SINGLE' => array(1 => "#"),
+    'COMMENT_MULTI' => array("=begin" => "=end"),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', '`','\''),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+                'alias', 'and', 'begin', 'break', 'case', 'class',
+                'def', 'defined', 'do', 'else', 'elsif', 'end',
+                'ensure', 'for', 'if', 'in', 'module', 'while',
+                'next', 'not', 'or', 'redo', 'rescue', 'yield',
+                'retry', 'super', 'then', 'undef', 'unless',
+                'until', 'when', 'BEGIN', 'END', 'include'
+            ),
+        2 => array(
+                '__FILE__', '__LINE__', 'false', 'nil', 'self', 'true',
+                'return'
+            ),
+        3 => array(
+                'Array', 'Float', 'Integer', 'String', 'at_exit',
+                'autoload', 'binding', 'caller', 'catch', 'chop', 'chop!',
+                'chomp', 'chomp!', 'eval', 'exec', 'exit', 'exit!', 'fail',
+                'fork', 'format', 'gets', 'global_variables', 'gsub', 'gsub!',
+                'iterator?', 'lambda', 'load', 'local_variables', 'loop',
+                'open', 'p', 'print', 'printf', 'proc', 'putc', 'puts',
+                'raise', 'rand', 'readline', 'readlines', 'require', 'select',
+                'sleep', 'split', 'sprintf', 'srand', 'sub', 'sub!', 'syscall',
+                'system', 'trace_var', 'trap', 'untrace_var'
+            ),
+        4 => array(
+                'Abbrev', 'ArgumentError', 'Base64', 'Benchmark',
+                'Benchmark::Tms', 'Bignum', 'Binding', 'CGI', 'CGI::Cookie',
+                'CGI::HtmlExtension', 'CGI::QueryExtension',
+                'CGI::Session', 'CGI::Session::FileStore',
+                'CGI::Session::MemoryStore', 'Class', 'Comparable', 'Complex',
+                'ConditionVariable', 'Continuation', 'Data',
+                'Date', 'DateTime', 'Delegator', 'Dir', 'EOFError', 'ERB',
+                'ERB::Util', 'Enumerable', 'Enumerable::Enumerator', 'Errno',
+                'Exception', 'FalseClass', 'File',
+                'File::Constants', 'File::Stat', 'FileTest', 'FileUtils',
+                'FileUtils::DryRun', 'FileUtils::NoWrite',
+                'FileUtils::StreamUtils_', 'FileUtils::Verbose', 'Find',
+                'Fixnum', 'FloatDomainError', 'Forwardable', 'GC', 'Generator',
+                'Hash', 'IO', 'IOError', 'Iconv', 'Iconv::BrokenLibrary',
+                'Iconv::Failure', 'Iconv::IllegalSequence',
+                'Iconv::InvalidCharacter', 'Iconv::InvalidEncoding',
+                'Iconv::OutOfRange', 'IndexError', 'Interrupt', 'Kernel',
+                'LoadError', 'LocalJumpError', 'Logger', 'Logger::Application',
+                'Logger::Error', 'Logger::Formatter', 'Logger::LogDevice',
+                'Logger::LogDevice::LogDeviceMutex', 'Logger::Severity',
+                'Logger::ShiftingError', 'Marshal', 'MatchData',
+                'Math', 'Matrix', 'Method', 'Module', 'Mutex', 'NameError',
+                'NameError::message', 'NilClass', 'NoMemoryError',
+                'NoMethodError', 'NotImplementedError', 'Numeric', 'Object',
+                'ObjectSpace', 'Observable', 'PStore', 'PStore::Error',
+                'Pathname', 'Precision', 'Proc', 'Process', 'Process::GID',
+                'Process::Status', 'Process::Sys', 'Process::UID', 'Queue',
+                'Range', 'RangeError', 'Rational', 'Regexp', 'RegexpError',
+                'RuntimeError', 'ScriptError', 'SecurityError', 'Set',
+                'Shellwords', 'Signal', 'SignalException', 'SimpleDelegator',
+                'SingleForwardable', 'Singleton', 'SingletonClassMethods',
+                'SizedQueue', 'SortedSet', 'StandardError', 'StringIO',
+                'StringScanner', 'StringScanner::Error', 'Struct', 'Symbol',
+                'SyncEnumerator', 'SyntaxError', 'SystemCallError',
+                'SystemExit', 'SystemStackError', 'Tempfile',
+                'Test::Unit::TestCase', 'Test::Unit', 'Test', 'Thread',
+                'ThreadError', 'ThreadGroup',
+                'ThreadsWait', 'Time', 'TrueClass', 'TypeError', 'URI',
+                'URI::BadURIError', 'URI::Error', 'URI::Escape', 'URI::FTP',
+                'URI::Generic', 'URI::HTTP', 'URI::HTTPS',
+                'URI::InvalidComponentError', 'URI::InvalidURIError',
+                'URI::LDAP', 'URI::MailTo', 'URI::REGEXP',
+                'URI::REGEXP::PATTERN', 'UnboundMethod', 'Vector', 'YAML',
+                'ZeroDivisionError', 'Zlib',
+                'Zlib::BufError', 'Zlib::DataError', 'Zlib::Deflate',
+                'Zlib::Error', 'Zlib::GzipFile', 'Zlib::GzipFile::CRCError',
+                'Zlib::GzipFile::Error', 'Zlib::GzipFile::LengthError',
+                'Zlib::GzipFile::NoFooter', 'Zlib::GzipReader',
+                'Zlib::GzipWriter', 'Zlib::Inflate', 'Zlib::MemError',
+                'Zlib::NeedDict', 'Zlib::StreamEnd', 'Zlib::StreamError',
+                'Zlib::VersionError',
+                'Zlib::ZStream',
+                'HTML::Selector', 'HashWithIndifferentAccess', 'Inflector',
+                'Inflector::Inflections', 'Mime', 'Mime::Type',
+                'OCI8AutoRecover', 'TimeZone', 'XmlSimple'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '%', '&', '*', '|', '/', '<', '>',
+        '+', '-', '=>', '<<'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color:#9966CC; font-weight:bold;',
+            2 => 'color:#0000FF; font-weight:bold;',
+            3 => 'color:#CC0066; font-weight:bold;',
+            4 => 'color:#CC00FF; font-weight:bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color:#008000; font-style:italic;',
+            'MULTI' => 'color:#000080; font-style:italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color:#000099;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color:#006600; font-weight:bold;'
+            ),
+        'STRINGS' => array(
+            0 => 'color:#996600;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color:#006666;'
+            ),
+        'METHODS' => array(
+            1 => 'color:#9900CC;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color:#006600; font-weight:bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color:#ff6633; font-weight:bold;',
+            1 => 'color:#0066ff; font-weight:bold;',
+            2 => 'color:#6666ff; font-weight:bold;',
+            3 => 'color:#ff3333; font-weight:bold;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        0 => array(//Variables
+            GESHI_SEARCH => "([[:space:]])(\\$[a-zA-Z_][a-zA-Z0-9_]*)",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        1 => array(//Arrays
+            GESHI_SEARCH => "([[:space:]])(@[a-zA-Z_][a-zA-Z0-9_]*)",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        2 => "([A-Z][a-zA-Z0-9_]*::)+[A-Z][a-zA-Z0-9_]*",//Static OOP symbols
+        3 => array(
+            GESHI_SEARCH => "([[:space:]]|\[|\()(:[a-zA-Z_][a-zA-Z0-9_]*)",
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '<%' => '%>'
+            )
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        ),
+    'TAB_WIDTH' => 2
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/sas.php b/examples/includes/geshi/geshi/sas.php
new file mode 100644 (file)
index 0000000..d4ee828
--- /dev/null
@@ -0,0 +1,290 @@
+<?php
+/*************************************************************************************
+ * sas.php
+ * -------
+ * Author: Galen Johnson (solitaryr@gmail.com)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/12/27
+ *
+ * SAS language file for GeSHi. Based on the sas vim file.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ *   -  Cleaned up code style
+ * 2005/12/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2005/12/27)
+ * -------------------------
+ * * Check highlighting stuff works
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'SAS',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            '_ALL_','_CHARACTER_','_INFILE_','_N_','_NULL_','_NUMERIC_',
+            '_WEBOUT_'
+            ),
+        2 => array(
+            '%BQUOTE','%CMPRES','%COMPSTOR','%DATATYP','%DISPLAY','%DO','%ELSE',
+            '%END','%EVAL','%GLOBAL','%GOTO','%IF','%INDEX','%INPUT','%KEYDEF',
+            '%LABEL','%LEFT','%LENGTH','%LET','%LOCAL','%LOWCASE','%MACRO',
+            '%MEND','%NRBQUOTE','%NRQUOTE','%NRSTR','%PUT','%QCMPRES','%QLEFT',
+            '%QLOWCASE','%QSCAN','%QSUBSTR','%QSYSFUNC','%QTRIM','%QUOTE',
+            '%QUPCASE','%SCAN','%STR','%SUBSTR','%SUPERQ','%SYSCALL',
+            '%SYSEVALF','%SYSEXEC','%SYSFUNC','%SYSGET','%SYSLPUT','%SYSPROD',
+            '%SYSRC','%SYSRPUT','%THEN','%TO','%TRIM','%UNQUOTE','%UNTIL',
+            '%UPCASE','%VERIFY','%WHILE','%WINDOW'
+            ),
+        3 => array(
+            'ABS','ADDR','AIRY','ARCOS','ARSIN','ATAN','ATTRC','ATTRN','BAND',
+            'BETAINV','BLSHIFT','BNOT','BOR','BRSHIFT','BXOR','BYTE','CDF',
+            'CEIL','CEXIST','CINV','CLOSE','CNONCT','COLLATE','COMPBL',
+            'COMPOUND','COMPRESS','COSH','COS','CSS','CUROBS','CV','DACCDBSL',
+            'DACCDB','DACCSL','DACCSYD','DACCTAB','DAIRY','DATETIME','DATEJUL',
+            'DATEPART','DATE','DAY','DCLOSE','DEPDBSL','DEPDB','DEPSL','DEPSYD',
+            'DEPTAB','DEQUOTE','DHMS','DIF','DIGAMMA','DIM','DINFO','DNUM',
+            'DOPEN','DOPTNAME','DOPTNUM','DREAD','DROPNOTE','DSNAME','ERFC',
+            'ERF','EXIST','EXP','FAPPEND','FCLOSE','FCOL','FDELETE','FETCHOBS',
+            'FETCH','FEXIST','FGET','FILEEXIST','FILENAME','FILEREF','FINFO',
+            'FINV','FIPNAMEL','FIPNAME','FIPSTATE','FLOOR','FNONCT','FNOTE',
+            'FOPEN','FOPTNAME','FOPTNUM','FPOINT','FPOS','FPUT','FREAD',
+            'FREWIND','FRLEN','FSEP','FUZZ','FWRITE','GAMINV','GAMMA',
+            'GETOPTION','GETVARC','GETVARN','HBOUND','HMS','HOSTHELP','HOUR',
+            'IBESSEL','INDEXW','INDEXC','INDEX','INPUTN','INPUTC','INPUT',
+            'INTRR','INTCK','INTNX','INT','IRR','JBESSEL','JULDATE','KURTOSIS',
+            'LAG','LBOUND','LEFT','LENGTH','LGAMMA','LIBNAME','LIBREF','LOG10',
+            'LOG2','LOGPDF','LOGPMF','LOGSDF','LOG','LOWCASE','MAX','MDY',
+            'MEAN','MINUTE','MIN','MOD','MONTH','MOPEN','MORT','NETPV','NMISS',
+            'NORMAL','NPV','N','OPEN','ORDINAL','PATHNAME','PDF','PEEKC','PEEK',
+            'PMF','POINT','POISSON','POKE','PROBBETA','PROBBNML','PROBCHI',
+            'PROBF','PROBGAM','PROBHYPR','PROBIT','PROBNEGB','PROBNORM','PROBT',
+            'PUTN','PUTC','PUT','QTR','QUOTE','RANBIN','RANCAU','RANEXP',
+            'RANGAM','RANGE','RANK','RANNOR','RANPOI','RANTBL','RANTRI',
+            'RANUNI','REPEAT','RESOLVE','REVERSE','REWIND','RIGHT','ROUND',
+            'SAVING','SCAN','SDF','SECOND','SIGN','SINH','SIN','SKEWNESS',
+            'SOUNDEX','SPEDIS','SQRT','STDERR','STD','STFIPS','STNAME',
+            'STNAMEL','SUBSTR','SUM','SYMGET','SYSGET','SYSMSG','SYSPROD',
+            'SYSRC','SYSTEM','TANH','TAN','TIMEPART','TIME','TINV','TNONCT',
+            'TODAY','TRANSLATE','TRANWRD','TRIGAMMA','TRIMN','TRIM','TRUNC',
+            'UNIFORM','UPCASE','USS','VARFMT','VARINFMT','VARLABEL','VARLEN',
+            'VARNAME','VARNUM','VARRAYX','VARRAY','VARTYPE','VAR','VERIFY',
+            'VFORMATX','VFORMATDX','VFORMATD','VFORMATNX','VFORMATN',
+            'VFORMATWX','VFORMATW','VFORMAT','VINARRAYX','VINARRAY',
+            'VINFORMATX','VINFORMATDX','VINFORMATD','VINFORMATNX','VINFORMATN',
+            'VINFORMATWX','VINFORMATW','VINFORMAT','VLABELX','VLABEL',
+            'VLENGTHX','VLENGTH','VNAMEX','VNAME','VTYPEX','VTYPE','WEEKDAY',
+            'YEAR','YYQ','ZIPFIPS','ZIPNAME','ZIPNAMEL','ZIPSTATE'
+            ),
+        4 => array(
+            'ABORT','ADD','ALTER','AND','ARRAY','AS','ATTRIB','BY','CALL',
+            'CARDS4','CASCADE','CATNAME','CHECK','CONTINUE','CREATE',
+            'DATALINES4','DELETE','DESCRIBE','DISPLAY','DISTINCT','DM','DROP',
+            'ENDSAS','FILE','FOOTNOTE','FOREIGN','FORMAT','FROM',
+            'GOTO','GROUP','HAVING','IN','INFILE','INFORMAT',
+            'INSERT','INTO','KEEP','KEY','LABEL','LEAVE',
+            'LIKE','LINK','LIST','LOSTCARD','MERGE','MESSAGE','MISSING',
+            'MODIFY','MSGTYPE','NOT','NULL','ON','OPTIONS','OR','ORDER',
+            'OUTPUT','PAGE','PRIMARY','REDIRECT','REFERENCES','REMOVE',
+            'RENAME','REPLACE','RESET','RESTRICT','RETAIN','RETURN','SELECT',
+            'SET','SKIP','STARTSAS','STOP','SYSTASK','TABLE','TITLE','UNIQUE',
+            'UPDATE','VALIDATE','VIEW','WAITSAS','WHERE','WINDOW','X'
+            ),
+        5 => array(
+            'DO','ELSE','END','IF','THEN','UNTIL','WHILE'
+            ),
+        6 => array(
+            'RUN','QUIT','DATA'
+            ),
+        7 => array(
+            'ERROR'
+            ),
+        8 => array(
+            'WARNING'
+            ),
+        9 => array(
+            'NOTE'
+            )
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false,
+        8 => false,
+        9 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #0000ff;',
+            4 => 'color: #0000ff;',
+            5 => 'color: #0000ff;',
+            6 => 'color: #000080; font-weight: bold;',
+            7 => 'color: #ff0000;',
+            8 => 'color: #00ff00;',
+            9 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array(
+//            1 => 'color: #006400; font-style: italic;',
+            'MULTI' => 'color: #006400; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #a020f0;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #2e8b57; font-weight: bold;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff; font-weight: bold;',
+            1 => 'color: #000080; font-weight: bold;',
+            2 => 'color: #006400; font-style: italic;',
+            3 => 'color: #006400; font-style: italic;',
+            4 => 'color: #006400; font-style: italic;',
+            5 => 'color: #ff0000; font-weight: bold;',
+            6 => 'color: #00ff00; font-style: italic;',
+            7 => 'color: #0000ff; font-style: normal;',
+            8 => 'color: #b218b2; font-weight: bold;',
+            9 => 'color: #b218b2; font-weight: bold;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => '',
+        8 => '',
+        9 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        0 => "&amp;[a-zA-Z_][a-zA-Z0-9_]*",
+        1 => array(//Procedures
+            GESHI_SEARCH => '(^\\s*)(PROC \\w+)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        2 => array(
+            GESHI_SEARCH => '(^\\s*)(\\*.*;)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        3 => array(
+            GESHI_SEARCH => '(.*;\\s*)(\\*.*;)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        4 => array(
+            GESHI_SEARCH => '(^\\s*)(%\\*.*;)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        5 => array(//Error messages
+            GESHI_SEARCH => '(^ERROR.*)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        6 => array(//Warning messages
+            GESHI_SEARCH => '(^WARNING.*)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        7 => array(//Notice messages
+            GESHI_SEARCH => '(^NOTE.*)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'im',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        8 => array(
+            GESHI_SEARCH => '(^\\s*)(CARDS.*)(^\\s*;\\s*$)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'sim',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+        9 => array(
+            GESHI_SEARCH => '(^\\s*)(DATALINES.*)(^\\s*;\\s*$)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'sim',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/scala.php b/examples/includes/geshi/geshi/scala.php
new file mode 100644 (file)
index 0000000..c72de33
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+/*************************************************************************************
+ * scala.php
+ * ----------
+ * Author: Franco Lombardo (franco@francolombardo.net)
+ * Copyright: (c) 2008 Franco Lombardo, Benny Baumann
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/02/08
+ *
+ * Scala language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/02/08 (1.0.7.22)
+ *   -  First Release
+ *
+ * TODO (updated 2007/04/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Scala',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'abstract', 'case', 'catch', 'class', 'def',
+            'do', 'else', 'extends', 'false', 'final',
+            'finally', 'for', 'forSome', 'if', 'implicit',
+            'import', 'match', 'new', 'null', 'object',
+            'override', 'package', 'private', 'protected', 'requires',
+            'return', 'sealed', 'super', 'this', 'throw',
+            'trait', 'try', 'true', 'type', 'val',
+            'var', 'while', 'with', 'yield'
+            ),
+        2 => array(
+            'void', 'double', 'int', 'boolean', 'byte', 'short', 'long', 'char', 'float'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?',
+        '_', ':', '=', '=>', '<<:',
+        '<%', '>:', '#', '@'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff; font-weight: bold;',
+            2 => 'color: #9999cc; font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            1=> 'color: #008000; font-style: italic;',
+            'MULTI' => 'color: #00ff00; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #0000ff; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #F78811;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #6666FF;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #F78811;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #000000;',
+            2 => 'color: #000000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000080;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://scala-lang.org',
+        2 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/scheme.php b/examples/includes/geshi/geshi/scheme.php
new file mode 100644 (file)
index 0000000..1c85f80
--- /dev/null
@@ -0,0 +1,170 @@
+<?php
+/*************************************************************************************
+ * scheme.php
+ * ----------
+ * Author: Jon Raphaelson (jonraphaelson@gmail.com)
+ * Copyright: (c) 2005 Jon Raphaelson, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * Scheme language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/09/22 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2005/09/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Scheme',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array('#|' => '|#'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'abs', 'acos', 'and', 'angle', 'append', 'appply', 'approximate',
+            'asin', 'assoc', 'assq', 'assv', 'atan',
+
+            'begin', 'boolean?', 'bound-identifier=?',
+
+            'caar', 'caddr', 'cadr', 'call-with-current-continuation',
+            'call-with-input-file', 'call-with-output-file', 'call/cc', 'car',
+            'case', 'catch', 'cdddar', 'cddddr', 'cdr', 'ceiling', 'char->integer',
+            'char-alphabetic?', 'char-ci<=?', 'char-ci<?', 'char-ci?', 'char-ci>=?',
+            'char-ci>?', 'char-ci=?', 'char-downcase', 'char-lower-case?',
+            'char-numeric', 'char-ready', 'char-ready?', 'char-upcase',
+            'char-upper-case?', 'char-whitespace?', 'char<=?', 'char<?', 'char=?',
+            'char>=?', 'char>?', 'char?', 'close-input-port', 'close-output-port',
+            'complex?', 'cond', 'cons', 'construct-identifier', 'cos',
+            'current-input-port', 'current-output-port',
+
+            'd', 'define', 'define-syntax', 'delay', 'denominator', 'display', 'do',
+
+            'e', 'eof-object?', 'eq?', 'equal?', 'eqv?', 'even?', 'exact->inexact',
+            'exact?', 'exp', 'expt', 'else',
+
+            'f', 'floor', 'for-each', 'force', 'free-identifer=?',
+
+            'gcd', 'gen-counter', 'gen-loser', 'generate-identifier',
+
+            'identifier->symbol', 'identifier', 'if', 'imag-part', 'inexact->exact',
+            'inexact?', 'input-port?', 'integer->char', 'integer?', 'integrate-system',
+
+            'l', 'lambda', 'last-pair', 'lcm', 'length', 'let', 'let*', 'letrec',
+            'list', 'list->string', 'list->vector', 'list-ref', 'list-tail', 'list?',
+            'load', 'log',
+
+            'magnitude', 'make-polar', 'make-promise', 'make-rectangular',
+            'make-string', 'make-vector', 'map', 'map-streams', 'max', 'member',
+            'memq', 'memv', 'min', 'modulo',
+
+            'negative', 'newline', 'nil', 'not', 'null?', 'number->string', 'number?',
+            'numerator',
+
+            'odd?', 'open-input-file', 'open-output-file', 'or', 'output-port',
+
+            'pair?', 'peek-char', 'positive?', 'procedure?',
+
+            'quasiquote', 'quote', 'quotient',
+
+            'rational', 'rationalize', 'read', 'read-char', 'real-part', 'real?',
+            'remainder', 'return', 'reverse',
+
+            's', 'sequence', 'set!', 'set-char!', 'set-cdr!', 'sin', 'sqrt', 'string',
+            'string->list', 'string->number', 'string->symbol', 'string-append',
+            'string-ci<=?', 'string-ci<?', 'string-ci=?', 'string-ci>=?',
+            'string-ci>?', 'string-copy', 'string-fill!', 'string-length',
+            'string-ref', 'string-set!', 'string<=?', 'string<?', 'string=?',
+            'string>=?', 'string>?', 'string?', 'substring', 'symbol->string',
+            'symbol?', 'syntax', 'syntax-rules',
+
+            't', 'tan', 'template', 'transcript-off', 'transcript-on', 'truncate',
+
+            'unquote', 'unquote-splicing', 'unwrap-syntax',
+
+            'vector', 'vector->list', 'vector-fill!', 'vector-length', 'vector-ref',
+            'vector-set!', 'vector?',
+
+            'with-input-from-file', 'with-output-to-file', 'write', 'write-char',
+
+            'zero?'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '!', '%', '^', '&', '/','+','-','*','=','<','>',';','|'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/scilab.php b/examples/includes/geshi/geshi/scilab.php
new file mode 100644 (file)
index 0000000..bfe72ad
--- /dev/null
@@ -0,0 +1,295 @@
+<?php
+/*************************************************************************************
+ * scilab.php
+ * --------
+ * Author: Christophe David (geshi@christophedavid.org)
+ * Copyright: (c) 2008 Christophe David (geshi@christophedavid.org)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/08/04
+ *
+ * SciLab language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/25 (1.0.8.1)
+ *   - Corrected with the help of Benny Baumann (BenBE@geshi.org)
+ * 2008/08/04 (0.0.0.1)
+ *   - First beta Release - known problem with ' used to transpose matrices considered as start of strings
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'SciLab',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        2 => "/\w+'/"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'HARDQUOTE' => array("'", "'"),
+    'HARDESCAPE' => array(),
+    'KEYWORDS' => array(
+        1 => array(
+            'if', 'else', 'elseif', 'end', 'select', 'case', 'for', 'while', 'break'
+            ),
+        2 => array(
+            'STDIN', 'STDOUT', 'STDERR',
+            '%i', '%pi', '%e', '%eps', '%nan', '%inf', '%s', '%t', '%f',
+            'usual', 'polynomial', 'boolean', 'character', 'function', 'rational', 'state-space',
+            'sparse', 'boolean sparse', 'list', 'tlist', 'library', 'endfunction'
+            ),
+        3 => array(
+            '%asn', '%helps', '%k', '%sn', 'abcd', 'abinv', 'abort', 'about', 'About_M2SCI_tools',
+            'abs', 'acos', 'acosh', 'acoshm', 'acosm', 'AdCommunications', 'add_demo', 'add_edge',
+            'add_help_chapter', 'add_node', 'add_palette', 'addcolor', 'addf', 'addinter', 'addmenu',
+            'adj_lists', 'adj2sp', 'aff2ab', 'alufunctions', 'amell', 'analpf', 'analyze', 'and',
+            'ans', 'apropos', 'arc_graph', 'arc_number', 'arc_properties', 'argn', 'arhnk', 'arl2',
+            'arma', 'arma2p', 'armac', 'armax', 'armax1', 'arsimul', 'artest', 'articul', 'ascii',
+            'asciimat', 'asin', 'asinh', 'asinhm', 'asinm', 'assignation', 'atan', 'atanh', 'atanhm',
+            'atanm', 'augment', 'auread', 'auwrite', 'axes_properties', 'axis_properties', 'backslash',
+            'balanc', 'balreal', 'bandwr', 'banner','bar', 'barh', 'barhomogenize', 'basename', 'bdiag',
+            'beep', 'besselh', 'besseli', 'besselj', 'besselk', 'bessely', 'best_match', 'beta','bezout',
+            'bifish', 'bilin', 'binomial', 'black', 'bloc2exp', 'bloc2ss', 'bode', 'bool2s',
+            'boucle', 'brackets', 'browsevar', 'bsplin3val', 'bstap', 'buttmag', 'buttondialog',
+            'bvode', 'bvodeS', 'c_link', 'cainv', 'calendar', 'calerf', 'calfrq', 'call', 'canon', 'casc',
+            'cat', 'catch', 'ccontrg', 'cd', 'cdfbet', 'cdfbin', 'cdfchi', 'cdfchn', 'cdff', 'cdffnc',
+            'cdfgam', 'cdfnbn', 'cdfnor', 'cdfpoi', 'cdft', 'ceil', 'cell', 'cell2mat', 'cellstr', 'center',
+            'cepstrum', 'chain_struct', 'chaintest', 'champ', 'champ_properties', 'champ1', 'char', 'chart',
+            'chartooem', 'chdir', 'cheb1mag', 'cheb2mag', 'check_graph', 'chepol', 'chfact', 'chol', 'chsolve',
+            'circuit', 'classmarkov', 'clc', 'clean', 'clear', 'clear_pixmap', 'clearfun', 'clearglobal','clf',
+            'clipboard', 'close', 'cls2dls', 'cmb_lin', 'cmndred', 'cmoment', 'code2str', 'coeff', 'coff', 'coffg',
+            'colcomp', 'colcompr', 'colinout', 'colon', 'color', 'color_list', 'colorbar', 'colordef', 'colormap',
+            'colregul', 'comma', 'comments', 'comp', 'companion', 'comparison', 'Compound_properties', 'con_nodes',
+            'cond', 'config', 'configure_msvc', 'conj', 'connex', 'console', 'cont_frm', 'cont_mat', 'Contents',
+            'continue', 'contour', 'contour2d', 'contour2di', 'contourf', 'contr', 'contract_edge', 'contrss',
+            'convex_hull', 'convol', 'convstr', 'copfac', 'copy', 'corr', 'correl', 'cos', 'cosh', 'coshm',
+            'cosm', 'cotg', 'coth', 'cothm', 'covar', 'create_palette', 'cshep2d', 'csim', 'cspect', 'Cste',
+            'ctr_gram', 'cumprod', 'cumsum', 'cycle_basis', 'czt', 'dasrt', 'dassl', 'datafit', 'date', 'datenum',
+            'datevec', 'dbphi', 'dcf', 'ddp', 'debug', 'dec2hex', 'deff', 'definedfields', 'degree', 'delbpt',
+            'delete', 'delete_arcs', 'delete_nodes', 'delip', 'delmenu', 'demoplay', 'denom', 'derivat', 'derivative',
+            'des2ss', 'des2tf', 'det', 'determ', 'detr', 'detrend', 'dft', 'dhinf', 'dhnorm', 'diag', 'diary',
+            'diff', 'diophant', 'dir', 'dirname', 'disp', 'dispbpt', 'dispfiles', 'dlgamma', 'dnaupd', 'do', 'dot',
+            'double', 'dragrect', 'draw', 'drawaxis', 'drawlater', 'drawnow', 'driver', 'dsaupd', 'dscr',
+            'dsearch', 'dsimul', 'dt_ility', 'dtsi', 'edge_number', 'edit', 'edit_curv', 'edit_error',
+            'edit_graph', 'edit_graph_menus', 'editvar', 'eigenmarkov', 'ell1mag',
+            'empty', 'emptystr', 'eqfir', 'eqiir', 'equal', 'Equal', 'equil', 'equil1',
+            'ereduc', 'erf', 'erfc', 'erfcx', 'errbar', 'errcatch', 'errclear', 'error', 'error_table', 'etime',
+            'eval', 'eval_cshep2d', 'eval3d', 'eval3dp', 'evans', 'evstr', 'excel2sci', 'exec', 'execstr', 'exists',
+            'exit', 'exp', 'expm', 'external', 'extraction', 'eye', 'fac3d', 'factorial', 'factors', 'faurre', 'fchamp',
+            'fcontour', 'fcontour2d', 'fec', 'fec_properties', 'feedback', 'feval', 'ffilt', 'fft', 'fft2', 'fftshift',
+            'fgrayplot', 'figure', 'figure_properties', 'figure_style', 'file', 'fileinfo', 'fileparts', 'filter', 'find',
+            'find_freq', 'find_path', 'findABCD', 'findAC', 'findBD', 'findBDK', 'findm', 'findmsvccompiler', 'findobj',
+            'findR', 'findx0BD', 'firstnonsingleton', 'fit_dat', 'fix', 'floor', 'flts', 'foo', 'format',
+            'formatman', 'fort', 'fourplan', 'fplot2d', 'fplot3d', 'fplot3d1', 'fprintf', 'fprintfMat', 'frep2tf',
+            'freq', 'freson', 'frexp', 'frfit', 'frmag', 'fscanf', 'fscanfMat', 'fsfirlin', 'fsolve', 'fspecg',
+            'fstabst', 'fstair', 'ftest', 'ftuneq', 'full', 'fullfile', 'fullrf', 'fullrfk', 'fun2string', 'Funcall',
+            'funcprot', 'functions', 'funptr', 'fusee', 'G_make', 'g_margin', 'gainplot', 'gamitg',
+            'gamma', 'gammaln', 'gca', 'gcare', 'gcd', 'gce', 'gcf', 'gda', 'gdf', 'gen_net', 'genfac3d', 'genlib',
+            'genmarkov', 'geom3d', 'geomean', 'get', 'get_contents_infer', 'get_function_path', 'getcolor', 'getcwd',
+            'getd', 'getdate', 'getenv', 'getf', 'getfield', 'getfont', 'gethistory', 'getio', 'getlinestyle',
+            'getlongpathname', 'getmark', 'getmemory', 'getos', 'getpid', 'getscilabkeywords', 'getshell',
+            'getshortpathname', 'getsymbol', 'getvalue', 'getversion', 'gfare', 'gfrancis', 'girth', 'givens',
+            'glever', 'glist', 'global', 'GlobalProperty', 'glue', 'gmres', 'gpeche', 'gr_menu', 'graduate', 'grand',
+            'graph_2_mat', 'graph_center', 'graph_complement', 'graph_diameter', 'graph_power', 'graph_simp', 'graph_sum',
+            'graph_union', 'graphic', 'Graphics', 'graphics_entities', 'graph-list', 'graycolormap', 'grayplot',
+            'grayplot_properties', 'graypolarplot', 'great', 'grep', 'group', 'gschur', 'gsort', 'gspec', 'gstacksize',
+            'gtild', 'h_cl', 'h_inf', 'h_inf_st', 'h_norm', 'h2norm', 'halt', 'hamilton', 'hank', 'hankelsv', 'harmean',
+            'hat', 'havewindow', 'head_comments', 'help', 'help_skeleton', 'hermit', 'hess', 'hex2dec', 'hilb', 'hinf',
+            'hist3d', 'histplot', 'horner', 'host', 'hotcolormap', 'householder', 'hrmt', 'hsv2rgb', 'hsvcolormap',
+            'htrianr', 'hypermat', 'hypermatrices', 'iconvert', 'ieee', 'ifft', 'iir', 'iirgroup', 'iirlp',
+            'ilib_build', 'ilib_compile', 'ilib_for_link', 'ilib_gen_gateway', 'ilib_gen_loader', 'ilib_gen_Make',
+            'im_inv', 'imag', 'impl', 'imrep2ss', 'imult', 'ind2sub', 'Infer', 'inistate', 'input', 'insertion', 'int',
+            'int16', 'int2d', 'int32', 'int3d', 'int8', 'intc', 'intdec', 'integrate', 'interp', 'interp1', 'interp2d',
+            'interp3d', 'interpln', 'intersci', 'intersect', 'intg', 'intl', 'intppty', 'intsplin', 'inttrap', 'inttype',
+            'inv', 'inv_coeff', 'invr', 'invsyslin', 'iqr', 'is_connex', 'iscellstr', 'isdef', 'isdir', 'isempty',
+            'isequal', 'isequalbitwise', 'iserror', 'isglobal', 'isinf', 'isnan', 'isoview', 'isreal', 'javasci',
+            'jetcolormap', 'jmat', 'justify', 'kalm', 'karmarkar', 'kernel', 'keyboard', 'knapsack', 'kpure', 'krac2',
+            'kron', 'kroneck', 'label_properties', 'labostat', 'LANGUAGE', 'lasterror', 'lattn', 'lattp', 'lcf', 'lcm',
+            'lcmdiag', 'ldiv', 'ldivf', 'leastsq', 'left', 'legend', 'legend_properties', 'legendre', 'legends', 'length',
+            'leqr', 'less', 'lev', 'levin', 'lex_sort', 'lft', 'lgfft', 'lib', 'lin', 'lin2mu', 'lindquist',
+            'line_graph', 'linear_interpn', 'lines', 'LineSpec', 'linf', 'linfn', 'link', 'linmeq', 'linpro', 'linsolve',
+            'linspace', 'listfiles', 'listvarinfile', 'lmisolver', 'lmitool', 'load', 'load_graph', 'loadhistory',
+            'loadmatfile', 'loadplots', 'loadwave', 'locate', 'log', 'log10', 'log1p', 'log2', 'logm', 'logspace',
+            'lotest', 'lqe', 'lqg', 'lqg_ltr', 'lqg2stan', 'lqr', 'ls', 'lsq', 'lsq_splin', 'lsqrsolve', 'lsslist',
+            'lstcat', 'lstsize', 'ltitr', 'lu', 'ludel', 'lufact', 'luget', 'lusolve', 'lyap', 'm_circle', 'm2scideclare',
+            'macglov', 'macr2lst', 'macr2tree', 'macro', 'macrovar', 'mad', 'make_graph', 'make_index', 'makecell', 'man',
+            'manedit', 'mapsound', 'markp2ss', 'mat_2_graph', 'matfile2sci', 'Matlab-Scilab_character_strings', 'Matplot',
+            'Matplot_properties', 'Matplot1', 'matrices', 'matrix', 'max', 'max_cap_path', 'max_clique', 'max_flow',
+            'maxi', 'mcisendstring', 'mclearerr', 'mclose', 'mdelete', 'mean', 'meanf', 'median', 'menus', 'meof',
+            'merror', 'mese', 'mesh', 'mesh2d', 'meshgrid', 'mfft', 'mfile2sci', 'mfprintf', 'mfscanf', 'mget', 'mgeti',
+            'mgetl', 'mgetstr', 'milk_drop', 'min', 'min_lcost_cflow', 'min_lcost_flow1', 'min_lcost_flow2',
+            'min_qcost_flow', 'min_weight_tree', 'mine', 'mini', 'minreal', 'minss', 'minus', 'mkdir', 'mlist', 'mode',
+            'modulo', 'moment', 'mopen', 'move', 'mprintf', 'mps2linpro', 'mput', 'mputl', 'mputstr', 'mrfit', 'mscanf',
+            'msd', 'mseek', 'msprintf', 'msscanf', 'mstr2sci', 'mtell', 'mtlb_0', 'mtlb_a', 'mtlb_all', 'mtlb_any',
+            'mtlb_axis', 'mtlb_beta', 'mtlb_box', 'mtlb_close', 'mtlb_colordef', 'mtlb_conv', 'mtlb_cumprod', 'mtlb_cumsum',
+            'mtlb_dec2hex', 'mtlb_delete', 'mtlb_diag', 'mtlb_diff', 'mtlb_dir', 'mtlb_double', 'mtlb_e', 'mtlb_echo',
+            'mtlb_eig', 'mtlb_eval', 'mtlb_exist', 'mtlb_eye', 'mtlb_false', 'mtlb_fft', 'mtlb_fftshift', 'mtlb_find',
+            'mtlb_findstr', 'mtlb_fliplr', 'mtlb_fopen', 'mtlb_format', 'mtlb_fprintf', 'mtlb_fread', 'mtlb_fscanf',
+            'mtlb_full', 'mtlb_fwrite', 'mtlb_grid', 'mtlb_hold', 'mtlb_i', 'mtlb_ifft', 'mtlb_imp', 'mtlb_int16',
+            'mtlb_int32', 'mtlb_int8', 'mtlb_is', 'mtlb_isa', 'mtlb_isfield', 'mtlb_isletter', 'mtlb_isspace', 'mtlb_l',
+            'mtlb_legendre', 'mtlb_linspace', 'mtlb_load', 'mtlb_logic', 'mtlb_logical', 'mtlb_lower', 'mtlb_max',
+            'mtlb_min', 'mtlb_mode', 'mtlb_more', 'mtlb_num2str', 'mtlb_ones', 'mtlb_plot', 'mtlb_prod', 'mtlb_rand',
+            'mtlb_randn', 'mtlb_rcond', 'mtlb_realmax', 'mtlb_realmin', 'mtlb_repmat', 'mtlb_s', 'mtlb_save',
+            'mtlb_setstr', 'mtlb_size', 'mtlb_sort', 'mtlb_sparse', 'mtlb_strcmp', 'mtlb_strcmpi', 'mtlb_strfind',
+            'mtlb_strrep', 'mtlb_sum', 'mtlb_t', 'mtlb_toeplitz', 'mtlb_tril', 'mtlb_triu', 'mtlb_true', 'mtlb_uint16',
+            'mtlb_uint32', 'mtlb_uint8', 'mtlb_upper', 'mtlb_zeros', 'mu2lin', 'mucomp', 'mulf', 'mvvacov', 'name2rgb',
+            'names', 'nancumsum', 'nand2mean', 'nanmax', 'nanmean', 'nanmeanf', 'nanmedian', 'nanmin', 'nanstdev',
+            'nansum', 'narsimul', 'NDcost', 'ndgrid', 'ndims', 'nearfloat', 'nehari', 'neighbors', 'netclose', 'netwindow',
+            'netwindows', 'new', 'newaxes', 'newest', 'newfun', 'nextpow2', 'nf3d', 'nfreq', 'nlev', 'nnz', 'node_number',
+            'nodes_2_path', 'nodes_degrees', 'noisegen', 'norm', 'not', 'null', 'number_properties', 'numdiff', 'numer',
+            'nyquist', 'object_editor', 'obs_gram', 'obscont', 'obscont1', 'observer', 'obsv_mat', 'obsvss', 'ode',
+            'ode_discrete', 'ode_optional_output', 'ode_root', 'odedc', 'odeoptions', 'oemtochar', 'old_style',
+            'oldbesseli', 'oldbesselj', 'oldbesselk', 'oldbessely', 'oldload', 'oldplot', 'oldsave', 'ones',
+            'Operation', 'optim', 'or', 'orth', 'overloading', 'p_margin', 'param3d', 'param3d_properties',
+            'param3d1', 'paramfplot2d', 'parents', 'parrot', 'part', 'path_2_nodes', 'pathconvert', 'pause', 'pbig',
+            'pca', 'pcg', 'pdiv', 'pen2ea', 'pencan', 'penlaur', 'percent', 'perctl', 'perfect_match', 'perl',
+            'perms', 'permute', 'pertrans', 'pfss', 'phasemag', 'phc', 'pie', 'pinv', 'pipe_network', 'playsnd', 'plot',
+            'plot_graph', 'plot2d', 'plot2d_old_version', 'plot2d1', 'plot2d2', 'plot2d3', 'plot2d4', 'plot3d',
+            'plot3d_old_version', 'plot3d1', 'plot3d2', 'plot3d3', 'plotframe', 'plotprofile', 'plus', 'plzr',
+            'pmodulo', 'pol2des', 'pol2str', 'pol2tex', 'polar', 'polarplot', 'polfact', 'poly', 'polyline_properties',
+            'portr3d', 'portrait', 'power', 'ppol', 'prbs_a', 'predecessors', 'predef', 'print', 'printf',
+            'printf_conversion', 'printing', 'printsetupbox', 'prod', 'profile', 'progressionbar', 'proj', 'projsl',
+            'projspec', 'psmall', 'pspect', 'pvm', 'pvm_addhosts', 'pvm_barrier', 'pvm_bcast', 'pvm_bufinfo', 'pvm_config',
+            'pvm_delhosts', 'pvm_error', 'pvm_exit', 'pvm_f772sci', 'pvm_get_timer', 'pvm_getinst', 'pvm_gettid',
+            'pvm_gsize', 'pvm_halt', 'pvm_joingroup', 'pvm_kill', 'pvm_lvgroup', 'pvm_mytid', 'pvm_parent', 'pvm_probe',
+            'pvm_recv', 'pvm_reduce', 'pvm_sci2f77', 'pvm_send', 'pvm_set_timer', 'pvm_spawn', 'pvm_spawn_independent',
+            'pvm_start', 'pvm_tasks', 'pvm_tidtohost', 'pvmd3', 'pwd', 'qassign', 'qld', 'qmr', 'qr', 'quapro', 'quart',
+            'quaskro', 'quit', 'quote', 'rand', 'randpencil', 'range', 'rank', 'rankqr', 'rat',  'rcond',
+            'rdivf', 'read', 'read4b', 'readb', 'readc_', 'readmps', 'readxls', 'real', 'realtime', 'realtimeinit',
+            'rectangle_properties', 'recur', 'reglin', 'regress', 'remez', 'remezb', 'repfreq', 'replot', 'resethistory',
+            'residu', 'resume', 'return', 'rgb2name', 'ric_desc', 'ricc', 'riccati', 'rlist', 'rmdir', 'roots', 'rotate',
+            'round', 'routh_t', 'rowcomp', 'rowcompr', 'rowinout', 'rowregul', 'rowshuff', 'rpem', 'rref', 'rtitr',
+            'rubberbox', 'salesman', 'sample', 'samplef', 'samwr', 'save', 'save_format', 'save_graph', 'savehistory',
+            'savematfile', 'savewave', 'sca', 'scaling', 'scanf', 'scanf_conversion', 'scf', 'schur', 'sci_files',
+            'sci2exp', 'sci2for', 'sci2map', 'sciargs', 'SciComplex', 'SciComplexArray', 'SciDouble', 'SciDoubleArray',
+            'scilab', 'Scilab', 'ScilabEval', 'scilink', 'scipad', 'SciString', 'SciStringArray', 'sd2sci', 'sda', 'sdf',
+            'secto3d', 'segs_properties', 'semi', 'semicolon', 'semidef', 'sensi', 'set', 'set_posfig_dim',
+            'setbpt', 'setdiff', 'setenv', 'seteventhandler', 'setfield', 'sethomedirectory', 'setlanguage', 'setmenu',
+            'sfact', 'Sfgrayplot', 'Sgrayplot', 'sgrid', 'shortest_path', 'show_arcs', 'show_graph', 'show_nodes',
+            'show_pixmap', 'showprofile', 'sident', 'sign', 'Signal', 'signm', 'simp', 'simp_mode', 'sin', 'sinc',
+            'sincd', 'sinh', 'sinhm', 'sinm', 'size', 'slash', 'sleep', 'sm2des', 'sm2ss', 'smooth', 'solve',
+            'sorder', 'sort', 'sound', 'soundsec', 'sp2adj', 'spaninter', 'spanplus', 'spantwo', 'spchol',
+            'spcompack', 'spec', 'specfact', 'speye', 'spget', 'splin', 'splin2d', 'splin3d', 'split_edge', 'spones',
+            'sprand', 'sprintf', 'spzeros', 'sqroot', 'sqrt', 'sqrtm', 'square', 'squarewave', 'srfaur', 'srkf', 'ss2des',
+            'ss2ss', 'ss2tf', 'sscanf', 'sskf', 'ssprint', 'ssrand', 'st_deviation', 'st_ility', 'stabil', 'stacksize',
+            'star', 'startup', 'stdev', 'stdevf', 'str2code', 'strange', 'strcat', 'strindex', 'string', 'stringbox',
+            'strings', 'stripblanks', 'strong_con_nodes', 'strong_connex', 'strsplit', 'strsubst', 'struct', 'sub2ind',
+            'subf', 'subgraph', 'subplot', 'successors', 'sum', 'supernode', 'surf', 'surface_properties', 'sva',
+            'svd', 'svplot', 'sylm', 'sylv', 'symbols', 'sysconv', 'sysdiag', 'sysfact', 'syslin', 'syssize', 'system',
+            'systems', 'systmat', 'tabul', 'tan', 'tangent', 'tanh', 'tanhm', 'tanm', 'TCL_CreateSlave', 'TCL_DeleteInterp',
+            'TCL_EvalFile', 'TCL_EvalStr', 'TCL_ExistInterp', 'TCL_ExistVar', 'TCL_GetVar', 'TCL_GetVersion', 'TCL_SetVar',
+            'TCL_UnsetVar', 'TCL_UpVar', 'tdinit', 'testmatrix', 'texprint', 'text_properties', 'tf2des', 'tf2ss', 'then',
+            'thrownan', 'tic', 'tilda', 'time_id', 'timer', 'title', 'titlepage', 'TK_EvalFile', 'TK_EvalStr', 'tk_getdir',
+            'tk_getfile', 'TK_GetVar', 'tk_savefile', 'TK_SetVar',  'toc', 'toeplitz', 'tohome', 'tokenpos',
+            'tokens', 'toolbar', 'toprint', 'trace', 'trans', 'trans_closure', 'translatepaths', 'tree2code', 'trfmod',
+            'trianfml', 'tril', 'trimmean', 'trisolve', 'triu', 'try', 'trzeros', 'twinkle', 'type', 'Type', 'typename',
+            'typeof', 'ui_observer', 'uicontrol', 'uimenu', 'uint16', 'uint32', 'uint8', 'ulink', 'unglue', 'union',
+            'unique', 'unix', 'unix_g', 'unix_s', 'unix_w', 'unix_x', 'unobs', 'unsetmenu', 'unzoom', 'user', 'varargin',
+            'varargout', 'Variable', 'variance', 'variancef', 'varn', 'vectorfind', 'waitbar', 'warning', 'wavread',
+            'wavwrite', 'wcenter', 'wfir', 'what', 'where', 'whereami', 'whereis', 'who', 'who_user', 'whos',
+            'wiener', 'wigner', 'winclose', 'window', 'winlist', 'winopen', 'winqueryreg', 'winsid', 'with_atlas',
+            'with_gtk', 'with_javasci', 'with_pvm', 'with_texmacs', 'with_tk', 'writb', 'write', 'write4b', 'x_choices',
+            'x_choose', 'x_dialog', 'x_matrix', 'x_mdialog', 'x_message', 'x_message_modeless', 'xarc', 'xarcs', 'xarrows',
+            'xaxis', 'xbasc', 'xbasimp', 'xbasr', 'xchange', 'xclea', 'xclear', 'xclick', 'xclip', 'xdel', 'xend',
+            'xfarc', 'xfarcs', 'xfpoly', 'xfpolys', 'xfrect', 'xget', 'xgetech', 'xgetfile', 'xgetmouse', 'xgraduate',
+            'xgrid', 'xinfo', 'xinit', 'xlfont', 'xload', 'xls_open', 'xls_read', 'xmltohtml', 'xname', 'xnumb', 'xpause',
+            'xpoly', 'xpolys', 'xrect', 'xrects', 'xrpoly', 'xs2bmp', 'xs2emf', 'xs2eps', 'xs2fig', 'xs2gif', 'xs2ppm',
+            'xs2ps', 'xsave', 'xsegs', 'xselect', 'xset', 'xsetech', 'xsetm', 'xstring', 'xstringb', 'xstringl', 'xtape',
+            'xtitle', 'yulewalk', 'zeropen', 'zeros', 'zgrid', 'zoom_rect', 'zpbutt', 'zpch1', 'zpch2', 'zpell'
+            )
+        ),
+    'SYMBOLS' => array(
+        '<', '>', '=',
+        '!', '@', '~', '&', '|',
+        '+','-', '*', '/', '%',
+        ',', ';', '?', ':', "'"
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => true,
+        1 => true,
+        2 => true,
+        3 => true,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #000000; font-weight: bold;',
+            3 => 'color: #000066;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #666666; font-style: italic;',
+            2 => '',
+            'MULTI' => 'color: #666666; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;',
+            'HARD' => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;',
+            'HARD' => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;',
+            2 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;',
+            4 => 'color: #009999;',
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://www.scilab.org/product/dic-mat-sci/M2SCI_doc.htm',
+        2 => 'http://www.scilab.org/product/dic-mat-sci/M2SCI_doc.htm',
+        3 => 'http://www.scilab.org/product/dic-mat-sci/M2SCI_doc.htm'
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '-&gt;',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        //Variable
+        0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*',
+        //File Descriptor
+        4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/sdlbasic.php b/examples/includes/geshi/geshi/sdlbasic.php
new file mode 100644 (file)
index 0000000..2e85964
--- /dev/null
@@ -0,0 +1,165 @@
+<?php
+/*************************************************************************************
+ * sdlbasic.php
+ * ------------
+ * Author: Roberto Rossi
+ * Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/08/19
+ *
+ * sdlBasic (http://sdlbasic.sf.net) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/19 (1.0.0)
+ *  -  First Release
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'sdlBasic',
+    'COMMENT_SINGLE' => array(1 => "'", 2 => "rem", 3 => "!", 4 => "#"),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'const', 'option', 'explicit', 'qbasic', 'include', 'argc',
+            'argv', 'command', 'command$', 'run', 'shell', 'os', 'declare',
+            'sub', 'function', 'return', 'while', 'wend', 'exit', 'end',
+            'continue', 'if', 'then', 'else', 'elseif',
+            'select', 'case', 'for', 'each', 'step',
+            'next', 'to', 'dim', 'shared', 'common', 'lbound', 'bound',
+            'erase', 'asc', 'chr', 'chr$', 'insert', 'insert$', 'instr', 'lcase',
+            'lcase$', 'left', 'left$', 'len', 'length', 'ltrim', 'ltrim$', 'mid',
+            'mid$', 'replace', 'replace$', 'replacesubstr', 'replacesubstr$',
+            'reverse', 'reverse$', 'right', 'right$', 'rinstr', 'rtrim', 'rtrim$',
+            'space', 'space$', 'str', 'str$', 'strf', 'strf$', 'string', 'string$',
+            'tally', 'trim', 'trim$', 'typeof', 'typeof$', 'ucase', 'ucase$', 'val',
+            'abs', 'acos', 'andbit', 'asin', 'atan', 'bitwiseand', 'bitwiseor',
+            'bitwisexor', 'cos', 'exp', 'fix', 'floor', 'frac', 'hex', 'hex$', 'int',
+            'log', 'min', 'max', 'orbit', 'randomize', 'rnd', 'round', 'sgn', 'sin',
+            'sqr', 'tan', 'xorbit', 'open', 'as', 'file', 'input', 'close', 'output',
+            'append', 'eof', 'fileexists', 'filecopy', 'filemove', 'filerename',
+            'freefile', 'kill', 'loc', 'lof', 'readbyte', 'rename', 'seek',
+            'writebyte', 'chdir', 'dir', 'dir$', 'direxists', 'dirfirst', 'dirnext',
+            'mkdir', 'rmdir', 'print', 'date', 'date$', 'time', 'time$', 'ticks',
+            'data', 'read', 'reservebank', 'freebank', 'copybank', 'loadbank',
+            'savebank', 'setbank', 'sizebank', 'poke', 'doke', 'loke', 'peek', 'deek',
+            'leek', 'memcopy', 'setdisplay', 'setcaption', 'caption', 'displaywidth',
+            'displayheight', 'displaybpp', 'screen', 'directscreen', 'screenopen',
+            'screenclose', 'screenclone', 'screencopy', 'screenfade', 'screenfadein',
+            'screencrossfade', 'screenalpha', 'screenlock', 'screenunlock',
+            'screenrect', 'xscreenrect', 'yscreenrect', 'wscreenrect', 'hscreenrect',
+            'flagscreenrect', 'screenwidth', 'screenheight', 'offset', 'xoffset',
+            'yoffset', 'cls', 'screenswap', 'autoback', 'setautoback',
+            'dualplayfield', 'waitvbl', 'fps', 'rgb', 'enablepalette', 'color',
+            'palette', 'colorcycling', 'ink', 'point', 'dot', 'plot', 'line', 'box',
+            'bar', 'circle', 'fillcircle', 'ellipse', 'fillellipse', 'paint',
+            'loadimage', 'saveimage', 'loadsound', 'savesound', 'loadmusic',
+            'hotspot', 'setcolorkey', 'imageexists', 'imagewidth', 'imageheight',
+            'deleteimage', 'copyimage', 'setalpha', 'zoomimage', 'rotateimage',
+            'rotozoomimage', 'blt', 'pastebob', 'pasteicon', 'grab', 'spriteclip',
+            'sprite', 'deletesprite', 'xsprite', 'ysprite', 'spritewidth',
+            'spriteheight', 'frsprite', 'livesprite', 'spritehit', 'autoupdatesprite',
+            'updatesprite', 'setbob', 'bob', 'deletebob', 'xbob', 'ybob', 'bobwidth',
+            'bobheight', 'frbob', 'livebob', 'bobhit', 'autoupdatebob', 'updatebob',
+            'text', 'setfont', 'textrender', 'pen', 'paper', 'prints', 'locate',
+            'atx', 'aty', 'curson', 'cursoff', 'inputs', 'zoneinputs',
+            'isenabledsound', 'soundexists', 'deletesound', 'copysound',
+            'musicexists', 'playsound', 'volumesound', 'stopsound', 'pausesound',
+            'resumesound', 'vumetersound', 'positionsound', 'soundchannels',
+            'playmusic', 'positionmusic', 'stopmusic', 'fademusic', 'pausemusic',
+            'resumemusic', 'rewindmusic', 'volumemusic', 'speedmusic', 'numdrivescd',
+            'namecd', 'getfreecd', 'opencd', 'indrivecd', 'trackscd', 'curtrackcd',
+            'curframecd', 'playcd', 'playtrackscd',
+            'pausecd', 'resumecd', 'stopcd', 'ejectcd', 'closecd', 'tracktypecd',
+            'tracklengthcd', 'trackoffsetcd', 'key', 'inkey', 'waitkey', 'xmouse',
+            'ymouse', 'xmousescreen', 'ymousescreen', 'bmouse', 'changemouse',
+            'locatemouse', 'mouseshow', 'mousehide', 'mousezone', 'numjoysticks',
+            'namejoystick', 'numaxesjoystick', 'numballsjoystick', 'numhatsjoystick',
+            'numbuttonsjoystick', 'getaxisjoystick', 'gethatjoystick',
+            'getbuttonjoystick', 'xgetballjoystick', 'ygetballjoystick', 'joy',
+            'bjoy', 'wait', 'timer', 'isenabledsock', 'getfreesock', 'opensock',
+            'acceptsock', 'isserverready', 'connectsock', 'connectionreadysock',
+            'isclientready', 'losesock', 'peeksock', 'readsock', 'readbytesock',
+            'readlinesock', 'writesock', 'writebytesock', 'writelinesock',
+            'getremoteip', 'getremoteport', 'getlocalip'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080;',
+            2 => 'color: #808080;',
+            3 => 'color: #808080;',
+            4 => 'color: #808080;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/smalltalk.php b/examples/includes/geshi/geshi/smalltalk.php
new file mode 100644 (file)
index 0000000..9316773
--- /dev/null
@@ -0,0 +1,160 @@
+<?php
+/*************************************************************************************
+ * smalltalk.php
+ * --------
+ * Author: Bananeweizen (Bananeweizen@gmx.de)
+ * Copyright: (c) 2005 Bananeweizen (www.bananeweizen.de)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/03/27
+ *
+ * Smalltalk language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006-05-24 (1.0.0)
+ *   -  First Release
+ *
+ * TODO
+ * -------------------------
+ * * recognize nested array symbols correctly
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Smalltalk',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('"' => '"'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'"),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array('self','super','true','false','nil')
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '=' , ':=', '(', ')', '#'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #7f007f;'
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #007f00; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'BRACKETS' => array(
+            0 => ''
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #7f0000;'
+            ),
+        'METHODS' => array(
+            0 => ''
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066; font-weight:bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;',
+            1 => 'color: #7f0000;',
+            2 => 'color: #7f0000;',
+            3 => 'color: #00007f;',
+            4 => 'color: #7f007f;',
+            5 => 'color: #00007f;',
+            6 => 'color: #00007f;'
+            ),
+        'SCRIPT' => array(
+            0 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        0 => array(
+            GESHI_SEARCH => '([^a-zA-Z0-9_#<])([A-Z]+[a-zA-Z0-9_]*)(?!>)', //class names
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        1 => array(
+            GESHI_SEARCH => '(#+)([a-zA-Z0-9_]+)', //symbols
+            GESHI_REPLACE => '\\1\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        2 => array(
+            GESHI_SEARCH => '(#\s*\([^)]*\))', //array symbols
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        3 => array(
+            GESHI_SEARCH => '<PIPE>([a-zA-Z0-9_\s]+)<PIPE>', //temporary variables
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '|',
+            GESHI_AFTER => '|'
+            ),
+        4 => array(
+            GESHI_SEARCH => '(self|super|true|false|nil)', //keywords again (to avoid matching in next regexp)
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        5 => array(
+            GESHI_SEARCH => '([:(,=[.*\/+-]\s*)([a-zA-Z0-9_]+)', //message parameters, message receivers
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 's',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+        6 => array(
+            GESHI_SEARCH => '([a-zA-Z0-9_]+)(\s*:=)', //assignment targets
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => '\\2'
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/smarty.php b/examples/includes/geshi/geshi/smarty.php
new file mode 100644 (file)
index 0000000..112ab5a
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+/*************************************************************************************
+ * smarty.php
+ * ----------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/07/10
+ *
+ * Smarty template language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.0)
+ *  -  Initial Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Smarty',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array('{*' => '*}'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            '$smarty', 'now', 'const', 'capture', 'config', 'section', 'foreach', 'template', 'version', 'ldelim', 'rdelim',
+            'foreachelse', 'include', 'include_php', 'insert', 'if', 'elseif', 'else', 'php',
+            'sectionelse', 'is_cached',
+            ),
+        2 => array(
+            'capitalize', 'count_characters', 'cat', 'count_paragraphs', 'count_sentences', 'count_words', 'date_format',
+            'default', 'escape', 'indent', 'lower', 'nl2br', 'regex_replace', 'replace', 'spacify', 'string_format',
+            'strip', 'strip_tags', 'truncate', 'upper', 'wordwrap',
+            ),
+        3 => array(
+            'counter', 'cycle', 'debug', 'eval', 'html_checkboxes', 'html_image', 'html_options',
+            'html_radios', 'html_select_date', 'html_select_time', 'html_table', 'math', 'mailto', 'popup_init',
+            'popup', 'textformat'
+            ),
+        4 => array(
+            '$template_dir', '$compile_dir', '$config_dir', '$plugins_dir', '$debugging', '$debug_tpl',
+            '$debugging_ctrl', '$autoload_filters', '$compile_check', '$force_compile', '$caching', '$cache_dir',
+            '$cache_lifetime', '$cache_handler_func', '$cache_modified_check', '$config_overwrite',
+            '$config_booleanize', '$config_read_hidden', '$config_fix_newlines', '$default_template_handler_func',
+            '$php_handling', '$security', '$secure_dir', '$security_settings', '$trusted_dir', '$left_delimiter',
+            '$right_delimiter', '$compiler_class', '$request_vars_order', '$request_use_auto_globals',
+            '$error_reporting', '$compile_id', '$use_sub_dirs', '$default_modifiers', '$default_resource_type'
+            ),
+        5 => array(
+            'append', 'append_by_ref', 'assign', 'assign_by_ref', 'clear_all_assign', 'clear_all_cache',
+            'clear_assign', 'clear_cache', 'clear_compiled_tpl', 'clear_config', 'config_load', 'display',
+            'fetch', 'get_config_vars', 'get_registered_object', 'get_template_vars',
+            'load_filter', 'register_block', 'register_compiler_function', 'register_function',
+            'register_modifier', 'register_object', 'register_outputfilter', 'register_postfilter',
+            'register_prefilter', 'register_resource', 'trigger_error', 'template_exists', 'unregister_block',
+            'unregister_compiler_function', 'unregister_function', 'unregister_modifier', 'unregister_object',
+            'unregister_outputfilter', 'unregister_postfilter', 'unregister_prefilter', 'unregister_resource'
+            ),
+        6 => array(
+            'name', 'file', 'scope', 'global', 'key', 'once', 'script',
+            'loop', 'start', 'step', 'max', 'show', 'values', 'value', 'from', 'item'
+            ),
+        7 => array(
+            'eq', 'neq', 'ne', 'lte', 'gte', 'ge', 'le', 'not', 'mod'
+            ),
+        8 => array(
+            // some common php functions
+            'isset', 'is_array', 'empty', 'count', 'sizeof'
+            )
+        ),
+    'SYMBOLS' => array(
+        '/', '=', '==', '!=', '>', '<', '>=', '<=', '!', '%'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false,
+        8 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0600FF;',        //Functions
+            2 => 'color: #008000;',        //Modifiers
+            3 => 'color: #0600FF;',        //Custom Functions
+            4 => 'color: #804040;',        //Variables
+            5 => 'color: #008000;',        //Methods
+            6 => 'color: #6A0A0A;',        //Attributes
+            7 => 'color: #D36900;',        //Text-based symbols
+            8 => 'color: #0600FF;'        //php functions
+            ),
+        'COMMENTS' => array(
+            'MULTI' => 'color: #008080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #D36900;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #D36900;'
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #009000;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #00aaff;'
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://smarty.php.net/{FNAMEL}',
+        2 => 'http://smarty.php.net/{FNAMEL}',
+        3 => 'http://smarty.php.net/{FNAMEL}',
+        4 => 'http://smarty.php.net/{FNAMEL}',
+        5 => 'http://smarty.php.net/{FNAMEL}',
+        6 => '',
+        7 => 'http://smarty.php.net/{FNAMEL}',
+        8 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        // variables
+        0 => '\$[a-zA-Z][a-zA-Z0-9_]*'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        0 => array(
+            '{' => '}'
+            ),
+        1 => array(
+            '<!--' => '-->',
+        ),
+        2 => array(
+            '<' => '>'
+            )
+    ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => false,
+        2 => false
+    ),
+    'PARSER_CONTROL' => array(
+        'KEYWORDS' => array(
+            'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#;>|^])",
+            'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-&])"
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/sql.php b/examples/includes/geshi/geshi/sql.php
new file mode 100644 (file)
index 0000000..00e4fd2
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+/*************************************************************************************
+ * sql.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * SQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added additional symbols for highlighting
+ * 2004/11/27 (1.0.3)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ *  -  Added "`" string delimiter
+ *  -  Added "#" single comment starter
+ * 2004/08/05 (1.0.1)
+ *  -  Added support for symbols
+ *  -  Added many more keywords (mostly MYSQL keywords)
+ * 2004/07/14 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Add all keywords
+ * * Split this to several sql files - mysql-sql, ansi-sql etc
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'SQL',
+    'COMMENT_SINGLE' => array(1 =>'--', 2 => '#'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => 1,
+    'QUOTEMARKS' => array("'", '"', '`'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC',
+            'AUTO_INCREMENT', 'BETWEEN', 'BINARY', 'BOOLEAN',
+            'BOTH', 'BY', 'CHANGE', 'CHECK', 'COLUMN', 'COLUMNS',
+            'CREATE', 'CROSS', 'DATA', 'DATABASE', 'DATABASES',
+            'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE',
+            'DISTINCT', 'DROP', 'ENCLOSED', 'ESCAPED', 'EXISTS',
+            'EXPLAIN', 'FIELD', 'FIELDS', 'FLUSH', 'FOR',
+            'FOREIGN', 'FROM', 'FULL', 'FUNCTION', 'GRANT',
+            'GROUP', 'HAVING', 'IDENTIFIED', 'IF', 'IGNORE',
+            'IN', 'INDEX', 'INFILE', 'INNER', 'INSERT', 'INTO',
+            'IS', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LANGUAGE',
+            'LEADING', 'LEFT', 'LIKE', 'LIMIT', 'LINES', 'LOAD',
+            'LOCAL', 'LOCK', 'LOW_PRIORITY', 'MODIFY', 'NATURAL',
+            'NEXTVAL', 'NOT', 'NULL', 'ON', 'OPTIMIZE', 'OPTION',
+            'OPTIONALLY', 'OR', 'ORDER', 'OUTER', 'OUTFILE',
+            'PRIMARY', 'PROCEDURAL', 'PROCEEDURE', 'READ',
+            'REFERENCES', 'REGEXP', 'RENAME', 'REPLACE',
+            'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SELECT',
+            'SET', 'SETVAL', 'SHOW', 'SONAME', 'STATUS',
+            'STRAIGHT_JOIN', 'TABLE', 'TABLES', 'TEMINATED',
+            'TEMPORARY', 'TO', 'TRAILING', 'TRIGGER', 'TRUNCATE',
+            'TRUSTED', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED',
+            'UPDATE', 'USE', 'USING', 'VALUES', 'VARIABLES',
+            'VIEW', 'WHERE', 'WITH', 'WRITE', 'XOR', 'ZEROFILL'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '=', '<', '>', '|', ',', '.', '+', '-', '*', '/'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #993333; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #808080; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/tcl.php b/examples/includes/geshi/geshi/tcl.php
new file mode 100644 (file)
index 0000000..9badb21
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * tcl.php
+ * ---------------------------------
+ * Author: Reid van Melle (rvanmelle@gmail.com)
+ * Copyright: (c) 2004 Reid van Melle (sorry@nowhere)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/05/05
+ *
+ * TCL/iTCL language file for GeSHi.
+ *
+ * This was thrown together in about an hour so I don't expect
+ * really great things.  However, it is a good start.  I never
+ * got a change to try out the iTCL or object-based support but
+ * this is not widely used anyway.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ * 2006/05/05 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2006/05/05)
+ * -------------------------
+ * - Get TCL built-in special variables highlighted with a new color..
+ *   currently, these are listed in //special variables in the keywords
+ *   section, but they get covered by the general REGEXP for symbols
+ * - General cleanup, testing, and verification
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'TCL',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        1 => '/(?<!\\\\)#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+        2 => '/{[^}\n]+}/'
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"', "'"),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        /*
+         * Set 1: reserved words
+         * http://python.org/doc/current/ref/keywords.html
+         */
+        1 => array(
+            'proc', 'global', 'upvar', 'if', 'then', 'else', 'elseif', 'for', 'foreach',
+            'break', 'continue', 'while', 'set', 'eval', 'case', 'in', 'switch',
+            'default', 'exit', 'error', 'return', 'uplevel', 'loop',
+            'for_array_keys', 'for_recursive_glob', 'for_file', 'unwind_protect',
+            'expr', 'catch', 'namespace', 'rename', 'variable',
+            // itcl
+            'method', 'itcl_class', 'public', 'protected'),
+
+        /*
+         * Set 2: builtins
+         * http://asps.activatestate.com/ASPN/docs/ActiveTcl/8.4/tcl/tcl_2_contents.htm
+         */
+        2 => array(
+            // string handling
+            'append', 'binary', 'format', 're_syntax', 'regexp', 'regsub',
+            'scan', 'string', 'subst',
+            // list handling
+            'concat', 'join', 'lappend', 'lindex', 'list', 'llength', 'lrange',
+            'lreplace', 'lsearch', 'lset', 'lsort', 'split',
+            // procedures and output
+            'incr', 'close', 'eof', 'fblocked', 'fconfigure', 'fcopy', 'file',
+            'fileevent', 'flush', 'gets', 'open', 'puts', 'read', 'seek',
+            'socket', 'tell',
+            // packages and source files
+            'load', 'loadTk', 'package', 'pgk::create', 'pgk_mkIndex', 'source',
+            // interpreter routines
+            'bgerror', 'history', 'info', 'interp', 'memory', 'unknown',
+            // library routines
+            'enconding', 'http', 'msgcat',
+            // system related
+            'cd', 'clock', 'exec', 'glob', 'pid', 'pwd', 'time',
+            // platform specified
+            'dde', 'registry', 'resource',
+            // special variables
+            '$argc', '$argv', '$errorCode', '$errorInfo', '$argv0',
+            '$auto_index', '$auto_oldpath', '$auto_path', '$env',
+            '$tcl_interactive', '$tcl_libpath', '$tcl_library',
+            '$tcl_pkgPath', '$tcl_platform', '$tcl_precision', '$tcl_traceExec',
+            ),
+
+        /*
+         * Set 3: standard library
+         */
+        3 => array(
+            'comment', 'filename', 'library', 'packagens', 'tcltest', 'tclvars',
+            ),
+
+        /*
+         * Set 4: special methods
+         */
+//        4 => array(
+//            )
+
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '$', '*', '&', '%', '!', ';', '<', '>', '?'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+//        4 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #ff7700;font-weight:bold;',    // Reserved
+            2 => 'color: #008000;',                        // Built-ins + self
+            3 => 'color: #dc143c;',                        // Standard lib
+//            4 => 'color: #0000cd;'                        // Special methods
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #808080; font-style: italic;',
+            2 => 'color: #483d8b;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: black;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #483d8b;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff4500;'
+            ),
+        'METHODS' => array(
+            1 => 'color: black;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #ff3333;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+//        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '::'
+        ),
+    'REGEXPS' => array(
+        //Special variables
+        0 => '[\\$]+[a-zA-Z_][a-zA-Z0-9_]*',
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'COMMENTS' => array(
+            'DISALLOWED_BEFORE' => '\\'
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/teraterm.php b/examples/includes/geshi/geshi/teraterm.php
new file mode 100644 (file)
index 0000000..f2938ca
--- /dev/null
@@ -0,0 +1,317 @@
+<?php
+/*************************************************************************************
+ * teraterm.php
+ * --------
+ * Author: Boris Maisuradze (boris at logmett.com)
+ * Copyright: (c) 2008 Boris Maisuradze (http://logmett.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/09/26
+ *
+ * Tera Term Macro language file for GeSHi.
+ *
+ *
+ * This version of ttl.php was created for Tera Term 4.60 and LogMeTT 2.9.4.
+ * Newer versions of these application can contain additional Macro commands
+ * and/or keywords that are not listed here. The latest release of ttl.php
+ * can be downloaded from Download section of LogMeTT.com
+ *
+ * CHANGES
+ * -------
+ * 2008/09/26 (1.0.8)
+ *   -  First Release for Tera Term 4.60 and below.
+ *
+ * TODO (updated 2008/09/26)
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Tera Term Macro',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /* Commands */
+        1 => array(
+            'Beep',
+            'BplusRecv',
+            'BplusSend',
+            'Break',            // (version 4.53 or later)
+            'Call',
+            'CallMenu',         // (version 4.56 or later)
+            'ChangeDir',
+            'ClearScreen',
+            'Clipb2Var',        //(version 4.46 or later)
+            'ClosesBox',
+            'CloseTT',
+            'Code2Str',
+            'Connect',
+            'CRC32',            // (version 4.60 or later)
+            'CRC32File',        // (version 4.60 or later)
+            'CygConnect',       // (version 4.57 or later)
+            'DelPassword',
+            'Disconnect',
+            'Do',               // (version 4.56 or later)
+            'Else',
+            'EnableKeyb',
+            'End',
+            'EndIf',
+            'EndUntil',         // (version 4.56 or later)
+            'EndWhile',
+            'Exec',
+            'ExecCmnd',
+            'Exit',
+            'FileClose',
+            'FileConcat',
+            'FileCopy',
+            'FileCreate',
+            'FileDelete',
+            'FileMarkPtr',
+            'FilenameBox',      //(version 4.54 or later)
+            'FileOpen',
+            'FileRead',
+            'FileReadln',       // (version 4.48 or later)
+            'FileRename',
+            'FileSearch',
+            'FileSeek',
+            'FileSeekBack',
+            'FileStrSeek',
+            'FileStrSeek2',
+            'FileWrite',
+            'FileWriteln',
+            'FindOperations',
+            'FlushRecv',
+            'ForNext',
+            'GetDate',
+            'GetDir',           //(version 4.46 or later)
+            'GetEnv',
+            'GetPassword',
+            'GetTime',
+            'GetTitle',
+            'GetVer',           //(version 4.58 or later)
+            'GoTo',
+            'If',
+            'IfDefined',        // (version 4.46 or later)
+            'IfThenElseIf',
+            'Include',
+            'InputBox',
+            'Int2Str',
+            'KmtFinish',
+            'KmtGet',
+            'KmtRecv',
+            'KmtSend',
+            'LoadKeyMap',
+            'LogClose',
+            'LogOpen',
+            'LogPause',
+            'LogStart',
+            'LogWrite',
+            'Loop',             // (version 4.56 or later)
+            'MakePath',
+            'MessageBox',
+            'MPause',           // (version 4.27 or later)
+            'PasswordBox',
+            'Pause',
+            'QuickvanRecv',
+            'QuickvanSend',
+            'Random',           //(version 4.27 or later)
+            'Recvln',
+            'RestoreSetup',
+            'Return',
+            'RotateLeft',       //(version 4.54 or later)
+            'RotateRight',      //(version 4.54 or later)
+            'ScpRecv',          // (version 4.57 or later)
+            'ScpSend',          // (version 4.57 or later)
+            'Send',
+            'SendBreak',
+            'SendFile',
+            'SendKcode',
+            'Sendln',
+            'SetBaud',          // (version 4.58 or later)
+            'SetDate',
+            'SetDir',
+            'SetDlgPos',
+            'SetDTR',           // (version 4.59 or later)
+            'SetRTS',           // (version 4.59 or later)
+            'SetEnv',           // (version 4.54 or later)
+            'SetEcho',
+            'SetExitCode',
+            'SetSync',
+            'SetTime',
+            'SetTitle',
+            'Show',
+            'ShowTT',
+            'Sprintf',          // (version 4.52 or later)
+            'StatusBox',
+            'Str2Code',
+            'Str2Int',
+            'StrCompare',
+            'StrConcat',
+            'StrCopy',
+            'StrLen',
+            'StrMatch',         // (version 4.59 or later)
+            'StrScan',
+            'Testlink',
+            'Then',
+            'ToLower',          //(version 4.53 or later)
+            'ToUpper',          //(version 4.53 or later)
+            'Unlink',
+            'Until',            // (version 4.56 or later)
+            'Var2Clipb',        //(version 4.46 or later)
+            'Wait',
+            'WaitEvent',
+            'Waitln',
+            'WaitRecv',
+            'WaitRegex',        // (version 4.21 or later)
+            'While',
+            'XmodemRecv',
+            'XmodemSend',
+            'YesNoBox',
+            'ZmodemRecv',
+            'ZmodemSend'
+            ),
+        /* System Variables */
+        2 => array(
+            'groupmatchstr1',
+            'groupmatchstr2',
+            'groupmatchstr3',
+            'groupmatchstr4',
+            'groupmatchstr5',
+            'groupmatchstr6',
+            'groupmatchstr7',
+            'groupmatchstr8',
+            'groupmatchstr9',
+            'inputstr',
+            'matchstr',
+            'param2',
+            'param3',
+            'param4',
+            'param5',
+            'param6',
+            'param7',
+            'param8',
+            'param9',
+            'result',
+            'timeout'
+            ),
+        /* LogMeTT Key Words */
+        3 => array(
+            '$[1]',
+            '$[2]',
+            '$[3]',
+            '$[4]',
+            '$[5]',
+            '$[6]',
+            '$[7]',
+            '$[8]',
+            '$connection$',
+            '$email$',
+            '$logdir$',
+            '$logfilename$',
+            '$logit$',
+            '$mobile$',
+            '$name$',
+            '$pager$',
+            '$parent$',
+            '$phone$',
+            '$snippet$',
+            '$ttdir$',
+            '$user$',
+            '$windir$',
+            ),
+        /* Keyword Symbols */
+        4 => array(
+            'and',
+            'not',
+            'or',
+            'xor'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']',
+        '~', '!', '+', '-', '*', '/', '%', '>>', '<<', '<<<', '>>>', '&', '^', '|',
+        '<>', '<=', '>=', '=', '==', '<>', '!=', '&&', '||'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000080; font-weight: bold!important;',
+            2 => 'color: #808000; font-weight: bold;',  // System Variables
+            3 => 'color: #ff0000; font-weight: bold;',  // LogMeTT Key Words
+            4 => 'color: #ff00ff; font-weight: bold;'   // Keyword Symbols
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(),
+        'BRACKETS' => array(
+            0 => 'color: #ff00ff; font-weight: bold;'
+        ),
+        'STRINGS' => array(
+            0 => 'color: #800080;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #008080;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #ff00ff; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff; font-weight: bold;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        0 => array (
+            GESHI_SEARCH => '(\:[_a-zA-Z][_a-zA-Z0-9]+)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array(),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/text.php b/examples/includes/geshi/geshi/text.php
new file mode 100644 (file)
index 0000000..6c6e260
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+/*************************************************************************************
+ * text.php
+ * --------
+ * Author: Sean Hanna (smokingrope@gmail.com)
+ * Copyright: (c) 2006 Sean Hanna
+ * Release Version: 1.0.8.3
+ * Date Started: 04/23/2006
+ *
+ * Standard Text File (No Syntax Highlighting).
+ * Plaintext language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 04/23/2006 (0.5.0)
+ * - Syntax File Created
+ *
+ * 04/27/2006 (1.0.0)
+ * - Documentation Cleaned Up
+ * - First Release
+ *
+ * TODO (updated 04/27/2006)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Text',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(),
+    'SYMBOLS' => array(),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(),
+        'COMMENTS' => array(),
+        'ESCAPE_CHAR' => array(),
+        'BRACKETS' => array(),
+        'STRINGS' => array(),
+        'NUMBERS' => array(),
+        'METHODS' => array(),
+        'SYMBOLS' => array(),
+        'SCRIPT' => array(),
+        'REGEXPS' => array()
+        ),
+    'URLS' => array(),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array(),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'ALL' => GESHI_NEVER
+        ),
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/thinbasic.php b/examples/includes/geshi/geshi/thinbasic.php
new file mode 100644 (file)
index 0000000..caa6edf
--- /dev/null
@@ -0,0 +1,868 @@
+<?php
+/*************************************************************************************
+ * thinbasic.php
+ * ------
+ * Author: Eros Olmi (eros.olmi@thinbasic.com)
+ * Copyright: (c) 2006 Eros Olmi (http://www.thinbasic.com), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/05/12
+ *
+ * thinBasic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006/05/12 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2006/05/12)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'thinBasic',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'XOR','XML_TREETOSTRING','XML_PARSEFILE','XML_PARSE','XML_PARENT','XML_NODETYPE','XML_NODETOSTRING','XML_NEXTSIBLING',
+            'XML_LASTERROR','XML_GETTAG','XML_FREE','XML_FINDNODE','XML_DECODEPARAM','XML_CHILDDATA','XML_CHILD','XML_ATTRIBVALUE',
+            'XML_ATTRIBNAME','XML_ATTRIBCOUNT','WORD','WITH','WIN_SHOW','WIN_SETTITLE','WIN_SETFOREGROUND','WIN_ISZOOMED',
+            'WIN_ISVISIBLE','WIN_ISICONIC','WIN_GETTITLE','WIN_GETFOREGROUND','WIN_GETCLASS','WIN_GETACTIVE','WIN_FLASH','WIN_FINDBYTITLE',
+            'WIN_FINDBYCLASS','WHILE','WEND','VERIFY','VARPTR','VARIANTVT$','VARIANTVT','VARIANT',
+            'VARIABLE_GETINFO','VARIABLE_EXISTS','VARIABLE_EXIST','VALUE','VAL','USING$','USING','USES',
+            'USER','UNTIL','UNITS','UNION','UNICODE2ASCII','UDP_SEND','UDP_RECV','UDP_OPENSERVER',
+            'UDP_OPEN','UDP_FREEFILE','UDP_CLOSE','UCODE$','UCASE$','UBOUND','TYPE','TRIMFULL$',
+            'TRIM$','TOOLTIP','TOKENIZER_MOVETOEOL','TOKENIZER_KEYSETUSERSTRING','TOKENIZER_KEYSETUSERNUMBER','TOKENIZER_KEYGETUSERSTRING','TOKENIZER_KEYGETUSERNUMBER','TOKENIZER_KEYGETSUBTYPE',
+            'TOKENIZER_KEYGETNAME','TOKENIZER_KEYGETMAINTYPE','TOKENIZER_KEYFIND','TOKENIZER_KEYADD','TOKENIZER_GETNEXTTOKEN','TOKENIZER_DEFAULT_SET','TOKENIZER_DEFAULT_GET','TOKENIZER_DEFAULT_CODE',
+            'TOKENIZER_DEFAULT_CHAR','TO','TIMER','TIME$','THEN','TEXTBOX','TEXT','TCP_SEND',
+            'TCP_RECV','TCP_PRINT','TCP_OPEN','TCP_LINEINPUT','TCP_FREEFILE','TCP_CLOSE','TB_IMGCTX_SETIMAGEADJUSTMENT','TB_IMGCTX_LOADIMAGE',
+            'TB_IMGCTX_GETIMAGEADJUSTMENT','TBGL_VIEWPORT','TBGL_VERTEX','TBGL_USETEXTUREFLAG','TBGL_USETEXTURE','TBGL_USELINESTIPPLEFLAG','TBGL_USELINESTIPPLE','TBGL_USELIGHTSOURCEFLAG',
+            'TBGL_USELIGHTSOURCE','TBGL_USELIGHTINGFLAG','TBGL_USELIGHTING','TBGL_USEFOGFLAG','TBGL_USEFOG','TBGL_USEDEPTHMASK','TBGL_USEDEPTHFLAG','TBGL_USEDEPTH',
+            'TBGL_USECLIPPLANEFLAG','TBGL_USECLIPPLANE','TBGL_USEBLENDFLAG','TBGL_USEBLEND','TBGL_USEALPHATEST','TBGL_TRANSLATE','TBGL_TORUS','TBGL_TEXCOORD2D',
+            'TBGL_SPHERE','TBGL_SHOWWINDOW','TBGL_SHOWCURSOR','TBGL_SETWINDOWTITLE','TBGL_SETUPLIGHTSOURCE','TBGL_SETUPFOG','TBGL_SETUPCLIPPLANE','TBGL_SETPRIMITIVEQUALITY',
+            'TBGL_SETLIGHTPARAMETER','TBGL_SETDRAWDISTANCE','TBGL_SCALE','TBGL_SAVESCREENSHOT','TBGL_ROTATEXYZ','TBGL_ROTATE','TBGL_RESETMATRIX','TBGL_RENDERTOTEXTURE',
+            'TBGL_RENDERMATRIX3D','TBGL_RENDERMATRIX2D','TBGL_PUSHMATRIX','TBGL_PRINTFONT','TBGL_PRINTBMP','TBGL_PRINT','TBGL_POS3DTOPOS2D','TBGL_POPMATRIX',
+            'TBGL_POLYGONLOOK','TBGL_POINTSIZE','TBGL_POINTINSIDE3D','TBGL_NORMAL','TBGL_NEWLIST','TBGL_MOUSEGETWHEELDELTA','TBGL_MOUSEGETRBUTTON','TBGL_MOUSEGETPOSY',
+            'TBGL_MOUSEGETPOSX','TBGL_MOUSEGETMBUTTON','TBGL_MOUSEGETLBUTTON','TBGL_M15SETVERTEXZ','TBGL_M15SETVERTEXY','TBGL_M15SETVERTEXXYZ','TBGL_M15SETVERTEXX','TBGL_M15SETVERTEXTEXY',
+            'TBGL_M15SETVERTEXTEXXY','TBGL_M15SETVERTEXTEXX','TBGL_M15SETVERTEXTEXN','TBGL_M15SETVERTEXRGB','TBGL_M15SETVERTEXR','TBGL_M15SETVERTEXPSTOP','TBGL_M15SETVERTEXPARAM','TBGL_M15SETVERTEXLAYER',
+            'TBGL_M15SETVERTEXG','TBGL_M15SETVERTEXB','TBGL_M15SETMODELVERTEXCOUNT','TBGL_M15SETBONECHILD','TBGL_M15ROTBONEZ','TBGL_M15ROTBONEY','TBGL_M15ROTBONEX','TBGL_M15ROTBONE',
+            'TBGL_M15RESETBONES','TBGL_M15RECALCNORMALS','TBGL_M15LOADMODEL','TBGL_M15INITMODELBUFFERS','TBGL_M15GETVERTEXZ','TBGL_M15GETVERTEXY','TBGL_M15GETVERTEXXYZ','TBGL_M15GETVERTEXX',
+            'TBGL_M15GETVERTEXTEXY','TBGL_M15GETVERTEXTEXXY','TBGL_M15GETVERTEXTEXX','TBGL_M15GETVERTEXTEXN','TBGL_M15GETVERTEXRGB','TBGL_M15GETVERTEXR','TBGL_M15GETVERTEXPSTOP','TBGL_M15GETVERTEXPARAM',
+            'TBGL_M15GETVERTEXLAYER','TBGL_M15GETVERTEXG','TBGL_M15GETVERTEXB','TBGL_M15GETMODELVERTEXCOUNT','TBGL_M15GETMODELPOLYCOUNT','TBGL_M15ERASECHILDBONES','TBGL_M15DRAWMODEL','TBGL_M15DEFBONERESET',
+            'TBGL_M15DEFBONELAYER','TBGL_M15DEFBONEBOX','TBGL_M15DEFBONEANCHOR','TBGL_M15DEFBONEADDVERTEX','TBGL_M15CLEARMODEL','TBGL_M15APPLYBONES','TBGL_M15ADDBONETREEITEM','TBGL_LOADTEXTURE',
+            'TBGL_LOADFONT','TBGL_LOADBMPFONT','TBGL_LINEWIDTH','TBGL_LINESTIPPLE','TBGL_KILLFONT','TBGL_ISWINDOW','TBGL_ISPOINTVISIBLE','TBGL_ISPOINTBEHINDVIEW',
+            'TBGL_GETWINDOWMULTIKEYSTATE','TBGL_GETWINDOWKEYSTATE','TBGL_GETWINDOWKEYONCE','TBGL_GETWINDOWCLIENT','TBGL_GETTEXTURENAME','TBGL_GETTEXTURELIST','TBGL_GETPIXELINFO','TBGL_GETMULTIASYNCKEYSTATE',
+            'TBGL_GETLASTGLERROR','TBGL_GETFRAMERATE','TBGL_GETDESKTOPINFO','TBGL_GETASYNCKEYSTATE','TBGL_ERRORMESSAGES','TBGL_ENDPOLY','TBGL_ENDLIST','TBGL_DRAWFRAME',
+            'TBGL_DESTROYWINDOW','TBGL_DELETELIST','TBGL_CYLINDER','TBGL_CREATEWINDOWEX','TBGL_CREATEWINDOW','TBGL_COLORALPHA','TBGL_COLOR','TBGL_CLEARFRAME',
+            'TBGL_CAMERA','TBGL_CALLLIST','TBGL_BUILDFONT','TBGL_BOX','TBGL_BLENDFUNC','TBGL_BINDTEXTURE','TBGL_BEGINPOLY','TBGL_BACKCOLOR',
+            'TBGL_ALPHAFUNC','TBDI_JOYZ','TBDI_JOYY','TBDI_JOYX','TBDI_JOYSTOPEFFECT','TBDI_JOYSLIDER','TBDI_JOYSETRANGEZ','TBDI_JOYSETRANGEY',
+            'TBDI_JOYSETRANGEXYZ','TBDI_JOYSETRANGEX','TBDI_JOYSETDEADZONEZ','TBDI_JOYSETDEADZONEY','TBDI_JOYSETDEADZONEXYZ','TBDI_JOYSETDEADZONEX','TBDI_JOYSETAUTOCENTER','TBDI_JOYRZ',
+            'TBDI_JOYRY','TBDI_JOYRX','TBDI_JOYPOV','TBDI_JOYPLAYEFFECT','TBDI_JOYLOADEFFECT','TBDI_JOYHASFF','TBDI_JOYHASEFFECT','TBDI_JOYGETEFFECTNAME',
+            'TBDI_JOYGETEFFECTGUID','TBDI_JOYCREATEEFFECT','TBDI_JOYCOUNTPOV','TBDI_JOYCOUNTEFFECTS','TBDI_JOYCOUNTBTN','TBDI_JOYCOUNTAXES','TBDI_JOYBUTTON','TBDI_JOYAVAIL',
+            'TBDI_INIT','TBASS_STREAMFREE','TBASS_STREAMCREATEFILE','TBASS_SETVOLUME','TBASS_SETEAXPRESET','TBASS_SETEAXPARAMETERS','TBASS_SETCONFIG','TBASS_SET3DPOSITION',
+            'TBASS_SET3DFACTORS','TBASS_SAMPLELOAD','TBASS_SAMPLEGETCHANNEL','TBASS_MUSICLOAD','TBASS_MUSICFREE','TBASS_INIT','TBASS_GETVOLUME','TBASS_GETVERSION',
+            'TBASS_GETCONFIG','TBASS_FREE','TBASS_ERRORGETCODE','TBASS_CHANNELSTOP','TBASS_CHANNELSETPOSITION','TBASS_CHANNELSETATTRIBUTES','TBASS_CHANNELSET3DPOSITION','TBASS_CHANNELPLAY',
+            'TBASS_CHANNELPAUSE','TBASS_CHANNELISACTIVE','TBASS_CHANNELGETPOSITION','TBASS_CHANNELGETLENGTH','TBASS_CHANNELGETATTRIBUTES','TBASS_APPLY3D','TANH','TANGENT',
+            'TAN','TALLY','TABCTRL_ONNOTIFY','TABCTRL_INSERTITEM','TABCTRL_GETCURSEL','SWAP','SUB','STRZIP$',
+            'STRUNZIP$','STRREVERSE$','STRPTRLEN','STRPTR','STRINSERT$','STRING$','STRING','STRDELETE$',
+            'STR$','STOP','STEP','STDOUT','STDIN','STAT_SUM','STAT_STDERROR','STAT_STDDEVIATION',
+            'STAT_RANDOM','STAT_PRODUCT','STAT_MIN','STAT_MEDIAN','STAT_MEANHARMONIC','STAT_MEANGEOMETRIC','STAT_MEANARITHMETIC','STAT_MAX',
+            'STAT_INVERSESUM','STAT_HISTOGRAM','STAT_FILLARRAY','STAT_COUNT','STAT_COPYARRAY','STAT_CLONEARRAY','STAT_CHISQUARE','STATIC',
+            'STATE','SQR','SPLIT','SORT','SMTP_STATISTICS','SMTP_SETOPTION','SMTP_SETLOGFILE','SMTP_SENDHTML',
+            'SMTP_SENDEMAIL','SMTP_GETERROR','SMTP_FINISHED','SMTP_DEBUG','SMTP_CONNECT','SMTP_CLOSE','SLEEP','SIZEOF',
+            'SIZE','SINH','SINGLE','SIN','SIGNED','SHOW','SHIFT','SHAPETOBMP',
+            'SGN','SETAT','SET','SENDMESSAGE','SENDKEYSBULK','SENDKEYS','SEND','SELECTEXPRESSION',
+            'SELECT','SECH','SEC','SCAN','SAPI_SPEAK','SAPI_SETVOLUME','SAPI_SETRATE','SAPI_MODULELOADED',
+            'SAPI_GETVOLUME','SAPI_GETRATE','RTRIM$','RTF_SETTEXT','RTF_SETFONTSIZE','RTF_SETFONTNAME','RTF_SETFGCOLOR','RTF_SETEFFECT',
+            'RTF_SETBGCOLOR','RTF_SETALIGN','RTF_SAVETOFILE','RTF_LOADFROMFILE','RTF_GETTEXT','RTF_GETFONTSIZE','RTF_GETFONTNAME','RTF_GETEFFECT',
+            'RTF_GETCLASS','RTF_APPENDTEXT','RSET$','ROUND','RNDF','RND','RIGHT$','RIGHT',
+            'RGB','RESOURCE','RESIZE','RESET','REPLACE$','REPEAT$','REMOVE$','REM',
+            'REGISTRY_SETVALUE','REGISTRY_SETTXTNUM','REGISTRY_SETTXTBOOL','REGISTRY_SETDWORD','REGISTRY_GETVALUE','REGISTRY_GETTXTNUM','REGISTRY_GETTXTBOOL','REGISTRY_GETDWORD',
+            'REGISTRY_GETALLKEYS','REGISTRY_DELVALUE','REGISTRY_DELKEY','REFERENCE','REF','REDRAW','REDIM','RAS_SETPARAMS',
+            'RAS_OPENDIALUPDIALOG','RAS_LOADENTRIES','RAS_HANGUPALL','RAS_HANGUP','RAS_GETENTRY','RAS_BEGINDIAL','RANDOMIZE','RADTODEG',
+            'QUERYPERFORMANCEFREQUENCY','QUERYPERFORMANCECOUNTER','QUAD','PTR','PRESERVE','POST','POPUP','POKE$',
+            'POKE','PIXELS','PI','PERMUTATIONS','PEEKMESSAGE','PEEK$','PEEK','PC_SYSTEMUPFROM',
+            'PC_SUSPENDSTATE','PC_SHUTDOWN','PC_SHOWCARET','PC_SETCARETBLINKTIME','PC_RESTARTDIALOG','PC_PREVENTSHUTDOWN','PC_LOCK','PC_INSERTCD',
+            'PC_HIDECARET','PC_GETSTATEONOFF','PC_GETSCROLLLOCKKEYSTATE','PC_GETNUMLOCKKEYSTATE','PC_GETCARETBLINKTIME','PC_GETCAPSLOCKKEYSTATE','PC_EMPTYBIN','PC_EJECTCD',
+            'PC_DECODECDERROR','PCT','PARSESET$','PARSECOUNT','PARSE$','PARSE','PARAMETERS','OUTSIDE',
+            'OS_WINVERSIONTEXT','OS_WINGETVERSIONTIMELINE','OS_SHELLEXECUTE','OS_SHELLABOUT','OS_SHELL','OS_SETLASTCALLDLLERROR','OS_SERVICESTOP','OS_SERVICESTATUSDESCRIPTION',
+            'OS_SERVICESTARTTYPEDESCRIPTION','OS_SERVICESTART','OS_SERVICESETSTARTTYPE','OS_SERVICEQUERY','OS_SERVICEGETSTARTTYPE','OS_SERVICEGETLIST','OS_PROCESSKILLBYNAME','OS_PROCESSKILLBYID',
+            'OS_PROCESSISRUNNING','OS_PROCESSGETLIST','OS_PROCESSGETID','OS_PROCESSARERUNNING','OS_MESSAGEBEEP','OS_ISWOW64','OS_ISFEATUREPRESENT','OS_IEVERSION',
+            'OS_GETWINDOWSDIR','OS_GETUSERNAME','OS_GETTEMPDIR','OS_GETSYSTEMDIR','OS_GETSPECIALFOLDER','OS_GETLASTCALLDLLSTATUS','OS_GETLASTCALLDLLERROR','OS_GETCURRENTTHREADID',
+            'OS_GETCURRENTPROCESSID','OS_GETCOMPUTERNAME','OS_GETCOMMANDS','OS_GETCOMMAND','OS_FLASHWINDOW','OS_FATALAPPEXIT','OS_ENVIRON','OS_CALLDLL',
+            'OR','OPTIONAL','OPTION','OPT','ONCE','ON','OFF','NUMBER',
+            'NOT','NEXT','NEW','MSGBOX','MOUSEPTR','MODULE','MODELESS','MODAL',
+            'MOD','MKWRD$','MKS$','MKQ$','MKL$','MKI$','MKE$','MKDWD$',
+            'MKD$','MKCUX$','MKCUR$','MKBYT$','MIN$','MIN','MID$','MENU',
+            'MDI_CREATE','MCASE$','MAX$','MAX','MAKWRD','MAKLNG','MAKINT','MAKDWR',
+            'LTRIM$','LSET$','LOWRD','LOOP','LONG','LOINT','LOG_WRITE','LOGB',
+            'LOG2','LOG10','LOG','LOCAL','LOC','LL_UPDATEBYNAME','LL_UPDATE','LL_TOSTRING',
+            'LL_TOFILE','LL_NAME','LL_GETITEM','LL_GETBYNUMBER','LL_FROMFILE','LL_FREE','LL_FINDLAST','LL_FINDBYNAME',
+            'LL_FINDBYDATA','LL_DELETELIKE','LL_DELETEBYNAME','LL_DELETE','LL_DATABYNAME','LL_DATA','LL_COUNT','LL_ADD',
+            'LISTBOX','LINE','LIBRARY_EXISTS','LIB','LEN','LEFT$','LEFT','LCASE$',
+            'LBOUND','LABEL','KILL','JOIN$','ITERATE','ISWINDOW','ISUNICODE','ISTRUE',
+            'ISODD','ISLIKE','ISFALSE','ISEVEN','IP_TOSTRING','IP_ADDR','INTERNALINFO','INTEGER',
+            'INT','INSTR','INSIDE','INPUTBOX$','INI_SETKEY','INI_GETSECTIONSLIST','INI_GETSECTIONKEYLIST','INI_GETKEY',
+            'INET_URLDOWNLOAD','INET_PING','INET_OPENDIALUPDIALOG','INET_GETSTATE','INET_GETREMOTEMACADDRESS','INET_GETIP','INET_GETCONNECTIONMODE','INCR',
+            'IN','IMAGE','IIF$','IIF','IF','ICRYPTO_TESTSHA1','ICRYPTO_TESTMD5','ICRYPTO_TESTCRC32',
+            'ICRYPTO_TESTCRC16','ICRYPTO_STRING2ASCII','ICRYPTO_SHA1','ICRYPTO_MD5','ICRYPTO_ENCRYPTRIJNDAEL','ICRYPTO_ENCRYPTRC4','ICRYPTO_DECRYPTRIJNDAEL','ICRYPTO_DECRYPTRC4',
+            'ICRYPTO_CRC32','ICRYPTO_CRC16','ICRYPTO_BYTEXOR','ICRYPTO_BIN2ASCII','ICRYPTO_ASCII2STRING','ICRYPTO_ASCII2BIN','HOST_ADDR','HOSTNAME_TOIP',
+            'HOSTIP_TONAME','HIWRD','HIINT','HEX$','HASH','HANDLE','GUIDTXT$','GUID$',
+            'GRAPHIC','GLVOID','GLUSHORT','GLUINT','GLUBYTE','GLSIZEI','GLSHORT','GLOBAL',
+            'GLINT','GLFLOAT','GLENUM','GLDOUBLE','GLCLAMPF','GLCLAMPD','GLBYTE','GLBOOLEAN',
+            'GLBITFIELD','GETWINDOWMULTIKEYSTATE','GETWINDOWKEYSTATE','GETTICKCOUNT','GETS','GETMULTIASYNCKEYSTATE','GETMESSAGE','GETCURRENTINSTANCE',
+            'GETAT','GETASYNCKEYSTATE','GET','FUNCTION_NPARAMS','FUNCTION_EXISTS','FUNCTION_CPARAMS','FUNCTION','FTP_SETSTRING',
+            'FTP_SETSERVERDIR','FTP_SETNUMBER','FTP_SETMODE','FTP_SETLOGFILE','FTP_SETLOCALDIR','FTP_QUIT','FTP_PUTFILE','FTP_GETSTRING',
+            'FTP_GETSERVERDIR','FTP_GETNUMBER','FTP_GETLOCALDIR','FTP_GETLIST','FTP_GETFILE','FTP_GETERRORSTRING','FTP_GETERRORNUMBER','FTP_FINISHED',
+            'FTP_EXTRACT','FTP_DELFILE','FTP_CONNECT','FTP_COMMAND','FRAME','FRAC','FORMAT$','FOR',
+            'FONT_LIST','FONT_CREATE','FONT','FOCUS','FLUSH','FIX','FILE_SIZE','FILE_SHELLDELETE',
+            'FILE_SHELLCOPY','FILE_SETDATETIME','FILE_SEEK','FILE_SAVE','FILE_RENAME','FILE_PUT','FILE_PATHSPLIT','FILE_OPEN',
+            'FILE_LOF','FILE_LOAD','FILE_LINEPRINT','FILE_LINEINPUT','FILE_KILL','FILE_GETVERSIONSTRING','FILE_GETVERSION','FILE_GETTIME',
+            'FILE_GETDATETIMESTAMP','FILE_GETDATETIME','FILE_GETDATE','FILE_GET','FILE_EXISTS','FILE_EOF','FILE_COPY','FILE_CLOSE',
+            'FILE_CHANGED','FILE_APPEND','FACTORIAL','EXTRACT$','EXT','EXPORT','EXP2','EXP10',
+            'EXP','EXIT','EVAL_STRING','EVAL_SETSTRING','EVAL_SETNUMBER','EVAL_MATH','EVAL_LINKEXT','EVAL_GETSTRING',
+            'EVAL_GETNUMBER','EVAL_ERRORGETTOKEN','EVAL_ERRORDESCRIPTION','EVAL_ERRORCLEAR','EVAL','ERRCLEAR','ERR','ENGINE_GETCURRENTTOKEN',
+            'ENDIF','END','ENABLE','ELSEIF','ELSE','ECHO','DWORD','DT_YEAR',
+            'DT_TIMETOSEC','DT_TIMESUBSECONDS','DT_TIMEFORMAT','DT_TIMEADDSECONDS','DT_SETTIMESEPARATOR','DT_SETDATESEPARATOR','DT_SETDATECENTURY','DT_SECTOTIME',
+            'DT_SECTODATE','DT_SECOND','DT_MONTH','DT_MINUTE','DT_LASTDAYOFMONTH','DT_ISVALIDDATE','DT_ISLEAPYEAR','DT_HOUR',
+            'DT_GETWEEKDAYNAME','DT_GETWEEKDAY','DT_GETTIMESTAMP','DT_GETTIMESEPARATOR','DT_GETMONTHNAME','DT_GETDATESEPARATOR','DT_GETDATECENTURY','DT_DAY',
+            'DT_DATETOSEC','DT_DATETIMESUBSECONDS','DT_DATETIMEADDSECONDS','DT_DATESUBDAYS','DT_DATEFORMAT','DT_DATEDIFF','DT_DATEADDDAYS','DT_COOKIEDATE',
+            'DRAW','DOUBLE','DOEVENTS','DO','DISABLE','DIR_REMOVE','DIR_MAKEALL','DIR_MAKE',
+            'DIR_LISTARRAY','DIR_LIST','DIR_ISEMPTY','DIR_ISDIR','DIR_GETCURRENT','DIR_EXISTS','DIR_CHANGEDRIVE','DIR_CHANGE',
+            'DIM','DICTIONARY_MEMINFO','DICTIONARY_LISTKEYS','DICTIONARY_FREE','DICTIONARY_FIND','DICTIONARY_EXISTS','DICTIONARY_CREATE','DICTIONARY_COUNT',
+            'DICTIONARY_ADD','DIALOG_STOPEVENTS','DIALOG_SAVEFILE','DIALOG_OPENFILE','DIALOG_GETCONTROL','DIALOG_CHOOSECOLOR','DIALOG_BROWSEFORFOLDER','DIALOG',
+            'DESKTOP','DESCENDING','DESCEND','DELETEOBJECT','DELETE','DEGTORAD','DECR','DECLARE',
+            'DATE$','CVWRD','CVS','CVQ','CVL','CVI','CVE','CVDWD',
+            'CVD','CVCUX','CVCUR','CVBYT','CURRENCY','CUR','CSET$','CSCH',
+            'CSC','CRYPTO_GETPROVIDERTYPESCOUNT','CRYPTO_GETPROVIDERSCOUNT','CRYPTO_GETDEFAULTPROVIDER','CRYPTO_GENRANDOMSTRING','CRYPTO_ENUMPROVIDERTYPES','CRYPTO_ENUMPROVIDERS','CRYPTO_ENCRYPT',
+            'CRYPTO_DECRYPT','CREATEFONT','COTH','COTAN','COSH','COS','CONTROL_SETTEXT','CONTROL_GETTEXT',
+            'CONTROL_GETNUMBER','CONTROL','CONST','CONSOLE_WRITELINE','CONSOLE_WRITE','CONSOLE_WAITKEY','CONSOLE_SHOWWINDOW','CONSOLE_SHOWCURSOR',
+            'CONSOLE_SETTITLE','CONSOLE_SETTEXTATTRIBUTE','CONSOLE_SETSTDHANDLE','CONSOLE_SETSCREENBUFFERSIZE','CONSOLE_SETPROGRESSBARCHAR','CONSOLE_SETOUTPUTMODE','CONSOLE_SETOUTPUTCP','CONSOLE_SETINPUTMODE',
+            'CONSOLE_SETFILEAPISTOOEM','CONSOLE_SETFILEAPISTOANSI','CONSOLE_SETCURSORSIZE','CONSOLE_SETCURSORPOSITION','CONSOLE_SETCP','CONSOLE_SETACTIVESCREENBUFFER','CONSOLE_SCROLLWINDOW','CONSOLE_SCROLLBUFFERONEROW',
+            'CONSOLE_SCROLLBUFFER','CONSOLE_SAVESCREEN','CONSOLE_RESTORESCREEN','CONSOLE_READLINE','CONSOLE_READ','CONSOLE_PROGRESSBAR','CONSOLE_PRINTLINE','CONSOLE_PRINTAT',
+            'CONSOLE_PRINT','CONSOLE_NORMALSCREEN','CONSOLE_LINE','CONSOLE_INKEYB','CONSOLE_INKEY','CONSOLE_HIDECURSOR','CONSOLE_GETTITLE','CONSOLE_GETTEXTATTRIBUTE',
+            'CONSOLE_GETSTDHANDLE','CONSOLE_GETSIZEY','CONSOLE_GETSIZEX','CONSOLE_GETPROGRESSBARCHAR','CONSOLE_GETOUTPUTMODE','CONSOLE_GETOUTPUTCP','CONSOLE_GETNUMBEROFMOUSEBUTTONS','CONSOLE_GETINPUTMODE',
+            'CONSOLE_GETCURSORY','CONSOLE_GETCURSORX','CONSOLE_GETCURSORSIZE','CONSOLE_GETCURRENTFONTINDEX','CONSOLE_GETCP','CONSOLE_GENERATECTRLEVENT','CONSOLE_FULLSCREEN','CONSOLE_FREE',
+            'CONSOLE_FOREGROUNDRGB','CONSOLE_ENABLECTRLC','CONSOLE_DISABLECTRLC','CONSOLE_CREATESCREENBUFFER','CONSOLE_COLORAT','CONSOLE_CLS','CONSOLE_BOX','CONSOLE_BACKGROUNDRGB',
+            'CONSOLE_ATTACH','CONSOLE_AREFILEAPISANSI','CONSOLE_ALLOC','COM_VARIANTINIT','COM_VARIANTCOPY','COM_VARIANTCLEAR','COM_SUCCEEDED','COM_STRINGFROMCLSID',
+            'COM_RELEASE','COM_QUERYINTERFACE','COM_PROGIDFROMCLSID','COM_ISEQUALIID','COM_ISEQUALGUID','COM_ISEQUALCLSID','COM_GETOBJECT','COM_GETENGINEGUID',
+            'COM_EXECUTE','COM_DISPLAYERROR','COM_CREATEOBJECT','COM_CLSIDFROMSTRING','COM_CLSIDFROMPROGID','COM_BUILDVARIANT','COMBOBOX','COMBINATIONS',
+            'COLOR','CLIPBOARD_SETTEXT','CLIPBOARD_GETTEXT','CLIENT','CLEARMESSAGES','CHR$','CHOOSE$','CHOOSE',
+            'CHECKBOX','CHECK3STATE','CHECK','CGI_WRITELOGFILE','CGI_WRITE','CGI_URLDECODESTRING','CGI_UPLOADFILESTIME','CGI_UPLOADFILESNUMBER',
+            'CGI_UPLOADFILESIZE','CGI_STARTSESSION','CGI_SETSESSIONVARIABLE','CGI_RESETDEFAULTSETTINGS','CGI_REMOVESPECIALCHARSPREFIX','CGI_REMOVEQUOTE','CGI_READ','CGI_LOADCONFIGFILE',
+            'CGI_HEADER','CGI_GETSESSIONVARIABLE','CGI_GETREQUESTMETHOD','CGI_GETQUERYVALUE','CGI_GETCURRENTSESSION','CGI_GETCURRENTGUID','CGI_ENVIRON','CGI_CFGSETOPTION',
+            'CGI_CFGGETOPTION','CGI_ADDSPECIALCHARSPREFIX','CGI_ADDQUOTE','CEIL','CASE','CALL','BYVAL','BYTE',
+            'BYREF','BYCMD','BUTTON','BUNDLE_SETSCRIPTPARAMETERS','BUNDLE_SETSCRIPTNAME','BUNDLE_SETFLAGOBFUSCATEMAINSCRIPT','BUNDLE_SETFLAGDELETEAFTERRUN','BUNDLE_SETFLAGCOMPRESSALLFILES',
+            'BUNDLE_SETFLAGASKBEFOREEXTRACT','BUNDLE_SETEXTRACTIONFOLDER','BUNDLE_SETCREATIONFOLDER','BUNDLE_SETBUNDLENAME','BUNDLE_RESET','BUNDLE_MAKE','BUNDLE_BUILDER','BUNDLE_ADDFOLDER',
+            'BUNDLE_ADDFILE','BOUNDCHECK','BIN$','BIFF_WRITETEXT','BIFF_WRITENUMBER','BIFF_WRITEDATE','BIFF_SETROWHEIGHT','BIFF_SETCOLWIDTH',
+            'BIFF_SETBUFFER','BIFF_CREATEFILE','BIFF_CLOSEFILE','BETWEEN','BEEP','BAR','ATTACH','ATN',
+            'AT','ASSIGN','ASCIZ','ASCIIZ','ASCII2UNICODE','ASCENDING','ASCEND','ASC',
+            'AS','ARRAY','ARCTANH','ARCSINH','ARCSIN','ARCSECH','ARCSEC','ARCCSCH',
+            'ARCCSC','ARCCOTH','ARCCOT','ARCCOSH','ARCCOS','APP_TIMER','APP_SOURCEPATH','APP_SOURCENAME',
+            'APP_SOURCEFULLNAME','APP_PATH','APP_NAME','APP_LISTVARIABLES','APP_LISTKEYWORDS','APP_LISTFUNCTIONS','APP_LISTEQUATES','APP_INCLUDEPATH',
+            'APP_GETMODULEFULLPATH','APP_COUNTER','APPEND','ANY','ANIMATE_STOP','ANIMATE_PLAY','ANIMATE_OPEN','AND',
+            'ALIAS','ALERT','ADD','ACODE$','ABS','%DEF','#MINVERSION','#IF',
+            '#ENDIF','#ELSEIF','#ELSE','#DEFAULT','#DEF','SQLWRITEPRIVATEPROFILESTRING','SQLWRITEFILEDSN','SQLWRITEDSNTOINI',
+            'SQLVALIDDSN','SQLTRANSACT','SQLTABLES','SQLTABLEPRIVILEGES','SQLSTATISTICS','SQLSPECIALCOLUMNS','SQLSETSTMTOPTION','SQLSETSTMTATTR',
+            'SQLSETSCROLLOPTIONS','SQLSETPOS','SQLSETPARAM','SQLSETENVATTR','SQLSETDESCREC','SQLSETDESCFIELD','SQLSETCURSORNAME','SQLSETCONNECTOPTION',
+            'SQLSETCONNECTATTR','SQLSETCONFIGMODE','SQLROWCOUNT','SQLREMOVETRANSLATOR','SQLREMOVEDSNFROMINI','SQLREMOVEDRIVERMANAGER','SQLREMOVEDRIVER','SQLREADFILEDSN',
+            'SQLPUTDATA','SQLPROCEDURES','SQLPROCEDURECOLUMNS','SQLPRIMARYKEYS','SQLPREPARE','SQLPOSTINSTALLERERROR','SQLPARAMOPTIONS','SQLPARAMDATA',
+            'SQLNUMRESULTCOLS','SQLNUMPARAMS','SQLNATIVESQL','SQLMORERESULTS','SQLMANAGEDATASOURCES','SQLINSTALLTRANSLATOREX','SQLINSTALLERERROR','SQLINSTALLDRIVERMANAGER',
+            'SQLINSTALLDRIVEREX','SQLGETTYPEINFO','SQLGETTRANSLATOR','SQLGETSTMTOPTION','SQLGETSTMTATTR','SQLGETPRIVATEPROFILESTRING','SQLGETINSTALLEDDRIVERS','SQLGETINFO',
+            'SQLGETFUNCTIONS','SQLGETENVATTR','SQLGETDIAGREC','SQLGETDIAGFIELD','SQLGETDESCREC','SQLGETDESCFIELD','SQLGETDATA','SQLGETCURSORNAME',
+            'SQLGETCONNECTOPTION','SQLGETCONNECTATTR','SQLGETCONFIGMODE','SQLFREESTMT','SQLFREEHANDLE','SQLFREEENV','SQLFREECONNECT','SQLFOREIGNKEYS',
+            'SQLFETCHSCROLL','SQLFETCH','SQLEXTENDEDFETCH','SQLEXECUTE','SQLEXECDIRECT','SQLERROR','SQLENDTRAN','SQLDRIVERS',
+            'SQLDRIVERCONNECT','SQLDISCONNECT','SQLDESCRIBEPARAM','SQLDESCRIBECOL','SQLDATASOURCES','SQLCREATEDATASOURCE','SQLCOPYDESC','SQLCONNECT',
+            'SQLCONFIGDRIVER','SQLCONFIGDATASOURCE','SQLCOLUMNS','SQLCOLUMNPRIVILEGES','SQLCOLATTRIBUTES','SQLCOLATTRIBUTE','SQLCLOSECURSOR','SQLCANCEL',
+            'SQLBULKOPERATIONS','SQLBROWSECONNECT','SQLBINDPARAMETER','SQLBINDPARAM','SQLBINDCOL','SQLALLOCSTMT','SQLALLOCHANDLE','SQLALLOCENV',
+            'SQLALLOCCONNECT','ODBCWRONGDRIVER','ODBCWRITEPRIVATEPROFILESTRING','ODBCWRITEFILEDSN','ODBCWRITEDSNTOINI','ODBCVALIDDSN','ODBCUPDATERECORD','ODBCUPDATEBYBOOKMARK',
+            'ODBCUNLOCKRECORD','ODBCUNBINDCOLUMNS','ODBCUNBINDCOL','ODBCTABLESCOUNT','ODBCTABLES','ODBCTABLEPRIVILEGESCOUNT','ODBCTABLEPRIVILEGES','ODBCSUPPORTS',
+            'ODBCSTATTABLESCHEMANAME','ODBCSTATTABLEPAGES','ODBCSTATTABLECATALOGNAME','ODBCSTATTABLECARDINALITY','ODBCSTATISTICSCOUNT','ODBCSTATISTICS','ODBCSTATINDEXSORTSEQUENCE','ODBCSTATINDEXSCHEMANAME',
+            'ODBCSTATINDEXQUALIFIER','ODBCSTATINDEXPAGES','ODBCSTATINDEXFILTERCONDITION','ODBCSTATINDEXCOLUMNORDINALPOSITION','ODBCSTATINDEXCOLUMNNAME','ODBCSTATINDEXCATALOGNAME','ODBCSTATINDEXCARDINALITY','ODBCSTATINDEXALLOWDUPLICATES',
+            'ODBCSPECIALCOLUMNSCOUNT','ODBCSPECIALCOLUMNS','ODBCSETTXNISOLATION','ODBCSETTRANSLATELIB','ODBCSETTRACEFILE','ODBCSETTRACE','ODBCSETSTMTUSEBOOKMARKS','ODBCSETSTMTSIMULATECURSOR',
+            'ODBCSETSTMTROWSTATUSPTR','ODBCSETSTMTROWSFETCHEDPTR','ODBCSETSTMTROWOPERATIONPTR','ODBCSETSTMTROWBINDTYPE','ODBCSETSTMTROWBINDOFFSETPTR','ODBCSETSTMTROWARRAYSIZE','ODBCSETSTMTRETRIEVEDATA','ODBCSETSTMTQUERYTIMEOUT',
+            'ODBCSETSTMTPARAMSTATUSPTR','ODBCSETSTMTPARAMSPROCESSEDPTR','ODBCSETSTMTPARAMSETSIZE','ODBCSETSTMTPARAMOPERATIONPTR','ODBCSETSTMTPARAMBINDTYPE','ODBCSETSTMTPARAMBINDOFFSETPTR','ODBCSETSTMTNOSCAN','ODBCSETSTMTMETADATAID',
+            'ODBCSETSTMTMAXROWS','ODBCSETSTMTMAXLENGTH','ODBCSETSTMTKEYSETSIZE','ODBCSETSTMTFETCHBOOKMARKPTR','ODBCSETSTMTENABLEAUTOIPD','ODBCSETSTMTCURSORTYPE','ODBCSETSTMTCURSORSENSITIVITY','ODBCSETSTMTCURSORSCROLLABLE',
+            'ODBCSETSTMTCONCURRENCY','ODBCSETSTMTATTR','ODBCSETSTMTASYNCENABLE','ODBCSETSTMTAPPROWDESC','ODBCSETSTMTAPPPARAMDESC','ODBCSETSTATICCURSOR','ODBCSETROWVERCONCURRENCY','ODBCSETRESULT',
+            'ODBCSETRELATIVEPOSITION','ODBCSETREADONLYCONCURRENCY','ODBCSETQUIETMODE','ODBCSETPOSITION','ODBCSETPOS','ODBCSETPACKETMODE','ODBCSETOPTIMISTICCONCURRENCY','ODBCSETODBCCURSORS',
+            'ODBCSETMULTIUSERKEYSETCURSOR','ODBCSETMETADATAID','ODBCSETLOGINTIMEOUT','ODBCSETLOCKCONCURRENCY','ODBCSETKEYSETDRIVENCURSOR','ODBCSETFORWARDONLYCURSOR','ODBCSETENVOUTPUTNTS','ODBCSETENVODBCVERSION',
+            'ODBCSETENVCPMATCH','ODBCSETENVCONNECTIONPOOLING','ODBCSETENVATTR','ODBCSETDYNAMICCURSOR','ODBCSETDESCREC','ODBCSETDESCFIELD','ODBCSETCURSORTYPE','ODBCSETCURSORSENSITIVITY',
+            'ODBCSETCURSORSCROLLABILITY','ODBCSETCURSORNAME','ODBCSETCURSORLOCKTYPE','ODBCSETCURSORKEYSETSIZE','ODBCSETCURSORCONCURRENCY','ODBCSETCURRENTCATALOG','ODBCSETCONNECTIONTIMEOUT','ODBCSETCONNECTATTR',
+            'ODBCSETCONFIGMODE','ODBCSETCONCURVALUESCONCURRENCY','ODBCSETAUTOCOMMITON','ODBCSETAUTOCOMMITOFF','ODBCSETAUTOCOMMIT','ODBCSETASYNCENABLE','ODBCSETACCESSMODE','ODBCSETABSOLUTEPOSITION',
+            'ODBCROWCOUNT','ODBCROLLBACKTRAN','ODBCROLLBACKENVTRAN','ODBCROLLBACKDBCTRAN','ODBCRESULT','ODBCRESETPARAMS','ODBCREMOVETRANSLATOR','ODBCREMOVEDSNFROMINI',
+            'ODBCREMOVEDRIVERMANAGER','ODBCREMOVEDRIVER','ODBCREFRESHRECORD','ODBCRECORDCOUNT','ODBCREADFILEDSN','ODBCQUOTEDIDENTIFIERCASE','ODBCPUTDATA','ODBCPROCEDURESCOUNT',
+            'ODBCPROCEDURES','ODBCPROCEDURECOLUMNSCOUNT','ODBCPROCEDURECOLUMNS','ODBCPRIMARYKEYSCOUNT','ODBCPRIMARYKEYS','ODBCPREPARE','ODBCPOSTINSTALLERERROR','ODBCPARAMDATA',
+            'ODBCOPENSTMT','ODBCOPENCONNECTION','ODBCNUMRESULTCOLS','ODBCNUMPARAMS','ODBCNATIVESQL','ODBCMOVEPREVIOUS','ODBCMOVENEXT','ODBCMOVELAST',
+            'ODBCMOVEFIRST','ODBCMOVE','ODBCMORERESULTS','ODBCMANAGEDATASOURCES','ODBCLOCKRECORD','ODBCINSTALLTRANSLATOREX','ODBCINSTALLERERROR','ODBCINSTALLDRIVERMANAGER',
+            'ODBCINSTALLDRIVEREX','ODBCGETXOPENCLIYEAR','ODBCGETUSERNAME','ODBCGETUNION','ODBCGETTYPEINFOCOUNT','ODBCGETTYPEINFO','ODBCGETTXNISOLATIONOPTION','ODBCGETTXNISOLATION',
+            'ODBCGETTXNCAPABLE','ODBCGETTRANSLATOR','ODBCGETTRANSLATELIB','ODBCGETTRACEFILE','ODBCGETTRACE','ODBCGETTIMEDATEFUNCTIONS','ODBCGETTIMEDATEDIFFINTERVALS','ODBCGETTIMEDATEADDINTERVALS',
+            'ODBCGETTABLETERM','ODBCGETSYSTEMFUNCTIONS','ODBCGETSUBQUERIES','ODBCGETSTRINGFUNCTIONS','ODBCGETSTMTUSEBOOKMARKS','ODBCGETSTMTSQLSTATE','ODBCGETSTMTSIMULATECURSOR','ODBCGETSTMTROWSTATUSPTR',
+            'ODBCGETSTMTROWSFETCHEDPTR','ODBCGETSTMTROWOPERATIONPTR','ODBCGETSTMTROWNUMBER','ODBCGETSTMTROWBINDTYPE','ODBCGETSTMTROWBINDOFFSETPTR','ODBCGETSTMTROWARRAYSIZE','ODBCGETSTMTRETRIEVEDATA','ODBCGETSTMTQUERYTIMEOUT',
+            'ODBCGETSTMTPARAMSTATUSPTR','ODBCGETSTMTPARAMSPROCESSEDPTR','ODBCGETSTMTPARAMSETSIZE','ODBCGETSTMTPARAMOPERATIONPTR','ODBCGETSTMTPARAMBINDTYPE','ODBCGETSTMTPARAMBINDOFFSETPTR','ODBCGETSTMTNOSCAN','ODBCGETSTMTMETADATAID',
+            'ODBCGETSTMTMAXROWS','ODBCGETSTMTMAXLENGTH','ODBCGETSTMTKEYSETSIZE','ODBCGETSTMTIMPROWDESC','ODBCGETSTMTIMPPARAMDESC','ODBCGETSTMTFETCHBOOKMARKPTR','ODBCGETSTMTERRORINFO','ODBCGETSTMTENABLEAUTOIPD',
+            'ODBCGETSTMTCURSORTYPE','ODBCGETSTMTCURSORSENSITIVITY','ODBCGETSTMTCURSORSCROLLABLE','ODBCGETSTMTCONCURRENCY','ODBCGETSTMTATTR','ODBCGETSTMTASYNCENABLE','ODBCGETSTMTAPPROWDESC','ODBCGETSTMTAPPPARAMDESC',
+            'ODBCGETSTATICCURSORATTRIBUTES2','ODBCGETSTATICCURSORATTRIBUTES1','ODBCGETSTATEMENTSQLSTATE','ODBCGETSTATEMENTERRORINFO','ODBCGETSTANDARDCLICONFORMANCE','ODBCGETSQLSTATE','ODBCGETSQLCONFORMANCE','ODBCGETSQL92VALUEEXPRESSIONS',
+            'ODBCGETSQL92STRINGFUNCTIONS','ODBCGETSQL92ROWVALUECONSTRUCTOR','ODBCGETSQL92REVOKE','ODBCGETSQL92RELATIONALJOINOPERATORS','ODBCGETSQL92PREDICATES','ODBCGETSQL92NUMERICVALUEFUNCTIONS','ODBCGETSQL92GRANT','ODBCGETSQL92FOREIGNKEYUPDATERULE',
+            'ODBCGETSQL92FOREIGNKEYDELETERULE','ODBCGETSQL92DATETIMEFUNCTIONS','ODBCGETSPECIALCHARACTERS','ODBCGETSERVERNAME','ODBCGETSEARCHPATTERNESCAPE','ODBCGETSCROLLOPTIONS','ODBCGETSCHEMAUSAGE','ODBCGETSCHEMATERM',
+            'ODBCGETROWUPDATES','ODBCGETQUIETMODE','ODBCGETPROCEDURETERM','ODBCGETPROCEDURESSUPPORT','ODBCGETPRIVATEPROFILESTRING','ODBCGETPOSOPERATIONS','ODBCGETPARAMARRAYSELECTS','ODBCGETPARAMARRAYROWCOUNTS',
+            'ODBCGETPACKETMODE','ODBCGETOUTERJOINS','ODBCGETORDERBYCOLUMNSINSELECT','ODBCGETOJCAPABILITIES','ODBCGETODBCVER','ODBCGETODBCINTERFACECONFORMANCE','ODBCGETODBCCURSORS','ODBCGETNUMERICFUNCTIONS',
+            'ODBCGETNULLCOLLATION','ODBCGETNONNULLABLECOLUMNS','ODBCGETNEEDLONGDATALEN','ODBCGETMULTRESULTSETS','ODBCGETMULTIPLEACTIVETXN','ODBCGETMETADATAID','ODBCGETMAXUSERNAMELEN','ODBCGETMAXTABLESINSELECT',
+            'ODBCGETMAXTABLENAMELEN','ODBCGETMAXSTATEMENTLEN','ODBCGETMAXSCHEMANAMELEN','ODBCGETMAXROWSIZEINCLUDESLONG','ODBCGETMAXROWSIZE','ODBCGETMAXPROCEDURENAMELEN','ODBCGETMAXINDEXSIZE','ODBCGETMAXIDENTIFIERLEN',
+            'ODBCGETMAXDRIVERCONNECTIONS','ODBCGETMAXCURSORNAMELEN','ODBCGETMAXCONCURRENTACTIVITIES','ODBCGETMAXCOLUMNSINTABLE','ODBCGETMAXCOLUMNSINSELECT','ODBCGETMAXCOLUMNSINORDERBY','ODBCGETMAXCOLUMNSININDEX','ODBCGETMAXCOLUMNSINGROUPBY',
+            'ODBCGETMAXCOLUMNNAMELEN','ODBCGETMAXCHARLITERALLEN','ODBCGETMAXCATALOGNAMELEN','ODBCGETMAXBINARYLITERALLEN','ODBCGETMAXASYNCCONCURRENTSTATEMENTS','ODBCGETLONGVARCHARDATABYCOLNAME','ODBCGETLONGVARCHARDATA','ODBCGETLOGINTIMEOUT',
+            'ODBCGETLIKEESCAPECLAUSE','ODBCGETKEYWORDS','ODBCGETKEYSETCURSORATTRIBUTES2','ODBCGETKEYSETCURSORATTRIBUTES1','ODBCGETINTEGRITY','ODBCGETINSTALLERERRORMESSAGE','ODBCGETINSTALLERERRORCODE','ODBCGETINSTALLEDDRIVERS',
+            'ODBCGETINSERTSTATEMENT','ODBCGETINFOSTR','ODBCGETINFOSCHEMAVIEWS','ODBCGETINFOLONG','ODBCGETINFOINT','ODBCGETINFO','ODBCGETINDEXKEYWORDS','ODBCGETIMPROWDESCREC',
+            'ODBCGETIMPROWDESCFIELDTYPE','ODBCGETIMPROWDESCFIELDSCALE','ODBCGETIMPROWDESCFIELDPRECISION','ODBCGETIMPROWDESCFIELDOCTETLENGTH','ODBCGETIMPROWDESCFIELDNULLABLE','ODBCGETIMPROWDESCFIELDNAME','ODBCGETIMPROWDESCFIELD','ODBCGETIMPPARAMDESCREC',
+            'ODBCGETIMPPARAMDESCFIELDTYPE','ODBCGETIMPPARAMDESCFIELDSCALE','ODBCGETIMPPARAMDESCFIELDPRECISION','ODBCGETIMPPARAMDESCFIELDOCTETLENGTH','ODBCGETIMPPARAMDESCFIELDNULLABLE','ODBCGETIMPPARAMDESCFIELDNAME','ODBCGETIMPPARAMDESCFIELD','ODBCGETIDENTIFIERQUOTECHAR',
+            'ODBCGETIDENTIFIERCASE','ODBCGETGROUPBY','ODBCGETFUNCTIONS','ODBCGETFORWARDONLYCURSORATTRIBUTES2','ODBCGETFORWARDONLYCURSORATTRIBUTES1','ODBCGETFILEUSAGE','ODBCGETEXPRESSIONSINORDERBY','ODBCGETERRORINFO',
+            'ODBCGETENVSQLSTATE','ODBCGETENVOUTPUTNTS','ODBCGETENVODBCVERSION','ODBCGETENVIRONMENTSQLSTATE','ODBCGETENVIRONMENTERRORINFO','ODBCGETENVERRORINFO','ODBCGETENVCPMATCH','ODBCGETENVCONNECTIONPOOLING',
+            'ODBCGETENVATTR','ODBCGETDYNAMICCURSORATTRIBUTES2','ODBCGETDYNAMICCURSORATTRIBUTES1','ODBCGETDROPVIEW','ODBCGETDROPTRANSLATION','ODBCGETDROPTABLE','ODBCGETDROPSCHEMA','ODBCGETDROPDOMAIN',
+            'ODBCGETDROPCOLLATION','ODBCGETDROPCHARACTERSET','ODBCGETDROPASSERTION','ODBCGETDRIVERVER','ODBCGETDRIVERODBCVER','ODBCGETDRIVERNAME','ODBCGETDRIVERMANAGERINSTALLPATH','ODBCGETDRIVERHLIB',
+            'ODBCGETDRIVERHENV','ODBCGETDRIVERHDBC','ODBCGETDMVERMINOR','ODBCGETDMVERMAJOR','ODBCGETDMVER','ODBCGETDIAGREC','ODBCGETDIAGFIELD','ODBCGETDESCSQLSTATE',
+            'ODBCGETDESCRIPTORSQLSTATE','ODBCGETDESCRIPTORERRORINFO','ODBCGETDESCRIBEPARAMETER','ODBCGETDESCREC','ODBCGETDESCFIELD','ODBCGETDESCERRORINFO','ODBCGETDEFAULTTXNISOLATION','ODBCGETDDLINDEX',
+            'ODBCGETDBMSVER','ODBCGETDBMSNAME','ODBCGETDBCSQLSTATE','ODBCGETDBCERRORINFO','ODBCGETDATETIMELITERALS','ODBCGETDATASTRINGBYCOLNAME','ODBCGETDATASTRING','ODBCGETDATASOURCEREADONLY',
+            'ODBCGETDATASOURCENAME','ODBCGETDATAEXTENSIONS','ODBCGETDATABASENAME','ODBCGETDATA','ODBCGETCURSORTYPE','ODBCGETCURSORSENSITIVITYSUPPORT','ODBCGETCURSORSENSITIVITY','ODBCGETCURSORSCROLLABILITY',
+            'ODBCGETCURSORROLLBACKBEHAVIOR','ODBCGETCURSORNAME','ODBCGETCURSORLOCKTYPE','ODBCGETCURSORKEYSETSIZE','ODBCGETCURSORCONCURRENCY','ODBCGETCURSORCOMMITBEHAVIOR','ODBCGETCURRENTCATALOG','ODBCGETCREATEVIEW',
+            'ODBCGETCREATETRANSLATION','ODBCGETCREATETABLE','ODBCGETCREATESCHEMA','ODBCGETCREATEDOMAIN','ODBCGETCREATECOLLATION','ODBCGETCREATECHARACTERSET','ODBCGETCREATEASSERTION','ODBCGETCORRELATIONNAME',
+            'ODBCGETCONVERTVARCHAR','ODBCGETCONVERTVARBINARY','ODBCGETCONVERTTINYINT','ODBCGETCONVERTTIMESTAMP','ODBCGETCONVERTTIME','ODBCGETCONVERTSMALLINT','ODBCGETCONVERTREAL','ODBCGETCONVERTNUMERIC',
+            'ODBCGETCONVERTLONGVARCHAR','ODBCGETCONVERTLONGVARBINARY','ODBCGETCONVERTINTERVALYEARMONTH','ODBCGETCONVERTINTERVALDAYTIME','ODBCGETCONVERTINTEGER','ODBCGETCONVERTFUNCTIONS','ODBCGETCONVERTFLOAT','ODBCGETCONVERTDOUBLE',
+            'ODBCGETCONVERTDECIMAL','ODBCGETCONVERTDATE','ODBCGETCONVERTCHAR','ODBCGETCONVERTBIT','ODBCGETCONVERTBINARY','ODBCGETCONVERTBIGINT','ODBCGETCONNECTIONTIMEOUT','ODBCGETCONNECTIONSQLSTATE',
+            'ODBCGETCONNECTIONERRORINFO','ODBCGETCONNECTIONDEAD','ODBCGETCONNECTATTR','ODBCGETCONFIGMODE','ODBCGETCONCATNULLBEHAVIOR','ODBCGETCOLUMNALIAS','ODBCGETCOLLATIONSEQ','ODBCGETCATALOGUSAGE',
+            'ODBCGETCATALOGTERM','ODBCGETCATALOGNAMESEPARATOR','ODBCGETCATALOGNAME','ODBCGETCATALOGLOCATION','ODBCGETBOOKMARKPERSISTENCE','ODBCGETBATCHSUPPORT','ODBCGETBATCHROWCOUNT','ODBCGETAUTOIPD',
+            'ODBCGETAUTOCOMMIT','ODBCGETASYNCMODE','ODBCGETASYNCENABLE','ODBCGETALTERTABLE','ODBCGETALTERDOMAIN','ODBCGETAGGREGATEFUNCTIONS','ODBCGETACTIVEENVIRONMENTS','ODBCGETACCESSMODE',
+            'ODBCGETACCESSIBLETABLES','ODBCGETACCESSIBLEPROCEDURES','ODBCFREESTMT','ODBCFREEHANDLE','ODBCFREEENV','ODBCFREEDESC','ODBCFREEDBC','ODBCFREECONNECT',
+            'ODBCFOREIGNKEYSCOUNT','ODBCFOREIGNKEYS','ODBCFETCHSCROLL','ODBCFETCHBYBOOKMARK','ODBCFETCH','ODBCEXTENDEDFETCH','ODBCEXECUTE','ODBCEXECDIRECT',
+            'ODBCERROR','ODBCEOF','ODBCENDTRAN','ODBCDRIVERSCOUNT','ODBCDRIVERS','ODBCDRIVERCONNECT','ODBCDISCONNECT','ODBCDESCRIBEPARAM',
+            'ODBCDESCRIBECOL','ODBCDELETERECORD','ODBCDELETEBYBOOKMARK','ODBCDATASOURCES','ODBCCREATEDATASOURCE','ODBCCOPYDESC','ODBCCONNECTIONISDEAD','ODBCCONNECTIONISALIVE',
+            'ODBCCONNECT','ODBCCONFIGDRIVER','ODBCCONFIGDATASOURCE','ODBCCOMMITTRAN','ODBCCOMMITENVTRAN','ODBCCOMMITDBCTRAN','ODBCCOLUPDATABLE','ODBCCOLUNSIGNED',
+            'ODBCCOLUNNAMED','ODBCCOLUMNSCOUNT','ODBCCOLUMNS','ODBCCOLUMNPRIVILEGESCOUNT','ODBCCOLUMNPRIVILEGES','ODBCCOLUMN','ODBCCOLTYPENAME','ODBCCOLTYPE',
+            'ODBCCOLTABLENAME','ODBCCOLSEARCHABLE','ODBCCOLSCHEMANAME','ODBCCOLSCALE','ODBCCOLPRECISION','ODBCCOLOCTETLENGTH','ODBCCOLNUMPRECRADIX','ODBCCOLNULLABLE',
+            'ODBCCOLNAME','ODBCCOLLOCALTYPENAME','ODBCCOLLITERALSUFFIX','ODBCCOLLITERALPREFIX','ODBCCOLLENGTH','ODBCCOLLABEL','ODBCCOLISNULL','ODBCCOLFIXEDPRECSCALE',
+            'ODBCCOLDISPLAYSIZE','ODBCCOLCOUNT','ODBCCOLCONCISETYPE','ODBCCOLCATALOGNAME','ODBCCOLCASESENSITIVE','ODBCCOLBASETABLENAME','ODBCCOLBASECOLUMNNAME','ODBCCOLAUTOUNIQUEVALUE',
+            'ODBCCOLATTRIBUTE','ODBCCLOSESTMTCURSOR','ODBCCLOSESTMT','ODBCCLOSECURSOR','ODBCCLOSECONNECTION','ODBCCLEARRESULT','ODBCCANCEL','ODBCBULKOPERATIONS',
+            'ODBCBROWSECONNECT','ODBCBINDPARAMETER','ODBCBINDCOLTOWORD','ODBCBINDCOLTOTIMESTAMP','ODBCBINDCOLTOTIME','ODBCBINDCOLTOSTRING','ODBCBINDCOLTOSINGLE','ODBCBINDCOLTOQUAD',
+            'ODBCBINDCOLTONUMERIC','ODBCBINDCOLTOLONG','ODBCBINDCOLTOINTEGER','ODBCBINDCOLTODWORD','ODBCBINDCOLTODOUBLE','ODBCBINDCOLTODECIMAL','ODBCBINDCOLTODATE','ODBCBINDCOLTOCURRENCY',
+            'ODBCBINDCOLTOBYTE','ODBCBINDCOLTOBIT','ODBCBINDCOLTOBINARY','ODBCBINDCOL','ODBCALLOCSTMT','ODBCALLOCHANDLE','ODBCALLOCENV','ODBCALLOCDESC',
+            'ODBCALLOCDBC','ODBCALLOCCONNECT','ODBCADDRECORD','GLVIEWPORT','GLVERTEXPOINTER','GLVERTEX4SV','GLVERTEX4S','GLVERTEX4IV',
+            'GLVERTEX4I','GLVERTEX4FV','GLVERTEX4F','GLVERTEX4DV','GLVERTEX4D','GLVERTEX3SV','GLVERTEX3S','GLVERTEX3IV',
+            'GLVERTEX3I','GLVERTEX3FV','GLVERTEX3F','GLVERTEX3DV','GLVERTEX3D','GLVERTEX2SV','GLVERTEX2S','GLVERTEX2IV',
+            'GLVERTEX2I','GLVERTEX2FV','GLVERTEX2F','GLVERTEX2DV','GLVERTEX2D','GLUUNPROJECT','GLUTESSVERTEX','GLUTESSPROPERTY',
+            'GLUTESSNORMAL','GLUTESSENDPOLYGON','GLUTESSENDCONTOUR','GLUTESSCALLBACK','GLUTESSBEGINPOLYGON','GLUTESSBEGINCONTOUR','GLUSPHERE','GLUSCALEIMAGE',
+            'GLUQUADRICTEXTURE','GLUQUADRICORIENTATION','GLUQUADRICNORMALS','GLUQUADRICDRAWSTYLE','GLUQUADRICCALLBACK','GLUPWLCURVE','GLUPROJECT','GLUPICKMATRIX',
+            'GLUPERSPECTIVE','GLUPARTIALDISK','GLUORTHO2D','GLUNURBSSURFACE','GLUNURBSPROPERTY','GLUNURBSCURVE','GLUNURBSCALLBACK','GLUNEXTCONTOUR',
+            'GLUNEWTESS','GLUNEWQUADRIC','GLUNEWNURBSRENDERER','GLULOOKAT','GLULOADSAMPLINGMATRICES','GLUGETTESSPROPERTY','GLUGETSTRING','GLUGETNURBSPROPERTY',
+            'GLUERRORSTRING','GLUENDTRIM','GLUENDSURFACE','GLUENDPOLYGON','GLUENDCURVE','GLUDISK','GLUDELETETESS','GLUDELETEQUADRIC',
+            'GLUDELETENURBSRENDERER','GLUCYLINDER','GLUBUILD2DMIPMAPS','GLUBUILD1DMIPMAPS','GLUBEGINTRIM','GLUBEGINSURFACE','GLUBEGINPOLYGON','GLUBEGINCURVE',
+            'GLTRANSLATEF','GLTRANSLATED','GLTEXSUBIMAGE2D','GLTEXSUBIMAGE1D','GLTEXPARAMETERIV','GLTEXPARAMETERI','GLTEXPARAMETERFV','GLTEXPARAMETERF',
+            'GLTEXIMAGE2D','GLTEXIMAGE1D','GLTEXGENIV','GLTEXGENI','GLTEXGENFV','GLTEXGENF','GLTEXGENDV','GLTEXGEND',
+            'GLTEXENVIV','GLTEXENVI','GLTEXENVFV','GLTEXENVF','GLTEXCOORDPOINTER','GLTEXCOORD4SV','GLTEXCOORD4S','GLTEXCOORD4IV',
+            'GLTEXCOORD4I','GLTEXCOORD4FV','GLTEXCOORD4F','GLTEXCOORD4DV','GLTEXCOORD4D','GLTEXCOORD3SV','GLTEXCOORD3S','GLTEXCOORD3IV',
+            'GLTEXCOORD3I','GLTEXCOORD3FV','GLTEXCOORD3F','GLTEXCOORD3DV','GLTEXCOORD3D','GLTEXCOORD2SV','GLTEXCOORD2S','GLTEXCOORD2IV',
+            'GLTEXCOORD2I','GLTEXCOORD2FV','GLTEXCOORD2F','GLTEXCOORD2DV','GLTEXCOORD2D','GLTEXCOORD1SV','GLTEXCOORD1S','GLTEXCOORD1IV',
+            'GLTEXCOORD1I','GLTEXCOORD1FV','GLTEXCOORD1F','GLTEXCOORD1DV','GLTEXCOORD1D','GLSTENCILOP','GLSTENCILMASK','GLSTENCILFUNC',
+            'GLSHADEMODEL','GLSELECTBUFFER','GLSCISSOR','GLSCALEF','GLSCALED','GLROTATEF','GLROTATED','GLRENDERMODE',
+            'GLRECTSV','GLRECTS','GLRECTIV','GLRECTI','GLRECTFV','GLRECTF','GLRECTDV','GLRECTD',
+            'GLREADPIXELS','GLREADBUFFER','GLRASTERPOS4SV','GLRASTERPOS4S','GLRASTERPOS4IV','GLRASTERPOS4I','GLRASTERPOS4FV','GLRASTERPOS4F',
+            'GLRASTERPOS4DV','GLRASTERPOS4D','GLRASTERPOS3SV','GLRASTERPOS3S','GLRASTERPOS3IV','GLRASTERPOS3I','GLRASTERPOS3FV','GLRASTERPOS3F',
+            'GLRASTERPOS3DV','GLRASTERPOS3D','GLRASTERPOS2SV','GLRASTERPOS2S','GLRASTERPOS2IV','GLRASTERPOS2I','GLRASTERPOS2FV','GLRASTERPOS2F',
+            'GLRASTERPOS2DV','GLRASTERPOS2D','GLPUSHNAME','GLPUSHMATRIX','GLPUSHCLIENTATTRIB','GLPUSHATTRIB','GLPRIORITIZETEXTURES','GLPOPNAME',
+            'GLPOPMATRIX','GLPOPCLIENTATTRIB','GLPOPATTRIB','GLPOLYGONSTIPPLE','GLPOLYGONOFFSET','GLPOLYGONMODE','GLPOINTSIZE','GLPIXELZOOM',
+            'GLPIXELTRANSFERI','GLPIXELTRANSFERF','GLPIXELSTOREI','GLPIXELSTOREF','GLPIXELMAPUSV','GLPIXELMAPUIV','GLPIXELMAPFV','GLPASSTHROUGH',
+            'GLORTHO','GLNORMALPOINTER','GLNORMAL3SV','GLNORMAL3S','GLNORMAL3IV','GLNORMAL3I','GLNORMAL3FV','GLNORMAL3F',
+            'GLNORMAL3DV','GLNORMAL3D','GLNORMAL3BV','GLNORMAL3B','GLNEWLIST','GLMULTMATRIXF','GLMULTMATRIXD','GLMATRIXMODE',
+            'GLMATERIALIV','GLMATERIALI','GLMATERIALFV','GLMATERIALF','GLMAPGRID2F','GLMAPGRID2D','GLMAPGRID1F','GLMAPGRID1D',
+            'GLMAP2F','GLMAP2D','GLMAP1F','GLMAP1D','GLLOGICOP','GLLOADNAME','GLLOADMATRIXF','GLLOADMATRIXD',
+            'GLLOADIDENTITY','GLLISTBASE','GLLINEWIDTH','GLLINESTIPPLE','GLLIGHTMODELIV','GLLIGHTMODELI','GLLIGHTMODELFV','GLLIGHTMODELF',
+            'GLLIGHTIV','GLLIGHTI','GLLIGHTFV','GLLIGHTF','GLISTEXTURE','GLISLIST','GLISENABLED','GLINTERLEAVEDARRAYS',
+            'GLINITNAMES','GLINDEXUBV','GLINDEXUB','GLINDEXSV','GLINDEXS','GLINDEXPOINTER','GLINDEXMASK','GLINDEXIV',
+            'GLINDEXI','GLINDEXFV','GLINDEXF','GLINDEXDV','GLINDEXD','GLHINT','GLGETTEXPARAMETERIV','GLGETTEXPARAMETERFV',
+            'GLGETTEXLEVELPARAMETERIV','GLGETTEXLEVELPARAMETERFV','GLGETTEXIMAGE','GLGETTEXGENIV','GLGETTEXGENFV','GLGETTEXGENDV','GLGETTEXENVIV','GLGETTEXENVFV',
+            'GLGETSTRING','GLGETPOLYGONSTIPPLE','GLGETPOINTERV','GLGETPIXELMAPUSV','GLGETPIXELMAPUIV','GLGETPIXELMAPFV','GLGETMATERIALIV','GLGETMATERIALFV',
+            'GLGETMAPIV','GLGETMAPFV','GLGETMAPDV','GLGETLIGHTIV','GLGETLIGHTFV','GLGETINTEGERV','GLGETFLOATV','GLGETERROR',
+            'GLGETDOUBLEV','GLGETCLIPPLANE','GLGETBOOLEANV','GLGENTEXTURES','GLGENLISTS','GLFRUSTUM','GLFRONTFACE','GLFOGIV',
+            'GLFOGI','GLFOGFV','GLFOGF','GLFLUSH','GLFINISH','GLFEEDBACKBUFFER','GLEVALPOINT2','GLEVALPOINT1',
+            'GLEVALMESH2','GLEVALMESH1','GLEVALCOORD2FV','GLEVALCOORD2F','GLEVALCOORD2DV','GLEVALCOORD2D','GLEVALCOORD1FV','GLEVALCOORD1F',
+            'GLEVALCOORD1DV','GLEVALCOORD1D','GLENDLIST','GLEND','GLENABLECLIENTSTATE','GLENABLE','GLEDGEFLAGV','GLEDGEFLAGPOINTER',
+            'GLEDGEFLAG','GLDRAWPIXELS','GLDRAWELEMENTS','GLDRAWBUFFER','GLDRAWARRAYS','GLDISABLECLIENTSTATE','GLDISABLE','GLDEPTHRANGE',
+            'GLDEPTHMASK','GLDEPTHFUNC','GLDELETETEXTURES','GLDELETELISTS','GLCULLFACE','GLCOPYTEXSUBIMAGE2D','GLCOPYTEXSUBIMAGE1D','GLCOPYTEXIMAGE2D',
+            'GLCOPYTEXIMAGE1D','GLCOPYPIXELS','GLCOLORPOINTER','GLCOLORMATERIAL','GLCOLORMASK','GLCOLOR4USV','GLCOLOR4US','GLCOLOR4UIV',
+            'GLCOLOR4UI','GLCOLOR4UBV','GLCOLOR4UB','GLCOLOR4SV','GLCOLOR4S','GLCOLOR4IV','GLCOLOR4I','GLCOLOR4FV',
+            'GLCOLOR4F','GLCOLOR4DV','GLCOLOR4D','GLCOLOR4BV','GLCOLOR4B','GLCOLOR3USV','GLCOLOR3US','GLCOLOR3UIV',
+            'GLCOLOR3UI','GLCOLOR3UBV','GLCOLOR3UB','GLCOLOR3SV','GLCOLOR3S','GLCOLOR3IV','GLCOLOR3I','GLCOLOR3FV',
+            'GLCOLOR3F','GLCOLOR3DV','GLCOLOR3D','GLCOLOR3BV','GLCOLOR3B','GLCLIPPLANE','GLCLEARSTENCIL','GLCLEARINDEX',
+            'GLCLEARDEPTH','GLCLEARCOLOR','GLCLEARACCUM','GLCLEAR','GLCALLLISTS','GLCALLLIST','GLBLENDFUNC','GLBITMAP',
+            'GLBINDTEXTURE','GLBEGIN','GLARRAYELEMENT','GLARETEXTURESRESIDENT','GLALPHAFUNC','GLACCUM'),
+        2 => array(
+            '$BEL','$BS','$CR','$CRLF','$DQ','$DT_DATE_SEPARATOR','$DT_LANGUAGE','$DT_TIME_SEPARATOR',
+            '$ESC','$FF','$LF','$NUL','$PC_SD_MY_PC','$SPC','$SQL_OPT_TRACE_FILE_DEFAULT','$SQL_SPEC_STRING',
+            '$TAB','$TRACKBAR_CLASS','$VT','%ACM_OPEN','%ACM_OPENW','%ACM_PLAY','%ACM_STOP','%ACN_START',
+            '%ACN_STOP','%ACS_AUTOPLAY','%ACS_CENTER','%ACS_TIMER','%ACS_TRANSPARENT','%APP_COUNTER_FUNLOOKUP','%APP_COUNTER_KEYLOOKUP','%APP_COUNTER_LOOKUP',
+            '%APP_COUNTER_TESTALPHA','%APP_COUNTER_UDTLOOKUP','%APP_COUNTER_VARLOOKUP','%APP_TIMER_EXECTOTAL','%APP_TIMER_INIT','%APP_TIMER_LOAD','%APP_TIMER_PREPROCESSOR','%AW_ACTIVATE',
+            '%AW_BLEND','%AW_CENTER','%AW_HIDE','%AW_HOR_NEGATIVE','%AW_HOR_POSITIVE','%AW_SLIDE','%AW_VER_NEGATIVE','%AW_VER_POSITIVE',
+            '%BCM_FIRST','%BLACK','%BLUE','%BM_GETCHECK','%BM_SETCHECK','%BST_CHECKED','%BST_UNCHECKED','%BS_AUTOCHECKBOX',
+            '%BS_BOTTOM','%BS_CENTER','%BS_DEFAULT','%BS_DEFPUSHBUTTON','%BS_FLAT','%BS_LEFT','%BS_LEFTTEXT','%BS_MULTILINE',
+            '%BS_NOTIFY','%BS_OWNERDRAW','%BS_PUSHLIKE','%BS_RIGHT','%BS_TOP','%BS_VCENTER','%BUNDLE_BUILDER_CANCELLED','%CBM_FIRST',
+            '%CBN_CLOSEUP','%CBN_DBLCLK','%CBN_DROPDOWN','%CBN_EDITCHANGE','%CBN_EDITUPDATE','%CBN_ERRSPACE','%CBN_KILLFOCUS','%CBN_SELCANCEL',
+            '%CBN_SELCHANGE','%CBN_SELENDCANCEL','%CBN_SELENDOK','%CBN_SETFOCUS','%CBS_AUTOHSCROLL','%CBS_DISABLENOSCROLL','%CBS_DROPDOWN','%CBS_DROPDOWNLIST',
+            '%CBS_HASSTRINGS','%CBS_LOWERCASE','%CBS_NOINTEGRALHEIGHT','%CBS_SIMPLE','%CBS_SORT','%CBS_UPPERCASE','%CB_SELECTSTRING','%CCM_FIRST',
+            '%CC_ANYCOLOR','%CC_ENABLEHOOK','%CC_ENABLETEMPLATE','%CC_ENABLETEMPLATEHANDLE','%CC_FULLOPEN','%CC_PREVENTFULLOPEN','%CC_RGBINIT','%CC_SHOWHELP',
+            '%CC_SOLIDCOLOR','%CFE_BOLD','%CFE_ITALIC','%CFE_LINK','%CFE_PROTECTED','%CFE_STRIKEOUT','%CFE_UNDERLINE','%CFM_ANIMATION',
+            '%CFM_BACKCOLOR','%CFM_BOLD','%CFM_CHARSET','%CFM_COLOR','%CFM_FACE','%CFM_ITALIC','%CFM_KERNING','%CFM_LCID',
+            '%CFM_LINK','%CFM_OFFSET','%CFM_PROTECTED','%CFM_REVAUTHOR','%CFM_SIZE','%CFM_SPACING','%CFM_STRIKEOUT','%CFM_STYLE',
+            '%CFM_UNDERLINE','%CFM_UNDERLINETYPE','%CFM_WEIGHT','%CGI_ACCEPT_FILE_UPLOAD','%CGI_AUTO_ADD_SPECIAL_CHARS_PREFIX','%CGI_AUTO_CREATE_VARS','%CGI_BUFFERIZE_OUTPUT','%CGI_DOUBLE_QUOTE',
+            '%CGI_FILE_UPLOAD_BASEPATH','%CGI_FORCE_SESSION_VALIDATION','%CGI_MAX_BYTE_FROM_STD_IN','%CGI_REQUEST_METHOD_GET','%CGI_REQUEST_METHOD_POST','%CGI_SESSION_FILE_BASEPATH','%CGI_SINGLE_QUOTE','%CGI_SPECIAL_CHARS_PREFIX',
+            '%CGI_TEMPORARY_UPLOAD_PATH','%CGI_UPLOAD_CAN_OVERWRITE','%CGI_WRITE_LOG_FILE','%CGI_WRITE_VARS_INTO_LOG_FILE','%CONOLE_ATTACH_PARENT_PROCESS','%CONSOLE_BACKGROUND_BLUE','%CONSOLE_BACKGROUND_GREEN','%CONSOLE_BACKGROUND_INTENSITY',
+            '%CONSOLE_BACKGROUND_RED','%CONSOLE_BOX_FLAG_3DOFF','%CONSOLE_BOX_FLAG_3DON','%CONSOLE_BOX_FLAG_SHADOW','%CONSOLE_COMMON_LVB_GRID_HORIZONTAL','%CONSOLE_COMMON_LVB_GRID_LVERTICAL','%CONSOLE_COMMON_LVB_GRID_RVERTICAL','%CONSOLE_COMMON_LVB_LEADING_BYTE',
+            '%CONSOLE_COMMON_LVB_REVERSE_VIDEO','%CONSOLE_COMMON_LVB_TRAILING_BYTE','%CONSOLE_COMMON_LVB_UNDERSCORE','%CONSOLE_CTRL_BREAK_EVENT','%CONSOLE_CTRL_C_EVENT','%CONSOLE_DOUBLE_CLICK','%CONSOLE_ENABLE_AUTO_POSITION','%CONSOLE_ENABLE_ECHO_INPUT',
+            '%CONSOLE_ENABLE_EXTENDED_FLAGS','%CONSOLE_ENABLE_INSERT_MODE','%CONSOLE_ENABLE_LINE_INPUT','%CONSOLE_ENABLE_MOUSE_INPUT','%CONSOLE_ENABLE_PROCESSED_INPUT','%CONSOLE_ENABLE_PROCESSED_OUTPUT','%CONSOLE_ENABLE_QUICK_EDIT_MODE','%CONSOLE_ENABLE_WINDOW_INPUT',
+            '%CONSOLE_ENABLE_WRAP_AT_EOL_OUTPUT','%CONSOLE_FOREGROUND_BLUE','%CONSOLE_FOREGROUND_GREEN','%CONSOLE_FOREGROUND_INTENSITY','%CONSOLE_FOREGROUND_RED','%CONSOLE_LBUTTON','%CONSOLE_LINE_HORIZONTAL','%CONSOLE_LINE_VERTICAL',
+            '%CONSOLE_MBUTTON','%CONSOLE_MOUSE_MOVED','%CONSOLE_MOUSE_WHEELED','%CONSOLE_RBUTTON','%CONSOLE_SCROLLBUF_DOWN','%CONSOLE_SCROLLBUF_UP','%CONSOLE_SCROLLWND_ABSOLUTE','%CONSOLE_SCROLLWND_RELATIVE',
+            '%CONSOLE_STD_ERROR_HANDLE','%CONSOLE_STD_INPUT_HANDLE','%CONSOLE_STD_OUTPUT_HANDLE','%CONSOLE_SW_FORCEMINIMIZE','%CONSOLE_SW_HIDE','%CONSOLE_SW_MAXIMIZE','%CONSOLE_SW_MINIMIZE','%CONSOLE_SW_RESTORE',
+            '%CONSOLE_SW_SHOW','%CONSOLE_SW_SHOWDEFAULT','%CONSOLE_SW_SHOWMAXIMIZED','%CONSOLE_SW_SHOWMINIMIZED','%CONSOLE_SW_SHOWMINNOACTIVE','%CONSOLE_SW_SHOWNA','%CONSOLE_SW_SHOWNOACTIVATE','%CONSOLE_SW_SHOWNORMAL',
+            '%CONSOLE_UNAVAILABLE','%CRYPTO_CALG_DES','%CRYPTO_CALG_RC2','%CRYPTO_CALG_RC4','%CRYPTO_PROV_DH_SCHANNEL','%CRYPTO_PROV_DSS','%CRYPTO_PROV_DSS_DH','%CRYPTO_PROV_FORTEZZA',
+            '%CRYPTO_PROV_MS_EXCHANGE','%CRYPTO_PROV_RSA_FULL','%CRYPTO_PROV_RSA_SCHANNEL','%CRYPTO_PROV_RSA_SIG','%CRYPTO_PROV_SSL','%CSIDL_ADMINTOOLS','%CSIDL_ALTSTARTUP','%CSIDL_APPDATA',
+            '%CSIDL_BITBUCKET','%CSIDL_CDBURN_AREA','%CSIDL_COMMON_ADMINTOOLS','%CSIDL_COMMON_ALTSTARTUP','%CSIDL_COMMON_APPDATA','%CSIDL_COMMON_DESKTOPDIRECTORY','%CSIDL_COMMON_DOCUMENTS','%CSIDL_COMMON_FAVORITES',
+            '%CSIDL_COMMON_MUSIC','%CSIDL_COMMON_PICTURES','%CSIDL_COMMON_PROGRAMS','%CSIDL_COMMON_STARTMENU','%CSIDL_COMMON_STARTUP','%CSIDL_COMMON_TEMPLATES','%CSIDL_COMMON_VIDEO','%CSIDL_CONTROLS',
+            '%CSIDL_COOKIES','%CSIDL_DESKTOP','%CSIDL_DESKTOPDIRECTORY','%CSIDL_DRIVES','%CSIDL_FAVORITES','%CSIDL_FLAG_CREATE','%CSIDL_FONTS','%CSIDL_HISTORY',
+            '%CSIDL_INTERNET','%CSIDL_INTERNET_CACHE','%CSIDL_LOCAL_APPDATA','%CSIDL_MYDOCUMENTS','%CSIDL_MYMUSIC','%CSIDL_MYPICTURES','%CSIDL_MYVIDEO','%CSIDL_NETHOOD',
+            '%CSIDL_NETWORK','%CSIDL_PERSONAL','%CSIDL_PRINTERS','%CSIDL_PRINTHOOD','%CSIDL_PROFILE','%CSIDL_PROGRAMS','%CSIDL_PROGRAM_FILES','%CSIDL_PROGRAM_FILES_COMMON',
+            '%CSIDL_RECENT','%CSIDL_SENDTO','%CSIDL_STARTMENU','%CSIDL_STARTUP','%CSIDL_SYSTEM','%CSIDL_TEMPLATES','%CSIDL_WINDOWS','%CW_USEDEFAULT',
+            '%CYAN','%DATE_TIME_FILE_CREATION','%DATE_TIME_LAST_FILE_ACCESS','%DATE_TIME_LAST_FILE_WRITE','%DICTIONARY_MEMINFO_DATA','%DICTIONARY_MEMINFO_KEYS','%DICTIONARY_MEMINFO_TOTAL','%DICTIONARY_SORTDESCENDING',
+            '%DICTIONARY_SORTKEYS','%DSCAPS_CERTIFIED','%DSCAPS_CONTINUOUSRATE','%DSCAPS_EMULDRIVER','%DSCAPS_SECONDARY16BIT','%DSCAPS_SECONDARY8BIT','%DSCAPS_SECONDARYMONO','%DSCAPS_SECONDARYSTEREO',
+            '%DSCCAPS_CERTIFIED','%DSCCAPS_EMULDRIVER','%DS_3DLOOK','%DS_ABSALIGN','%DS_CENTER','%DS_CENTERMOUSE','%DS_CONTEXTHELP','%DS_CONTROL',
+            '%DS_MODALFRAME','%DS_NOFAILCREATE','%DS_SETFONT','%DS_SETFOREGROUND','%DS_SYSMODAL','%DTM_FIRST','%DTM_GETMCCOLOR','%DTM_GETMCFONT',
+            '%DTM_GETMONTHCAL','%DTM_GETRANGE','%DTM_GETSYSTEMTIME','%DTM_SETFORMAT','%DTM_SETFORMATW','%DTM_SETMCCOLOR','%DTM_SETMCFONT','%DTM_SETRANGE',
+            '%DTM_SETSYSTEMTIME','%DTN_CLOSEUP','%DTN_DATETIMECHANGE','%DTN_DROPDOWN','%DTN_FORMAT','%DTN_FORMATQUERY','%DTN_FORMATQUERYW','%DTN_FORMATW',
+            '%DTN_USERSTRING','%DTN_USERSTRINGW','%DTN_WMKEYDOWN','%DTN_WMKEYDOWNW','%DTS_APPCANPARSE','%DTS_LONGDATEFORMAT','%DTS_RIGHTALIGN','%DTS_SHORTDATECENTURYFORMAT',
+            '%DTS_SHORTDATEFORMAT','%DTS_SHOWNONE','%DTS_TIMEFORMAT','%DTS_UPDOWN','%DT_DATE_CENTURY','%DT_DATE_OK','%DT_DAY_IN_YEAR','%DT_DIFF_IN_DAYS',
+            '%DT_DIFF_IN_HOURS','%DT_DIFF_IN_MINUTES','%DT_DIFF_IN_SECONDS','%DT_HOURS_IN_DAY','%DT_MINUTES_IN_HOUR','%DT_SECONDS_IN_DAY','%DT_SECONDS_IN_HOUR','%DT_SECONDS_IN_MINUTE',
+            '%DT_SECONDS_IN_YEAR','%DT_USE_LONG_FORM','%DT_USE_SHORT_FORM','%DT_WRONG_DATE','%DT_WRONG_DAY','%DT_WRONG_MONTH','%ECM_FIRST','%ECOOP_AND',
+            '%ECOOP_OR','%ECOOP_SET','%ECOOP_XOR','%ECO_AUTOHSCROLL','%ECO_AUTOVSCROLL','%ECO_AUTOWORDSELECTION','%ECO_NOHIDESEL','%ECO_READONLY',
+            '%ECO_SELECTIONBAR','%ECO_WANTRETURN','%EM_AUTOURLDETECT','%EM_CANPASTE','%EM_CANREDO','%EM_CANUNDO','%EM_CHARFROMPOS','%EM_DISPLAYBAND',
+            '%EM_EMPTYUNDOBUFFER','%EM_EXGETSEL','%EM_EXLIMITTEXT','%EM_EXLINEFROMCHAR','%EM_EXSETSEL','%EM_FINDTEXT','%EM_FINDTEXTEX','%EM_FINDWORDBREAK',
+            '%EM_FMTLINES','%EM_FORMATRANGE','%EM_GETAUTOURLDETECT','%EM_GETCHARFORMAT','%EM_GETEDITSTYLE','%EM_GETEVENTMASK','%EM_GETFIRSTVISIBLELINE','%EM_GETHANDLE',
+            '%EM_GETIMESTATUS','%EM_GETLIMITTEXT','%EM_GETLINE','%EM_GETLINECOUNT','%EM_GETMARGINS','%EM_GETMODIFY','%EM_GETOLEINTERFACE','%EM_GETOPTIONS',
+            '%EM_GETPARAFORMAT','%EM_GETPASSWORDCHAR','%EM_GETRECT','%EM_GETREDONAME','%EM_GETSCROLLPOS','%EM_GETSEL','%EM_GETSELTEXT','%EM_GETTEXTMODE',
+            '%EM_GETTEXTRANGE','%EM_GETTHUMB','%EM_GETUNDONAME','%EM_GETWORDBREAKPROC','%EM_GETWORDBREAKPROCEX','%EM_HIDESELECTION','%EM_LIMITTEXT','%EM_LINEFROMCHAR',
+            '%EM_LINEINDEX','%EM_LINELENGTH','%EM_LINESCROLL','%EM_PASTESPECIAL','%EM_POSFROMCHAR','%EM_REDO','%EM_REPLACESEL','%EM_REQUESTRESIZE',
+            '%EM_SCROLL','%EM_SCROLLCARET','%EM_SELECTIONTYPE','%EM_SETBKGNDCOLOR','%EM_SETCHARFORMAT','%EM_SETEDITSTYLE','%EM_SETEVENTMASK','%EM_SETHANDLE',
+            '%EM_SETIMESTATUS','%EM_SETLIMITTEXT','%EM_SETMARGINS','%EM_SETMODIFY','%EM_SETOLECALLBACK','%EM_SETOPTIONS','%EM_SETPARAFORMAT','%EM_SETPASSWORDCHAR',
+            '%EM_SETREADONLY','%EM_SETRECT','%EM_SETRECTNP','%EM_SETSCROLLPOS','%EM_SETSEL','%EM_SETTABSTOPS','%EM_SETTARGETDEVICE','%EM_SETTEXTMODE',
+            '%EM_SETUNDOLIMIT','%EM_SETWORDBREAKPROC','%EM_SETWORDBREAKPROCEX','%EM_SETWORDWRAPMODE','%EM_SETZOOM','%EM_STOPGROUPTYPING','%EM_STREAMIN','%EM_STREAMOUT',
+            '%EM_UNDO','%ENM_CHANGE','%ENM_CORRECTTEXT','%ENM_DRAGDROPDONE','%ENM_DROPFILES','%ENM_KEYEVENTS','%ENM_MOUSEEVENTS','%ENM_NONE',
+            '%ENM_PARAGRAPHEXPANDED','%ENM_PROTECTED','%ENM_REQUESTRESIZE','%ENM_SCROLL','%ENM_SCROLLEVENTS','%ENM_SELCHANGE','%ENM_UPDATE','%EN_CHANGE',
+            '%EN_MSGFILTER','%EN_SELCHANGE','%EN_UPDATE','%ES_AUTOHSCROLL','%ES_AUTOVSCROLL','%ES_CENTER','%ES_DISABLENOSCROLL','%ES_EX_NOCALLOLEINIT',
+            '%ES_LEFT','%ES_LOWERCASE','%ES_MULTILINE','%ES_NOHIDESEL','%ES_NOOLEDRAGDROP','%ES_NUMBER','%ES_OEMCONVERT','%ES_PASSWORD',
+            '%ES_READONLY','%ES_RIGHT','%ES_SAVESEL','%ES_SELECTIONBAR','%ES_SUNKEN','%ES_UPPERCASE','%ES_WANTRETURN','%EVAL_EXEC_STRING',
+            '%FALSE','%FILE_ADDPATH','%FILE_ARCHIVE','%FILE_BUILDVERSION','%FILE_HIDDEN','%FILE_MAJORVERSION','%FILE_MINORVERSION','%FILE_NORMAL',
+            '%FILE_READONLY','%FILE_REVISIONVERSION','%FILE_SUBDIR','%FILE_SYSTEM','%FILE_VLABEL','%FTP_GET_CONNECT_STATUS','%FTP_GET_FILE_BYTES_RCVD','%FTP_GET_FILE_BYTES_SENT',
+            '%FTP_GET_LAST_RESPONSE','%FTP_GET_LOCAL_IP','%FTP_GET_SERVER_IP','%FTP_GET_TOTAL_BYTES_RCVD','%FTP_GET_TOTAL_BYTES_SENT','%FTP_LIST_FULLLIST','%FTP_LIST_FULLLISTDIR','%FTP_LIST_FULLLISTFILE',
+            '%FTP_SET_ASYNC','%FTP_SET_CONNECT_WAIT','%FTP_SET_MAX_LISTEN_WAIT','%FTP_SET_MAX_RESPONSE_WAIT','%FTP_SET_PASSIVE','%FTP_SET_SYNC','%FW_BLACK','%FW_BOLD',
+            '%FW_DEMIBOLD','%FW_DONTCARE','%FW_EXTRABOLD','%FW_EXTRALIGHT','%FW_HEAVY','%FW_LIGHT','%FW_MEDIUM','%FW_NORMAL',
+            '%FW_REGULAR','%FW_SEMIBOLD','%FW_THIN','%FW_ULTRABOLD','%FW_ULTRALIGHT','%GDTR_MAX','%GDTR_MIN','%GLU_AUTO_LOAD_MATRIX',
+            '%GLU_BEGIN','%GLU_CCW','%GLU_CULLING','%GLU_CW','%GLU_DISPLAY_MODE','%GLU_DOMAIN_DISTANCE','%GLU_EDGE_FLAG','%GLU_END',
+            '%GLU_ERROR','%GLU_EXTENSIONS','%GLU_EXTERIOR','%GLU_FALSE','%GLU_FILL','%GLU_FLAT','%GLU_INCOMPATIBLE_GL_VERSION','%GLU_INSIDE',
+            '%GLU_INTERIOR','%GLU_INVALID_ENUM','%GLU_INVALID_VALUE','%GLU_LINE','%GLU_MAP1_TRIM_2','%GLU_MAP1_TRIM_3','%GLU_NONE','%GLU_NURBS_ERROR1',
+            '%GLU_NURBS_ERROR10','%GLU_NURBS_ERROR11','%GLU_NURBS_ERROR12','%GLU_NURBS_ERROR13','%GLU_NURBS_ERROR14','%GLU_NURBS_ERROR15','%GLU_NURBS_ERROR16','%GLU_NURBS_ERROR17',
+            '%GLU_NURBS_ERROR18','%GLU_NURBS_ERROR19','%GLU_NURBS_ERROR2','%GLU_NURBS_ERROR20','%GLU_NURBS_ERROR21','%GLU_NURBS_ERROR22','%GLU_NURBS_ERROR23','%GLU_NURBS_ERROR24',
+            '%GLU_NURBS_ERROR25','%GLU_NURBS_ERROR26','%GLU_NURBS_ERROR27','%GLU_NURBS_ERROR28','%GLU_NURBS_ERROR29','%GLU_NURBS_ERROR3','%GLU_NURBS_ERROR30','%GLU_NURBS_ERROR31',
+            '%GLU_NURBS_ERROR32','%GLU_NURBS_ERROR33','%GLU_NURBS_ERROR34','%GLU_NURBS_ERROR35','%GLU_NURBS_ERROR36','%GLU_NURBS_ERROR37','%GLU_NURBS_ERROR4','%GLU_NURBS_ERROR5',
+            '%GLU_NURBS_ERROR6','%GLU_NURBS_ERROR7','%GLU_NURBS_ERROR8','%GLU_NURBS_ERROR9','%GLU_OUTLINE_PATCH','%GLU_OUTLINE_POLYGON','%GLU_OUTSIDE','%GLU_OUT_OF_MEMORY',
+            '%GLU_PARAMETRIC_ERROR','%GLU_PARAMETRIC_TOLERANCE','%GLU_PATH_LENGTH','%GLU_POINT','%GLU_SAMPLING_METHOD','%GLU_SAMPLING_TOLERANCE','%GLU_SILHOUETTE','%GLU_SMOOTH',
+            '%GLU_TESS_BEGIN','%GLU_TESS_BEGIN_DATA','%GLU_TESS_BOUNDARY_ONLY','%GLU_TESS_COMBINE','%GLU_TESS_COMBINE_DATA','%GLU_TESS_COORD_TOO_LARGE','%GLU_TESS_EDGE_FLAG','%GLU_TESS_EDGE_FLAG_DATA',
+            '%GLU_TESS_END','%GLU_TESS_END_DATA','%GLU_TESS_ERROR','%GLU_TESS_ERROR1','%GLU_TESS_ERROR2','%GLU_TESS_ERROR3','%GLU_TESS_ERROR4','%GLU_TESS_ERROR5',
+            '%GLU_TESS_ERROR6','%GLU_TESS_ERROR7','%GLU_TESS_ERROR8','%GLU_TESS_ERROR_DATA','%GLU_TESS_MISSING_BEGIN_CONTOUR','%GLU_TESS_MISSING_BEGIN_POLYGON','%GLU_TESS_MISSING_END_CONTOUR','%GLU_TESS_MISSING_END_POLYGON',
+            '%GLU_TESS_NEED_COMBINE_CALLBACK','%GLU_TESS_TOLERANCE','%GLU_TESS_VERTEX','%GLU_TESS_VERTEX_DATA','%GLU_TESS_WINDING_ABS_GEQ_TWO','%GLU_TESS_WINDING_NEGATIVE','%GLU_TESS_WINDING_NONZERO','%GLU_TESS_WINDING_ODD',
+            '%GLU_TESS_WINDING_POSITIVE','%GLU_TESS_WINDING_RULE','%GLU_TRUE','%GLU_UNKNOWN','%GLU_U_STEP','%GLU_VERSION','%GLU_VERSION_1_1','%GLU_VERSION_1_2',
+            '%GLU_VERTEX','%GLU_V_STEP','%GL_2D','%GL_2_BYTES','%GL_3D','%GL_3D_COLOR','%GL_3D_COLOR_TEXTURE','%GL_3_BYTES',
+            '%GL_4D_COLOR_TEXTURE','%GL_4_BYTES','%GL_ABGR_EXT','%GL_ACCUM','%GL_ACCUM_ALPHA_BITS','%GL_ACCUM_BLUE_BITS','%GL_ACCUM_BUFFER_BIT','%GL_ACCUM_CLEAR_VALUE',
+            '%GL_ACCUM_GREEN_BITS','%GL_ACCUM_RED_BITS','%GL_ADD','%GL_ALL_ATTRIB_BITS','%GL_ALPHA','%GL_ALPHA12','%GL_ALPHA16','%GL_ALPHA4',
+            '%GL_ALPHA8','%GL_ALPHA_BIAS','%GL_ALPHA_BITS','%GL_ALPHA_SCALE','%GL_ALPHA_TEST','%GL_ALPHA_TEST_FUNC','%GL_ALPHA_TEST_REF','%GL_ALWAYS',
+            '%GL_AMBIENT','%GL_AMBIENT_AND_DIFFUSE','%GL_AND','%GL_AND_INVERTED','%GL_AND_REVERSE','%GL_ARRAY_ELEMENT_LOCK_COUNT_EXT','%GL_ARRAY_ELEMENT_LOCK_FIRST_EXT','%GL_ATTRIB_STACK_DEPTH',
+            '%GL_AUTO_NORMAL','%GL_AUX0','%GL_AUX1','%GL_AUX2','%GL_AUX3','%GL_AUX_BUFFERS','%GL_BACK','%GL_BACK_LEFT',
+            '%GL_BACK_RIGHT','%GL_BGRA_EXT','%GL_BGR_EXT','%GL_BITMAP','%GL_BITMAP_TOKEN','%GL_BLEND','%GL_BLEND_COLOR_EXT','%GL_BLEND_DST',
+            '%GL_BLEND_EQUATION_EXT','%GL_BLEND_SRC','%GL_BLUE','%GL_BLUE_BIAS','%GL_BLUE_BITS','%GL_BLUE_SCALE','%GL_BYTE','%GL_C3F_V3F',
+            '%GL_C4F_N3F_V3F','%GL_C4UB_V2F','%GL_C4UB_V3F','%GL_CCW','%GL_CLAMP','%GL_CLEAR','%GL_CLIENT_ALL_ATTRIB_BITS','%GL_CLIENT_ATTRIB_STACK_DEPTH',
+            '%GL_CLIENT_PIXEL_STORE_BIT','%GL_CLIENT_VERTEX_ARRAY_BIT','%GL_CLIP_PLANE0','%GL_CLIP_PLANE1','%GL_CLIP_PLANE2','%GL_CLIP_PLANE3','%GL_CLIP_PLANE4','%GL_CLIP_PLANE5',
+            '%GL_CLIP_VOLUME_CLIPPING_HINT_EXT','%GL_COEFF','%GL_COLOR','%GL_COLOR_ARRAY','%GL_COLOR_ARRAY_COUNT_EXT','%GL_COLOR_ARRAY_EXT','%GL_COLOR_ARRAY_POINTER','%GL_COLOR_ARRAY_POINTER_EXT',
+            '%GL_COLOR_ARRAY_SIZE','%GL_COLOR_ARRAY_SIZE_EXT','%GL_COLOR_ARRAY_STRIDE','%GL_COLOR_ARRAY_STRIDE_EXT','%GL_COLOR_ARRAY_TYPE','%GL_COLOR_ARRAY_TYPE_EXT','%GL_COLOR_BUFFER_BIT','%GL_COLOR_CLEAR_VALUE',
+            '%GL_COLOR_INDEX','%GL_COLOR_INDEX12_EXT','%GL_COLOR_INDEX16_EXT','%GL_COLOR_INDEX1_EXT','%GL_COLOR_INDEX2_EXT','%GL_COLOR_INDEX4_EXT','%GL_COLOR_INDEX8_EXT','%GL_COLOR_INDEXES',
+            '%GL_COLOR_LOGIC_OP','%GL_COLOR_MATERIAL','%GL_COLOR_MATERIAL_FACE','%GL_COLOR_MATERIAL_PARAMETER','%GL_COLOR_SUM_EXT','%GL_COLOR_TABLE_ALPHA_SIZE_EXT','%GL_COLOR_TABLE_BIAS_EXT','%GL_COLOR_TABLE_BLUE_SIZE_EXT',
+            '%GL_COLOR_TABLE_EXT','%GL_COLOR_TABLE_FORMAT_EXT','%GL_COLOR_TABLE_GREEN_SIZE_EXT','%GL_COLOR_TABLE_INTENSITY_SIZE_EXT','%GL_COLOR_TABLE_LUMINANCE_SIZE_EXT','%GL_COLOR_TABLE_RED_SIZE_EXT','%GL_COLOR_TABLE_SCALE_EXT','%GL_COLOR_TABLE_WIDTH_EXT',
+            '%GL_COLOR_WRITEMASK','%GL_COMPILE','%GL_COMPILE_AND_EXECUTE','%GL_CONSTANT_ALPHA_EXT','%GL_CONSTANT_ATTENUATION','%GL_CONSTANT_COLOR_EXT','%GL_CONVOLUTION_1D_EXT','%GL_CONVOLUTION_2D_EXT',
+            '%GL_CONVOLUTION_BORDER_MODE_EXT','%GL_CONVOLUTION_FILTER_BIAS_EXT','%GL_CONVOLUTION_FILTER_SCALE_EXT','%GL_CONVOLUTION_FORMAT_EXT','%GL_CONVOLUTION_HEIGHT_EXT','%GL_CONVOLUTION_WIDTH_EXT','%GL_COPY','%GL_COPY_INVERTED',
+            '%GL_COPY_PIXEL_TOKEN','%GL_CULL_FACE','%GL_CULL_FACE_MODE','%GL_CULL_VERTEX_EXT','%GL_CULL_VERTEX_EYE_POSITION_EXT','%GL_CULL_VERTEX_OBJECT_POSITION_EXT','%GL_CURRENT_BIT','%GL_CURRENT_COLOR',
+            '%GL_CURRENT_INDEX','%GL_CURRENT_NORMAL','%GL_CURRENT_RASTER_COLOR','%GL_CURRENT_RASTER_DISTANCE','%GL_CURRENT_RASTER_INDEX','%GL_CURRENT_RASTER_POSITION','%GL_CURRENT_RASTER_POSITION_VALID','%GL_CURRENT_RASTER_TEXTURE_COORDS',
+            '%GL_CURRENT_SECONDARY_COLOR_EXT','%GL_CURRENT_TEXTURE_COORDS','%GL_CW','%GL_DECAL','%GL_DECR','%GL_DEPTH','%GL_DEPTH_BIAS','%GL_DEPTH_BITS',
+            '%GL_DEPTH_BUFFER_BIT','%GL_DEPTH_CLEAR_VALUE','%GL_DEPTH_COMPONENT','%GL_DEPTH_FUNC','%GL_DEPTH_RANGE','%GL_DEPTH_SCALE','%GL_DEPTH_TEST','%GL_DEPTH_WRITEMASK',
+            '%GL_DIFFUSE','%GL_DITHER','%GL_DOMAIN','%GL_DONT_CARE','%GL_DOUBLE','%GL_DOUBLEBUFFER','%GL_DOUBLE_EXT','%GL_DRAW_BUFFER',
+            '%GL_DRAW_PIXEL_TOKEN','%GL_DST_ALPHA','%GL_DST_COLOR','%GL_EDGE_FLAG','%GL_EDGE_FLAG_ARRAY','%GL_EDGE_FLAG_ARRAY_COUNT_EXT','%GL_EDGE_FLAG_ARRAY_EXT','%GL_EDGE_FLAG_ARRAY_POINTER',
+            '%GL_EDGE_FLAG_ARRAY_POINTER_EXT','%GL_EDGE_FLAG_ARRAY_STRIDE','%GL_EDGE_FLAG_ARRAY_STRIDE_EXT','%GL_EMISSION','%GL_ENABLE_BIT','%GL_EQUAL','%GL_EQUIV','%GL_EVAL_BIT',
+            '%GL_EXP','%GL_EXP2','%GL_EXTENSIONS','%GL_EXT_ABGR','%GL_EXT_BGRA','%GL_EXT_BLEND_COLOR','%GL_EXT_BLEND_MINMAX','%GL_EXT_BLEND_SUBTRACT',
+            '%GL_EXT_CLIP_VOLUME_HINT','%GL_EXT_COLOR_TABLE','%GL_EXT_COMPILED_VERTEX_ARRAY','%GL_EXT_CONVOLUTION','%GL_EXT_CULL_VERTEX','%GL_EXT_HISTOGRAM','%GL_EXT_PACKED_PIXELS','%GL_EXT_PALETTED_TEXTURE',
+            '%GL_EXT_POLYGON_OFFSET','%GL_EXT_SECONDARY_COLOR','%GL_EXT_SEPARATE_SPECULAR_COLOR','%GL_EXT_VERTEX_ARRAY','%GL_EYE_LINEAR','%GL_EYE_PLANE','%GL_FALSE','%GL_FASTEST',
+            '%GL_FEEDBACK','%GL_FEEDBACK_BUFFER_POINTER','%GL_FEEDBACK_BUFFER_SIZE','%GL_FEEDBACK_BUFFER_TYPE','%GL_FILL','%GL_FLAT','%GL_FLOAT','%GL_FOG',
+            '%GL_FOG_BIT','%GL_FOG_COLOR','%GL_FOG_DENSITY','%GL_FOG_END','%GL_FOG_HINT','%GL_FOG_INDEX','%GL_FOG_MODE','%GL_FOG_START',
+            '%GL_FRONT','%GL_FRONT_AND_BACK','%GL_FRONT_FACE','%GL_FRONT_LEFT','%GL_FRONT_RIGHT','%GL_FUNC_ADD_EXT','%GL_FUNC_REVERSE_SUBTRACT_EXT','%GL_FUNC_SUBTRACT_EXT',
+            '%GL_GEQUAL','%GL_GREATER','%GL_GREEN','%GL_GREEN_BIAS','%GL_GREEN_BITS','%GL_GREEN_SCALE','%GL_HINT_BIT','%GL_HISTOGRAM_ALPHA_SIZE_EXT',
+            '%GL_HISTOGRAM_BLUE_SIZE_EXT','%GL_HISTOGRAM_EXT','%GL_HISTOGRAM_FORMAT_EXT','%GL_HISTOGRAM_GREEN_SIZE_EXT','%GL_HISTOGRAM_LUMINANCE_SIZE_EXT','%GL_HISTOGRAM_RED_SIZE_EXT','%GL_HISTOGRAM_SINK_EXT','%GL_HISTOGRAM_WIDTH_EXT',
+            '%GL_INCR','%GL_INDEX_ARRAY','%GL_INDEX_ARRAY_COUNT_EXT','%GL_INDEX_ARRAY_EXT','%GL_INDEX_ARRAY_POINTER','%GL_INDEX_ARRAY_POINTER_EXT','%GL_INDEX_ARRAY_STRIDE','%GL_INDEX_ARRAY_STRIDE_EXT',
+            '%GL_INDEX_ARRAY_TYPE','%GL_INDEX_ARRAY_TYPE_EXT','%GL_INDEX_BITS','%GL_INDEX_CLEAR_VALUE','%GL_INDEX_LOGIC_OP','%GL_INDEX_MODE','%GL_INDEX_OFFSET','%GL_INDEX_SHIFT',
+            '%GL_INDEX_WRITEMASK','%GL_INT','%GL_INTENSITY','%GL_INTENSITY12','%GL_INTENSITY16','%GL_INTENSITY4','%GL_INTENSITY8','%GL_INVALID_ENUM',
+            '%GL_INVALID_OPERATION','%GL_INVALID_VALUE','%GL_INVERT','%GL_KEEP','%GL_LEFT','%GL_LEQUAL','%GL_LESS','%GL_LIGHT0',
+            '%GL_LIGHT1','%GL_LIGHT2','%GL_LIGHT3','%GL_LIGHT4','%GL_LIGHT5','%GL_LIGHT6','%GL_LIGHT7','%GL_LIGHTING',
+            '%GL_LIGHTING_BIT','%GL_LIGHT_MODEL_AMBIENT','%GL_LIGHT_MODEL_COLOR_CONTROL_EXT','%GL_LIGHT_MODEL_LOCAL_VIEWER','%GL_LIGHT_MODEL_TWO_SIDE','%GL_LINE','%GL_LINEAR','%GL_LINEAR_ATTENUATION',
+            '%GL_LINEAR_MIPMAP_LINEAR','%GL_LINEAR_MIPMAP_NEAREST','%GL_LINES','%GL_LINE_BIT','%GL_LINE_LOOP','%GL_LINE_RESET_TOKEN','%GL_LINE_SMOOTH','%GL_LINE_SMOOTH_HINT',
+            '%GL_LINE_STIPPLE','%GL_LINE_STIPPLE_PATTERN','%GL_LINE_STIPPLE_REPEAT','%GL_LINE_STRIP','%GL_LINE_TOKEN','%GL_LINE_WIDTH','%GL_LINE_WIDTH_GRANULARITY','%GL_LINE_WIDTH_RANGE',
+            '%GL_LIST_BASE','%GL_LIST_BIT','%GL_LIST_INDEX','%GL_LIST_MODE','%GL_LOAD','%GL_LOGIC_OP','%GL_LOGIC_OP_MODE','%GL_LUMINANCE',
+            '%GL_LUMINANCE12','%GL_LUMINANCE12_ALPHA12','%GL_LUMINANCE12_ALPHA4','%GL_LUMINANCE16','%GL_LUMINANCE16_ALPHA16','%GL_LUMINANCE4','%GL_LUMINANCE4_ALPHA4','%GL_LUMINANCE6_ALPHA2',
+            '%GL_LUMINANCE8','%GL_LUMINANCE8_ALPHA8','%GL_LUMINANCE_ALPHA','%GL_MAP1_COLOR_4','%GL_MAP1_GRID_DOMAIN','%GL_MAP1_GRID_SEGMENTS','%GL_MAP1_INDEX','%GL_MAP1_NORMAL',
+            '%GL_MAP1_TEXTURE_COORD_1','%GL_MAP1_TEXTURE_COORD_2','%GL_MAP1_TEXTURE_COORD_3','%GL_MAP1_TEXTURE_COORD_4','%GL_MAP1_VERTEX_3','%GL_MAP1_VERTEX_4','%GL_MAP2_COLOR_4','%GL_MAP2_GRID_DOMAIN',
+            '%GL_MAP2_GRID_SEGMENTS','%GL_MAP2_INDEX','%GL_MAP2_NORMAL','%GL_MAP2_TEXTURE_COORD_1','%GL_MAP2_TEXTURE_COORD_2','%GL_MAP2_TEXTURE_COORD_3','%GL_MAP2_TEXTURE_COORD_4','%GL_MAP2_VERTEX_3',
+            '%GL_MAP2_VERTEX_4','%GL_MAP_COLOR','%GL_MAP_STENCIL','%GL_MATRIX_MODE','%GL_MAX_ATTRIB_STACK_DEPTH','%GL_MAX_CLIENT_ATTRIB_STACK_DEPTH','%GL_MAX_CLIP_PLANES','%GL_MAX_CONVOLUTION_HEIGHT_EXT',
+            '%GL_MAX_CONVOLUTION_WIDTH_EXT','%GL_MAX_EVAL_ORDER','%GL_MAX_EXT','%GL_MAX_LIGHTS','%GL_MAX_LIST_NESTING','%GL_MAX_MODELVIEW_STACK_DEPTH','%GL_MAX_NAME_STACK_DEPTH','%GL_MAX_PIXEL_MAP_TABLE',
+            '%GL_MAX_PROJECTION_STACK_DEPTH','%GL_MAX_TEXTURE_SIZE','%GL_MAX_TEXTURE_STACK_DEPTH','%GL_MAX_VIEWPORT_DIMS','%GL_MINMAX_EXT','%GL_MINMAX_FORMAT_EXT','%GL_MINMAX_SINK_EXT','%GL_MIN_EXT',
+            '%GL_MODELVIEW','%GL_MODELVIEW_MATRIX','%GL_MODELVIEW_STACK_DEPTH','%GL_MODULATE','%GL_MULT','%GL_N3F_V3F','%GL_NAME_STACK_DEPTH','%GL_NAND',
+            '%GL_NEAREST','%GL_NEAREST_MIPMAP_LINEAR','%GL_NEAREST_MIPMAP_NEAREST','%GL_NEVER','%GL_NICEST','%GL_NONE','%GL_NOOP','%GL_NOR',
+            '%GL_NORMALIZE','%GL_NORMAL_ARRAY','%GL_NORMAL_ARRAY_COUNT_EXT','%GL_NORMAL_ARRAY_EXT','%GL_NORMAL_ARRAY_POINTER','%GL_NORMAL_ARRAY_POINTER_EXT','%GL_NORMAL_ARRAY_STRIDE','%GL_NORMAL_ARRAY_STRIDE_EXT',
+            '%GL_NORMAL_ARRAY_TYPE','%GL_NORMAL_ARRAY_TYPE_EXT','%GL_NOTEQUAL','%GL_NO_ERROR','%GL_OBJECT_LINEAR','%GL_OBJECT_PLANE','%GL_ONE','%GL_ONE_MINUS_CONSTANT_ALPHA_EXT',
+            '%GL_ONE_MINUS_CONSTANT_COLOR_EXT','%GL_ONE_MINUS_DST_ALPHA','%GL_ONE_MINUS_DST_COLOR','%GL_ONE_MINUS_SRC_ALPHA','%GL_ONE_MINUS_SRC_COLOR','%GL_OR','%GL_ORDER','%GL_OR_INVERTED',
+            '%GL_OR_REVERSE','%GL_OUT_OF_MEMORY','%GL_PACK_ALIGNMENT','%GL_PACK_LSB_FIRST','%GL_PACK_ROW_LENGTH','%GL_PACK_SKIP_PIXELS','%GL_PACK_SKIP_ROWS','%GL_PACK_SWAP_BYTES',
+            '%GL_PASS_THROUGH_TOKEN','%GL_PERSPECTIVE_CORRECTION_HINT','%GL_PIXEL_MAP_A_TO_A','%GL_PIXEL_MAP_A_TO_A_SIZE','%GL_PIXEL_MAP_B_TO_B','%GL_PIXEL_MAP_B_TO_B_SIZE','%GL_PIXEL_MAP_G_TO_G','%GL_PIXEL_MAP_G_TO_G_SIZE',
+            '%GL_PIXEL_MAP_I_TO_A','%GL_PIXEL_MAP_I_TO_A_SIZE','%GL_PIXEL_MAP_I_TO_B','%GL_PIXEL_MAP_I_TO_B_SIZE','%GL_PIXEL_MAP_I_TO_G','%GL_PIXEL_MAP_I_TO_G_SIZE','%GL_PIXEL_MAP_I_TO_I','%GL_PIXEL_MAP_I_TO_I_SIZE',
+            '%GL_PIXEL_MAP_I_TO_R','%GL_PIXEL_MAP_I_TO_R_SIZE','%GL_PIXEL_MAP_R_TO_R','%GL_PIXEL_MAP_R_TO_R_SIZE','%GL_PIXEL_MAP_S_TO_S','%GL_PIXEL_MAP_S_TO_S_SIZE','%GL_PIXEL_MODE_BIT','%GL_POINT',
+            '%GL_POINTS','%GL_POINT_BIT','%GL_POINT_SIZE','%GL_POINT_SIZE_GRANULARITY','%GL_POINT_SIZE_RANGE','%GL_POINT_SMOOTH','%GL_POINT_SMOOTH_HINT','%GL_POINT_TOKEN',
+            '%GL_POLYGON','%GL_POLYGON_BIT','%GL_POLYGON_MODE','%GL_POLYGON_OFFSET_BIAS_EXT','%GL_POLYGON_OFFSET_EXT','%GL_POLYGON_OFFSET_FACTOR','%GL_POLYGON_OFFSET_FACTOR_EXT','%GL_POLYGON_OFFSET_FILL',
+            '%GL_POLYGON_OFFSET_LINE','%GL_POLYGON_OFFSET_POINT','%GL_POLYGON_OFFSET_UNITS','%GL_POLYGON_SMOOTH','%GL_POLYGON_SMOOTH_HINT','%GL_POLYGON_STIPPLE','%GL_POLYGON_STIPPLE_BIT','%GL_POLYGON_TOKEN',
+            '%GL_POSITION','%GL_POST_COLOR_MATRIX_COLOR_TABLE_EXT','%GL_POST_CONVOLUTION_ALPHA_BIAS_EXT','%GL_POST_CONVOLUTION_ALPHA_SCALE_EXT','%GL_POST_CONVOLUTION_BLUE_BIAS_EXT','%GL_POST_CONVOLUTION_BLUE_SCALE_EXT','%GL_POST_CONVOLUTION_COLOR_TABLE_EXT','%GL_POST_CONVOLUTION_GREEN_BIAS_EXT',
+            '%GL_POST_CONVOLUTION_GREEN_SCALE_EXT','%GL_POST_CONVOLUTION_RED_BIAS_EXT','%GL_POST_CONVOLUTION_RED_SCALE_EXT','%GL_PROJECTION','%GL_PROJECTION_MATRIX','%GL_PROJECTION_STACK_DEPTH','%GL_PROXY_COLOR_TABLE_EXT','%GL_PROXY_HISTOGRAM_EXT',
+            '%GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_EXT','%GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_EXT','%GL_PROXY_TEXTURE_1D','%GL_PROXY_TEXTURE_2D','%GL_Q','%GL_QUADRATIC_ATTENUATION','%GL_QUADS','%GL_QUAD_STRIP',
+            '%GL_R','%GL_R3_G3_B2','%GL_READ_BUFFER','%GL_RED','%GL_REDUCE_EXT','%GL_RED_BIAS','%GL_RED_BITS','%GL_RED_SCALE',
+            '%GL_RENDER','%GL_RENDERER','%GL_RENDER_MODE','%GL_REPEAT','%GL_REPLACE','%GL_RETURN','%GL_RGB','%GL_RGB10',
+            '%GL_RGB10_A2','%GL_RGB12','%GL_RGB16','%GL_RGB4','%GL_RGB5','%GL_RGB5_A1','%GL_RGB8','%GL_RGBA',
+            '%GL_RGBA12','%GL_RGBA16','%GL_RGBA2','%GL_RGBA4','%GL_RGBA8','%GL_RGBA_MODE','%GL_RIGHT','%GL_S',
+            '%GL_SCISSOR_BIT','%GL_SCISSOR_BOX','%GL_SCISSOR_TEST','%GL_SECONDARY_COLOR_ARRAY_EXT','%GL_SECONDARY_COLOR_ARRAY_POINTER_EXT','%GL_SECONDARY_COLOR_ARRAY_SIZE_EXT','%GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT','%GL_SECONDARY_COLOR_ARRAY_TYPE_EXT',
+            '%GL_SELECT','%GL_SELECTION_BUFFER_POINTER','%GL_SELECTION_BUFFER_SIZE','%GL_SEPARABLE_2D_EXT','%GL_SEPARATE_SPECULAR_COLOR_EXT','%GL_SET','%GL_SHADE_MODEL','%GL_SHININESS',
+            '%GL_SHORT','%GL_SINGLE_COLOR_EXT','%GL_SMOOTH','%GL_SPECULAR','%GL_SPHERE_MAP','%GL_SPOT_CUTOFF','%GL_SPOT_DIRECTION','%GL_SPOT_EXPONENT',
+            '%GL_SRC_ALPHA','%GL_SRC_ALPHA_SATURATE','%GL_SRC_COLOR','%GL_STACK_OVERFLOW','%GL_STACK_UNDERFLOW','%GL_STENCIL','%GL_STENCIL_BITS','%GL_STENCIL_BUFFER_BIT',
+            '%GL_STENCIL_CLEAR_VALUE','%GL_STENCIL_FAIL','%GL_STENCIL_FUNC','%GL_STENCIL_INDEX','%GL_STENCIL_PASS_DEPTH_FAIL','%GL_STENCIL_PASS_DEPTH_PASS','%GL_STENCIL_REF','%GL_STENCIL_TEST',
+            '%GL_STENCIL_VALUE_MASK','%GL_STENCIL_WRITEMASK','%GL_STEREO','%GL_SUBPIXEL_BITS','%GL_T','%GL_T2F_C3F_V3F','%GL_T2F_C4F_N3F_V3F','%GL_T2F_C4UB_V3F',
+            '%GL_T2F_N3F_V3F','%GL_T2F_V3F','%GL_T4F_C4F_N3F_V4F','%GL_T4F_V4F','%GL_TABLE_TOO_LARGE_EXT','%GL_TEXTURE','%GL_TEXTURE_1D','%GL_TEXTURE_2D',
+            '%GL_TEXTURE_ALPHA_SIZE','%GL_TEXTURE_BINDING_1D','%GL_TEXTURE_BINDING_2D','%GL_TEXTURE_BIT','%GL_TEXTURE_BLUE_SIZE','%GL_TEXTURE_BORDER','%GL_TEXTURE_BORDER_COLOR','%GL_TEXTURE_COMPONENTS',
+            '%GL_TEXTURE_COORD_ARRAY','%GL_TEXTURE_COORD_ARRAY_COUNT_EXT','%GL_TEXTURE_COORD_ARRAY_EXT','%GL_TEXTURE_COORD_ARRAY_POINTER','%GL_TEXTURE_COORD_ARRAY_POINTER_EXT','%GL_TEXTURE_COORD_ARRAY_SIZE','%GL_TEXTURE_COORD_ARRAY_SIZE_EXT','%GL_TEXTURE_COORD_ARRAY_STRIDE',
+            '%GL_TEXTURE_COORD_ARRAY_STRIDE_EXT','%GL_TEXTURE_COORD_ARRAY_TYPE','%GL_TEXTURE_COORD_ARRAY_TYPE_EXT','%GL_TEXTURE_ENV','%GL_TEXTURE_ENV_COLOR','%GL_TEXTURE_ENV_MODE','%GL_TEXTURE_GEN_MODE','%GL_TEXTURE_GEN_Q',
+            '%GL_TEXTURE_GEN_R','%GL_TEXTURE_GEN_S','%GL_TEXTURE_GEN_T','%GL_TEXTURE_GREEN_SIZE','%GL_TEXTURE_HEIGHT','%GL_TEXTURE_INTENSITY_SIZE','%GL_TEXTURE_INTERNAL_FORMAT','%GL_TEXTURE_LUMINANCE_SIZE',
+            '%GL_TEXTURE_MAG_FILTER','%GL_TEXTURE_MATRIX','%GL_TEXTURE_MIN_FILTER','%GL_TEXTURE_PRIORITY','%GL_TEXTURE_RED_SIZE','%GL_TEXTURE_RESIDENT','%GL_TEXTURE_STACK_DEPTH','%GL_TEXTURE_WIDTH',
+            '%GL_TEXTURE_WRAP_S','%GL_TEXTURE_WRAP_T','%GL_TRANSFORM_BIT','%GL_TRIANGLES','%GL_TRIANGLE_FAN','%GL_TRIANGLE_STRIP','%GL_TRUE','%GL_UNPACK_ALIGNMENT',
+            '%GL_UNPACK_LSB_FIRST','%GL_UNPACK_ROW_LENGTH','%GL_UNPACK_SKIP_PIXELS','%GL_UNPACK_SKIP_ROWS','%GL_UNPACK_SWAP_BYTES','%GL_UNSIGNED_BYTE','%GL_UNSIGNED_BYTE_3_3_2_EXT','%GL_UNSIGNED_INT',
+            '%GL_UNSIGNED_INT_10_10_10_2_EXT','%GL_UNSIGNED_INT_8_8_8_8_EXT','%GL_UNSIGNED_SHORT','%GL_UNSIGNED_SHORT_4_4_4_4_EXT','%GL_UNSIGNED_SHORT_5_5_5_1_EXT','%GL_V2F','%GL_V3F','%GL_VENDOR',
+            '%GL_VERSION','%GL_VERSION_1_1','%GL_VERTEX_ARRAY','%GL_VERTEX_ARRAY_COUNT_EXT','%GL_VERTEX_ARRAY_EXT','%GL_VERTEX_ARRAY_POINTER','%GL_VERTEX_ARRAY_POINTER_EXT','%GL_VERTEX_ARRAY_SIZE',
+            '%GL_VERTEX_ARRAY_SIZE_EXT','%GL_VERTEX_ARRAY_STRIDE','%GL_VERTEX_ARRAY_STRIDE_EXT','%GL_VERTEX_ARRAY_TYPE','%GL_VERTEX_ARRAY_TYPE_EXT','%GL_VIEWPORT','%GL_VIEWPORT_BIT','%GL_WIN_SWAP_HINT',
+            '%GL_XOR','%GL_ZERO','%GL_ZOOM_X','%GL_ZOOM_Y','%GRAY','%GREEN','%GWLP_HINSTANCE','%GWLP_HWNDPARENT',
+            '%GWLP_ID','%GWLP_USERDATA','%GWLP_WNDPROC','%GWL_EXSTYLE','%GWL_HINSTANCE','%GWL_HWNDPARENT','%GWL_ID','%GWL_STYLE',
+            '%GWL_USERDATA','%GWL_WNDPROC','%HDM_FIRST','%HTCAPTION','%HWND_BOTTOM','%HWND_DESKTOP','%HWND_MESSAGE','%HWND_NOTOPMOST',
+            '%HWND_TOP','%HWND_TOPMOST','%ICRYPTO_XOR_DECREASE','%ICRYPTO_XOR_INCREASE','%ICRYPTO_XOR_NORMAL','%IDABORT','%IDCANCEL','%IDCONTINUE',
+            '%IDIGNORE','%IDNO','%IDOK','%IDRETRY','%IDTIMEOUT','%IDTRYAGAIN','%IDYES','%INTERNET_CONNECTION_CONFIGURED',
+            '%INTERNET_CONNECTION_LAN','%INTERNET_CONNECTION_MODEM','%INTERNET_CONNECTION_MODEM_BUSY','%INTERNET_CONNECTION_OFFLINE','%INTERNET_CONNECTION_PROXY','%INTERNET_RAS_INSTALLED','%LBN_DBLCLK','%LBN_KILLFOCUS',
+            '%LBN_SELCANCEL','%LBN_SELCHANGE','%LBN_SETFOCUS','%LBS_DISABLENOSCROLL','%LBS_EXTENDEDSEL','%LBS_MULTICOLUMN','%LBS_MULTIPLESEL','%LBS_NOINTEGRALHEIGHT',
+            '%LBS_NOSEL','%LBS_NOTIFY','%LBS_SORT','%LBS_STANDARD','%LBS_USETABSTOPS','%LB_ADDFILE','%LB_ADDSTRING','%LB_DELETESTRING',
+            '%LB_DIR','%LB_FINDSTRING','%LB_FINDSTRINGEXACT','%LB_GETANCHORINDEX','%LB_GETCARETINDEX','%LB_GETCOUNT','%LB_GETCURSEL','%LB_GETHORIZONTALEXTENT',
+            '%LB_GETITEMDATA','%LB_GETITEMHEIGHT','%LB_GETITEMRECT','%LB_GETLISTBOXINFO','%LB_GETLOCALE','%LB_GETSEL','%LB_GETSELCOUNT','%LB_GETSELITEMS',
+            '%LB_GETTEXT','%LB_GETTEXTLEN','%LB_GETTOPINDEX','%LB_INITSTORAGE','%LB_INSERTSTRING','%LB_ITEMFROMPOINT','%LB_MULTIPLEADDSTRING','%LB_RESETCONTENT',
+            '%LB_SELECTSTRING','%LB_SELITEMRANGE','%LB_SELITEMRANGEEX','%LB_SETANCHORINDEX','%LB_SETCARETINDEX','%LB_SETCOLUMNWIDTH','%LB_SETCOUNT','%LB_SETCURSEL',
+            '%LB_SETHORIZONTALEXTENT','%LB_SETITEMDATA','%LB_SETITEMHEIGHT','%LB_SETLOCALE','%LB_SETSEL','%LB_SETTABSTOPS','%LB_SETTOPINDEX','%LF_FACESIZE',
+            '%LTGRAY','%LVM_FIRST','%LWA_ALPHA','%LWA_COLORKEY','%MAGENTA','%MAXBYTE','%MAXCHAR','%MAXDWORD',
+            '%MAXSHORT','%MAXWORD','%MAX_PATH','%MB_ABORTRETRYIGNORE','%MB_APPLMODAL','%MB_CANCELTRYCONTINUE','%MB_DEFBUTTON1','%MB_DEFBUTTON2',
+            '%MB_DEFBUTTON3','%MB_HELP','%MB_ICONASTERISK','%MB_ICONERROR','%MB_ICONEXCLAMATION','%MB_ICONHAND','%MB_ICONINFORMATION','%MB_ICONQUESTION',
+            '%MB_ICONSTOP','%MB_ICONWARNING','%MB_OK','%MB_OKCANCEL','%MB_RETRYCANCEL','%MB_SIMPLE','%MB_SYSTEMMODAL','%MB_TOPMOST',
+            '%MB_YESNO','%MB_YESNOCANCEL','%MF_CHECKED','%MF_DISABLED','%MF_ENABLED','%MF_GRAYED','%MF_SEPARATOR','%MF_UNCHECKED',
+            '%MINCHAR','%MINLONG','%MINSHORT','%NULL','%ODBC352_INC','%ODBCVER','%ODBC_ADD_DSN','%ODBC_ADD_SYS_DSN',
+            '%ODBC_BOTH_DSN','%ODBC_CONFIG_DRIVER','%ODBC_CONFIG_DRIVER_MAX','%ODBC_CONFIG_DSN','%ODBC_CONFIG_SYS_DSN','%ODBC_DRIVER_VERSION','%ODBC_ERROR_COMPONENT_NOT_FOUND','%ODBC_ERROR_CREATE_DSN_FAILED',
+            '%ODBC_ERROR_GENERAL_ERR','%ODBC_ERROR_INVALID_BUFF_LEN','%ODBC_ERROR_INVALID_DSN','%ODBC_ERROR_INVALID_HWND','%ODBC_ERROR_INVALID_INF','%ODBC_ERROR_INVALID_KEYWORD_VALUE','%ODBC_ERROR_INVALID_LOG_FILE','%ODBC_ERROR_INVALID_NAME',
+            '%ODBC_ERROR_INVALID_PARAM_SEQUENCE','%ODBC_ERROR_INVALID_PATH','%ODBC_ERROR_INVALID_REQUEST_TYPE','%ODBC_ERROR_INVALID_STR','%ODBC_ERROR_LOAD_LIB_FAILED','%ODBC_ERROR_OUTPUT_STRING_TRUNCATED','%ODBC_ERROR_OUT_OF_MEM','%ODBC_ERROR_REMOVE_DSN_FAILED',
+            '%ODBC_ERROR_REQUEST_FAILED','%ODBC_ERROR_USAGE_UPDATE_FAILED','%ODBC_ERROR_USER_CANCELED','%ODBC_ERROR_WRITING_SYSINFO_FAILED','%ODBC_INSTALL_COMPLETE','%ODBC_INSTALL_DRIVER','%ODBC_INSTALL_INQUIRY','%ODBC_REMOVE_DEFAULT_DSN',
+            '%ODBC_REMOVE_DRIVER','%ODBC_REMOVE_DSN','%ODBC_REMOVE_SYS_DSN','%ODBC_SYSTEM_DSN','%ODBC_USER_DSN','%OFN_ALLOWMULTISELECT','%OFN_CREATEPROMPT','%OFN_ENABLEHOOK',
+            '%OFN_ENABLEINCLUDENOTIFY','%OFN_ENABLESIZING','%OFN_ENABLETEMPLATE','%OFN_ENABLETEMPLATEHANDLE','%OFN_EXPLORER','%OFN_EXTENSIONDIFFERENT','%OFN_FILEMUSTEXIST','%OFN_HIDEREADONLY',
+            '%OFN_LONGNAMES','%OFN_NOCHANGEDIR','%OFN_NODEREFERENCELINKS','%OFN_NOLONGNAMES','%OFN_NONETWORKBUTTON','%OFN_NOREADONLYRETURN','%OFN_NOTESTFILECREATE','%OFN_NOVALIDATE',
+            '%OFN_OVERWRITEPROMPT','%OFN_PATHMUSTEXIST','%OFN_READONLY','%OFN_SHAREAWARE','%OFN_SHOWHELP','%OS_ERROR_CALLFUNCTION','%OS_ERROR_EMPTYSTRING','%OS_ERROR_LOADLIBRARY',
+            '%OS_ERROR_SUCCESS','%OS_ERROR_WRONGPARAMETER','%OS_SHELL_ASYNC','%OS_SHELL_SYNC','%OS_WINDOWS_2K','%OS_WINDOWS_95','%OS_WINDOWS_95_OSR2','%OS_WINDOWS_98',
+            '%OS_WINDOWS_98_SE','%OS_WINDOWS_ME','%OS_WINDOWS_NT','%OS_WINDOWS_SERVER_2003','%OS_WINDOWS_SERVER_LONGHORN','%OS_WINDOWS_SERVER_LONGHORN_DC','%OS_WINDOWS_VISTA','%OS_WINDOWS_XP',
+            '%OS_WNDSTYLE_HIDE','%OS_WNDSTYLE_MAXIMIZED','%OS_WNDSTYLE_MINIMIZED','%OS_WNDSTYLE_MINIMIZEDNOFOCUS','%OS_WNDSTYLE_NORMAL','%OS_WNDSTYLE_NORMALNOFOCUS','%PATH_EXT','%PATH_FILE',
+            '%PATH_FILEEXT','%PATH_ROOT','%PATH_ROOTPATH','%PATH_ROOTPATHPROG','%PATH_ROOTPATHPROGEXT','%PBM_DELTAPOS','%PBM_GETPOS','%PBM_GETRANGE',
+            '%PBM_SETBARCOLOR','%PBM_SETBKCOLOR','%PBM_SETPOS','%PBM_SETRANGE','%PBM_SETRANGE32','%PBM_SETSTEP','%PBM_STEPIT','%PBS_SMOOTH',
+            '%PBS_VERTICAL','%PC_DISABLEWAKEEVENT_OFF','%PC_DISABLEWAKEEVENT_ON','%PC_EB_NOCONFIRMATION','%PC_EB_NOPROGRESSUI','%PC_EB_NORMAL','%PC_EB_NOSOUND','%PC_FORCECRITICAL_OFF',
+            '%PC_FORCECRITICAL_ON','%PC_HIBERNATE_OFF','%PC_HIBERNATE_ON','%PC_RD_FORCE','%PC_RD_FORCEIFHUNG','%PC_RD_LOGOFF','%PC_RD_POWEROFF','%PC_RD_REBOOT',
+            '%PC_RD_SHUTDOWN','%PC_SD_DONOT_FORCE','%PC_SD_DONOT_REBOOT','%PC_SD_FORCE','%PC_SD_REBOOT','%PFA_CENTER','%PFA_LEFT','%PFA_RIGHT',
+            '%PF_3DNOW_INSTRUCTIONS_AVAILABLE','%PF_CHANNELS_ENABLED','%PF_COMPARE64_EXCHANGE128','%PF_COMPARE_EXCHANGE128','%PF_COMPARE_EXCHANGE_DOUBLE','%PF_FLOATING_POINT_EMULATED','%PF_FLOATING_POINT_PRECISION_ERRATA','%PF_MMX_INSTRUCTIONS_AVAILABLE',
+            '%PF_NX_ENABLED','%PF_PAE_ENABLED','%PF_RDTSC_INSTRUCTION_AVAILABLE','%PF_SSE3_INSTRUCTIONS_AVAILABLE','%PF_XMMI64_INSTRUCTIONS_AVAILABLE','%PF_XMMI_INSTRUCTIONS_AVAILABLE','%PGM_FIRST','%RED',
+            '%RTF_UBB','%SAPI_SVSFDEFAULT','%SAPI_SVSFISFILENAME','%SAPI_SVSFISNOTXML','%SAPI_SVSFISXML','%SAPI_SVSFLAGSASYNC','%SAPI_SVSFNLPMASK','%SAPI_SVSFNLPSPEAKPUNC',
+            '%SAPI_SVSFPERSISTXML','%SAPI_SVSFPURGEBEFORESPEAK','%SAPI_SVSFUNUSEDFLAGS','%SAPI_SVSFVOICEMASK','%SBS_SIZEGRIP','%SB_BOTTOM','%SB_ENDSCROLL','%SB_LEFT',
+            '%SB_LINEDOWN','%SB_LINELEFT','%SB_LINERIGHT','%SB_LINEUP','%SB_PAGEDOWN','%SB_PAGELEFT','%SB_PAGERIGHT','%SB_PAGEUP',
+            '%SB_RIGHT','%SB_SETPARTS','%SB_SETTEXT','%SB_THUMBPOSITION','%SB_THUMBTRACK','%SB_TOP','%SCF_ALL','%SCF_ASSOCIATEFONT',
+            '%SCF_DEFAULT','%SCF_NOKBUPDATE','%SCF_SELECTION','%SCF_USEUIRULES','%SCF_WORD','%SC_CLOSE','%SC_CONTEXTHELP','%SC_HOTKEY',
+            '%SC_HSCROLL','%SC_KEYMENU','%SC_MAXIMIZE','%SC_MINIMIZE','%SC_MONITORPOWER','%SC_MOUSEMENU','%SC_MOVE','%SC_NEXTWINDOW',
+            '%SC_PREVWINDOW','%SC_RESTORE','%SC_SCREENSAVE','%SC_SIZE','%SC_TASKLIST','%SC_VSCROLL','%SERVICE_ACTIVE','%SERVICE_AUTO_START',
+            '%SERVICE_BOOT_START','%SERVICE_CONTINUE_PENDING','%SERVICE_DEMAND_START','%SERVICE_DISABLED','%SERVICE_DRIVER','%SERVICE_INACTIVE','%SERVICE_INFO_DISPLAY_NAME','%SERVICE_INFO_NAME',
+            '%SERVICE_PAUSED','%SERVICE_PAUSE_PENDING','%SERVICE_RUNNING','%SERVICE_START_PENDING','%SERVICE_STATE_ALL','%SERVICE_STOPPED','%SERVICE_STOP_PENDING','%SERVICE_SYSTEM_START',
+            '%SERVICE_TYPE_ALL','%SERVICE_WIN32','%SES_ALLOWBEEPS','%SES_BEEPONMAXTEXT','%SES_BIDI','%SES_EMULATE10','%SES_EMULATESYSEDIT','%SES_EXTENDBACKCOLOR',
+            '%SES_LOWERCASE','%SES_MAPCPS','%SES_NOIME','%SES_NOINPUTSEQUENCECHK','%SES_SCROLLONKILLFOCUS','%SES_UPPERCASE','%SES_USEAIMM','%SES_USECRLF',
+            '%SES_XLTCRCRLFTOCR','%SF_RTF','%SF_TEXT','%SMTP_SET_ATTACH_CONTENT_TYPE','%SMTP_SET_CONTENT_TYPE_PREFIX','%SQL_AA_FALSE','%SQL_AA_TRUE','%SQL_ACCESSIBLE_PROCEDURES',
+            '%SQL_ACCESSIBLE_TABLES','%SQL_ACCESS_MODE','%SQL_ACTIVE_CONNECTIONS','%SQL_ACTIVE_ENVIRONMENTS','%SQL_ACTIVE_STATEMENTS','%SQL_ADD','%SQL_AD_ADD_CONSTRAINT_DEFERRABLE','%SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED',
+            '%SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE','%SQL_AD_ADD_DOMAIN_CONSTRAINT','%SQL_AD_ADD_DOMAIN_DEFAULT','%SQL_AD_CONSTRAINT_NAME_DEFINITION','%SQL_AD_DROP_DOMAIN_CONSTRAINT','%SQL_AD_DROP_DOMAIN_DEFAULT','%SQL_AF_ALL',
+            '%SQL_AF_AVG','%SQL_AF_COUNT','%SQL_AF_DISTINCT','%SQL_AF_MAX','%SQL_AF_MIN','%SQL_AF_SUM','%SQL_AGGREGATE_FUNCTIONS','%SQL_ALL_EXCEPT_LIKE',
+            '%SQL_ALL_TYPES','%SQL_ALTER_DOMAIN','%SQL_ALTER_TABLE','%SQL_AM_CONNECTION','%SQL_AM_NONE','%SQL_AM_STATEMENT','%SQL_API_ALL_FUNCTIONS','%SQL_API_LOADBYORDINAL',
+            '%SQL_API_ODBC3_ALL_FUNCTIONS','%SQL_API_ODBC3_ALL_FUNCTIONS_SIZE','%SQL_API_SQLALLOCCONNECT','%SQL_API_SQLALLOCENV','%SQL_API_SQLALLOCHANDLE','%SQL_API_SQLALLOCHANDLESTD','%SQL_API_SQLALLOCSTMT','%SQL_API_SQLBINDCOL',
+            '%SQL_API_SQLBINDPARAM','%SQL_API_SQLBINDPARAMETER','%SQL_API_SQLBROWSECONNECT','%SQL_API_SQLBULKOPERATIONS','%SQL_API_SQLCANCEL','%SQL_API_SQLCLOSECURSOR','%SQL_API_SQLCOLATTRIBUTE','%SQL_API_SQLCOLATTRIBUTES',
+            '%SQL_API_SQLCOLUMNPRIVILEGES','%SQL_API_SQLCOLUMNS','%SQL_API_SQLCONNECT','%SQL_API_SQLCOPYDESC','%SQL_API_SQLDATASOURCES','%SQL_API_SQLDESCRIBECOL','%SQL_API_SQLDESCRIBEPARAM','%SQL_API_SQLDISCONNECT',
+            '%SQL_API_SQLDRIVERCONNECT','%SQL_API_SQLDRIVERS','%SQL_API_SQLENDTRAN','%SQL_API_SQLERROR','%SQL_API_SQLEXECDIRECT','%SQL_API_SQLEXECUTE','%SQL_API_SQLEXTENDEDFETCH','%SQL_API_SQLFETCH',
+            '%SQL_API_SQLFETCHSCROLL','%SQL_API_SQLFOREIGNKEYS','%SQL_API_SQLFREECONNECT','%SQL_API_SQLFREEENV','%SQL_API_SQLFREEHANDLE','%SQL_API_SQLFREESTMT','%SQL_API_SQLGETCONNECTATTR','%SQL_API_SQLGETCONNECTOPTION',
+            '%SQL_API_SQLGETCURSORNAME','%SQL_API_SQLGETDATA','%SQL_API_SQLGETDESCFIELD','%SQL_API_SQLGETDESCREC','%SQL_API_SQLGETDIAGFIELD','%SQL_API_SQLGETDIAGREC','%SQL_API_SQLGETENVATTR','%SQL_API_SQLGETFUNCTIONS',
+            '%SQL_API_SQLGETINFO','%SQL_API_SQLGETSTMTATTR','%SQL_API_SQLGETSTMTOPTION','%SQL_API_SQLGETTYPEINFO','%SQL_API_SQLMORERESULTS','%SQL_API_SQLNATIVESQL','%SQL_API_SQLNUMPARAMS','%SQL_API_SQLNUMRESULTCOLS',
+            '%SQL_API_SQLPARAMDATA','%SQL_API_SQLPARAMOPTIONS','%SQL_API_SQLPREPARE','%SQL_API_SQLPRIMARYKEYS','%SQL_API_SQLPROCEDURECOLUMNS','%SQL_API_SQLPROCEDURES','%SQL_API_SQLPUTDATA','%SQL_API_SQLROWCOUNT',
+            '%SQL_API_SQLSETCONNECTATTR','%SQL_API_SQLSETCONNECTOPTION','%SQL_API_SQLSETCURSORNAME','%SQL_API_SQLSETDESCFIELD','%SQL_API_SQLSETDESCREC','%SQL_API_SQLSETENVATTR','%SQL_API_SQLSETPARAM','%SQL_API_SQLSETPOS',
+            '%SQL_API_SQLSETSCROLLOPTIONS','%SQL_API_SQLSETSTMTATTR','%SQL_API_SQLSETSTMTOPTION','%SQL_API_SQLSPECIALCOLUMNS','%SQL_API_SQLSTATISTICS','%SQL_API_SQLTABLEPRIVILEGES','%SQL_API_SQLTABLES','%SQL_API_SQLTRANSACT',
+            '%SQL_ARD_TYPE','%SQL_ASYNC_ENABLE','%SQL_ASYNC_ENABLE_DEFAULT','%SQL_ASYNC_ENABLE_OFF','%SQL_ASYNC_ENABLE_ON','%SQL_ASYNC_MODE','%SQL_ATTR_ACCESS_MODE','%SQL_ATTR_ANSI_APP',
+            '%SQL_ATTR_APP_PARAM_DESC','%SQL_ATTR_APP_ROW_DESC','%SQL_ATTR_ASYNC_ENABLE','%SQL_ATTR_AUTOCOMMIT','%SQL_ATTR_AUTO_IPD','%SQL_ATTR_CONCURRENCY','%SQL_ATTR_CONNECTION_DEAD','%SQL_ATTR_CONNECTION_POOLING',
+            '%SQL_ATTR_CONNECTION_TIMEOUT','%SQL_ATTR_CP_MATCH','%SQL_ATTR_CURRENT_CATALOG','%SQL_ATTR_CURSOR_SCROLLABLE','%SQL_ATTR_CURSOR_SENSITIVITY','%SQL_ATTR_CURSOR_TYPE','%SQL_ATTR_DISCONNECT_BEHAVIOR','%SQL_ATTR_ENABLE_AUTO_IPD',
+            '%SQL_ATTR_ENLIST_IN_DTC','%SQL_ATTR_ENLIST_IN_XA','%SQL_ATTR_FETCH_BOOKMARK_PTR','%SQL_ATTR_IMP_PARAM_DESC','%SQL_ATTR_IMP_ROW_DESC','%SQL_ATTR_KEYSET_SIZE','%SQL_ATTR_LOGIN_TIMEOUT','%SQL_ATTR_MAX_LENGTH',
+            '%SQL_ATTR_MAX_ROWS','%SQL_ATTR_METADATA_ID','%SQL_ATTR_NOSCAN','%SQL_ATTR_ODBC_CURSORS','%SQL_ATTR_ODBC_VERSION','%SQL_ATTR_OUTPUT_NTS','%SQL_ATTR_PACKET_SIZE','%SQL_ATTR_PARAMSET_SIZE',
+            '%SQL_ATTR_PARAMS_PROCESSED_PTR','%SQL_ATTR_PARAM_BIND_OFFSET_PTR','%SQL_ATTR_PARAM_BIND_TYPE','%SQL_ATTR_PARAM_OPERATION_PTR','%SQL_ATTR_PARAM_STATUS_PTR','%SQL_ATTR_QUERY_TIMEOUT','%SQL_ATTR_QUIET_MODE','%SQL_ATTR_READONLY',
+            '%SQL_ATTR_READWRITE_UNKNOWN','%SQL_ATTR_RETRIEVE_DATA','%SQL_ATTR_ROWS_FETCHED_PTR','%SQL_ATTR_ROW_ARRAY_SIZE','%SQL_ATTR_ROW_BIND_OFFSET_PTR','%SQL_ATTR_ROW_BIND_TYPE','%SQL_ATTR_ROW_NUMBER','%SQL_ATTR_ROW_OPERATION_PTR',
+            '%SQL_ATTR_ROW_STATUS_PTR','%SQL_ATTR_SIMULATE_CURSOR','%SQL_ATTR_TRACE','%SQL_ATTR_TRACEFILE','%SQL_ATTR_TRANSLATE_LIB','%SQL_ATTR_TRANSLATE_OPTION','%SQL_ATTR_TXN_ISOLATION','%SQL_ATTR_USE_BOOKMARKS',
+            '%SQL_ATTR_WRITE','%SQL_AT_ADD_COLUMN','%SQL_AT_ADD_COLUMN_COLLATION','%SQL_AT_ADD_COLUMN_DEFAULT','%SQL_AT_ADD_COLUMN_SINGLE','%SQL_AT_ADD_CONSTRAINT','%SQL_AT_ADD_TABLE_CONSTRAINT','%SQL_AT_CONSTRAINT_DEFERRABLE',
+            '%SQL_AT_CONSTRAINT_INITIALLY_DEFERRED','%SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_AT_CONSTRAINT_NAME_DEFINITION','%SQL_AT_CONSTRAINT_NON_DEFERRABLE','%SQL_AT_DROP_COLUMN','%SQL_AT_DROP_COLUMN_CASCADE','%SQL_AT_DROP_COLUMN_DEFAULT','%SQL_AT_DROP_COLUMN_RESTRICT',
+            '%SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE','%SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT','%SQL_AT_SET_COLUMN_DEFAULT','%SQL_AUTOCOMMIT','%SQL_AUTOCOMMIT_DEFAULT','%SQL_AUTOCOMMIT_OFF','%SQL_AUTOCOMMIT_ON','%SQL_BATCH_ROW_COUNT',
+            '%SQL_BATCH_SUPPORT','%SQL_BEST_ROWID','%SQL_BIGINT','%SQL_BINARY','%SQL_BIND_BY_COLUMN','%SQL_BIND_TYPE','%SQL_BIND_TYPE_DEFAULT','%SQL_BIT',
+            '%SQL_BOOKMARK_PERSISTENCE','%SQL_BP_CLOSE','%SQL_BP_DELETE','%SQL_BP_DROP','%SQL_BP_OTHER_HSTMT','%SQL_BP_SCROLL','%SQL_BP_TRANSACTION','%SQL_BP_UPDATE',
+            '%SQL_BRC_EXPLICIT','%SQL_BRC_PROCEDURES','%SQL_BRC_ROLLED_UP','%SQL_BS_ROW_COUNT_EXPLICIT','%SQL_BS_ROW_COUNT_PROC','%SQL_BS_SELECT_EXPLICIT','%SQL_BS_SELECT_PROC','%SQL_CA1_ABSOLUTE',
+            '%SQL_CA1_BOOKMARK','%SQL_CA1_BULK_ADD','%SQL_CA1_BULK_DELETE_BY_BOOKMARK','%SQL_CA1_BULK_FETCH_BY_BOOKMARK','%SQL_CA1_BULK_UPDATE_BY_BOOKMARK','%SQL_CA1_LOCK_EXCLUSIVE','%SQL_CA1_LOCK_NO_CHANGE','%SQL_CA1_LOCK_UNLOCK',
+            '%SQL_CA1_NEXT','%SQL_CA1_POSITIONED_DELETE','%SQL_CA1_POSITIONED_UPDATE','%SQL_CA1_POS_DELETE','%SQL_CA1_POS_POSITION','%SQL_CA1_POS_REFRESH','%SQL_CA1_POS_UPDATE','%SQL_CA1_RELATIVE',
+            '%SQL_CA1_SELECT_FOR_UPDATE','%SQL_CA2_CRC_APPROXIMATE','%SQL_CA2_CRC_EXACT','%SQL_CA2_LOCK_CONCURRENCY','%SQL_CA2_MAX_ROWS_AFFECTS_ALL','%SQL_CA2_MAX_ROWS_CATALOG','%SQL_CA2_MAX_ROWS_DELETE','%SQL_CA2_MAX_ROWS_INSERT',
+            '%SQL_CA2_MAX_ROWS_SELECT','%SQL_CA2_MAX_ROWS_UPDATE','%SQL_CA2_OPT_ROWVER_CONCURRENCY','%SQL_CA2_OPT_VALUES_CONCURRENCY','%SQL_CA2_READ_ONLY_CONCURRENCY','%SQL_CA2_SENSITIVITY_ADDITIONS','%SQL_CA2_SENSITIVITY_DELETIONS','%SQL_CA2_SENSITIVITY_UPDATES',
+            '%SQL_CA2_SIMULATE_NON_UNIQUE','%SQL_CA2_SIMULATE_TRY_UNIQUE','%SQL_CA2_SIMULATE_UNIQUE','%SQL_CASCADE','%SQL_CATALOG_LOCATION','%SQL_CATALOG_NAME','%SQL_CATALOG_NAME_SEPARATOR','%SQL_CATALOG_TERM',
+            '%SQL_CATALOG_USAGE','%SQL_CA_CONSTRAINT_DEFERRABLE','%SQL_CA_CONSTRAINT_INITIALLY_DEFERRED','%SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_CA_CONSTRAINT_NON_DEFERRABLE','%SQL_CA_CREATE_ASSERTION','%SQL_CB_CLOSE','%SQL_CB_DELETE',
+            '%SQL_CB_NON_NULL','%SQL_CB_NULL','%SQL_CB_PRESERVE','%SQL_CCOL_CREATE_COLLATION','%SQL_CCS_COLLATE_CLAUSE','%SQL_CCS_CREATE_CHARACTER_SET','%SQL_CCS_LIMITED_COLLATION','%SQL_CC_CLOSE',
+            '%SQL_CC_DELETE','%SQL_CC_PRESERVE','%SQL_CDO_COLLATION','%SQL_CDO_CONSTRAINT','%SQL_CDO_CONSTRAINT_DEFERRABLE','%SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED','%SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_CDO_CONSTRAINT_NAME_DEFINITION',
+            '%SQL_CDO_CONSTRAINT_NON_DEFERRABLE','%SQL_CDO_CREATE_DOMAIN','%SQL_CDO_DEFAULT','%SQL_CD_FALSE','%SQL_CD_TRUE','%SQL_CHAR','%SQL_CLOSE','%SQL_CL_END',
+            '%SQL_CL_START','%SQL_CN_ANY','%SQL_CN_DIFFERENT','%SQL_CN_NONE','%SQL_CODE_DATE','%SQL_CODE_DAY','%SQL_CODE_DAY_TO_HOUR','%SQL_CODE_DAY_TO_MINUTE',
+            '%SQL_CODE_DAY_TO_SECOND','%SQL_CODE_HOUR','%SQL_CODE_HOUR_TO_MINUTE','%SQL_CODE_HOUR_TO_SECOND','%SQL_CODE_MINUTE','%SQL_CODE_MINUTE_TO_SECOND','%SQL_CODE_MONTH','%SQL_CODE_SECOND',
+            '%SQL_CODE_TIME','%SQL_CODE_TIMESTAMP','%SQL_CODE_YEAR','%SQL_CODE_YEAR_TO_MONTH','%SQL_COLATT_OPT_MAX','%SQL_COLATT_OPT_MIN','%SQL_COLLATION_SEQ','%SQL_COLUMN_ALIAS',
+            '%SQL_COLUMN_AUTO_INCREMENT','%SQL_COLUMN_CASE_SENSITIVE','%SQL_COLUMN_COUNT','%SQL_COLUMN_DISPLAY_SIZE','%SQL_COLUMN_IGNORE','%SQL_COLUMN_LABEL','%SQL_COLUMN_LENGTH','%SQL_COLUMN_MONEY',
+            '%SQL_COLUMN_NAME','%SQL_COLUMN_NULLABLE','%SQL_COLUMN_NUMBER_UNKNOWN','%SQL_COLUMN_OWNER_NAME','%SQL_COLUMN_PRECISION','%SQL_COLUMN_QUALIFIER_NAME','%SQL_COLUMN_SCALE','%SQL_COLUMN_SEARCHABLE',
+            '%SQL_COLUMN_TABLE_NAME','%SQL_COLUMN_TYPE','%SQL_COLUMN_TYPE_NAME','%SQL_COLUMN_UNSIGNED','%SQL_COLUMN_UPDATABLE','%SQL_COL_PRED_BASIC','%SQL_COL_PRED_CHAR','%SQL_COMMIT',
+            '%SQL_CONCAT_NULL_BEHAVIOR','%SQL_CONCURRENCY','%SQL_CONCUR_DEFAULT','%SQL_CONCUR_LOCK','%SQL_CONCUR_READ_ONLY','%SQL_CONCUR_ROWVER','%SQL_CONCUR_TIMESTAMP','%SQL_CONCUR_VALUES',
+            '%SQL_CONVERT_BIGINT','%SQL_CONVERT_BINARY','%SQL_CONVERT_BIT','%SQL_CONVERT_CHAR','%SQL_CONVERT_DATE','%SQL_CONVERT_DECIMAL','%SQL_CONVERT_DOUBLE','%SQL_CONVERT_FLOAT',
+            '%SQL_CONVERT_FUNCTIONS','%SQL_CONVERT_GUID','%SQL_CONVERT_INTEGER','%SQL_CONVERT_INTERVAL_DAY_TIME','%SQL_CONVERT_INTERVAL_YEAR_MONTH','%SQL_CONVERT_LONGVARBINARY','%SQL_CONVERT_LONGVARCHAR','%SQL_CONVERT_NUMERIC',
+            '%SQL_CONVERT_REAL','%SQL_CONVERT_SMALLINT','%SQL_CONVERT_TIME','%SQL_CONVERT_TIMESTAMP','%SQL_CONVERT_TINYINT','%SQL_CONVERT_VARBINARY','%SQL_CONVERT_VARCHAR','%SQL_CONVERT_WCHAR',
+            '%SQL_CONVERT_WLONGVARCHAR','%SQL_CONVERT_WVARCHAR','%SQL_CORRELATION_NAME','%SQL_CP_DEFAULT','%SQL_CP_MATCH_DEFAULT','%SQL_CP_OFF','%SQL_CP_ONE_PER_DRIVER','%SQL_CP_ONE_PER_HENV',
+            '%SQL_CP_RELAXED_MATCH','%SQL_CP_STRICT_MATCH','%SQL_CREATE_ASSERTION','%SQL_CREATE_CHARACTER_SET','%SQL_CREATE_COLLATION','%SQL_CREATE_DOMAIN','%SQL_CREATE_SCHEMA','%SQL_CREATE_TABLE',
+            '%SQL_CREATE_TRANSLATION','%SQL_CREATE_VIEW','%SQL_CR_CLOSE','%SQL_CR_DELETE','%SQL_CR_PRESERVE','%SQL_CS_AUTHORIZATION','%SQL_CS_CREATE_SCHEMA','%SQL_CS_DEFAULT_CHARACTER_SET',
+            '%SQL_CTR_CREATE_TRANSLATION','%SQL_CT_COLUMN_COLLATION','%SQL_CT_COLUMN_CONSTRAINT','%SQL_CT_COLUMN_DEFAULT','%SQL_CT_COMMIT_DELETE','%SQL_CT_COMMIT_PRESERVE','%SQL_CT_CONSTRAINT_DEFERRABLE','%SQL_CT_CONSTRAINT_INITIALLY_DEFERRED',
+            '%SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_CT_CONSTRAINT_NAME_DEFINITION','%SQL_CT_CONSTRAINT_NON_DEFERRABLE','%SQL_CT_CREATE_TABLE','%SQL_CT_GLOBAL_TEMPORARY','%SQL_CT_LOCAL_TEMPORARY','%SQL_CT_TABLE_CONSTRAINT','%SQL_CURRENT_QUALIFIER',
+            '%SQL_CURSOR_COMMIT_BEHAVIOR','%SQL_CURSOR_DYNAMIC','%SQL_CURSOR_FORWARD_ONLY','%SQL_CURSOR_KEYSET_DRIVEN','%SQL_CURSOR_ROLLBACK_BEHAVIOR','%SQL_CURSOR_SENSITIVITY','%SQL_CURSOR_STATIC','%SQL_CURSOR_TYPE',
+            '%SQL_CURSOR_TYPE_DEFAULT','%SQL_CUR_DEFAULT','%SQL_CUR_USE_DRIVER','%SQL_CUR_USE_IF_NEEDED','%SQL_CUR_USE_ODBC','%SQL_CU_DML_STATEMENTS','%SQL_CU_INDEX_DEFINITION','%SQL_CU_PRIVILEGE_DEFINITION',
+            '%SQL_CU_PROCEDURE_INVOCATION','%SQL_CU_TABLE_DEFINITION','%SQL_CVT_BIGINT','%SQL_CVT_BINARY','%SQL_CVT_BIT','%SQL_CVT_CHAR','%SQL_CVT_DATE','%SQL_CVT_DECIMAL',
+            '%SQL_CVT_DOUBLE','%SQL_CVT_FLOAT','%SQL_CVT_GUID','%SQL_CVT_INTEGER','%SQL_CVT_INTERVAL_DAY_TIME','%SQL_CVT_INTERVAL_YEAR_MONTH','%SQL_CVT_LONGVARBINARY','%SQL_CVT_LONGVARCHAR',
+            '%SQL_CVT_NUMERIC','%SQL_CVT_REAL','%SQL_CVT_SMALLINT','%SQL_CVT_TIME','%SQL_CVT_TIMESTAMP','%SQL_CVT_TINYINT','%SQL_CVT_VARBINARY','%SQL_CVT_VARCHAR',
+            '%SQL_CVT_WCHAR','%SQL_CVT_WLONGVARCHAR','%SQL_CVT_WVARCHAR','%SQL_CV_CASCADED','%SQL_CV_CHECK_OPTION','%SQL_CV_CREATE_VIEW','%SQL_CV_LOCAL','%SQL_C_BINARY',
+            '%SQL_C_BIT','%SQL_C_BOOKMARK','%SQL_C_CHAR','%SQL_C_DATE','%SQL_C_DEFAULT','%SQL_C_DOUBLE','%SQL_C_FLOAT','%SQL_C_GUID',
+            '%SQL_C_INTERVAL_DAY','%SQL_C_INTERVAL_DAY_TO_HOUR','%SQL_C_INTERVAL_DAY_TO_MINUTE','%SQL_C_INTERVAL_DAY_TO_SECOND','%SQL_C_INTERVAL_HOUR','%SQL_C_INTERVAL_HOUR_TO_MINUTE','%SQL_C_INTERVAL_HOUR_TO_SECOND','%SQL_C_INTERVAL_MINUTE',
+            '%SQL_C_INTERVAL_MINUTE_TO_SECOND','%SQL_C_INTERVAL_MONTH','%SQL_C_INTERVAL_SECOND','%SQL_C_INTERVAL_YEAR','%SQL_C_INTERVAL_YEAR_TO_MONTH','%SQL_C_LONG','%SQL_C_NUMERIC','%SQL_C_SBIGINT',
+            '%SQL_C_SHORT','%SQL_C_SLONG','%SQL_C_SSHORT','%SQL_C_STINYINT','%SQL_C_TIME','%SQL_C_TIMESTAMP','%SQL_C_TINYINT','%SQL_C_TYPE_DATE',
+            '%SQL_C_TYPE_TIME','%SQL_C_TYPE_TIMESTAMP','%SQL_C_UBIGINT','%SQL_C_ULONG','%SQL_C_USHORT','%SQL_C_UTINYINT','%SQL_C_VARBOOKMARK','%SQL_DATABASE_NAME',
+            '%SQL_DATA_AT_EXEC','%SQL_DATA_SOURCE_NAME','%SQL_DATA_SOURCE_READ_ONLY','%SQL_DATE','%SQL_DATETIME','%SQL_DATETIME_LITERALS','%SQL_DATE_LEN','%SQL_DAY',
+            '%SQL_DAY_TO_HOUR','%SQL_DAY_TO_MINUTE','%SQL_DAY_TO_SECOND','%SQL_DA_DROP_ASSERTION','%SQL_DBMS_NAME','%SQL_DBMS_VER','%SQL_DB_DEFAULT','%SQL_DB_DISCONNECT',
+            '%SQL_DB_RETURN_TO_POOL','%SQL_DCS_DROP_CHARACTER_SET','%SQL_DC_DROP_COLLATION','%SQL_DDL_INDEX','%SQL_DD_CASCADE','%SQL_DD_DROP_DOMAIN','%SQL_DD_RESTRICT','%SQL_DECIMAL',
+            '%SQL_DEFAULT','%SQL_DEFAULT_PARAM','%SQL_DEFAULT_TXN_ISOLATION','%SQL_DELETE','%SQL_DELETE_BY_BOOKMARK','%SQL_DESCRIBE_PARAMETER','%SQL_DESC_ALLOC_AUTO','%SQL_DESC_ALLOC_TYPE',
+            '%SQL_DESC_ALLOC_USER','%SQL_DESC_ARRAY_SIZE','%SQL_DESC_ARRAY_STATUS_PTR','%SQL_DESC_AUTO_UNIQUE_VALUE','%SQL_DESC_BASE_COLUMN_NAME','%SQL_DESC_BASE_TABLE_NAME','%SQL_DESC_BIND_OFFSET_PTR','%SQL_DESC_BIND_TYPE',
+            '%SQL_DESC_CASE_SENSITIVE','%SQL_DESC_CATALOG_NAME','%SQL_DESC_CONCISE_TYPE','%SQL_DESC_COUNT','%SQL_DESC_DATA_PTR','%SQL_DESC_DATETIME_INTERVAL_CODE','%SQL_DESC_DATETIME_INTERVAL_PRECISION','%SQL_DESC_DISPLAY_SIZE',
+            '%SQL_DESC_FIXED_PREC_SCALE','%SQL_DESC_INDICATOR_PTR','%SQL_DESC_LABEL','%SQL_DESC_LENGTH','%SQL_DESC_LITERAL_PREFIX','%SQL_DESC_LITERAL_SUFFIX','%SQL_DESC_LOCAL_TYPE_NAME','%SQL_DESC_MAXIMUM_SCALE',
+            '%SQL_DESC_MINIMUM_SCALE','%SQL_DESC_NAME','%SQL_DESC_NULLABLE','%SQL_DESC_NUM_PREC_RADIX','%SQL_DESC_OCTET_LENGTH','%SQL_DESC_OCTET_LENGTH_PTR','%SQL_DESC_PARAMETER_TYPE','%SQL_DESC_PRECISION',
+            '%SQL_DESC_ROWS_PROCESSED_PTR','%SQL_DESC_SCALE','%SQL_DESC_SCHEMA_NAME','%SQL_DESC_SEARCHABLE','%SQL_DESC_TABLE_NAME','%SQL_DESC_TYPE','%SQL_DESC_TYPE_NAME','%SQL_DESC_UNNAMED',
+            '%SQL_DESC_UNSIGNED','%SQL_DESC_UPDATABLE','%SQL_DIAG_ALTER_TABLE','%SQL_DIAG_CALL','%SQL_DIAG_CLASS_ORIGIN','%SQL_DIAG_COLUMN_NUMBER','%SQL_DIAG_CONNECTION_NAME','%SQL_DIAG_CREATE_INDEX',
+            '%SQL_DIAG_CREATE_TABLE','%SQL_DIAG_CREATE_VIEW','%SQL_DIAG_CURSOR_ROW_COUNT','%SQL_DIAG_DELETE_WHERE','%SQL_DIAG_DROP_INDEX','%SQL_DIAG_DROP_TABLE','%SQL_DIAG_DROP_VIEW','%SQL_DIAG_DYNAMIC_DELETE_CURSOR',
+            '%SQL_DIAG_DYNAMIC_FUNCTION','%SQL_DIAG_DYNAMIC_FUNCTION_CODE','%SQL_DIAG_DYNAMIC_UPDATE_CURSOR','%SQL_DIAG_GRANT','%SQL_DIAG_INSERT','%SQL_DIAG_MESSAGE_TEXT','%SQL_DIAG_NATIVE','%SQL_DIAG_NUMBER',
+            '%SQL_DIAG_RETURNCODE','%SQL_DIAG_REVOKE','%SQL_DIAG_ROW_COUNT','%SQL_DIAG_ROW_NUMBER','%SQL_DIAG_SELECT_CURSOR','%SQL_DIAG_SERVER_NAME','%SQL_DIAG_SQLSTATE','%SQL_DIAG_SUBCLASS_ORIGIN',
+            '%SQL_DIAG_UNKNOWN_STATEMENT','%SQL_DIAG_UPDATE_WHERE','%SQL_DI_CREATE_INDEX','%SQL_DI_DROP_INDEX','%SQL_DL_SQL92_DATE','%SQL_DL_SQL92_INTERVAL_DAY','%SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR','%SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE',
+            '%SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND','%SQL_DL_SQL92_INTERVAL_HOUR','%SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE','%SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND','%SQL_DL_SQL92_INTERVAL_MINUTE','%SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND','%SQL_DL_SQL92_INTERVAL_MONTH','%SQL_DL_SQL92_INTERVAL_SECOND',
+            '%SQL_DL_SQL92_INTERVAL_YEAR','%SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH','%SQL_DL_SQL92_TIME','%SQL_DL_SQL92_TIMESTAMP','%SQL_DM_VER','%SQL_DOUBLE','%SQL_DRIVER_COMPLETE','%SQL_DRIVER_COMPLETE_REQUIRED',
+            '%SQL_DRIVER_HDBC','%SQL_DRIVER_HDESC','%SQL_DRIVER_HENV','%SQL_DRIVER_HLIB','%SQL_DRIVER_HSTMT','%SQL_DRIVER_NAME','%SQL_DRIVER_NOPROMPT','%SQL_DRIVER_ODBC_VER',
+            '%SQL_DRIVER_PROMPT','%SQL_DRIVER_VER','%SQL_DROP','%SQL_DROP_ASSERTION','%SQL_DROP_CHARACTER_SET','%SQL_DROP_COLLATION','%SQL_DROP_DOMAIN','%SQL_DROP_SCHEMA',
+            '%SQL_DROP_TABLE','%SQL_DROP_TRANSLATION','%SQL_DROP_VIEW','%SQL_DS_CASCADE','%SQL_DS_DROP_SCHEMA','%SQL_DS_RESTRICT','%SQL_DTC_DONE','%SQL_DTC_ENLIST_EXPENSIVE',
+            '%SQL_DTC_TRANSITION_COST','%SQL_DTC_UNENLIST_EXPENSIVE','%SQL_DTR_DROP_TRANSLATION','%SQL_DT_CASCADE','%SQL_DT_DROP_TABLE','%SQL_DT_RESTRICT','%SQL_DV_CASCADE','%SQL_DV_DROP_VIEW',
+            '%SQL_DV_RESTRICT','%SQL_DYNAMIC_CURSOR_ATTRIBUTES1','%SQL_DYNAMIC_CURSOR_ATTRIBUTES2','%SQL_ENSURE','%SQL_ENTIRE_ROWSET','%SQL_ERROR','%SQL_EXPRESSIONS_IN_ORDERBY','%SQL_FALSE',
+            '%SQL_FD_FETCH_ABSOLUTE','%SQL_FD_FETCH_BOOKMARK','%SQL_FD_FETCH_FIRST','%SQL_FD_FETCH_LAST','%SQL_FD_FETCH_NEXT','%SQL_FD_FETCH_PREV','%SQL_FD_FETCH_PRIOR','%SQL_FD_FETCH_RELATIVE',
+            '%SQL_FETCH_ABSOLUTE','%SQL_FETCH_BOOKMARK','%SQL_FETCH_BY_BOOKMARK','%SQL_FETCH_DIRECTION','%SQL_FETCH_FIRST','%SQL_FETCH_FIRST_SYSTEM','%SQL_FETCH_FIRST_USER','%SQL_FETCH_LAST',
+            '%SQL_FETCH_NEXT','%SQL_FETCH_PREV','%SQL_FETCH_PRIOR','%SQL_FETCH_RELATIVE','%SQL_FILE_CATALOG','%SQL_FILE_NOT_SUPPORTED','%SQL_FILE_QUALIFIER','%SQL_FILE_TABLE',
+            '%SQL_FILE_USAGE','%SQL_FLOAT','%SQL_FN_CVT_CAST','%SQL_FN_CVT_CONVERT','%SQL_FN_NUM_ABS','%SQL_FN_NUM_ACOS','%SQL_FN_NUM_ASIN','%SQL_FN_NUM_ATAN',
+            '%SQL_FN_NUM_ATAN2','%SQL_FN_NUM_CEILING','%SQL_FN_NUM_COS','%SQL_FN_NUM_COT','%SQL_FN_NUM_DEGREES','%SQL_FN_NUM_EXP','%SQL_FN_NUM_FLOOR','%SQL_FN_NUM_LOG',
+            '%SQL_FN_NUM_LOG10','%SQL_FN_NUM_MOD','%SQL_FN_NUM_PI','%SQL_FN_NUM_POWER','%SQL_FN_NUM_RADIANS','%SQL_FN_NUM_RAND','%SQL_FN_NUM_ROUND','%SQL_FN_NUM_SIGN',
+            '%SQL_FN_NUM_SIN','%SQL_FN_NUM_SQRT','%SQL_FN_NUM_TAN','%SQL_FN_NUM_TRUNCATE','%SQL_FN_STR_ASCII','%SQL_FN_STR_BIT_LENGTH','%SQL_FN_STR_CHAR','%SQL_FN_STR_CHARACTER_LENGTH',
+            '%SQL_FN_STR_CHAR_LENGTH','%SQL_FN_STR_CONCAT','%SQL_FN_STR_DIFFERENCE','%SQL_FN_STR_INSERT','%SQL_FN_STR_LCASE','%SQL_FN_STR_LEFT','%SQL_FN_STR_LENGTH','%SQL_FN_STR_LOCATE',
+            '%SQL_FN_STR_LOCATE_2','%SQL_FN_STR_LTRIM','%SQL_FN_STR_OCTET_LENGTH','%SQL_FN_STR_POSITION','%SQL_FN_STR_REPEAT','%SQL_FN_STR_REPLACE','%SQL_FN_STR_RIGHT','%SQL_FN_STR_RTRIM',
+            '%SQL_FN_STR_SOUNDEX','%SQL_FN_STR_SPACE','%SQL_FN_STR_SUBSTRING','%SQL_FN_STR_UCASE','%SQL_FN_SYS_DBNAME','%SQL_FN_SYS_IFNULL','%SQL_FN_SYS_USERNAME','%SQL_FN_TD_CURDATE',
+            '%SQL_FN_TD_CURRENT_DATE','%SQL_FN_TD_CURRENT_TIME','%SQL_FN_TD_CURRENT_TIMESTAMP','%SQL_FN_TD_CURTIME','%SQL_FN_TD_DAYNAME','%SQL_FN_TD_DAYOFMONTH','%SQL_FN_TD_DAYOFWEEK','%SQL_FN_TD_DAYOFYEAR',
+            '%SQL_FN_TD_EXTRACT','%SQL_FN_TD_HOUR','%SQL_FN_TD_MINUTE','%SQL_FN_TD_MONTH','%SQL_FN_TD_MONTHNAME','%SQL_FN_TD_NOW','%SQL_FN_TD_QUARTER','%SQL_FN_TD_SECOND',
+            '%SQL_FN_TD_TIMESTAMPADD','%SQL_FN_TD_TIMESTAMPDIFF','%SQL_FN_TD_WEEK','%SQL_FN_TD_YEAR','%SQL_FN_TSI_DAY','%SQL_FN_TSI_FRAC_SECOND','%SQL_FN_TSI_HOUR','%SQL_FN_TSI_MINUTE',
+            '%SQL_FN_TSI_MONTH','%SQL_FN_TSI_QUARTER','%SQL_FN_TSI_SECOND','%SQL_FN_TSI_WEEK','%SQL_FN_TSI_YEAR','%SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1','%SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2','%SQL_GB_COLLATE',
+            '%SQL_GB_GROUP_BY_CONTAINS_SELECT','%SQL_GB_GROUP_BY_EQUALS_SELECT','%SQL_GB_NOT_SUPPORTED','%SQL_GB_NO_RELATION','%SQL_GD_ANY_COLUMN','%SQL_GD_ANY_ORDER','%SQL_GD_BLOCK','%SQL_GD_BOUND',
+            '%SQL_GETDATA_EXTENSIONS','%SQL_GET_BOOKMARK','%SQL_GROUP_BY','%SQL_GUID','%SQL_HANDLE_DBC','%SQL_HANDLE_DESC','%SQL_HANDLE_ENV','%SQL_HANDLE_SENV',
+            '%SQL_HANDLE_STMT','%SQL_HOUR','%SQL_HOUR_TO_MINUTE','%SQL_HOUR_TO_SECOND','%SQL_IC_LOWER','%SQL_IC_MIXED','%SQL_IC_SENSITIVE','%SQL_IC_UPPER',
+            '%SQL_IDENTIFIER_CASE','%SQL_IDENTIFIER_QUOTE_CHAR','%SQL_IGNORE','%SQL_IK_ALL','%SQL_IK_ASC','%SQL_IK_DESC','%SQL_IK_NONE','%SQL_INDEX_ALL',
+            '%SQL_INDEX_CLUSTERED','%SQL_INDEX_HASHED','%SQL_INDEX_KEYWORDS','%SQL_INDEX_OTHER','%SQL_INDEX_UNIQUE','%SQL_INFO_FIRST','%SQL_INFO_SCHEMA_VIEWS','%SQL_INITIALLY_DEFERRED',
+            '%SQL_INITIALLY_IMMEDIATE','%SQL_INSENSITIVE','%SQL_INSERT_STATEMENT','%SQL_INTEGER','%SQL_INTEGRITY','%SQL_INTERVAL','%SQL_INTERVAL_DAY','%SQL_INTERVAL_DAY_TO_HOUR',
+            '%SQL_INTERVAL_DAY_TO_MINUTE','%SQL_INTERVAL_DAY_TO_SECOND','%SQL_INTERVAL_HOUR','%SQL_INTERVAL_HOUR_TO_MINUTE','%SQL_INTERVAL_HOUR_TO_SECOND','%SQL_INTERVAL_MINUTE','%SQL_INTERVAL_MINUTE_TO_SECOND','%SQL_INTERVAL_MONTH',
+            '%SQL_INTERVAL_SECOND','%SQL_INTERVAL_YEAR','%SQL_INTERVAL_YEAR_TO_MONTH','%SQL_INVALID_HANDLE','%SQL_ISV_ASSERTIONS','%SQL_ISV_CHARACTER_SETS','%SQL_ISV_CHECK_CONSTRAINTS','%SQL_ISV_COLLATIONS',
+            '%SQL_ISV_COLUMNS','%SQL_ISV_COLUMN_DOMAIN_USAGE','%SQL_ISV_COLUMN_PRIVILEGES','%SQL_ISV_CONSTRAINT_COLUMN_USAGE','%SQL_ISV_CONSTRAINT_TABLE_USAGE','%SQL_ISV_DOMAINS','%SQL_ISV_DOMAIN_CONSTRAINTS','%SQL_ISV_KEY_COLUMN_USAGE',
+            '%SQL_ISV_REFERENTIAL_CONSTRAINTS','%SQL_ISV_SCHEMATA','%SQL_ISV_SQL_LANGUAGES','%SQL_ISV_TABLES','%SQL_ISV_TABLE_CONSTRAINTS','%SQL_ISV_TABLE_PRIVILEGES','%SQL_ISV_TRANSLATIONS','%SQL_ISV_USAGE_PRIVILEGES',
+            '%SQL_ISV_VIEWS','%SQL_ISV_VIEW_COLUMN_USAGE','%SQL_ISV_VIEW_TABLE_USAGE','%SQL_IS_DAY','%SQL_IS_DAY_TO_HOUR','%SQL_IS_DAY_TO_MINUTE','%SQL_IS_DAY_TO_SECOND','%SQL_IS_HOUR',
+            '%SQL_IS_HOUR_TO_MINUTE','%SQL_IS_HOUR_TO_SECOND','%SQL_IS_INSERT_LITERALS','%SQL_IS_INSERT_SEARCHED','%SQL_IS_INTEGER','%SQL_IS_MINUTE','%SQL_IS_MINUTE_TO_SECOND','%SQL_IS_MONTH',
+            '%SQL_IS_POINTER','%SQL_IS_SECOND','%SQL_IS_SELECT_INTO','%SQL_IS_SMALLINT','%SQL_IS_UINTEGER','%SQL_IS_USMALLINT','%SQL_IS_YEAR','%SQL_IS_YEAR_TO_MONTH',
+            '%SQL_KEYSET_CURSOR_ATTRIBUTES1','%SQL_KEYSET_CURSOR_ATTRIBUTES2','%SQL_KEYSET_SIZE','%SQL_KEYSET_SIZE_DEFAULT','%SQL_KEYWORDS','%SQL_LCK_EXCLUSIVE','%SQL_LCK_NO_CHANGE','%SQL_LCK_UNLOCK',
+            '%SQL_LEN_BINARY_ATTR_OFFSET','%SQL_LEN_DATA_AT_EXEC_OFFSET','%SQL_LIKE_ESCAPE_CLAUSE','%SQL_LIKE_ONLY','%SQL_LOCK_EXCLUSIVE','%SQL_LOCK_NO_CHANGE','%SQL_LOCK_TYPES','%SQL_LOCK_UNLOCK',
+            '%SQL_LOGIN_TIMEOUT','%SQL_LOGIN_TIMEOUT_DEFAULT','%SQL_LONGVARBINARY','%SQL_LONGVARCHAR','%SQL_MAXIMUM_CATALOG_NAME_LENGTH','%SQL_MAXIMUM_COLUMNS_IN_GROUP_BY','%SQL_MAXIMUM_COLUMNS_IN_INDEX','%SQL_MAXIMUM_COLUMNS_IN_ORDER_BY',
+            '%SQL_MAXIMUM_COLUMNS_IN_SELECT','%SQL_MAXIMUM_COLUMN_NAME_LENGTH','%SQL_MAXIMUM_CONCURRENT_ACTIVITIES','%SQL_MAXIMUM_CURSOR_NAME_LENGTH','%SQL_MAXIMUM_DRIVER_CONNECTIONS','%SQL_MAXIMUM_IDENTIFIER_LENGTH','%SQL_MAXIMUM_INDEX_SIZE','%SQL_MAXIMUM_ROW_SIZE',
+            '%SQL_MAXIMUM_SCHEMA_NAME_LENGTH','%SQL_MAXIMUM_STATEMENT_LENGTH','%SQL_MAXIMUM_TABLES_IN_SELECT','%SQL_MAXIMUM_USER_NAME_LENGTH','%SQL_MAX_ASYNC_CONCURRENT_STATEMENTS','%SQL_MAX_BINARY_LITERAL_LEN','%SQL_MAX_CATALOG_NAME_LEN','%SQL_MAX_CHAR_LITERAL_LEN',
+            '%SQL_MAX_COLUMNS_IN_GROUP_BY','%SQL_MAX_COLUMNS_IN_INDEX','%SQL_MAX_COLUMNS_IN_ORDER_BY','%SQL_MAX_COLUMNS_IN_SELECT','%SQL_MAX_COLUMNS_IN_TABLE','%SQL_MAX_COLUMN_NAME_LEN','%SQL_MAX_CONCURRENT_ACTIVITIES','%SQL_MAX_CURSOR_NAME_LEN',
+            '%SQL_MAX_DRIVER_CONNECTIONS','%SQL_MAX_DSN_LENGTH','%SQL_MAX_IDENTIFIER_LEN','%SQL_MAX_INDEX_SIZE','%SQL_MAX_LENGTH','%SQL_MAX_LENGTH_DEFAULT','%SQL_MAX_MESSAGE_LENGTH','%SQL_MAX_NUMERIC_LEN',
+            '%SQL_MAX_OPTION_STRING_LENGTH','%SQL_MAX_OWNER_NAME_LEN','%SQL_MAX_PROCEDURE_NAME_LEN','%SQL_MAX_QUALIFIER_NAME_LEN','%SQL_MAX_ROWS','%SQL_MAX_ROWS_DEFAULT','%SQL_MAX_ROW_SIZE','%SQL_MAX_ROW_SIZE_INCLUDES_LONG',
+            '%SQL_MAX_SCHEMA_NAME_LEN','%SQL_MAX_STATEMENT_LEN','%SQL_MAX_TABLES_IN_SELECT','%SQL_MAX_TABLE_NAME_LEN','%SQL_MAX_USER_NAME_LEN','%SQL_MINUTE','%SQL_MINUTE_TO_SECOND','%SQL_MODE_DEFAULT',
+            '%SQL_MODE_READ_ONLY','%SQL_MODE_READ_WRITE','%SQL_MONTH','%SQL_MULTIPLE_ACTIVE_TXN','%SQL_MULT_RESULT_SETS','%SQL_NAMED','%SQL_NC_END','%SQL_NC_HIGH',
+            '%SQL_NC_LOW','%SQL_NC_START','%SQL_NEED_DATA','%SQL_NEED_LONG_DATA_LEN','%SQL_NNC_NON_NULL','%SQL_NNC_NULL','%SQL_NONSCROLLABLE','%SQL_NON_NULLABLE_COLUMNS',
+            '%SQL_NOSCAN','%SQL_NOSCAN_DEFAULT','%SQL_NOSCAN_OFF','%SQL_NOSCAN_ON','%SQL_NOT_DEFERRABLE','%SQL_NO_ACTION','%SQL_NO_COLUMN_NUMBER','%SQL_NO_DATA',
+            '%SQL_NO_DATA_FOUND','%SQL_NO_NULLS','%SQL_NO_ROW_NUMBER','%SQL_NO_TOTAL','%SQL_NTS','%SQL_NTSL','%SQL_NULLABLE','%SQL_NULLABLE_UNKNOWN',
+            '%SQL_NULL_COLLATION','%SQL_NULL_DATA','%SQL_NULL_HANDLE','%SQL_NULL_HDBC','%SQL_NULL_HDESC','%SQL_NULL_HENV','%SQL_NULL_HSTMT','%SQL_NUMERIC',
+            '%SQL_NUMERIC_FUNCTIONS','%SQL_OAC_LEVEL1','%SQL_OAC_LEVEL2','%SQL_OAC_NONE','%SQL_ODBC_API_CONFORMANCE','%SQL_ODBC_CURSORS','%SQL_ODBC_INTERFACE_CONFORMANCE','%SQL_ODBC_SAG_CLI_CONFORMANCE',
+            '%SQL_ODBC_SQL_CONFORMANCE','%SQL_ODBC_SQL_OPT_IEF','%SQL_ODBC_VER','%SQL_OIC_CORE','%SQL_OIC_LEVEL1','%SQL_OIC_LEVEL2','%SQL_OJ_ALL_COMPARISON_OPS','%SQL_OJ_CAPABILITIES',
+            '%SQL_OJ_FULL','%SQL_OJ_INNER','%SQL_OJ_LEFT','%SQL_OJ_NESTED','%SQL_OJ_NOT_ORDERED','%SQL_OJ_RIGHT','%SQL_OPT_TRACE','%SQL_OPT_TRACEFILE',
+            '%SQL_OPT_TRACE_DEFAULT','%SQL_OPT_TRACE_OFF','%SQL_OPT_TRACE_ON','%SQL_ORDER_BY_COLUMNS_IN_SELECT','%SQL_OSCC_COMPLIANT','%SQL_OSCC_NOT_COMPLIANT','%SQL_OSC_CORE','%SQL_OSC_EXTENDED',
+            '%SQL_OSC_MINIMUM','%SQL_OUTER_JOINS','%SQL_OUTER_JOIN_CAPABILITIES','%SQL_OU_DML_STATEMENTS','%SQL_OU_INDEX_DEFINITION','%SQL_OU_PRIVILEGE_DEFINITION','%SQL_OU_PROCEDURE_INVOCATION','%SQL_OU_TABLE_DEFINITION',
+            '%SQL_OV_ODBC2','%SQL_OV_ODBC3','%SQL_OWNER_TERM','%SQL_OWNER_USAGE','%SQL_PACKET_SIZE','%SQL_PARAM_ARRAY_ROW_COUNTS','%SQL_PARAM_ARRAY_SELECTS','%SQL_PARAM_BIND_BY_COLUMN',
+            '%SQL_PARAM_BIND_TYPE_DEFAULT','%SQL_PARAM_DIAG_UNAVAILABLE','%SQL_PARAM_ERROR','%SQL_PARAM_IGNORE','%SQL_PARAM_INPUT','%SQL_PARAM_INPUT_OUTPUT','%SQL_PARAM_OUTPUT','%SQL_PARAM_PROCEED',
+            '%SQL_PARAM_SUCCESS','%SQL_PARAM_SUCCESS_WITH_INFO','%SQL_PARAM_TYPE_DEFAULT','%SQL_PARAM_TYPE_UNKNOWN','%SQL_PARAM_UNUSED','%SQL_PARC_BATCH','%SQL_PARC_NO_BATCH','%SQL_PAS_BATCH',
+            '%SQL_PAS_NO_BATCH','%SQL_PAS_NO_SELECT','%SQL_PC_NON_PSEUDO','%SQL_PC_NOT_PSEUDO','%SQL_PC_PSEUDO','%SQL_PC_UNKNOWN','%SQL_POSITION','%SQL_POSITIONED_STATEMENTS',
+            '%SQL_POS_ADD','%SQL_POS_DELETE','%SQL_POS_OPERATIONS','%SQL_POS_POSITION','%SQL_POS_REFRESH','%SQL_POS_UPDATE','%SQL_PRED_BASIC','%SQL_PRED_CHAR',
+            '%SQL_PRED_NONE','%SQL_PRED_SEARCHABLE','%SQL_PROCEDURES','%SQL_PROCEDURE_TERM','%SQL_PS_POSITIONED_DELETE','%SQL_PS_POSITIONED_UPDATE','%SQL_PS_SELECT_FOR_UPDATE','%SQL_PT_FUNCTION',
+            '%SQL_PT_PROCEDURE','%SQL_PT_UNKNOWN','%SQL_QL_END','%SQL_QL_START','%SQL_QUALIFIER_LOCATION','%SQL_QUALIFIER_NAME_SEPARATOR','%SQL_QUALIFIER_TERM','%SQL_QUALIFIER_USAGE',
+            '%SQL_QUERY_TIMEOUT','%SQL_QUERY_TIMEOUT_DEFAULT','%SQL_QUICK','%SQL_QUIET_MODE','%SQL_QUOTED_IDENTIFIER_CASE','%SQL_QU_DML_STATEMENTS','%SQL_QU_INDEX_DEFINITION','%SQL_QU_PRIVILEGE_DEFINITION',
+            '%SQL_QU_PROCEDURE_INVOCATION','%SQL_QU_TABLE_DEFINITION','%SQL_RD_DEFAULT','%SQL_RD_OFF','%SQL_RD_ON','%SQL_REAL','%SQL_REFRESH','%SQL_RESET_PARAMS',
+            '%SQL_RESTRICT','%SQL_RESULT_COL','%SQL_RETRIEVE_DATA','%SQL_RETURN_VALUE','%SQL_ROLLBACK','%SQL_ROWSET_SIZE','%SQL_ROWSET_SIZE_DEFAULT','%SQL_ROWVER',
+            '%SQL_ROW_ADDED','%SQL_ROW_DELETED','%SQL_ROW_ERROR','%SQL_ROW_IDENTIFIER','%SQL_ROW_IGNORE','%SQL_ROW_NOROW','%SQL_ROW_NUMBER','%SQL_ROW_NUMBER_UNKNOWN',
+            '%SQL_ROW_PROCEED','%SQL_ROW_SUCCESS','%SQL_ROW_SUCCESS_WITH_INFO','%SQL_ROW_UPDATED','%SQL_ROW_UPDATES','%SQL_SCCO_LOCK','%SQL_SCCO_OPT_ROWVER','%SQL_SCCO_OPT_TIMESTAMP',
+            '%SQL_SCCO_OPT_VALUES','%SQL_SCCO_READ_ONLY','%SQL_SCC_ISO92_CLI','%SQL_SCC_XOPEN_CLI_VERSION1','%SQL_SCHEMA_TERM','%SQL_SCHEMA_USAGE','%SQL_SCOPE_CURROW','%SQL_SCOPE_SESSION',
+            '%SQL_SCOPE_TRANSACTION','%SQL_SCROLLABLE','%SQL_SCROLL_CONCURRENCY','%SQL_SCROLL_DYNAMIC','%SQL_SCROLL_FORWARD_ONLY','%SQL_SCROLL_KEYSET_DRIVEN','%SQL_SCROLL_OPTIONS','%SQL_SCROLL_STATIC',
+            '%SQL_SC_FIPS127_2_TRANSITIONAL','%SQL_SC_NON_UNIQUE','%SQL_SC_SQL92_ENTRY','%SQL_SC_SQL92_FULL','%SQL_SC_SQL92_INTERMEDIATE','%SQL_SC_TRY_UNIQUE','%SQL_SC_UNIQUE','%SQL_SDF_CURRENT_DATE',
+            '%SQL_SDF_CURRENT_TIME','%SQL_SDF_CURRENT_TIMESTAMP','%SQL_SEARCHABLE','%SQL_SEARCH_PATTERN_ESCAPE','%SQL_SECOND','%SQL_SENSITIVE','%SQL_SERVER_NAME','%SQL_SETPARAM_VALUE_MAX',
+            '%SQL_SETPOS_MAX_LOCK_VALUE','%SQL_SETPOS_MAX_OPTION_VALUE','%SQL_SET_DEFAULT','%SQL_SET_NULL','%SQL_SFKD_CASCADE','%SQL_SFKD_NO_ACTION','%SQL_SFKD_SET_DEFAULT','%SQL_SFKD_SET_NULL',
+            '%SQL_SFKU_CASCADE','%SQL_SFKU_NO_ACTION','%SQL_SFKU_SET_DEFAULT','%SQL_SFKU_SET_NULL','%SQL_SG_DELETE_TABLE','%SQL_SG_INSERT_COLUMN','%SQL_SG_INSERT_TABLE','%SQL_SG_REFERENCES_COLUMN',
+            '%SQL_SG_REFERENCES_TABLE','%SQL_SG_SELECT_TABLE','%SQL_SG_UPDATE_COLUMN','%SQL_SG_UPDATE_TABLE','%SQL_SG_USAGE_ON_CHARACTER_SET','%SQL_SG_USAGE_ON_COLLATION','%SQL_SG_USAGE_ON_DOMAIN','%SQL_SG_USAGE_ON_TRANSLATION',
+            '%SQL_SG_WITH_GRANT_OPTION','%SQL_SIGNED_OFFSET','%SQL_SIMULATE_CURSOR','%SQL_SMALLINT','%SQL_SNVF_BIT_LENGTH','%SQL_SNVF_CHARACTER_LENGTH','%SQL_SNVF_CHAR_LENGTH','%SQL_SNVF_EXTRACT',
+            '%SQL_SNVF_OCTET_LENGTH','%SQL_SNVF_POSITION','%SQL_SO_DYNAMIC','%SQL_SO_FORWARD_ONLY','%SQL_SO_KEYSET_DRIVEN','%SQL_SO_MIXED','%SQL_SO_STATIC','%SQL_SPECIAL_CHARACTERS',
+            '%SQL_SPEC_MAJOR','%SQL_SPEC_MINOR','%SQL_SP_BETWEEN','%SQL_SP_COMPARISON','%SQL_SP_EXISTS','%SQL_SP_IN','%SQL_SP_ISNOTNULL','%SQL_SP_ISNULL',
+            '%SQL_SP_LIKE','%SQL_SP_MATCH_FULL','%SQL_SP_MATCH_PARTIAL','%SQL_SP_MATCH_UNIQUE_FULL','%SQL_SP_MATCH_UNIQUE_PARTIAL','%SQL_SP_OVERLAPS','%SQL_SP_QUANTIFIED_COMPARISON','%SQL_SP_UNIQUE',
+            '%SQL_SQL92_DATETIME_FUNCTIONS','%SQL_SQL92_FOREIGN_KEY_DELETE_RULE','%SQL_SQL92_FOREIGN_KEY_UPDATE_RULE','%SQL_SQL92_GRANT','%SQL_SQL92_NUMERIC_VALUE_FUNCTIONS','%SQL_SQL92_PREDICATES','%SQL_SQL92_RELATIONAL_JOIN_OPERATORS','%SQL_SQL92_REVOKE',
+            '%SQL_SQL92_ROW_VALUE_CONSTRUCTOR','%SQL_SQL92_STRING_FUNCTIONS','%SQL_SQL92_VALUE_EXPRESSIONS','%SQL_SQLSTATE_SIZE','%SQL_SQL_CONFORMANCE','%SQL_SQ_COMPARISON','%SQL_SQ_CORRELATED_SUBQUERIES','%SQL_SQ_EXISTS',
+            '%SQL_SQ_IN','%SQL_SQ_QUANTIFIED','%SQL_SRJO_CORRESPONDING_CLAUSE','%SQL_SRJO_CROSS_JOIN','%SQL_SRJO_EXCEPT_JOIN','%SQL_SRJO_FULL_OUTER_JOIN','%SQL_SRJO_INNER_JOIN','%SQL_SRJO_INTERSECT_JOIN',
+            '%SQL_SRJO_LEFT_OUTER_JOIN','%SQL_SRJO_NATURAL_JOIN','%SQL_SRJO_RIGHT_OUTER_JOIN','%SQL_SRJO_UNION_JOIN','%SQL_SRVC_DEFAULT','%SQL_SRVC_NULL','%SQL_SRVC_ROW_SUBQUERY','%SQL_SRVC_VALUE_EXPRESSION',
+            '%SQL_SR_CASCADE','%SQL_SR_DELETE_TABLE','%SQL_SR_GRANT_OPTION_FOR','%SQL_SR_INSERT_COLUMN','%SQL_SR_INSERT_TABLE','%SQL_SR_REFERENCES_COLUMN','%SQL_SR_REFERENCES_TABLE','%SQL_SR_RESTRICT',
+            '%SQL_SR_SELECT_TABLE','%SQL_SR_UPDATE_COLUMN','%SQL_SR_UPDATE_TABLE','%SQL_SR_USAGE_ON_CHARACTER_SET','%SQL_SR_USAGE_ON_COLLATION','%SQL_SR_USAGE_ON_DOMAIN','%SQL_SR_USAGE_ON_TRANSLATION','%SQL_SSF_CONVERT',
+            '%SQL_SSF_LOWER','%SQL_SSF_SUBSTRING','%SQL_SSF_TRANSLATE','%SQL_SSF_TRIM_BOTH','%SQL_SSF_TRIM_LEADING','%SQL_SSF_TRIM_TRAILING','%SQL_SSF_UPPER','%SQL_SS_ADDITIONS',
+            '%SQL_SS_DELETIONS','%SQL_SS_UPDATES','%SQL_STANDARD_CLI_CONFORMANCE','%SQL_STATIC_CURSOR_ATTRIBUTES1','%SQL_STATIC_CURSOR_ATTRIBUTES2','%SQL_STATIC_SENSITIVITY','%SQL_STILL_EXECUTING','%SQL_STRING_FUNCTIONS',
+            '%SQL_SUBQUERIES','%SQL_SUCCESS','%SQL_SUCCESS_WITH_INFO','%SQL_SU_DML_STATEMENTS','%SQL_SU_INDEX_DEFINITION','%SQL_SU_PRIVILEGE_DEFINITION','%SQL_SU_PROCEDURE_INVOCATION','%SQL_SU_TABLE_DEFINITION',
+            '%SQL_SVE_CASE','%SQL_SVE_CAST','%SQL_SVE_COALESCE','%SQL_SVE_NULLIF','%SQL_SYSTEM_FUNCTIONS','%SQL_TABLE_STAT','%SQL_TABLE_TERM','%SQL_TC_ALL',
+            '%SQL_TC_DDL_COMMIT','%SQL_TC_DDL_IGNORE','%SQL_TC_DML','%SQL_TC_NONE','%SQL_TIME','%SQL_TIMEDATE_ADD_INTERVALS','%SQL_TIMEDATE_DIFF_INTERVALS','%SQL_TIMEDATE_FUNCTIONS',
+            '%SQL_TIMESTAMP','%SQL_TIMESTAMP_LEN','%SQL_TIME_LEN','%SQL_TINYINT','%SQL_TRANSACTION_CAPABLE','%SQL_TRANSACTION_ISOLATION_OPTION','%SQL_TRANSACTION_READ_COMMITTED','%SQL_TRANSACTION_READ_UNCOMMITTED',
+            '%SQL_TRANSACTION_REPEATABLE_READ','%SQL_TRANSACTION_SERIALIZABLE','%SQL_TRANSLATE_DLL','%SQL_TRANSLATE_OPTION','%SQL_TRUE','%SQL_TXN_CAPABLE','%SQL_TXN_ISOLATION','%SQL_TXN_ISOLATION_OPTION',
+            '%SQL_TXN_READ_COMMITTED','%SQL_TXN_READ_UNCOMMITTED','%SQL_TXN_REPEATABLE_READ','%SQL_TXN_SERIALIZABLE','%SQL_TYPE_DATE','%SQL_TYPE_NULL','%SQL_TYPE_TIME','%SQL_TYPE_TIMESTAMP',
+            '%SQL_UB_DEFAULT','%SQL_UB_FIXED','%SQL_UB_OFF','%SQL_UB_ON','%SQL_UB_VARIABLE','%SQL_UNBIND','%SQL_UNICODE','%SQL_UNICODE_CHAR',
+            '%SQL_UNICODE_LONGVARCHAR','%SQL_UNICODE_VARCHAR','%SQL_UNION','%SQL_UNION_STATEMENT','%SQL_UNKNOWN_TYPE','%SQL_UNNAMED','%SQL_UNSEARCHABLE','%SQL_UNSIGNED_OFFSET',
+            '%SQL_UNSPECIFIED','%SQL_UPDATE','%SQL_UPDATE_BY_BOOKMARK','%SQL_USER_NAME','%SQL_USE_BOOKMARKS','%SQL_US_UNION','%SQL_US_UNION_ALL','%SQL_U_UNION',
+            '%SQL_U_UNION_ALL','%SQL_VARBINARY','%SQL_VARCHAR','%SQL_XOPEN_CLI_YEAR','%SQL_YEAR','%SQL_YEAR_TO_MONTH','%SRCCOPY','%SS_BITMAP',
+            '%SS_BLACKFRAME','%SS_BLACKRECT','%SS_CENTER','%SS_CENTERIMAGE','%SS_ENDELLIPSIS','%SS_ETCHEDFRAME','%SS_ETCHEDHORZ','%SS_ETCHEDVERT',
+            '%SS_GRAYFRAME','%SS_GRAYRECT','%SS_LEFT','%SS_NOPREFIX','%SS_NOTIFY','%SS_NOWORDWRAP','%SS_PATHELLIPSIS','%SS_RIGHT',
+            '%SS_RIGHTJUST','%SS_SIMPLE','%SS_SUNKEN','%SS_WHITEFRAME','%SS_WHITERECT','%SS_WORDELLIPSIS','%STAT_FILL_FROM_MEMORY','%STAT_FILL_NATURAL',
+            '%STAT_FILL_NATURAL_ERASTONE','%STAT_FILL_NATURAL_EVEN','%STAT_FILL_NATURAL_FIBONACCI','%STAT_FILL_NATURAL_ODD','%STAT_FILL_WITH_NUMBER','%STAT_MINMAX_INDEX','%STAT_MINMAX_VALUE','%STAT_TYPE_BYTE',
+            '%STAT_TYPE_CURRENCY','%STAT_TYPE_DOUBLE','%STAT_TYPE_DWORD','%STAT_TYPE_EXT','%STAT_TYPE_INTEGER','%STAT_TYPE_LONG','%STAT_TYPE_QUAD','%STAT_TYPE_SINGLE',
+            '%STAT_TYPE_WORD','%SWP_ASYNCWINDOWPOS','%SWP_DEFERERASE','%SWP_DRAWFRAME','%SWP_FRAMECHANGED','%SWP_HIDEWINDOW','%SWP_NOACTIVATE','%SWP_NOCOPYBITS',
+            '%SWP_NOMOVE','%SWP_NOOWNERZORDER','%SWP_NOREDRAW','%SWP_NOREPOSITION','%SWP_NOSENDCHANGING','%SWP_NOSIZE','%SWP_NOZORDER','%SWP_SHOWWINDOW',
+            '%SW_FORCEMINIMIZE','%SW_HIDE','%SW_MAXIMIZE','%SW_MINIMIZE','%SW_NORMAL','%SW_RESTORE','%SW_SHOW','%SW_SHOWDEFAULT',
+            '%SW_SHOWMAXIMIZED','%SW_SHOWMINIMIZED','%SW_SHOWMINNOACTIVE','%SW_SHOWNA','%SW_SHOWNOACTIVATE','%SW_SHOWNORMAL','%TBASS_3DALG_DEFAULT','%TBASS_3DALG_FULL',
+            '%TBASS_3DALG_LIGHT','%TBASS_3DALG_OFF','%TBASS_3DMODE_NORMAL','%TBASS_3DMODE_OFF','%TBASS_3DMODE_RELATIVE','%TBASS_ACTIVE_PAUSED','%TBASS_ACTIVE_PLAYING','%TBASS_ACTIVE_STALLED',
+            '%TBASS_ACTIVE_STOPPED','%TBASS_CONFIG_3DALGORITHM','%TBASS_CONFIG_BUFFER','%TBASS_CONFIG_CURVE_PAN','%TBASS_CONFIG_CURVE_VOL','%TBASS_CONFIG_FLOATDSP','%TBASS_CONFIG_GVOL_MUSIC','%TBASS_CONFIG_GVOL_SAMPLE',
+            '%TBASS_CONFIG_GVOL_STREAM','%TBASS_CONFIG_MAXVOL','%TBASS_CONFIG_MP3_CODEC','%TBASS_CONFIG_NET_AGENT','%TBASS_CONFIG_NET_BUFFER','%TBASS_CONFIG_NET_PASSIVE','%TBASS_CONFIG_NET_PREBUF','%TBASS_CONFIG_NET_PROXY',
+            '%TBASS_CONFIG_NET_TIMEOUT','%TBASS_CONFIG_PAUSE_NOPLAY','%TBASS_CONFIG_UPDATEPERIOD','%TBASS_CTYPE_MUSIC_IT','%TBASS_CTYPE_MUSIC_MO3','%TBASS_CTYPE_MUSIC_MOD','%TBASS_CTYPE_MUSIC_MTM','%TBASS_CTYPE_MUSIC_S3M',
+            '%TBASS_CTYPE_MUSIC_XM','%TBASS_CTYPE_RECORD','%TBASS_CTYPE_SAMPLE','%TBASS_CTYPE_STREAM','%TBASS_CTYPE_STREAM_AIFF','%TBASS_CTYPE_STREAM_MP1','%TBASS_CTYPE_STREAM_MP2','%TBASS_CTYPE_STREAM_MP3',
+            '%TBASS_CTYPE_STREAM_OGG','%TBASS_CTYPE_STREAM_WAV','%TBASS_CTYPE_STREAM_WAV_FLOAT','%TBASS_CTYPE_STREAM_WAV_PCM','%TBASS_DATA_AVAILABLE','%TBASS_DATA_FFT1024','%TBASS_DATA_FFT2048','%TBASS_DATA_FFT4096',
+            '%TBASS_DATA_FFT512','%TBASS_DATA_FFT_INDIVIDUAL','%TBASS_DATA_FFT_NOWINDOW','%TBASS_DATA_FLOAT','%TBASS_DEVICE_3D','%TBASS_DEVICE_8BITS','%TBASS_DEVICE_LATENCY','%TBASS_DEVICE_MONO',
+            '%TBASS_DEVICE_NOSPEAKER','%TBASS_DEVICE_SPEAKERS','%TBASS_EAX_ENVIRONMENT_ALLEY','%TBASS_EAX_ENVIRONMENT_ARENA','%TBASS_EAX_ENVIRONMENT_AUDITORIUM','%TBASS_EAX_ENVIRONMENT_BATHROOM','%TBASS_EAX_ENVIRONMENT_CARPETEDHALLWAY','%TBASS_EAX_ENVIRONMENT_CAVE',
+            '%TBASS_EAX_ENVIRONMENT_CITY','%TBASS_EAX_ENVIRONMENT_CONCERTHALL','%TBASS_EAX_ENVIRONMENT_COUNT','%TBASS_EAX_ENVIRONMENT_DIZZY','%TBASS_EAX_ENVIRONMENT_DRUGGED','%TBASS_EAX_ENVIRONMENT_FOREST','%TBASS_EAX_ENVIRONMENT_GENERIC','%TBASS_EAX_ENVIRONMENT_HALLWAY',
+            '%TBASS_EAX_ENVIRONMENT_HANGAR','%TBASS_EAX_ENVIRONMENT_LIVINGROOM','%TBASS_EAX_ENVIRONMENT_MOUNTAINS','%TBASS_EAX_ENVIRONMENT_PADDEDCELL','%TBASS_EAX_ENVIRONMENT_PARKINGLOT','%TBASS_EAX_ENVIRONMENT_PLAIN','%TBASS_EAX_ENVIRONMENT_PSYCHOTIC','%TBASS_EAX_ENVIRONMENT_QUARRY',
+            '%TBASS_EAX_ENVIRONMENT_ROOM','%TBASS_EAX_ENVIRONMENT_SEWERPIPE','%TBASS_EAX_ENVIRONMENT_STONECORRIDOR','%TBASS_EAX_ENVIRONMENT_STONEROOM','%TBASS_EAX_ENVIRONMENT_UNDERWATER','%TBASS_ERROR_ALREADY','%TBASS_ERROR_BUFLOST','%TBASS_ERROR_CODEC',
+            '%TBASS_ERROR_CREATE','%TBASS_ERROR_DECODE','%TBASS_ERROR_DEVICE','%TBASS_ERROR_DRIVER','%TBASS_ERROR_DX','%TBASS_ERROR_EMPTY','%TBASS_ERROR_FILEFORM','%TBASS_ERROR_FILEOPEN',
+            '%TBASS_ERROR_FORMAT','%TBASS_ERROR_FREQ','%TBASS_ERROR_HANDLE','%TBASS_ERROR_ILLPARAM','%TBASS_ERROR_ILLTYPE','%TBASS_ERROR_INIT','%TBASS_ERROR_MEM','%TBASS_ERROR_NO3D',
+            '%TBASS_ERROR_NOCHAN','%TBASS_ERROR_NOEAX','%TBASS_ERROR_NOFX','%TBASS_ERROR_NOHW','%TBASS_ERROR_NONET','%TBASS_ERROR_NOPAUSE','%TBASS_ERROR_NOPLAY','%TBASS_ERROR_NOTAVAIL',
+            '%TBASS_ERROR_NOTFILE','%TBASS_ERROR_PLAYING','%TBASS_ERROR_POSITION','%TBASS_ERROR_SPEAKER','%TBASS_ERROR_START','%TBASS_ERROR_TIMEOUT','%TBASS_ERROR_UNKNOWN','%TBASS_ERROR_VERSION',
+            '%TBASS_FALSE','%TBASS_FILEPOS_CURRENT','%TBASS_FILEPOS_DECODE','%TBASS_FILEPOS_DOWNLOAD','%TBASS_FILEPOS_END','%TBASS_FILEPOS_START','%TBASS_FILE_CLOSE','%TBASS_FILE_LEN',
+            '%TBASS_FILE_READ','%TBASS_FILE_SEEK','%TBASS_FX_CHORUS','%TBASS_FX_COMPRESSOR','%TBASS_FX_DISTORTION','%TBASS_FX_ECHO','%TBASS_FX_FLANGER','%TBASS_FX_GARGLE',
+            '%TBASS_FX_I3DL2REVERB','%TBASS_FX_PARAMEQ','%TBASS_FX_PHASE_180','%TBASS_FX_PHASE_90','%TBASS_FX_PHASE_NEG_180','%TBASS_FX_PHASE_NEG_90','%TBASS_FX_PHASE_ZERO','%TBASS_FX_REVERB',
+            '%TBASS_INPUT_LEVEL','%TBASS_INPUT_OFF','%TBASS_INPUT_ON','%TBASS_INPUT_TYPE_ANALOG','%TBASS_INPUT_TYPE_AUX','%TBASS_INPUT_TYPE_CD','%TBASS_INPUT_TYPE_DIGITAL','%TBASS_INPUT_TYPE_LINE',
+            '%TBASS_INPUT_TYPE_MASK','%TBASS_INPUT_TYPE_MIC','%TBASS_INPUT_TYPE_PHONE','%TBASS_INPUT_TYPE_SPEAKER','%TBASS_INPUT_TYPE_SYNTH','%TBASS_INPUT_TYPE_UNDEF','%TBASS_INPUT_TYPE_WAVE','%TBASS_MP3_SETPOS',
+            '%TBASS_MUSIC_3D','%TBASS_MUSIC_ATTRIB_AMPLIFY','%TBASS_MUSIC_ATTRIB_BPM','%TBASS_MUSIC_ATTRIB_PANSEP','%TBASS_MUSIC_ATTRIB_PSCALER','%TBASS_MUSIC_ATTRIB_SPEED','%TBASS_MUSIC_ATTRIB_VOL_CHAN','%TBASS_MUSIC_ATTRIB_VOL_GLOBAL',
+            '%TBASS_MUSIC_ATTRIB_VOL_INST','%TBASS_MUSIC_AUTOFREE','%TBASS_MUSIC_CALCLEN','%TBASS_MUSIC_DECODE','%TBASS_MUSIC_FLOAT','%TBASS_MUSIC_FT2MOD','%TBASS_MUSIC_FX','%TBASS_MUSIC_LOOP',
+            '%TBASS_MUSIC_MONO','%TBASS_MUSIC_NONINTER','%TBASS_MUSIC_NOSAMPLE','%TBASS_MUSIC_POSRESET','%TBASS_MUSIC_POSRESETEX','%TBASS_MUSIC_PRESCAN','%TBASS_MUSIC_PT1MOD','%TBASS_MUSIC_RAMP',
+            '%TBASS_MUSIC_RAMPS','%TBASS_MUSIC_STOPBACK','%TBASS_MUSIC_SURROUND','%TBASS_MUSIC_SURROUND2','%TBASS_OBJECT_DS','%TBASS_OBJECT_DS3DL','%TBASS_OK','%TBASS_RECORD_PAUSE',
+            '%TBASS_SAMPLE_3D','%TBASS_SAMPLE_8BITS','%TBASS_SAMPLE_FLOAT','%TBASS_SAMPLE_FX','%TBASS_SAMPLE_LOOP','%TBASS_SAMPLE_MONO','%TBASS_SAMPLE_MUTEMAX','%TBASS_SAMPLE_OVER_DIST',
+            '%TBASS_SAMPLE_OVER_POS','%TBASS_SAMPLE_OVER_VOL','%TBASS_SAMPLE_SOFTWARE','%TBASS_SAMPLE_VAM','%TBASS_SLIDE_FREQ','%TBASS_SLIDE_PAN','%TBASS_SLIDE_VOL','%TBASS_SPEAKER_CENLFE',
+            '%TBASS_SPEAKER_CENTER','%TBASS_SPEAKER_FRONT','%TBASS_SPEAKER_FRONTLEFT','%TBASS_SPEAKER_FRONTRIGHT','%TBASS_SPEAKER_LEFT','%TBASS_SPEAKER_LFE','%TBASS_SPEAKER_REAR','%TBASS_SPEAKER_REAR2',
+            '%TBASS_SPEAKER_REAR2LEFT','%TBASS_SPEAKER_REAR2RIGHT','%TBASS_SPEAKER_REARLEFT','%TBASS_SPEAKER_REARRIGHT','%TBASS_SPEAKER_RIGHT','%TBASS_STREAMPROC_END','%TBASS_STREAM_AUTOFREE','%TBASS_STREAM_BLOCK',
+            '%TBASS_STREAM_DECODE','%TBASS_STREAM_PRESCAN','%TBASS_STREAM_RESTRATE','%TBASS_STREAM_STATUS','%TBASS_SYNC_DOWNLOAD','%TBASS_SYNC_END','%TBASS_SYNC_FREE','%TBASS_SYNC_MESSAGE',
+            '%TBASS_SYNC_META','%TBASS_SYNC_MIXTIME','%TBASS_SYNC_MUSICFX','%TBASS_SYNC_MUSICINST','%TBASS_SYNC_MUSICPOS','%TBASS_SYNC_ONETIME','%TBASS_SYNC_POS','%TBASS_SYNC_SLIDE',
+            '%TBASS_SYNC_STALL','%TBASS_TAG_HTTP','%TBASS_TAG_ICY','%TBASS_TAG_ID3','%TBASS_TAG_ID3V2','%TBASS_TAG_META','%TBASS_TAG_MUSIC_INST','%TBASS_TAG_MUSIC_MESSAGE',
+            '%TBASS_TAG_MUSIC_NAME','%TBASS_TAG_MUSIC_SAMPLE','%TBASS_TAG_OGG','%TBASS_TAG_RIFF_INFO','%TBASS_TAG_VENDOR','%TBASS_TRUE','%TBASS_UNICODE','%TBASS_VAM_HARDWARE',
+            '%TBASS_VAM_SOFTWARE','%TBASS_VAM_TERM_DIST','%TBASS_VAM_TERM_PRIO','%TBASS_VAM_TERM_TIME','%TBASS_VERSION','%TBCD_CHANNEL','%TBCD_THUMB','%TBCD_TICS',
+            '%TBGL_ALIGN_CENTER','%TBGL_ALIGN_CENTER_CENTER','%TBGL_ALIGN_CENTER_DOWN','%TBGL_ALIGN_CENTER_UP','%TBGL_ALIGN_LEFT','%TBGL_ALIGN_LEFT_CENTER','%TBGL_ALIGN_LEFT_DOWN','%TBGL_ALIGN_LEFT_UP',
+            '%TBGL_ALIGN_RIGHT','%TBGL_ALIGN_RIGHT_CENTER','%TBGL_ALIGN_RIGHT_DOWN','%TBGL_ALIGN_RIGHT_UP','%TBGL_ALWAYS','%TBGL_EQUAL','%TBGL_ERROR_FILE','%TBGL_ERROR_MSGBOX',
+            '%TBGL_ERROR_NONE','%TBGL_GEQUAL','%TBGL_GREATER','%TBGL_LEQUAL','%TBGL_LESS','%TBGL_LIGHT_AMBIENT','%TBGL_LIGHT_CONSTANT_ATTENUATION','%TBGL_LIGHT_DIFFUSE',
+            '%TBGL_LIGHT_LINEAR_ATTENUATION','%TBGL_LIGHT_POSITION','%TBGL_LIGHT_QUADRATIC_ATTENUATION','%TBGL_LIGHT_SPECULAR','%TBGL_LIGHT_SPOT_CUTOFF','%TBGL_LIGHT_SPOT_DIRECTION','%TBGL_LIGHT_SPOT_EXPONENT','%TBGL_M15B',
+            '%TBGL_M15G','%TBGL_M15LAYER','%TBGL_M15PSTOP','%TBGL_M15R','%TBGL_M15TEXN','%TBGL_M15TEXX','%TBGL_M15TEXY','%TBGL_M15X',
+            '%TBGL_M15Y','%TBGL_M15Z','%TBGL_NEVER','%TBGL_NORMAL_NONE','%TBGL_NORMAL_PRECISE','%TBGL_NORMAL_SMOOTH','%TBGL_NOTEQUAL','%TBGL_OBJ_CUBE',
+            '%TBGL_OBJ_CUBE3','%TBGL_OBJ_CYLINDER','%TBGL_OBJ_SPHERE','%TBGL_PINFO_RGB','%TBGL_PINFO_XYZ','%TBGL_TEX_LINEAR','%TBGL_TEX_MIPMAP','%TBGL_TEX_NEAREST',
+            '%TBM_CLEARSEL','%TBM_CLEARTICS','%TBM_GETBUDDY','%TBM_GETCHANNELRECT','%TBM_GETLINESIZE','%TBM_GETNUMTICS','%TBM_GETPAGESIZE','%TBM_GETPOS',
+            '%TBM_GETPTICS','%TBM_GETRANGEMAX','%TBM_GETRANGEMIN','%TBM_GETSELEND','%TBM_GETSELSTART','%TBM_GETTHUMBLENGTH','%TBM_GETTHUMBRECT','%TBM_GETTIC',
+            '%TBM_GETTICPOS','%TBM_GETTOOLTIPS','%TBM_GETUNICODEFORMAT','%TBM_SETBUDDY','%TBM_SETLINESIZE','%TBM_SETPAGESIZE','%TBM_SETPOS','%TBM_SETRANGE',
+            '%TBM_SETRANGEMAX','%TBM_SETRANGEMIN','%TBM_SETSEL','%TBM_SETSELEND','%TBM_SETSELSTART','%TBM_SETTHUMBLENGTH','%TBM_SETTIC','%TBM_SETTICFREQ',
+            '%TBM_SETTIPSIDE','%TBM_SETTOOLTIPS','%TBM_SETUNICODEFORMAT','%TBS_AUTOTICKS','%TBS_BOTH','%TBS_BOTTOM','%TBS_DOWNISLEFT','%TBS_ENABLESELRANGE',
+            '%TBS_FIXEDLENGTH','%TBS_HORZ','%TBS_LEFT','%TBS_NOTHUMB','%TBS_NOTICKS','%TBS_REVERSED','%TBS_RIGHT','%TBS_TOOLTIPS',
+            '%TBS_TOP','%TBS_VERT','%TBTS_BOTTOM','%TBTS_LEFT','%TBTS_RIGHT','%TBTS_TOP','%TB_%VT_BSTR','%TB_%VT_CY',
+            '%TB_%VT_DATE','%TB_%VT_EMPTY','%TB_%VT_I2','%TB_%VT_I4','%TB_%VT_NULL','%TB_%VT_R4','%TB_%VT_R8','%TB_BOTTOM',
+            '%TB_CLASS_E_NOAGGREGATION','%TB_CO_E_CLASSSTRING','%TB_DISPATCH_METHOD','%TB_DISPATCH_PROPERTYGET','%TB_DISPATCH_PROPERTYPUT','%TB_DISPATCH_PROPERTYPUTREF','%TB_ENDTRACK','%TB_E_INVALIDARG',
+            '%TB_E_NOINTERFACE','%TB_E_OUTOFMEMORY','%TB_IMGCTX_ACTUALSIZE','%TB_IMGCTX_AUTOSIZE','%TB_IMGCTX_FITTOHEIGHT','%TB_IMGCTX_FITTOWIDTH','%TB_IMGCTX_STRETCH','%TB_LINEDOWN',
+            '%TB_LINEUP','%TB_MK_E_CONNECTMANUALLY','%TB_MK_E_EXCEEDEDDEADLINE','%TB_MK_E_INTERMEDIATEINTERFACENOTSUPPORTED','%TB_MK_E_NOOBJECT','%TB_MK_E_SYNTAX','%TB_PAGEDOWN','%TB_PAGEUP',
+            '%TB_REGDB_E_CLASSNOTREG','%TB_REGDB_E_WRITEREGDB','%TB_SIZEOF_TBVARIANT','%TB_S_FALSE','%TB_S_OK','%TB_THUMBPOSITION','%TB_THUMBTRACK','%TB_TOP',
+            '%TCM_FIRST','%TCM_GETCURSEL','%TCN_FOCUSCHANGE','%TCN_GETOBJECT','%TCN_SELCHANGE','%TCN_SELCHANGING','%TCS_BOTTOM','%TCS_BUTTONS',
+            '%TCS_EX_FLATSEPARATORS','%TCS_EX_REGISTERDROP','%TCS_FIXEDWIDTH','%TCS_FLATBUTTONS','%TCS_FOCUSNEVER','%TCS_FOCUSONBUTTONDOWN','%TCS_FORCEICONLEFT','%TCS_FORCELABELLEFT',
+            '%TCS_HOTTRACK','%TCS_MULTILINE','%TCS_MULTISELECT','%TCS_OWNERDRAWFIXED','%TCS_RAGGEDRIGHT','%TCS_RIGHT','%TCS_RIGHTJUSTIFY','%TCS_SCROLLOPPOSITE',
+            '%TCS_SINGLELINE','%TCS_TABS','%TCS_TOOLTIPS','%TCS_VERTICAL','%TM_PLAINTEXT','%TM_RICHTEXT','%TOKENIZER_DEFAULT_ALPHA','%TOKENIZER_DEFAULT_DELIM',
+            '%TOKENIZER_DEFAULT_DQUOTE','%TOKENIZER_DEFAULT_NEWLINE','%TOKENIZER_DEFAULT_NUMERIC','%TOKENIZER_DEFAULT_SPACE','%TOKENIZER_DELIMITER','%TOKENIZER_EOL','%TOKENIZER_ERROR','%TOKENIZER_FINISHED',
+            '%TOKENIZER_NUMBER','%TOKENIZER_QUOTE','%TOKENIZER_STRING','%TOKENIZER_UNDEFTOK','%TRUE','%TV_FIRST','%UDM_GETACCEL','%UDM_GETBASE',
+            '%UDM_GETBUDDY','%UDM_GETPOS','%UDM_GETPOS32','%UDM_GETRANGE','%UDM_GETRANGE32','%UDM_GETUNICODEFORMAT','%UDM_SETACCEL','%UDM_SETBASE',
+            '%UDM_SETBUDDY','%UDM_SETPOS','%UDM_SETPOS32','%UDM_SETRANGE','%UDM_SETRANGE32','%UDM_SETUNICODEFORMAT','%UDS_ALIGNLEFT','%UDS_ALIGNRIGHT',
+            '%UDS_ARROWKEYS','%UDS_AUTOBUDDY','%UDS_HORZ','%UDS_HOTTRACK','%UDS_NOTHOUSANDS','%UDS_SETBUDDYINT','%UDS_WRAP','%UD_MAXVAL',
+            '%UD_MINVAL','%VK_0','%VK_1','%VK_2','%VK_3','%VK_4','%VK_5','%VK_6',
+            '%VK_7','%VK_8','%VK_9','%VK_A','%VK_ACCEPT','%VK_ADD','%VK_APPS','%VK_B',
+            '%VK_BACK','%VK_C','%VK_CANCEL','%VK_CAPITAL','%VK_CLEAR','%VK_CONTROL','%VK_CONVERT','%VK_D',
+            '%VK_DECIMAL','%VK_DELETE','%VK_DIVIDE','%VK_DOWN','%VK_E','%VK_END','%VK_ESCAPE','%VK_EXECUTE',
+            '%VK_F','%VK_F1','%VK_F10','%VK_F11','%VK_F12','%VK_F13','%VK_F14','%VK_F15',
+            '%VK_F16','%VK_F17','%VK_F18','%VK_F19','%VK_F2','%VK_F20','%VK_F21','%VK_F22',
+            '%VK_F23','%VK_F24','%VK_F3','%VK_F4','%VK_F5','%VK_F6','%VK_F7','%VK_F8',
+            '%VK_F9','%VK_FINAL','%VK_G','%VK_H','%VK_HANGEUL','%VK_HANGUL','%VK_HANJA','%VK_HELP',
+            '%VK_HOME','%VK_I','%VK_INSERT','%VK_J','%VK_JUNJA','%VK_K','%VK_KANA','%VK_KANJI',
+            '%VK_L','%VK_LBUTTON','%VK_LEFT','%VK_LINEFEED','%VK_LWIN','%VK_M','%VK_MBUTTON','%VK_MENU',
+            '%VK_MODECHANGE','%VK_MULTIPLY','%VK_N','%VK_NEXT','%VK_NONCONVERT','%VK_NUMLOCK','%VK_NUMPAD0','%VK_NUMPAD1',
+            '%VK_NUMPAD2','%VK_NUMPAD3','%VK_NUMPAD4','%VK_NUMPAD5','%VK_NUMPAD6','%VK_NUMPAD7','%VK_NUMPAD8','%VK_NUMPAD9',
+            '%VK_O','%VK_P','%VK_PAUSE','%VK_PGDN','%VK_PGUP','%VK_PRINT','%VK_PRIOR','%VK_Q',
+            '%VK_R','%VK_RBUTTON','%VK_RETURN','%VK_RIGHT','%VK_RWIN','%VK_S','%VK_SCROLL','%VK_SELECT',
+            '%VK_SEPARATOR','%VK_SHIFT','%VK_SLEEP','%VK_SNAPSHOT','%VK_SPACE','%VK_SUBTRACT','%VK_T','%VK_TAB',
+            '%VK_U','%VK_UP','%VK_V','%VK_W','%VK_X','%VK_XBUTTON1','%VK_XBUTTON2','%VK_Y',
+            '%VK_Z','%VT_ARRAY','%VT_BLOB','%VT_BLOB_OBJECT','%VT_BOOL','%VT_BSTR','%VT_BYREF','%VT_CARRAY',
+            '%VT_CF','%VT_CLSID','%VT_CY','%VT_DATE','%VT_DISPATCH','%VT_EMPTY','%VT_ERROR','%VT_FILETIME',
+            '%VT_HRESULT','%VT_I1','%VT_I2','%VT_I4','%VT_I8','%VT_INT','%VT_LPSTR','%VT_LPWSTR',
+            '%VT_NULL','%VT_PTR','%VT_R4','%VT_R8','%VT_RECORD','%VT_RESERVED','%VT_SAFEARRAY','%VT_STORAGE',
+            '%VT_STORED_OBJECT','%VT_STREAM','%VT_STREAMED_OBJECT','%VT_UI1','%VT_UI2','%VT_UI4','%VT_UI8','%VT_UINT',
+            '%VT_UNKNOWN','%VT_USERDEFINED','%VT_VARIANT','%VT_VECTOR','%VT_VOID','%WAVE_FORMAT_1M08','%WAVE_FORMAT_1M16','%WAVE_FORMAT_1S08',
+            '%WAVE_FORMAT_1S16','%WAVE_FORMAT_2M08','%WAVE_FORMAT_2M16','%WAVE_FORMAT_2S08','%WAVE_FORMAT_2S16','%WAVE_FORMAT_4M08','%WAVE_FORMAT_4M16','%WAVE_FORMAT_4S08',
+            '%WAVE_FORMAT_4S16','%WBF_CUSTOM','%WBF_LEVEL1','%WBF_LEVEL2','%WBF_OVERFLOW','%WBF_WORDBREAK','%WBF_WORDWRAP','%WHITE',
+            '%WIN_FINDTITLECONTAIN','%WIN_FINDTITLEEND','%WIN_FINDTITLEEQUAL','%WIN_FINDTITLESTART','%WM_ACTIVATE','%WM_ACTIVATEAPP','%WM_CAPTURECHANGED','%WM_CHAR',
+            '%WM_CLOSE','%WM_COMMAND','%WM_DESTROY','%WM_DROPFILES','%WM_ERASEBKGND','%WM_GETTEXTLENGTH','%WM_HOTKEY','%WM_HSCROLL',
+            '%WM_IDLE','%WM_INITDIALOG','%WM_KEYDOWN','%WM_KEYUP','%WM_KILLFOCUS','%WM_LBUTTONDBLCLK','%WM_LBUTTONDOWN','%WM_LBUTTONUP',
+            '%WM_MBUTTONDBLCLK','%WM_MBUTTONDOWN','%WM_MBUTTONUP','%WM_MOUSEFIRST','%WM_MOUSEMOVE','%WM_MOUSEWHEEL','%WM_MOVE','%WM_MOVING',
+            '%WM_NCLBUTTONDOWN','%WM_NCRBUTTONDOWN','%WM_NEXTDLGCTL','%WM_NOTIFY','%WM_PAINT','%WM_QUIT','%WM_RBUTTONDBLCLK','%WM_RBUTTONDOWN',
+            '%WM_RBUTTONUP','%WM_SETFOCUS','%WM_SETFONT','%WM_SETTEXT','%WM_SIZE','%WM_SIZING','%WM_SYSCOMMAND','%WM_TIMER',
+            '%WM_USER','%WM_VSCROLL','%WS_BORDER','%WS_CAPTION','%WS_CHILD','%WS_CLIPCHILDREN','%WS_CLIPSIBLINGS','%WS_DISABLED',
+            '%WS_DLGFRAME','%WS_EX_ACCEPTFILES','%WS_EX_APPWINDOW','%WS_EX_CLIENTEDGE','%WS_EX_CONTEXTHELP','%WS_EX_CONTROLPARENT','%WS_EX_LAYERED','%WS_EX_LEFT',
+            '%WS_EX_LEFTSCROLLBAR','%WS_EX_LTRREADING','%WS_EX_MDICHILD','%WS_EX_NOPARENTNOTIFY','%WS_EX_OVERLAPPEDWINDOW','%WS_EX_PALETTEWINDOW','%WS_EX_RIGHT','%WS_EX_RIGHTSCROLLBAR',
+            '%WS_EX_RTLREADING','%WS_EX_STATICEDGE','%WS_EX_TOOLWINDOW','%WS_EX_TOPMOST','%WS_EX_TRANSPARENT','%WS_EX_WINDOWEDGE','%WS_GROUP','%WS_HSCROLL',
+            '%WS_ICONIC','%WS_MAXIMIZE','%WS_MAXIMIZEBOX','%WS_MINIMIZE','%WS_MINIMIZEBOX','%WS_OVERLAPPEDWINDOW','%WS_POPUP','%WS_POPUPWINDOW',
+            '%WS_SYSMENU','%WS_TABSTOP','%WS_THICKFRAME','%WS_VISIBLE','%WS_VSCROLL','%YELLOW','%ZERO','CRLF',
+            'FALSE','M_E','M_PI','NULL','TAB','TRUE'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000FF; font-weight: bold;',
+            2 => 'color: #993333; font-style: italic; font-weight: bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #333333;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #800080;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #CC0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #66cc66;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #333333;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        1 => '_'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/tsql.php b/examples/includes/geshi/geshi/tsql.php
new file mode 100644 (file)
index 0000000..dd6b0cc
--- /dev/null
@@ -0,0 +1,378 @@
+<?php
+/*************************************************************************************
+ * tsql.php
+ * --------
+ * Author: Duncan Lock (dunc@dflock.co.uk)
+ * Copyright: (c) 2006 Duncan Lock (http://dflock.co.uk/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/11/22
+ *
+ * T-SQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/01/23 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2006/01/23)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'T-SQL',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            // Datatypes
+            'bigint', 'int', 'smallint', 'tinyint', 'bit', 'decimal', 'numeric', 'money',
+            'smallmoney', 'float', 'real', 'datetime', 'smalldatetime', 'char', 'varchar',
+            'text', 'nchar', 'nvarchar', 'ntext', 'binary', 'varbinary', 'image', 'cursor',
+            'sql_variant', 'table', 'timestamp', 'uniqueidentifier',
+
+            // Keywords
+            'ABSOLUTE', 'ACTION', 'ADD', 'ADMIN', 'AFTER', 'AGGREGATE', 'ALIAS', 'ALLOCATE', 'ALTER', 'ARE', 'ARRAY', 'AS',
+            'ASC', 'ASSERTION', 'AT', 'AUTHORIZATION', 'BACKUP', 'BEFORE', 'BEGIN', 'BINARY', 'BIT', 'BLOB', 'BOOLEAN', 'BOTH', 'BREADTH',
+            'BREAK', 'BROWSE', 'BULK', 'BY', 'CALL', 'CASCADE', 'CASCADED', 'CASE', 'CAST', 'CATALOG', 'CHAR', 'CHARACTER', 'CHECK', 'CHECKPOINT',
+            'CLASS', 'CLOB', 'CLOSE', 'CLUSTERED', 'COALESCE', 'COLLATE', 'COLLATION', 'COLUMN', 'COMMIT', 'COMPLETION', 'COMPUTE', 'CONNECT',
+            'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONSTRUCTOR', 'CONTAINS', 'CONTAINSTABLE', 'CONTINUE', 'CONVERT', 'CORRESPONDING', 'CREATE',
+            'CUBE', 'CURRENT', 'CURRENT_DATE', 'CURRENT_PATH', 'CURRENT_ROLE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER',
+            'CURSOR', 'CYCLE', 'DATA', 'DATABASE', 'DATE', 'DAY', 'DBCC', 'DEALLOCATE', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DEFERRABLE',
+            'DEFERRED', 'DELETE', 'DENY', 'DEPTH', 'DEREF', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DESTROY', 'DESTRUCTOR', 'DETERMINISTIC',
+            'DIAGNOSTICS', 'DICTIONARY', 'DISCONNECT', 'DISK', 'DISTINCT', 'DISTRIBUTED', 'DOMAIN', 'DOUBLE', 'DROP', 'DUMMY', 'DUMP', 'DYNAMIC',
+            'EACH', 'ELSE', 'END', 'END-EXEC', 'EQUALS', 'ERRLVL', 'ESCAPE', 'EVERY', 'EXCEPT', 'EXCEPTION', 'EXEC', 'EXECUTE', 'EXIT',
+            'EXTERNAL', 'FALSE', 'FETCH', 'FILE', 'FILLFACTOR', 'FIRST', 'FLOAT', 'FOR', 'FOREIGN', 'FOUND', 'FREE', 'FREETEXT', 'FREETEXTTABLE',
+            'FROM', 'FULL', 'FUNCTION', 'GENERAL', 'GET', 'GLOBAL', 'GOTO', 'GRANT', 'GROUP', 'GROUPING', 'HAVING', 'HOLDLOCK', 'HOST', 'HOUR',
+            'IDENTITY', 'IDENTITY_INSERT', 'IDENTITYCOL', 'IF', 'IGNORE', 'IMMEDIATE', 'INDEX', 'INDICATOR', 'INITIALIZE', 'INITIALLY',
+            'INNER', 'INOUT', 'INPUT', 'INSERT', 'INT', 'INTEGER', 'INTERSECT', 'INTERVAL', 'INTO', 'IS', 'ISOLATION', 'ITERATE', 'KEY',
+            'KILL', 'LANGUAGE', 'LARGE', 'LAST', 'LATERAL', 'LEADING', 'LEFT', 'LESS', 'LEVEL', 'LIMIT', 'LINENO', 'LOAD', 'LOCAL',
+            'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATOR', 'MAP', 'MATCH', 'MINUTE', 'MODIFIES', 'MODIFY', 'MODULE', 'MONTH', 'NAMES', 'NATIONAL',
+            'NATURAL', 'NCHAR', 'NCLOB', 'NEW', 'NEXT', 'NO', 'NOCHECK', 'NONCLUSTERED', 'NONE', 'NULLIF', 'NUMERIC', 'OBJECT', 'OF',
+            'OFF', 'OFFSETS', 'OLD', 'ON', 'ONLY', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPERATION', 'OPTION',
+            'ORDER', 'ORDINALITY', 'OUT', 'OUTPUT', 'OVER', 'PAD', 'PARAMETER', 'PARAMETERS', 'PARTIAL', 'PATH', 'PERCENT', 'PLAN',
+            'POSTFIX', 'PRECISION', 'PREFIX', 'PREORDER', 'PREPARE', 'PRESERVE', 'PRIMARY', 'PRINT', 'PRIOR', 'PRIVILEGES', 'PROC', 'PROCEDURE',
+            'PUBLIC', 'RAISERROR', 'READ', 'READS', 'READTEXT', 'REAL', 'RECONFIGURE', 'RECURSIVE', 'REF', 'REFERENCES', 'REFERENCING', 'RELATIVE',
+            'REPLICATION', 'RESTORE', 'RESTRICT', 'RESULT', 'RETURN', 'RETURNS', 'REVOKE', 'RIGHT', 'ROLE', 'ROLLBACK', 'ROLLUP', 'ROUTINE', 'ROW',
+            'ROWGUIDCOL', 'ROWS', 'RULE', 'SAVE', 'SAVEPOINT', 'SCHEMA', 'SCOPE', 'SCROLL', 'SEARCH', 'SECOND', 'SECTION', 'SELECT',
+            'SEQUENCE', 'SESSION', 'SESSION_USER', 'SET', 'SETS', 'SETUSER', 'SHUTDOWN', 'SIZE', 'SMALLINT', 'SPACE', 'SPECIFIC',
+            'SPECIFICTYPE', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'START', 'STATE', 'STATEMENT', 'STATIC', 'STATISTICS', 'STRUCTURE',
+            'SYSTEM_USER', 'TABLE', 'TEMPORARY', 'TERMINATE', 'TEXTSIZE', 'THAN', 'THEN', 'TIME', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE',
+            'TO', 'TOP', 'TRAILING', 'TRAN', 'TRANSACTION', 'TRANSLATION', 'TREAT', 'TRIGGER', 'TRUE', 'TRUNCATE', 'TSEQUAL', 'UNDER', 'UNION',
+            'UNIQUE', 'UNKNOWN', 'UNNEST', 'UPDATE', 'UPDATETEXT', 'USAGE', 'USE', 'USER', 'USING', 'VALUE', 'VALUES', 'VARCHAR', 'VARIABLE',
+            'VARYING', 'VIEW', 'WAITFOR', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WITH', 'WITHOUT', 'WORK', 'WRITE', 'WRITETEXT', 'YEAR', 'ZONE',
+            'UNCOMMITTED', 'NOCOUNT',
+            ),
+        2 => array(
+            /*
+                Built-in functions
+                Highlighted in pink.
+            */
+
+            //Configuration Functions
+            '@@DATEFIRST','@@OPTIONS','@@DBTS','@@REMSERVER','@@LANGID','@@SERVERNAME',
+            '@@LANGUAGE','@@SERVICENAME','@@LOCK_TIMEOUT','@@SPID','@@MAX_CONNECTIONS','@@TEXTSIZE',
+            '@@MAX_PRECISION','@@VERSION','@@NESTLEVEL',
+
+            //Cursor Functions
+            '@@CURSOR_ROWS','@@FETCH_STATUS',
+
+            //Date and Time Functions
+            'DATEADD','DATEDIFF','DATENAME','DATEPART','DAY','GETDATE','GETUTCDATE','MONTH','YEAR',
+
+            //Mathematical Functions
+            'ABS','DEGREES','RAND','ACOS','EXP','ROUND','ASIN','FLOOR','SIGN',
+            'ATAN','LOG','SIN','ATN2','LOG10','SQUARE','CEILING','PI','SQRT','COS',
+            'POWER','TAN','COT','RADIANS',
+
+            //Meta Data Functions
+            'COL_LENGTH','fn_listextendedproperty','COL_NAME','FULLTEXTCATALOGPROPERTY',
+            'COLUMNPROPERTY','FULLTEXTSERVICEPROPERTY','DATABASEPROPERTY','INDEX_COL',
+            'DATABASEPROPERTYEX','INDEXKEY_PROPERTY','DB_ID','INDEXPROPERTY','DB_NAME',
+            'OBJECT_ID','FILE_ID','OBJECT_NAME','FILE_NAME','OBJECTPROPERTY','FILEGROUP_ID',
+            '@@PROCID','FILEGROUP_NAME','SQL_VARIANT_PROPERTY','FILEGROUPPROPERTY',
+            'TYPEPROPERTY','FILEPROPERTY',
+
+            //Security Functions
+            'fn_trace_geteventinfo','IS_SRVROLEMEMBER','fn_trace_getfilterinfo','SUSER_SID',
+            'fn_trace_getinfo','SUSER_SNAME','fn_trace_gettable','USER_ID','HAS_DBACCESS',
+            'IS_MEMBER',
+
+            //String Functions
+            'ASCII','NCHAR','SOUNDEX','CHAR','PATINDEX','SPACE','CHARINDEX',
+            'REPLACE','STR','DIFFERENCE','QUOTENAME','STUFF','LEFT','REPLICATE',
+            'SUBSTRING','LEN','REVERSE','UNICODE','LOWER','RIGHT','UPPER','LTRIM',
+            'RTRIM',
+
+            //System Functions
+            'APP_NAME','COLLATIONPROPERTY','@@ERROR','fn_helpcollations',
+            'fn_servershareddrives','fn_virtualfilestats','FORMATMESSAGE',
+            'GETANSINULL','HOST_ID','HOST_NAME','IDENT_CURRENT','IDENT_INCR',
+            'IDENT_SEED','@@IDENTITY','ISDATE','ISNUMERIC','PARSENAME','PERMISSIONS',
+            '@@ROWCOUNT','ROWCOUNT_BIG','SCOPE_IDENTITY','SERVERPROPERTY','SESSIONPROPERTY',
+            'STATS_DATE','@@TRANCOUNT','USER_NAME',
+
+            //System Statistical Functions
+            '@@CONNECTIONS','@@PACK_RECEIVED','@@CPU_BUSY','@@PACK_SENT',
+            '@@TIMETICKS','@@IDLE','@@TOTAL_ERRORS','@@IO_BUSY',
+            '@@TOTAL_READ','@@PACKET_ERRORS','@@TOTAL_WRITE',
+
+            //Text and Image Functions
+            'TEXTPTR','TEXTVALID',
+
+            //Aggregate functions
+            'AVG', 'MAX', 'BINARY_CHECKSUM', 'MIN', 'CHECKSUM', 'SUM', 'CHECKSUM_AGG',
+            'STDEV', 'COUNT', 'STDEVP', 'COUNT_BIG', 'VAR', 'GROUPING', 'VARP'
+            ),
+        3 => array(
+            /*
+                System stored procedures
+                Higlighted dark brown
+            */
+
+            //Active Directory Procedures
+            'sp_ActiveDirectory_Obj', 'sp_ActiveDirectory_SCP',
+
+            //Catalog Procedures
+            'sp_column_privileges', 'sp_special_columns', 'sp_columns', 'sp_sproc_columns',
+            'sp_databases', 'sp_statistics', 'sp_fkeys', 'sp_stored_procedures', 'sp_pkeys',
+            'sp_table_privileges', 'sp_server_info', 'sp_tables',
+
+            //Cursor Procedures
+            'sp_cursor_list', 'sp_describe_cursor_columns', 'sp_describe_cursor', 'sp_describe_cursor_tables',
+
+            //Database Maintenance Plan Procedures
+            'sp_add_maintenance_plan', 'sp_delete_maintenance_plan_db', 'sp_add_maintenance_plan_db',
+            'sp_delete_maintenance_plan_job', 'sp_add_maintenance_plan_job', 'sp_help_maintenance_plan',
+            'sp_delete_maintenance_plan',
+
+            //Distributed Queries Procedures
+            'sp_addlinkedserver', 'sp_indexes', 'sp_addlinkedsrvlogin', 'sp_linkedservers', 'sp_catalogs',
+            'sp_primarykeys', 'sp_column_privileges_ex', 'sp_columns_ex',
+            'sp_table_privileges_ex', 'sp_tables_ex', 'sp_foreignkeys',
+
+            //Full-Text Search Procedures
+            'sp_fulltext_catalog', 'sp_help_fulltext_catalogs_cursor', 'sp_fulltext_column',
+            'sp_help_fulltext_columns', 'sp_fulltext_database', 'sp_help_fulltext_columns_cursor',
+            'sp_fulltext_service', 'sp_help_fulltext_tables', 'sp_fulltext_table',
+            'sp_help_fulltext_tables_cursor', 'sp_help_fulltext_catalogs',
+
+            //Log Shipping Procedures
+            'sp_add_log_shipping_database', 'sp_delete_log_shipping_database', 'sp_add_log_shipping_plan',
+            'sp_delete_log_shipping_plan', 'sp_add_log_shipping_plan_database',
+            'sp_delete_log_shipping_plan_database', 'sp_add_log_shipping_primary',
+            'sp_delete_log_shipping_primary', 'sp_add_log_shipping_secondary',
+            'sp_delete_log_shipping_secondary', 'sp_can_tlog_be_applied', 'sp_get_log_shipping_monitor_info',
+            'sp_change_monitor_role', 'sp_remove_log_shipping_monitor', 'sp_change_primary_role',
+            'sp_resolve_logins', 'sp_change_secondary_role', 'sp_update_log_shipping_monitor_info',
+            'sp_create_log_shipping_monitor_account', 'sp_update_log_shipping_plan',
+            'sp_define_log_shipping_monitor', 'sp_update_log_shipping_plan_database',
+
+            //OLE Automation Extended Stored Procedures
+            'sp_OACreate', 'sp_OAMethod', 'sp_OADestroy', 'sp_OASetProperty', 'sp_OAGetErrorInfo',
+            'sp_OAStop', 'sp_OAGetProperty',
+
+            //Replication Procedures
+            'sp_add_agent_parameter', 'sp_enableagentoffload', 'sp_add_agent_profile',
+            'sp_enumcustomresolvers', 'sp_addarticle', 'sp_enumdsn', 'sp_adddistpublisher',
+            'sp_enumfullsubscribers', 'sp_adddistributiondb', 'sp_expired_subscription_cleanup',
+            'sp_adddistributor', 'sp_generatefilters', 'sp_addmergealternatepublisher',
+            'sp_getagentoffloadinfo', 'sp_addmergearticle', 'sp_getmergedeletetype', 'sp_addmergefilter',
+            'sp_get_distributor', 'sp_addmergepublication', 'sp_getqueuedrows', 'sp_addmergepullsubscription',
+            'sp_getsubscriptiondtspackagename', 'sp_addmergepullsubscription_agent', 'sp_grant_publication_access',
+            'sp_addmergesubscription', 'sp_help_agent_default', 'sp_addpublication', 'sp_help_agent_parameter',
+            'sp_addpublication_snapshot', 'sp_help_agent_profile', 'sp_addpublisher70', 'sp_helparticle',
+            'sp_addpullsubscription', 'sp_helparticlecolumns', 'sp_addpullsubscription_agent', 'sp_helparticledts',
+            'sp_addscriptexec', 'sp_helpdistpublisher', 'sp_addsubscriber', 'sp_helpdistributiondb',
+            'sp_addsubscriber_schedule', 'sp_helpdistributor', 'sp_addsubscription', 'sp_helpmergealternatepublisher',
+            'sp_addsynctriggers', 'sp_helpmergearticle', 'sp_addtabletocontents', 'sp_helpmergearticlecolumn',
+            'sp_adjustpublisheridentityrange', 'sp_helpmergearticleconflicts', 'sp_article_validation',
+            'sp_helpmergeconflictrows', 'sp_articlecolumn', 'sp_helpmergedeleteconflictrows', 'sp_articlefilter',
+            'sp_helpmergefilter', 'sp_articlesynctranprocs', 'sp_helpmergepublication', 'sp_articleview',
+            'sp_helpmergepullsubscription', 'sp_attachsubscription', 'sp_helpmergesubscription', 'sp_browsesnapshotfolder',
+            'sp_helppublication', 'sp_browsemergesnapshotfolder', 'sp_help_publication_access', 'sp_browsereplcmds',
+            'sp_helppullsubscription', 'sp_change_agent_parameter', 'sp_helpreplfailovermode', 'sp_change_agent_profile',
+            'sp_helpreplicationdboption', 'sp_changearticle', 'sp_helpreplicationoption', 'sp_changedistpublisher',
+            'sp_helpsubscriberinfo', 'sp_changedistributiondb', 'sp_helpsubscription', 'sp_changedistributor_password',
+            'sp_ivindexhasnullcols', 'sp_changedistributor_property', 'sp_helpsubscription_properties', 'sp_changemergearticle',
+            'sp_link_publication', 'sp_changemergefilter', 'sp_marksubscriptionvalidation', 'sp_changemergepublication',
+            'sp_mergearticlecolumn', 'sp_changemergepullsubscription', 'sp_mergecleanupmetadata', 'sp_changemergesubscription',
+            'sp_mergedummyupdate', 'sp_changepublication', 'sp_mergesubscription_cleanup', 'sp_changesubscriber',
+            'sp_publication_validation', 'sp_changesubscriber_schedule', 'sp_refreshsubscriptions', 'sp_changesubscriptiondtsinfo',
+            'sp_reinitmergepullsubscription', 'sp_changesubstatus', 'sp_reinitmergesubscription', 'sp_change_subscription_properties',
+            'sp_reinitpullsubscription', 'sp_check_for_sync_trigger', 'sp_reinitsubscription', 'sp_copymergesnapshot',
+            'sp_removedbreplication', 'sp_copysnapshot', 'sp_repladdcolumn', 'sp_copysubscription', 'sp_replcmds',
+            'sp_deletemergeconflictrow', 'sp_replcounters', 'sp_disableagentoffload', 'sp_repldone', 'sp_drop_agent_parameter',
+            'sp_repldropcolumn', 'sp_drop_agent_profile', 'sp_replflush', 'sp_droparticle', 'sp_replicationdboption',
+            'sp_dropanonymouseagent', 'sp_replication_agent_checkup', 'sp_dropdistpublisher', 'sp_replqueuemonitor',
+            'sp_dropdistributiondb', 'sp_replsetoriginator', 'sp_dropmergealternatepublisher', 'sp_replshowcmds',
+            'sp_dropdistributor', 'sp_repltrans', 'sp_dropmergearticle', 'sp_restoredbreplication', 'sp_dropmergefilter',
+            'sp_revoke_publication_access', 'sp_scriptsubconflicttable', 'sp_dropmergepublication', 'sp_script_synctran_commands',
+            'sp_dropmergepullsubscription', 'sp_setreplfailovermode', 'sp_showrowreplicainfo', 'sp_dropmergesubscription',
+            'sp_subscription_cleanup', 'sp_droppublication', 'sp_table_validation', 'sp_droppullsubscription',
+            'sp_update_agent_profile', 'sp_dropsubscriber', 'sp_validatemergepublication', 'sp_dropsubscription',
+            'sp_validatemergesubscription', 'sp_dsninfo', 'sp_vupgrade_replication', 'sp_dumpparamcmd',
+
+            //Security Procedures
+            'sp_addalias', 'sp_droprolemember', 'sp_addapprole', 'sp_dropserver', 'sp_addgroup', 'sp_dropsrvrolemember',
+            'sp_dropuser', 'sp_addlogin', 'sp_grantdbaccess', 'sp_addremotelogin',
+            'sp_grantlogin', 'sp_addrole', 'sp_helpdbfixedrole', 'sp_addrolemember', 'sp_helpgroup',
+            'sp_addserver', 'sp_helplinkedsrvlogin', 'sp_addsrvrolemember', 'sp_helplogins', 'sp_adduser',
+            'sp_helpntgroup', 'sp_approlepassword', 'sp_helpremotelogin', 'sp_changedbowner', 'sp_helprole',
+            'sp_changegroup', 'sp_helprolemember', 'sp_changeobjectowner', 'sp_helprotect', 'sp_change_users_login',
+            'sp_helpsrvrole', 'sp_dbfixedrolepermission', 'sp_helpsrvrolemember', 'sp_defaultdb', 'sp_helpuser',
+            'sp_defaultlanguage', 'sp_MShasdbaccess', 'sp_denylogin', 'sp_password', 'sp_dropalias', 'sp_remoteoption',
+            'sp_dropapprole', 'sp_revokedbaccess', 'sp_dropgroup', 'sp_revokelogin', 'sp_droplinkedsrvlogin',
+            'sp_setapprole', 'sp_droplogin', 'sp_srvrolepermission', 'sp_dropremotelogin', 'sp_validatelogins', 'sp_droprole',
+
+            //SQL Mail Procedures
+            'sp_processmail', 'xp_sendmail', 'xp_deletemail', 'xp_startmail', 'xp_findnextmsg', 'xp_stopmail', 'xp_readmail',
+
+            //SQL Profiler Procedures
+            'sp_trace_create', 'sp_trace_setfilter', 'sp_trace_generateevent', 'sp_trace_setstatus', 'sp_trace_setevent',
+
+            //SQL Server Agent Procedures
+            'sp_add_alert', 'sp_help_jobhistory', 'sp_add_category', 'sp_help_jobschedule', 'sp_add_job',
+            'sp_help_jobserver', 'sp_add_jobschedule', 'sp_help_jobstep', 'sp_add_jobserver', 'sp_help_notification',
+            'sp_add_jobstep', 'sp_help_operator', 'sp_add_notification', 'sp_help_targetserver',
+            'sp_add_operator', 'sp_help_targetservergroup', 'sp_add_targetservergroup', 'sp_helptask',
+            'sp_add_targetsvrgrp_member', 'sp_manage_jobs_by_login', 'sp_addtask', 'sp_msx_defect',
+            'sp_apply_job_to_targets', 'sp_msx_enlist', 'sp_delete_alert', 'sp_post_msx_operation',
+            'sp_delete_category', 'sp_purgehistory', 'sp_delete_job', 'sp_purge_jobhistory', 'sp_delete_jobschedule',
+            'sp_reassigntask', 'sp_delete_jobserver', 'sp_remove_job_from_targets', 'sp_delete_jobstep',
+            'sp_resync_targetserver', 'sp_delete_notification', 'sp_start_job', 'sp_delete_operator',
+            'sp_stop_job', 'sp_delete_targetserver', 'sp_update_alert', 'sp_delete_targetservergroup',
+            'sp_update_category', 'sp_delete_targetsvrgrp_member', 'sp_update_job', 'sp_droptask',
+            'sp_update_jobschedule', 'sp_help_alert', 'sp_update_jobstep', 'sp_help_category',
+            'sp_update_notification', 'sp_help_downloadlist', 'sp_update_operator', 'sp_helphistory',
+            'sp_update_targetservergroup', 'sp_help_job', 'sp_updatetask', 'xp_sqlagent_proxy_account',
+
+            //System Procedures
+            'sp_add_data_file_recover_suspect_db', 'sp_helpconstraint', 'sp_addextendedproc',
+            'sp_helpdb', 'sp_addextendedproperty', 'sp_helpdevice', 'sp_add_log_file_recover_suspect_db',
+            'sp_helpextendedproc', 'sp_addmessage', 'sp_helpfile', 'sp_addtype', 'sp_helpfilegroup',
+            'sp_addumpdevice', 'sp_helpindex', 'sp_altermessage', 'sp_helplanguage', 'sp_autostats',
+            'sp_helpserver', 'sp_attach_db', 'sp_helpsort', 'sp_attach_single_file_db', 'sp_helpstats',
+            'sp_bindefault', 'sp_helptext', 'sp_bindrule', 'sp_helptrigger', 'sp_bindsession',
+            'sp_indexoption', 'sp_certify_removable', 'sp_invalidate_textptr', 'sp_configure',
+            'sp_lock', 'sp_create_removable', 'sp_monitor', 'sp_createstats', 'sp_procoption',
+            'sp_cycle_errorlog', 'sp_recompile', 'sp_datatype_info', 'sp_refreshview', 'sp_dbcmptlevel',
+            'sp_releaseapplock', 'sp_dboption', 'sp_rename', 'sp_dbremove', 'sp_renamedb',
+            'sp_delete_backuphistory', 'sp_resetstatus', 'sp_depends', 'sp_serveroption', 'sp_detach_db',
+            'sp_setnetname', 'sp_dropdevice', 'sp_settriggerorder', 'sp_dropextendedproc', 'sp_spaceused',
+            'sp_dropextendedproperty', 'sp_tableoption', 'sp_dropmessage', 'sp_unbindefault', 'sp_droptype',
+            'sp_unbindrule', 'sp_executesql', 'sp_updateextendedproperty', 'sp_getapplock', 'sp_updatestats',
+            'sp_getbindtoken', 'sp_validname', 'sp_help', 'sp_who',
+
+            //Web Assistant Procedures
+            'sp_dropwebtask', 'sp_makewebtask', 'sp_enumcodepages', 'sp_runwebtask',
+
+            //XML Procedures
+            'sp_xml_preparedocument', 'sp_xml_removedocument',
+
+            //General Extended Procedures
+            'xp_cmdshellxp_logininfo', 'xp_enumgroups', 'xp_msver', 'xp_findnextmsgxp_revokelogin',
+            'xp_grantlogin', 'xp_sprintf', 'xp_logevent', 'xp_sqlmaint', 'xp_loginconfig', 'xp_sscanf',
+
+            //API System Stored Procedures
+            'sp_cursor', 'sp_cursorclose', 'sp_cursorexecute', 'sp_cursorfetch', 'sp_cursoropen',
+            'sp_cursoroption', 'sp_cursorprepare', 'sp_cursorunprepare', 'sp_execute', 'sp_prepare', 'sp_unprepare',
+
+            //Misc
+            'sp_createorphan', 'sp_droporphans', 'sp_reset_connection', 'sp_sdidebug'
+            ),
+        4 => array(
+            //Function/sp's higlighted brown.
+            'fn_helpcollations', 'fn_listextendedproperty ', 'fn_servershareddrives',
+            'fn_trace_geteventinfo', 'fn_trace_getfilterinfo', 'fn_trace_getinfo',
+            'fn_trace_gettable', 'fn_virtualfilestats',
+            ),
+        ),
+    'SYMBOLS' => array(
+        '!', '!=', '%', '&', '&&', '(', ')', '*', '+', '-', '/', '<', '<<', '<=',
+        '<=>', '<>', '=', '>', '>=', '>>', '^', 'ALL', 'AND', 'ANY', 'BETWEEN', 'CROSS',
+        'EXISTS', 'IN', 'JOIN', 'LIKE', 'NOT', 'NULL', 'OR', 'OUTER', 'SOME', '|', '||', '~'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000FF;',
+            2 => 'color: #FF00FF;',
+            3 => 'color: #AF0000;',
+            4 => 'color: #AF0000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008080;',
+            'MULTI' => 'color: #008080;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #808080;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;',
+            2 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #808080;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/typoscript.php b/examples/includes/geshi/geshi/typoscript.php
new file mode 100644 (file)
index 0000000..b0ae753
--- /dev/null
@@ -0,0 +1,300 @@
+<?php
+/*************************************************************************************
+ * typoscript.php
+ * --------
+ * Author: Jan-Philipp Halle (typo3@jphalle.de)
+ * Copyright: (c) 2005 Jan-Philipp Halle (http://www.jphalle.de/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/07/29
+ *
+ * TypoScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ * - Michiel Roos <geshi@typofree.org> Complete rewrite
+ * 2005/07/29 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * <things-to-do>
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'TypoScript',
+    'COMMENT_SINGLE' => array(1  => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(2 => '/(?<!(#|\'|"))(?:#(?!(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3}))[^\n#]+|#{2}[^\n#]+|#{7,999}[^\n]+)/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        // Conditions: http://documentation.typo3.org/documentation/tsref/conditions/
+        1 => array(
+            'browser', 'compatVersion', 'dayofmonth', 'dayofweek', 'device',
+            'globalString', 'globalVars', 'hostname', 'hour',
+            'ip', 'language', 'loginUser', 'loginuser', 'minute',
+            'month', 'PIDinRootline', 'PIDupinRootline',
+            'system', 'treelevel', 'useragent', 'userFunc',
+            'usergroup', 'version'
+            ),
+
+        // Functions: http://documentation.typo3.org/documentation/tsref/functions/
+        2 => array(
+            'addParams', 'encapsLines', 'filelink', 'HTMLparser',
+            'HTMLparser_tags', 'if', 'imageLinkWrap',
+            'imgResource', 'makelinks', 'numRows', 'parseFunc',
+            'select', 'split', 'stdWrap', 'tableStyle', 'tags',
+            'textStyle', 'typolink'
+            ),
+
+        // Toplevel objects: http://documentation.typo3.org/documentation/tsref/tlo-objects/
+        3 => array(
+            'CARRAY', 'CONFIG', 'CONSTANTS', 'FE_DATA', 'FE_TABLE', 'FRAME',
+            'FRAMESET', 'META', 'PAGE', 'plugin'
+            ),
+
+        // Content Objects (cObject) : http://documentation.typo3.org/documentation/tsref/cobjects/
+        4 => array(
+            'CASE', 'CLEARGIF', 'COA', 'COA_INT', 'COBJ_ARRAY', 'COLUMNS',
+            'CONTENT', 'CTABLE', 'EDITPANEL', 'FILE', 'FORM',
+            'HMENU', 'HRULER', 'HTML', 'IMAGE', 'IMGTEXT',
+            'IMG_RESOURCE', 'LOAD_REGISTER', 'MULTIMEDIA',
+            'OTABLE', 'PHP_SCRIPT', 'PHP_SCRIPT_EXT',
+            'PHP_SCRIPT_INT', 'RECORDS', 'RESTORE_REGISTER',
+            'SEARCHRESULT', 'TEMPLATE', 'TEXT', 'USER',
+            'USER_INT'
+            ),
+
+        // GIFBUILDER toplevel link: http://documentation.typo3.org/documentation/tsref/gifbuilder/
+        5 => array(
+            'GIFBUILDER',
+            ),
+
+        // GIFBUILDER: http://documentation.typo3.org/documentation/tsref/gifbuilder/
+        // skipped fields: IMAGE, TEXT
+        // NOTE! the IMAGE and TEXT field already are linked in group 4, they
+        // cannot be linked twice . . . . unfortunately
+        6 => array(
+            'ADJUST', 'BOX', 'CROP', 'EFFECT', 'EMBOSS',
+            'IMGMAP', 'OUTLINE', 'SCALE', 'SHADOW',
+            'WORKAREA'
+            ),
+
+        // MENU Objects: http://documentation.typo3.org/documentation/tsref/menu/
+        7 => array(
+            'GMENU', 'GMENU_FOLDOUT', 'GMENU_LAYERS', 'IMGMENU',
+            'IMGMENUITEM', 'JSMENU', 'JSMENUITEM', 'TMENU',
+            'TMENUITEM', 'TMENU_LAYERS'
+            ),
+
+        // MENU common properties: http://documentation.typo3.org/documentation/tsref/menu/common-properties/
+        8 => array(
+            'alternativeSortingField', 'begin', 'debugItemConf',
+            'imgNameNotRandom', 'imgNamePrefix',
+            'itemArrayProcFunc', 'JSWindow', 'maxItems',
+            'minItems', 'overrideId', 'sectionIndex',
+            'showAccessRestrictedPages', 'submenuObjSuffixes'
+            ),
+
+        // MENU item states: http://documentation.typo3.org/documentation/tsref/menu/item-states/
+        9 => array(
+            'ACT', 'ACTIFSUB', 'ACTIFSUBRO', 'ACTRO', 'CUR', 'CURIFSUB',
+            'CURIFSUBRO', 'CURRO', 'IFSUB', 'IFSUBRO', 'NO',
+            'SPC', 'USERDEF1', 'USERDEF1RO', 'USERDEF2',
+            'USERDEF2RO', 'USR', 'USRRO'
+            ),
+        ),
+
+    // Does not include '-' because of stuff like htmlTag_langKey = en-GB and
+    // lib.nav-sub
+    'SYMBOLS' => array(
+        0 => array(
+            '|',
+            '+', '*', '/', '%',
+            '!', '&&', '^',
+            '<', '>', '=',
+            '?', ':',
+            '.'
+            ),
+        1 => array(
+            '(', ')', '{', '}', '[', ']'
+            )
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true,
+        4 => true,
+        5 => true,
+        6 => true,
+        7 => true,
+        8 => true,
+        9 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #ed7d14;',
+            2 => 'font-weight: bold;',
+            3 => 'color: #990000; font-weight: bold;',
+            4 => 'color: #990000; font-weight: bold;',
+            5 => 'color: #990000; font-weight: bold;',
+            6 => 'color: #990000; font-weight: bold;',
+            7 => 'color: #990000; font-weight: bold;',
+            8 => 'font-weight: bold;',
+            9 => 'color: #990000; font-weight: bold;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #aaa; font-style: italic;',
+            2 => 'color: #aaa; font-style: italic;',
+            'MULTI' => 'color: #aaa; font-style: italic;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ac14aa;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000e0; font-weight: bold;',
+            2 => 'color: #0000e0; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #009900;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #339933; font-weight: bold;',
+                // Set this to the same value as brackets above
+            1 => 'color: #009900; font-weight: bold;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #009900;',
+            1 => 'color: #009900; font-weight: bold;',
+            2 => 'color: #3366CC;',
+            3 => 'color: #000066; font-weight: bold;',
+            4 => 'color: #ed7d14;',
+            5 => 'color: #000066; font-weight: bold;',
+            6 => 'color: #009900;',
+            7 => 'color: #3366CC;'
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => 'http://documentation.typo3.org/documentation/tsref/conditions/{FNAME}/',
+        2 => 'http://documentation.typo3.org/documentation/tsref/functions/{FNAME}/',
+        3 => 'http://documentation.typo3.org/documentation/tsref/tlo-objects/{FNAME}/',
+        4 => 'http://documentation.typo3.org/documentation/tsref/cobjects/{FNAME}/',
+        5 => 'http://documentation.typo3.org/documentation/tsref/gifbuilder/',
+        6 => 'http://documentation.typo3.org/documentation/tsref/gifbuilder/{FNAME}/',
+        7 => 'http://documentation.typo3.org/documentation/tsref/menu/{FNAME}/',
+        8 => 'http://documentation.typo3.org/documentation/tsref/menu/common-properties/',
+        9 => 'http://documentation.typo3.org/documentation/tsref/menu/item-states/'
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+            // Constant
+        0 => array(
+            GESHI_SEARCH => '(\{)(\$[a-zA-Z_\.]+[a-zA-Z0-9_\.]*)(\})',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => '\\3'
+            ),
+
+            // Constant dollar sign
+        1 => array(
+            GESHI_SEARCH => '(\$)([a-zA-Z_\.]+[a-zA-Z0-9_\.]*)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => '\\2'
+            ),
+
+            // xhtml tag
+        2 => array(
+            GESHI_SEARCH => '(&lt;[a-zA-Z\!\/].*?&gt;)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 's',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+
+            // extension keys / tables: (static|user|ttx|tx|tt|fe)_something[_something]
+        3 => array(
+            GESHI_SEARCH => '(plugin\.|[^\.]\b)((?:static|user|ttx|tx|tt|fe)(?:_[0-9A-Za-z_]+?)\b)',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+
+            // conditions and controls
+        4 => array(
+            GESHI_SEARCH => '(\[)(globalVar|global|end)\b',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+
+            // lowlevel setup and constant objects
+        5 => array(
+            GESHI_SEARCH => '([^\.\$-\{]\b)(cObj|field|config|content|file|frameset|includeLibs|lib|page|plugin|register|resources|sitemap|sitetitle|styles|temp|tt_content|tt_news|types|xmlnews)\b',
+            GESHI_REPLACE => '\\2',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '\\1',
+            GESHI_AFTER => ''
+            ),
+
+            // markers
+        6 => array(
+            GESHI_SEARCH => '(###[^#]+###)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+
+            // hex color codes
+        7 => array(
+            GESHI_SEARCH => '(#[a-fA-F0-9]{6}\b|#[a-fA-F0-9]{3}\b)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => '',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            )
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/vb.php b/examples/includes/geshi/geshi/vb.php
new file mode 100644 (file)
index 0000000..0409058
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+/*************************************************************************************
+ * vb.php
+ * ------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org),
+ *                     Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/08/30
+ *
+ * Visual Basic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/27 (1.0.8.1)
+ *  -  changed keyword list for better Visual Studio compliance
+ * 2008/08/26 (1.0.8.1)
+ *  -  Fixed multiline comments
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Visual Basic',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        // Comments (either single or multiline with _
+        1 => '/\'.*(?<! _)\n/sU',
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'AddressOf', 'Alias', 'And', 'Append', 'As', 'BF', 'Binary',
+            'Boolean', 'ByRef', 'Byte', 'ByVal', 'Call', 'Case', 'CBool',
+            'CByte', 'CCur', 'CDate', 'CDbl', 'CDec', 'CInt', 'CLng',
+            'Close', 'Collection', 'Const', 'Control', 'CSng', 'CStr',
+            'Currency', 'CVar', 'Date', 'Declare', 'Dim', 'Do', 'Double',
+            'Each', 'Else', 'ElseIf', 'End', 'Enum', 'Erase', 'Error',
+            'Event', 'Exit', 'Explicit', 'False', 'For', 'Friend',
+            'Function', 'Get', 'GoSub', 'Goto', 'If', 'Implements', 'In',
+            'Input', 'Integer', 'Is', 'LBound', 'Let', 'Lib', 'Like',
+            'Line', 'Long', 'Loop', 'Mod', 'New', 'Next', 'Not',
+            'Nothing', 'Object', 'On', 'Open', 'Option', 'Optional',
+            'Or', 'Output', 'ParamArray', 'Preserve', 'Print', 'Private',
+            'Property', 'Public', 'RaiseEvent', 'Random', 'ReDim',
+            'Resume', 'Select', 'Set', 'Single', 'Static', 'Step',
+            'Stop', 'String', 'Sub', 'Then', 'To', 'True', 'Type',
+            'TypeOf', 'UBound', 'Until', 'Variant', 'While', 'With',
+            'WithEvents', 'Xor'
+            )
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000080;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000;'
+            ),
+        'BRACKETS' => array(
+            ),
+        'STRINGS' => array(
+            0 => 'color: #800000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #800000; font-weight: bold;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'BRACKETS' => GESHI_NEVER,
+            'SYMBOLS' => GESHI_NEVER,
+            'NUMBERS' => GESHI_NEVER
+            )
+        )
+);
+
+?>
\ No newline at end of file
diff --git a/examples/includes/geshi/geshi/vbnet.php b/examples/includes/geshi/geshi/vbnet.php
new file mode 100644 (file)
index 0000000..4a0f000
--- /dev/null
@@ -0,0 +1,201 @@
+<?php
+/*************************************************************************************
+ * vbnet.php
+ * ---------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/06/04
+ *
+ * VB.NET language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.0)
+ *  -  Initial release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'vb.net',
+    'COMMENT_SINGLE' => array(1 => "'"),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            '3DDKSHADOW', '3DHIGHLIGHT', '3DLIGHT', 'ABORT', 'ABORTRETRYIGNORE', 'ACTIVEBORDER',
+            'ACTIVETITLEBAR', 'ALIAS', 'APPLICATIONMODAL', 'APPLICATIONWORKSPACE', 'ARCHIVE',
+            'BACK', 'BINARYCOMPARE', 'BLACK', 'BLUE', 'BUTTONFACE', 'BUTTONSHADOW', 'BUTTONTEXT',
+            'CANCEL', 'CDROM', 'CR', 'CRITICAL', 'CRLF', 'CYAN', 'DEFAULT', 'DEFAULTBUTTON1',
+            'DEFAULTBUTTON2', 'DEFAULTBUTTON3', 'DESKTOP', 'DIRECTORY', 'EXCLAMATION', 'FALSE',
+            'FIXED', 'FORAPPENDING', 'FORMFEED', 'FORREADING', 'FORWRITING', 'FROMUNICODE',
+            'GRAYTEXT', 'GREEN', 'HIDDEN', 'HIDE', 'HIGHLIGHT', 'HIGHLIGHTTEXT', 'HIRAGANA',
+            'IGNORE', 'INACTIVEBORDER', 'INACTIVECAPTIONTEXT', 'INACTIVETITLEBAR', 'INFOBACKGROUND',
+            'INFORMATION', 'INFOTEXT', 'KATAKANALF', 'LOWERCASE', 'MAGENTA', 'MAXIMIZEDFOCUS',
+            'MENUBAR', 'MENUTEXT', 'METHOD', 'MINIMIZEDFOCUS', 'MINIMIZEDNOFOCUS', 'MSGBOXRIGHT',
+            'MSGBOXRTLREADING', 'MSGBOXSETFOREGROUND', 'NARROW', 'NEWLINE', 'NO', 'NORMAL',
+            'NORMALFOCUS', 'NORMALNOFOCUS', 'NULLSTRING', 'OBJECTERROR', 'OK', 'OKCANCEL', 'OKONLY',
+            'PROPERCASE', 'QUESTION', 'RAMDISK', 'READONLY', 'RED', 'REMOTE', 'REMOVABLE', 'RETRY',
+            'RETRYCANCEL', 'SCROLLBARS', 'SYSTEMFOLDER', 'SYSTEMMODAL', 'TEMPORARYFOLDER',
+            'TEXTCOMPARE', 'TITLEBARTEXT', 'TRUE', 'UNICODE', 'UNKNOWN', 'UPPERCASE', 'VERTICALTAB',
+            'VOLUME', 'WHITE', 'WIDE', 'WIN16', 'WIN32', 'WINDOWBACKGROUND', 'WINDOWFRAME',
+            'WINDOWSFOLDER', 'WINDOWTEXT', 'YELLOW', 'YES', 'YESNO', 'YESNOCANCEL'
+            ),
+        2 => array(
+            'AndAlso', 'As', 'ADDHANDLER', 'ASSEMBLY', 'AUTO', 'Binary', 'ByRef', 'ByVal', 'BEGINEPILOGUE',
+            'Else', 'ElseIf', 'Empty', 'Error', 'ENDPROLOGUE', 'EXTERNALSOURCE', 'ENVIRON', 'For',
+            'Friend', 'GET', 'HANDLES', 'Input', 'Is', 'IsNot', 'Len', 'Lock', 'Me', 'Mid', 'MUSTINHERIT', 'MustOverride',
+            'MYBASE', 'MYCLASS', 'New', 'Next', 'Nothing', 'Null', 'NOTINHERITABLE',
+            'NOTOVERRIDABLE', 'OFF', 'On', 'Option', 'Optional', 'Overloads', 'OVERRIDABLE', 'Overrides', 'ParamArray',
+            'Print', 'Private', 'Property', 'Public', 'Resume', 'Return', 'Seek', 'Static', 'Step',
+            'String', 'SHELL', 'SENDKEYS', 'SET', 'Shared', 'Then', 'Time', 'To', 'THROW', 'WithEvents'
+            ),
+        3 => array(
+            'COLLECTION', 'DEBUG', 'DICTIONARY', 'DRIVE', 'DRIVES', 'ERR', 'FILE', 'FILES',
+            'FILESYSTEMOBJECT', 'FOLDER', 'FOLDERS', 'TEXTSTREAM'
+            ),
+        4 => array(
+            'BOOLEAN', 'BYTE', 'DATE', 'DECIMIAL', 'DOUBLE', 'INTEGER', 'LONG', 'OBJECT',
+            'SINGLE STRING'
+            ),
+        5 => array(
+            'ADDRESSOF', 'AND', 'BITAND', 'BITNOT', 'BITOR', 'BITXOR',
+            'GETTYPE', 'LIKE', 'MOD', 'NOT', 'ORXOR'
+            ),
+        6 => array(
+            'APPACTIVATE', 'BEEP', 'CALL', 'CHDIR', 'CHDRIVE', 'CLASS', 'CASE', 'CATCH', 'CONST',
+            'DECLARE', 'DELEGATE', 'DELETESETTING', 'DIM', 'DO', 'DOEVENTS', 'END', 'ENUM',
+            'EVENT', 'EXIT', 'EACH', 'FUNCTION', 'FINALLY', 'IF', 'IMPORTS', 'INHERITS',
+            'INTERFACE', 'IMPLEMENTS', 'KILL', 'LOOP', 'NAMESPACE', 'OPEN', 'PUT',
+            'RAISEEVENT', 'RANDOMIZE', 'REDIM', 'REM', 'RESET', 'SAVESETTING', 'SELECT',
+            'SETATTR', 'STOP', 'SUB', 'SYNCLOCK', 'STRUCTURE', 'SHADOWS', 'SWITCH',
+            'TRY', 'WIDTH', 'WITH', 'WRITE', 'WHILE'
+            ),
+        7 => array(
+            'ABS', 'ARRAY', 'ASC', 'ASCB', 'ASCW', 'CALLBYNAME', 'CBOOL', 'CBYTE', 'CCHAR',
+            'CCHR', 'CDATE', 'CDBL', 'CDEC', 'CHOOSE', 'CHR', 'CHR$', 'CHRB', 'CHRB$', 'CHRW',
+            'CINT', 'CLNG', 'CLNG8', 'CLOSE', 'COBJ', 'COMMAND', 'COMMAND$', 'CONVERSION',
+            'COS', 'CREATEOBJECT', 'CSHORT', 'CSTR', 'CURDIR', 'CTYPE', 'CVDATE', 'DATEADD',
+            'DATEDIFF', 'DATEPART', 'DATESERIAL', 'DATEVALUE', 'DAY', 'DDB', 'DIR', 'DIR$',
+            'EOF', 'ERROR$', 'EXP', 'FILEATTR', 'FILECOPY', 'FILEDATATIME', 'FILELEN', 'FILTER',
+            'FIX', 'FORMAT', 'FORMAT$', 'FORMATCURRENCY', 'FORMATDATETIME', 'FORMATNUMBER',
+            'FORMATPERCENT', 'FREEFILE', 'FV', 'GETALLSETTINGS', 'GETATTRGETOBJECT', 'GETSETTING',
+            'HEX', 'HEX$', 'HOUR', 'IIF', 'IMESTATUS', 'INPUT$', 'INPUTB', 'INPUTB$', 'INPUTBOX',
+            'INSTR', 'INSTRB', 'INSTRREV', 'INT', 'IPMT', 'IRR', 'ISARRAY', 'ISDATE', 'ISEMPTY',
+            'ISERROR', 'ISNULL', 'ISNUMERIC', 'ISOBJECT', 'JOIN', 'LBOUND', 'LCASE', 'LCASE$',
+            'LEFT', 'LEFT$', 'LEFTB', 'LEFTB$', 'LENB', 'LINEINPUT', 'LOC', 'LOF', 'LOG', 'LTRIM',
+            'LTRIM$', 'MID$', 'MIDB', 'MIDB$', 'MINUTE', 'MIRR', 'MKDIR', 'MONTH', 'MONTHNAME',
+            'MSGBOX', 'NOW', 'NPER', 'NPV', 'OCT', 'OCT$', 'PARTITION', 'PMT', 'PPMT', 'PV',
+            'RATE', 'REPLACE', 'RIGHT', 'RIGHT$', 'RIGHTB', 'RIGHTB$', 'RMDIR', 'RND', 'RTRIM',
+            'RTRIM$', 'SECOND', 'SIN', 'SLN', 'SPACE', 'SPACE$', 'SPC', 'SPLIT', 'SQRT', 'STR', 'STR$',
+            'STRCOMP', 'STRCONV', 'STRING$', 'STRREVERSE', 'SYD', 'TAB', 'TAN', 'TIMEOFDAY',
+            'TIMER', 'TIMESERIAL', 'TIMEVALUE', 'TODAY', 'TRIM', 'TRIM$', 'TYPENAME', 'UBOUND',
+            'UCASE', 'UCASE$', 'VAL', 'WEEKDAY', 'WEEKDAYNAME', 'YEAR'
+            ),
+        8 => array(
+            'ANY', 'ATN', 'CALENDAR', 'CIRCLE', 'CURRENCY', 'DEFBOOL', 'DEFBYTE', 'DEFCUR',
+            'DEFDATE', 'DEFDBL', 'DEFDEC', 'DEFINT', 'DEFLNG', 'DEFOBJ', 'DEFSNG', 'DEFSTR',
+            'DEFVAR', 'EQV', 'GOSUB', 'IMP', 'INITIALIZE', 'ISMISSING', 'LET', 'LINE', 'LSET',
+            'RSET', 'SGN', 'SQR', 'TERMINATE', 'VARIANT', 'VARTYPE', 'WEND'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '&', '&=', '*', '*=', '+', '+=', '-', '-=', '//', '/', '/=', '=', '\\', '\\=',
+        '^', '^='
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false,
+        6 => false,
+        7 => false,
+        8 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0600FF;',        //Constants
+            2 => 'color: #FF8000;',        //Keywords
+            3 => 'color: #008000;',        //Data Types
+            4 => 'color: #FF0000;',        //Objects
+            5 => 'color: #804040;',        //Operators
+            6 => 'color: #0600FF;',        //Statements
+            7 => 'color: #0600FF;',        //Functions
+            8 => 'color: #0600FF;'        //Deprecated
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008080; font-style: italic;',
+            'MULTI' => 'color: #008080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008080; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #808080;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #FF0000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #0000FF;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => 'http://www.google.com/search?q={FNAMEU}+site:msdn.microsoft.com',
+        4 => '',
+        5 => '',
+        6 => '',
+        7 => '',
+        8 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 =>'.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/verilog.php b/examples/includes/geshi/geshi/verilog.php
new file mode 100644 (file)
index 0000000..57d268e
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+/**
+ * verilog.php
+ * -----------
+ * Author: G�nter Dannoritzer <dannoritzer@web.de>
+ * Copyright: (C) 2008 Guenter Dannoritzer
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/05/28
+ *
+ * Verilog language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/29
+ *   -  added regular expression to find numbers of the form 4'b001xz
+ *   -  added regular expression to find values for `timescale command
+ *   -  extended macro keywords
+ *
+ * TODO (updated 2008/05/29)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Verilog',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'COMMENT_REGEXP' => array(1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        // keywords
+        1 => array('always', 'and', 'assign', 'begin', 'buf', 'bufif0', 'bufif1', 'case',
+            'casex', 'casez', 'cmos', 'deassign', 'default', 'defparam',
+            'disable', 'edge', 'else', 'end', 'endcase', 'endfunction',
+            'endmodule', 'endprimitive', 'endspecify', 'endtable', 'endtask',
+            'event', 'for', 'force', 'forever', 'function', 'highz0',
+            'highz1', 'if', 'ifnone', 'initial', 'inout', 'input', 'integer',
+            'join', 'large', 'macromodule', 'medium', 'module', 'nand',
+            'negedge', 'nmos', 'nor', 'not', 'notif0', 'notif1', 'or',
+            'output', 'parameter', 'pmos', 'posedge', 'primitive', 'pull0',
+            'pull1', 'pulldown', 'pullup', 'rcmos', 'real', 'realtime', 'reg',
+            'release', 'repeat', 'rnmos', 'rpmos', 'rtran', 'rtranif0',
+            'rtranif1', 'scalared', 'small', 'specify', 'specparam',
+            'strong0', 'strong1', 'supply0', 'supply1', 'table', 'task',
+            'time', 'tran', 'tranif0', 'tranif1', 'tri', 'tri0', 'tri1',
+            'triand', 'trior', 'trireg', 'vectored', 'wait', 'wand', 'weak0',
+            'weak1', 'while', 'wire', 'wor', 'xnor', 'xor'
+            ),
+        // system tasks
+        2 => array(
+            '$display', '$monitor',
+            '$dumpall', '$dumpfile', '$dumpflush', '$dumplimit', '$dumpoff',
+            '$dumpon', '$dumpvars',
+            '$fclose', '$fdisplay', '$fopen',
+            '$finish', '$fmonitor', '$fstrobe', '$fwrite',
+            '$fgetc', '$ungetc', '$fgets', '$fscanf', '$fread', '$ftell',
+            '$fseek', '$frewind', '$ferror', '$fflush', '$feof',
+            '$random',
+            '$readmemb', '$readmemh', '$readmemx',
+            '$signed', '$stime', '$stop',
+            '$strobe', '$time', '$unsigned', '$write'
+            ),
+        // macros
+        3 => array(
+            '`default-net', '`define',
+            '`celldefine', '`default_nettype', '`else', '`elsif', '`endcelldefine',
+            '`endif', '`ifdef', '`ifndef', '`include', '`line', '`nounconnected_drive',
+            '`resetall', '`timescale', '`unconnected_drive', '`undef'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%',
+        '^', '&', '|', '~',
+        '?', ':',
+        '#', '<<', '<<<',
+        '>', '<', '>=', '<=',
+        '@', ';', ','
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #A52A2A; font-weight: bold;',
+            2 => 'color: #9932CC;',
+            3 => 'color: #008800;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #00008B; font-style: italic;',
+            'MULTI' => 'color: #00008B; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #9F79EE'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #9F79EE;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #FF00FF;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff0055;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #202020;',
+            2 => 'color: #202020;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #5D478B;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #ff0055;',
+            1 => 'color: #ff0055;',
+            ),
+        'SCRIPT' => array(
+            0 => '',
+            1 => '',
+            2 => '',
+            3 => ''
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        1 => ''
+        ),
+    'REGEXPS' => array(
+        // numbers
+        0 => "\d'[bdh][0-9_a-fA-FxXzZ]+",
+        // time -> 1, 10, or 100; s, ms, us, ns, ps, of fs
+        1 => "1[0]{0,2}[munpf]?s"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        1 => ''
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        0 => true,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/vhdl.php b/examples/includes/geshi/geshi/vhdl.php
new file mode 100644 (file)
index 0000000..6fd537e
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * vhdl.php
+ * --------
+ * Author: Alexander 'E-Razor' Krause (admin@erazor-zone.de)
+ * Copyright: (c) 2005 Alexander Krause
+ * Release Version: 1.0.8.3
+ * Date Started: 2005/06/15
+ *
+ * VHDL (VHSICADL, very high speed integrated circuit HDL) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Added description of extra language features (SF#1970248)
+ *  -  Optimized regexp group 0 somewhat
+ * 2006/06/15 (1.0.0)
+ *  -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'VHDL',
+    'COMMENT_SINGLE' => array(1 => '--'),
+    'COMMENT_MULTI' => array('%' => '%'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /*keywords*/
+        1 => array(
+            'access','after','alias','all','assert','attribute','architecture','begin',
+            'block','body','buffer','bus','case','component','configuration','constant',
+            'disconnect','downto','else','elsif','end','entity','exit','file','for',
+            'function','generate','generic','group','guarded','if','impure','in',
+            'inertial','inout','is','label','library','linkage','literal','loop',
+            'map','new','next','null','of','on','open','others','out','package',
+            'port','postponed','procedure','process','pure','range','record','register',
+            'reject','report','return','select','severity','signal','shared','subtype',
+            'then','to','transport','type','unaffected','units','until','use','variable',
+            'wait','when','while','with','note','warning','error','failure','and',
+            'or','xor','not','nor','used','memory','segments','dff','dffe','help_id',
+            'mod','info','latch','rising_edge','falling_edge'
+        ),
+        /*types*/
+        2 => array(
+            'bit','bit_vector','character','boolean','integer','real','time','string',
+            'severity_level','positive','natural','signed','unsigned','line','text',
+            'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector','qsim_state',
+            'qsim_state_vector','qsim_12state','qsim_12state_vector','qsim_strength',
+            'mux_bit','mux_vector','reg_bit','reg_vector','wor_bit','wor_vector',
+            'work','ieee','std_logic_signed','std_logic_1164','std_logic_arith',
+            'numeric_std'
+
+        ),
+        /*operators*/
+    ),
+    'SYMBOLS' => array(
+        '[', ']', '(', ')',
+        ';',':',
+        '<','>','=','<=',':=','=>','=='
+    ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #000080; font-weight: bold;',
+            2 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000; font-style: italic;',
+            'MULTI' => 'color: #008000; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000066;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000066;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #ff0000;',
+            1 => 'color: #ff0000;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => ''
+    ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Hex numbers and scientific notation for numbers
+        0 => '(\b0x[0-9a-fA-F]+|\b\d[0-9a-fA-F]+[hH])|'.
+            '(\b\d+?(\.\d+?)?E[+\-]?\d+)|(\bns)|'.
+            "('[0-9a-zA-Z]+(?!'))",
+        //Number characters?
+        1 => "\b(''\d'')"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/vim.php b/examples/includes/geshi/geshi/vim.php
new file mode 100644 (file)
index 0000000..94927ea
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+
+/*************************************************************************************
+ * vim.php
+ * ----------------
+ * Author: Swaroop C H (swaroop@swaroopch.com)
+ * Copyright: (c) 2008 Swaroop C H (http://www.swaroopch.com)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/10/19
+ *
+ * Vim scripting language file for GeSHi.
+ *
+ * Reference: http://qbnz.com/highlighter/geshi-doc.html#language-files
+ * All keywords scraped from `:help expression-commands`.
+ * All method names scraped from `:help function-list`.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/19 (1.0.8.2)
+ * - Started.
+ *
+ * TODO (updated 2008/10/19)
+ * -------------------------
+ * - Fill out list of zillion commands
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+    'LANG_NAME' => 'Vim Script',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_REGEXP' => array(
+        1 => "/^\".*$/m"
+        ),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'brea', 'break', 'call', 'cat', 'catc',
+            'catch', 'con', 'cont', 'conti',
+            'contin', 'continu', 'continue', 'ec', 'echo',
+            'echoe', 'echoer', 'echoerr', 'echoh',
+            'echohl', 'echom', 'echoms', 'echomsg', 'echon',
+            'el', 'els', 'else', 'elsei', 'elseif',
+            'en', 'end', 'endi', 'endif', 'endfo',
+            'endfor', 'endt', 'endtr', 'endtry', 'endw',
+            'endwh', 'endwhi', 'endwhil', 'endwhile', 'exe', 'exec', 'execu',
+            'execut', 'execute', 'fina', 'final', 'finall', 'finally', 'for',
+            'fun', 'func', 'funct', 'functi', 'functio', 'function', 'if', 'in',
+            'let', 'lockv', 'lockva', 'lockvar', 'retu', 'retur', 'return', 'th',
+            'thr', 'thro', 'throw', 'try', 'unl', 'unle', 'unlet', 'unlo', 'unloc',
+            'unlock', 'unlockv', 'unlockva', 'unlockvar', 'wh', 'whi', 'whil',
+            'while'
+            ),
+        2 => array(
+            'autocmd', 'com', 'comm', 'comma', 'comman', 'command', 'comc',
+            'comcl', 'comcle', 'comclea', 'comclear', 'delc', 'delco',
+            'delcom', 'delcomm', 'delcomma', 'delcomman', 'delcommand',
+            '-nargs' # TODO There are zillions of commands to be added here from http://vimdoc.sourceforge.net/htmldoc/usr_toc.html
+            ),
+        3 => array(
+            'abs', 'add', 'append', 'argc', 'argidx', 'argv', 'atan',
+            'browse', 'browsedir', 'bufexists', 'buflisted', 'bufloaded',
+            'bufname', 'bufnr', 'bufwinnr', 'byte2line', 'byteidx',
+            'ceil', 'changenr', 'char2nr', 'cindent', 'clearmatches',
+            'col', 'complete', 'complete_add', 'complete_check', 'confirm',
+            'copy', 'cos', 'count', 'cscope_connection', 'cursor',
+            'deepcopy', 'delete', 'did_filetype', 'diff_filler',
+            'diff_hlID', 'empty', 'escape', 'eval', 'eventhandler',
+            'executable', 'exists', 'extend', 'expand', 'feedkeys',
+            'filereadable', 'filewritable', 'filter', 'finddir',
+            'findfile', 'float2nr', 'floor', 'fnameescape', 'fnamemodify',
+            'foldclosed', 'foldclosedend', 'foldlevel', 'foldtext',
+            'foldtextresult', 'foreground', 'garbagecollect',
+            'get', 'getbufline', 'getbufvar', 'getchar', 'getcharmod',
+            'getcmdline', 'getcmdpos', 'getcmdtype', 'getcwd', 'getfperm',
+            'getfsize', 'getfontname', 'getftime', 'getftype', 'getline',
+            'getloclist', 'getmatches', 'getpid', 'getpos', 'getqflist',
+            'getreg', 'getregtype', 'gettabwinvar', 'getwinposx',
+            'getwinposy', 'getwinvar', 'glob', 'globpath', 'has',
+            'has_key', 'haslocaldir', 'hasmapto', 'histadd', 'histdel',
+            'histget', 'histnr', 'hlexists', 'hlID', 'hostname', 'iconv',
+            'indent', 'index', 'input', 'inputdialog', 'inputlist',
+            'inputrestore', 'inputsave', 'inputsecret', 'insert',
+            'isdirectory', 'islocked', 'items', 'join', 'keys', 'len',
+            'libcall', 'libcallnr', 'line', 'line2byte', 'lispindent',
+            'localtime', 'log10', 'map', 'maparg', 'mapcheck', 'match',
+            'matchadd', 'matcharg', 'matchdelete', 'matchend', 'matchlist',
+            'matchstr', 'max', 'min', 'mkdir', 'mode', 'nextnonblank',
+            'nr2char', 'pathshorten', 'pow', 'prevnonblank', 'printf',
+            'pumvisible', 'range', 'readfile', 'reltime', 'reltimestr',
+            'remote_expr', 'remote_foreground', 'remote_peek',
+            'remote_read', 'remote_send', 'remove', 'rename', 'repeat',
+            'resolve', 'reverse', 'round', 'search', 'searchdecl',
+            'searchpair', 'searchpairpos', 'searchpos', 'server2client',
+            'serverlist', 'setbufvar', 'setcmdpos', 'setline',
+            'setloclist', 'setmatches', 'setpos', 'setqflist', 'setreg',
+            'settabwinvar', 'setwinvar', 'shellescape', 'simplify', 'sin',
+            'sort', 'soundfold', 'spellbadword', 'spellsuggest', 'split',
+            'sqrt', 'str2float', 'str2nr', 'strftime', 'stridx', 'string',
+            'strlen', 'strpart', 'strridx', 'strtrans', 'submatch',
+            'substitute', 'synID', 'synIDattr', 'synIDtrans', 'synstack',
+            'system', 'tabpagebuflist', 'tabpagenr', 'tabpagewinnr',
+            'taglist', 'tagfiles', 'tempname', 'tolower', 'toupper', 'tr',
+            'trunc', 'type', 'values', 'virtcol', 'visualmode', 'winbufnr',
+            'wincol', 'winheight', 'winline', 'winnr', 'winrestcmd',
+            'winrestview', 'winsaveview', 'winwidth', 'writefile'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '%', '&', '*', '|', '/', '<', '>',
+        '^', '-', '+', '~', '?', ':', '$', '@', '.'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'STYLES' => array(
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => ''
+            ),
+        'KEYWORDS' => array(
+            1 => 'color: #804040;',
+            2 => 'color: #668080;',
+            3 => 'color: #25BB4D;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #000000;',
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000; font-weight:bold;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'STRINGS' => array(
+            0 => 'color: #C5A22D;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;'
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false, //Save some time as OO identifiers aren't used
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(),
+    'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/visualfoxpro.php b/examples/includes/geshi/geshi/visualfoxpro.php
new file mode 100644 (file)
index 0000000..4592dd7
--- /dev/null
@@ -0,0 +1,456 @@
+<?php
+/*************************************************************************************
+ * visualfoxpro.php
+ * ----------------
+ * Author: Roberto Armellin (r.armellin@tin.it)
+ * Copyright: (c) 2004 Roberto Armellin, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/09/17
+ *
+ * Visual FoxPro language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *  -  Removed tab as a symbol char
+ * 2004/11/27 (1.0.1)
+ *  -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/10/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Visual Fox Pro',
+    'COMMENT_SINGLE' => array(1 => "//", 2 => "\n*"),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'Case', 'Else', '#Else', 'Then',
+            'Endcase', 'Enddefine', 'Enddo', 'Endfor', 'Endfunc', 'Endif', 'Endprintjob',
+            'Endproc', 'Endscan', 'Endtext', 'Endwith', '#Endif',
+            '#Elif','#Define','#If','#Include',
+            '#Itsexpression','#Readclauses','#Region','#Section','#Undef','#Wname',
+            'Define','Do',
+            'For','Function','Hidden',
+            'If','Local','Lparameter','Lparameters','Next','Otherwise',
+            'Parameters','Printjob','Procedure','Protected','Public','Scan',
+            'Text','While','With','Abs','Accept','Access','Aclass','Acopy',
+            'Acos','Adatabases','Adbobjects','Addbs','Addrelationtoenv','Addtabletoenv',
+            'Adel','Adir','Aelement','Aerror','Afields','Afont',
+            'Agetclass','Agetfileversion','Ains','Ainstance','Alen','Align',
+            'Alines','Alltrim','Alter','Amembers','Amouseobj','Anetresources',
+            'Ansitooem','Append','Aprinters','Ascan','Aselobj','Asin',
+            'Asort','Assert','Asserts','Assist','Asubscript','Asynchronous',
+            'At_c','Atan','Atc','Atcc','Atcline','Atline',
+            'Atn2','Aused','Autoform','Autoreport','Avcxclasses','Average',
+            'BarCount','BarPrompt','BatchMode','BatchUpdateCount','Begin','BellSound',
+            'BinToC','Bintoc','Bitand','Bitclear','Bitlshift','Bitnot',
+            'Bitor','Bitrshift','Bitset','Bittest','Bitxor','Bof',
+            'Browse','BrowseRefresh','Buffering','BuilderLock','COMArray','COMReturnError',
+            'CToBin','Calculate','Call','Capslock','Cd','Cdow',
+            'Ceiling','Central','Change','Char','Chdir','Chr',
+            'Chrsaw','Chrtran','Chrtranc','Close','Cmonth','Cntbar',
+            'Cntpad','Col','Comclassinfo','CommandTargetQuery','Compile','Completed',
+            'Compobj','Compute','Concat','ConnectBusy','ConnectHandle','ConnectName',
+            'ConnectString','ConnectTimeOut','ContainerReleaseType','Continue','Copy','Cos',
+            'Cot','Count','Coverage','Cpconvert','Cpcurrent','Cpdbf',
+            'Cpnotrans','Create','CreateBinary','Createobject','Createobjectex','Createoffline',
+            'CrsBuffering','CrsFetchMemo','CrsFetchSize','CrsMaxRows','CrsMethodUsed','CrsNumBatch',
+            'CrsShareConnection','CrsUseMemoSize','CrsWhereClause','Ctobin','Ctod','Ctot',
+            'Curdate','Curdir','CurrLeft','CurrSymbol','CursorGetProp','CursorSetProp',
+            'Curtime','Curval','DBGetProp','DBSetProp','DB_BufLockRow','DB_BufLockTable',
+            'DB_BufOff','DB_BufOptRow','DB_BufOptTable','DB_Complette','DB_DeleteInsert','DB_KeyAndModified',
+            'DB_KeyAndTimestamp','DB_KeyAndUpdatable','DB_LocalSQL','DB_NoPrompt','DB_Prompt','DB_RemoteSQL',
+            'DB_TransAuto','DB_TransManual','DB_TransNone','DB_Update','Datetime','Day',
+            'Dayname','Dayofmonth','Dayofweek','Dayofyear','Dbalias','Dbused',
+            'Ddeaborttrans','Ddeadvise','Ddeenabled','Ddeexecute','Ddeinitiate','Ddelasterror',
+            'Ddepoke','Dderequest','Ddesetoption','Ddesetservice','Ddesettopic','Ddeterminate',
+            'Debugout','Declare','DefOLELCid','DefaultValue','Defaultext','Degrees',
+            'DeleteTrigger','Desc','Description','Difference','Dimension','Dir',
+            'Directory','Diskspace','DispLogin','DispWarnings','Display','Dll',
+            'Dmy','DoDefault','DoEvents','Doc','Doevents','Dow',
+            'Drivetype','Drop','Dropoffline','Dtoc','Dtor','Dtos',
+            'Dtot','DynamicInputMask','Each','Edit','Eject','Elif',
+            'End','Eof','Erase','Evaluate','Event','Eventtracking',
+            'Exclude','Exclusive','Exit','Exp','Export','External',
+            'FDate','FTime','Fchsize','Fclose','Fcount','Fcreate',
+            'Feof','Ferror','FetchMemo','FetchSize','Fflush','Fgets',
+            'Filer','Filetostr','Find','Fklabel','Fkmax','Fldlist',
+            'Flock','Floor','Flush','Fontmetric','Fopen','Forceext',
+            'Forcepath','FormSetClass','FormSetLib','FormsClass','FormsLib','Found',
+            'FoxPro','Foxcode','Foxdoc','Foxgen','Foxgraph','Foxview',
+            'Fputs','Fread','French','Fseek','Fsize','Fv',
+            'Fwrite','Gather','German','GetPem','Getbar','Getcolor',
+            'Getcp','Getdir','Getenv','Getexpr','Getfile','Getfldstate',
+            'Getfont','Gethost','Getnextmodified','Getobject','Getpad','Getpict',
+            'Getprinter','Go','Gomonth','Goto','Graph','GridHorz',
+            'GridShow','GridShowPos','GridSnap','GridVert','Help','HelpOn',
+            'HelpTo','HighLightRow','Home','Hour','IMEStatus','IdleTimeOut',
+            'Idxcollate','Ifdef','Ifndef','Iif','Import','Include',
+            'Indbc','Index','Indexseek','Inkey','Inlist','Input',
+            'Insert','InsertTrigger','Insmode','IsBlank','IsFLocked','IsLeadByte',
+            'IsMouse','IsNull','IsRLocked','Isalpha','Iscolor','Isdigit',
+            'Isexclusive','Isflocked','Ishosted','Islower','Isreadonly','Isrlocked',
+            'Isupper','Italian','Japan','Join','Justdrive','Justext',
+            'Justfname','Justpath','Juststem','KeyField','KeyFieldList','Keyboard'
+            ),
+        2 => array('Keymatch','LastProject','Lastkey','Lcase','Leftc','Len',
+            'Lenc','Length','Likec','Lineno','LoadPicture','Loadpicture',
+            'Locate','Locfile','Log','Log10','Logout','Lookup',
+            'Loop','Lower','Ltrim','Lupdate','Mail','MaxRecords',
+            'Mcol','Md','Mdown','Mdx','Mdy','Memlines',
+            'Menu','Messagebox','Minute','Mkdir','Mline','Modify',
+            'Month','Monthname','Mouse','Mrkbar','Mrkpad','Mrow',
+            'Mtdll','Mton','Mwindow','Native','Ndx','Network',
+            'NoFilter','Nodefault','Normalize','Note','Now','Ntom',
+            'NullString','Numlock','Nvl','ODBChdbc','ODBChstmt','OLEDropTextInsertion',
+            'OLELCid','Objnum','Objref','Objtoclient','Objvar','Occurs',
+            'Oemtoansi','Oldval','OlePublic','Olereturnerror','On','Open',
+            'Oracle','Order','Os','Outer','PCount','Pack',
+            'PacketSize','Padc','Padl','Padr','Payment','Pcol',
+            'PemStatus','Pi','Pivot','Play','Pop','Popup',
+            'Power','PrimaryKey','Printstatus','Private','Prmbar','Prmpad',
+            'ProjectClick','Proper','Prow','Prtinfo','Push','Putfile',
+            'Pv','Qpr','Quater','QueryTimeOut','Quit','Radians',
+            'Rand','Rat','Ratc','Ratline','Rd','Rdlevel',
+            'Read','Readkey','Recall','Reccount','RecentlyUsedFiles','Recno',
+            'Recsize','Regional','Reindex','RelatedChild','RelatedTable','RelatedTag',
+            'Remove','Rename','Repeat','Replace','Replicate','Report',
+            'ResHeight','ResWidth','ResourceOn','ResourceTo','Resources','Restore',
+            'Resume','Retry','Return','Revertoffline','Rgbscheme','Rightc',
+            'Rlock','Rmdir','Rollback','Round','Rtod','Rtrim',
+            'RuleExpression','RuleText','Run','Runscript','Rview','SQLAsynchronous',
+            'SQLBatchMode','SQLCancel','SQLColumns','SQLConnect','SQLConnectTimeOut','SQLDisconnect',
+            'SQLDispLogin','SQLDispWarnings','SQLExec','SQLGetProp','SQLIdleTimeOut','SQLMoreResults',
+            'SQLPrepare','SQLQueryTimeOut','SQLSetProp','SQLTables','SQLTransactions','SQLWaitTime',
+            'Save','SavePicture','Savepicture','ScaleUnits','Scatter','Scols',
+            'Scroll','Sec','Second','Seek','Select','SendUpdates',
+            'Set','SetDefault','Setfldstate','Setup','ShareConnection','ShowOLEControls',
+            'ShowOLEInsertable','ShowVCXs','Sign','Sin','Size','SizeBox',
+            'Skpbar','Skppad','Sort','Soundex','SourceName','Sqlcommit',
+            'Sqll','Sqlrollback','Sqlstringconnect','Sqrt','Srows','StatusBar',
+            'Store','Str','Strconv','Strtofile','Strtran','Stuff',
+            'Stuffc','Substr','Substrc','Substring','Sum','Suspend',
+            'Sys','Sysmetric','TabOrdering','Table','TableRefresh','Tablerevert',
+            'Tableupdate','TagCount','TagNo','Tan','Target','This',
+            'Thisform','Thisformset','Timestamp','Timestampdiff','Total','Transactions',
+            'Transform','Trim','Truncate','Ttoc','Ttod','Txnlevel',
+            'Txtwidth','Type','Ucase','Undefine','Unlock','Unpack',
+            'Updatable','UpdatableFieldList','Update','UpdateName','UpdateNameList','UpdateTrigger',
+            'UpdateType','Updated','Upper','Upsizing','Usa','Use',
+            'UseMemoSize','Used','Val','Validate','Varread','Vartype',
+            'Version','VersionLanguage','Wait','WaitTime','Wborder','Wchild',
+            'Wcols','Week','Wexist','Wfont','WhereType','Windcmd',
+            'Windhelp','Windmemo','Windmenu','Windmodify','Windquery','Windscreen',
+            'Windsnip','Windstproc','WizardPrompt','Wlast','Wlcol','Wlrow',
+            'Wmaximum','Wminimum','Wontop','Woutput','Wparent','Wread',
+            'Wrows','Wtitle','Wvisible','Year','Zap','_Alignment',
+            '_Asciicols','_Asciirows','_Assist','_Beautify','_Box','_Browser',
+            '_Builder','_Calcmem','_Calcvalue','_Cliptext','_Converter','_Coverage',
+            '_Curobj','_Dblclick','_Diarydate','_Dos','_Foxdoc','_Foxgraph',
+            '_Gallery','_Gengraph','_Genhtml','_Genmenu','_Genpd','_Genscrn',
+            '_Genxtab','_Getexpr','_Include','_Indent','_Lmargin','_Mac',
+            '_Mbr_appnd','_Mbr_cpart','_Mbr_delet','_Mbr_font','_Mbr_goto','_Mbr_grid',
+            '_Mbr_link','_Mbr_mode','_Mbr_mvfld','_Mbr_mvprt','_Mbr_seek','_Mbr_sp100',
+            '_Mbr_sp200','_Mbr_szfld','_Mbrowse','_Mda_appnd','_Mda_avg','_Mda_brow',
+            '_Mda_calc','_Mda_copy','_Mda_count','_Mda_label','_Mda_pack','_Mda_reprt',
+            '_Mda_rindx','_Mda_setup','_Mda_sort','_Mda_sp100','_Mda_sp200','_Mda_sp300',
+            '_Mda_sum','_Mda_total','_Mdata','_Mdiary','_Med_clear','_Med_copy',
+            '_Med_cut','_Med_cvtst','_Med_find','_Med_finda','_Med_goto','_Med_insob',
+            '_Med_link','_Med_obj','_Med_paste','_Med_pref','_Med_pstlk','_Med_redo',
+            '_Med_repl','_Med_repla','_Med_slcta','_Med_sp100','_Med_sp200','_Med_sp300',
+            '_Med_sp400','_Med_sp500','_Med_undo','_Medit','_Mfi_clall','_Mfi_close',
+            '_Mfi_export','_Mfi_import','_Mfi_new','_Mfi_open','_Mfi_pgset','_Mfi_prevu',
+            '_Mfi_print','_Mfi_quit','_Mfi_revrt','_Mfi_savas','_Mfi_save','_Mfi_send',
+            '_Mfi_setup','_Mfi_sp100','_Mfi_sp200','_Mfi_sp300','_Mfi_sp400','_Mfile',
+            '_Mfiler','_Mfirst','_Mlabel','_Mlast','_Mline','_Mmacro',
+            '_Mmbldr','_Mpr_beaut','_Mpr_cancl','_Mpr_compl','_Mpr_do','_Mpr_docum',
+            '_Mpr_formwz','_Mpr_gener','_Mpr_graph','_Mpr_resum','_Mpr_sp100','_Mpr_sp200',
+            '_Mpr_sp300','_Mpr_suspend','_Mprog','_Mproj','_Mrc_appnd','_Mrc_chnge',
+            '_Mrc_cont','_Mrc_delet','_Mrc_goto','_Mrc_locat','_Mrc_recal','_Mrc_repl',
+            '_Mrc_seek','_Mrc_sp100','_Mrc_sp200','_Mrecord','_Mreport','_Mrqbe',
+            '_Mscreen','_Msm_data','_Msm_edit','_Msm_file','_Msm_format','_Msm_prog',
+            '_Msm_recrd','_Msm_systm','_Msm_text','_Msm_tools','_Msm_view','_Msm_windo',
+            '_Mst_about','_Mst_ascii','_Mst_calcu','_Mst_captr','_Mst_dbase','_Mst_diary',
+            '_Mst_filer','_Mst_help','_Mst_hphow','_Mst_hpsch','_Mst_macro','_Mst_office',
+            '_Mst_puzzl','_Mst_sp100','_Mst_sp200','_Mst_sp300','_Mst_specl','_Msysmenu',
+            '_Msystem','_Mtable','_Mtb_appnd','_Mtb_cpart','_Mtb_delet','_Mtb_delrc',
+            '_Mtb_goto','_Mtb_link','_Mtb_mvfld','_Mtb_mvprt','_Mtb_props','_Mtb_recal',
+            '_Mtb_sp100','_Mtb_sp200','_Mtb_sp300','_Mtb_sp400','_Mtb_szfld','_Mwi_arran',
+            '_Mwi_clear','_Mwi_cmd','_Mwi_color','_Mwi_debug','_Mwi_hide','_Mwi_hidea',
+            '_Mwi_min','_Mwi_move','_Mwi_rotat','_Mwi_showa','_Mwi_size','_Mwi_sp100',
+            '_Mwi_sp200','_Mwi_toolb','_Mwi_trace','_Mwi_view','_Mwi_zoom','_Mwindow',
+            '_Mwizards','_Mwz_all','_Mwz_form','_Mwz_foxdoc','_Mwz_import','_Mwz_label',
+            '_Mwz_mail','_Mwz_pivot','_Mwz_query','_Mwz_reprt','_Mwz_setup','_Mwz_table',
+            '_Mwz_upsizing','_Netware','_Oracle','_Padvance','_Pageno','_Pbpage',
+            '_Pcolno','_Pcopies','_Pdparms','_Pdriver','_Pdsetup','_Pecode',
+            '_Peject','_Pepage','_Pform','_Plength','_Plineno','_Ploffset',
+            '_Ppitch','_Pquality','_Pretext','_Pscode','_Pspacing','_Pwait',
+            '_Rmargin','_Runactivedoc','_Samples','_Screen','_Shell','_Spellchk',
+            '_Sqlserver','_Startup','_Tabs','_Tally','_Text','_Throttle',
+            '_Transport','_Triggerlevel','_Unix','_WebDevOnly','_WebMenu','_WebMsftHomePage',
+            '_WebVFPHomePage','_WebVfpOnlineSupport','_Windows','_Wizard','_Wrap','_scctext',
+            '_vfp','Additive','After','Again','Aindent','Alignright',
+            'All','Alt','Alternate','And','Ansi','Any',
+            'Aplabout','App','Array','As','Asc','Ascending',
+            'Ascii','At','Attributes','Automatic','Autosave','Avg',
+            'Bar','Before','Bell','Between','Bitmap','Blank',
+            'Blink','Blocksize','Border','Bottom','Brstatus','Bucket',
+            'Buffers','By','Candidate','Carry','Cascade','Catalog',
+            'Cdx','Center','Century','Cga','Character','Check',
+            'Classlib','Clock','Cnt','Codepage','Collate','Color',
+            'Com1','Com2','Command','Compact','Compatible','Compress',
+            'Confirm','Connection','Connections','Connstring','Console','Copies',
+            'Cpcompile','Cpdialog','Csv','Currency','Cycle','Databases',
+            'Datasource','Date','Db4','Dbc','Dbf','Dbmemo3',
+            'Debug','Decimals','Defaultsource','Deletetables','Delimited','Delimiters',
+            'Descending','Design','Development','Device','Dif','Disabled',
+            'Distinct','Dlls','Dohistory','Dos','Dosmem','Double',
+            'Driver','Duplex','Echo','Editwork','Ega25','Ega43',
+            'Ems','Ems64','Encrypt','Encryption','Environment','Escape',
+            'Events','Exact','Except','Exe','Exists','Expression',
+            'Extended','F','Fdow','Fetch','Field','Fields',
+            'File','Files','Fill','Fixed','Float','Foldconst',
+            'Font','Footer','Force','Foreign','Fox2x','Foxplus',
+            'Free','Freeze','From','Fullpath','Fw2','Fweek',
+            'Get','Gets','Global','Group','Grow','Halfheight',
+            'Having','Heading','Headings','Helpfilter','History','Hmemory',
+            'Hours','Id','In','Indexes','Information','Instruct',
+            'Int','Integer','Intensity','Intersect','Into','Is',
+            'Isometric','Key','Keycolumns','Keycomp','Keyset','Last',
+            'Ledit','Level','Library','Like','Linked','Lock',
+            'Logerrors','Long','Lpartition','Mac','Macdesktop','Machelp',
+            'Mackey','Macros','Mark','Master','Max','Maxmem',
+            'Mdi','Memlimit','Memory','Memos','Memowidth','Memvar',
+            'Menus','Messages','Middle','Min','Minimize','Minus',
+            'Mod','Modal','Module','Mono43','Movers','Multilocks',
+            'Mvarsiz','Mvcount','N','Near','Negotiate','Noalias',
+            'Noappend','Noclear','Noclose','Noconsole','Nocptrans','Nodata',
+            'Nodebug','Nodelete','Nodup','Noedit','Noeject','Noenvironment',
+            'Nofloat','Nofollow','Nogrow','Noinit','Nolgrid','Nolink',
+            'Nolock','Nomargin','Nomdi','Nomenu','Nominimize','Nomodify'
+            ),
+        3 => array('Nomouse','None','Nooptimize','Nooverwrite','Noprojecthook','Noprompt',
+            'Noread','Norefresh','Norequery','Norgrid','Norm','Normal',
+            'Nosave','Noshadow','Noshow','Nospace','Not','Notab',
+            'Notify','Noupdate','Novalidate','Noverify','Nowait','Nowindow',
+            'Nowrap','Nozoom','Npv','Null','Number','Objects',
+            'Odometer','Of','Off','Oleobjects','Only','Optimize',
+            'Or','Orientation','Output','Outshow','Overlay','Overwrite',
+            'Pad','Palette','Paperlength','Papersize','Paperwidth','Password',
+            'Path','Pattern','Pause','Pdox','Pdsetup','Pen',
+            'Pfs','Pixels','Plain','Popups','Precision','Preference',
+            'Preview','Primary','Printer','Printquality','Procedures','Production',
+            'Program','Progwork','Project','Prompt','Query','Random',
+            'Range','Readborder','Readerror','Record','Recover','Redit',
+            'Reference','References','Relative','Remote','Reprocess','Resource',
+            'Rest','Restrict','Rgb','Right','Row','Rowset',
+            'Rpd','Runtime','Safety','Same','Sample','Say',
+            'Scale','Scheme','Scoreboard','Screen','Sdf','Seconds',
+            'Selection','Shadows','Shared','Sheet','Shell','Shift',
+            'Shutdown','Single','Some','Sortwork','Space','Sql',
+            'Standalone','Status','Std','Step','Sticky','String',
+            'Structure','Subclass','Summary','Sylk','Sysformats','Sysmenus',
+            'System','T','Tab','Tables','Talk','Tedit',
+            'Textmerge','Time','Timeout','Titles','Tmpfiles','To',
+            'Topic','Transaction','Trap','Trbetween','Trigger','Ttoption',
+            'Typeahead','Udfparms','Union','Unique','Userid','Users',
+            'Values','Var','Verb','Vga25','Vga50','Views',
+            'Volume','Where','Windows','Wk1','Wk3','Wks',
+            'Workarea','Wp','Wr1','Wrap','Wrk','Xcmdfile',
+            'Xl5','Xl8','Xls','Y','Yresolution','Zoom',
+            'Activate','ActivateCell','Add','AddColumn','AddItem','AddListItem',
+            'AddObject','AddProperty','AddToSCC','AfterBuild','AfterCloseTables','AfterDock',
+            'AfterRowColChange','BeforeBuild','BeforeDock','BeforeOpenTables','BeforeRowColChange','Box',
+            'Build','CheckIn','CheckOut','Circle','Clear','ClearData',
+            'Cleanup','Click','CloneObject','CloseEditor','CloseTables','Cls',
+            'CommandTargetExec','CommandTargetQueryStas','ContainerRelease','DataToClip','DblClick','Deactivate',
+            'Delete','DeleteColumn','Deleted','Destroy','DoCmd','Dock',
+            'DoScroll','DoVerb','DownClick','Drag','DragDrop','DragOver',
+            'DropDown','Draw','EnterFocus','Error','ErrorMessage','Eval',
+            'ExitFocus','FormatChange','GetData','GetFormat','GetLatestVersion','GoBack',
+            'GotFocus','GoForward','GridHitTest','Hide','HideDoc','IndexToItemId',
+            'Init','InteractiveChange','Item','ItemIdToIndex','KeyPress','Line',
+            'Load','LostFocus','Message','MiddleClick','MouseDown','MouseMove',
+            'MouseUp','MouseWheel','Move','Moved','NavigateTo','Newobject',
+            'OLECompleteDrag','OLEDrag','OLEDragDrop','OLEDragOver','OLEGiveFeedback','OLESetData',
+            'OLEStartDrag','OpenEditor','OpenTables','Paint','Point','Print',
+            'ProgrammaticChange','PSet','QueryAddFile','QueryModifyFile','QueryRemoveFile','QueryRunFile',
+            'QueryUnload','RangeHigh','RangeLow','ReadActivate','ReadExpression','ReadDeactivate',
+            'ReadMethod','ReadShow','ReadValid','ReadWhen','Refresh','Release',
+            'RemoveFromSCC','RemoveItem','RemoveListItem','RemoveObject','Requery','RequestData',
+            'Reset','ResetToDefault','Resize','RightClick','SaveAs','SaveAsClass',
+            'Scrolled','SetAll','SetData','SetFocus','SetFormat','SetMain',
+            'SetVar','SetViewPort','ShowDoc','ShowWhatsThis','TextHeight','TextWidth',
+            'Timer','UIEnable','UnDock','UndoCheckOut','Unload','UpClick',
+            'Valid','WhatsThisMode','When','WriteExpression','WriteMethod','ZOrder',
+            'ATGetColors','ATListColors','Accelerate','ActiveColumn','ActiveControl','ActiveForm',
+            'ActiveObjectId','ActivePage','ActiveProject','ActiveRow','AddLineFeeds','Alias',
+            'Alignment','AllowAddNew','AllowHeaderSizing','AllowResize','AllowRowSizing','AllowTabs',
+            'AlwaysOnTop','Application','AutoActivate','AutoCenter','AutoCloseTables','AutoIncrement',
+            'AutoOpenTables','AutoRelease','AutoSize','AutoVerbMenu','AutoYield','AvailNum',
+            'BackColor','BackStyle','BaseClass','BorderColor','BorderStyle','BorderWidth',
+            'Bound','BoundColumn','BoundTo','BrowseAlignment','BrowseCellMarg','BrowseDestWidth',
+            'BufferMode','BufferModeOverride','BuildDateTime','ButtonCount','ButtonIndex','Buttons',
+            'CLSID','CanAccelerate','CanGetFocus','CanLoseFocus','Cancel','Caption',
+            'ChildAlias','ChildOrder','Class','ClassLibrary','ClipControls','ClipRect',
+            'Closable','ColorScheme','ColorSource','ColumnCount','ColumnHeaders','ColumnLines',
+            'ColumnOrder','ColumnWidths','Columns','Comment','ContinuousScroll','ControlBox',
+            'ControlCount','ControlIndex','ControlSource','Controls','CurrentControl','CurrentX',
+            'CurrentY','CursorSource','Curvature','DataSession','DataSessionId','DataSourceObj',
+            'DataType','Database','DateFormat','DateMark','DefButton','DefButtonOrig',
+            'DefHeight','DefLeft','DefTop','DefWidth','Default','DefaultFilePath',
+            'DefineWindows','DeleteMark','Desktop','Dirty','DisabledBackColor','DisabledByEOF',
+            'DisabledForeColor','DisabledItemBackColor','DisabledItemForeColor','DisabledPicture','DispPageHeight','DispPageWidth',
+            'DisplayCount','DisplayValue','DoCreate','DockPosition','Docked','DocumentFile',
+            'DownPicture','DragIcon','DragMode','DragState','DrawMode','DrawStyle',
+            'DrawWidth','DynamicAlignment','DynamicBackColor','DynamicCurrentControl','DynamicFontBold','DynamicFontItalic',
+            'DynamicFontName','DynamicFontOutline','DynamicFontShadow','DynamicFontSize','DynamicFontStrikethru','DynamicFontUnderline',
+            'DynamicForeColor','EditFlags','Enabled','EnabledByReadLock','Encrypted','EnvLevel',
+            'ErasePage','FileClass','FileClassLibrary','FillColor','FillStyle','Filter',
+            'FirstElement','FontBold','FontItalic','FontName','FontOutline','FontShadow',
+            'FontSize','FontStrikethru','FontUnderline','ForceFocus','ForeColor','FormCount',
+            'FormIndex','FormPageCount','FormPageIndex','Format','Forms','FoxFont',
+            'FullName','GoFirst','GoLast','GridLineColor','GridLineWidth','GridLines'
+            ),
+        4 => array('HPROJ','HWnd','HalfHeightCaption','HasClip','HeaderGap','HeaderHeight',
+            'Height','HelpContextID','HideSelection','Highlight','HomeDir','HostName',
+            'HotKey','HscrollSmallChange','IMEMode','Icon','IgnoreInsert','InResize',
+            'Increment','IncrementalSearch','InitialSelectedAlias','InputMask','Instancing','IntegralHeight',
+            'Interval','ItemBackColor','ItemData','ItemForeColor','ItemIDData','ItemTips',
+            'JustReadLocked','KeyPreview','KeyboardHighValue','KeyboardLowValue','LastModified','Left',
+            'LeftColumn','LineSlant','LinkMaster','List','ListCount','ListIndex',
+            'ListItem','ListItemId','LockDataSource','LockScreen','MDIForm','MainClass',
+            'MainFile','Margin','MaxButton','MaxHeight','MaxLeft','MaxLength',
+            'MaxTop','MaxWidth','MemoWindow','MinButton','MinHeight','MinWidth',
+            'MouseIcon','MousePointer','Movable','MoverBars','MultiSelect','Name',
+            'NapTime','NewIndex','NewItemId','NoDataOnLoad','NoDefine','NotifyContainer',
+            'NullDisplay','NumberOfElements','OLEDragMode','OLEDragPicture','OLEDropEffects','OLEDropHasData',
+            'OLEDropMode','OLERequestPendingTimeOut','OLEServerBusyRaiseError','OLEServerBusyTimeOut','OLETypeAllowed','OleClass',
+            'OleClassId','OleControlContainer','OleIDispInValue','OleIDispOutValue','OleIDispatchIncoming','OleIDispatchOutgoing',
+            'OnResize','OneToMany','OpenViews','OpenWindow','PageCount','PageHeight',
+            'PageOrder','PageWidth','Pages','Panel','PanelLink','Parent',
+            'ParentAlias','ParentClass','Partition','PasswordChar','Picture','ProcessID',
+            'ProgID','ProjectHookClass','ProjectHookLibrary','Projects','ReadColors','ReadCycle',
+            'ReadFiller','ReadLock','ReadMouse','ReadOnly','ReadSave','ReadSize',
+            'ReadTimeout','RecordMark','RecordSource','RecordSourceType','Rect','RelationalExpr',
+            'RelativeColumn','RelativeRow','ReleaseErase','ReleaseType','ReleaseWindows','Resizable',
+            'RightToLeft','RowHeight','RowSource','RowSourceType','SCCProvider','SCCStatus',
+            'SDIForm','ScaleMode','ScrollBars','SelLength','SelStart','SelText',
+            'SelectOnEntry','Selected','SelectedBackColor','SelectedForeColor','SelectedID','SelectedItemBackColor',
+            'SelectedItemForeColor','SelfEdit','ServerClass','ServerClassLibrary','ServerHelpFile','ServerName',
+            'ServerProject','ShowTips','ShowWindow','Sizable','Size<height>','Size<maxlength>',
+            'Size<width>','Skip','SkipForm','Sorted','SourceType','Sparse',
+            'SpecialEffect','SpinnerHighValue','SpinnerLowValue','SplitBar','StartMode','StatusBarText',
+            'Stretch','StrictDateEntry','Style','SystemRefCount','TabIndex','TabStop',
+            'TabStretch','TabStyle','Tabhit','Tabs','Tag','TerminateRead',
+            'ThreadID','TitleBar','ToolTipText','Top','TopIndex','TopItemId',
+            'TypeLibCLSID','TypeLibDesc','TypeLibName','UnlockDataSource','Value','ValueDirty',
+            'VersionComments','VersionCompany','VersionCopyright','VersionDescription','VersionNumber','VersionProduct',
+            'VersionTrademarks','View','ViewPortHeight','ViewPortLeft','ViewPortTop','ViewPortWidth',
+            'Visible','VscrollSmallChange','WasActive','WasOpen','WhatsThisButton','WhatsThisHelp',
+            'WhatsThisHelpID','Width','WindowList','WindowNTIList','WindowState','WindowType',
+            'WordWrap','ZOrderSet','ActiveDoc','Checkbox','Column','ComboBox',
+            'CommandButton','CommandGroup','Container','Control','Cursor','Custom',
+            'DataEnvironment','EditBox','Empty','FontClass','Form','Formset',
+            'General','Grid','Header','HyperLink','Image','Label',
+            'ListBox','Memo','OleBaseControl','OleBoundControl','OleClassIDispOut','OleControl',
+            'OptionButton','OptionGroup','Page','PageFrame','ProjectHook','RectClass',
+            'Relation','Session','Shape','Spinner','TextBox' ,'Toolbar'
+            ),
+        ),
+    'SYMBOLS' => array(
+        "!", "@", "$", "%",
+        "(", ")", "{", "}", "[", "]",
+        "-", "+", "*", "/",
+        "=", "<", ">",
+        ":", ";", ",", ".", "&",
+        "?", "??", "???"
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: blue;',
+            2 => 'color: blue;',
+            3 => 'color: blue;',
+            4 => 'color: blue;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: green; font-style: italic;',
+            2 => 'color: green; font-style: italic;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: blue;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: blue;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/visualprolog.php b/examples/includes/geshi/geshi/visualprolog.php
new file mode 100644 (file)
index 0000000..2a5656b
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+/*************************************************************************************
+ * visualprolog.php
+ * ----------
+ * Author: Thomas Linder Puls (puls@pdc.dk)
+ * Copyright: (c) 2008 Thomas Linder Puls (puls@pdc.dk)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/11/20
+ *
+ * Visual Prolog language file for GeSHi.
+ *
+ * CHANGES
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Visual Prolog',
+    'COMMENT_SINGLE' => array(1 => '%'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'HARDQUOTE' => array('@"', '"'),
+    'HARDESCAPE' => array('""'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array(
+            'clauses','constants','constructors','delegate','domains','facts',
+            'goal','guards','inherits','monitor','namespace','open',
+            'predicates','properties','resolve','supports'
+            ),
+        2 => array(
+            'align','and','anyflow','as','bitsize','catch','determ','digits',
+            'div','do','else','elseif','erroneous','externally','failure',
+            'finally','from','language','mod','multi','nondeterm','or',
+            'procedure','quot','rem','single','then','to'
+            ),
+        3 => array(
+            '#bininclude','#else','#elseif','#endif','#error','#export',
+            '#externally','#if','#import','#include','#message','#options',
+            '#orrequires','#requires','#then','#warning'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '+', '-', '*', '?', '=', '/', '>', '<', '^', '!', ':', '(', ')', '{', '}', '[', ']'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => true,
+        1 => true,
+        2 => true,
+        3 => true
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #808000;',
+            2 => 'color: #333399;',
+            3 => 'color: #800080;',
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #AA77BD',
+            'MULTI' => 'color: #AA77BD'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #008080;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #00B7B7;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #0000FF;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #000000;'
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #008000;',
+            1 => 'color: #808000;',
+            2 => 'color: #333399;',
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => ':',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        0 => "(?<![a-zA-Z0-9_])(?!(?:PIPE|SEMI)>)[A-Z_]\w*(?!\w)",
+        1 => "\\b(end\\s+)?(implement|class|interface)\\b",
+        2 => "\\b(end\\s+)?(foreach|if|try)\\b",
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/whitespace.php b/examples/includes/geshi/geshi/whitespace.php
new file mode 100644 (file)
index 0000000..dfada78
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/*************************************************************************************
+ * whitespace.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2009/10/31
+ *
+ * Whitespace language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ *   -  First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+$language_data = array (
+    'LANG_NAME' => 'Whitespace',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'COMMENT_REGEXP' => array(
+        3 => "/[^\n\x20\x09]+/s"
+        ),
+    'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+    'QUOTEMARKS' => array(),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            ),
+        'COMMENTS' => array(
+            3 => 'color: #666666; font-style: italic;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'SCRIPT' => array(
+            ),
+        'REGEXPS' => array(
+            2 => 'background-color: #FF9999;',
+            3 => 'background-color: #9999FF;'
+            )
+        ),
+    'URLS' => array(
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        2 => array(
+            GESHI_SEARCH => "(?<!\\A)\x20",
+            GESHI_REPLACE => "&#32;",
+            GESHI_MODIFIERS => 's',
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        3 => array(
+            GESHI_SEARCH => "\x09",
+            GESHI_REPLACE => "&#9;",
+            GESHI_MODIFIERS => 's',
+            GESHI_BEFORE => "",
+            GESHI_AFTER => ""
+            ),
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4,
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'KEYWORDS' => GESHI_NEVER,
+            'SYMBOLS' => GESHI_NEVER,
+            'STRINGS' => GESHI_NEVER,
+//            'REGEXPS' => GESHI_NEVER,
+            'NUMBERS' => GESHI_NEVER
+            )
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/winbatch.php b/examples/includes/geshi/geshi/winbatch.php
new file mode 100644 (file)
index 0000000..caa94a4
--- /dev/null
@@ -0,0 +1,369 @@
+<?php
+/*************************************************************************************
+ * winbatch.php
+ * ------------
+ * Author: Craig Storey (storey.craig@gmail.com)
+ * Copyright: (c) 2004 Craig Storey (craig.xcottawa.ca)
+ * Release Version: 1.0.8.3
+ * Date Started: 2006/05/19
+ *
+ * WinBatch language file for GeSHi.
+ *
+ * WinBatch is a Windows scripting language - www.winbatch.com.
+ * The keywords were pulled from the winbatch/system/WIL.clr file for v2005G.
+ * Not all extender functions are added, but a very large set of the most common.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2006/05/05 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * - Right now any ':Subroutine' is treated as a comment. This highlights the
+ *   Subroutine's name, but it's not a perfect fix. I should use a RegEx in
+ *   GeSHI_Search&Replace features..
+ * - Update the list of extender functions.
+ * - Use a regular expression to comment UDFs that start with 'udf_'.
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Winbatch',
+    'COMMENT_SINGLE' => array(1 => ';', 2 => ':'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"', '`'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        1 => array(
+            'While', 'To', 'Then', 'Switch', 'Select', 'Return', 'Next', 'IntControl', 'Include', 'In', 'If',
+            'Goto', 'GoSub', 'ForEach', 'For', 'Exit', 'Execute', 'ErrorMode', 'EndWhile', 'EndSwitch', '#EndSubRoutine',
+            'EndSelect', 'EndIf', '#EEndFunction', 'EndFor', 'End', 'Else', 'DropWild', 'Drop', '#DefineSubRoutine',
+            '#DefineFunction', 'Debug', 'Continue', 'Case', 'CallExt', 'Call', 'By', 'BreakPoint', 'Break'
+            ),
+        2 => array(
+            'ZOOMED', 'YES', 'WORD4', 'WORD2', 'WORD1', 'WHOLESECTION', 'WAIT', 'UNSORTED', 'UNCHECK', 'TRUE', 'TILE',
+            'TAB', 'STRING', 'STACK', 'SPC2NET', 'SORTED', 'SOK', 'SNET2PC', 'SINGLE', 'SHIFT', 'SERVER', 'SERRWINSOCK',
+            'SERRVOICE', 'SERRSOCKET', 'SERRSERVICE', 'SERRSELECT', 'SERRPARAM', 'SERROUTOFMEM', 'SERRNOTFOUND', 'SERRNOCONN',
+            'SERRNOANSWER', 'SERRMUSTWAIT', 'SERRIPADDR', 'SERRHOSTNAME', 'SERRFAILURE', 'SERRBUSY', 'SCROLLLOCK', 'SCANCEL',
+            'SAVE', 'SALREADY', 'ROWS', 'REGUSERS', 'REGROOT', 'REGMACHINE', 'REGCURRENT', 'REGCLASSES', 'RDBLCLICK', 'RCLICK',
+            'RBUTTON', 'RAD2DEG', 'QSUCCESSINFO', 'QSUCCESS', 'QSTILLEX', 'QROLLBACK', 'QNULL', 'QNODATA', 'QNEXT', 'QNEEDDATA',
+            'QFIRST', 'QCOMMIT', 'QBADHANDLE', 'PRINTER', 'PLANCKJOULES', 'PLANCKERGS', 'PI', 'PARSEONLY', 'PARSEC', 'P3ERRREPLY',
+            'OPEN', 'ON', 'OFF', 'NUMLOCK', 'NOWAIT', 'NOTIFY', 'NORMAL', 'NORESIZE', 'NONE', 'NO', 'NCSAFORMAT', 'MULTIPLE',
+            'MSFORMAT', 'MPLAYRDBLCK', 'MPLAYRCLK', 'MPLAYRBUTTON', 'MPLAYMDBLCK', 'MPLAYMCLK', 'MPLAYMBUTTON', 'MPLAYLDBLCK',
+            'MPLAYLCLK', 'MPLAYLBUTTON', 'MINOR', 'MDBLCLICK', 'MCLICK', 'MBYESNO', 'MBUTTON', 'MBOKCANCEL', 'MAJOR', 'MAGFIELD',
+            'LOCALGROUP', 'LIGHTMTPS', 'LIGHTMPS', 'LF', 'LDBLCLICK', 'LCLICK', 'LBUTTON', 'LAFFDBERROR', 'ICON', 'HTTPS', 'HTTP',
+            'HNOHEADER', 'HMETHODPOST', 'HMETHODGET', 'HIDDEN', 'HHEADERONLY', 'HHEADER', 'GRAVITATION', 'GOPHER', 'GOLDENRATIO',
+            'GMTSEC', 'GLOBALGROUP', 'GFTSEC', 'GETPROCID', 'GETEXITCODE', 'FWDSCAN', 'FTPPASSIVE', 'FTP', 'FLOAT8', 'FARADAY',
+            'FALSE', 'EXTENDED', 'EULERS', 'ENABLE', 'ELECTRIC', 'DRIVE', 'DISABLE', 'DESCENDING', 'DEG2RAD', 'DEFAULT', 'CTRL',
+            'CRLF', 'CR', 'COMMONFORMAT', 'COLUMNS', 'CHECK', 'CAPSLOCK', 'CANCEL', 'BOLTZMANN', 'BACKSCAN', 'AVOGADRO', 'ATTR_X',
+            'ATTR_T', 'ATTR_SY', 'ATTR_SH', 'ATTR_RO', 'ATTR_RI', 'ATTR_P', 'ATTR_IC', 'ATTR_H', 'ATTR_DM', 'ATTR_DI', 'ATTR_DC',
+            'ATTR_CI', 'ATTR_A', 'ASCENDING', 'ARRANGE', 'AMC', 'ACC_WRITE', 'ACC_READ_NT', 'ACC_READ_95', 'ACC_READ', 'ACC_PRINT_NT',
+            'ACC_PMANG_NT', 'ACC_PFULL_NT', 'ACC_LIST', 'ACC_FULL_NT', 'ACC_FULL_95', 'ACC_DELETE', 'ACC_CREATE', 'ACC_CONTROL',
+            'ACC_CHNG_NT', 'ACC_ATTRIB', 'ABOVEICONS'
+            ),
+        3 => array(
+            'Yields', 'Yield', 'WinZoom', 'WinWaitExist', 'WinWaitClose', 'WinWaitChild', 'WinVersion', 'WinTitle', 'WinSysInfo',
+            'WinState', 'WinShow', 'WinResources', 'WinPositionChild', 'WinPosition', 'WinPlaceSet', 'WinPlaceGet', 'WinPlaceChild',
+            'WinPlace', 'WinParmSet', 'WinParmGet', 'WinName', 'WinMetrics', 'WinItemProcId', 'WinItemNameId', 'WinItemizeEx',
+            'WinItemize', 'WinItemChild', 'WinIsDos', 'WinIdGet', 'WinIconize', 'WinHide', 'WinHelp', 'WinGetactive', 'WinExistchild',
+            'WinExist', 'WinExename', 'WinConfig', 'WinClosenot', 'WinClose', 'WinArrange', 'WinActivechild', 'WinActivchild',
+            'WinActivate', 'WebVerifyCard', 'WebSetTimeout', 'WebParamSize', 'WebParamNames', 'WebParamFile', 'WebParamData',
+            'WebParamBuf', 'WebOutFile', 'WebOutBinary', 'WebOut', 'WebDumpError', 'WebDatData', 'WebCounter', 'WebConSize', 'WebConData',
+            'WebConBuf', 'WebCmdData', 'WebBaseConv', 'Wallpaper', 'WaitForKeyEX', 'WaitForKey', 'VersionDLL', 'Version', 'VarType',
+            'TimeYmdHms', 'TimeWait', 'TimeSubtract', 'TimeJulToYmd', 'TimeJulianDay', 'TimeDiffSecs', 'TimeDiffDays', 'TimeDiff', 'TimeDelay',
+            'TimeDate', 'TimeAdd', 'TextSelect', 'TextBoxSort', 'TextBox', 'Terminate', 'Tanh', 'Tan', 'SysParamInfo', 'SvcWaitForCmd',
+            'SvcSetState', 'SvcSetAccept', 'StrUpper', 'StrTrim', 'StrSubWild', 'StrSub', 'StrScan', 'StrReplace', 'StrLower', 'StrLenWild',
+            'StrLen', 'StrIndexWild', 'StrIndexNC', 'StrIndex', 'StriCmp', 'StrFixLeft', 'StrFixCharsL', 'StrFixChars', 'StrFix', 'StrFill',
+            'StrCnt', 'StrCmp', 'StrClean', 'StrCharCount', 'StrCat', 'StrByteCount', 'Sqrt', 'SoundVolume', 'Sounds', 'Snapshot', 'Sinh', 'Sin',
+            'ShortCutMake', 'ShortCutInfo', 'ShortCutExtra', 'ShortCutEdit', 'ShortCutDir', 'ShellExecute', 'SendMenusToEx', 'SendMenusTo',
+            'SendKeysTo', 'SendKeysChild', 'SendKey', 'RunZoomWait', 'RunZoom', 'RunWithLogon', 'RunWait', 'RunShell', 'RunIconWait',
+            'RunIcon', 'RunHideWait', 'RunHide', 'RunExit', 'RunEnviron', 'Run', 'RtStatus', 'Reload', 'RegUnloadHive', 'RegSetValue',
+            'RegSetQword', 'RegSetMulSz', 'RegSetExpSz', 'RegSetEx', 'RegSetDword', 'RegSetBin', 'RegQueryValue', 'RegQueryStr',
+            'RegQueryQword', 'RegQueryMulSz', 'RegQueryKeys', 'RegQueryKeyLastWriteTime', 'RegQueryKey', 'RegQueryItem', 'RegQueryExpSz',
+            'RegQueryEx', 'RegQueryDword', 'RegQueryBin', 'RegOpenKeyEx', 'RegOpenKey', 'RegOpenFlags', 'RegLoadHive', 'RegExistValue',
+            'RegExistKey', 'RegEntryType', 'RegDelValue', 'RegDeleteKey', 'RegCreateKey', 'RegConnect', 'RegCloseKey', 'RegApp', 'Random',
+            'PtrPersistent', 'PtrGlobalDefine', 'PtrGlobal', 'Print', 'PlayWaveform', 'PlayMidi', 'PlayMedia', 'PipeServerWrite', 'PipeServerRead',
+            'PipeServerCreate', 'PipeServerClose', 'PipeInfo', 'PipeClientSendRecvData', 'PipeClientOpen', 'PipeClientClose', 'Pause',
+            'ParseData', 'ObjectTypeGet', 'ObjectType', 'ObjectOpen', 'ObjectGet', 'ObjectEventRemove', 'objecteventremove', 'ObjectEventAdd',
+            'objecteventadd', 'ObjectCreate', 'ObjectConstToArray', 'ObjectConstantsGet', 'ObjectCollectionOpen', 'ObjectCollectionNext',
+            'ObjectCollectionClose', 'ObjectClose', 'ObjectAccess', 'Num2Char', 'NetInfo', 'MsgTextGet', 'MousePlay', 'MouseMove', 'MouseInfo',
+            'MouseDrag', 'MouseCoords', 'MouseClickBtn', 'MouseClick', 'mod', 'Min', 'Message', 'Max', 'Loge', 'LogDisk', 'Log10', 'LastError',
+            'KeyToggleSet', 'KeyToggleGet', 'ItemSortNc', 'ItemSort', 'ItemSelect', 'ItemReplace', 'ItemRemove', 'ItemLocate', 'ItemInsert',
+            'ItemExtractCSV', 'ItemExtract', 'ItemCountCSV', 'ItemCount', 'IsNumber', 'IsLicensed', 'IsKeyDown', 'IsInt', 'IsFloat', 'IsDefined',
+            'Int', 'InstallFile', 'IniWritePvt', 'IniWrite', 'IniReadPvt', 'IniRead', 'IniItemizePvt', 'IniItemize', 'IniDeletePvt', 'IniDelete',
+            'IgnoreInput', 'IconReplace', 'IconInfo', 'IconExtract', 'IconArrange', 'GetTickCount', 'GetObject', 'GetExactTime', 'Floor',
+            'FindWindow', 'FileYmdHms', 'FileWrite', 'FileVerInfo', 'FileTimeTouch', 'FileTimeSetEx', 'FileTimeSet', 'FileTimeGetEx',
+            'FileTimeGet', 'FileTimeCode', 'FileSizeEx', 'FileSize', 'FileRoot', 'FileRename', 'FileRead', 'FilePutW', 'FilePut', 'FilePath',
+            'FileOpen', 'FileNameShort', 'FileNameLong', 'FileNameEval2', 'FileNameEval1', 'FileMoveAttr', 'FileMove', 'FileMapName',
+            'FileLocate', 'FileItemPath', 'FileItemize', 'FileInfoToArray', 'FileGetW', 'FileGet', 'FileFullname', 'FileExtension', 'FileExist',
+            'FileDelete', 'FileCreateTemp', 'FileCopyAttr', 'FileCopy', 'FileCompare', 'FileClose', 'FileBaseName', 'FileAttrSetEx',
+            'FileAttrSet', 'FileAttrGetEx', 'FileAttrGet', 'FileAppend', 'Fabs', 'ExtractAttachedFile', 'Exp', 'ExeTypeInfo', 'Exclusive',
+            'EnvItemize', 'EnvironSet', 'Environment', 'EndSession', 'DosVersion', 'DllLoad', 'DllLastError', 'DllHwnd', 'DllHinst',
+            'DllFree', 'DllCallCDecl', 'DllCall', 'Display', 'DiskVolinfo', 'DiskSize', 'DiskScan', 'DiskInfo', 'DiskFree', 'DiskExist',
+            'DirWindows', 'DirSize', 'DirScript', 'DirRename', 'DirRemove', 'DirMake', 'DirItemize', 'DirInfoToArray', 'DirHome', 'DirGet',
+            'DirExist', 'DirChange', 'DirAttrSetEx', 'DirAttrSet', 'DirAttrGetEx', 'DirAttrGet', 'DialogProcOptions', 'DialogObject',
+            'DialogControlState', 'DialogControlSet', 'DialogControlGet', 'DialogBox', 'Dialog', 'Delay', 'Decimals', 'DebugTrace',
+            'DebugData', 'DDETimeout', 'DDETerminate', 'DDERequest', 'DDEPoke', 'DDEInitiate', 'DDEExecute', 'DateTime', 'CurrFilepath',
+            'CurrentPath', 'CurrentFile', 'CreateObject', 'Cosh', 'Cos', 'ClipPut', 'ClipHasFormat', 'ClipGetEx', 'ClipGet', 'ClipAppend',
+            'ChrUnicodeToString', 'ChrUnicodeToHex', 'ChrStringToUnicode', 'ChrSetCodepage', 'ChrHexToUnicode', 'ChrGetCodepage',
+            'Char2Num', 'Ceiling', 'ButtonNames', 'BoxUpdates', 'BoxTitle', 'BoxTextFont', 'BoxTextColor', 'BoxText', 'BoxShut', 'BoxPen',
+            'BoxOpen', 'BoxNew', 'BoxMapmode', 'BoxesUp', 'BoxDrawText', 'BoxDrawRect', 'BoxDrawLine', 'BoxDrawCircle', 'BoxDestroy',
+            'BoxDataTag', 'BoxDataClear', 'BoxColor', 'BoxCaption', 'BoxButtonWait', 'BoxButtonStat', 'BoxButtonKill', 'BoxButtonDraw',
+            'BoxBitMap', 'BinaryXor', 'BinaryXlate', 'BinaryWriteEx', 'BinaryWrite', 'BinaryTagRepl', 'BinaryTagLen', 'BinaryTagInit',
+            'BinaryTagIndex', 'BinaryTagFind', 'BinaryTagExtr', 'BinaryStrCnt', 'BinarySort', 'BinaryReplace', 'BinaryReadEx',
+            'BinaryRead', 'BinaryPokeStrW', 'BinaryPokeStr', 'BinaryPokeHex', 'BinaryPokeFlt', 'BinaryPoke4', 'BinaryPoke2', 'BinaryPoke',
+            'BinaryPeekStrW', 'BinaryPeekStr', 'BinaryPeekHex', 'BinaryPeekFlt', 'BinaryPeek4', 'BinaryPeek2', 'BinaryPeek', 'BinaryOr',
+            'BinaryOleType', 'BinaryIndexNc', 'BinaryIndexEx', 'BinaryIndexBin', 'BinaryIndex', 'BinaryIncrFlt', 'BinaryIncr4',
+            'BinaryIncr2', 'BinaryIncr', 'BinaryHashRec', 'BinaryFree', 'BinaryEodSet', 'BinaryEodGet', 'BinaryCopy', 'BinaryConvert',
+            'BinaryCompare', 'BinaryClipPut', 'BinaryClipGet', 'BinaryChecksum', 'BinaryBufInfo', 'BinaryAnd', 'BinaryAllocArray',
+            'BinaryAlloc', 'Beep', 'Average', 'Atan', 'AskYesNo', 'AskTextbox', 'AskPassword', 'AskLine', 'AskItemlist', 'AskFont',
+            'AskFiletext', 'AskFilename', 'AskDirectory', 'AskColor', 'Asin', 'ArrInitialize', 'ArrInfo', 'ArrDimension',
+            'Arrayize', 'ArrayFilePutCSV', 'ArrayFilePut', 'ArrayFileGetCSV', 'ArrayFileGet', 'AppWaitClose', 'AppExist', 'AddExtender',
+            'Acos', 'Abs', 'About'
+            ),
+        4 => array(
+            'zZipFiles', 'zVersionInfo', 'zVersion', 'zUnZipFiles', 'zSetPortBit', 'zRPortShift', 'zPortOut', 'zPortIn', 'zNotPortBit',
+            'zLPortShift', 'zGetPortBit', 'zClrPortBit', 'xVerifyCCard', 'xSendMessage', 'xMessageBox', 'xMemCompact', 'xHex', 'xGetElapsed',
+            'xGetChildHwnd', 'xExtenderInfo', 'xEnumStreams', 'xEjectMedia', 'xDriveReady', 'xDiskLabelGet', 'xCursorSet', 'xBaseConvert',
+            'wxPing', 'wxParmSet', 'wxParmGet', 'wxMsgSetHdr', 'wxMsgGetHdr', 'wxMsgGetBody', 'wxHost2Addr', 'wxGetLastErr', 'wxGetInfo',
+            'wxGetErrDesc', 'wxAddr2Host', 'wtsWaitSystemEvent', 'wtsVersion', 'wtsTerminateProcess', 'wtsShutdownSystem', 'wtsSendMessage',
+            'wtsQuerySessionInfo', 'wtsProcIdToSessId', 'wtsLogoffSession', 'wtsLastErrMsg', 'wtsIsTSEnabled', 'wtsIsCitrixEnabled',
+            'wtsGetActiveConsoleSessId', 'wtsEnumSessions', 'wtsEnumProcesses', 'wtsDisconnectSession', 'wnWrkGroups', 'wnVersion', 'wntWtsUserSet',
+            'wntWtsUserGet', 'wntVersion', 'wntUserSidChk', 'wntUserSetDat', 'wntUserRename', 'wntUserProps', 'wntUserList', 'wntUserInfo',
+            'wntUserGetDat', 'wntUserFiles', 'wntUserExist', 'wntUserDel', 'wntUserAddDat', 'wntUserAdd', 'wntSvcStatus', 'wntSvcStart',
+            'wntSvcList', 'wntSvcDelete', 'wntSvcCreate', 'wntSvcControl', 'wntSvcCfgSet', 'wntSvcCfgGet', 'wntShutdown', 'wntShareUsers',
+            'wntShareSet', 'wntShareList', 'wntShareInfo', 'wntShareDel', 'wntShareAdd', 'wntServiceInf', 'wntServiceAt', 'wntServerType',
+            'wntServerList', 'wntServerInfo', 'wntSecurityGet', 'wntRunAsUser', 'wntResources2', 'wntResources', 'wntRemoteTime', 'wntRasUserSet',
+            'wntRasUserGet', 'wntProfileInfo', 'wntProfileDel', 'wntPrivUsers', 'wntPrivList', 'wntPrivGet', 'wntPrivDel', 'wntPrivAdd',
+            'wntOwnerSet', 'wntOwnerGet', 'wntMemberSet', 'wntMemberLst2', 'wntMemberList', 'wntMemberGrps', 'wntMemberGet', 'wntMemberDel',
+            'wntLsaPolSet', 'wntLsaPolGet', 'wntListGroups', 'wntLastErrMsg', 'wntGroupRen', 'wntGroupInfo', 'wntGroupEdit', 'wntGroupDel',
+            'wntGroupAdd', 'wntGetUser', 'wntGetDrive', 'wntGetDc', 'wntGetCon', 'wntFileUsers', 'wntFilesOpen', 'wntFileClose', 'wntEventWrite',
+            'wntEventLog', 'wntDomainSync', 'wntDirDialog', 'wntDfsList', 'wntDfsGetInfo', 'wntCurrUsers', 'wntChgPswd', 'wntCancelCon',
+            'wntAuditMod', 'wntAuditList', 'wntAuditGet', 'wntAuditDel', 'wntAuditAdd2', 'wntAuditAdd', 'wntAddPrinter', 'wntAddDrive',
+            'wntAcctPolSet', 'wntAcctPolGet', 'wntAcctList', 'wntAcctInfo', 'wntAccessMod', 'wntAccessList', 'wntAccessGet', 'wntAccessDel',
+            'wntaccessadd2', 'wntAccessAdd', 'wnShares', 'wnSharePath', 'wnShareName', 'wnShareCnt', 'wnServers', 'wnRestore', 'wnNetNames',
+            'wnGetUser', 'wnGetCon', 'wnGetCaps', 'wnDlgShare', 'wnDlgNoShare', 'wnDlgDiscon', 'wnDlgCon4', 'wnDlgCon3', 'wnDlgCon2', 'wnDlgCon',
+            'wnDlgBrowse', 'wnDialog', 'wnCmptrInfo', 'wnCancelCon', 'wnAddCon', 'WaitSRQ', 'w9xVersion', 'w9xUserSetDat', 'w9xUserRename',
+            'w9xUserprops', 'w9xUserList', 'w9xUserinfo', 'w9xUserGetDat', 'w9xUserExist', 'w9xUserDel', 'w9xUserAddDat', 'w9xUserAdd', 'w9xShareSet',
+            'w9xShareInfo', 'w9xShareDel', 'w9xShareAdd', 'w9xServiceAt', 'w9xServerList', 'w9xRemoteTime', 'w9xOwnerGet', 'w9xMemberSet',
+            'w9xMemberList', 'w9xMemberGrps', 'w9xMemberGet', 'w9xMemberDel', 'w9xListGroups', 'w9xGroupInfo', 'w9xGroupDel', 'w9xGroupAdd',
+            'w9xGetDC', 'w9xFileUsers', 'w9xAccessList', 'w9xAccessGet', 'w9xAccessDel', 'w9xAccessAdd', 'w95Version', 'w95ShareUsers',
+            'w95ShareSet', 'w95ShareList', 'w95ShareInfo', 'w95ShareDel', 'w95ShareAdd', 'w95ServiceInf', 'w95ServiceAt', 'w95ServerType',
+            'w95ServerInfo', 'w95Resources', 'w95GetUser', 'w95GetDrive', 'w95GetCon', 'w95FileUsers', 'w95FileClose', 'w95DirDialog',
+            'w95CancelCon', 'w95AddPrinter', 'w95AddDrive', 'w95AccessDel', 'w95AccessAdd', 'w3Version', 'w3PrtBrowse', 'w3NetGetUser',
+            'w3NetDialog', 'w3GetCon', 'w3GetCaps', 'w3DirBrowse', 'w3CancelCon', 'w3AddCon', 'urlGetScheme', 'urlEncode', 'urlDecode',
+            'tVersion', 'tSetPriority', 'TriggerList', 'Trigger', 'tRemoteConn', 'tOpenProc', 'tListProc', 'tListMod', 'tKillProc', 'tGetProcInfo',
+            'tGetPriority', 'tGetModInfo', 'tGetLastError', 'tGetData', 'TestSys', 'TestSRQ', 'tCountProc', 'tCompatible', 'tCloseProc',
+            'tBrowseCntrs', 'sSendString', 'sSendNum', 'sSendLine', 'sSendBinary', 'sRecvNum', 'sRecvLine', 'sRecvBinary', 'SrchVersion',
+            'SrchNext', 'SrchInit', 'SrchFree', 'sOpen', 'sOK2Send', 'sOK2Recv', 'smtpSendText', 'smtpSendFile', 'sListen', 'SetRWLS',
+            'SendSetup', 'SendLLO', 'SendList', 'SendIFC', 'SendDataBytes', 'SendCmds', 'Send', 'sConnect', 'sClose', 'SByteOrder32',
+            'sByteOrder16', 'sAccept', 'rRegVersion', 'rRegSearch', 'ResetSys', 'ReceiveSetup', 'Receive', 'ReadStsByte', 'RcvRespMsg',
+            'RasVersion', 'RasTypeSize', 'RasRename', 'RasNumCons', 'RasNameValid', 'RasListActCon', 'RasItemize', 'RasHangUp', 'RasGetLastErr',
+            'RasGetConStat', 'RasEntrySet', 'RasEntryInfo', 'RasEntryExist', 'RasEntryDel', 'RasEntryAdd', 'RasDialInfo', 'RasDial',
+            'RasCopy', 'RasConStatus', 'qVersionInfo', 'qTransact', 'qTables', 'qSpecial', 'qSetConnOpt', 'qNumRsltCol', 'qNativeSql', 'qLastCode',
+            'qGetData', 'qFreeStmt', 'qFreeEnv', 'qFreeConnect', 'qFetch', 'qExecDirect', 'qError', 'qDriverList', 'qDriverCon', 'qDisconnect',
+            'qDataSources', 'qConnect', 'qConfigError', 'qConfigData', 'qColumns', 'qBindCol', 'qAllocStmt', 'qAllocEnv', 'qAllocConnect',
+            'pWaitFor', 'pVersionInfo', 'pTimeout', 'pSetPublish', 'pSetPrtInfo', 'pSetPrtAttrib', 'pSetDefPrtEx', 'pSetDefPrt', 'pSendFile',
+            'pRecvFile', 'pPutString', 'pPutLine', 'pPutChar', 'pPutByte', 'pPutBinary', 'PPollUnconfig', 'PPollConfig', 'PPoll', 'pPeekChar',
+            'pPeekByte', 'pPaperSizes', 'pPaperBins', 'pModemSReg', 'pModemParams', 'pModemInit', 'pModemHangUp', 'pModemDial', 'pModemControl',
+            'pModemConnect', 'pModemCommand', 'pModemAnsRing', 'pModemAnsCall', 'pMediaTypes', 'pGetString', 'pGetPublish', 'pGetPrtList',
+            'pGetPrtInfo', 'pGetPrtAttrib', 'pGetLine', 'pGetLastError', 'pGetErrorMsg', 'pGetErrorCode', 'pGetDefPrtInf', 'pGetChar',
+            'pGetByte', 'pGetBinary', 'pDelPrtConn', 'pDelPrinter', 'pComOpen', 'pComModify', 'pComInfo', 'pComControl', 'pComClose',
+            'pCheckSum', 'pCheckBinary', 'pCaptureOn', 'pCaptureOff', 'pCaptureLog', 'PassControl', 'pAddPrtConn', 'pAddPrinter', 'p3RecvText',
+            'p3RecvFile', 'p3Peek', 'p3Open', 'p3GetReply', 'p3Delete', 'p3Count', 'p3Close', 'nwWhoAmI', 'nwVfyPassword', 'nwVersion',
+            'nwSrvShutdown', 'nwSrvNLMMgr', 'nwSrvGenGUID', 'nwSrvExecNCF', 'nwSetVolLimit', 'nwSetSrvParam', 'nwSetSrvInfo', 'nwSetPrimServ',
+            'nwSetPassword', 'nwSetOptions', 'nwSetFileInfo', 'nwSetDirLimit', 'nwSetDirInfo', 'nwSetContext', 'nwSetBcastMode', 'nwServerList',
+            'nwSendBcastMsg', 'nwSearchObjects', 'nwSearchFilter', 'nwRenameObject', 'nwRemoveObject', 'nwReceiveBcastMsg', 'nwNameConvert',
+            'nwMutateObject', 'nwMoveObject', 'nwModifyObject', 'nwMapDelete', 'nwMap', 'nwLogout', 'nwLogin', 'nwListUserGroups',
+            'nwListObjects', 'nwListGroupMembers', 'nwLastErrMsg', 'nwIsUserInGroup', 'nwGetVolLimit', 'nwGetSrvStats', 'nwGetSrvParam',
+            'nwGetSrvInfo', 'nwGetSrvCfg', 'nwGetOptions', 'nwGetObjValue', 'nwGetObjInfo', 'nwGetNLMInfo', 'nwGetMapped', 'nwGetFileInfo',
+            'nwGetDirLimit', 'nwGetDirInfo', 'nwGetContext', 'nwGetConnInfo', 'nwGetCapture', 'nwGetBcastMode', 'nwGetAttrInfo',
+            'nwDriveStatus', 'nwDrivePath', 'nwDetachFromServer', 'nwDelUserFromGroup', 'nwDelConnNum', 'nwCompareObject', 'nwClientInfo',
+            'nwChgPassword', 'nwAttachToServer', 'nwAddUserToGroup', 'nwAddObject', 'netVersion', 'netResources', 'netGetUser', 'netGetCon',
+            'netDirDialog', 'netCancelCon', 'netAddPrinter', 'netAddDrive', 'n4Version', 'n4UserGroups', 'n4UserGroupEx', 'n4SetPrimServ',
+            'n4SetOptions', 'n4SetContextG', 'n4SetContext', 'n4ServerList', 'n4ServerInfo', 'n4ObjSearch', 'n4ObjRename', 'n4ObjOptions',
+            'n4ObjMove', 'n4ObjGetVal', 'n4ObjectProps', 'n4ObjectList', 'n4ObjectInfo', 'n4ObjDelete', 'n4NameConvert', 'n4MsgsEndAll',
+            'n4MsgsEnd', 'n4MemberSet', 'n4MemberGet', 'n4MemberDel', 'n4MapRoot', 'n4MapDir', 'n4MapDelete', 'n4Map', 'n4LogoutTree',
+            'n4Logout', 'n4Login', 'n4GetUserName', 'n4GetUserId', 'n4GetUser', 'n4GetNetAddr', 'n4GetMapped', 'n4GetContext',
+            'n4GetConnNum', 'n4FileUsers', 'n4FileTimeGet', 'n4FileAttrSet', 'n4FileAttrGet', 'n4DriveStatus', 'n4DrivePath', 'n4DirTimeGet',
+            'n4DirAttrSet', 'n4DirAttrGet', 'n4Detach', 'n4ChgPassword', 'n4CapturePrt', 'n4CaptureGet', 'n4CaptureEnd', 'n4Attach',
+            'n3Version', 'n3UserGroups', 'n3ServerList', 'n3ServerInfo', 'n3MsgsEndAll', 'n3MsgsEnd', 'n3MemberSet', 'n3MemberGet',
+            'n3MemberDel', 'n3Maproot', 'n3Mapdir', 'n3Mapdelete', 'n3Map', 'n3Logout', 'n3GetUserId', 'n3GetUser', 'n3GetNetAddr',
+            'n3GetMapped', 'n3GetConnNum', 'n3FileTimeGet', 'n3FileAttrSet', 'n3FileAttrGet', 'n3DriveStatus', 'n3DrivePath',
+            'n3DirTimeGet', 'n3DirAttrSet', 'n3DirAttrGet', 'n3Detach', 'n3ChgPassword', 'n3CapturePrt', 'n3CaptureGet',
+            'n3CaptureEnd', 'n3Attach', 'mVersion', 'mSyncMail', 'mSendMailEx', 'mSendMail', 'mrecvmail', 'mReadNextMsg', 'mLogOn',
+            'mLogOff', 'mFindNext', 'mError', 'mCompatible', 'kVerInfo', 'kStatusInfo', 'kSendText', 'kSendFile', 'kManageImap4',
+            'kInit', 'kGetMail', 'kExtra', 'kDest', 'kDeletePop3', 'iWriteDataBuf', 'iWriteData', 'iVersion', 'IUrlOpen', 'iUrlEncode',
+            'iUrlDecode', 'iReadDataBuf', 'iReadData', 'ipVersion', 'ipPing', 'iPing', 'ipHost2Addr', 'ipGetLastErr', 'ipGetAddress',
+            'iParseURL', 'ipAddr2Host', 'iOptionSet', 'iOptionGet', 'ImgWave', 'ImgVersion', 'ImgUnsharpMask', 'ImgThreshold', 'ImgSwirl',
+            'ImgSpread', 'ImgSolarize', 'ImgShear', 'ImgSharpen', 'ImgShade', 'ImgScale', 'ImgSample', 'ImgRotate', 'ImgResize',
+            'ImgReduceNoise', 'ImgRaise', 'ImgOilPaint', 'ImgNormalize', 'ImgNegate', 'ImgMotionBlur', 'ImgModulate', 'ImgMinify',
+            'ImgMedianFilter', 'ImgMagnify', 'ImgLevel', 'ImgIsValid', 'ImgIsPalette', 'ImgIsMono', 'ImgIsGray', 'ImgInfo', 'ImgImplode',
+            'ImgGetImageType', 'ImgGetColorCount', 'ImgGaussianBlur', 'ImgGamma', 'ImgFrame', 'ImgFlop', 'ImgFlip', 'ImgEqualize',
+            'ImgEnhance', 'ImgEmboss', 'ImgCrop', 'ImgConvert', 'ImgContrast', 'ImgCompare', 'ImgColorize', 'ImgChop', 'ImgCharcoal',
+            'ImgBorder', 'ImgBlur', 'ImgAddNoise', 'iLocFindNext', 'iLocFindInit', 'iHttpOpen', 'iHttpInit', 'iHttpHeaders', 'iHttpAccept',
+            'iHostConnect', 'iHost2Addr', 'iGetResponse', 'iGetLastError', 'iGetIEVer', 'iGetConStatEx', 'iGetConState', 'iFtpRename',
+            'iFtpPut', 'iFtpOpen', 'iFtpGet', 'iFtpFindNext', 'iFtpFindInit', 'iFtpDirRemove', 'iFtpDirMake', 'iFtpDirGet', 'iFtpDirChange',
+            'iFtpDialog', 'iFtpDelete', 'iFtpCmd', 'iErrorDialog', 'iDialItemize', 'iDialHangUp', 'iDial', 'iCookieSet', 'iCookieGet',
+            'iContentURL', 'iContentFile', 'iContentData', 'iClose', 'ibWrtf', 'ibWrt', 'ibWait', 'ibVersion', 'ibUnlock', 'ibTrg',
+            'ibTmo', 'ibStop', 'ibStatus', 'ibSta', 'ibSre', 'ibSic', 'ibSad', 'ibRsv', 'ibRsp', 'ibRsc', 'ibRpp', 'ibRdf', 'ibRd',
+            'ibPpc', 'ibPoke', 'ibPct', 'ibPad', 'ibOnl', 'ibMakeAddr', 'ibLock', 'ibLoc', 'ibLn', 'ibLines', 'ibIst', 'ibInit',
+            'ibGts', 'ibGetSad', 'ibGetPad', 'ibFind', 'ibEvent', 'ibErr', 'ibEot', 'ibEos', 'iBegin', 'ibDma', 'ibDev', 'ibConfig',
+            'ibCntl', 'ibCnt', 'ibCmda', 'ibCmd', 'ibClr', 'ibCac', 'ibBna', 'ibAsk', 'iAddr2Host', 'huge_Thousands', 'huge_Subtract',
+            'huge_SetOptions', 'huge_Multiply', 'huge_GetLastError', 'huge_ExtenderInfo', 'huge_Divide', 'huge_Decimal', 'huge_Add',
+            'httpStripHTML', 'httpRecvTextF', 'httpRecvText', 'httpRecvQuery', 'httpRecvQryF', 'httpRecvFile', 'httpGetServer',
+            'httpGetQuery', 'httpGetPath', 'httpGetFile', 'httpGetDir', 'httpGetAnchor', 'httpFullPath', 'httpFirewall', 'httpAuth',
+            'ftpRename', 'ftpQuote', 'ftpPut', 'ftpOpen', 'ftpList', 'ftpGet', 'ftpFirewall', 'ftpDelete', 'ftpClose', 'ftpChDir',
+            'FindRQS', 'FindLstn', 'EnvSetVar', 'EnvPathDel', 'EnvPathChk', 'EnvPathAdd', 'EnvListVars', 'EnvGetVar', 'EnvGetInfo',
+            'EnableRemote', 'EnableLocal', 'ehllapiWait', 'ehllapiVersion', 'ehllapiUninit', 'ehllapiStopKeyIntercept', 'ehllapiStopHostNotify',
+            'ehllapiStopCloseIntercept', 'ehllapiStartKeyIntercept', 'ehllapiStartHostNotify', 'ehllapiStartCloseIntercept',
+            'ehllapiSetWindowStatus', 'ehllapiSetSessionParams', 'ehllapiSetPSWindowName', 'ehllapiSetCursorLoc', 'ehllapiSendKey',
+            'ehllapiSendFile', 'ehllapiSearchPS', 'ehllapiSearchField', 'ehllapiRunProfile', 'ehllapiResetSystem', 'ehllapiReserve',
+            'ehllapiRelease', 'ehllapiReceiveFile', 'ehllapiQuerySystem', 'ehllapiQueryPSStatus', 'ehllapiQueryHostNotify',
+            'ehllapiQueryFieldAttr', 'ehllapiQueryCursorLoc', 'ehllapiQueryCloseIntercept', 'ehllapiPostInterceptStatus',
+            'ehllapiPause', 'ehllapiLastErrMsg', 'ehllapiInit', 'ehllapiGetWindowStatus', 'ehllapiGetPSHWND', 'ehllapiGetKey',
+            'ehllapiFindFieldPos', 'ehllapiFindFieldLen', 'ehllapiDisconnectPS', 'ehllapiCvtRCToPos', 'ehllapiCvtPosToRC',
+            'ehllapiCopyTextToPS', 'ehllapiCopyTextToField', 'ehllapiCopyTextFromPS', 'ehllapiCopyTextFromField', 'ehllapiCopyOIA',
+            'ehllapiConnectPS', 'dunItemize', 'dunDisconnect', 'dunConnectEx', 'dunConnect', 'dsTestParam', 'dsSIDtoHexStr', 'dsSetSecProp',
+            'dsSetProperty', 'dsSetPassword', 'dsSetObj', 'dsSetCredentX', 'dsSetCredent', 'dsRemFromGrp', 'dsRelSecObj', 'dsMoveObj',
+            'dsIsObject', 'dsIsMemberGrp', 'dsIsContainer', 'dsGetUsersGrps', 'dsGetSecProp', 'dsGetPropName', 'dsGetProperty',
+            'dsGetPrntPath', 'dsGetPrimGrp', 'dsGetMemGrp', 'dsGetInfo', 'dsGetClass', 'dsGetChldPath', 'dsFindPath', 'dsDeleteObj',
+            'dsCreatSecObj', 'dsCreateObj', 'dsCopySecObj', 'dsAddToGrp', 'dsAclRemAce', 'dsAclOrderAce', 'dsAclGetAces', 'dsAclAddAce',
+            'DevClearList', 'DevClear', 'dbTest', 'dbSwapColumns', 'dbSort', 'dbSetRecordField', 'dbSetOptions', 'dbSetErrorReporting',
+            'dbSetEntireRecord', 'dbSetDelimiter', 'dbSave', 'dbOpen', 'dbNameColumn', 'dbMakeNewItem', 'dbInsertColumn', 'dbGetVersion',
+            'dbGetSaveStatus', 'dbGetRecordField', 'dbGetRecordCount', 'dbGetNextItem', 'dbGetLastError', 'dbGetEntireRecord',
+            'dbGetColumnType', 'dbGetColumnNumber', 'dbGetColumnName', 'dbGetColumnCount', 'dbFindRecord', 'dbExist', 'dbEasterEgg',
+            'dbDeleteRecord', 'dbDeleteColumn', 'dbDebug', 'dbCookDatabases', 'dbClose', 'dbCloneRecord', 'dbBindCol', 'cWndState',
+            'cWndinfo', 'cWndGetWndSpecName', 'cWndGetWndSpec', 'cWndexist', 'cWndByWndSpecName', 'cWndByWndSpec', 'cWndbyseq',
+            'cWndbyname', 'cWndbyid', 'cWndbyclass', 'cWinIDConvert', 'cVersionInfo', 'cVendorId', 'cSetWndText', 'cSetUpDownPos',
+            'cSetTvItem', 'cSetTrackPos', 'cSetTabItem', 'cSetLvItem', 'cSetLbItemEx', 'cSetLbItem', 'cSetIpAddr', 'cSetFocus',
+            'cSetEditText', 'cSetDtpDate', 'cSetCbItem', 'cSetCalDate', 'cSendMessage', 'cRadioButton', 'cPostMessage', 'cPostButton',
+            'cMemStat', 'cGetWndCursor', 'cGetUpDownPos', 'cGetUpDownMin', 'cGetUpDownMax', 'cGetTVItem', 'cGetTrackPos', 'cGetTrackMin',
+            'cGetTrackMax', 'cGetTbText', 'cGetSbText', 'cGetLvText', 'cGetLvSelText', 'cGetLvFocText', 'cGetLvDdtText', 'cGetLvColText',
+            'cGetLbText', 'cGetLbSelText', 'cGetLbCount', 'cGetIpAddr', 'cGetInfo', 'cGetHrText', 'cGetFocus', 'cGetEditText', 'cGetDtpDate',
+            'cGetControlImageCRC', 'cGetCBText', 'cGetCbCount', 'cGetCalDate', 'cFindByName', 'cFindByClass', 'cEnablestate', 'cDblClickItem',
+            'cCpuSupt', 'cCpuSpeed', 'cCpuIdExt', 'cCpuId', 'cCpuFeat', 'cCpuBenchmark', 'cCloneCheck', 'cClickToolbar', 'cClickButton',
+            'cClearTvItem', 'cClearLvItem', 'cClearLbAll', 'cCheckbox', 'aVersion', 'aStatusbar', 'aShellFolder', 'aMsgTimeout', 'AllSPoll',
+            'aGetLastError', 'aFileRename', 'aFileMove', 'aFileDelete', 'aFileCopy'
+            ),
+        5 => array(
+            'wWordRight', 'wWordLeft', 'wWinTile', 'wWinRestore', 'wWinNext', 'wWinMinimize', 'wWinMaximize', 'wWinCloseAll', 'wWinClose',
+            'wWinCascade', 'wWinArricons', 'wViewOutput', 'wViewOptions', 'wViewHtml', 'wUpperCase', 'wUpline', 'wUndo', 'wTopOfFile', 'wToggleIns',
+            'wTab', 'wStatusMsg', 'wStartSel', 'wSpellcheck', 'wSetProject', 'wSetPrefs', 'wSetColblk', 'wSetBookmark', 'wSelWordRight',
+            'wSelWordLeft', 'wSelUp', 'wSelTop', 'wSelRight', 'wSelPgUp', 'wSelPgDn', 'wSelLeft', 'wSelInfo', 'wSelHome', 'wSelEnd', 'wSelectAll',
+            'wSelDown', 'wSelBottom', 'wRunRebuild', 'wRunMake', 'wRunExecute', 'wRunDebug', 'wRunConfig', 'wRunCompile', 'wRunCommand', 'wRight',
+            'wRepeat', 'wRedo', 'wRecord', 'wProperties', 'wPrintDirect', 'wPrinSetup', 'wPrevError', 'wPaste', 'wPageUp', 'wPageDown', 'wNextError',
+            'wNewLine', 'wLowerCase', 'wLineCount', 'wLeft', 'wInvertCase', 'wInsString', 'wInsLine', 'wHome', 'wHelpKeyword', 'wHelpKeybrd',
+            'wHelpIndex', 'wHelpHelp', 'wHelpCmds', 'wHelpAbout', 'wGotoLine', 'wGotoCol', 'wGetWrap', 'wGetWord', 'wGetUndo', 'wGetSelstate',
+            'wGetRedo', 'wGetOutput', 'wGetModified', 'wGetLineNo', 'wGetIns', 'wGetFilename', 'wGetColNo', 'wGetChar', 'wFtpOpen', 'wFindNext',
+            'wFindInFiles', 'wFind', 'wFileSaveAs', 'wFileSave', 'wFileRevert', 'wFilePrint', 'wFilePgSetup', 'wFileOpen', 'wFileNew', 'wFileMerge',
+            'wFileList', 'wFileExit', 'wEndSel', 'wEndOfFile', 'wEnd', 'wEdWrap', 'wEdWordRight', 'wEdWordLeft', 'wEdUpLine', 'wEdUndo', 'wEdTopOfFile',
+            'wEdToggleIns', 'wEdTab', 'wEdStartSel', 'wEdSetColBlk', 'wEdSelectAll', 'wEdRight', 'wEdRedo', 'wEdPaste', 'wEdPageUp', 'wEdPageDown',
+            'wEdNewLine', 'wEdLeft', 'wEdInsString', 'wEdHome', 'wEdGoToLine', 'wEdGoToCol', 'wEdGetWord', 'wEdEndSel', 'wEdEndOfFile', 'wEdEnd',
+            'wEdDownLine', 'wEdDelete', 'wEdCutLine', 'wEdCut', 'wEdCopyLine', 'wEdCopy', 'wEdClearSel', 'wEdBackTab', 'wEdBackspace', 'wDownLine',
+            'wDelete', 'wDelButton', 'wCutMarked', 'wCutLine', 'wCutAppend', 'wCut', 'wCopyMarked', 'wCopyLine', 'wCopyAppend', 'wCopy', 'wCompile',
+            'wClearSel', 'wChange', 'wCallMacro', 'wBackTab', 'wBackspace', 'wAutoIndent', 'wAddButton', 'edWindowTile', 'edWindowRestore',
+            'edWindowNext', 'edWindowMinimize', 'edWindowMaximize', 'edWindowCloseall', 'edWindowClose', 'edWindowCascade', 'edWindowArrangeIcons',
+            'edStatusMsg', 'edSearchViewOutput', 'edSearchRepeat', 'edSearchPrevError', 'edSearchNextError', 'edSearchFind', 'edSearchChange',
+            'edRunRebuild', 'edRunMake', 'edRunExecute', 'edRunDebug', 'edRunConfigure', 'edRunCompile', 'edRunCommand', 'edRecord', 'edHelpProcedures',
+            'edHelpKeyword', 'edHelpKeyboard', 'edHelpIndex', 'edHelpHelp', 'edHelpCommands', 'edHelpAbout', 'edGetWordWrapState', 'edGetWindowName',
+            'edGetUndoState', 'edGetSelectionState', 'edGetRedoState', 'edGetModifiedStatus', 'edGetLineNumber', 'edGetInsertState', 'edGetColumnNumber',
+            'edGetChar', 'edFileSetPreferences', 'edFileSaveAs', 'edFileSave', 'edFilePrinterSetup', 'edFilePrint', 'edFilePageSetup', 'edFileOpen',
+            'edFileNew', 'edFileMerge', 'edFileList', 'edFileExit', 'edEditWrap', 'edEditWordRight', 'edEditWordLeft', 'edEditUpLine', 'edEditUndo',
+            'edEditToggleIns', 'edEditTab', 'edEditStartSelection', 'edEditSetColumnBlock', 'edEditSetBookmark', 'edEditSelectAll', 'edEditRight',
+            'edEditRedo', 'edEditPaste', 'edEditPageUp', 'edEditPageDown', 'edEditLeft', 'edEditInsertString', 'edEditGoToLine', 'edEditGoToColumn',
+            'edEditGoToBookmark', 'edEditGetCurrentWord', 'edEditEndSelection', 'edEditEndOfLine', 'edEditEndOfFile', 'edEditDownline', 'edEditDelete',
+            'edEditCutline', 'edEditCut', 'edEditCopyline', 'edEditCopy', 'edEditClearSelection', 'edEditBeginningOfLine', 'edEditBeginningOfFile',
+            'edEditBackTab', 'edEditBackspace', 'edDeleteButton', 'edAddButton'
+            )
+        ),
+    'SYMBOLS' => array(
+        '(', ')', '[', ']', '{', '}', '!', '+', '-', '~', '$', '^', '?', '@', '%', '#', '&', '*', '|', '/', '<', '>'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false,
+        5 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #800080;',
+            2 => 'color: #0080FF; font-weight: bold;',
+            3 => 'color: #0000FF;',
+            4 => 'color: #FF00FF;',
+            5 => 'color: #008000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #008000; font-style: italic;',
+            2 => 'color: #FF1010; font-weight: bold;',
+            'MULTI' => 'color: #808080; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            0 => 'color: #006600;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => '',
+        5 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(),
+    'REGEXPS' => array(//Variable names
+        0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/xml.php b/examples/includes/geshi/geshi/xml.php
new file mode 100644 (file)
index 0000000..48b748c
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/*************************************************************************************
+ * xml.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2004/09/01
+ *
+ * XML language file for GeSHi. Based on the idea/file by Christian Weiske
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2005/12/28 (1.0.2)
+ *   -  Removed escape character for strings
+ * 2004/11/27 (1.0.1)
+ *   -  Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Check regexps work and correctly highlight XML stuff and nothing else
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'XML',
+    'COMMENT_SINGLE' => array(),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            ),
+        'COMMENTS' => array(
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #66cc66;'
+            ),
+        'SCRIPT' => array(
+            -1 => 'color: #808080; font-style: italic;', // comments
+            0 => 'color: #00bbdd;',
+            1 => 'color: #ddbb00;',
+            2 => 'color: #339933;',
+            3 => 'color: #009900;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #000066;',
+            1 => 'color: #000000; font-weight: bold;',
+            2 => 'color: #000000; font-weight: bold;'
+            )
+        ),
+    'URLS' => array(
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        0 => array(//attribute names
+            GESHI_SEARCH => '([a-z_:][\w\-\.:]*)(=)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => '\\2'
+            ),
+        1 => array(//Initial header line
+            GESHI_SEARCH => '(&lt;[\/?|(\?xml)]?[a-z_:][\w\-\.:]*(\??&gt;)?)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        2 => array(//Tag end markers
+            GESHI_SEARCH => '(([\/|\?])?&gt;)',
+            GESHI_REPLACE => '\\1',
+            GESHI_MODIFIERS => 'i',
+            GESHI_BEFORE => '',
+            GESHI_AFTER => ''
+            ),
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+    'SCRIPT_DELIMITERS' => array(
+        -1 => array(
+            '<!--' => '-->'
+            ),
+        0 => array(
+            '<!DOCTYPE' => '>'
+            ),
+        1 => array(
+            '&' => ';'
+            ),
+        2 => array(
+            '<![CDATA[' => ']]>'
+            ),
+        3 => array(
+            '<' => '>'
+            )
+    ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        -1 => false,
+        0 => false,
+        1 => false,
+        2 => false,
+        3 => true
+        ),
+    'TAB_WIDTH' => 2,
+    'PARSER_CONTROL' => array(
+        'ENABLE_FLAGS' => array(
+            'NUMBERS' => GESHI_NEVER
+        )
+    )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/xorg_conf.php b/examples/includes/geshi/geshi/xorg_conf.php
new file mode 100644 (file)
index 0000000..643d38d
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+/*************************************************************************************
+ * xorg_conf.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.8.3
+ * Date Started: 2008/06/18
+ *
+ * xorg.conf language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/18 (1.0.8)
+ *  -  Initial import
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'Xorg configuration',
+    'COMMENT_SINGLE' => array(1 => '#'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array('"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        // sections
+        1 => array(
+            'Section', 'EndSection', 'SubSection', 'EndSubSection'
+            ),
+        2 => array(
+            // see http://www.x.org/archive/X11R6.9.0/doc/html/xorg.conf.5.html
+            'BiosBase', 'Black', 'Boardname', 'BusID', 'ChipID', 'ChipRev',
+            'Chipset', 'ClockChip', 'Clocks', 'DacSpeed',
+            'DefaultDepth', 'DefaultFbBpp', 'Depth', 'Device',
+            'DisplaySize', 'Driver', 'FbBpp', 'Gamma',
+            'HorizSync', 'IOBase', 'Identifier', 'InputDevice',
+            'Load', 'MemBase', 'Mode', 'Modeline', 'Modelname',
+            'Modes', 'Monitor', 'Option', 'Ramdac', 'RgbPath',
+            'Screen', 'TextClockFreq', 'UseModes', 'VendorName',
+            'VertRefresh', 'VideoAdaptor', 'VideoRam',
+            'ViewPort', 'Virtual', 'Visual', 'Weight', 'White'
+            ),
+        3 => array(
+            // some sub-keywords
+            // screen position
+            'Above', 'Absolute', 'Below', 'LeftOf', 'Relative', 'RightOf',
+            // modes
+            'DotClock', 'Flags', 'HSkew', 'HTimings', 'VScan', 'VTimings'
+            ),
+        ),
+    'REGEXPS' => array(
+        ),
+    'SYMBOLS' => array(
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #b1b100;',
+            2 => 'color: #990000;',
+            3 => 'color: #550000;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            ),
+        'BRACKETS' => array(
+            ),
+        'STRINGS' => array(
+            0 => 'color: #0000ff;',
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #cc66cc;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 4
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/xpp.php b/examples/includes/geshi/geshi/xpp.php
new file mode 100644 (file)
index 0000000..6e7c980
--- /dev/null
@@ -0,0 +1,436 @@
+<?php
+/*************************************************************************************
+ * xpp.php
+ * -------
+ * Author: Simon Butcher (simon@butcher.name)
+ * Copyright: (c) 2007 Simon Butcher (http://simon.butcher.name/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/02/27
+ *
+ * Axapta/Dynamics Ax X++ language file for GeSHi.
+ * For details, see <http://msdn.microsoft.com/en-us/library/aa867122.aspx>
+ *
+ * CHANGES
+ * -------
+ * 2007/02/28 (1.0.0)
+ *  -  First Release
+ *
+ * TODO (updated 2007/02/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'X++',
+    'COMMENT_SINGLE' => array(1 => '//'),
+    'COMMENT_MULTI' => array('/*' => '*/'),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '\\',
+    'KEYWORDS' => array(
+        1 => array( // Primitive types
+            'void',
+            'str',
+            'real',
+            'int64',
+            'int',
+            'date',
+            'container',
+            'boolean',
+            'anytype'
+            ),
+        2 => array( // Keywords
+            'window',
+            'while',
+            'try',
+            'true',
+            'throw',
+            'switch',
+            'super',
+            'static',
+            'server',
+            'right',
+            'return',
+            'retry',
+            'public',
+            'protected',
+            'private',
+            'print',
+            'pause',
+            'null',
+            'new',
+            'mod',
+            'left',
+            'interface',
+            'implements',
+            'if',
+            'for',
+            'final',
+            'false',
+            'extends',
+            'else',
+            'edit',
+            'do',
+            'div',
+            'display',
+            'default',
+            'continue',
+            'client',
+            'class',
+            'changeCompany',
+            'case',
+            'breakpoint',
+            'break',
+            'at',
+            'abstract'
+            ),
+        3 => array( // Functions within the Axapta kernel
+            'year',
+            'wkofyr',
+            'webwebpartstr',
+            'webstaticfilestr',
+            'websitetempstr',
+            'websitedefstr',
+            'webreportstr',
+            'webpagedefstr',
+            'weboutputcontentitemstr',
+            'webmenustr',
+            'webletitemstr',
+            'webformstr',
+            'webdisplaycontentitemstr',
+            'webactionitemstr',
+            'varstr',
+            'utilmoyr',
+            'uint2str',
+            'typeof',
+            'typeid',
+            'trunc',
+            'today',
+            'timenow',
+            'time2str',
+            'term',
+            'tanh',
+            'tan',
+            'tablestr',
+            'tablestaticmethodstr',
+            'tablepname',
+            'tablenum',
+            'tablename2id',
+            'tablemethodstr',
+            'tableid2pname',
+            'tableid2name',
+            'tablefieldgroupstr',
+            'tablecollectionstr',
+            'systemdateset',
+            'systemdateget',
+            'syd',
+            'substr',
+            'strupr',
+            'strscan',
+            'strrtrim',
+            'strrep',
+            'strrem',
+            'strprompt',
+            'strpoke',
+            'strnfind',
+            'strlwr',
+            'strltrim',
+            'strline',
+            'strlen',
+            'strkeep',
+            'strins',
+            'strfmt',
+            'strfind',
+            'strdel',
+            'strcolseq',
+            'strcmp',
+            'stralpha',
+            'str2time',
+            'str2num',
+            'str2int64',
+            'str2int',
+            'str2guid',
+            'str2enum',
+            'str2date',
+            'staticmethodstr',
+            'sln',
+            'sleep',
+            'sinh',
+            'sin',
+            'setprefix',
+            'sessionid',
+            'securitykeystr',
+            'securitykeynum',
+            'runbuf',
+            'runas',
+            'round',
+            'resourcestr',
+            'reportstr',
+            'refprintall',
+            'rate',
+            'querystr',
+            'pv',
+            'pt',
+            'prmisdefault',
+            'primoyr',
+            'prevyr',
+            'prevqtr',
+            'prevmth',
+            'power',
+            'pmt',
+            'num2str',
+            'num2date',
+            'num2char',
+            'nextyr',
+            'nextqtr',
+            'nextmth',
+            'newguid',
+            'mthofyr',
+            'mthname',
+            'mkdate',
+            'minint',
+            'min',
+            'methodstr',
+            'menustr',
+            'menuitemoutputstr',
+            'menuitemdisplaystr',
+            'menuitemactionstr',
+            'maxint',
+            'maxdate',
+            'max',
+            'match',
+            'logn',
+            'log10',
+            'literalstr',
+            'licensecodestr',
+            'licensecodenum',
+            'intvnorm',
+            'intvno',
+            'intvname',
+            'intvmax',
+            'int64str',
+            'indexstr',
+            'indexnum',
+            'indexname2id',
+            'indexid2name',
+            'idg',
+            'identifierstr',
+            'helpfilestr',
+            'helpdevstr',
+            'helpapplstr',
+            'guid2str',
+            'getprefix',
+            'getCurrentUTCTime',
+            'fv',
+            'funcname',
+            'frac',
+            'formstr',
+            'fieldstr',
+            'fieldpname',
+            'fieldnum',
+            'fieldname2id',
+            'fieldid2pname',
+            'fieldid2name',
+            'extendedTypeStr',
+            'extendedTypeNum',
+            'exp10',
+            'exp',
+            'evalbuf',
+            'enumstr',
+            'enumnum',
+            'enumcnt',
+            'enum2str',
+            'endmth',
+            'dimof',
+            'dg',
+            'decround',
+            'ddb',
+            'dayofyr',
+            'dayofwk',
+            'dayofmth',
+            'dayname',
+            'date2str',
+            'date2num',
+            'curuserid',
+            'curext',
+            'cterm',
+            'cosh',
+            'cos',
+            'corrflagset',
+            'corrflagget',
+            'convertUTCTimeToLocalTime',
+            'convertUTCDateToLocalDate',
+            'conpoke',
+            'conpeek',
+            'connull',
+            'conlen',
+            'conins',
+            'confind',
+            'configurationkeystr',
+            'configurationkeynum',
+            'condel',
+            'classstr',
+            'classnum',
+            'classidget',
+            'char2num',
+            'beep',
+            'atan',
+            'asin',
+            'ascii2ansi',
+            'any2str',
+            'any2real',
+            'any2int64',
+            'any2int',
+            'any2guid',
+            'any2enum',
+            'any2date',
+            'ansi2ascii',
+            'acos',
+            'abs'
+            ),
+        4 => array( // X++ SQL stuff
+            'where',
+            'update_recordset',
+            'ttsCommit',
+            'ttsBegin',
+            'ttsAbort',
+            'sum',
+            'setting',
+            'select',
+            'reverse',
+            'pessimisticLock',
+            'outer',
+            'order by',
+            'optimisticLock',
+            'notExists',
+            'noFetch',
+            'next',
+            'minof',
+            'maxof',
+            'like',
+            'join',
+            'insert_recordset',
+            'index hint',
+            'index',
+            'group by',
+            'from',
+            'forUpdate',
+            'forceSelectOrder',
+            'forcePlaceholders',
+            'forceNestedLoop',
+            'forceLiterals',
+            'flush',
+            'firstOnly',
+            'firstFast',
+            'exists',
+            'desc',
+            'delete_from',
+            'count',
+            'avg',
+            'asc'
+            )
+        ),
+    'SYMBOLS' => array( // X++ symbols
+        '!',
+        '&',
+        '(',
+        ')',
+        '*',
+        '^',
+        '|',
+        '~',
+        '+',
+        ',',
+        '-',
+        '/',
+        ':',
+        '<',
+        '=',
+        '>',
+        '?',
+        '[',
+        ']',
+        '{',
+        '}'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        4 => false
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #0000ff;',
+            4 => 'color: #0000ff;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #007f00;',
+            'MULTI' => 'color: #007f00; font-style: italic;'
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000000;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #000000;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #ff0000;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #000000;'
+            ),
+        'METHODS' => array(
+            1 => 'color: #000000;',
+            2 => 'color: #000000;'
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #00007f;'
+            ),
+        'REGEXPS' => array(
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => '',
+        4 => ''
+        ),
+    'OOLANG' => true,
+    'OBJECT_SPLITTERS' => array(
+        1 => '.',
+        2 => '::'
+        ),
+    'REGEXPS' => array(
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        )
+);
+
+?>
diff --git a/examples/includes/geshi/geshi/z80.php b/examples/includes/geshi/geshi/z80.php
new file mode 100644 (file)
index 0000000..845712f
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * z80.php
+ * -------
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2007-2008 Benny Baumann (http://www.omorphia.de/)
+ * Release Version: 1.0.8.3
+ * Date Started: 2007/02/06
+ *
+ * ZiLOG Z80 Assembler language file for GeSHi.
+ * Syntax definition as commonly used with table assembler TASM32
+ * This file will contain some undocumented opcodes.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ *   -  Added description of extra language features (SF#1970248)
+ * 2007/06/03 (1.0.1)
+ *   -  Fixed two typos in the language file
+ * 2007/02/06 (1.0.0)
+ *   -  First Release
+ *
+ * TODO (updated 2007/02/06)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ *     This file is part of GeSHi.
+ *
+ *   GeSHi is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   GeSHi is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with GeSHi; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+    'LANG_NAME' => 'ZiLOG Z80 Assembler',
+    'COMMENT_SINGLE' => array(1 => ';'),
+    'COMMENT_MULTI' => array(),
+    'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+    'QUOTEMARKS' => array("'", '"'),
+    'ESCAPE_CHAR' => '',
+    'KEYWORDS' => array(
+        /*CPU*/
+        1 => array(
+            'adc','add','and','bit','call','ccf','cp','cpd','cpdr','cpir','cpi',
+            'cpl','daa','dec','di','djnz','ei','ex','exx','halt','im','in',
+            'in0','inc','ind','indr','inir','ini','jp','jr','ld','ldd','lddr',
+            'ldir','ldi','mlt','neg','nop','or','otdm','otdmr','otdr','otim',
+            'otimr','otir','out','out0','outd','outi','pop','push','res','ret',
+            'reti','retn','rl','rla','rlc','rlca','rld','rr','rra','rrc','rrca',
+            'rrd','rst','sbc','scf','set','sla','sl1','sll','slp','sra','srl',
+            'sub','tst','tstio','xor'
+            ),
+        /*registers*/
+        2 => array(
+            'a','b','c','d','e','h','l',
+            'af','bc','de','hl','ix','iy','sp',
+            'af\'','ixh','ixl','iyh','iyl'
+            ),
+        /*Directive*/
+        3 => array(
+            '#define','#endif','#else','#ifdef','#ifndef','#include','#undef',
+            '.db','.dd','.df','.dq','.dt','.dw','.end','.org','equ'
+            ),
+        ),
+    'SYMBOLS' => array(
+        '[', ']', '(', ')', '?', '+', '-', '*', '/', '%', '$'
+        ),
+    'CASE_SENSITIVE' => array(
+        GESHI_COMMENTS => false,
+        1 => false,
+        2 => false,
+        3 => false,
+        ),
+    'STYLES' => array(
+        'KEYWORDS' => array(
+            1 => 'color: #0000ff; font-weight:bold;',
+            2 => 'color: #0000ff;',
+            3 => 'color: #46aa03; font-weight:bold;'
+            ),
+        'COMMENTS' => array(
+            1 => 'color: #adadad; font-style: italic;',
+            ),
+        'ESCAPE_CHAR' => array(
+            0 => 'color: #000099; font-weight: bold;'
+            ),
+        'BRACKETS' => array(
+            0 => 'color: #0000ff;'
+            ),
+        'STRINGS' => array(
+            0 => 'color: #7f007f;'
+            ),
+        'NUMBERS' => array(
+            0 => 'color: #dd22dd;'
+            ),
+        'METHODS' => array(
+            ),
+        'SYMBOLS' => array(
+            0 => 'color: #008000;'
+            ),
+        'REGEXPS' => array(
+            0 => 'color: #22bbff;',
+            1 => 'color: #22bbff;',
+            2 => 'color: #993333;'
+            ),
+        'SCRIPT' => array(
+            )
+        ),
+    'URLS' => array(
+        1 => '',
+        2 => '',
+        3 => ''
+        ),
+    'OOLANG' => false,
+    'OBJECT_SPLITTERS' => array(
+        ),
+    'REGEXPS' => array(
+        //Hex numbers
+        0 => '0[0-9a-fA-F]{1,32}[hH]',
+        //Binary numbers
+        1 => '\%[01]{1,64}|[01]{1,64}[bB]?',
+        //Labels
+        2 => '^[_a-zA-Z][_a-zA-Z0-9]?\:'
+        ),
+    'STRICT_MODE_APPLIES' => GESHI_NEVER,
+    'SCRIPT_DELIMITERS' => array(
+        ),
+    'HIGHLIGHT_STRICT_BLOCK' => array(
+        ),
+    'TAB_WIDTH' => 8
+);
+
+?>
diff --git a/examples/includes/vp8_doc_tools.php b/examples/includes/vp8_doc_tools.php
new file mode 100644 (file)
index 0000000..aee2a2e
--- /dev/null
@@ -0,0 +1,207 @@
+#!/usr/bin/env php
+<?php
+/**
+ * vp8_doc_tools.php - Functions used when generating the
+ *   On2 VP8 user documentation.
+ *
+ * Requirements
+ *
+ *   PHP Markdown Extra
+ *   http://michelf.com/projects/php-markdown/extra/
+ *
+ *   PHP SmartyPants
+ *   http://michelf.com/projects/php-smartypants/
+ *
+ *   GeSHI
+ *   http://qbnz.com/highlighter/
+ *
+ *   ASCIIMathPHP
+ *   http://tinyurl.com/asciimathphp
+ *
+ *   HTML::Toc
+ *   http://search.cpan.org/~fvulto/HTML-Toc-0.91/Toc.pod
+ *
+ *
+ * April 2009 - Lou Quillio <lou.quillio@on2.com>
+ *
+ **********************************************************/
+
+
+// Includes
+include_once('PHP-Markdown-Extra-1.2.3/markdown.php');
+include_once('PHP-SmartyPants-1.5.1e/smartypants.php');
+include_once('ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.cfg.php');
+require_once('ASCIIMathPHP-2.0/ASCIIMathPHP-2.0.class.php');
+include_once('geshi/geshi.php');
+
+
+// Paths and Scripts
+$geshi_lang   = 'geshi/geshi/';       // GeSHi language files
+$toc_script     = './do_toc.pl';
+
+
+
+/**
+ * ASCIIMathML parser
+ * http://tinyurl.com/ASCIIMathPHP
+ *
+ * @PARAM mtch_arr array - Array of ASCIIMath expressions
+ *   as returned by preg_replace_callback([pattern]). First
+ *   dimension is the full matched string (with delimiter);
+ *   2nd dimension is the undelimited contents (typically
+ *   a capture group).
+ *
+ **********************************************************/
+
+function ASCIIMathPHPCallback($mtch_arr)
+{
+  $txt = trim($mtch_arr[1]);
+
+  static $asciimath;
+
+  if (!isset($asciimath)) $asciimath = new ASCIIMathPHP($symbol_arr);
+
+  $math_attr_arr = array('displaystyle' => 'true');
+
+  $asciimath->setExpr($txt);
+  $asciimath->genMathML($math_attr_arr);
+
+  return($asciimath->getMathML());
+}
+
+/**
+ * fix_asciiMath()
+ *
+ * ASCIIMath pretty-prints its output, with linefeeds
+ * and tabs. Causes unexpected behavior in some renderers.
+ * This flattens <math> blocks.
+ *
+ * @PARAM page_body str - The <body> element of an
+ * XHTML page to transform.
+ *
+ **********************************************************/
+
+function fix_asciiMath($page_body)
+{
+  $out = FALSE;
+
+  // Remove linefeeds and whitespace in <math> elements
+  $tags_bad  = array('/(<math.*?>)\n*\s*/'
+                    , '/(<mstyle.*?>)\n*\s*/'
+                    , '/(<\/mstyle>)\n*\s*/'
+                    , '/(<mrow.*?>)\n*\s*/'
+                    , '/(<\/mrow>)\n*\s*/'
+                    , '/(<mo.*?>)\n*\s*/'
+                    , '/(<\/mo>)\n*\s*/'
+                    , '/(<mi.*?>)\n*\s*/'
+                    , '/(<\/mi>)\n*\s*/'
+                    , '/(<mn.*?>)\n*\s*/'
+                    , '/(<\/mn>)\n*\s*/'
+                    , '/(<mtext.*?>)\n*\s*/'
+                    , '/(<\/mtext>)\n*\s*/'
+                    , '/(<msqrt.*?>)\n*\s*/'
+                    , '/(<\/msqrt>)\n*\s*/'
+                    , '/(<mfrac.*?>)\n*\s*/'
+                    , '/(<\/mfrac>)\n*\s*/'
+                    );
+  $tags_good = array( '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    , '$1'
+                    );
+  $out = preg_replace($tags_bad, $tags_good, $page_body);
+
+  return $out;
+
+}
+
+/**
+ * do_geshi() - Performs GeSHi transforms on XHTML blobs
+ *
+ * @param $blob str  - The blob to transform
+ * @param $open str  - Opening expression to match
+ * @param $close str - Closing expression to match
+ * @param $lang str  - Language file to use
+ *
+ **********************************************************/
+
+function do_geshi($blob, $open = '<pre>',
+                    $close = '</pre>', $lang = 'c')
+{
+  $out = FALSE;
+  $regexp = '|' . $open . '(.*?)' . $close . '|si';
+  echo $regexp . "\n\n";
+
+  while (preg_match($regexp, $blob, $matches))
+  {
+    $geshi = new GeSHi($matches[1], $lang);
+    $geshi->set_language_path($geshi_lang);
+    $blob_new = $geshi->parse_code();
+    // Strip annoying final <br />
+    $blob_new  = preg_replace('/\n&nbsp;<\/pre>/', '</pre>' , $blob_new);
+    // Fix annoying GeSHI-injected attributes
+    $blob_new  = preg_replace('/<pre.*>/i', '<pre>' , $blob_new);
+    $blob  = preg_replace($regexp, $blob_new, $blob, 1);
+    unset($geshi);
+  }
+
+  return $out;
+
+}
+
+
+
+
+/**
+ * prep_dd_codeblocks()
+ *
+ * I'm _so_ not proud of this, but don't have time to
+ * write a proper regex.
+ *
+ * @TODO - Write that regex.
+ *
+ **********************************************************/
+/*
+function prep_dd_codeblocks($page_body)
+{
+  $out = FALSE;
+  $toggle = 0;
+  $regexp = '/~{3,}/';
+
+  while (preg_match($regexp, $page_body))
+  {
+    if ($toggle == 0)
+    {
+      $regexp = '/:\s*~{3,}\s*\n/';
+      $page_body = preg_replace($regexp, ': <pre><code>', $page_body, 1);
+      $toggle = 1;
+    }
+    else
+    {
+      $regexp = '/\n\s*~{3,}/';
+      $page_body = preg_replace($regexp, '</code></pre>', $page_body, 1);
+      $toggle = 0;
+    }
+  }
+
+  // One more time
+  $regexp = '/\n\s*~{3,}/';
+  $page_body = preg_replace($regexp, '</code></pre>', $page_body, 1);
+  $out = $page_body;
+
+  return $out;
+}
+*/
diff --git a/examples/postproc.txt b/examples/postproc.txt
new file mode 100644 (file)
index 0000000..c65ddda
--- /dev/null
@@ -0,0 +1,67 @@
+@TEMPLATE decoder_tmpl.c
+Postprocessing Decoder
+======================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This example adds postprocessing to the simple decoder loop.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Initializing Postprocessing
+---------------------------
+You must inform the codec that you might request postprocessing at
+initialization time. This is done by passing the VPX_CODEC_USE_POSTPROC
+flag to `vpx_codec_dec_init`. If the codec does not support
+postprocessing, this call will return VPX_CODEC_INCAPABLE. For
+demonstration purposes, we also fall back to default initialization if
+the codec does not provide support.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
+/* Initialize codec */
+res = vpx_codec_dec_init(&codec, interface, NULL,
+                         VPX_CODEC_USE_POSTPROC);
+if(res == VPX_CODEC_INCAPABLE) {
+    printf("NOTICE: Postproc not supported by %s\n",
+           vpx_codec_iface_name(interface));
+    res = vpx_codec_dec_init(&codec, interface, NULL, 0);
+}
+if(res)
+    die_codec(&codec, "Failed to initialize decoder");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
+
+
+Using Adaptive Postprocessing
+-----------------------------
+VP6 provides "adaptive postprocessing." It will automatically select the
+best postprocessing filter on a frame by frame basis based on the amount
+of time remaining before the user's specified deadline expires. The
+special value 0 indicates that the codec should take as long as
+necessary to provide the best quality frame. This example gives the
+codec 15ms (15000us) to return a frame. Remember that this is a soft
+deadline, and the codec may exceed it doing its regular processing. In
+these cases, no additional postprocessing will be done.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE
+/* Decode the frame with 15ms deadline */
+if(vpx_codec_decode(&codec, frame, frame_sz, NULL, 15000))
+    die_codec(&codec, "Failed to decode frame");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE
+
+
+Codec Specific Postprocessing Controls
+--------------------------------------
+Some codecs provide fine grained controls over their built-in
+postprocessors. VP8 is one example. The following sample code toggles
+postprocessing on and off every 15 frames.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PRE_DECODE
+#if CONFIG_VP8_DECODER
+if(frame_cnt%30 == 1) {
+    vp8_postproc_cfg_t  pp = {0, 0, 0};
+
+    if(vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
+        die_codec(&codec, "Failed to turn off postproc");
+} else if(frame_cnt%30 == 16) {
+    vp8_postproc_cfg_t  pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK, 4, 0};
+
+    if(vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
+        die_codec(&codec, "Failed to turn on postproc");
+};
+#endif
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PRE_DECODE
diff --git a/examples/simple_decoder.txt b/examples/simple_decoder.txt
new file mode 100644 (file)
index 0000000..be8ca73
--- /dev/null
@@ -0,0 +1,96 @@
+@TEMPLATE decoder_tmpl.c
+Simple Decoder
+==============
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example of a simple decoder loop. It takes an input file
+containing the compressed data (in IVF format), passes it through the
+decoder, and writes the decompressed frames to disk. Other decoder
+examples build upon this one.
+
+The details of the IVF format have been elided from this example for
+simplicity of presentation, as IVF files will not generally be used by
+your application. In general, an IVF file consists of a file header,
+followed by a variable number of frames. Each frame consists of a frame
+header followed by a variable length payload. The length of the payload
+is specified in the first four bytes of the frame header. The payload is
+the raw compressed data.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Standard Includes
+-----------------
+For decoders, you only have to include `vpx_decoder.h` and then any
+header files for the specific codecs you use. In this case, we're using
+vp8. The `VPX_CODEC_DISABLE_COMPAT` macro can be defined to ensure
+strict compliance with the latest SDK by disabling some backwards
+compatibility features. Defining this macro is encouraged.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INCLUDES
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INCLUDES
+
+
+Initializing The Codec
+----------------------
+The decoder is initialized by the following code. This is an example for
+the VP8 decoder, but the code is analogous for all algorithms. Replace
+`&vpx_codec_vp8_dx_algo` with a pointer to the interface exposed by the
+algorithm you want to use. The `cfg` argument is left as NULL in this
+example, because we want the algorithm to determine the stream
+configuration (width/height) and allocate memory automatically. This
+parameter is generally only used if you need to preallocate memory,
+particularly in External Memory Allocation mode.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
+
+
+Decoding A Frame
+----------------
+Once the frame has been read into memory, it is decoded using the
+`vpx_codec_decode` function. The call takes a pointer to the data
+(`frame`) and the length of the data (`frame_sz`). No application data
+is associated with the frame in this example, so the `user_priv`
+parameter is NULL. The `deadline` parameter is left at zero for this
+example. This parameter is generally only used when doing adaptive
+postprocessing.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DECODE
+
+Codecs may produce a variable number of output frames for every call to
+`vpx_codec_decode`. These frames are retrieved by the
+`vpx_codec_get_frame` iterator function. The iterator variable `iter` is
+initialized to NULL each time `vpx_codec_decode` is called.
+`vpx_codec_get_frame` is called in a loop, returning a pointer to a
+decoded image or NULL to indicate the end of list.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GET_FRAME
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GET_FRAME
+
+
+Processing The Decoded Data
+---------------------------
+In this example, we simply write the encoded data to disk. It is
+important to honor the image's `stride` values.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_DX
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_DX
+
+
+Cleanup
+-------
+The `vpx_codec_destroy` call frees any memory allocated by the codec.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
+
+
+Error Handling
+--------------
+This example does not special case any error return codes. If there was
+an error, a descriptive message is printed and the program exits. With
+few exeptions, vpx_codec functions return an enumerated error status,
+with the value `0` indicating success.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
diff --git a/examples/simple_encoder.txt b/examples/simple_encoder.txt
new file mode 100644 (file)
index 0000000..44c5b08
--- /dev/null
@@ -0,0 +1,105 @@
+@TEMPLATE encoder_tmpl.c
+Simple Encoder
+==============
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example of a simple encoder loop. It takes an input file in
+YV12 format, passes it through the encoder, and writes the compressed
+frames to disk in IVF format. Other decoder examples build upon this
+one.
+
+The details of the IVF format have been elided from this example for
+simplicity of presentation, as IVF files will not generally be used by
+your application. In general, an IVF file consists of a file header,
+followed by a variable number of frames. Each frame consists of a frame
+header followed by a variable length payload. The length of the payload
+is specified in the first four bytes of the frame header. The payload is
+the raw compressed data.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Standard Includes
+-----------------
+For encoders, you only have to include `vpx_encoder.h` and then any
+header files for the specific codecs you use. In this case, we're using
+vp8. The `VPX_CODEC_DISABLE_COMPAT` macro can be defined to ensure
+strict compliance with the latest SDK by disabling some backwards
+compatibility features. Defining this macro is encouraged.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INCLUDES
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INCLUDES
+
+
+Getting The Default Configuration
+---------------------------------
+Encoders have the notion of "usage profiles." For example, an encoder
+may want to publish default configurations for both a video
+conferencing appliction and a best quality offline encoder. These
+obviously have very different default settings. Consult the
+documentation for your codec to see if it provides any default
+configurations. All codecs provide a default configuration, number 0,
+which is valid for material in the vacinity of QCIF/QVGA.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_DEF_CFG
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_DEF_CFG
+
+
+Updating The Configuration
+---------------------------------
+Almost all applications will want to update the default configuration
+with settings specific to their usage. Here we set the width and height
+of the video file to that specified on the command line. We also scale
+the default bitrate based on the ratio between the default resolution
+and the resolution specified on the command line.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG
+
+
+Initializing The Codec
+----------------------
+The encoder is initialized by the following code.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INIT
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_INIT
+
+
+Encoding A Frame
+----------------
+The frame is read as a continuous block (size width * height * 3 / 2)
+from the input file. If a frame was read (the input file has not hit
+EOF) then the frame is passed to the encoder. Otherwise, a NULL
+is passed, indicating the End-Of-Stream condition to the encoder. The
+`frame_cnt` is reused as the presentation time stamp (PTS) and each
+frame is shown for one frame-time in duration. The flags parameter is
+unused in this example. The deadline is set to VPX_DL_REALTIME to
+make the example run as quickly as possible.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+
+Processing The Encoded Data
+---------------------------
+Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data
+for this frame. We write a IVF frame header, followed by the raw data.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_FRAME
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_FRAME
+
+
+Cleanup
+-------
+The `vpx_codec_destroy` call frees any memory allocated by the codec.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DESTROY
+
+
+Error Handling
+--------------
+This example does not special case any error return codes. If there was
+an error, a descriptive message is printed and the program exits. With
+few exeptions, vpx_codec functions return an enumerated error status,
+with the value `0` indicating success.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
+@DEFAULT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIE_CODEC
diff --git a/examples/twopass_encoder.txt b/examples/twopass_encoder.txt
new file mode 100644 (file)
index 0000000..4683bc7
--- /dev/null
@@ -0,0 +1,75 @@
+@TEMPLATE encoder_tmpl.c
+Two Pass Encoder
+================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example of a two pass encoder loop. It takes an input file in
+YV12 format, passes it through the encoder twice, and writes the compressed
+frames to disk in IVF format. It builds upon the simple_encoder example.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Twopass Variables
+-----------------
+Twopass mode needs to track the current pass number and the buffer of
+statistics packets.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
+int                  pass;
+vpx_fixed_buf_t      stats = {0};
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
+
+
+Updating The Configuration
+---------------------------------
+In two pass mode, the configuration has to be updated on each pass. The
+statistics buffer is passed on the last pass.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN
+for(pass=0; pass<2; pass++) {
+    frame_cnt = 0;
+
+    if(pass == 0)
+        cfg.g_pass = VPX_RC_FIRST_PASS;
+    else {
+        cfg.g_pass              = VPX_RC_LAST_PASS;
+        cfg.rc_twopass_stats_in = stats;
+    }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_BEGIN
+
+
+Encoding A Frame
+----------------
+Encoding a frame in two pass mode is identical to the simple encoder
+example, except the deadline is set to VPX_DL_BEST_QUALITY to get the
+best quality possible. VPX_DL_GOOD_QUALITY could also be used.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+frame_avail = read_frame(infile, &raw);
+if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt,
+                    1, flags, VPX_DL_BEST_QUALITY))
+    die_codec(&codec, "Failed to encode frame");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+
+
+Processing Statistics Packets
+-----------------------------
+Each packet of type `VPX_CODEC_CX_FRAME_PKT` contains the encoded data
+for this frame. We write a IVF frame header, followed by the raw data.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS
+case VPX_CODEC_STATS_PKT:
+    stats.buf = realloc(stats.buf, stats.sz
+                        + pkt->data.twopass_stats.sz);
+    if(!stats.buf)
+        die("Memory reallocation failed.\n");
+    memcpy((char*)stats.buf + stats.sz,
+           pkt->data.twopass_stats.buf,
+           pkt->data.twopass_stats.sz);
+    stats.sz +=  pkt->data.twopass_stats.sz;
+    break;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS_STATS
+
+
+Pass Progress Reporting
+-----------------------------
+It's sometimes helpful to see when each pass completes.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END
+    printf("Pass %d complete.\n", pass+1);
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_LOOP_END
diff --git a/examples/vp8_scalable_patterns.txt b/examples/vp8_scalable_patterns.txt
new file mode 100644 (file)
index 0000000..e1d5dbd
--- /dev/null
@@ -0,0 +1,143 @@
+@TEMPLATE encoder_tmpl.c
+VP8 Scalable Frame Patterns
+===========================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example demonstrating how to control the VP8 encoder's
+reference frame selection and update mechanism for video applications
+that benefit from a scalable bitstream.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Configuration
+-------------
+Scalable frame patterns are most useful in an error resilient context,
+so error resiliency mode is enabled, as in the `error_resilient.c`
+example. In addition, we want to disable automatic keyframe selection,
+so we force an interval of 1000 frames.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ENC_SET_CFG2
+
+/* Enable error resilient mode */
+cfg.g_error_resilient = 1;
+cfg.g_lag_in_frames   = 0;
+cfg.kf_mode           = VPX_KF_FIXED;
+
+/* Disable automatic keyframe placement */
+cfg.kf_min_dist = cfg.kf_max_dist = 1000;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENC_SET_CFG2
+
+This example uses the following frame pattern (L->last_frame,
+G->golden_frame, A->alt_ref_frame):
+
+*  Frame  0  Intra, use none,  update L&G&A
+*  Frame  1  Inter, use LGA,   update none
+*  Frame  2  Inter, use LGA,   update L
+*  Frame  3  Inter, use LGA,   update none
+*  Frame  4  Inter, use GA,    update L&G
+*  Frame  5  Inter, use LGA,   update none
+*  Frame  6  Inter, use LGA,   update L
+*  Frame  7  Inter, use LGA,   update none
+*  Frame  8  Inter, use A,     update L&G&A
+*  Frame  9  Inter, use LGA,   update none
+*  Frame 10  Inter, use LGA,   update L
+*  Frame 11  Inter, use LGA,   update none
+*  Frame 12  Inter, use GA,    update L&G
+*  Frame 13  Inter, use LGA,   update none
+*  Frame 14  Inter, use LGA,   update L
+*  Frame 15  Inter, use LGA,   update none
+*  ...Repeats the pattern from frame 0
+
+Change this variable to test the 3 decodable streams case.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
+int                  num_streams = 5;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG
+flags = 0;
+if(num_streams == 5)
+{
+    switch(frame_cnt % 16) {
+        case 0:
+            flags |= VPX_EFLAG_FORCE_KF;
+            flags |= VP8_EFLAG_FORCE_GF;
+            flags |= VP8_EFLAG_FORCE_ARF;
+            break;
+        case 1:
+        case 3:
+        case 5:
+        case 7:
+        case 9:
+        case 11:
+        case 13:
+        case 15:
+            flags |= VP8_EFLAG_NO_UPD_LAST;
+            flags |= VP8_EFLAG_NO_UPD_GF;
+            flags |= VP8_EFLAG_NO_UPD_ARF;
+            break;
+        case 2:
+        case 6:
+        case 10:
+        case 14:
+            break;
+        case 4:
+            flags |= VP8_EFLAG_NO_REF_LAST;
+            flags |= VP8_EFLAG_FORCE_GF;
+            break;
+        case 8:
+            flags |= VP8_EFLAG_NO_REF_LAST;
+            flags |= VP8_EFLAG_NO_REF_GF;
+            flags |= VP8_EFLAG_FORCE_GF;
+            flags |= VP8_EFLAG_FORCE_ARF;
+            break;
+        case 12:
+            flags |= VP8_EFLAG_NO_REF_LAST;
+            flags |= VP8_EFLAG_FORCE_GF;
+            break;
+    }
+}
+else
+{
+    switch(frame_cnt % 9) {
+        case 0:
+            if(frame_cnt==0)
+            {
+                flags |= VPX_EFLAG_FORCE_KF;
+            }
+            else
+            {
+                cfg.rc_max_quantizer = 26;
+                cfg.rc_min_quantizer = 0;
+                cfg.rc_target_bitrate = 300;
+                flags |= VP8_EFLAG_NO_REF_LAST;
+                flags |= VP8_EFLAG_NO_REF_ARF;
+            }
+            flags |= VP8_EFLAG_FORCE_GF;
+            flags |= VP8_EFLAG_FORCE_ARF;
+            break;
+        case 1:
+        case 2:
+        case 4:
+        case 5:
+        case 7:
+        case 8:
+            cfg.rc_max_quantizer = 45;
+            cfg.rc_min_quantizer = 0;
+            cfg.rc_target_bitrate = 230;
+            break;
+        case 3:
+        case 6:
+            cfg.rc_max_quantizer = 45;
+            cfg.rc_min_quantizer = 0;
+            cfg.rc_target_bitrate = 215;
+            flags |= VP8_EFLAG_NO_REF_LAST;
+            flags |= VP8_EFLAG_FORCE_ARF;
+            break;
+    }
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PER_FRAME_CFG
+
+Observing The Effects
+---------------------
+Use the `decode_with_drops` example to decode with various dropped frame
+patterns. Good patterns to start with are 1/2, 3/4, 7/8, and 15/16
+drops.
diff --git a/examples/vp8_set_maps.txt b/examples/vp8_set_maps.txt
new file mode 100644 (file)
index 0000000..94554ba
--- /dev/null
@@ -0,0 +1,96 @@
+@TEMPLATE encoder_tmpl.c
+VP8 Set Active and ROI Maps
+===========================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example demonstrating how to control the VP8 encoder's
+ROI and Active maps.
+
+ROI (Reigon of Interest) maps are a way for the application to assign
+each macroblock in the image to a region, and then set quantizer and
+filtering parameters on that image.
+
+Active maps are a way for the application to specify on a
+macroblock-by-macroblock basis whether there is any activity in that
+macroblock.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Configuration
+-------------
+An ROI map is set on frame 22. If the width of the image in macroblocks
+is evenly divisble by 4, then the output will appear to have distinct
+columns, where the quantizer, loopfilter, and static threshold differ
+from column to column.
+
+An active map is set on frame 33. If the width of the image in macroblocks
+is evenly divisble by 4, then the output will appear to have distinct
+columns, where one column will have motion and the next will not.
+
+The active map is cleared on frame 44.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  PER_FRAME_CFG
+if(frame_cnt + 1 == 22) {
+    vpx_roi_map_t  roi;
+    int            i;
+
+    roi.rows = cfg.g_h/16;
+    roi.cols = cfg.g_w/16;
+
+    roi.delta_q[0] = 0;
+    roi.delta_q[1] = -2;
+    roi.delta_q[2] = -4;
+    roi.delta_q[3] = -6;
+
+    roi.delta_lf[0] = 0;
+    roi.delta_lf[1] = 1;
+    roi.delta_lf[2] = 2;
+    roi.delta_lf[3] = 3;
+
+    roi.static_threshold[0] = 1500;
+    roi.static_threshold[1] = 1000;
+    roi.static_threshold[2] =  500;
+    roi.static_threshold[3] =    0;
+
+    /* generate an ROI map for example */
+    roi.roi_map = malloc(roi.rows * roi.cols);
+    for(i=0;i<roi.rows*roi.cols;i++)
+        roi.roi_map[i] = i & 3;
+
+    if(vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
+        die_codec(&codec, "Failed to set ROI map");
+
+    free(roi.roi_map);
+} else if(frame_cnt + 1 == 33) {
+    vpx_active_map_t  active;
+    int               i;
+
+    active.rows = cfg.g_h/16;
+    active.cols = cfg.g_w/16;
+
+    /* generate active map for example */
+    active.active_map = malloc(active.rows * active.cols);
+    for(i=0;i<active.rows*active.cols;i++)
+        active.active_map[i] = i & 1;
+
+    if(vpx_codec_control(&codec, VP8E_SET_ACTIVEMAP, &active))
+        die_codec(&codec, "Failed to set active map");
+
+    free(active.active_map);
+} else if(frame_cnt + 1 == 44) {
+    vpx_active_map_t  active;
+
+    active.rows = 240/16;
+    active.cols = 320/16;
+
+    /* pass in null map to disable active_map*/
+    active.active_map = NULL;
+
+    if(vpx_codec_control(&codec, VP8E_SET_ACTIVEMAP, &active))
+        die_codec(&codec, "Failed to set active map");
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  PER_FRAME_CFG
+
+
+Observing The Effects
+---------------------
+Use the `simple_decoder` example to decode this sample, and observe
+the change in the image at frames 22, 33, and 44.
diff --git a/examples/vp8cx_set_ref.txt b/examples/vp8cx_set_ref.txt
new file mode 100644 (file)
index 0000000..dc8a717
--- /dev/null
@@ -0,0 +1,73 @@
+@TEMPLATE encoder_tmpl.c
+VP8 Set Reference Frame
+=======================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+This is an example demonstrating how to overwrite the VP8 encoder's
+internal reference frame. In the sample we set the last frame to the
+current frame. If this is done at a cut scene it will avoid a keyframe.
+This technique could be used to bounce between two cameras.
+
+Note that the decoder would also have to set the reference frame to the
+same value on the same frame, or the video will become corrupt.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTRODUCTION
+
+
+Usage
+-----
+This example adds a single argument to the `simple_encoder` example,
+which specifies the frame number to update the reference frame on.
+The parameter is parsed as follows:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+if(argc!=6)
+    die("Usage: %s <width> <height> <infile> <outfile> <frame>\n",
+        argv[0]);
+
+    update_frame_num = atoi(argv[5]);
+    if(!update_frame_num)
+        die("Couldn't parse frame number '%s'\n", argv[5]);
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
+
+
+Extra Variables
+---------------
+This example maintains the frame number passed on the command line
+in the `update_frame_num` variable:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
+int                  update_frame_num = 0;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TWOPASS_VARS
+
+
+Configuration
+-------------
+
+The reference frame is updated on the frame specified on the command
+line.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+frame_avail = read_frame(infile, &raw);
+
+if(frame_cnt + 1 == update_frame_num) {
+    vpx_ref_frame_t ref;
+
+    ref.frame_type = VP8_LAST_FRAME;
+    ref.img        = raw;
+
+    if(vpx_codec_control(&codec, VP8_SET_REFERENCE, &ref))
+        die_codec(&codec, "Failed to set reference frame");
+}
+
+if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt,
+                    1, flags, VPX_DL_REALTIME))
+    die_codec(&codec, "Failed to encode frame");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENCODE_FRAME
+
+
+Observing The Effects
+---------------------
+Use the `simple_encoder` example to encode a sample with a cut scene.
+Determine the frame number of the cut scene by looking for a generated
+key-frame (indicated by a 'K'). Supply that frame number as an argument
+to this example, and observe that no key-frame is generated.
diff --git a/ivfdec.c b/ivfdec.c
new file mode 100644 (file)
index 0000000..e4c9981
--- /dev/null
+++ b/ivfdec.c
@@ -0,0 +1,593 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This is a simple program that reads ivf files and decodes them
+ * using the new interface. Decoded frames are output as YV12 raw.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define VPX_CODEC_DISABLE_COMPAT 1
+#include "vpx_config.h"
+#include "vpx_decoder.h"
+#include "vpx_ports/vpx_timer.h"
+#if CONFIG_VP8_DECODER
+#include "vp8dx.h"
+#endif
+#if CONFIG_MD5
+#include "md5_utils.h"
+#endif
+
+static const char *exec_name;
+
+static const struct
+{
+    char const *name;
+    const vpx_codec_iface_t *iface;
+    unsigned int             fourcc;
+    unsigned int             fourcc_mask;
+} ifaces[] =
+{
+#if CONFIG_VP8_DECODER
+    {"vp8",  &vpx_codec_vp8_dx_algo,   0x00385056, 0x00FFFFFF},
+#endif
+};
+
+#include "args.h"
+static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1,
+                                  "Codec to use");
+static const arg_def_t prefixarg = ARG_DEF("p", "prefix", 1,
+                                   "Prefix to use when saving frames");
+static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0,
+                                  "Output file is YV12 ");
+static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
+                                  "Output file is I420 (default)");
+static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0,
+                                   "Synonym for --yv12");
+static const arg_def_t noblitarg = ARG_DEF(NULL, "noblit", 0,
+                                   "Don't process the decoded frames");
+static const arg_def_t progressarg = ARG_DEF(NULL, "progress", 0,
+                                     "Show progress after each frame decodes");
+static const arg_def_t limitarg = ARG_DEF(NULL, "limit", 1,
+                                  "Stop decoding after n frames");
+static const arg_def_t postprocarg = ARG_DEF(NULL, "postproc", 0,
+                                     "Postprocess decoded frames");
+static const arg_def_t summaryarg = ARG_DEF(NULL, "summary", 0,
+                                    "Show timing summary");
+static const arg_def_t outputfile = ARG_DEF("o", "output-raw-file", 1,
+                                    "Output raw yv12 file instead of images");
+static const arg_def_t threadsarg = ARG_DEF("t", "threads", 1,
+                                    "Max threads to use");
+static const arg_def_t quietarg = ARG_DEF("q", "quiet", 0,
+                                  "Suppress version string");
+
+#if CONFIG_MD5
+static const arg_def_t md5arg = ARG_DEF(NULL, "md5", 0,
+                                        "Compute the MD5 sum of the decoded frame");
+#endif
+static const arg_def_t *all_args[] =
+{
+    &codecarg, &prefixarg, &use_yv12, &use_i420, &flipuvarg, &noblitarg,
+    &progressarg, &limitarg, &postprocarg, &summaryarg, &outputfile,
+    &threadsarg, &quietarg,
+#if CONFIG_MD5
+    &md5arg,
+#endif
+    NULL
+};
+
+#if CONFIG_VP8_DECODER
+static const arg_def_t addnoise_level = ARG_DEF(NULL, "noise-level", 1,
+                                        "Enable VP8 postproc add noise");
+static const arg_def_t deblock = ARG_DEF(NULL, "deblock", 0,
+                                 "Enable VP8 deblocking");
+static const arg_def_t demacroblock_level = ARG_DEF(NULL, "demacroblock-level", 1,
+        "Enable VP8 demacroblocking, w/ level");
+static const arg_def_t pp_debug_info = ARG_DEF(NULL, "pp-debug-info", 1,
+                                       "Enable VP8 visible debug info");
+
+
+static const arg_def_t *vp8_pp_args[] =
+{
+    &addnoise_level, &deblock, &demacroblock_level, &pp_debug_info,
+    NULL
+};
+#endif
+
+static void usage_exit()
+{
+    int i;
+
+    fprintf(stderr, "Usage: %s <options> filename\n\n"
+            "Options:\n", exec_name);
+    arg_show_usage(stderr, all_args);
+#if CONFIG_VP8_DECODER
+    fprintf(stderr, "\nvp8 Postprocessing Options:\n");
+    arg_show_usage(stderr, vp8_pp_args);
+#endif
+    fprintf(stderr, "\nIncluded decoders:\n\n");
+
+    for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
+        fprintf(stderr, "    %-6s - %s\n",
+                ifaces[i].name,
+                vpx_codec_iface_name(ifaces[i].iface));
+
+    exit(EXIT_FAILURE);
+}
+
+void die(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    usage_exit();
+}
+
+static unsigned int mem_get_le16(const void *vmem)
+{
+    unsigned int  val;
+    const unsigned char *mem = (const unsigned char *)vmem;
+
+    val = mem[1] << 8;
+    val |= mem[0];
+    return val;
+}
+
+static unsigned int mem_get_le32(const void *vmem)
+{
+    unsigned int  val;
+    const unsigned char *mem = (const unsigned char *)vmem;
+
+    val = mem[3] << 24;
+    val |= mem[2] << 16;
+    val |= mem[1] << 8;
+    val |= mem[0];
+    return val;
+}
+
+#define IVF_FRAME_HDR_SZ (sizeof(uint32_t) + sizeof(uint64_t))
+#define RAW_FRAME_HDR_SZ (sizeof(uint32_t))
+static int read_frame(FILE                  *infile,
+                      uint8_t               **buf,
+                      uint32_t              *buf_sz,
+                      uint32_t              *buf_alloc_sz,
+                      int                    is_ivf)
+{
+    char     raw_hdr[IVF_FRAME_HDR_SZ];
+    uint32_t new_buf_sz;
+
+    /* For both the raw and ivf formats, the frame size is the first 4 bytes
+     * of the frame header. We just need to special case on the header
+     * size.
+     */
+    if (fread(raw_hdr, is_ivf ? IVF_FRAME_HDR_SZ : RAW_FRAME_HDR_SZ, 1,
+              infile) != 1)
+    {
+        if (!feof(infile))
+            fprintf(stderr, "Failed to read frame size\n");
+
+        new_buf_sz = 0;
+    }
+    else
+    {
+        new_buf_sz = mem_get_le32(raw_hdr);
+
+        if (new_buf_sz > 256 * 1024 * 1024)
+        {
+            fprintf(stderr, "Error: Read invalid frame size (%u)\n",
+                    new_buf_sz);
+            new_buf_sz = 0;
+        }
+
+        if (!is_ivf && new_buf_sz > 256 * 1024)
+            fprintf(stderr, "Warning: Read invalid frame size (%u)"
+                    " - not a raw file?\n", new_buf_sz);
+
+        if (new_buf_sz > *buf_alloc_sz)
+        {
+            uint8_t *new_buf = realloc(*buf, 2 * new_buf_sz);
+
+            if (new_buf)
+            {
+                *buf = new_buf;
+                *buf_alloc_sz = 2 * new_buf_sz;
+            }
+            else
+            {
+                fprintf(stderr, "Failed to allocate compressed data buffer\n");
+                new_buf_sz = 0;
+            }
+        }
+    }
+
+    *buf_sz = new_buf_sz;
+
+    if (*buf_sz)
+    {
+        if (fread(*buf, 1, *buf_sz, infile) != *buf_sz)
+        {
+            fprintf(stderr, "Failed to read full frame\n");
+            return 1;
+        }
+
+        return 0;
+    }
+
+    return 1;
+}
+
+void *out_open(const char *out_fn, int do_md5)
+{
+    void *out = NULL;
+
+    if (do_md5)
+    {
+#if CONFIG_MD5
+        md5_ctx_t *md5_ctx = out = malloc(sizeof(md5_ctx_t));
+        (void)out_fn;
+        md5_init(md5_ctx);
+#endif
+    }
+    else
+    {
+        FILE *outfile = out = strcmp("-", out_fn) ? fopen(out_fn, "wb") : stdout;
+
+        if (!outfile)
+        {
+            fprintf(stderr, "Failed to output file");
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    return out;
+}
+
+void out_put(void *out, const uint8_t *buf, unsigned int len, int do_md5)
+{
+    if (do_md5)
+    {
+#if CONFIG_MD5
+        md5_update(out, buf, len);
+#endif
+    }
+    else
+    {
+        fwrite(buf, 1, len, out);
+    }
+}
+
+void out_close(void *out, const char *out_fn, int do_md5)
+{
+    if (do_md5)
+    {
+#if CONFIG_MD5
+        uint8_t md5[16];
+        int i;
+
+        md5_finalize(out, md5);
+        free(out);
+
+        for (i = 0; i < 16; i++)
+            printf("%02x", md5[i]);
+
+        printf("  %s\n", out_fn);
+#endif
+    }
+    else
+    {
+        fclose(out);
+    }
+}
+
+unsigned int file_is_ivf(FILE *infile, unsigned int *fourcc)
+{
+    char raw_hdr[32];
+    int is_ivf = 0;
+
+    if (fread(raw_hdr, 1, 32, infile) == 32)
+    {
+        if (raw_hdr[0] == 'D' && raw_hdr[1] == 'K'
+            && raw_hdr[2] == 'I' && raw_hdr[3] == 'F')
+        {
+            is_ivf = 1;
+
+            if (mem_get_le16(raw_hdr + 4) != 0)
+                fprintf(stderr, "Error: Unrecognized IVF version! This file may not"
+                        " decode properly.");
+
+            *fourcc = mem_get_le32(raw_hdr + 8);
+        }
+    }
+
+    if (!is_ivf)
+        rewind(infile);
+
+    return is_ivf;
+}
+
+int main(int argc, const char **argv_)
+{
+    vpx_codec_ctx_t          decoder;
+    char                  *prefix = NULL, *fn = NULL;
+    int                    i;
+    uint8_t               *buf = NULL;
+    uint32_t               buf_sz = 0, buf_alloc_sz = 0;
+    FILE                  *infile;
+    int                    frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0, do_md5 = 0, progress = 0;
+    int                    stop_after = 0, postproc = 0, summary = 0, quiet = 0;
+    vpx_codec_iface_t       *iface = NULL;
+    unsigned int           is_ivf, fourcc;
+    unsigned long          dx_time = 0;
+    struct arg               arg;
+    char                   **argv, **argi, **argj;
+    const char                   *fn2 = 0;
+    void                   *out = NULL;
+    vpx_codec_dec_cfg_t     cfg = {0};
+#if CONFIG_VP8_DECODER
+    vp8_postproc_cfg_t      vp8_pp_cfg = {0};
+#endif
+
+    /* Parse command line */
+    exec_name = argv_[0];
+    argv = argv_dup(argc - 1, argv_ + 1);
+
+    for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step)
+    {
+        memset(&arg, 0, sizeof(arg));
+        arg.argv_step = 1;
+
+        if (arg_match(&arg, &codecarg, argi))
+        {
+            int j, k = -1;
+
+            for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++)
+                if (!strcmp(ifaces[j].name, arg.val))
+                    k = j;
+
+            if (k >= 0)
+                iface = ifaces[k].iface;
+            else
+                die("Error: Unrecognized argument (%s) to --codec\n",
+                    arg.val);
+        }
+        else if (arg_match(&arg, &outputfile, argi))
+            fn2 = arg.val;
+        else if (arg_match(&arg, &prefixarg, argi))
+            prefix = strdup(arg.val);
+        else if (arg_match(&arg, &use_yv12, argi))
+            flipuv = 1;
+        else if (arg_match(&arg, &use_i420, argi))
+            flipuv = 0;
+        else if (arg_match(&arg, &flipuvarg, argi))
+            flipuv = 1;
+        else if (arg_match(&arg, &noblitarg, argi))
+            noblit = 1;
+        else if (arg_match(&arg, &progressarg, argi))
+            progress = 1;
+        else if (arg_match(&arg, &limitarg, argi))
+            stop_after = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &postprocarg, argi))
+            postproc = 1;
+        else if (arg_match(&arg, &md5arg, argi))
+            do_md5 = 1;
+        else if (arg_match(&arg, &summaryarg, argi))
+            summary = 1;
+        else if (arg_match(&arg, &threadsarg, argi))
+            cfg.threads = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &quietarg, argi))
+            quiet = 1;
+
+#if CONFIG_VP8_DECODER
+        else if (arg_match(&arg, &addnoise_level, argi))
+        {
+            postproc = 1;
+            vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
+            vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
+        }
+        else if (arg_match(&arg, &demacroblock_level, argi))
+        {
+            postproc = 1;
+            vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
+            vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
+        }
+        else if (arg_match(&arg, &deblock, argi))
+        {
+            postproc = 1;
+            vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK;
+        }
+        else if (arg_match(&arg, &pp_debug_info, argi))
+        {
+            unsigned int level = arg_parse_uint(&arg);
+
+            postproc = 1;
+            vp8_pp_cfg.post_proc_flag &= ~0x7;
+
+            if (level)
+                vp8_pp_cfg.post_proc_flag |= 8 << (level - 1);
+        }
+
+#endif
+        else
+            argj++;
+    }
+
+    /* Check for unrecognized options */
+    for (argi = argv; *argi; argi++)
+        if (argi[0][0] == '-' && strlen(argi[0]) > 1)
+            die("Error: Unrecognized option %s\n", *argi);
+
+    /* Handle non-option arguments */
+    fn = argv[0];
+
+    if (!fn)
+        usage_exit();
+
+    if (!prefix)
+        prefix = strdup("img");
+
+    /* Open file */
+    infile = strcmp(fn, "-") ? fopen(fn, "rb") : stdin;
+
+    if (!infile)
+    {
+        fprintf(stderr, "Failed to open file");
+        return EXIT_FAILURE;
+    }
+
+    if (fn2)
+        out = out_open(fn2, do_md5);
+
+    is_ivf = file_is_ivf(infile, &fourcc);
+
+    if (is_ivf)
+    {
+        /* Try to determine the codec from the fourcc. */
+        for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++)
+            if ((fourcc & ifaces[i].fourcc_mask) == ifaces[i].fourcc)
+            {
+                vpx_codec_iface_t  *ivf_iface = ifaces[i].iface;
+
+                if (iface && iface != ivf_iface)
+                    fprintf(stderr, "Notice -- IVF header indicates codec: %s\n",
+                            ifaces[i].name);
+                else
+                    iface = ivf_iface;
+
+                break;
+            }
+    }
+
+    if (vpx_codec_dec_init(&decoder, iface ? iface :  ifaces[0].iface, &cfg,
+                           postproc ? VPX_CODEC_USE_POSTPROC : 0))
+    {
+        fprintf(stderr, "Failed to initialize decoder: %s\n", vpx_codec_error(&decoder));
+        return EXIT_FAILURE;
+    }
+
+    if (!quiet)
+        fprintf(stderr, "%s\n", decoder.name);
+
+#if CONFIG_VP8_DECODER
+
+    if (vp8_pp_cfg.post_proc_flag
+        && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg))
+    {
+        fprintf(stderr, "Failed to configure postproc: %s\n", vpx_codec_error(&decoder));
+        return EXIT_FAILURE;
+    }
+
+#endif
+
+    /* Decode file */
+    while (!read_frame(infile, &buf, &buf_sz, &buf_alloc_sz, is_ivf))
+    {
+        vpx_codec_iter_t  iter = NULL;
+        vpx_image_t    *img;
+        struct vpx_usec_timer timer;
+
+        vpx_usec_timer_start(&timer);
+
+        if (vpx_codec_decode(&decoder, buf, buf_sz, NULL, 0))
+        {
+            const char *detail = vpx_codec_error_detail(&decoder);
+            fprintf(stderr, "Failed to decode frame: %s\n", vpx_codec_error(&decoder));
+
+            if (detail)
+                fprintf(stderr, "  Additional information: %s\n", detail);
+
+            goto fail;
+        }
+
+        vpx_usec_timer_mark(&timer);
+        dx_time += vpx_usec_timer_elapsed(&timer);
+
+        ++frame_in;
+
+        if (progress)
+            fprintf(stderr, "decoded frame %d.\n", frame_in);
+
+        if ((img = vpx_codec_get_frame(&decoder, &iter)))
+            ++frame_out;
+
+        if (!noblit)
+        {
+            if (img)
+            {
+                unsigned int y;
+                char out_fn[128+24];
+                uint8_t *buf;
+                const char *sfx = flipuv ? "yv12" : "i420";
+
+                if (!fn2)
+                {
+                    sprintf(out_fn, "%s-%dx%d-%04d.%s",
+                            prefix, img->d_w, img->d_h, frame_in, sfx);
+                    out = out_open(out_fn, do_md5);
+                }
+
+                buf = img->planes[PLANE_Y];
+
+                for (y = 0; y < img->d_h; y++)
+                {
+                    out_put(out, buf, img->d_w, do_md5);
+                    buf += img->stride[PLANE_Y];
+                }
+
+                buf = img->planes[flipuv?PLANE_V:PLANE_U];
+
+                for (y = 0; y < (1 + img->d_h) / 2; y++)
+                {
+                    out_put(out, buf, (1 + img->d_w) / 2, do_md5);
+                    buf += img->stride[PLANE_U];
+                }
+
+                buf = img->planes[flipuv?PLANE_U:PLANE_V];
+
+                for (y = 0; y < (1 + img->d_h) / 2; y++)
+                {
+                    out_put(out, buf, (1 + img->d_w) / 2, do_md5);
+                    buf += img->stride[PLANE_V];
+                }
+
+                if (!fn2)
+                    out_close(out, out_fn, do_md5);
+            }
+        }
+
+        if (stop_after && frame_in >= stop_after)
+            break;
+    }
+
+    if (summary)
+    {
+        fprintf(stderr, "%d decoded frames/%d showed frames in %lu us (%.2f fps)\n",
+                frame_in, frame_out, dx_time, (float)frame_out * 1000000.0 / (float)dx_time);
+    }
+
+fail:
+
+    if (vpx_codec_destroy(&decoder))
+    {
+        fprintf(stderr, "Failed to destroy decoder: %s\n", vpx_codec_error(&decoder));
+        return EXIT_FAILURE;
+    }
+
+    if (fn2)
+        out_close(out, fn2, do_md5);
+
+    free(buf);
+    fclose(infile);
+    free(prefix);
+    free(argv);
+
+    return EXIT_SUCCESS;
+}
diff --git a/ivfenc.c b/ivfenc.c
new file mode 100644 (file)
index 0000000..bef3d58
--- /dev/null
+++ b/ivfenc.c
@@ -0,0 +1,1059 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This is a simple program that encodes YV12 files and generates ivf
+ * files using the new interface.
+ */
+#define USE_POSIX_MMAP HAVE_SYS_MMAN_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "vpx_encoder.h"
+#if USE_POSIX_MMAP
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+#if CONFIG_VP8_ENCODER
+#include "vp8cx.h"
+#endif
+#include "vpx_ports/mem_ops.h"
+#include "vpx_ports/vpx_timer.h"
+
+static const char *exec_name;
+
+static const struct codec_item
+{
+    char const              *name;
+    const vpx_codec_iface_t *iface;
+    unsigned int             fourcc;
+} codecs[] =
+{
+#if CONFIG_VP8_ENCODER
+    {"vp8",  &vpx_codec_vp8_cx_algo, 0x30385056},
+#endif
+};
+
+static void usage_exit();
+
+void die(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    printf("\n");
+    usage_exit();
+}
+
+static void ctx_exit_on_error(vpx_codec_ctx_t *ctx, const char *s)
+{
+    if (ctx->err)
+    {
+        const char *detail = vpx_codec_error_detail(ctx);
+
+        printf("%s: %s\n", s, vpx_codec_error(ctx));
+
+        if (detail)
+            printf("    %s\n", detail);
+
+        exit(EXIT_FAILURE);
+    }
+}
+
+/* This structure is used to abstract the different ways of handling
+ * first pass statistics.
+ */
+typedef struct
+{
+    vpx_fixed_buf_t buf;
+    int             pass;
+    FILE           *file;
+    char           *buf_ptr;
+    size_t          buf_alloc_sz;
+} stats_io_t;
+
+int stats_open_file(stats_io_t *stats, const char *fpf, int pass)
+{
+    int res;
+
+    stats->pass = pass;
+
+    if (pass == 0)
+    {
+        stats->file = fopen(fpf, "wb");
+        stats->buf.sz = 0;
+        stats->buf.buf = NULL,
+                   res = (stats->file != NULL);
+    }
+    else
+    {
+#if 0
+#elif USE_POSIX_MMAP
+        struct stat stat_buf;
+        int fd;
+
+        fd = open(fpf, O_RDONLY);
+        stats->file = fdopen(fd, "rb");
+        fstat(fd, &stat_buf);
+        stats->buf.sz = stat_buf.st_size;
+        stats->buf.buf = mmap(NULL, stats->buf.sz, PROT_READ, MAP_PRIVATE,
+                              fd, 0);
+        res = (stats->buf.buf != NULL);
+#else
+        size_t nbytes;
+
+        stats->file = fopen(fpf, "rb");
+
+        if (fseek(stats->file, 0, SEEK_END))
+        {
+            fprintf(stderr, "First-pass stats file must be seekable!\n");
+            exit(EXIT_FAILURE);
+        }
+
+        stats->buf.sz = stats->buf_alloc_sz = ftell(stats->file);
+        rewind(stats->file);
+
+        stats->buf.buf = malloc(stats->buf_alloc_sz);
+
+        if (!stats->buf.buf)
+        {
+            fprintf(stderr, "Failed to allocate first-pass stats buffer (%d bytes)\n",
+                    stats->buf_alloc_sz);
+            exit(EXIT_FAILURE);
+        }
+
+        nbytes = fread(stats->buf.buf, 1, stats->buf.sz, stats->file);
+        res = (nbytes == stats->buf.sz);
+#endif
+    }
+
+    return res;
+}
+
+int stats_open_mem(stats_io_t *stats, int pass)
+{
+    int res;
+    stats->pass = pass;
+
+    if (!pass)
+    {
+        stats->buf.sz = 0;
+        stats->buf_alloc_sz = 64 * 1024;
+        stats->buf.buf = malloc(stats->buf_alloc_sz);
+    }
+
+    stats->buf_ptr = stats->buf.buf;
+    res = (stats->buf.buf != NULL);
+    return res;
+}
+
+
+void stats_close(stats_io_t *stats)
+{
+    if (stats->file)
+    {
+        if (stats->pass == 1)
+        {
+#if 0
+#elif USE_POSIX_MMAP
+            munmap(stats->buf.buf, stats->buf.sz);
+#else
+            free(stats->buf.buf);
+#endif
+        }
+
+        fclose(stats->file);
+        stats->file = NULL;
+    }
+    else
+    {
+        if (stats->pass == 1)
+            free(stats->buf.buf);
+    }
+}
+
+void stats_write(stats_io_t *stats, const void *pkt, size_t len)
+{
+    if (stats->file)
+    {
+        fwrite(pkt, 1, len, stats->file);
+    }
+    else
+    {
+        if (stats->buf.sz + len > stats->buf_alloc_sz)
+        {
+            size_t  new_sz = stats->buf_alloc_sz + 64 * 1024;
+            char   *new_ptr = realloc(stats->buf.buf, new_sz);
+
+            if (new_ptr)
+            {
+                stats->buf_ptr = new_ptr + (stats->buf_ptr - (char *)stats->buf.buf);
+                stats->buf.buf = new_ptr;
+                stats->buf_alloc_sz = new_sz;
+            } /* else ... */
+        }
+
+        memcpy(stats->buf_ptr, pkt, len);
+        stats->buf.sz += len;
+        stats->buf_ptr += len;
+    }
+}
+
+vpx_fixed_buf_t stats_get(stats_io_t *stats)
+{
+    return stats->buf;
+}
+
+#define IVF_FRAME_HDR_SZ (4+8) /* 4 byte size + 8 byte timestamp */
+static int read_frame(FILE *f, vpx_image_t *img, unsigned int is_ivf)
+{
+    int plane = 0;
+
+    if (is_ivf)
+    {
+        char junk[IVF_FRAME_HDR_SZ];
+
+        /* Skip the frame header. We know how big the frame should be. See
+         * write_ivf_frame_header() for documentation on the frame header
+         * layout.
+         */
+        fread(junk, 1, IVF_FRAME_HDR_SZ, f);
+    }
+
+    for (plane = 0; plane < 3; plane++)
+    {
+        unsigned char *ptr;
+        int w = (plane ? (1 + img->d_w) / 2 : img->d_w);
+        int h = (plane ? (1 + img->d_h) / 2 : img->d_h);
+        int r;
+
+        /* Determine the correct plane based on the image format. The for-loop
+         * always counts in Y,U,V order, but this may not match the order of
+         * the data on disk.
+         */
+        switch (plane)
+        {
+        case 1:
+            ptr = img->planes[img->fmt==IMG_FMT_YV12? PLANE_V : PLANE_U];
+            break;
+        case 2:
+            ptr = img->planes[img->fmt==IMG_FMT_YV12?PLANE_U : PLANE_V];
+            break;
+        default:
+            ptr = img->planes[plane];
+        }
+
+        for (r = 0; r < h; r++)
+        {
+            fread(ptr, 1, w, f);
+            ptr += img->stride[plane];
+        }
+    }
+
+    return !feof(f);
+}
+
+
+#define IVF_FILE_HDR_SZ (32)
+unsigned int file_is_ivf(FILE *infile,
+                         unsigned int *fourcc,
+                         unsigned int *width,
+                         unsigned int *height)
+{
+    char raw_hdr[IVF_FILE_HDR_SZ];
+    int is_ivf = 0;
+
+    /* See write_ivf_file_header() for more documentation on the file header
+     * layout.
+     */
+    if (fread(raw_hdr, 1, IVF_FILE_HDR_SZ, infile) == IVF_FILE_HDR_SZ)
+    {
+        if (raw_hdr[0] == 'D' && raw_hdr[1] == 'K'
+            && raw_hdr[2] == 'I' && raw_hdr[3] == 'F')
+        {
+            is_ivf = 1;
+
+            if (mem_get_le16(raw_hdr + 4) != 0)
+                fprintf(stderr, "Error: Unrecognized IVF version! This file may not"
+                        " decode properly.");
+
+            *fourcc = mem_get_le32(raw_hdr + 8);
+        }
+    }
+
+    if (is_ivf)
+    {
+        *width = mem_get_le16(raw_hdr + 12);
+        *height = mem_get_le16(raw_hdr + 14);
+    }
+    else
+        rewind(infile);
+
+    return is_ivf;
+}
+
+
+static void write_ivf_file_header(FILE *outfile,
+                                  const vpx_codec_enc_cfg_t *cfg,
+                                  unsigned int fourcc,
+                                  int frame_cnt)
+{
+    char header[32];
+
+    if (cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
+        return;
+
+    header[0] = 'D';
+    header[1] = 'K';
+    header[2] = 'I';
+    header[3] = 'F';
+    mem_put_le16(header + 4,  0);                 /* version */
+    mem_put_le16(header + 6,  32);                /* headersize */
+    mem_put_le32(header + 8,  fourcc);            /* headersize */
+    mem_put_le16(header + 12, cfg->g_w);          /* width */
+    mem_put_le16(header + 14, cfg->g_h);          /* height */
+    mem_put_le32(header + 16, cfg->g_timebase.den); /* rate */
+    mem_put_le32(header + 20, cfg->g_timebase.num); /* scale */
+    mem_put_le32(header + 24, frame_cnt);         /* length */
+    mem_put_le32(header + 28, 0);                 /* unused */
+
+    fwrite(header, 1, 32, outfile);
+}
+
+
+static void write_ivf_frame_header(FILE *outfile,
+                                   const vpx_codec_cx_pkt_t *pkt)
+{
+    char             header[12];
+    vpx_codec_pts_t  pts;
+
+    if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
+        return;
+
+    pts = pkt->data.frame.pts;
+    mem_put_le32(header, pkt->data.frame.sz);
+    mem_put_le32(header + 4, pts & 0xFFFFFFFF);
+    mem_put_le32(header + 8, pts >> 32);
+
+    fwrite(header, 1, 12, outfile);
+}
+
+#include "args.h"
+
+static const arg_def_t use_yv12 = ARG_DEF(NULL, "yv12", 0,
+                                  "Input file is YV12 ");
+static const arg_def_t use_i420 = ARG_DEF(NULL, "i420", 0,
+                                  "Input file is I420 (default)");
+static const arg_def_t codecarg = ARG_DEF(NULL, "codec", 1,
+                                  "Codec to use");
+static const arg_def_t passes           = ARG_DEF("p", "passes", 1,
+        "Number of passes (1/2)");
+static const arg_def_t pass_arg         = ARG_DEF(NULL, "pass", 1,
+        "Pass to execute (1/2)");
+static const arg_def_t fpf_name         = ARG_DEF(NULL, "fpf", 1,
+        "First pass statistics file name");
+static const arg_def_t limit = ARG_DEF(NULL, "limit", 1,
+                                       "Stop encoding after n input frames");
+static const arg_def_t deadline         = ARG_DEF("d", "deadline", 1,
+        "Deadline per frame (usec)");
+static const arg_def_t best_dl          = ARG_DEF(NULL, "best", 0,
+        "Use Best Quality Deadline");
+static const arg_def_t good_dl          = ARG_DEF(NULL, "good", 0,
+        "Use Good Quality Deadline");
+static const arg_def_t rt_dl            = ARG_DEF(NULL, "rt", 0,
+        "Use Realtime Quality Deadline");
+static const arg_def_t verbosearg       = ARG_DEF("v", "verbose", 0,
+        "Show encoder parameters");
+static const arg_def_t psnrarg          = ARG_DEF(NULL, "psnr", 0,
+        "Show PSNR in status line");
+static const arg_def_t *main_args[] =
+{
+    &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline, &best_dl, &good_dl, &rt_dl,
+    &verbosearg, &psnrarg,
+    NULL
+};
+
+static const arg_def_t usage            = ARG_DEF("u", "usage", 1,
+        "Usage profile number to use");
+static const arg_def_t threads          = ARG_DEF("t", "threads", 1,
+        "Max number of threads to use");
+static const arg_def_t profile          = ARG_DEF(NULL, "profile", 1,
+        "Bitstream profile number to use");
+static const arg_def_t width            = ARG_DEF("w", "width", 1,
+        "Frame width");
+static const arg_def_t height           = ARG_DEF("h", "height", 1,
+        "Frame height");
+static const arg_def_t timebase         = ARG_DEF(NULL, "timebase", 1,
+        "Stream timebase (frame duration)");
+static const arg_def_t error_resilient  = ARG_DEF(NULL, "error-resilient", 1,
+        "Enable error resiliency features");
+static const arg_def_t lag_in_frames    = ARG_DEF(NULL, "lag-in-frames", 1,
+        "Max number of frames to lag");
+
+static const arg_def_t *global_args[] =
+{
+    &use_yv12, &use_i420, &usage, &threads, &profile,
+    &width, &height, &timebase, &error_resilient,
+    &lag_in_frames, NULL
+};
+
+static const arg_def_t dropframe_thresh   = ARG_DEF(NULL, "drop-frame", 1,
+        "Temporal resampling threshold (buf %)");
+static const arg_def_t resize_allowed     = ARG_DEF(NULL, "resize-allowed", 1,
+        "Spatial resampling enabled (bool)");
+static const arg_def_t resize_up_thresh   = ARG_DEF(NULL, "resize-up", 1,
+        "Upscale threshold (buf %)");
+static const arg_def_t resize_down_thresh = ARG_DEF(NULL, "resize-down", 1,
+        "Downscale threshold (buf %)");
+static const arg_def_t end_usage          = ARG_DEF(NULL, "end-usage", 1,
+        "VBR=0 | CBR=1");
+static const arg_def_t target_bitrate     = ARG_DEF(NULL, "target-bitrate", 1,
+        "Bitrate (kbps)");
+static const arg_def_t min_quantizer      = ARG_DEF(NULL, "min-q", 1,
+        "Minimum (best) quantizer");
+static const arg_def_t max_quantizer      = ARG_DEF(NULL, "max-q", 1,
+        "Maximum (worst) quantizer");
+static const arg_def_t undershoot_pct     = ARG_DEF(NULL, "undershoot-pct", 1,
+        "Datarate undershoot (min) target (%)");
+static const arg_def_t overshoot_pct      = ARG_DEF(NULL, "overshoot-pct", 1,
+        "Datarate overshoot (max) target (%)");
+static const arg_def_t buf_sz             = ARG_DEF(NULL, "buf-sz", 1,
+        "Client buffer size (ms)");
+static const arg_def_t buf_initial_sz     = ARG_DEF(NULL, "buf-initial-sz", 1,
+        "Client initial buffer size (ms)");
+static const arg_def_t buf_optimal_sz     = ARG_DEF(NULL, "buf-optimal-sz", 1,
+        "Client optimal buffer size (ms)");
+static const arg_def_t *rc_args[] =
+{
+    &dropframe_thresh, &resize_allowed, &resize_up_thresh, &resize_down_thresh,
+    &end_usage, &target_bitrate, &min_quantizer, &max_quantizer,
+    &undershoot_pct, &overshoot_pct, &buf_sz, &buf_initial_sz, &buf_optimal_sz,
+    NULL
+};
+
+
+static const arg_def_t bias_pct = ARG_DEF(NULL, "bias-pct", 1,
+                                  "CBR/VBR bias (0=CBR, 100=VBR)");
+static const arg_def_t minsection_pct = ARG_DEF(NULL, "minsection-pct", 1,
+                                        "GOP min bitrate (% of target)");
+static const arg_def_t maxsection_pct = ARG_DEF(NULL, "maxsection-pct", 1,
+                                        "GOP max bitrate (% of target)");
+static const arg_def_t *rc_twopass_args[] =
+{
+    &bias_pct, &minsection_pct, &maxsection_pct, NULL
+};
+
+
+static const arg_def_t kf_min_dist = ARG_DEF(NULL, "kf-min-dist", 1,
+                                     "Minimum keyframe interval (frames)");
+static const arg_def_t kf_max_dist = ARG_DEF(NULL, "kf-max-dist", 1,
+                                     "Maximum keyframe interval (frames)");
+static const arg_def_t *kf_args[] =
+{
+    &kf_min_dist, &kf_max_dist, NULL
+};
+
+
+#if CONFIG_VP8_ENCODER
+static const arg_def_t noise_sens = ARG_DEF(NULL, "noise-sensitivity", 1,
+                                    "Noise sensitivity (frames to blur)");
+static const arg_def_t sharpness = ARG_DEF(NULL, "sharpness", 1,
+                                   "Filter sharpness (0-7)");
+static const arg_def_t static_thresh = ARG_DEF(NULL, "static-thresh", 1,
+                                       "Motion detection threshold");
+#endif
+
+#if CONFIG_VP8_ENCODER
+static const arg_def_t cpu_used = ARG_DEF(NULL, "cpu-used", 1,
+                                  "CPU Used (-16..16)");
+#endif
+
+
+#if CONFIG_VP8_ENCODER
+static const arg_def_t token_parts = ARG_DEF(NULL, "token-parts", 1,
+                                     "Number of token partitions to use, log2");
+static const arg_def_t auto_altref = ARG_DEF(NULL, "auto-alt-ref", 1,
+                                     "Enable automatic alt reference frames");
+static const arg_def_t arnr_maxframes = ARG_DEF(NULL, "arnr-maxframes", 1,
+                                        "alt_ref Max Frames");
+static const arg_def_t arnr_strength = ARG_DEF(NULL, "arnr-strength", 1,
+                                       "alt_ref Strength");
+static const arg_def_t arnr_type = ARG_DEF(NULL, "arnr-type", 1,
+                                   "alt_ref Type");
+
+static const arg_def_t *vp8_args[] =
+{
+    &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh,
+    &token_parts, &arnr_maxframes, &arnr_strength, &arnr_type, NULL
+};
+static const int vp8_arg_ctrl_map[] =
+{
+    VP8E_SET_CPUUSED, VP8E_SET_ENABLEAUTOALTREF,
+    VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD,
+    VP8E_SET_TOKEN_PARTITIONS,
+    VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH , VP8E_SET_ARNR_TYPE, 0
+};
+#endif
+
+static const arg_def_t *no_args[] = { NULL };
+
+static void usage_exit()
+{
+    int i;
+
+    printf("Usage: %s <options> src_filename dst_filename\n", exec_name);
+
+    printf("\n_options:\n");
+    arg_show_usage(stdout, main_args);
+    printf("\n_encoder Global Options:\n");
+    arg_show_usage(stdout, global_args);
+    printf("\n_rate Control Options:\n");
+    arg_show_usage(stdout, rc_args);
+    printf("\n_twopass Rate Control Options:\n");
+    arg_show_usage(stdout, rc_twopass_args);
+    printf("\n_keyframe Placement Options:\n");
+    arg_show_usage(stdout, kf_args);
+#if CONFIG_VP8_ENCODER
+    printf("\n_vp8 Specific Options:\n");
+    arg_show_usage(stdout, vp8_args);
+#endif
+    printf("\n"
+           "Included encoders:\n"
+           "\n");
+
+    for (i = 0; i < sizeof(codecs) / sizeof(codecs[0]); i++)
+        printf("    %-6s - %s\n",
+               codecs[i].name,
+               vpx_codec_iface_name(codecs[i].iface));
+
+    exit(EXIT_FAILURE);
+}
+
+#define ARG_CTRL_CNT_MAX 10
+
+
+int main(int argc, const char **argv_)
+{
+    vpx_codec_ctx_t        encoder;
+    const char                  *in_fn = NULL, *out_fn = NULL, *stats_fn = NULL;
+    int                    i;
+    FILE                  *infile, *outfile;
+    vpx_codec_enc_cfg_t    cfg;
+    vpx_codec_err_t        res;
+    int                    pass, one_pass_only = 0;
+    stats_io_t             stats;
+    vpx_image_t            raw;
+    const struct codec_item  *codec = codecs;
+    int                    frame_avail, got_data;
+
+    struct arg               arg;
+    char                   **argv, **argi, **argj;
+    int                      arg_usage = 0, arg_passes = 1, arg_deadline = 0;
+    int                      arg_ctrls[ARG_CTRL_CNT_MAX][2], arg_ctrl_cnt = 0;
+    int                      arg_limit = 0;
+    static const arg_def_t **ctrl_args = no_args;
+    static const int        *ctrl_args_map = NULL;
+    int                      verbose = 0, show_psnr = 0;
+    int                      arg_use_i420 = 1;
+    unsigned long            cx_time = 0;
+    unsigned int             is_ivf, fourcc;
+
+    exec_name = argv_[0];
+
+    if (argc < 3)
+        usage_exit();
+
+
+    /* First parse the codec and usage values, because we want to apply other
+     * parameters on top of the default configuration provided by the codec.
+     */
+    argv = argv_dup(argc - 1, argv_ + 1);
+
+    for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step)
+    {
+        arg.argv_step = 1;
+
+        if (arg_match(&arg, &codecarg, argi))
+        {
+            int j, k = -1;
+
+            for (j = 0; j < sizeof(codecs) / sizeof(codecs[0]); j++)
+                if (!strcmp(codecs[j].name, arg.val))
+                    k = j;
+
+            if (k >= 0)
+                codec = codecs + k;
+            else
+                die("Error: Unrecognized argument (%s) to --codec\n",
+                    arg.val);
+
+        }
+        else if (arg_match(&arg, &passes, argi))
+        {
+            arg_passes = arg_parse_uint(&arg);
+
+            if (arg_passes < 1 || arg_passes > 2)
+                die("Error: Invalid number of passes (%d)\n", arg_passes);
+        }
+        else if (arg_match(&arg, &pass_arg, argi))
+        {
+            one_pass_only = arg_parse_uint(&arg);
+
+            if (one_pass_only < 1 || one_pass_only > 2)
+                die("Error: Invalid pass selected (%d)\n", one_pass_only);
+        }
+        else if (arg_match(&arg, &fpf_name, argi))
+            stats_fn = arg.val;
+        else if (arg_match(&arg, &usage, argi))
+            arg_usage = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &deadline, argi))
+            arg_deadline = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &best_dl, argi))
+            arg_deadline = VPX_DL_BEST_QUALITY;
+        else if (arg_match(&arg, &good_dl, argi))
+            arg_deadline = VPX_DL_GOOD_QUALITY;
+        else if (arg_match(&arg, &rt_dl, argi))
+            arg_deadline = VPX_DL_REALTIME;
+        else if (arg_match(&arg, &use_yv12, argi))
+        {
+            arg_use_i420 = 0;
+        }
+        else if (arg_match(&arg, &use_i420, argi))
+        {
+            arg_use_i420 = 1;
+        }
+        else if (arg_match(&arg, &verbosearg, argi))
+            verbose = 1;
+        else if (arg_match(&arg, &limit, argi))
+            arg_limit = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &psnrarg, argi))
+            show_psnr = 1;
+        else
+            argj++;
+    }
+
+    /* Ensure that --passes and --pass are consistent. If --pass is set and --passes=2,
+     * ensure --fpf was set.
+     */
+    if (one_pass_only)
+    {
+        /* DWIM: Assume the user meant passes=2 if pass=2 is specified */
+        if (one_pass_only > arg_passes)
+        {
+            printf("Warning: Assuming --pass=%d implies --passes=%d\n",
+                   one_pass_only, one_pass_only);
+            arg_passes = one_pass_only;
+        }
+
+        if (arg_passes == 2 && !stats_fn)
+            die("Must specify --fpf when --pass=%d and --passes=2\n", one_pass_only);
+    }
+
+    /* Populate encoder configuration */
+    res = vpx_codec_enc_config_default(codec->iface, &cfg, arg_usage);
+
+    if (res)
+    {
+        printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
+        return EXIT_FAILURE;
+    }
+
+    /* Now parse the remainder of the parameters. */
+    for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step)
+    {
+        arg.argv_step = 1;
+
+        if (0);
+        else if (arg_match(&arg, &threads, argi))
+            cfg.g_threads = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &profile, argi))
+            cfg.g_profile = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &width, argi))
+            cfg.g_w = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &height, argi))
+            cfg.g_h = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &timebase, argi))
+            cfg.g_timebase = arg_parse_rational(&arg);
+        else if (arg_match(&arg, &error_resilient, argi))
+            cfg.g_error_resilient = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &lag_in_frames, argi))
+            cfg.g_lag_in_frames = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &dropframe_thresh, argi))
+            cfg.rc_dropframe_thresh = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &resize_allowed, argi))
+            cfg.rc_resize_allowed = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &resize_up_thresh, argi))
+            cfg.rc_resize_up_thresh = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &resize_down_thresh, argi))
+            cfg.rc_resize_down_thresh = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &resize_down_thresh, argi))
+            cfg.rc_resize_down_thresh = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &end_usage, argi))
+            cfg.rc_end_usage = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &target_bitrate, argi))
+            cfg.rc_target_bitrate = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &min_quantizer, argi))
+            cfg.rc_min_quantizer = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &max_quantizer, argi))
+            cfg.rc_max_quantizer = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &undershoot_pct, argi))
+            cfg.rc_undershoot_pct = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &overshoot_pct, argi))
+            cfg.rc_overshoot_pct = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &buf_sz, argi))
+            cfg.rc_buf_sz = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &buf_initial_sz, argi))
+            cfg.rc_buf_initial_sz = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &buf_optimal_sz, argi))
+            cfg.rc_buf_optimal_sz = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &bias_pct, argi))
+        {
+            cfg.rc_2pass_vbr_bias_pct = arg_parse_uint(&arg);
+
+            if (arg_passes < 2)
+                printf("Warning: option %s ignored in one-pass mode.\n",
+                       arg.name);
+        }
+        else if (arg_match(&arg, &minsection_pct, argi))
+        {
+            cfg.rc_2pass_vbr_minsection_pct = arg_parse_uint(&arg);
+
+            if (arg_passes < 2)
+                printf("Warning: option %s ignored in one-pass mode.\n",
+                       arg.name);
+        }
+        else if (arg_match(&arg, &maxsection_pct, argi))
+        {
+            cfg.rc_2pass_vbr_maxsection_pct = arg_parse_uint(&arg);
+
+            if (arg_passes < 2)
+                printf("Warning: option %s ignored in one-pass mode.\n",
+                       arg.name);
+        }
+        else if (arg_match(&arg, &kf_min_dist, argi))
+            cfg.kf_min_dist = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &kf_max_dist, argi))
+            cfg.kf_max_dist = arg_parse_uint(&arg);
+        else
+            argj++;
+    }
+
+    /* Handle codec specific options */
+#if CONFIG_VP8_ENCODER
+
+    if (codec->iface == &vpx_codec_vp8_cx_algo)
+    {
+        ctrl_args = vp8_args;
+        ctrl_args_map = vp8_arg_ctrl_map;
+    }
+
+#endif
+
+    for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step)
+    {
+        int match = 0;
+
+        arg.argv_step = 1;
+
+        for (i = 0; ctrl_args[i]; i++)
+        {
+            if (arg_match(&arg, ctrl_args[i], argi))
+            {
+                match = 1;
+
+                if (arg_ctrl_cnt < ARG_CTRL_CNT_MAX)
+                {
+                    arg_ctrls[arg_ctrl_cnt][0] = ctrl_args_map[i];
+                    arg_ctrls[arg_ctrl_cnt][1] = arg_parse_int(&arg);
+                    arg_ctrl_cnt++;
+                }
+            }
+        }
+
+        if (!match)
+            argj++;
+    }
+
+    /* Check for unrecognized options */
+    for (argi = argv; *argi; argi++)
+        if (argi[0][0] == '-')
+            die("Error: Unrecognized option %s\n", *argi);
+
+    /* Handle non-option arguments */
+    in_fn = argv[0];
+    out_fn = argv[1];
+
+    if (!in_fn || !out_fn)
+        usage_exit();
+
+    /* Parse certain options from the input file, if possible */
+    infile = fopen(in_fn, "rb");
+
+    if (!infile)
+    {
+        printf("Failed to open input file");
+        return EXIT_FAILURE;
+    }
+
+    is_ivf = file_is_ivf(infile, &fourcc, &cfg.g_w, &cfg.g_h);
+
+    if (is_ivf)
+    {
+        switch (fourcc)
+        {
+        case 0x32315659:
+            arg_use_i420 = 0;
+            break;
+        case 0x30323449:
+            arg_use_i420 = 1;
+            break;
+        default:
+            printf("Unsupported fourcc (%08x) in IVF\n", fourcc);
+            return EXIT_FAILURE;
+        }
+    }
+
+    fclose(infile);
+
+
+#define SHOW(field) printf("    %-28s = %d\n", #field, cfg.field)
+
+    if (verbose)
+    {
+        printf("Codec: %s\n", vpx_codec_iface_name(codec->iface));
+        printf("Source file: %s Format: %s\n", in_fn, arg_use_i420 ? "I420" : "YV12");
+        printf("Destination file: %s\n", out_fn);
+        printf("Encoder parameters:\n");
+
+        SHOW(g_usage);
+        SHOW(g_threads);
+        SHOW(g_profile);
+        SHOW(g_w);
+        SHOW(g_h);
+        SHOW(g_timebase.num);
+        SHOW(g_timebase.den);
+        SHOW(g_error_resilient);
+        SHOW(g_pass);
+        SHOW(g_lag_in_frames);
+        SHOW(rc_dropframe_thresh);
+        SHOW(rc_resize_allowed);
+        SHOW(rc_resize_up_thresh);
+        SHOW(rc_resize_down_thresh);
+        SHOW(rc_end_usage);
+        SHOW(rc_target_bitrate);
+        SHOW(rc_min_quantizer);
+        SHOW(rc_max_quantizer);
+        SHOW(rc_undershoot_pct);
+        SHOW(rc_overshoot_pct);
+        SHOW(rc_buf_sz);
+        SHOW(rc_buf_initial_sz);
+        SHOW(rc_buf_optimal_sz);
+        SHOW(rc_2pass_vbr_bias_pct);
+        SHOW(rc_2pass_vbr_minsection_pct);
+        SHOW(rc_2pass_vbr_maxsection_pct);
+        SHOW(kf_mode);
+        SHOW(kf_min_dist);
+        SHOW(kf_max_dist);
+    }
+
+    vpx_img_alloc(&raw, arg_use_i420 ? IMG_FMT_I420 : IMG_FMT_YV12,
+                  cfg.g_w, cfg.g_h, 1);
+
+    // This was added so that ivfenc will create monotically increasing
+    // timestamps.  Since we create new timestamps for alt-reference frames
+    // we need to make room in the series of timestamps.  Since there can
+    // only be 1 alt-ref frame ( current bitstream) multiplying by 2
+    // gives us enough room.
+    cfg.g_timebase.den *= 2;
+
+    memset(&stats, 0, sizeof(stats));
+
+    for (pass = one_pass_only ? one_pass_only - 1 : 0; pass < arg_passes; pass++)
+    {
+        int frames_in = 0, frames_out = 0;
+        unsigned long nbytes = 0;
+
+        infile = fopen(in_fn, "rb");
+
+        if (!infile)
+        {
+            printf("Failed to open input file");
+            return EXIT_FAILURE;
+        }
+
+        outfile = fopen(out_fn, "wb");
+
+        if (!outfile)
+        {
+            printf("Failed to open output file");
+            return EXIT_FAILURE;
+        }
+
+        if (stats_fn)
+        {
+            if (!stats_open_file(&stats, stats_fn, pass))
+            {
+                printf("Failed to open statistics store\n");
+                return EXIT_FAILURE;
+            }
+        }
+        else
+        {
+            if (!stats_open_mem(&stats, pass))
+            {
+                printf("Failed to open statistics store\n");
+                return EXIT_FAILURE;
+            }
+        }
+
+        cfg.g_pass = arg_passes == 2
+                     ? pass ? VPX_RC_LAST_PASS : VPX_RC_FIRST_PASS
+                 : VPX_RC_ONE_PASS;
+#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
+
+        if (pass)
+        {
+            cfg.rc_twopass_stats_in = stats_get(&stats);
+        }
+
+#endif
+
+        write_ivf_file_header(outfile, &cfg, codec->fourcc, 0);
+
+
+        /* Construct Encoder Context */
+        if (cfg.kf_min_dist == cfg.kf_max_dist)
+            cfg.kf_mode = VPX_KF_FIXED;
+
+        vpx_codec_enc_init(&encoder, codec->iface, &cfg,
+                           show_psnr ? VPX_CODEC_USE_PSNR : 0);
+        ctx_exit_on_error(&encoder, "Failed to initialize encoder");
+
+        /* Note that we bypass the vpx_codec_control wrapper macro because
+         * we're being clever to store the control IDs in an array. Real
+         * applications will want to make use of the enumerations directly
+         */
+        for (i = 0; i < arg_ctrl_cnt; i++)
+        {
+            if (vpx_codec_control_(&encoder, arg_ctrls[i][0], arg_ctrls[i][1]))
+                printf("Error: Tried to set control %d = %d\n",
+                       arg_ctrls[i][0], arg_ctrls[i][1]);
+
+            ctx_exit_on_error(&encoder, "Failed to control codec");
+        }
+
+        frame_avail = 1;
+        got_data = 0;
+
+        while (frame_avail || got_data)
+        {
+            vpx_codec_iter_t iter = NULL;
+            const vpx_codec_cx_pkt_t *pkt;
+            struct vpx_usec_timer timer;
+
+            if (!arg_limit || frames_in < arg_limit)
+            {
+                frame_avail = read_frame(infile, &raw, is_ivf);
+
+                if (frame_avail)
+                    frames_in++;
+
+                printf("\rPass %d/%d frame %4d/%-4d %7ldB \033[K", pass + 1,
+                       arg_passes, frames_in, frames_out, nbytes);
+            }
+            else
+                frame_avail = 0;
+
+            vpx_usec_timer_start(&timer);
+
+            // since we halved our timebase we need to double the timestamps
+            // and duration we pass in.
+            vpx_codec_encode(&encoder, frame_avail ? &raw : NULL, (frames_in - 1) * 2,
+                             2, 0, arg_deadline);
+            vpx_usec_timer_mark(&timer);
+            cx_time += vpx_usec_timer_elapsed(&timer);
+            ctx_exit_on_error(&encoder, "Failed to encode frame");
+            got_data = 0;
+
+            while ((pkt = vpx_codec_get_cx_data(&encoder, &iter)))
+            {
+                got_data = 1;
+                nbytes += pkt->data.raw.sz;
+
+                switch (pkt->kind)
+                {
+                case VPX_CODEC_CX_FRAME_PKT:
+                    frames_out++;
+                    printf(" %6luF",
+                           (unsigned long)pkt->data.frame.sz);
+                    write_ivf_frame_header(outfile, pkt);
+                    fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile);
+                    break;
+                case VPX_CODEC_STATS_PKT:
+                    frames_out++;
+                    printf(" %6luS",
+                           (unsigned long)pkt->data.twopass_stats.sz);
+                    stats_write(&stats,
+                                pkt->data.twopass_stats.buf,
+                                pkt->data.twopass_stats.sz);
+                    break;
+                case VPX_CODEC_PSNR_PKT:
+
+                    if (show_psnr)
+                    {
+                        int i;
+
+                        for (i = 0; i < 4; i++)
+                            printf("%.3lf ", pkt->data.psnr.psnr[i]);
+                    }
+
+                    break;
+                default:
+                    break;
+                }
+            }
+
+            fflush(stdout);
+        }
+
+        /* this bitrate calc is simplified and relies on the fact that this
+         * application uses 1/timebase for framerate.
+         */
+        printf("\rPass %d/%d frame %4d/%-4d %7ldB %7ldb/f %7"PRId64"b/s"
+               " %7lu %s (%.2f fps)\033[K", pass + 1,
+               arg_passes, frames_in, frames_out, nbytes, nbytes * 8 / frames_in,
+               nbytes * 8 *(int64_t)cfg.g_timebase.den / cfg.g_timebase.num / frames_in,
+               cx_time > 9999999 ? cx_time / 1000 : cx_time,
+               cx_time > 9999999 ? "ms" : "us",
+               (float)frames_in * 1000000.0 / (float)cx_time);
+
+        vpx_codec_destroy(&encoder);
+
+        fclose(infile);
+
+        if (!fseek(outfile, 0, SEEK_SET))
+            write_ivf_file_header(outfile, &cfg, codec->fourcc, frames_out);
+
+        fclose(outfile);
+        stats_close(&stats);
+        printf("\n");
+
+        if (one_pass_only)
+            break;
+    }
+
+    vpx_img_free(&raw);
+    free(argv);
+    return EXIT_SUCCESS;
+}
diff --git a/keywords.dox b/keywords.dox
new file mode 100644 (file)
index 0000000..56f5368
--- /dev/null
@@ -0,0 +1,51 @@
+/*!\page rfc2119 RFC2119 Keywords
+
+      The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and
+      "OPTIONAL" in this document are to be interpreted as described in
+      <a href="http://www.ietf.org/rfc/rfc2119.txt">RFC 2119.</a>
+
+Specifically, the following definitions are used:
+
+\section MUST
+\anchor REQUIRED
+\anchor SHALL
+   This word, or the terms "REQUIRED" or "SHALL", mean that the
+   definition is an absolute requirement of the specification.
+
+\section MUSTNOT MUST NOT
+\anchor SHALLNOT
+   This phrase, or the phrase "SHALL NOT", mean that the
+   definition is an absolute prohibition of the specification.
+
+\section SHOULD
+\anchor RECOMMENDED
+   This word, or the adjective "RECOMMENDED", mean that there
+   may exist valid reasons in particular circumstances to ignore a
+   particular item, but the full implications must be understood and
+   carefully weighed before choosing a different course.
+
+\section SHOULDNOT SHOULD NOT
+\anchor NOTRECOMMENDED
+   This phrase, or the phrase "NOT RECOMMENDED" mean that
+   there may exist valid reasons in particular circumstances when the
+   particular behavior is acceptable or even useful, but the full
+   implications should be understood and the case carefully weighed
+   before implementing any behavior described with this label.
+
+\section MAY
+\anchor OPTIONAL
+   This word, or the adjective "OPTIONAL", mean that an item is
+   truly optional.  One vendor may choose to include the item because a
+   particular marketplace requires it or because the vendor feels that
+   it enhances the product while another vendor may omit the same item.
+   An implementation which does not include a particular option \ref MUST be
+   prepared to interoperate with another implementation which does
+   include the option, though perhaps with reduced functionality. In the
+   same vein an implementation which does include a particular option
+   \ref MUST be prepared to interoperate with another implementation which
+   does not include the option (except, of course, for the feature the
+   option provides.)
+
+
+*/
diff --git a/libs.doxy_template b/libs.doxy_template
new file mode 100644 (file)
index 0000000..eb37dfc
--- /dev/null
@@ -0,0 +1,1307 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+# Doxyfile 1.5.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that
+# follow. The default is UTF-8 which is also the encoding used for all text before
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "WebM VP8 Codec SDK"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = docs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to java_doc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a java_doc-style
+# comment as the brief description. If set to NO, the java_doc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the defqault) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is
+# documented as struct with the name of the typedef. So
+# typedef struct type_s {} type_t, will appear in the documentation as a struct
+# with name type_t. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named type_s. This can typically
+# be useful for C code where the coding convention is that all structs are
+# typedef'ed and only the typedef is referenced never the struct's name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be extracted
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+# where file will be replaced with the base name of the file that contains the anonymous
+# namespace. By default anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files that
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the output.
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.  Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.  The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
+# then you must also enable this option. If you don't then doxygen will produce
+# a warning and turn it on anyway
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# java_script and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# java_script, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the la_te_x output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the la_te_x docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the la_te_x command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for la_te_x. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# la_te_x documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of la_te_x
+# packages that should be included in the la_te_x output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal la_te_x header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the la_te_x that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated la_te_x files. This will instruct la_te_x to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the auto_gen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an auto_gen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and la_te_x code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.  This is useful
+# if you want to understand what is going on.  On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  = *.h
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#   TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#   TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and la_te_x) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
+# be found in the default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a caller dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the number
+# of direct children of the root node in a graph is already larger than
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/libs.mk b/libs.mk
new file mode 100644 (file)
index 0000000..f741dba
--- /dev/null
+++ b/libs.mk
@@ -0,0 +1,225 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+ASM:=$(if $(filter yes,$(CONFIG_GCC)),.asm.s,.asm)
+
+include $(SRC_PATH_BARE)/vpx_codec/vpx_codec.mk
+CODEC_SRCS-yes += $(addprefix vpx_codec/,$(call enabled,API_SRCS))
+
+include $(SRC_PATH_BARE)/vpx_mem/vpx_mem.mk
+CODEC_SRCS-yes += $(addprefix vpx_mem/,$(call enabled,MEM_SRCS))
+
+include $(SRC_PATH_BARE)/vpx_scale/vpx_scale.mk
+CODEC_SRCS-yes += $(addprefix vpx_scale/,$(call enabled,SCALE_SRCS))
+
+# Add vpx_codec/ to the include path to allow vp_n[cd]x.h to reference
+# vpx_codec_impl_*.h without extra ifdeffery
+CFLAGS += -I$(SRC_PATH_BARE)/vpx_codec
+
+ifeq ($(CONFIG_VP8_ENCODER),yes)
+  VP8_PREFIX=vp8/
+  include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8cx.mk
+  CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS))
+  CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_CX_EXPORTS))
+  CODEC_SRCS-yes += $(VP8_PREFIX)vp8cx.mk
+  INSTALL_MAPS += include/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
+  CODEC_DOC_SRCS += vp8/vp8.h vp8/vp8cx.h
+  CODEC_DOC_SECTIONS += vp8 vp8_encoder
+endif
+
+ifeq ($(CONFIG_VP8_DECODER),yes)
+  VP8_PREFIX=vp8/
+  include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8dx.mk
+  CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_DX_SRCS))
+  CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_DX_EXPORTS))
+  CODEC_SRCS-yes += $(VP8_PREFIX)vp8dx.mk
+  INSTALL_MAPS += include/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
+  CODEC_DOC_SRCS += vp8/vp8.h vp8/vp8dx.h
+  CODEC_DOC_SECTIONS += vp8 vp8_decoder
+endif
+
+
+ifeq ($(CONFIG_ENCODERS),yes)
+  CODEC_DOC_SECTIONS += encoder
+endif
+ifeq ($(CONFIG_DECODERS),yes)
+  CODEC_DOC_SECTIONS += decoder
+endif
+
+
+ifeq ($(CONFIG_MSVS),yes)
+CODEC_LIB=$(if $(CONFIG_STATIC_MSVCRT),vpxmt,vpxmd)
+# This variable uses deferred expansion intentionally, since the results of
+# $(wildcard) may change during the course of the Make.
+VS_PLATFORMS = $(foreach d,$(wildcard */Release/$(CODEC_LIB).lib),$(word 1,$(subst /, ,$(d))))
+CODEC_SRCS-yes += $(SRC_PATH_BARE)/libs.mk # to show up in the msvs workspace
+endif
+
+# The following pairs define a mapping of locations in the distribution
+# tree to locations in the source/build trees.
+INSTALL_MAPS += include/% $(SRC_PATH_BARE)/vpx_codec/%
+INSTALL_MAPS += include/% $(SRC_PATH_BARE)/vpx_ports/%
+INSTALL_MAPS += lib/%     %
+INSTALL_MAPS += src/%     $(SRC_PATH_BARE)/%
+ifeq ($(CONFIG_MSVS),yes)
+INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),lib/$(p)/%  $(p)/Release/%)
+INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),lib/$(p)/%  $(p)/Debug/%)
+endif
+
+# If this is a universal (fat) binary, then all the subarchitectures have
+# already been built and our job is to stitch them together. The
+# BUILD_LIBVPX variable indicates whether we should be building
+# (compiling, linking) the library. The LIPO_LIBVPX variable indicates
+# that we're stitching.
+$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_LIBVPX,BUILD_LIBVPX):=yes)
+
+CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh
+CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_integer.h
+CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_timer.h
+CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem.h
+CODEC_SRCS-$(BUILD_LIBVPX) += $(BUILD_PFX)vpx_config.c
+INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
+ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
+CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/emms.asm
+CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/x86.h
+CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/x86_abi_support.asm
+endif
+CODEC_SRCS-$(ARCH_ARM) += $(BUILD_PFX)vpx_config.asm
+CODEC_EXPORTS-$(BUILD_LIBVPX) += vpx_codec/exports
+
+INSTALL-LIBS-yes += include/vpx_codec.h
+INSTALL-LIBS-yes += include/vpx_image.h
+INSTALL-LIBS-yes += include/vpx_integer.h
+INSTALL-LIBS-yes += include/vpx_codec_impl_top.h
+INSTALL-LIBS-yes += include/vpx_codec_impl_bottom.h
+INSTALL-LIBS-$(CONFIG_DECODERS) += include/vpx_decoder.h
+INSTALL-LIBS-$(CONFIG_DECODERS) += include/vpx_decoder_compat.h
+INSTALL-LIBS-$(CONFIG_ENCODERS) += include/vpx_encoder.h
+ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
+ifeq ($(CONFIG_MSVS),yes)
+INSTALL-LIBS-yes                  += $(foreach p,$(VS_PLATFORMS),lib/$(p)/$(CODEC_LIB).lib)
+INSTALL-LIBS-$(CONFIG_DEBUG_LIBS) += $(foreach p,$(VS_PLATFORMS),lib/$(p)/$(CODEC_LIB)d.lib)
+INSTALL-LIBS-$(CONFIG_SHARED) += $(foreach p,$(VS_PLATFORMS),lib/$(p)/vpx.dll)
+INSTALL-LIBS-$(CONFIG_SHARED) += $(foreach p,$(VS_PLATFORMS),lib/$(p)/vpx.exp)
+endif
+else
+INSTALL-LIBS-yes += lib/libvpx.a
+INSTALL-LIBS-$(CONFIG_DEBUG_LIBS) += lib/libvpx_g.a
+endif
+
+CODEC_SRCS=$(call enabled,CODEC_SRCS)
+INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(CODEC_SRCS)
+INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(call enabled,CODEC_EXPORTS)
+
+ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
+ifeq ($(CONFIG_MSVS),yes)
+
+ifeq ($(ARCH_ARM),yes)
+ifeq ($(HAVE_ARMV5TE),yes)
+ARM_ARCH=v5
+endif
+ifeq ($(HAVE_ARMV6),yes)
+ARM_ARCH=v6
+endif
+obj_int_extract.vcproj: $(SRC_PATH_BARE)/build/make/obj_int_extract.c
+       @cp $(SRC_PATH_BARE)/build/arm-wince-vs8/obj_int_extract.bat .
+       @cp $(SRC_PATH_BARE)/build/arm-wince-vs8/armasm$(ARM_ARCH).rules .
+       @echo "    [CREATE] $@"
+       $(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh\
+                       --exe\
+                       --target=$(TOOLCHAIN)\
+            $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
+            --name=obj_int_extract\
+            --proj-guid=E1360C65-D375-4335-8057-7ED99CC3F9B2\
+            --out=$@ $^\
+            -I".&quot;;&quot;$(SRC_PATH_BARE)"
+
+PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.vcproj
+PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.bat
+PROJECTS-$(BUILD_LIBVPX) += armasm$(ARM_ARCH).rules
+endif
+
+vpx.def: $(call enabled,CODEC_EXPORTS)
+       @echo "    [CREATE] $@"
+       $(SRC_PATH_BARE)/build/make/gen_msvs_def.sh\
+            --name=vpx\
+            --out=$@ $^
+CLEAN-OBJS += vpx.def
+
+vpx.vcproj: $(CODEC_SRCS) vpx.def
+       @echo "    [CREATE] $@"
+       $(SRC_PATH_BARE)/build/make/gen_msvs_proj.sh\
+                       --lib\
+                       --target=$(TOOLCHAIN)\
+            $(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
+            --name=vpx\
+            --proj-guid=DCE19DAF-69AC-46DB-B14A-39F0FAA5DB74\
+            --module-def=vpx.def\
+            --ver=$(CONFIG_VS_VERSION)\
+            --out=$@ $(CFLAGS) $^\
+
+PROJECTS-$(BUILD_LIBVPX) += vpx.vcproj
+
+vpx.vcproj: vpx_config.asm
+
+endif
+else
+LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
+OBJS-$(BUILD_LIBVPX) += $(LIBVPX_OBJS)
+LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
+$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
+endif
+
+LIBS-$(LIPO_LIBVPX) += libvpx.a
+$(eval $(if $(LIPO_LIBVPX),$(call lipo_lib_template,libvpx.a)))
+
+#
+# Rule to make assembler configuration file from C configuration file
+#
+ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
+# YASM
+$(BUILD_PFX)vpx_config.asm: $(BUILD_PFX)vpx_config.h
+       @echo "    [CREATE] $@"
+       @egrep "#define [A-Z0-9_]+ [01]" $< \
+           | awk '{print $$2 " equ " $$3}' > $@
+else
+ADS2GAS=$(if $(filter yes,$(CONFIG_GCC)),| $(ASM_CONVERSION))
+$(BUILD_PFX)vpx_config.asm: $(BUILD_PFX)vpx_config.h
+       @echo "    [CREATE] $@"
+       @egrep "#define [A-Z0-9_]+ [01]" $< \
+           | awk '{print $$2 " EQU " $$3}' $(ADS2GAS) > $@
+       @echo "        END" $(ADS2GAS) >> $@
+CLEAN-OBJS += $(BUILD_PFX)vpx_config.asm
+endif
+
+#
+# Add assembler dependencies for configuration and offsets
+#
+#$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm $(BUILD_PFX)vpx_asm_offsets.asm
+$(filter %.s.o,$(OBJS-yes)):   $(BUILD_PFX)vpx_config.asm
+$(filter %.asm.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
+
+$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h)
+CLEAN-OBJS += $(BUILD_PFX)vpx_version.h
+
+CODEC_DOC_SRCS += vpx_codec/vpx_codec.h \
+                  vpx_codec/vpx_decoder.h \
+                  vpx_codec/vpx_encoder.h \
+                  vpx_codec/vpx_image.h
+
+CLEAN-OBJS += libs.doxy
+DOCS-yes += libs.doxy
+libs.doxy: $(CODEC_DOC_SRCS)
+       @echo "    [CREATE] $@"
+       @rm -f $@
+       @echo "INPUT += $^" >> $@
+       @echo "PREDEFINED = VPX_CODEC_DISABLE_COMPAT" >> $@
+       @echo "INCLUDE_PATH += ." >> $@;
+       @echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@
diff --git a/mainpage.dox b/mainpage.dox
new file mode 100644 (file)
index 0000000..3596ce0
--- /dev/null
@@ -0,0 +1,45 @@
+/*!\mainpage WebM VP8 Codec SDK
+
+  \section main_contents Page Contents
+  - \ref main_intro
+  - \ref main_startpoints
+  - \ref main_support
+
+  \section main_intro Introduction
+  Welcome to the WebM VP8 Codec SDK. This SDK allows you to integrate your
+  applications with the VP8 video codec, a high quality, royalty free, open
+  source codec deployed on millions of computers and devices worldwide.
+
+  This distribution of the WebM VP8 Codec SDK includes the following support:
+  
+  \if vp8_encoder    - \ref vp8_encoder   \endif
+  \if vp8_decoder    - \ref vp8_decoder   \endif
+
+
+  \section main_startpoints Starting Points
+  - Consult the \ref changelog for a complete list of improvements in this
+    release.
+  - The \ref readme contains instructions on recompiling the sample applications.
+  - Read the \ref usage "usage" for a narrative on codec usage.
+  - Read the \ref samples "sample code" for examples of how to interact with the
+    codec.
+  - \ref codec reference
+    \if encoder - \ref encoder reference \endif
+    \if decoder - \ref decoder reference \endif
+
+  \section main_support Support Options & FAQ
+  The WebM project is an open source project supported by its community. For
+  questions about this SDK, please mail the apps-devel@webmproject.org list.
+  To contribute, see http://www.webmproject.org/code/contribute and mail
+  vpx-devel@webmproject.org.
+*/
+
+/*!\page changelog CHANGELOG
+   \verbinclude CHANGELOG
+*/
+
+/*!\page readme README
+   \verbinclude README
+*/
+
+/*!\defgroup codecs Supported Codecs */
diff --git a/md5_utils.c b/md5_utils.c
new file mode 100644 (file)
index 0000000..16c6f7e
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+*/
+
+#include "md5_utils.h"
+#include <string.h>
+
+/* Constants for md5_transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void md5_transform(uint32_t state[4], const uint8_t block[64]);
+static void Encode(uint8_t *output, const uint32_t *input, unsigned int len);
+static void Decode(uint32_t *output, const uint8_t *input, unsigned int len);
+#define md5_memset memset
+#define md5_memcpy memcpy
+
+static unsigned char PADDING[64] =
+{
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+        (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+        (a) = ROTATE_LEFT ((a), (s)); \
+        (a) += (b); \
+    }
+#define GG(a, b, c, d, x, s, ac) { \
+        (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+        (a) = ROTATE_LEFT ((a), (s)); \
+        (a) += (b); \
+    }
+#define HH(a, b, c, d, x, s, ac) { \
+        (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+        (a) = ROTATE_LEFT ((a), (s)); \
+        (a) += (b); \
+    }
+#define II(a, b, c, d, x, s, ac) { \
+        (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+        (a) = ROTATE_LEFT ((a), (s)); \
+        (a) += (b); \
+    }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void md5_init(md5_ctx_t *context)
+{
+    context->count[0] = context->count[1] = 0;
+    /* Load magic initialization constants.
+    */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xefcdab89;
+    context->state[2] = 0x98badcfe;
+    context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+void md5_update(md5_ctx_t *context, const uint8_t *input, unsigned int input_len)
+{
+    unsigned int i, index, part_len;
+
+    /* Compute number of bytes mod 64 */
+    index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+    /* Update number of bits */
+    if ((context->count[0] += ((uint32_t)input_len << 3))
+        < ((uint32_t)input_len << 3))
+        context->count[1]++;
+
+    context->count[1] += ((uint32_t)input_len >> 29);
+
+    part_len = 64 - index;
+
+    /* Transform as many times as possible. */
+    if (input_len >= part_len)
+    {
+        memcpy(&context->buffer[index], input, part_len);
+        md5_transform(context->state, context->buffer);
+
+        for (i = part_len; i + 63 < input_len; i += 64)
+            md5_transform(context->state, &input[i]);
+
+        index = 0;
+    }
+    else
+        i = 0;
+
+    /* Buffer remaining input */
+    memcpy(&context->buffer[index], &input[i], input_len - i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+void md5_finalize(md5_ctx_t *context, uint8_t digest[16])
+{
+    unsigned char bits[8];
+    unsigned int index, pad_len;
+
+    /* Save number of bits */
+    Encode(bits, context->count, 8);
+
+    /* Pad out to 56 mod 64.
+    */
+    index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+    pad_len = (index < 56) ? (56 - index) : (120 - index);
+    md5_update(context, PADDING, pad_len);
+
+    /* Append length (before padding) */
+    md5_update(context, bits, 8);
+    /* Store state in digest */
+    Encode(digest, context->state, 16);
+
+    /* Zeroize sensitive information.
+    */
+    memset(context, 0, sizeof(*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void md5_transform(uint32_t state[4], const uint8_t block[64])
+{
+    uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+    Decode(x, block, 64);
+
+    /* Round 1 */
+    FF(a, b, c, d, x[ 0], S11, 0xd76aa478);  /* 1 */
+    FF(d, a, b, c, x[ 1], S12, 0xe8c7b756);  /* 2 */
+    FF(c, d, a, b, x[ 2], S13, 0x242070db);  /* 3 */
+    FF(b, c, d, a, x[ 3], S14, 0xc1bdceee);  /* 4 */
+    FF(a, b, c, d, x[ 4], S11, 0xf57c0faf);  /* 5 */
+    FF(d, a, b, c, x[ 5], S12, 0x4787c62a);  /* 6 */
+    FF(c, d, a, b, x[ 6], S13, 0xa8304613);  /* 7 */
+    FF(b, c, d, a, x[ 7], S14, 0xfd469501);  /* 8 */
+    FF(a, b, c, d, x[ 8], S11, 0x698098d8);  /* 9 */
+    FF(d, a, b, c, x[ 9], S12, 0x8b44f7af);  /* 10 */
+    FF(c, d, a, b, x[10], S13, 0xffff5bb1);  /* 11 */
+    FF(b, c, d, a, x[11], S14, 0x895cd7be);  /* 12 */
+    FF(a, b, c, d, x[12], S11, 0x6b901122);  /* 13 */
+    FF(d, a, b, c, x[13], S12, 0xfd987193);  /* 14 */
+    FF(c, d, a, b, x[14], S13, 0xa679438e);  /* 15 */
+    FF(b, c, d, a, x[15], S14, 0x49b40821);  /* 16 */
+
+    /* Round 2 */
+    GG(a, b, c, d, x[ 1], S21, 0xf61e2562);  /* 17 */
+    GG(d, a, b, c, x[ 6], S22, 0xc040b340);  /* 18 */
+    GG(c, d, a, b, x[11], S23, 0x265e5a51);  /* 19 */
+    GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa);  /* 20 */
+    GG(a, b, c, d, x[ 5], S21, 0xd62f105d);  /* 21 */
+    GG(d, a, b, c, x[10], S22,  0x2441453);  /* 22 */
+    GG(c, d, a, b, x[15], S23, 0xd8a1e681);  /* 23 */
+    GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8);  /* 24 */
+    GG(a, b, c, d, x[ 9], S21, 0x21e1cde6);  /* 25 */
+    GG(d, a, b, c, x[14], S22, 0xc33707d6);  /* 26 */
+    GG(c, d, a, b, x[ 3], S23, 0xf4d50d87);  /* 27 */
+    GG(b, c, d, a, x[ 8], S24, 0x455a14ed);  /* 28 */
+    GG(a, b, c, d, x[13], S21, 0xa9e3e905);  /* 29 */
+    GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8);  /* 30 */
+    GG(c, d, a, b, x[ 7], S23, 0x676f02d9);  /* 31 */
+    GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);  /* 32 */
+
+    /* Round 3 */
+    HH(a, b, c, d, x[ 5], S31, 0xfffa3942);  /* 33 */
+    HH(d, a, b, c, x[ 8], S32, 0x8771f681);  /* 34 */
+    HH(c, d, a, b, x[11], S33, 0x6d9d6122);  /* 35 */
+    HH(b, c, d, a, x[14], S34, 0xfde5380c);  /* 36 */
+    HH(a, b, c, d, x[ 1], S31, 0xa4beea44);  /* 37 */
+    HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9);  /* 38 */
+    HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60);  /* 39 */
+    HH(b, c, d, a, x[10], S34, 0xbebfbc70);  /* 40 */
+    HH(a, b, c, d, x[13], S31, 0x289b7ec6);  /* 41 */
+    HH(d, a, b, c, x[ 0], S32, 0xeaa127fa);  /* 42 */
+    HH(c, d, a, b, x[ 3], S33, 0xd4ef3085);  /* 43 */
+    HH(b, c, d, a, x[ 6], S34,  0x4881d05);  /* 44 */
+    HH(a, b, c, d, x[ 9], S31, 0xd9d4d039);  /* 45 */
+    HH(d, a, b, c, x[12], S32, 0xe6db99e5);  /* 46 */
+    HH(c, d, a, b, x[15], S33, 0x1fa27cf8);  /* 47 */
+    HH(b, c, d, a, x[ 2], S34, 0xc4ac5665);  /* 48 */
+
+    /* Round 4 */
+    II(a, b, c, d, x[ 0], S41, 0xf4292244);  /* 49 */
+    II(d, a, b, c, x[ 7], S42, 0x432aff97);  /* 50 */
+    II(c, d, a, b, x[14], S43, 0xab9423a7);  /* 51 */
+    II(b, c, d, a, x[ 5], S44, 0xfc93a039);  /* 52 */
+    II(a, b, c, d, x[12], S41, 0x655b59c3);  /* 53 */
+    II(d, a, b, c, x[ 3], S42, 0x8f0ccc92);  /* 54 */
+    II(c, d, a, b, x[10], S43, 0xffeff47d);  /* 55 */
+    II(b, c, d, a, x[ 1], S44, 0x85845dd1);  /* 56 */
+    II(a, b, c, d, x[ 8], S41, 0x6fa87e4f);  /* 57 */
+    II(d, a, b, c, x[15], S42, 0xfe2ce6e0);  /* 58 */
+    II(c, d, a, b, x[ 6], S43, 0xa3014314);  /* 59 */
+    II(b, c, d, a, x[13], S44, 0x4e0811a1);  /* 60 */
+    II(a, b, c, d, x[ 4], S41, 0xf7537e82);  /* 61 */
+    II(d, a, b, c, x[11], S42, 0xbd3af235);  /* 62 */
+    II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb);  /* 63 */
+    II(b, c, d, a, x[ 9], S44, 0xeb86d391);  /* 64 */
+
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+
+    /* Zeroize sensitive information.
+    */
+    memset(x, 0, sizeof(x));
+}
+
+/* Encodes input (uint32_t) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void Encode(uint8_t *output, const uint32_t *input, unsigned int len)
+{
+    unsigned int i, j;
+
+    for (i = 0, j = 0; j < len; i++, j += 4)
+    {
+        output[j] = (unsigned char)(input[i] & 0xff);
+        output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+        output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+        output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+    }
+}
+
+/* Decodes input (unsigned char) into output (uint32_t). Assumes len is
+  a multiple of 4.
+ */
+static void Decode(uint32_t *output, const uint8_t *input, unsigned int len)
+{
+    unsigned int i, j;
+
+    for (i = 0, j = 0; j < len; i++, j += 4)
+        output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
+                    (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
+}
diff --git a/md5_utils.h b/md5_utils.h
new file mode 100644 (file)
index 0000000..8dda8d1
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+/*
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+*/
+#ifndef HAVE_VPX_PORTS
+#define HAVE_VPX_PORTS 0
+#endif
+#if HAVE_VPX_PORTS
+#include "vpx_ports/vpx_integer.h"
+#else
+#include "vpx_integer.h"
+#endif
+
+/* MD5 context. */
+typedef struct
+{
+    uint32_t state[4];        /* state (ABCD) */
+    uint32_t count[2];        /* number of bits, modulo 2^64 (lsb first) */
+    uint8_t  buffer[64];      /* input buffer */
+} md5_ctx_t;
+
+void md5_init(md5_ctx_t *ctx);
+void md5_update(md5_ctx_t *ctx, const uint8_t *buf, unsigned int len);
+void md5_finalize(md5_ctx_t *ctx, uint8_t md5[16]);
diff --git a/release.sh b/release.sh
new file mode 100755 (executable)
index 0000000..3b77dad
--- /dev/null
@@ -0,0 +1,209 @@
+#!/bin/bash
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+
+self=$0
+
+for opt; do
+    case $opt in
+        --clean) clean=yes;;
+        -j*) jopt=$opt;;
+        *) echo "Unsupported option $opt"; exit 1;;
+    esac
+done
+
+TAB=$'\t'
+cat > release.mk << EOF
+%\$(BUILD_SFX).tar.bz2: %/.done
+${TAB}@echo "\$(subst .tar.bz2,,\$@): tarball"
+${TAB}@cd \$(dir \$<); tar -cf - \$(subst .tar.bz2,,\$@) | bzip2 > ../\$@
+
+%\$(BUILD_SFX).zip: %/.done
+${TAB}@echo "\$(subst .zip,,\$@): zip"
+${TAB}@rm -f \$@; cd \$(dir \$<); zip -rq ../\$@ \$(subst .zip,,\$@)
+
+logs/%\$(BUILD_SFX).log.bz2: %/.done
+${TAB}@echo "\$(subst .log.bz2,,\$(notdir \$@)): tarlog"
+${TAB}@mkdir -p logs
+${TAB}@cat \$< | bzip2 > \$@
+
+%/.done:
+${TAB}@mkdir -p \$(dir \$@)
+${TAB}@echo "\$(dir \$@): configure \$(CONFIG_OPTS) \$(EXTRA_PATH)"
+${TAB}@cd \$(dir \$@); export PATH=\$\$PATH\$(EXTRA_PATH); ../\$(SRC_ROOT)/configure \$(CONFIG_OPTS) >makelog.txt 2>&1
+${TAB}@echo "\$(dir \$@): make"
+${TAB}@cd \$(dir \$@); PATH=\$\$PATH\$(EXTRA_PATH) \$(MAKE) >>makelog.txt 2>&1
+${TAB}@echo "\$(dir \$@): test install"
+${TAB}@cd \$(dir \$@); PATH=\$\$PATH\$(EXTRA_PATH) \$(MAKE) install >>makelog.txt 2>&1
+${TAB}@cd \$(dir \$@)/dist/build; PATH=\$\$PATH\$(EXTRA_PATH) \$(MAKE) >>makelog.txt 2>&1
+${TAB}@echo "\$(dir \$@): install"
+${TAB}@cd \$(dir \$@); PATH=\$\$PATH\$(EXTRA_PATH) \$(MAKE) install DIST_DIR=\$(TGT) >>makelog.txt 2>&1
+${TAB}@touch \$@
+
+#include release-deps.mk
+EOF
+
+#[ -f release-deps.mk ] || \
+#    find ${self%/*} -name .git -prune -o -type f -print0 \
+#    | xargs -0 -n1 echo \
+#    | sed -e 's; ;\\ ;g' | awk '{print "$(TGT)/.done: "$0}' > release-deps.mk
+
+build_config_list() {
+    for codec in $CODEC_LIST; do
+        for arch in $ARCH_LIST; do
+            if [ -n "$OS_LIST" ]; then
+                for os in $OS_LIST; do
+                    CONFIGS="$CONFIGS vpx-${codec}-${arch}-${os}"
+                done
+            else
+                CONFIGS="$CONFIGS vpx-${codec}-${arch}"
+            fi
+        done
+    done
+}
+
+CODEC_LIST="vp8 vp8cx vp8dx"
+case `uname` in
+    Linux*)
+        ARCH_LIST="x86 x86_64"
+        OS_LIST="linux"
+        build_config_list
+        ARCH_LIST="armv5te armv6 armv7"
+        OS_LIST="linux-gcc"
+
+        ;;
+    CYGWIN*)
+        TAR_SFX=.zip
+        for vs in vs7 vs8; do
+            for arch in x86-win32 x86_64-win64; do
+                for msvcrt in md mt; do
+                    case $vs,$arch in
+                        vs7,x86_64-win64) continue ;;
+                    esac
+                    ARCH_LIST="$ARCH_LIST ${arch}${msvcrt}-${vs}"
+                done
+            done
+        done
+        ;;
+    Darwin*)
+        ARCH_LIST="universal"
+        OS_LIST="darwin8 darwin9"
+        ;;
+    sun_os*)
+        ARCH_LIST="x86 x86_64"
+        OS_LIST="solaris"
+        ;;
+esac
+build_config_list
+
+TAR_SFX=${TAR_SFX:-.tar.bz2}
+ARM_TOOLCHAIN=/usr/local/google/csl-2009q3-67
+for cfg in $CONFIGS; do
+    full_cfg=$cfg
+    cfg=${cfg#vpx-}
+    opts=
+    rm -f makelog.txt
+
+    case $cfg in
+        src-*)  opts="$opts --enable-codec-srcs"
+                cfg=${cfg#src-}
+                ;;
+        eval-*) opts="$opts --enable-eval-limit"
+                cfg=${cfg#src-}
+                ;;
+    esac
+
+    case $cfg in
+        #
+        # Linux
+        #
+        *x86-linux)
+            opts="$opts --target=x86-linux-gcc" ;;
+        *x86_64-linux)
+            opts="$opts --target=x86_64-linux-gcc" ;;
+        *arm*-linux-gcc)
+            armv=${cfg##*armv}
+            armv=${armv%%-*}
+            opts="$opts --target=armv${armv}-linux-gcc" ;;
+        *arm*-linux-rvct)
+            armv=${cfg##*armv}
+            armv=${armv%%-*}
+            opts="$opts --target=armv${armv}-linux-rvct"
+            opts="$opts --libc=${ARM_TOOLCHAIN}/arm-none-linux-gnueabi/libc" ;;
+
+
+        #
+        # Windows
+        #
+        # need --enable-debug-libs for now until we're smarter about
+        # building the debug/release from the customer installed
+        # environment
+        *-x86-win32*-vs*)
+            opts="$opts --target=x86-win32-vs${cfg##*-vs} --enable-debug-libs";;
+        *-x86_64-win64*-vs8)
+            opts="$opts --target=x86_64-win64-vs8 --enable-debug-libs" ;;
+
+        #
+        # Darwin
+        #
+        *-universal-darwin*)
+            opts="$opts --target=universal-darwin${cfg##*-darwin}-gcc" ;;
+
+        #
+        # Solaris
+        #
+        *x86-solaris)
+            opts="$opts --target=x86-solaris-gcc" ;;
+        *x86_64-solaris)
+            opts="$opts --target=x86_64-solaris-gcc" ;;
+    esac
+
+    case $cfg in
+        *x86-linux | *x86-solaris) opts="$opts --enable-pic" ;;
+    esac
+
+    case $cfg in
+        *-win[36][24]mt*)  opts="$opts --enable-static-msvcrt" ;;
+        *-win[36][24]md*)  opts="$opts --disable-static-msvcrt" ;;
+    esac
+
+    opts="$opts --disable-codecs"
+    case $cfg in
+        vp8*) opts="$opts --enable-vp8" ;;
+    esac
+    case $cfg in
+        *cx-*) opts="${opts}-encoder" ;;
+        *dx-*) opts="${opts}-decoder" ;;
+    esac
+    opts="$opts --enable-postproc"
+
+    [ "x${clean}" == "xyes" ] \
+        && rm -rf ${full_cfg}${BUILD_SFX}${TAR_SFX} \
+        && rm -rf logs/${full_cfg}${BUILD_SFX}.log.bz2
+
+    TGT=${full_cfg}${BUILD_SFX}
+    BUILD_TARGETS="logs/${TGT}.log.bz2 ${TGT}${TAR_SFX}"
+    echo "${BUILD_TARGETS}: CONFIG_OPTS=$opts" >>release.mk
+    echo "${BUILD_TARGETS}: TGT=${TGT}" >>release.mk
+    case $cfg in
+        *-arm*-linux-*)
+            echo "${BUILD_TARGETS}: EXTRA_PATH=:${ARM_TOOLCHAIN}/bin/" >>release.mk ;;
+        *-vs7)
+            echo "${BUILD_TARGETS}: EXTRA_PATH=:/cygdrive/c/Program\ Files/Microsoft\ Visual\ Studio\ .NET\ 2003/Common7/IDE" >>release.mk ;;
+        *-vs8)
+            echo "${BUILD_TARGETS}: EXTRA_PATH=:/cygdrive/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/Common7/IDE" >>release.mk ;;
+    esac
+    MAKE_TGTS="$MAKE_TGTS ${TGT}${TAR_SFX} logs/${TGT}.log.bz2"
+done
+
+
+${MAKE:-make} ${jopt:--j3} -f release.mk  \
+    SRC_ROOT=${self%/*} BUILD_SFX=${BUILD_SFX} ${MAKE_TGTS}
diff --git a/solution.mk b/solution.mk
new file mode 100644 (file)
index 0000000..783c6f8
--- /dev/null
@@ -0,0 +1,54 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+ifeq ($(ARCH_ARM),yes)
+ARM_DEVELOP=no
+ARM_DEVELOP:=$(if $(filter %vpx.vcproj,$(wildcard *.vcproj)),yes)
+
+ifeq ($(ARM_DEVELOP),yes)
+vpx.sln:
+       @echo "    [COPY] $@"
+       @cp $(SRC_PATH_BARE)/build/arm-wince-vs8/vpx.sln .
+PROJECTS-yes += vpx.sln
+else
+vpx.sln: $(wildcard *.vcproj)
+       @echo "    [CREATE] $@"
+       $(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \
+            $(if $(filter %vpx.vcproj,$^),--dep=ivfdec:vpx) \
+            $(if $(filter %vpx.vcproj,$^),--dep=xma:vpx) \
+            --ver=$(CONFIG_VS_VERSION)\
+            --target=$(TOOLCHAIN)\
+            --out=$@ $^
+vpx.sln.mk: vpx.sln
+       @true
+
+PROJECTS-yes += vpx.sln vpx.sln.mk
+-include vpx.sln.mk
+endif
+
+else
+vpx.sln: $(wildcard *.vcproj)
+       @echo "    [CREATE] $@"
+       $(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \
+            $(if $(filter %vpx.vcproj,$^),\
+                $(foreach vcp,$(filter-out %vpx.vcproj,$^),\
+                  --dep=$(vcp:.vcproj=):vpx)) \
+            --ver=$(CONFIG_VS_VERSION)\
+            --out=$@ $^
+vpx.sln.mk: vpx.sln
+       @true
+
+PROJECTS-yes += vpx.sln vpx.sln.mk
+-include vpx.sln.mk
+endif
+
+# Always install this file, as it is an unconditional post-build rule.
+INSTALL_MAPS += src/%     $(SRC_PATH_BARE)/%
+INSTALL-SRCS-yes            += $(target).mk
diff --git a/usage.dox b/usage.dox
new file mode 100644 (file)
index 0000000..53808fd
--- /dev/null
+++ b/usage.dox
@@ -0,0 +1,203 @@
+/*!\page usage Usage
+
+    The vpx Multi-Format codec SDK provides a unified interface amongst its
+    supported codecs. This abstraction allows applications using this SDK to
+    easily support multiple video formats with minimal code duplication or
+    "special casing." This section describes the interface common to all codecs.
+    For codec-specific details, see the \ref codecs page.
+
+    The following sections are common to all codecs:
+    - \ref usage_types
+    - \ref usage_features
+    - \ref usage_init
+    - \ref usage_errors
+
+    Fore more information on decoder and encoder specific usage, see the
+    following pages:
+    \if decoder - \subpage usage_decode \endif
+    \if decoder - \subpage usage_encode \endif
+
+    \section usage_types Important Data Types
+    There are two important data structures to consider in this interface.
+
+    \subsection usage_ctxs Contexts
+    A context is a storage area allocated by the calling application that the
+    codec may write into to store details about a single instance of that codec.
+    Most of the context is implementation specific, and thus opaque to the
+    application. The context structure as seen by the application is of fixed
+    size, and thus can be allocated eith with automatic storage or dynamically
+    on the heap.
+
+    Most operations require an initialized codec context. Codec context
+    instances are codec specific. That is, the codec to be used for the encoded
+    video must be known at initialization time. See #vpx_codec_ctx_t for further
+    information.
+
+    \subsection usage_ifaces Interfaces
+    A codec interface is an opaque structure that controls how function calls
+    into the generic interface are dispatched to their codec-specific
+    implementations. Applications \ref MUSTNOT attempt to examine or override
+    this storage, as it contains internal implementation details likely to
+    change from release to release.
+
+    Each supported codec will expose an interface structure to the application
+    as an <code>extern</code> reference to a structure of the incomplete type
+    #vpx_codec_iface_t.
+
+    \section usage_features Features
+    Several "features" are defined that are optionally implemented by codec
+    algorithms. Indeed, the same algorithm may support different features on
+    different platforms. The purpose of defining these features is that when
+    they are implemented, they conform to a common interface. The features, or
+    capabilities, of an algorithm can be queried from it's interface by using
+    the vpx_codec_get_caps() method. Attempts to invoke features not supported
+    by an algorithm will generally result in #VPX_CODEC_INCAPABLE.
+
+    Currently defined features available in both encoders and decoders include:
+    - \subpage usage_xma
+
+    \if decoder
+    Currently defined decoder features include:
+    - \ref usage_cb
+    - \ref usage_postproc
+    \endif
+
+    \section usage_init Initialization
+    To initialize a codec instance, the address of the codec context
+    and interface structures are passed to an initialization function. Depending
+    on the \ref usage_features that the codec supports, the codec could be
+    initialized in different modes. Most notably, the application may choose to
+    use \ref usage_xma mode to gain fine grained control over how and where
+    memory is allocated for the codec.
+
+    To prevent cases of confusion where the ABI of the library changes,
+    the ABI is versioned. The ABI version number must be passed at
+    initialization time to ensure the application is using a header file that
+    matches the library. The current ABI version number is stored in the
+    prepropcessor macros #VPX_CODEC_ABI_VERSION, #VPX_ENCODER_ABI_VERSION, and
+    #VPX_DECODER_ABI_VERSION. For convenience, each initialization function has
+    a wrapper macro that inserts the correct version number. These macros are
+    named like the initialization methods, but without the _ver suffix.
+
+
+    The available initialization methods are:
+    \if encoder - #vpx_codec_enc_init (calls vpx_codec_enc_init_ver()) \endif
+    \if decoder - #vpx_codec_dec_init (calls vpx_codec_dec_init_ver()) \endif
+
+
+
+    \section usage_errors Error Handling
+    Almost all codec functions return an error status of type #vpx_codec_err_t.
+    The semantics of how each error condition should be processed is clearly
+    defined in the definitions of each enumerated value. Error values can be
+    converted into ASCII strings with the vpx_codec_error() and
+    vpx_codec_err_to_string() methods. The difference between these two methods is
+    that vpx_codec_error() returns the error state from an initialized context,
+    whereas vpx_codec_err_to_string() can be used in cases where an error occurs
+    outside any context. The enumerated value returned from the last call can be
+    retrieved from the <code>err</code> member of the decoder context as well.
+    Finally, more detailed error information may be able to be obtained by using
+    the vpx_codec_error_detail() method. Not all errors produce detailed error
+    information.
+
+    In addition to error information, the codec library's build configuration
+    is available at runtime on some platforms. This information can be returned
+    by calling vpx_codec_build_config(), and is formatted as a base64 coded string
+    (comprised of characters in the set [a-z_a-Z0-9+/]). This information is not
+    useful to an application at runtime, but may be of use to vpx for support.
+
+
+    \section usage_deadline Deadline
+    Both the encoding and decoding functions have a <code>deadline</code>
+    parameter. This parameter indicates the amount of time, in microseconds
+    (us), that the application wants the codec to spend processing before
+    returning. This is a soft deadline -- that is, the semantics of the
+    requested operation take precedence over meeting the deadline. If, for
+    example, an application sets a <code>deadline</code> of 1000us, and the
+    frame takes 2000us to decode, the call to vpx_codec_decode() will return
+    after 2000us. In this case the deadline is not met, but the semantics of the
+    function are preserved. If, for the same frame, an application instead sets
+    a <code>deadline</code> of 5000us, the decoder will see that it has 3000us
+    remaining in its time slice when decoding completes. It could then choose to
+    run a set of \ref usage_postproc filters, and perhaps would return after
+    4000us (instead of the allocated 5000us). In this case the deadline is met,
+    and the semantics of the call are preserved, as before.
+
+    The special value <code>0</code> is reserved to represent an infinite
+    deadline. In this case, the codec will perform as much processing as
+    possible to yeild the highest quality frame.
+
+    By convention, the value <code>1</code> is used to mean "return as fast as
+    possible."
+
+*/
+
+
+/*! \page usage_xma External Memory Allocation
+    Applications that wish to have fine grained control over how and where
+    decoders allocate memory \ref MAY make use of the e_xternal Memory Allocation
+    (XMA) interface. Not all codecs support the XMA \ref usage_features.
+
+    To use a decoder in XMA mode, the decoder \ref MUST be initialized with the
+    vpx_codec_xma_init_ver() function. The amount of memory a decoder needs to
+    allocate is heavily dependent on the size of the encoded video frames. The
+    size of the video must be known before requesting the decoder's memory map.
+    This stream information can be obtained with the vpx_codec_peek_stream_info()
+    function, which does not require a contructed decoder context. If the exact
+    stream is not known, a stream info structure can be created that reflects
+    the maximum size that the decoder instance is required to support.
+
+    Once the decoder instance has been initialized and the stream information
+    determined, the application calls the vpx_codec_get_mem_map() iterator
+    repeatedly to get a list of the memory segments requested by the decoder.
+    The iterator value should be initialized to NULL to request the first
+    element, and the function will return #VPX_CODEC_LIST_END to signal the end of
+    the list.
+
+    After each segment is identified, it must be passed to the codec through the
+    vpx_codec_set_mem_map() function. Segments \ref MUST be passed in the same
+    order as they are returned from vpx_codec_get_mem_map(), but there is no
+    requirement that vpx_codec_get_mem_map() must finish iterating before
+    vpx_codec_set_mem_map() is called. For instance, some applications may choose
+    to get a list of all requests, construct an optimal heap, and then set all
+    maps at once with one call. Other applications may set one map at a time,
+    allocating it immediately after it is returned from vpx_codec_get_mem_map().
+
+    After all segments have been set using vpx_codec_set_mem_map(), the codec may
+    be used as it would be in normal internal allocation mode.
+
+    \section usage_xma_seg_id Segment Identifiers
+    Each requested segment is identified by an identifier unique to
+    that decoder type. Some of these identifiers are private, while others are
+    enumerated for application use. Identifiers not enumerated publicly are
+    subject to change. Identifiers are non-consecutive.
+
+    \section usage_xma_seg_szalign Segment Size and Alignment
+    The sz (size) and align (alignment) parameters describe the required size
+    and alignment of the requested segment. Alignment will always be a power of
+    two. Applications \ref MUST honor the aligment requested. Failure to do so
+    could result in program crashes or may incur a speed penalty.
+
+    \section usage_xma_seg_flags Segment Flags
+    The flags member of the segment structure indicates any requirements or
+    desires of the codec for the particular segment. The #VPX_CODEC_MEM_ZERO flag
+    indicates that the segment \ref MUST be zeroed by the application prior to
+    passing it to the application. The #VPX_CODEC_MEM_WRONLY flag indicates that
+    the segment will only be written into by the decoder, not read. If this flag
+    is not set, the application \ref MUST insure that the memory segment is
+    readable. On some platforms, framebuffer memory is writable but not
+    readable, for example. The #VPX_CODEC_MEM_FAST flag indicates that the segment
+    will be frequently accessed, and that it should be placed into fast memory,
+    if any is available. The application \ref MAY choose to place other segments
+    in fast memory as well, but the most critical segments will be identified by
+    this flag.
+
+    \section usage_xma_seg_basedtor Segment Base Address and Destructor
+    For each requested memory segment, the application must determine the
+    address of a memory segment that meets the requirements of the codec. This
+    address is set in the <code>base</code> member of the #vpx_codec_mmap
+    structure. If the application requires processing when the segment is no
+    longer used by the codec (for instance to deallocate it or close an
+    associated file descriptor) the <code>dtor</code> and <code>priv</code>
+    members can be set.
+*/
diff --git a/usage_cx.dox b/usage_cx.dox
new file mode 100644 (file)
index 0000000..980a034
--- /dev/null
@@ -0,0 +1,14 @@
+/*! \page usage_encode Encode
+
+    The vpx_codec_encode() function is at the core of the decode loop. It
+    processes raw images passed by the application, producing packets of
+    compressed data. The <code>deadline</code> parameter controls the amount
+    of time in microseconds the encoder should spend working on the frame. For
+    more information on the <code>deadline</code> parameter, see
+    \ref usage_deadline.
+
+
+    \ref samples
+
+
+*/
diff --git a/usage_dx.dox b/usage_dx.dox
new file mode 100644 (file)
index 0000000..883ce24
--- /dev/null
@@ -0,0 +1,62 @@
+/*! \page usage_decode Decoding
+
+    The vpx_codec_decode() function is at the core of the decode loop. It
+    processes packets of compressed data passed by the application, producing
+    decoded images. The decoder expects packets to comprise exactly one image
+    frame of data. Packets \ref MUST be passed in decode order. If the
+    application wishes to associate some data with the frame, the
+    <code>user_priv</code> member may be set. The <code>deadline</code>
+    parameter controls the amount of time in microseconds the decoder should
+    spend working on the frame. This is typically used to support adaptive
+    \ref usage_postproc based on the amount of free CPU time. For more
+    information on the <code>deadline</code> parameter, see \ref usage_deadline.
+
+    \ref samples
+
+
+    \section usage_cb Callback Based Decoding
+    There are two methods for the application to access decoded frame data. Some
+    codecs support asynchronous (callback-based) decoding \ref usage_features
+    that allow the application to register a callback to be invoked by the
+    decoder when decoded data becomes available. Decoders are not required to
+    support this feature, however. Like all \ref usage_features, support can be
+    determined by calling vpx_codec_get_caps(). Callbacks are available in both
+    frame-based and slice-based variants. Frame based callbacks conform to the
+    signature of #vpx_codec_put_frame_cb_fn_t and are invoked once the entire
+    frame has been decoded. Slice based callbacks conform to the signature of
+    #vpx_codec_put_slice_cb_fn_t and are invoked after a subsection of the frame
+    is decoded. For example, a slice callback could be issued for each
+    macroblock row. However, the number and size of slices to return is
+    implementation specific. Also, the image data passed in a slice callback is
+    not necessarily in the same memory segment as the data will be when it is
+    assembled into a full frame. For this reason, the application \ref MUST
+    examine the rectangles that describe what data is valid to access and what
+    data has been updated in this call. For all their additional complexity,
+    slice based decoding callbacks provide substantial speed gains to the
+    overall application in some cases, due to improved cache behavior.
+
+
+    \section usage_frame_iter Frame Iterator Based Decoding
+    If the codec does not support callback based decoding, or the application
+    chooses not to make use of that feature, decoded frames are made available
+    through the vpx_codec_get_frame() iterator. The application initializes the
+    iterator storage (of type #vpx_codec_iter_t) to NULL, then calls
+    vpx_codec_get_frame repeatedly until it returns NULL, indicating that all
+    images have been returned. This process may result in zero, one, or many
+    frames that are ready for display, depending on the codec.
+
+
+    \section usage_postproc Postprocessing
+    Postprocessing is a process that is applied after a frame is decoded to
+    enhance the image's appearance by removing artifacts introduced in the
+    compression process. It is not required to properly decode the frame, and
+    is generally done only when there is enough spare CPU time to execute
+    the required filters. Codecs may support a number of different
+    postprocessing filters, and the available filters may differ from platform
+    to platform. Embedded devices often do not have enough CPU to implement
+    postprocessing in software. The filter selection is generally handled
+    automatically by the codec, depending on the amount of time remaining before
+    hitting the user-specified \ref usage_deadline after decoding the frame.
+
+
+*/
diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c
new file mode 100644 (file)
index 0000000..ac110f7
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "blockd.h"
+#include "vpx_mem/vpx_mem.h"
+#include "onyxc_int.h"
+#include "findnearmv.h"
+#include "entropymode.h"
+#include "systemdependent.h"
+#include "vpxerrors.h"
+
+#ifdef HAVE_CONFIG_H
+#include "vpx_config.h"
+#endif
+
+extern  void vp8_init_scan_order_mask();
+
+void vp8_update_mode_info_border(MODE_INFO *mi, int rows, int cols)
+{
+    int i;
+    vpx_memset(mi - cols - 1, 0, sizeof(MODE_INFO) * cols + 1);
+
+    for (i = 0; i < rows; i++)
+    {
+        vpx_memset(&mi[i*cols-1], 0, sizeof(MODE_INFO));
+    }
+}
+void vp8_de_alloc_frame_buffers(VP8_COMMON *oci)
+{
+    vp8_yv12_de_alloc_frame_buffer(&oci->temp_scale_frame);
+    vp8_yv12_de_alloc_frame_buffer(&oci->new_frame);
+    vp8_yv12_de_alloc_frame_buffer(&oci->last_frame);
+    vp8_yv12_de_alloc_frame_buffer(&oci->golden_frame);
+    vp8_yv12_de_alloc_frame_buffer(&oci->alt_ref_frame);
+    vp8_yv12_de_alloc_frame_buffer(&oci->post_proc_buffer);
+
+    vpx_free(oci->above_context[Y1CONTEXT]);
+    vpx_free(oci->above_context[UCONTEXT]);
+    vpx_free(oci->above_context[VCONTEXT]);
+    vpx_free(oci->above_context[Y2CONTEXT]);
+    vpx_free(oci->mip);
+
+    oci->above_context[Y1CONTEXT] = 0;
+    oci->above_context[UCONTEXT]  = 0;
+    oci->above_context[VCONTEXT]  = 0;
+    oci->above_context[Y2CONTEXT] = 0;
+    oci->mip = 0;
+
+    // Structure used to minitor GF useage
+    if (oci->gf_active_flags != 0)
+        vpx_free(oci->gf_active_flags);
+
+    oci->gf_active_flags = 0;
+}
+
+int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
+{
+    vp8_de_alloc_frame_buffers(oci);
+
+    // our internal buffers are always multiples of 16
+    if ((width & 0xf) != 0)
+        width += 16 - (width & 0xf);
+
+    if ((height & 0xf) != 0)
+        height += 16 - (height & 0xf);
+
+
+    if (vp8_yv12_alloc_frame_buffer(&oci->temp_scale_frame,   width, 16, VP8BORDERINPIXELS) < 0)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+
+    if (vp8_yv12_alloc_frame_buffer(&oci->new_frame,   width, height, VP8BORDERINPIXELS) < 0)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    if (vp8_yv12_alloc_frame_buffer(&oci->last_frame,  width, height, VP8BORDERINPIXELS) < 0)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    if (vp8_yv12_alloc_frame_buffer(&oci->golden_frame, width, height, VP8BORDERINPIXELS) < 0)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    if (vp8_yv12_alloc_frame_buffer(&oci->alt_ref_frame, width, height, VP8BORDERINPIXELS) < 0)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    if (vp8_yv12_alloc_frame_buffer(&oci->post_proc_buffer, width, height, VP8BORDERINPIXELS) < 0)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    oci->mb_rows = height >> 4;
+    oci->mb_cols = width >> 4;
+    oci->MBs = oci->mb_rows * oci->mb_cols;
+    oci->mode_info_stride = oci->mb_cols + 1;
+    oci->mip = vpx_calloc((oci->mb_cols + 1) * (oci->mb_rows + 1), sizeof(MODE_INFO));
+
+    if (!oci->mip)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    oci->mi = oci->mip + oci->mode_info_stride + 1;
+
+
+    oci->above_context[Y1CONTEXT] = vpx_calloc(sizeof(ENTROPY_CONTEXT) * oci->mb_cols * 4 , 1);
+
+    if (!oci->above_context[Y1CONTEXT])
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    oci->above_context[UCONTEXT]  = vpx_calloc(sizeof(ENTROPY_CONTEXT) * oci->mb_cols * 2 , 1);
+
+    if (!oci->above_context[UCONTEXT])
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    oci->above_context[VCONTEXT]  = vpx_calloc(sizeof(ENTROPY_CONTEXT) * oci->mb_cols * 2 , 1);
+
+    if (!oci->above_context[VCONTEXT])
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    oci->above_context[Y2CONTEXT] = vpx_calloc(sizeof(ENTROPY_CONTEXT) * oci->mb_cols     , 1);
+
+    if (!oci->above_context[Y2CONTEXT])
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    vp8_update_mode_info_border(oci->mi, oci->mb_rows, oci->mb_cols);
+
+    // Structures used to minitor GF usage
+    if (oci->gf_active_flags != 0)
+        vpx_free(oci->gf_active_flags);
+
+    oci->gf_active_flags = (unsigned char *)vpx_calloc(oci->mb_rows * oci->mb_cols, 1);
+
+    if (!oci->gf_active_flags)
+    {
+        vp8_de_alloc_frame_buffers(oci);
+        return ALLOC_FAILURE;
+    }
+
+    oci->gf_active_count = oci->mb_rows * oci->mb_cols;
+
+    return 0;
+}
+void vp8_setup_version(VP8_COMMON *cm)
+{
+    switch (cm->version)
+    {
+    case 0:
+        cm->no_lpf = 0;
+        cm->simpler_lpf = 0;
+        cm->use_bilinear_mc_filter = 0;
+        cm->full_pixel = 0;
+        break;
+    case 1:
+        cm->no_lpf = 0;
+        cm->simpler_lpf = 1;
+        cm->use_bilinear_mc_filter = 1;
+        cm->full_pixel = 0;
+        break;
+    case 2:
+        cm->no_lpf = 1;
+        cm->simpler_lpf = 0;
+        cm->use_bilinear_mc_filter = 1;
+        cm->full_pixel = 0;
+        break;
+    case 3:
+        cm->no_lpf = 1;
+        cm->simpler_lpf = 1;
+        cm->use_bilinear_mc_filter = 1;
+        cm->full_pixel = 1;
+        break;
+    default:
+        //4,5,6,7 are reserved for future use
+        cm->no_lpf = 0;
+        cm->simpler_lpf = 0;
+        cm->use_bilinear_mc_filter = 0;
+        cm->full_pixel = 0;
+        break;
+    }
+}
+void vp8_create_common(VP8_COMMON *oci)
+{
+    vp8_machine_specific_config(oci);
+    vp8_default_coef_probs(oci);
+    vp8_init_mbmode_probs(oci);
+    vp8_default_bmode_probs(oci->fc.bmode_prob);
+
+    oci->mb_no_coeff_skip = 1;
+    oci->no_lpf = 0;
+    oci->simpler_lpf = 0;
+    oci->use_bilinear_mc_filter = 0;
+    oci->full_pixel = 0;
+    oci->multi_token_partition = ONE_PARTITION;
+    oci->clr_type = REG_YUV;
+    oci->clamp_type = RECON_CLAMP_REQUIRED;
+
+    // Initialise reference frame sign bias structure to defaults
+    vpx_memset(oci->ref_frame_sign_bias, 0, sizeof(oci->ref_frame_sign_bias));
+
+    // Default disable buffer to buffer copying
+    oci->copy_buffer_to_gf = 0;
+    oci->copy_buffer_to_arf = 0;
+}
+
+void vp8_remove_common(VP8_COMMON *oci)
+{
+    vp8_de_alloc_frame_buffers(oci);
+}
+
+void vp8_initialize_common()
+{
+    vp8_coef_tree_initialize();
+
+    vp8_entropy_mode_init();
+
+    vp8_init_scan_order_mask();
+
+}
diff --git a/vp8/common/alloccommon.h b/vp8/common/alloccommon.h
new file mode 100644 (file)
index 0000000..73c7383
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_ALLOCCOMMON_H
+#define __INC_ALLOCCOMMON_H
+
+#include "onyxc_int.h"
+
+void vp8_create_common(VP8_COMMON *oci);
+void vp8_remove_common(VP8_COMMON *oci);
+void vp8_de_alloc_frame_buffers(VP8_COMMON *oci);
+int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height);
+void vp8_setup_version(VP8_COMMON *oci);
+
+#endif
diff --git a/vp8/common/arm/armv6/bilinearfilter_v6.asm b/vp8/common/arm/armv6/bilinearfilter_v6.asm
new file mode 100644 (file)
index 0000000..4428cf8
--- /dev/null
@@ -0,0 +1,237 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_filter_block2d_bil_first_pass_armv6|
+    EXPORT  |vp8_filter_block2d_bil_second_pass_armv6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+;-------------------------------------
+; r0    unsigned char *src_ptr,
+; r1    unsigned short *output_ptr,
+; r2    unsigned int src_pixels_per_line,
+; r3    unsigned int output_height,
+; stack    unsigned int output_width,
+; stack    const short *vp8_filter
+;-------------------------------------
+; The output is transposed stroed in output array to make it easy for second pass filtering.
+|vp8_filter_block2d_bil_first_pass_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #40]                  ; vp8_filter address
+    ldr     r4, [sp, #36]                   ; output width
+
+    mov     r12, r3                         ; outer-loop counter
+    sub     r2, r2, r4                      ; src increment for height loop
+
+    ;;IF ARCHITECTURE=6
+    pld     [r0]
+    ;;ENDIF
+
+    ldr     r5, [r11]                       ; load up filter coefficients
+
+    mov     r3, r3, lsl #1                  ; output_height*2
+    add     r3, r3, #2                      ; plus 2 to make output buffer 4-bit aligned since height is actually (height+1)
+
+    mov     r11, r1                         ; save output_ptr for each row
+
+    cmp     r5, #128                        ; if filter coef = 128, then skip the filter
+    beq     bil_null_1st_filter
+
+|bil_height_loop_1st_v6|
+    ldrb    r6, [r0]                        ; load source data
+    ldrb    r7, [r0, #1]
+    ldrb    r8, [r0, #2]
+    mov     lr, r4, lsr #2                  ; 4-in-parellel loop counter
+
+|bil_width_loop_1st_v6|
+    ldrb    r9, [r0, #3]
+    ldrb    r10, [r0, #4]
+
+    pkhbt   r6, r6, r7, lsl #16             ; src[1] | src[0]
+    pkhbt   r7, r7, r8, lsl #16             ; src[2] | src[1]
+
+    smuad   r6, r6, r5                      ; apply the filter
+    pkhbt   r8, r8, r9, lsl #16             ; src[3] | src[2]
+    smuad   r7, r7, r5
+    pkhbt   r9, r9, r10, lsl #16            ; src[4] | src[3]
+
+    smuad   r8, r8, r5
+    smuad   r9, r9, r5
+
+    add     r0, r0, #4
+    subs    lr, lr, #1
+
+    add     r6, r6, #0x40                   ; round_shift_and_clamp
+    add     r7, r7, #0x40
+    usat    r6, #16, r6, asr #7
+    usat    r7, #16, r7, asr #7
+
+    strh    r6, [r1], r3                    ; result is transposed and stored
+
+    add     r8, r8, #0x40                   ; round_shift_and_clamp
+    strh    r7, [r1], r3
+    add     r9, r9, #0x40
+    usat    r8, #16, r8, asr #7
+    usat    r9, #16, r9, asr #7
+
+    strh    r8, [r1], r3                    ; result is transposed and stored
+
+    ldrneb  r6, [r0]                        ; load source data
+    strh    r9, [r1], r3
+
+    ldrneb  r7, [r0, #1]
+    ldrneb  r8, [r0, #2]
+
+    bne     bil_width_loop_1st_v6
+
+    add     r0, r0, r2                      ; move to next input row
+    subs    r12, r12, #1
+
+    ;;IF ARCHITECTURE=6
+    pld     [r0]
+    ;;ENDIF
+
+    add     r11, r11, #2                    ; move over to next column
+    mov     r1, r11
+
+    bne     bil_height_loop_1st_v6
+
+    ldmia   sp!, {r4 - r11, pc}
+
+|bil_null_1st_filter|
+|bil_height_loop_null_1st|
+    mov     lr, r4, lsr #2                  ; loop counter
+
+|bil_width_loop_null_1st|
+    ldrb    r6, [r0]                        ; load data
+    ldrb    r7, [r0, #1]
+    ldrb    r8, [r0, #2]
+    ldrb    r9, [r0, #3]
+
+    strh    r6, [r1], r3                    ; store it to immediate buffer
+    add     r0, r0, #4
+    strh    r7, [r1], r3
+    subs    lr, lr, #1
+    strh    r8, [r1], r3
+    strh    r9, [r1], r3
+
+    bne     bil_width_loop_null_1st
+
+    subs    r12, r12, #1
+    add     r0, r0, r2                      ; move to next input line
+    add     r11, r11, #2                    ; move over to next column
+    mov     r1, r11
+
+    bne     bil_height_loop_null_1st
+
+    ldmia   sp!, {r4 - r11, pc}
+
+    ENDP  ; |vp8_filter_block2d_bil_first_pass_armv6|
+
+
+;---------------------------------
+; r0    unsigned short *src_ptr,
+; r1    unsigned char *output_ptr,
+; r2    int output_pitch,
+; r3    unsigned int  output_height,
+; stack unsigned int  output_width,
+; stack const short *vp8_filter
+;---------------------------------
+|vp8_filter_block2d_bil_second_pass_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #40]                  ; vp8_filter address
+    ldr     r4, [sp, #36]                   ; output width
+
+    ldr     r5, [r11]                       ; load up filter coefficients
+    mov     r12, r4                         ; outer-loop counter = width, since we work on transposed data matrix
+    mov     r11, r1
+
+    cmp     r5, #128                        ; if filter coef = 128, then skip the filter
+    beq     bil_null_2nd_filter
+
+|bil_height_loop_2nd|
+    ldr     r6, [r0]                        ; load the data
+    ldr     r8, [r0, #4]
+    ldrh    r10, [r0, #8]
+    mov     lr, r3, lsr #2                  ; loop counter
+
+|bil_width_loop_2nd|
+    pkhtb   r7, r6, r8                      ; src[1] | src[2]
+    pkhtb   r9, r8, r10                     ; src[3] | src[4]
+
+    smuad   r6, r6, r5                      ; apply filter
+    smuad   r8, r8, r5                      ; apply filter
+
+    subs    lr, lr, #1
+
+    smuadx  r7, r7, r5                      ; apply filter
+    smuadx  r9, r9, r5                      ; apply filter
+
+    add     r0, r0, #8
+
+    add     r6, r6, #0x40                   ; round_shift_and_clamp
+    add     r7, r7, #0x40
+    usat    r6, #8, r6, asr #7
+    usat    r7, #8, r7, asr #7
+    strb    r6, [r1], r2                    ; the result is transposed back and stored
+
+    add     r8, r8, #0x40                   ; round_shift_and_clamp
+    strb    r7, [r1], r2
+    add     r9, r9, #0x40
+    usat    r8, #8, r8, asr #7
+    usat    r9, #8, r9, asr #7
+    strb    r8, [r1], r2                    ; the result is transposed back and stored
+
+    ldrne   r6, [r0]                        ; load data
+    strb    r9, [r1], r2
+    ldrne   r8, [r0, #4]
+    ldrneh  r10, [r0, #8]
+
+    bne     bil_width_loop_2nd
+
+    subs    r12, r12, #1
+    add     r0, r0, #4                      ; update src for next row
+    add     r11, r11, #1
+    mov     r1, r11
+
+    bne     bil_height_loop_2nd
+    ldmia   sp!, {r4 - r11, pc}
+
+|bil_null_2nd_filter|
+|bil_height_loop_null_2nd|
+    mov     lr, r3, lsr #2
+
+|bil_width_loop_null_2nd|
+    ldr     r6, [r0], #4                    ; load data
+    subs    lr, lr, #1
+    ldr     r8, [r0], #4
+
+    strb    r6, [r1], r2                    ; store data
+    mov     r7, r6, lsr #16
+    strb    r7, [r1], r2
+    mov     r9, r8, lsr #16
+    strb    r8, [r1], r2
+    strb    r9, [r1], r2
+
+    bne     bil_width_loop_null_2nd
+
+    subs    r12, r12, #1
+    add     r0, r0, #4
+    add     r11, r11, #1
+    mov     r1, r11
+
+    bne     bil_height_loop_null_2nd
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP  ; |vp8_filter_block2d_second_pass_armv6|
+
+    END
diff --git a/vp8/common/arm/armv6/copymem16x16_v6.asm b/vp8/common/arm/armv6/copymem16x16_v6.asm
new file mode 100644 (file)
index 0000000..00e9739
--- /dev/null
@@ -0,0 +1,181 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_copy_mem16x16_v6|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    Block, CODE, READONLY ; name this block of code
+;void copy_mem16x16_v6( unsigned char *src, int src_stride, unsigned char *dst, int dst_stride)
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_copy_mem16x16_v6| PROC
+    stmdb       sp!, {r4 - r7}
+    ;push   {r4-r7}
+
+    ;preload
+    pld     [r0]
+    pld     [r0, r1]
+    pld     [r0, r1, lsl #1]
+
+    ands    r4, r0, #15
+    beq     copy_mem16x16_fast
+
+    ands    r4, r0, #7
+    beq     copy_mem16x16_8
+
+    ands    r4, r0, #3
+    beq     copy_mem16x16_4
+
+    ;copy one byte each time
+    ldrb    r4, [r0]
+    ldrb    r5, [r0, #1]
+    ldrb    r6, [r0, #2]
+    ldrb    r7, [r0, #3]
+
+    mov     r12, #16
+
+copy_mem16x16_1_loop
+    strb    r4, [r2]
+    strb    r5, [r2, #1]
+    strb    r6, [r2, #2]
+    strb    r7, [r2, #3]
+
+    ldrb    r4, [r0, #4]
+    ldrb    r5, [r0, #5]
+    ldrb    r6, [r0, #6]
+    ldrb    r7, [r0, #7]
+
+    subs    r12, r12, #1
+
+    strb    r4, [r2, #4]
+    strb    r5, [r2, #5]
+    strb    r6, [r2, #6]
+    strb    r7, [r2, #7]
+
+    ldrb    r4, [r0, #8]
+    ldrb    r5, [r0, #9]
+    ldrb    r6, [r0, #10]
+    ldrb    r7, [r0, #11]
+
+    strb    r4, [r2, #8]
+    strb    r5, [r2, #9]
+    strb    r6, [r2, #10]
+    strb    r7, [r2, #11]
+
+    ldrb    r4, [r0, #12]
+    ldrb    r5, [r0, #13]
+    ldrb    r6, [r0, #14]
+    ldrb    r7, [r0, #15]
+
+    add     r0, r0, r1
+
+    strb    r4, [r2, #12]
+    strb    r5, [r2, #13]
+    strb    r6, [r2, #14]
+    strb    r7, [r2, #15]
+
+    add     r2, r2, r3
+
+    ldrneb  r4, [r0]
+    ldrneb  r5, [r0, #1]
+    ldrneb  r6, [r0, #2]
+    ldrneb  r7, [r0, #3]
+
+    bne     copy_mem16x16_1_loop
+
+    ldmia       sp!, {r4 - r7}
+    ;pop        {r4-r7}
+    mov     pc, lr
+
+;copy 4 bytes each time
+copy_mem16x16_4
+    ldr     r4, [r0]
+    ldr     r5, [r0, #4]
+    ldr     r6, [r0, #8]
+    ldr     r7, [r0, #12]
+
+    mov     r12, #16
+
+copy_mem16x16_4_loop
+    subs    r12, r12, #1
+    add     r0, r0, r1
+
+    str     r4, [r2]
+    str     r5, [r2, #4]
+    str     r6, [r2, #8]
+    str     r7, [r2, #12]
+
+    add     r2, r2, r3
+
+    ldrne   r4, [r0]
+    ldrne   r5, [r0, #4]
+    ldrne   r6, [r0, #8]
+    ldrne   r7, [r0, #12]
+
+    bne     copy_mem16x16_4_loop
+
+    ldmia       sp!, {r4 - r7}
+    ;pop        {r4-r7}
+    mov     pc, lr
+
+;copy 8 bytes each time
+copy_mem16x16_8
+    sub     r1, r1, #16
+    sub     r3, r3, #16
+
+    mov     r12, #16
+
+copy_mem16x16_8_loop
+    ldmia   r0!, {r4-r5}
+    ;ldm        r0, {r4-r5}
+    ldmia   r0!, {r6-r7}
+
+    add     r0, r0, r1
+
+    stmia   r2!, {r4-r5}
+    subs    r12, r12, #1
+    ;stm        r2, {r4-r5}
+    stmia   r2!, {r6-r7}
+
+    add     r2, r2, r3
+
+    bne     copy_mem16x16_8_loop
+
+    ldmia       sp!, {r4 - r7}
+    ;pop        {r4-r7}
+    mov     pc, lr
+
+;copy 16 bytes each time
+copy_mem16x16_fast
+    ;sub        r1, r1, #16
+    ;sub        r3, r3, #16
+
+    mov     r12, #16
+
+copy_mem16x16_fast_loop
+    ldmia   r0, {r4-r7}
+    ;ldm        r0, {r4-r7}
+    add     r0, r0, r1
+
+    subs    r12, r12, #1
+    stmia   r2, {r4-r7}
+    ;stm        r2, {r4-r7}
+    add     r2, r2, r3
+
+    bne     copy_mem16x16_fast_loop
+
+    ldmia       sp!, {r4 - r7}
+    ;pop        {r4-r7}
+    mov     pc, lr
+
+    ENDP  ; |vp8_copy_mem16x16_v6|
+
+    END
diff --git a/vp8/common/arm/armv6/copymem8x4_v6.asm b/vp8/common/arm/armv6/copymem8x4_v6.asm
new file mode 100644 (file)
index 0000000..94473ca
--- /dev/null
@@ -0,0 +1,127 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_copy_mem8x4_v6|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    Block, CODE, READONLY ; name this block of code
+;void vp8_copy_mem8x4_v6( unsigned char *src, int src_stride, unsigned char *dst, int dst_stride)
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_copy_mem8x4_v6| PROC
+    ;push   {r4-r5}
+    stmdb  sp!, {r4-r5}
+
+    ;preload
+    pld     [r0]
+    pld     [r0, r1]
+    pld     [r0, r1, lsl #1]
+
+    ands    r4, r0, #7
+    beq     copy_mem8x4_fast
+
+    ands    r4, r0, #3
+    beq     copy_mem8x4_4
+
+    ;copy 1 byte each time
+    ldrb    r4, [r0]
+    ldrb    r5, [r0, #1]
+
+    mov     r12, #4
+
+copy_mem8x4_1_loop
+    strb    r4, [r2]
+    strb    r5, [r2, #1]
+
+    ldrb    r4, [r0, #2]
+    ldrb    r5, [r0, #3]
+
+    subs    r12, r12, #1
+
+    strb    r4, [r2, #2]
+    strb    r5, [r2, #3]
+
+    ldrb    r4, [r0, #4]
+    ldrb    r5, [r0, #5]
+
+    strb    r4, [r2, #4]
+    strb    r5, [r2, #5]
+
+    ldrb    r4, [r0, #6]
+    ldrb    r5, [r0, #7]
+
+    add     r0, r0, r1
+
+    strb    r4, [r2, #6]
+    strb    r5, [r2, #7]
+
+    add     r2, r2, r3
+
+    ldrneb  r4, [r0]
+    ldrneb  r5, [r0, #1]
+
+    bne     copy_mem8x4_1_loop
+
+    ldmia       sp!, {r4 - r5}
+    ;pop        {r4-r5}
+    mov     pc, lr
+
+;copy 4 bytes each time
+copy_mem8x4_4
+    ldr     r4, [r0]
+    ldr     r5, [r0, #4]
+
+    mov     r12, #4
+
+copy_mem8x4_4_loop
+    subs    r12, r12, #1
+    add     r0, r0, r1
+
+    str     r4, [r2]
+    str     r5, [r2, #4]
+
+    add     r2, r2, r3
+
+    ldrne   r4, [r0]
+    ldrne   r5, [r0, #4]
+
+    bne     copy_mem8x4_4_loop
+
+    ldmia  sp!, {r4-r5}
+    ;pop        {r4-r5}
+    mov     pc, lr
+
+;copy 8 bytes each time
+copy_mem8x4_fast
+    ;sub        r1, r1, #8
+    ;sub        r3, r3, #8
+
+    mov     r12, #4
+
+copy_mem8x4_fast_loop
+    ldmia   r0, {r4-r5}
+    ;ldm        r0, {r4-r5}
+    add     r0, r0, r1
+
+    subs    r12, r12, #1
+    stmia   r2, {r4-r5}
+    ;stm        r2, {r4-r5}
+    add     r2, r2, r3
+
+    bne     copy_mem8x4_fast_loop
+
+    ldmia  sp!, {r4-r5}
+    ;pop        {r4-r5}
+    mov     pc, lr
+
+    ENDP  ; |vp8_copy_mem8x4_v6|
+
+    END
diff --git a/vp8/common/arm/armv6/copymem8x8_v6.asm b/vp8/common/arm/armv6/copymem8x8_v6.asm
new file mode 100644 (file)
index 0000000..7cfa533
--- /dev/null
@@ -0,0 +1,127 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_copy_mem8x8_v6|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    Block, CODE, READONLY ; name this block of code
+;void copy_mem8x8_v6( unsigned char *src, int src_stride, unsigned char *dst, int dst_stride)
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_copy_mem8x8_v6| PROC
+    ;push   {r4-r5}
+    stmdb  sp!, {r4-r5}
+
+    ;preload
+    pld     [r0]
+    pld     [r0, r1]
+    pld     [r0, r1, lsl #1]
+
+    ands    r4, r0, #7
+    beq     copy_mem8x8_fast
+
+    ands    r4, r0, #3
+    beq     copy_mem8x8_4
+
+    ;copy 1 byte each time
+    ldrb    r4, [r0]
+    ldrb    r5, [r0, #1]
+
+    mov     r12, #8
+
+copy_mem8x8_1_loop
+    strb    r4, [r2]
+    strb    r5, [r2, #1]
+
+    ldrb    r4, [r0, #2]
+    ldrb    r5, [r0, #3]
+
+    subs    r12, r12, #1
+
+    strb    r4, [r2, #2]
+    strb    r5, [r2, #3]
+
+    ldrb    r4, [r0, #4]
+    ldrb    r5, [r0, #5]
+
+    strb    r4, [r2, #4]
+    strb    r5, [r2, #5]
+
+    ldrb    r4, [r0, #6]
+    ldrb    r5, [r0, #7]
+
+    add     r0, r0, r1
+
+    strb    r4, [r2, #6]
+    strb    r5, [r2, #7]
+
+    add     r2, r2, r3
+
+    ldrneb  r4, [r0]
+    ldrneb  r5, [r0, #1]
+
+    bne     copy_mem8x8_1_loop
+
+    ldmia       sp!, {r4 - r5}
+    ;pop        {r4-r5}
+    mov     pc, lr
+
+;copy 4 bytes each time
+copy_mem8x8_4
+    ldr     r4, [r0]
+    ldr     r5, [r0, #4]
+
+    mov     r12, #8
+
+copy_mem8x8_4_loop
+    subs    r12, r12, #1
+    add     r0, r0, r1
+
+    str     r4, [r2]
+    str     r5, [r2, #4]
+
+    add     r2, r2, r3
+
+    ldrne   r4, [r0]
+    ldrne   r5, [r0, #4]
+
+    bne     copy_mem8x8_4_loop
+
+    ldmia       sp!, {r4 - r5}
+    ;pop        {r4-r5}
+    mov     pc, lr
+
+;copy 8 bytes each time
+copy_mem8x8_fast
+    ;sub        r1, r1, #8
+    ;sub        r3, r3, #8
+
+    mov     r12, #8
+
+copy_mem8x8_fast_loop
+    ldmia   r0, {r4-r5}
+    ;ldm        r0, {r4-r5}
+    add     r0, r0, r1
+
+    subs    r12, r12, #1
+    stmia   r2, {r4-r5}
+    ;stm        r2, {r4-r5}
+    add     r2, r2, r3
+
+    bne     copy_mem8x8_fast_loop
+
+    ldmia  sp!, {r4-r5}
+    ;pop        {r4-r5}
+    mov     pc, lr
+
+    ENDP  ; |vp8_copy_mem8x8_v6|
+
+    END
diff --git a/vp8/common/arm/armv6/filter_v6.asm b/vp8/common/arm/armv6/filter_v6.asm
new file mode 100644 (file)
index 0000000..a7863fc
--- /dev/null
@@ -0,0 +1,383 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_filter_block2d_first_pass_armv6|
+    EXPORT  |vp8_filter_block2d_second_pass_armv6|
+    EXPORT  |vp8_filter_block2d_first_pass_only_armv6|
+    EXPORT  |vp8_filter_block2d_second_pass_only_armv6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+;-------------------------------------
+; r0    unsigned char *src_ptr
+; r1    short         *output_ptr
+; r2    unsigned int src_pixels_per_line
+; r3    unsigned int output_width
+; stack unsigned int output_height
+; stack const short *vp8_filter
+;-------------------------------------
+; vp8_filter the input and put in the output array.  Apply the 6 tap FIR filter with
+; the output being a 2 byte value and the intput being a 1 byte value.
+|vp8_filter_block2d_first_pass_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #40]                  ; vp8_filter address
+    ldr     r7, [sp, #36]                   ; output height
+
+    sub     r2, r2, r3                      ; inside loop increments input array,
+                                            ; so the height loop only needs to add
+                                            ; r2 - width to the input pointer
+
+    mov     r3, r3, lsl #1                  ; multiply width by 2 because using shorts
+    add     r12, r3, #16                    ; square off the output
+    sub     sp, sp, #4
+
+    ;;IF ARCHITECTURE=6
+    ;pld        [r0, #-2]
+    ;;pld       [r0, #30]
+    ;;ENDIF
+
+    ldr     r4, [r11]                       ; load up packed filter coefficients
+    ldr     r5, [r11, #4]
+    ldr     r6, [r11, #8]
+
+    str     r1, [sp]                        ; push destination to stack
+    mov     r7, r7, lsl #16                 ; height is top part of counter
+
+; six tap filter
+|height_loop_1st_6|
+    ldrb    r8, [r0, #-2]                   ; load source data
+    ldrb    r9, [r0, #-1]
+    ldrb    r10, [r0], #2
+    orr     r7, r7, r3, lsr #2              ; construct loop counter
+
+|width_loop_1st_6|
+    ldrb    r11, [r0, #-1]
+
+    pkhbt   lr, r8, r9, lsl #16             ; r9 | r8
+    pkhbt   r8, r9, r10, lsl #16            ; r10 | r9
+
+    ldrb    r9, [r0]
+
+    smuad   lr, lr, r4                      ; apply the filter
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+    smuad   r8, r8, r4
+    pkhbt   r11, r11, r9, lsl #16           ; r9 | r11
+
+    smlad   lr, r10, r5, lr
+    ldrb    r10, [r0, #1]
+    smlad   r8, r11, r5, r8
+    ldrb    r11, [r0, #2]
+
+    sub     r7, r7, #1
+
+    pkhbt   r9, r9, r10, lsl #16            ; r10 | r9
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+
+    smlad   lr, r9, r6, lr
+    smlad   r11, r10, r6, r8
+
+    ands    r10, r7, #0xff                  ; test loop counter
+
+    add     lr, lr, #0x40                   ; round_shift_and_clamp
+    ldrneb  r8, [r0, #-2]                   ; load data for next loop
+    usat    lr, #8, lr, asr #7
+    add     r11, r11, #0x40
+    ldrneb  r9, [r0, #-1]
+    usat    r11, #8, r11, asr #7
+
+    strh    lr, [r1], r12                   ; result is transposed and stored, which
+                                            ; will make second pass filtering easier.
+    ldrneb  r10, [r0], #2
+    strh    r11, [r1], r12
+
+    bne     width_loop_1st_6
+
+    ;;add       r9, r2, #30                 ; attempt to load 2 adjacent cache lines
+    ;;IF ARCHITECTURE=6
+    ;pld        [r0, r2]
+    ;;pld       [r0, r9]
+    ;;ENDIF
+
+    ldr     r1, [sp]                        ; load and update dst address
+    subs    r7, r7, #0x10000
+    add     r0, r0, r2                      ; move to next input line
+    add     r1, r1, #2                      ; move over to next column
+    str     r1, [sp]
+
+    bne     height_loop_1st_6
+
+    add     sp, sp, #4
+    ldmia   sp!, {r4 - r11, pc}
+
+    ENDP
+
+;---------------------------------
+; r0    short         *src_ptr,
+; r1    unsigned char *output_ptr,
+; r2    unsigned int output_pitch,
+; r3    unsigned int cnt,
+; stack const short *vp8_filter
+;---------------------------------
+|vp8_filter_block2d_second_pass_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #36]                  ; vp8_filter address
+    sub     sp, sp, #4
+    mov     r7, r3, lsl #16                 ; height is top part of counter
+    str     r1, [sp]                        ; push destination to stack
+
+    ldr     r4, [r11]                       ; load up packed filter coefficients
+    ldr     r5, [r11, #4]
+    ldr     r6, [r11, #8]
+
+    pkhbt   r12, r5, r4                     ; pack the filter differently
+    pkhbt   r11, r6, r5
+
+    sub     r0, r0, #4                      ; offset input buffer
+
+|height_loop_2nd|
+    ldr     r8, [r0]                        ; load the data
+    ldr     r9, [r0, #4]
+    orr     r7, r7, r3, lsr #1              ; loop counter
+
+|width_loop_2nd|
+    smuad   lr, r4, r8                      ; apply filter
+    sub     r7, r7, #1
+    smulbt  r8, r4, r8
+
+    ldr     r10, [r0, #8]
+
+    smlad   lr, r5, r9, lr
+    smladx  r8, r12, r9, r8
+
+    ldrh    r9, [r0, #12]
+
+    smlad   lr, r6, r10, lr
+    smladx  r8, r11, r10, r8
+
+    add     r0, r0, #4
+    smlatb  r10, r6, r9, r8
+
+    add     lr, lr, #0x40                   ; round_shift_and_clamp
+    ands    r8, r7, #0xff
+    usat    lr, #8, lr, asr #7
+    add     r10, r10, #0x40
+    strb    lr, [r1], r2                    ; the result is transposed back and stored
+    usat    r10, #8, r10, asr #7
+
+    ldrne   r8, [r0]                        ; load data for next loop
+    ldrne   r9, [r0, #4]
+    strb    r10, [r1], r2
+
+    bne     width_loop_2nd
+
+    ldr     r1, [sp]                        ; update dst for next loop
+    subs    r7, r7, #0x10000
+    add     r0, r0, #16                     ; updata src for next loop
+    add     r1, r1, #1
+    str     r1, [sp]
+
+    bne     height_loop_2nd
+
+    add     sp, sp, #4
+    ldmia   sp!, {r4 - r11, pc}
+
+    ENDP
+
+;------------------------------------
+; r0    unsigned char *src_ptr
+; r1    unsigned char *output_ptr,
+; r2    unsigned int src_pixels_per_line
+; r3    unsigned int cnt,
+; stack unsigned int output_pitch,
+; stack const short *vp8_filter
+;------------------------------------
+|vp8_filter_block2d_first_pass_only_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r4, [sp, #36]                   ; output pitch
+    ldr     r11, [sp, #40]                  ; HFilter address
+    sub     sp, sp, #8
+
+    mov     r7, r3
+    sub     r2, r2, r3                      ; inside loop increments input array,
+                                            ; so the height loop only needs to add
+                                            ; r2 - width to the input pointer
+
+    sub     r4, r4, r3
+    str     r4, [sp]                        ; save modified output pitch
+    str     r2, [sp, #4]
+
+    mov     r2, #0x40
+
+    ldr     r4, [r11]                       ; load up packed filter coefficients
+    ldr     r5, [r11, #4]
+    ldr     r6, [r11, #8]
+
+; six tap filter
+|height_loop_1st_only_6|
+    ldrb    r8, [r0, #-2]                   ; load data
+    ldrb    r9, [r0, #-1]
+    ldrb    r10, [r0], #2
+
+    mov     r12, r3, lsr #1                 ; loop counter
+
+|width_loop_1st_only_6|
+    ldrb    r11, [r0, #-1]
+
+    pkhbt   lr, r8, r9, lsl #16             ; r9 | r8
+    pkhbt   r8, r9, r10, lsl #16            ; r10 | r9
+
+    ldrb    r9, [r0]
+
+;;  smuad   lr, lr, r4
+    smlad   lr, lr, r4, r2
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+;;  smuad   r8, r8, r4
+    smlad   r8, r8, r4, r2
+    pkhbt   r11, r11, r9, lsl #16           ; r9 | r11
+
+    smlad   lr, r10, r5, lr
+    ldrb    r10, [r0, #1]
+    smlad   r8, r11, r5, r8
+    ldrb    r11, [r0, #2]
+
+    subs    r12, r12, #1
+
+    pkhbt   r9, r9, r10, lsl #16            ; r10 | r9
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+
+    smlad   lr, r9, r6, lr
+    smlad   r10, r10, r6, r8
+
+;;  add     lr, lr, #0x40                   ; round_shift_and_clamp
+    ldrneb  r8, [r0, #-2]                   ; load data for next loop
+    usat    lr, #8, lr, asr #7
+;;  add     r10, r10, #0x40
+    strb    lr, [r1], #1                    ; store the result
+    usat    r10, #8, r10, asr #7
+
+    ldrneb  r9, [r0, #-1]
+    strb    r10, [r1], #1
+    ldrneb  r10, [r0], #2
+
+    bne     width_loop_1st_only_6
+
+    ;;add       r9, r2, #30                 ; attempt to load 2 adjacent cache lines
+    ;;IF ARCHITECTURE=6
+    ;pld        [r0, r2]
+    ;;pld       [r0, r9]
+    ;;ENDIF
+
+    ldr     lr, [sp]                        ; load back output pitch
+    ldr     r12, [sp, #4]                   ; load back output pitch
+    subs    r7, r7, #1
+    add     r0, r0, r12                     ; updata src for next loop
+    add     r1, r1, lr                      ; update dst for next loop
+
+    bne     height_loop_1st_only_6
+
+    add     sp, sp, #8
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP  ; |vp8_filter_block2d_first_pass_only_armv6|
+
+
+;------------------------------------
+; r0    unsigned char *src_ptr,
+; r1    unsigned char *output_ptr,
+; r2    unsigned int src_pixels_per_line
+; r3    unsigned int cnt,
+; stack unsigned int output_pitch,
+; stack const short *vp8_filter
+;------------------------------------
+|vp8_filter_block2d_second_pass_only_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #40]                  ; VFilter address
+    ldr     r12, [sp, #36]                  ; output pitch
+
+    mov     r7, r3, lsl #16                 ; height is top part of counter
+    sub     r0, r0, r2, lsl #1              ; need 6 elements for filtering, 2 before, 3 after
+
+    sub     sp, sp, #8
+
+    ldr     r4, [r11]                       ; load up packed filter coefficients
+    ldr     r5, [r11, #4]
+    ldr     r6, [r11, #8]
+
+    str     r0, [sp]                        ; save r0 to stack
+    str     r1, [sp, #4]                    ; save dst to stack
+
+; six tap filter
+|width_loop_2nd_only_6|
+    ldrb    r8, [r0], r2                    ; load data
+    orr     r7, r7, r3                      ; loop counter
+    ldrb    r9, [r0], r2
+    ldrb    r10, [r0], r2
+
+|height_loop_2nd_only_6|
+    ; filter first column in this inner loop, than, move to next colum.
+    ldrb    r11, [r0], r2
+
+    pkhbt   lr, r8, r9, lsl #16             ; r9 | r8
+    pkhbt   r8, r9, r10, lsl #16            ; r10 | r9
+
+    ldrb    r9, [r0], r2
+
+    smuad   lr, lr, r4
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+    smuad   r8, r8, r4
+    pkhbt   r11, r11, r9, lsl #16           ; r9 | r11
+
+    smlad   lr, r10, r5, lr
+    ldrb    r10, [r0], r2
+    smlad   r8, r11, r5, r8
+    ldrb    r11, [r0]
+
+    sub     r7, r7, #2
+    sub     r0, r0, r2, lsl #2
+
+    pkhbt   r9, r9, r10, lsl #16            ; r10 | r9
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+
+    smlad   lr, r9, r6, lr
+    smlad   r10, r10, r6, r8
+
+    ands    r9, r7, #0xff
+
+    add     lr, lr, #0x40                   ; round_shift_and_clamp
+    ldrneb  r8, [r0], r2                    ; load data for next loop
+    usat    lr, #8, lr, asr #7
+    add     r10, r10, #0x40
+    strb    lr, [r1], r12                   ; store the result for the column
+    usat    r10, #8, r10, asr #7
+
+    ldrneb  r9, [r0], r2
+    strb    r10, [r1], r12
+    ldrneb  r10, [r0], r2
+
+    bne     height_loop_2nd_only_6
+
+    ldr     r0, [sp]
+    ldr     r1, [sp, #4]
+    subs    r7, r7, #0x10000
+    add     r0, r0, #1                      ; move to filter next column
+    str     r0, [sp]
+    add     r1, r1, #1
+    str     r1, [sp, #4]
+
+    bne     width_loop_2nd_only_6
+
+    add     sp, sp, #8
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP  ; |vp8_filter_block2d_second_pass_only_armv6|
+
+    END
diff --git a/vp8/common/arm/armv6/idct_v6.asm b/vp8/common/arm/armv6/idct_v6.asm
new file mode 100644 (file)
index 0000000..25c5165
--- /dev/null
@@ -0,0 +1,376 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+;                   r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r10 r11 r12     r14
+    EXPORT  |vp8_short_idct4x4llm_1_v6|
+    EXPORT  |vp8_short_idct4x4llm_v6|
+    EXPORT  |vp8_short_idct4x4llm_v6_scott|
+    EXPORT  |vp8_short_idct4x4llm_v6_dual|
+
+    EXPORT  |vp8_dc_only_idct_armv6|
+
+    AREA    |.text|, CODE, READONLY
+
+;********************************************************************************
+;*  void short_idct4x4llm_1_v6(INT16 * input, INT16 * output, INT32 pitch)
+;*      r0  INT16 * input
+;*      r1  INT16 * output
+;*      r2  INT32 pitch
+;*  bench:  3/5
+;********************************************************************************
+
+|vp8_short_idct4x4llm_1_v6| PROC         ;   cycles  in  out pit
+            ;
+    ldrsh   r0, [r0]    ; load input[0] 1, r0 un 2
+    add r0, r0, #4  ;   1   +4
+    stmdb   sp!, {r4, r5, lr}   ; make room for wide writes 1                   backup
+    mov r0, r0, asr #3  ; (input[0] + 4) >> 3   1, r0 req`d ^1  >> 3
+    pkhbt   r4, r0, r0, lsl #16 ; pack r0 into r4   1, r0 req`d ^1                  pack
+    mov r5, r4  ; expand                        expand
+
+    strd    r4, [r1], r2    ; *output = r0, post inc    1
+    strd    r4, [r1], r2    ;   1
+    strd    r4, [r1], r2    ;   1
+    strd    r4, [r1]    ;   1
+            ;
+    ldmia   sp!, {r4, r5, pc}   ; replace vars, return                      restore
+    ENDP        ; |vp8_short_idct4x4llm_1_v6|
+;********************************************************************************
+;********************************************************************************
+;********************************************************************************
+
+;********************************************************************************
+;*  void short_idct4x4llm_v6(INT16 * input, INT16 * output, INT32 pitch)
+;*      r0  INT16 * input
+;*      r1  INT16 * output
+;*      r2  INT32 pitch
+;*  bench:
+;********************************************************************************
+
+|vp8_short_idct4x4llm_v6| PROC           ;   cycles  in  out pit
+            ;
+    stmdb   sp!, {r4-r11, lr}   ; backup registers  1                   backup
+            ;
+    mov r4, #0x00004E00 ;   1                   cst
+    orr r4, r4, #0x0000007B ; cospi8sqrt2minus1
+    mov r5, #0x00008A00 ;   1                       cst
+    orr r5, r5, #0x0000008C ; sinpi8sqrt2
+            ;
+    mov r6, #4  ; i=4   1                           i
+loop1           ;
+    ldrsh   r12, [r0, #8]   ; input[4]  1, r12 unavail 2                                                    [4]
+    ldrsh   r3, [r0, #24]   ; input[12] 1, r3 unavail 2             [12]
+    ldrsh   r8, [r0, #16]   ; input[8]  1, r8 unavail 2                                 [8]
+    ldrsh   r7, [r0], #0x2  ; input[0]  1, r7 unavail 2 ++                          [0]
+    smulwb  r10, r5, r12    ; ([4] * sinpi8sqrt2) >> 16 1, r10 un 2, r12/r5 ^1                                          t1
+    smulwb  r11, r4, r3 ; ([12] * cospi8sqrt2minus1) >> 16  1, r11 un 2, r3/r4 ^1                                               t2
+    add r9, r7, r8  ; a1 = [0] + [8]    1                                       a1
+    sub r7, r7, r8  ; b1 = [0] - [8]    1                               b1
+    add r11, r3, r11    ; temp2 1
+    rsb r11, r11, r10   ; c1 = temp1 - temp2    1                                               c1
+    smulwb  r3, r5, r3  ; ([12] * sinpi8sqrt2) >> 16    1, r3 un 2, r3/r5 ^ 1               t2
+    smulwb  r10, r4, r12    ; ([4] * cospi8sqrt2minus1) >> 16   1, r10 un 2, r12/r4 ^1                                          t1
+    add r8, r7, r11 ; b1 + c1   1                                   b+c
+    strh    r8, [r1, r2]    ; out[pitch] = b1+c1    1
+    sub r7, r7, r11 ; b1 - c1   1                               b-c
+    add r10, r12, r10   ; temp1 1
+    add r3, r10, r3 ; d1 = temp1 + temp2    1               d1
+    add r10, r9, r3 ; a1 + d1   1                                           a+d
+    sub r3, r9, r3  ; a1 - d1   1               a-d
+    add r8, r2, r2  ; pitch * 2 1                                   p*2
+    strh    r7, [r1, r8]    ; out[pitch*2] = b1-c1  1
+    add r7, r2, r2, lsl #1  ; pitch * 3 1                               p*3
+    strh    r3, [r1, r7]    ; out[pitch*3] = a1-d1  1
+    subs    r6, r6, #1  ; i--   1                           --
+    strh    r10, [r1], #0x2 ; out[0] = a1+d1    1       ++
+    bne loop1   ; if i>0, continue
+            ;
+    sub r1, r1, #8  ; set up out for next loop  1       -4
+            ; for this iteration, input=prev output
+    mov r6, #4  ; i=4   1                           i
+;   b   returnfull
+loop2           ;
+    ldrsh   r11, [r1, #2]   ; input[1]  1, r11 un 2                                             [1]
+    ldrsh   r8, [r1, #6]    ; input[3]  1, r8 un 2                                  [3]
+    ldrsh   r3, [r1, #4]    ; input[2]  1, r3 un 2              [2]
+    ldrsh   r0, [r1]    ; input[0]  1, r0 un 2  [0]
+    smulwb  r9, r5, r11 ; ([1] * sinpi8sqrt2) >> 16 1, r9 un 2, r5/r11 ^1                                       t1
+    smulwb  r10, r4, r8 ; ([3] * cospi8sqrt2minus1) >> 16   1, r10 un 2, r4/r8 ^1                                           t2
+    add r7, r0, r3  ; a1 = [0] + [2]    1                               a1
+    sub r0, r0, r3  ; b1 = [0] - [2]    1   b1
+    add r10, r8, r10    ; temp2 1
+    rsb r9, r10, r9 ; c1 = temp1 - temp2    1                                       c1
+    smulwb  r8, r5, r8  ; ([3] * sinpi8sqrt2) >> 16 1, r8 un 2, r5/r8 ^1                                    t2
+    smulwb  r10, r4, r11    ; ([1] * cospi8sqrt2minus1) >> 16   1, r10 un 2, r4/r11 ^1                                          t1
+    add r3, r0, r9  ; b1+c1 1               b+c
+    add r3, r3, #4  ; b1+c1+4   1               +4
+    add r10, r11, r10   ; temp1 1
+    mov r3, r3, asr #3  ; b1+c1+4 >> 3  1, r3 ^1                >>3
+    strh    r3, [r1, #2]    ; out[1] = b1+c1    1
+    add r10, r10, r8    ; d1 = temp1 + temp2    1                                           d1
+    add r3, r7, r10 ; a1+d1 1               a+d
+    add r3, r3, #4  ; a1+d1+4   1               +4
+    sub r7, r7, r10 ; a1-d1 1                               a-d
+    add r7, r7, #4  ; a1-d1+4   1                               +4
+    mov r3, r3, asr #3  ; a1+d1+4 >> 3  1, r3 ^1                >>3
+    mov r7, r7, asr #3  ; a1-d1+4 >> 3  1, r7 ^1                                >>3
+    strh    r7, [r1, #6]    ; out[3] = a1-d1    1
+    sub r0, r0, r9  ; b1-c1 1   b-c
+    add r0, r0, #4  ; b1-c1+4   1   +4
+    subs    r6, r6, #1  ; i--   1                           --
+    mov r0, r0, asr #3  ; b1-c1+4 >> 3  1, r0 ^1    >>3
+    strh    r0, [r1, #4]    ; out[2] = b1-c1    1
+    strh    r3, [r1], r2    ; out[0] = a1+d1    1
+;   add r1, r1, r2  ; out += pitch  1       ++
+    bne loop2   ; if i>0, continue
+returnfull          ;
+    ldmia   sp!, {r4 - r11, pc} ; replace vars, return                      restore
+    ENDP
+
+;********************************************************************************
+;********************************************************************************
+;********************************************************************************
+
+;********************************************************************************
+;*  void short_idct4x4llm_v6_scott(INT16 * input, INT16 * output, INT32 pitch)
+;*      r0  INT16 * input
+;*      r1  INT16 * output
+;*      r2  INT32 pitch
+;*  bench:
+;********************************************************************************
+
+|vp8_short_idct4x4llm_v6_scott| PROC         ;   cycles  in  out pit
+;   mov r0, #0  ;
+;   ldr r0, [r0]    ;
+    stmdb   sp!, {r4 - r11, lr} ; backup registers  1                   backup
+            ;
+    mov r3, #0x00004E00 ;                   cos
+    orr r3, r3, #0x0000007B ; cospi8sqrt2minus1
+    mov r4, #0x00008A00 ;                       sin
+    orr r4, r4, #0x0000008C ; sinpi8sqrt2
+            ;
+    mov r5, #0x2    ; i                         i
+            ;
+short_idct4x4llm_v6_scott_loop1          ;
+    ldr r10, [r0, #(4*2)]   ; i5 | i4                                               5,4
+    ldr r11, [r0, #(12*2)]  ; i13 | i12                                                 13,12
+            ;
+    smulwb  r6, r4, r10 ; ((ip[4] * sinpi8sqrt2) >> 16)                             lt1
+    smulwb  r7, r3, r11 ; ((ip[12] * cospi8sqrt2minus1) >> 16)                                  lt2
+            ;
+    smulwb  r12, r3, r10    ; ((ip[4] * cospi8sqrt2misu1) >> 16)                                                        l2t2
+    smulwb  r14, r4, r11    ; ((ip[12] * sinpi8sqrt2) >> 16)                                                                l2t1
+            ;
+    add r6, r6, r7  ; partial c1                                lt1-lt2
+    add r12, r12, r14   ; partial d1                                                        l2t2+l2t1
+            ;
+    smulwt  r14, r4, r10    ; ((ip[5] * sinpi8sqrt2) >> 16)                                                             ht1
+    smulwt  r7, r3, r11 ; ((ip[13] * cospi8sqrt2minus1) >> 16)                                  ht2
+            ;
+    smulwt  r8, r3, r10 ; ((ip[5] * cospi8sqrt2minus1) >> 16)                                       h2t1
+    smulwt  r9, r4, r11 ; ((ip[13] * sinpi8sqrt2) >> 16)                                            h2t2
+            ;
+    add r7, r14, r7 ; partial c1_2                                  ht1+ht2
+    sub r8, r8, r9  ; partial d1_2                                      h2t1-h2t2
+            ;
+    pkhbt   r6, r6, r7, lsl #16 ; partial c1_2 | partial c1_1                               pack
+    pkhbt   r12, r12, r8, lsl #16   ; partial d1_2 | partial d1_1                                                       pack
+            ;
+    usub16  r6, r6, r10 ; c1_2 | c1_1                               c
+    uadd16  r12, r12, r11   ; d1_2 | d1_1                                                       d
+            ;
+    ldr r10, [r0, #0]   ; i1 | i0                                               1,0
+    ldr r11, [r0, #(8*2)]   ; i9 | i10                                                  9,10
+            ;
+;;;;;;  add r0, r0, #0x4    ;       +4
+;;;;;;  add r1, r1, #0x4    ;           +4
+            ;
+    uadd16  r8, r10, r11    ; i1 + i9 | i0 + i8 aka a1                                      a
+    usub16  r9, r10, r11    ; i1 - i9 | i0 - i8 aka b1                                          b
+            ;
+    uadd16  r7, r8, r12 ; a1 + d1 pair                                  a+d
+    usub16  r14, r8, r12    ; a1 - d1 pair                                                              a-d
+            ;
+    str r7, [r1]    ; op[0] = a1 + d1
+    str r14, [r1, r2]   ; op[pitch*3] = a1 - d1
+            ;
+    add r0, r0, #0x4    ; op[pitch] = b1 + c1       ++
+    add r1, r1, #0x4    ; op[pitch*2] = b1 - c1         ++
+            ;
+    subs    r5, r5, #0x1    ;                           --
+    bne short_idct4x4llm_v6_scott_loop1  ;
+            ;
+    sub r1, r1, #16 ; reset output ptr
+    mov r5, #0x4    ;
+    mov r0, r1  ; input = output
+            ;
+short_idct4x4llm_v6_scott_loop2          ;
+            ;
+    subs    r5, r5, #0x1    ;
+    bne short_idct4x4llm_v6_scott_loop2  ;
+            ;
+    ldmia   sp!, {r4 - r11, pc} ;
+    ENDP        ;
+            ;
+;********************************************************************************
+;********************************************************************************
+;********************************************************************************
+
+;********************************************************************************
+;*  void short_idct4x4llm_v6_dual(INT16 * input, INT16 * output, INT32 pitch)
+;*      r0  INT16 * input
+;*      r1  INT16 * output
+;*      r2  INT32 pitch
+;*  bench:
+;********************************************************************************
+
+|vp8_short_idct4x4llm_v6_dual| PROC          ;   cycles  in  out pit
+            ;
+    stmdb   sp!, {r4-r11, lr}   ; backup registers  1                   backup
+    mov r3, #0x00004E00 ;                   cos
+    orr r3, r3, #0x0000007B ; cospi8sqrt2minus1
+    mov r4, #0x00008A00 ;                       sin
+    orr r4, r4, #0x0000008C ; sinpi8sqrt2
+    mov r5, #0x2    ; i=2                           i
+loop1_dual
+    ldr r6, [r0, #(4*2)]    ; i5 | i4                               5|4
+    ldr r12, [r0, #(12*2)]  ; i13 | i12                                                     13|12
+    ldr r14, [r0, #(8*2)]   ; i9 | i8                                                               9|8
+
+    smulwt  r9, r3, r6  ; (ip[5] * cospi8sqrt2minus1) >> 16                                         5c
+    smulwb  r7, r3, r6  ; (ip[4] * cospi8sqrt2minus1) >> 16                                 4c
+    smulwt  r10, r4, r6 ; (ip[5] * sinpi8sqrt2) >> 16                                               5s
+    smulwb  r8, r4, r6  ; (ip[4] * sinpi8sqrt2) >> 16                                       4s
+    pkhbt   r7, r7, r9, lsl #16 ; 5c | 4c
+    smulwt  r11, r3, r12    ; (ip[13] * cospi8sqrt2minus1) >> 16                                                    13c
+    pkhbt   r8, r8, r10, lsl #16    ; 5s | 4s
+    uadd16  r6, r6, r7  ; 5c+5 | 4c+4
+    smulwt  r7, r4, r12 ; (ip[13] * sinpi8sqrt2) >> 16                                  13s
+    smulwb  r9, r3, r12 ; (ip[12] * cospi8sqrt2minus1) >> 16                                            12c
+    smulwb  r10, r4, r12    ; (ip[12] * sinpi8sqrt2) >> 16                                              12s
+    subs    r5, r5, #0x1    ; i--                           --
+    pkhbt   r9, r9, r11, lsl #16    ; 13c | 12c
+    ldr r11, [r0], #0x4 ; i1 | i0       ++                                          1|0
+    pkhbt   r10, r10, r7, lsl #16   ; 13s | 12s
+    uadd16  r7, r12, r9 ; 13c+13 | 12c+12
+    usub16  r7, r8, r7  ; c                                 c
+    uadd16  r6, r6, r10 ; d                             d
+    uadd16  r10, r11, r14   ; a                                             a
+    usub16  r8, r11, r14    ; b                                     b
+    uadd16  r9, r10, r6 ; a+d                                           a+d
+    usub16  r10, r10, r6    ; a-d                                               a-d
+    uadd16  r6, r8, r7  ; b+c                               b+c
+    usub16  r7, r8, r7  ; b-c                                   b-c
+    str r6, [r1, r2]    ; o5 | o4
+    add r6, r2, r2  ; pitch * 2                             p2
+    str r7, [r1, r6]    ; o9 | o8
+    add r6,  r6, r2 ; pitch * 3                             p3
+    str r10, [r1, r6]   ; o13 | o12
+    str r9, [r1], #0x4  ; o1 | o0           ++
+    bne loop1_dual  ;
+    mov r5, #0x2    ; i=2                           i
+    sub r0, r1, #8  ; reset input/output        i/o
+loop2_dual
+    ldr r6, [r0, r2]    ; i5 | i4                               5|4
+    ldr r1, [r0]    ; i1 | i0           1|0
+    ldr r12, [r0, #0x4] ; i3 | i2                                                       3|2
+    add r14, r2, #0x4   ; pitch + 2                                                             p+2
+    ldr r14, [r0, r14]  ; i7 | i6                                                               7|6
+    smulwt  r9, r3, r6  ; (ip[5] * cospi8sqrt2minus1) >> 16                                         5c
+    smulwt  r7, r3, r1  ; (ip[1] * cospi8sqrt2minus1) >> 16                                 1c
+    smulwt  r10, r4, r6 ; (ip[5] * sinpi8sqrt2) >> 16                                               5s
+    smulwt  r8, r4, r1  ; (ip[1] * sinpi8sqrt2) >> 16                                       1s
+    pkhbt   r11, r6, r1, lsl #16    ; i0 | i4                                                   0|4
+    pkhbt   r7, r9, r7, lsl #16 ; 1c | 5c
+    pkhbt   r8, r10, r8, lsl #16    ; 1s | 5s = temp1 ©                                     tc1
+    pkhtb   r1, r1, r6, asr #16 ; i1 | i5           1|5
+    uadd16  r1, r7, r1  ; 1c+1 | 5c+5 = temp2 (d)           td2
+    pkhbt   r9, r14, r12, lsl #16   ; i2 | i6                                           2|6
+    uadd16  r10, r11, r9    ; a                                             a
+    usub16  r9, r11, r9 ; b                                         b
+    pkhtb   r6, r12, r14, asr #16   ; i3 | i7                               3|7
+    subs    r5, r5, #0x1    ; i--                           --
+    smulwt  r7, r3, r6  ; (ip[3] * cospi8sqrt2minus1) >> 16                                 3c
+    smulwt  r11, r4, r6 ; (ip[3] * sinpi8sqrt2) >> 16                                                   3s
+    smulwb  r12, r3, r6 ; (ip[7] * cospi8sqrt2minus1) >> 16                                                     7c
+    smulwb  r14, r4, r6 ; (ip[7] * sinpi8sqrt2) >> 16                                                               7s
+
+    pkhbt   r7, r12, r7, lsl #16    ; 3c | 7c
+    pkhbt   r11, r14, r11, lsl #16  ; 3s | 7s = temp1 (d)                                                   td1
+    uadd16  r6, r7, r6  ; 3c+3 | 7c+7 = temp2  (c)                              tc2
+    usub16  r12, r8, r6 ; c (o1 | o5)                                                       c
+    uadd16  r6, r11, r1 ; d (o3 | o7)                               d
+    uadd16  r7, r10, r6 ; a+d                                   a+d
+    mov r8, #0x4    ; set up 4's                                        4
+    orr r8, r8, #0x40000    ;                                       4|4
+    usub16  r6, r10, r6 ; a-d                               a-d
+    uadd16  r6, r6, r8  ; a-d+4                             3|7
+    uadd16  r7, r7, r8  ; a+d+4                                 0|4
+    uadd16  r10, r9, r12    ; b+c                                               b+c
+    usub16  r1, r9, r12 ; b-c           b-c
+    uadd16  r10, r10, r8    ; b+c+4                                             1|5
+    uadd16  r1, r1, r8  ; b-c+4         2|6
+    mov r8, r10, asr #19    ; o1 >> 3
+    strh    r8, [r0, #2]    ; o1
+    mov r8, r1, asr #19 ; o2 >> 3
+    strh    r8, [r0, #4]    ; o2
+    mov r8, r6, asr #19 ; o3 >> 3
+    strh    r8, [r0, #6]    ; o3
+    mov r8, r7, asr #19 ; o0 >> 3
+    strh    r8, [r0], r2    ; o0        +p
+    sxth    r10, r10    ;
+    mov r8, r10, asr #3 ; o5 >> 3
+    strh    r8, [r0, #2]    ; o5
+    sxth    r1, r1  ;
+    mov r8, r1, asr #3  ; o6 >> 3
+    strh    r8, [r0, #4]    ; o6
+    sxth    r6, r6  ;
+    mov r8, r6, asr #3  ; o7 >> 3
+    strh    r8, [r0, #6]    ; o7
+    sxth    r7, r7  ;
+    mov r8, r7, asr #3  ; o4 >> 3
+    strh    r8, [r0], r2    ; o4        +p
+;;;;;   subs    r5, r5, #0x1    ; i--                           --
+    bne loop2_dual  ;
+            ;
+    ldmia   sp!, {r4 - r11, pc} ; replace vars, return                      restore
+    ENDP
+
+
+; sjl added 10/17/08
+;void dc_only_idct_armv6(short input_dc, short *output, int pitch)
+|vp8_dc_only_idct_armv6| PROC
+    stmdb       sp!, {r4 - r6, lr}
+
+    add         r0, r0, #0x4
+    add         r4, r1, r2                      ; output + shortpitch
+    mov         r0, r0, ASR #0x3    ;aka a1
+    add         r5, r1, r2, LSL #1              ; output + shortpitch * 2
+    pkhbt       r0, r0, r0, lsl #16             ; a1 | a1
+    add         r6, r5, r2                      ; output + shortpitch * 3
+
+    str         r0, [r1, #0]
+    str         r0, [r1, #4]
+
+    str         r0, [r4, #0]
+    str         r0, [r4, #4]
+
+    str         r0, [r5, #0]
+    str         r0, [r5, #4]
+
+    str         r0, [r6, #0]
+    str         r0, [r6, #4]
+
+
+    ldmia       sp!, {r4 - r6, pc}
+
+    ENDP  ; |vp8_dc_only_idct_armv6|
+
+    END
diff --git a/vp8/common/arm/armv6/iwalsh_v6.asm b/vp8/common/arm/armv6/iwalsh_v6.asm
new file mode 100644 (file)
index 0000000..8747568
--- /dev/null
@@ -0,0 +1,151 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+    EXPORT |vp8_short_inv_walsh4x4_armv6|
+    EXPORT |vp8_short_inv_walsh4x4_1_armv6|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+;short vp8_short_inv_walsh4x4_armv6(short *input, short *output)
+|vp8_short_inv_walsh4x4_armv6| PROC
+
+    stmdb       sp!, {r4 - r11, lr}
+
+    ldr         r2, [r0], #4         ; [1  |  0]
+    ldr         r3, [r0], #4         ; [3  |  2]
+    ldr         r4, [r0], #4         ; [5  |  4]
+    ldr         r5, [r0], #4         ; [7  |  6]
+    ldr         r6, [r0], #4         ; [9  |  8]
+    ldr         r7, [r0], #4         ; [11 | 10]
+    ldr         r8, [r0], #4         ; [13 | 12]
+    ldr         r9, [r0]             ; [15 | 14]
+
+    qadd16      r10, r2, r8          ; a1 [1+13  |  0+12]
+    qadd16      r11, r4, r6          ; b1 [5+9   |  4+8]
+    qsub16      r12, r4, r6          ; c1 [5-9   |  4-8]
+    qsub16      lr, r2, r8           ; d1 [1-13  |  0-12]
+
+    qadd16      r2, r10, r11         ; a1 + b1 [1  |  0]
+    qadd16      r4, r12, lr          ; c1 + d1 [5  |  4]
+    qsub16      r6, r10, r11         ; a1 - b1 [9  |  8]
+    qsub16      r8, lr, r12          ; d1 - c1 [13 | 12]
+
+    qadd16      r10, r3, r9          ; a1 [3+15  |  2+14]
+    qadd16      r11, r5, r7          ; b1 [7+11  |  6+10]
+    qsub16      r12, r5, r7          ; c1 [7-11  |  6-10]
+    qsub16      lr, r3, r9           ; d1 [3-15  |  2-14]
+
+    qadd16      r3, r10, r11         ; a1 + b1 [3  |  2]
+    qadd16      r5, r12, lr          ; c1 + d1 [7  |  6]
+    qsub16      r7, r10, r11         ; a1 - b1 [11 | 10]
+    qsub16      r9, lr, r12          ; d1 - c1 [15 | 14]
+
+    ; first transform complete
+
+    qsubaddx    r10, r2, r3          ; [c1|a1] [1-2   |   0+3]
+    qaddsubx    r11, r2, r3          ; [b1|d1] [1+2   |   0-3]
+    qsubaddx    r12, r4, r5          ; [c1|a1] [5-6   |   4+7]
+    qaddsubx    lr, r4, r5           ; [b1|d1] [5+6   |   4-7]
+
+    qaddsubx    r2, r10, r11         ; [b2|c2] [c1+d1 | a1-b1]
+    qaddsubx    r3, r11, r10         ; [a2|d2] [b1+a1 | d1-c1]
+    ldr         r10, c0x00030003
+    qaddsubx    r4, r12, lr          ; [b2|c2] [c1+d1 | a1-b1]
+    qaddsubx    r5, lr, r12          ; [a2|d2] [b1+a1 | d1-c1]
+
+    qadd16      r2, r2, r10          ; [b2+3|c2+3]
+    qadd16      r3, r3, r10          ; [a2+3|d2+3]
+    qadd16      r4, r4, r10          ; [b2+3|c2+3]
+    qadd16      r5, r5, r10          ; [a2+3|d2+3]
+
+    asr         r12, r2, #3          ; [1  |  x]
+    pkhtb       r12, r12, r3, asr #19; [1  |  0]
+    lsl         lr, r3, #16          ; [~3 |  x]
+    lsl         r2, r2, #16          ; [~2 |  x]
+    asr         lr, lr, #3           ; [3  |  x]
+    pkhtb       lr, lr, r2, asr #19  ; [3  |  2]
+
+    asr         r2, r4, #3           ; [5  |  x]
+    pkhtb       r2, r2, r5, asr #19  ; [5  |  4]
+    lsl         r3, r5, #16          ; [~7 |  x]
+    lsl         r4, r4, #16          ; [~6 |  x]
+    asr         r3, r3, #3           ; [7  |  x]
+    pkhtb       r3, r3, r4, asr #19  ; [7  |  6]
+
+    str         r12, [r1], #4
+    str         lr, [r1], #4
+    str         r2, [r1], #4
+    str         r3, [r1], #4
+
+    qsubaddx    r2, r6, r7           ; [c1|a1] [9-10  |  8+11]
+    qaddsubx    r3, r6, r7           ; [b1|d1] [9+10  |  8-11]
+    qsubaddx    r4, r8, r9           ; [c1|a1] [13-14 | 12+15]
+    qaddsubx    r5, r8, r9           ; [b1|d1] [13+14 | 12-15]
+
+    qaddsubx    r6, r2, r3           ; [b2|c2] [c1+d1 | a1-b1]
+    qaddsubx    r7, r3, r2           ; [a2|d2] [b1+a1 | d1-c1]
+    qaddsubx    r8, r4, r5           ; [b2|c2] [c1+d1 | a1-b1]
+    qaddsubx    r9, r5, r4           ; [a2|d2] [b1+a1 | d1-c1]
+
+    qadd16      r6, r6, r10          ; [b2+3|c2+3]
+    qadd16      r7, r7, r10          ; [a2+3|d2+3]
+    qadd16      r8, r8, r10          ; [b2+3|c2+3]
+    qadd16      r9, r9, r10          ; [a2+3|d2+3]
+
+    asr         r2, r6, #3           ; [9  |  x]
+    pkhtb       r2, r2, r7, asr #19  ; [9  |  8]
+    lsl         r3, r7, #16          ; [~11|  x]
+    lsl         r4, r6, #16          ; [~10|  x]
+    asr         r3, r3, #3           ; [11 |  x]
+    pkhtb       r3, r3, r4, asr #19  ; [11 | 10]
+
+    asr         r4, r8, #3           ; [13 |  x]
+    pkhtb       r4, r4, r9, asr #19  ; [13 | 12]
+    lsl         r5, r9, #16          ; [~15|  x]
+    lsl         r6, r8, #16          ; [~14|  x]
+    asr         r5, r5, #3           ; [15 |  x]
+    pkhtb       r5, r5, r6, asr #19  ; [15 | 14]
+
+    str         r2, [r1], #4
+    str         r3, [r1], #4
+    str         r4, [r1], #4
+    str         r5, [r1]
+
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_short_inv_walsh4x4_armv6|
+
+
+;short vp8_short_inv_walsh4x4_1_armv6(short *input, short *output)
+|vp8_short_inv_walsh4x4_1_armv6| PROC
+
+    ldrsh       r2, [r0]             ; [0]
+    add         r2, r2, #3           ; [0] + 3
+    asr         r2, r2, #3           ; a1 ([0]+3) >> 3
+    lsl         r2, r2, #16          ; [a1 |  x]
+    orr         r2, r2, r2, lsr #16  ; [a1 | a1]
+
+    str         r2, [r1], #4
+    str         r2, [r1], #4
+    str         r2, [r1], #4
+    str         r2, [r1], #4
+    str         r2, [r1], #4
+    str         r2, [r1], #4
+    str         r2, [r1], #4
+    str         r2, [r1]
+
+    bx          lr
+    ENDP        ; |vp8_short_inv_walsh4x4_1_armv6|
+
+; Constant Pool
+c0x00030003 DCD 0x00030003
+    END
diff --git a/vp8/common/arm/armv6/loopfilter_v6.asm b/vp8/common/arm/armv6/loopfilter_v6.asm
new file mode 100644 (file)
index 0000000..c2b02dc
--- /dev/null
@@ -0,0 +1,1263 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8_loop_filter_horizontal_edge_armv6|
+    EXPORT |vp8_mbloop_filter_horizontal_edge_armv6|
+    EXPORT |vp8_loop_filter_vertical_edge_armv6|
+    EXPORT |vp8_mbloop_filter_vertical_edge_armv6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+    MACRO
+    TRANSPOSE_MATRIX $a0, $a1, $a2, $a3, $b0, $b1, $b2, $b3
+    ; input: $a0, $a1, $a2, $a3; output: $b0, $b1, $b2, $b3
+    ; a0: 03 02 01 00
+    ; a1: 13 12 11 10
+    ; a2: 23 22 21 20
+    ; a3: 33 32 31 30
+    ;     b3 b2 b1 b0
+
+    uxtb16      $b1, $a1                    ; xx 12 xx 10
+    uxtb16      $b0, $a0                    ; xx 02 xx 00
+    uxtb16      $b3, $a3                    ; xx 32 xx 30
+    uxtb16      $b2, $a2                    ; xx 22 xx 20
+    orr         $b1, $b0, $b1, lsl #8       ; 12 02 10 00
+    orr         $b3, $b2, $b3, lsl #8       ; 32 22 30 20
+
+    uxtb16      $a1, $a1, ror #8            ; xx 13 xx 11
+    uxtb16      $a3, $a3, ror #8            ; xx 33 xx 31
+    uxtb16      $a0, $a0, ror #8            ; xx 03 xx 01
+    uxtb16      $a2, $a2, ror #8            ; xx 23 xx 21
+    orr         $a0, $a0, $a1, lsl #8       ; 13 03 11 01
+    orr         $a2, $a2, $a3, lsl #8       ; 33 23 31 21
+
+    pkhtb       $b2, $b3, $b1, asr #16      ; 32 22 12 02   -- p1
+    pkhbt       $b0, $b1, $b3, lsl #16      ; 30 20 10 00   -- p3
+
+    pkhtb       $b3, $a2, $a0, asr #16      ; 33 23 13 03   -- p0
+    pkhbt       $b1, $a0, $a2, lsl #16      ; 31 21 11 01   -- p2
+    MEND
+
+
+src         RN  r0
+pstep       RN  r1
+count       RN  r5
+
+;r0     unsigned char *src_ptr,
+;r1     int src_pixel_step,
+;r2     const char *flimit,
+;r3     const char *limit,
+;stack  const char *thresh,
+;stack  int  count
+
+;Note: All 16 elements in flimit are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+|vp8_loop_filter_horizontal_edge_armv6| PROC
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+    stmdb       sp!, {r4 - r11, lr}
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+    ldr         count, [sp, #40]            ; count for 8-in-parallel
+    ldr         r6, [sp, #36]               ; load thresh address
+    sub         sp, sp, #16                 ; create temp buffer
+
+    ldr         r9, [src], pstep            ; p3
+    ldr         r4, [r2], #4                ; flimit
+    ldr         r10, [src], pstep           ; p2
+    ldr         r2, [r3], #4                ; limit
+    ldr         r11, [src], pstep           ; p1
+    uadd8       r4, r4, r4                  ; flimit * 2
+    ldr         r3, [r6], #4                ; thresh
+    mov         count, count, lsl #1        ; 4-in-parallel
+    uadd8       r4, r4, r2                  ; flimit * 2 + limit
+
+|Hnext8|
+    ; vp8_filter_mask() function
+    ; calculate breakout conditions
+    ldr         r12, [src], pstep           ; p0
+
+    uqsub8      r6, r9, r10                 ; p3 - p2
+    uqsub8      r7, r10, r9                 ; p2 - p3
+    uqsub8      r8, r10, r11                ; p2 - p1
+    uqsub8      r10, r11, r10               ; p1 - p2
+
+    orr         r6, r6, r7                  ; abs (p3-p2)
+    orr         r8, r8, r10                 ; abs (p2-p1)
+    uqsub8      lr, r6, r2                  ; compare to limit. lr: vp8_filter_mask
+    uqsub8      r8, r8, r2                  ; compare to limit
+    uqsub8      r6, r11, r12                ; p1 - p0
+    orr         lr, lr, r8
+    uqsub8      r7, r12, r11                ; p0 - p1
+    ldr         r9, [src], pstep            ; q0
+    ldr         r10, [src], pstep           ; q1
+    orr         r6, r6, r7                  ; abs (p1-p0)
+    uqsub8      r7, r6, r2                  ; compare to limit
+    uqsub8      r8, r6, r3                  ; compare to thresh  -- save r8 for later
+    orr         lr, lr, r7
+
+    uqsub8      r6, r11, r10                ; p1 - q1
+    uqsub8      r7, r10, r11                ; q1 - p1
+    uqsub8      r11, r12, r9                ; p0 - q0
+    uqsub8      r12, r9, r12                ; q0 - p0
+    orr         r6, r6, r7                  ; abs (p1-q1)
+    ldr         r7, c0x7F7F7F7F
+    orr         r12, r11, r12               ; abs (p0-q0)
+    ldr         r11, [src], pstep           ; q2
+    uqadd8      r12, r12, r12               ; abs (p0-q0) * 2
+    and         r6, r7, r6, lsr #1          ; abs (p1-q1) / 2
+    uqsub8      r7, r9, r10                 ; q0 - q1
+    uqadd8      r12, r12, r6                ; abs (p0-q0)*2 + abs (p1-q1)/2
+    uqsub8      r6, r10, r9                 ; q1 - q0
+    uqsub8      r12, r12, r4                ; compare to flimit
+    uqsub8      r9, r11, r10                ; q2 - q1
+
+    orr         lr, lr, r12
+
+    ldr         r12, [src], pstep           ; q3
+    uqsub8      r10, r10, r11               ; q1 - q2
+    orr         r6, r7, r6                  ; abs (q1-q0)
+    orr         r10, r9, r10                ; abs (q2-q1)
+    uqsub8      r7, r6, r2                  ; compare to limit
+    uqsub8      r10, r10, r2                ; compare to limit
+    uqsub8      r6, r6, r3                  ; compare to thresh -- save r6 for later
+    orr         lr, lr, r7
+    orr         lr, lr, r10
+
+    uqsub8      r10, r12, r11               ; q3 - q2
+    uqsub8      r9, r11, r12                ; q2 - q3
+
+    mvn         r11, #0                     ; r11 == -1
+
+    orr         r10, r10, r9                ; abs (q3-q2)
+    uqsub8      r10, r10, r2                ; compare to limit
+
+    mov         r12, #0
+    orr         lr, lr, r10
+    sub         src, src, pstep, lsl #2
+
+    usub8       lr, r12, lr                 ; use usub8 instead of ssub8
+    sel         lr, r11, r12                ; filter mask: lr
+
+    cmp         lr, #0
+    beq         hskip_filter                 ; skip filtering
+
+    sub         src, src, pstep, lsl #1     ; move src pointer down by 6 lines
+
+    ;vp8_hevmask() function
+    ;calculate high edge variance
+    orr         r10, r6, r8                 ; calculate vp8_hevmask
+
+    ldr         r7, [src], pstep            ; p1
+
+    usub8       r10, r12, r10               ; use usub8 instead of ssub8
+    sel         r6, r12, r11                ; obtain vp8_hevmask: r6
+
+    ;vp8_filter() function
+    ldr         r8, [src], pstep            ; p0
+    ldr         r12, c0x80808080
+    ldr         r9, [src], pstep            ; q0
+    ldr         r10, [src], pstep           ; q1
+
+    eor         r7, r7, r12                 ; p1 offset to convert to a signed value
+    eor         r8, r8, r12                 ; p0 offset to convert to a signed value
+    eor         r9, r9, r12                 ; q0 offset to convert to a signed value
+    eor         r10, r10, r12               ; q1 offset to convert to a signed value
+
+    str         r9, [sp]                    ; store qs0 temporarily
+    str         r8, [sp, #4]                ; store ps0 temporarily
+    str         r10, [sp, #8]               ; store qs1 temporarily
+    str         r7, [sp, #12]               ; store ps1 temporarily
+
+    qsub8       r7, r7, r10                 ; vp8_signed_char_clamp(ps1-qs1)
+    qsub8       r8, r9, r8                  ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+
+    and         r7, r7, r6                  ; vp8_filter (r7) &= hev
+
+    qadd8       r7, r7, r8
+    ldr         r9, c0x03030303             ; r9 = 3 --modified for vp8
+
+    qadd8       r7, r7, r8
+    ldr         r10, c0x04040404
+
+    qadd8       r7, r7, r8
+    and         r7, r7, lr                  ; vp8_filter &= mask;
+
+    ;modify code for vp8 -- Filter1 = vp8_filter (r7)
+    qadd8       r8 , r7 , r9                ; Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
+    qadd8       r7 , r7 , r10               ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
+
+    mov         r9, #0
+    shadd8      r8 , r8 , r9                ; Filter2 >>= 3
+    shadd8      r7 , r7 , r9                ; vp8_filter >>= 3
+    shadd8      r8 , r8 , r9
+    shadd8      r7 , r7 , r9
+    shadd8      lr , r8 , r9                ; lr: Filter2
+    shadd8      r7 , r7 , r9                ; r7: filter
+
+    ;usub8      lr, r8, r10                 ; s = (s==4)*-1
+    ;sel        lr, r11, r9
+    ;usub8      r8, r10, r8
+    ;sel        r8, r11, r9
+    ;and        r8, r8, lr                  ; -1 for each element that equals 4
+
+    ;calculate output
+    ;qadd8      lr, r8, r7                  ; u = vp8_signed_char_clamp(s + vp8_filter)
+
+    ldr         r8, [sp]                    ; load qs0
+    ldr         r9, [sp, #4]                ; load ps0
+
+    ldr         r10, c0x01010101
+
+    qsub8       r8 ,r8, r7                  ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
+    qadd8       r9, r9, lr                  ; u = vp8_signed_char_clamp(ps0 + Filter2)
+
+    ;end of modification for vp8
+
+    mov         lr, #0
+    sadd8       r7, r7 , r10                ; vp8_filter += 1
+    shadd8      r7, r7, lr                  ; vp8_filter >>= 1
+
+    ldr         r11, [sp, #12]              ; load ps1
+    ldr         r10, [sp, #8]               ; load qs1
+
+    bic         r7, r7, r6                  ; vp8_filter &= ~hev
+    sub         src, src, pstep, lsl #2
+
+    qadd8       r11, r11, r7                ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
+    qsub8       r10, r10,r7                 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
+
+    eor         r11, r11, r12               ; *op1 = u^0x80
+    str         r11, [src], pstep           ; store op1
+    eor         r9, r9, r12                 ; *op0 = u^0x80
+    str         r9, [src], pstep            ; store op0 result
+    eor         r8, r8, r12                 ; *oq0 = u^0x80
+    str         r8, [src], pstep            ; store oq0 result
+    eor         r10, r10, r12               ; *oq1 = u^0x80
+    str         r10, [src], pstep           ; store oq1
+
+    sub         src, src, pstep, lsl #1
+
+|hskip_filter|
+    add         src, src, #4
+    sub         src, src, pstep, lsl #2
+
+    subs        count, count, #1
+
+    ;pld            [src]
+    ;pld            [src, pstep]
+    ;pld            [src, pstep, lsl #1]
+    ;pld            [src, pstep, lsl #2]
+    ;pld            [src, pstep, lsl #3]
+
+    ldrne       r9, [src], pstep            ; p3
+    ldrne       r10, [src], pstep           ; p2
+    ldrne       r11, [src], pstep           ; p1
+
+    bne         Hnext8
+
+    add         sp, sp, #16
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_loop_filter_horizontal_edge_armv6|
+
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+|vp8_mbloop_filter_horizontal_edge_armv6| PROC
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+    stmdb       sp!, {r4 - r11, lr}
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+    ldr         count, [sp, #40]            ; count for 8-in-parallel
+    ldr         r6, [sp, #36]               ; load thresh address
+    sub         sp, sp, #16                 ; create temp buffer
+
+    ldr         r9, [src], pstep            ; p3
+    ldr         r4, [r2], #4                ; flimit
+    ldr         r10, [src], pstep           ; p2
+    ldr         r2, [r3], #4                ; limit
+    ldr         r11, [src], pstep           ; p1
+    uadd8       r4, r4, r4                  ; flimit * 2
+    ldr         r3, [r6], #4                ; thresh
+    mov         count, count, lsl #1        ; 4-in-parallel
+    uadd8       r4, r4, r2                  ; flimit * 2 + limit
+
+|MBHnext8|
+
+    ; vp8_filter_mask() function
+    ; calculate breakout conditions
+    ldr         r12, [src], pstep           ; p0
+
+    uqsub8      r6, r9, r10                 ; p3 - p2
+    uqsub8      r7, r10, r9                 ; p2 - p3
+    uqsub8      r8, r10, r11                ; p2 - p1
+    uqsub8      r10, r11, r10               ; p1 - p2
+
+    orr         r6, r6, r7                  ; abs (p3-p2)
+    orr         r8, r8, r10                 ; abs (p2-p1)
+    uqsub8      lr, r6, r2                  ; compare to limit. lr: vp8_filter_mask
+    uqsub8      r8, r8, r2                  ; compare to limit
+
+    uqsub8      r6, r11, r12                ; p1 - p0
+    orr         lr, lr, r8
+    uqsub8      r7, r12, r11                ; p0 - p1
+    ldr         r9, [src], pstep            ; q0
+    ldr         r10, [src], pstep           ; q1
+    orr         r6, r6, r7                  ; abs (p1-p0)
+    uqsub8      r7, r6, r2                  ; compare to limit
+    uqsub8      r8, r6, r3                  ; compare to thresh  -- save r8 for later
+    orr         lr, lr, r7
+
+    uqsub8      r6, r11, r10                ; p1 - q1
+    uqsub8      r7, r10, r11                ; q1 - p1
+    uqsub8      r11, r12, r9                ; p0 - q0
+    uqsub8      r12, r9, r12                ; q0 - p0
+    orr         r6, r6, r7                  ; abs (p1-q1)
+    ldr         r7, c0x7F7F7F7F
+    orr         r12, r11, r12               ; abs (p0-q0)
+    ldr         r11, [src], pstep           ; q2
+    uqadd8      r12, r12, r12               ; abs (p0-q0) * 2
+    and         r6, r7, r6, lsr #1          ; abs (p1-q1) / 2
+    uqsub8      r7, r9, r10                 ; q0 - q1
+    uqadd8      r12, r12, r6                ; abs (p0-q0)*2 + abs (p1-q1)/2
+    uqsub8      r6, r10, r9                 ; q1 - q0
+    uqsub8      r12, r12, r4                ; compare to flimit
+    uqsub8      r9, r11, r10                ; q2 - q1
+
+    orr         lr, lr, r12
+
+    ldr         r12, [src], pstep           ; q3
+
+    uqsub8      r10, r10, r11               ; q1 - q2
+    orr         r6, r7, r6                  ; abs (q1-q0)
+    orr         r10, r9, r10                ; abs (q2-q1)
+    uqsub8      r7, r6, r2                  ; compare to limit
+    uqsub8      r10, r10, r2                ; compare to limit
+    uqsub8      r6, r6, r3                  ; compare to thresh -- save r6 for later
+    orr         lr, lr, r7
+    orr         lr, lr, r10
+
+    uqsub8      r10, r12, r11               ; q3 - q2
+    uqsub8      r9, r11, r12                ; q2 - q3
+
+    mvn         r11, #0                     ; r11 == -1
+
+    orr         r10, r10, r9                ; abs (q3-q2)
+    uqsub8      r10, r10, r2                ; compare to limit
+
+    mov         r12, #0
+
+    orr         lr, lr, r10
+
+    usub8       lr, r12, lr                 ; use usub8 instead of ssub8
+    sel         lr, r11, r12                ; filter mask: lr
+
+    cmp         lr, #0
+    beq         mbhskip_filter               ; skip filtering
+
+    ;vp8_hevmask() function
+    ;calculate high edge variance
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 6 lines
+    sub         src, src, pstep, lsl #1
+
+    orr         r10, r6, r8
+    ldr         r7, [src], pstep            ; p1
+
+    usub8       r10, r12, r10
+    sel         r6, r12, r11                ; hev mask: r6
+
+    ;vp8_mbfilter() function
+    ;p2, q2 are only needed at the end. Don't need to load them in now.
+    ldr         r8, [src], pstep            ; p0
+    ldr         r12, c0x80808080
+    ldr         r9, [src], pstep            ; q0
+    ldr         r10, [src]                  ; q1
+
+    eor         r7, r7, r12                 ; ps1
+    eor         r8, r8, r12                 ; ps0
+    eor         r9, r9, r12                 ; qs0
+    eor         r10, r10, r12               ; qs1
+
+    qsub8       r12, r9, r8                 ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    str         r7, [sp, #12]               ; store ps1 temporarily
+    qsub8       r7, r7, r10                 ; vp8_signed_char_clamp(ps1-qs1)
+    str         r10, [sp, #8]               ; store qs1 temporarily
+    qadd8       r7, r7, r12
+    str         r9, [sp]                    ; store qs0 temporarily
+    qadd8       r7, r7, r12
+    str         r8, [sp, #4]                ; store ps0 temporarily
+    qadd8       r7, r7, r12                 ; vp8_filter: r7
+
+    ldr         r10, c0x03030303            ; r10 = 3 --modified for vp8
+    ldr         r9, c0x04040404
+
+    and         r7, r7, lr                  ; vp8_filter &= mask (lr is free)
+
+    mov         r12, r7                     ; Filter2: r12
+    and         r12, r12, r6                ; Filter2 &= hev
+
+    ;modify code for vp8
+    ;save bottom 3 bits so that we round one side +4 and the other +3
+    qadd8       r8 , r12 , r9               ; Filter1 (r8) = vp8_signed_char_clamp(Filter2+4)
+    qadd8       r12 , r12 , r10             ; Filter2 (r12) = vp8_signed_char_clamp(Filter2+3)
+
+    mov         r10, #0
+    shadd8      r8 , r8 , r10               ; Filter1 >>= 3
+    shadd8      r12 , r12 , r10             ; Filter2 >>= 3
+    shadd8      r8 , r8 , r10
+    shadd8      r12 , r12 , r10
+    shadd8      r8 , r8 , r10               ; r8: Filter1
+    shadd8      r12 , r12 , r10             ; r12: Filter2
+
+    ldr         r9, [sp]                    ; load qs0
+    ldr         r11, [sp, #4]               ; load ps0
+
+    qsub8       r9 , r9, r8                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
+    qadd8       r11, r11, r12               ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
+
+    ;save bottom 3 bits so that we round one side +4 and the other +3
+    ;and            r8, r12, r10                ; s = Filter2 & 7 (s: r8)
+    ;qadd8      r12 , r12 , r9              ; Filter2 = vp8_signed_char_clamp(Filter2+4)
+    ;mov            r10, #0
+    ;shadd8     r12 , r12 , r10             ; Filter2 >>= 3
+    ;usub8      lr, r8, r9                  ; s = (s==4)*-1
+    ;sel            lr, r11, r10
+    ;shadd8     r12 , r12 , r10
+    ;usub8      r8, r9, r8
+    ;sel            r8, r11, r10
+    ;ldr            r9, [sp]                    ; load qs0
+    ;ldr            r11, [sp, #4]               ; load ps0
+    ;shadd8     r12 , r12 , r10
+    ;and            r8, r8, lr                  ; -1 for each element that equals 4
+    ;qadd8      r10, r8, r12                ; u = vp8_signed_char_clamp(s + Filter2)
+    ;qsub8      r9 , r9, r12                ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
+    ;qadd8      r11, r11, r10               ; ps0 = vp8_signed_char_clamp(ps0 + u)
+
+    ;end of modification for vp8
+
+    bic         r12, r7, r6                 ; vp8_filter &= ~hev    ( r6 is free)
+    ;mov        r12, r7
+
+    ;roughly 3/7th difference across boundary
+    mov         lr, #0x1b                   ; 27
+    mov         r7, #0x3f                   ; 63
+
+    sxtb16      r6, r12
+    sxtb16      r10, r12, ror #8
+    smlabb      r8, r6, lr, r7
+    smlatb      r6, r6, lr, r7
+    smlabb      r7, r10, lr, r7
+    smultb      r10, r10, lr
+    ssat        r8, #8, r8, asr #7
+    ssat        r6, #8, r6, asr #7
+    add         r10, r10, #63
+    ssat        r7, #8, r7, asr #7
+    ssat        r10, #8, r10, asr #7
+
+    ldr         lr, c0x80808080
+
+    pkhbt       r6, r8, r6, lsl #16
+    pkhbt       r10, r7, r10, lsl #16
+    uxtb16      r6, r6
+    uxtb16      r10, r10
+
+    sub         src, src, pstep
+
+    orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
+
+    qsub8       r8, r9, r10                 ; s = vp8_signed_char_clamp(qs0 - u)
+    qadd8       r10, r11, r10               ; s = vp8_signed_char_clamp(ps0 + u)
+    eor         r8, r8, lr                  ; *oq0 = s^0x80
+    str         r8, [src]                   ; store *oq0
+    sub         src, src, pstep
+    eor         r10, r10, lr                ; *op0 = s^0x80
+    str         r10, [src]                  ; store *op0
+
+    ;roughly 2/7th difference across boundary
+    mov         lr, #0x12                   ; 18
+    mov         r7, #0x3f                   ; 63
+
+    sxtb16      r6, r12
+    sxtb16      r10, r12, ror #8
+    smlabb      r8, r6, lr, r7
+    smlatb      r6, r6, lr, r7
+    smlabb      r9, r10, lr, r7
+    smlatb      r10, r10, lr, r7
+    ssat        r8, #8, r8, asr #7
+    ssat        r6, #8, r6, asr #7
+    ssat        r9, #8, r9, asr #7
+    ssat        r10, #8, r10, asr #7
+
+    ldr         lr, c0x80808080
+
+    pkhbt       r6, r8, r6, lsl #16
+    pkhbt       r10, r9, r10, lsl #16
+
+    ldr         r9, [sp, #8]                ; load qs1
+    ldr         r11, [sp, #12]              ; load ps1
+
+    uxtb16      r6, r6
+    uxtb16      r10, r10
+
+    sub         src, src, pstep
+
+    orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
+
+    qadd8       r11, r11, r10               ; s = vp8_signed_char_clamp(ps1 + u)
+    qsub8       r8, r9, r10                 ; s = vp8_signed_char_clamp(qs1 - u)
+    eor         r11, r11, lr                ; *op1 = s^0x80
+    str         r11, [src], pstep           ; store *op1
+    eor         r8, r8, lr                  ; *oq1 = s^0x80
+    add         src, src, pstep, lsl #1
+
+    mov         r7, #0x3f                   ; 63
+
+    str         r8, [src], pstep            ; store *oq1
+
+    ;roughly 1/7th difference across boundary
+    mov         lr, #0x9                    ; 9
+    ldr         r9, [src]                   ; load q2
+
+    sxtb16      r6, r12
+    sxtb16      r10, r12, ror #8
+    smlabb      r8, r6, lr, r7
+    smlatb      r6, r6, lr, r7
+    smlabb      r12, r10, lr, r7
+    smlatb      r10, r10, lr, r7
+    ssat        r8, #8, r8, asr #7
+    ssat        r6, #8, r6, asr #7
+    ssat        r12, #8, r12, asr #7
+    ssat        r10, #8, r10, asr #7
+
+    sub         src, src, pstep, lsl #2
+
+    pkhbt       r6, r8, r6, lsl #16
+    pkhbt       r10, r12, r10, lsl #16
+
+    sub         src, src, pstep
+    ldr         lr, c0x80808080
+
+    ldr         r11, [src]                  ; load p2
+
+    uxtb16      r6, r6
+    uxtb16      r10, r10
+
+    eor         r9, r9, lr
+    eor         r11, r11, lr
+
+    orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
+
+    qadd8       r8, r11, r10                ; s = vp8_signed_char_clamp(ps2 + u)
+    qsub8       r10, r9, r10                ; s = vp8_signed_char_clamp(qs2 - u)
+    eor         r8, r8, lr                  ; *op2 = s^0x80
+    str         r8, [src], pstep, lsl #2    ; store *op2
+    add         src, src, pstep
+    eor         r10, r10, lr                ; *oq2 = s^0x80
+    str         r10, [src], pstep, lsl #1   ; store *oq2
+
+|mbhskip_filter|
+    add         src, src, #4
+    sub         src, src, pstep, lsl #3
+    subs        count, count, #1
+
+    ldrne       r9, [src], pstep            ; p3
+    ldrne       r10, [src], pstep           ; p2
+    ldrne       r11, [src], pstep           ; p1
+
+    bne         MBHnext8
+
+    add         sp, sp, #16
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_mbloop_filter_horizontal_edge_armv6|
+
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+|vp8_loop_filter_vertical_edge_armv6| PROC
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+    stmdb       sp!, {r4 - r11, lr}
+
+    sub         src, src, #4                ; move src pointer down by 4
+    ldr         count, [sp, #40]            ; count for 8-in-parallel
+    ldr         r12, [sp, #36]              ; load thresh address
+    sub         sp, sp, #16                 ; create temp buffer
+
+    ldr         r6, [src], pstep            ; load source data
+    ldr         r4, [r2], #4                ; flimit
+    ldr         r7, [src], pstep
+    ldr         r2, [r3], #4                ; limit
+    ldr         r8, [src], pstep
+    uadd8       r4, r4, r4                  ; flimit * 2
+    ldr         r3, [r12], #4               ; thresh
+    ldr         lr, [src], pstep
+    mov         count, count, lsl #1        ; 4-in-parallel
+    uadd8       r4, r4, r2                  ; flimit * 2 + limit
+
+|Vnext8|
+
+    ; vp8_filter_mask() function
+    ; calculate breakout conditions
+    ; transpose the source data for 4-in-parallel operation
+    TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
+
+    uqsub8      r7, r9, r10                 ; p3 - p2
+    uqsub8      r8, r10, r9                 ; p2 - p3
+    uqsub8      r9, r10, r11                ; p2 - p1
+    uqsub8      r10, r11, r10               ; p1 - p2
+    orr         r7, r7, r8                  ; abs (p3-p2)
+    orr         r10, r9, r10                ; abs (p2-p1)
+    uqsub8      lr, r7, r2                  ; compare to limit. lr: vp8_filter_mask
+    uqsub8      r10, r10, r2                ; compare to limit
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+
+    orr         lr, lr, r10
+
+    uqsub8      r6, r11, r12                ; p1 - p0
+    uqsub8      r7, r12, r11                ; p0 - p1
+    add         src, src, #4                ; move src pointer up by 4
+    orr         r6, r6, r7                  ; abs (p1-p0)
+    str         r11, [sp, #12]              ; save p1
+    uqsub8      r10, r6, r2                 ; compare to limit
+    uqsub8      r11, r6, r3                 ; compare to thresh
+    orr         lr, lr, r10
+
+    ; transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now
+    ; transpose the source data for 4-in-parallel operation
+    ldr         r6, [src], pstep            ; load source data
+    str         r11, [sp]                   ; push r11 to stack
+    ldr         r7, [src], pstep
+    str         r12, [sp, #4]               ; save current reg before load q0 - q3 data
+    ldr         r8, [src], pstep
+    str         lr, [sp, #8]
+    ldr         lr, [src], pstep
+
+    TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
+
+    ldr         lr, [sp, #8]                ; load back (f)limit accumulator
+
+    uqsub8      r6, r12, r11                ; q3 - q2
+    uqsub8      r7, r11, r12                ; q2 - q3
+    uqsub8      r12, r11, r10               ; q2 - q1
+    uqsub8      r11, r10, r11               ; q1 - q2
+    orr         r6, r6, r7                  ; abs (q3-q2)
+    orr         r7, r12, r11                ; abs (q2-q1)
+    uqsub8      r6, r6, r2                  ; compare to limit
+    uqsub8      r7, r7, r2                  ; compare to limit
+    ldr         r11, [sp, #4]               ; load back p0
+    ldr         r12, [sp, #12]              ; load back p1
+    orr         lr, lr, r6
+    orr         lr, lr, r7
+
+    uqsub8      r6, r11, r9                 ; p0 - q0
+    uqsub8      r7, r9, r11                 ; q0 - p0
+    uqsub8      r8, r12, r10                ; p1 - q1
+    uqsub8      r11, r10, r12               ; q1 - p1
+    orr         r6, r6, r7                  ; abs (p0-q0)
+    ldr         r7, c0x7F7F7F7F
+    orr         r8, r8, r11                 ; abs (p1-q1)
+    uqadd8      r6, r6, r6                  ; abs (p0-q0) * 2
+    and         r8, r7, r8, lsr #1          ; abs (p1-q1) / 2
+    uqsub8      r11, r10, r9                ; q1 - q0
+    uqadd8      r6, r8, r6                  ; abs (p0-q0)*2 + abs (p1-q1)/2
+    uqsub8      r12, r9, r10                ; q0 - q1
+    uqsub8      r6, r6, r4                  ; compare to flimit
+
+    orr         r9, r11, r12                ; abs (q1-q0)
+    uqsub8      r8, r9, r2                  ; compare to limit
+    uqsub8      r10, r9, r3                 ; compare to thresh
+    orr         lr, lr, r6
+    orr         lr, lr, r8
+
+    mvn         r11, #0                     ; r11 == -1
+    mov         r12, #0
+
+    usub8       lr, r12, lr
+    ldr         r9, [sp]                    ; load the compared result
+    sel         lr, r11, r12                ; filter mask: lr
+
+    cmp         lr, #0
+    beq         vskip_filter                 ; skip filtering
+
+    ;vp8_hevmask() function
+    ;calculate high edge variance
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+
+    orr         r9, r9, r10
+
+    ldrh        r7, [src, #-2]
+    ldrh        r8, [src], pstep
+
+    usub8       r9, r12, r9
+    sel         r6, r12, r11                ; hev mask: r6
+
+    ;vp8_filter() function
+    ; load soure data to r6, r11, r12, lr
+    ldrh        r9, [src, #-2]
+    ldrh        r10, [src], pstep
+
+    pkhbt       r12, r7, r8, lsl #16
+
+    ldrh        r7, [src, #-2]
+    ldrh        r8, [src], pstep
+
+    pkhbt       r11, r9, r10, lsl #16
+
+    ldrh        r9, [src, #-2]
+    ldrh        r10, [src], pstep
+
+    ; Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
+    str         r6, [sp]
+    str         lr, [sp, #4]
+
+    pkhbt       r6, r7, r8, lsl #16
+    pkhbt       lr, r9, r10, lsl #16
+
+    ;transpose r12, r11, r6, lr to r7, r8, r9, r10
+    TRANSPOSE_MATRIX r12, r11, r6, lr, r7, r8, r9, r10
+
+    ;load back hev_mask r6 and filter_mask lr
+    ldr         r12, c0x80808080
+    ldr         r6, [sp]
+    ldr         lr, [sp, #4]
+
+    eor         r7, r7, r12                 ; p1 offset to convert to a signed value
+    eor         r8, r8, r12                 ; p0 offset to convert to a signed value
+    eor         r9, r9, r12                 ; q0 offset to convert to a signed value
+    eor         r10, r10, r12               ; q1 offset to convert to a signed value
+
+    str         r9, [sp]                    ; store qs0 temporarily
+    str         r8, [sp, #4]                ; store ps0 temporarily
+    str         r10, [sp, #8]               ; store qs1 temporarily
+    str         r7, [sp, #12]               ; store ps1 temporarily
+
+    qsub8       r7, r7, r10                 ; vp8_signed_char_clamp(ps1-qs1)
+    qsub8       r8, r9, r8                  ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+
+    and         r7, r7, r6                  ;  vp8_filter (r7) &= hev (r7 : filter)
+
+    qadd8       r7, r7, r8
+    ldr         r9, c0x03030303             ; r9 = 3 --modified for vp8
+
+    qadd8       r7, r7, r8
+    ldr         r10, c0x04040404
+
+    qadd8       r7, r7, r8
+    ;mvn         r11, #0                     ; r11 == -1
+
+    and         r7, r7, lr                  ; vp8_filter &= mask
+
+    ;modify code for vp8 -- Filter1 = vp8_filter (r7)
+    qadd8       r8 , r7 , r9                ; Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
+    qadd8       r7 , r7 , r10               ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
+
+    mov         r9, #0
+    shadd8      r8 , r8 , r9                ; Filter2 >>= 3
+    shadd8      r7 , r7 , r9                ; vp8_filter >>= 3
+    shadd8      r8 , r8 , r9
+    shadd8      r7 , r7 , r9
+    shadd8      lr , r8 , r9                ; lr: filter2
+    shadd8      r7 , r7 , r9                ; r7: filter
+
+    ;usub8      lr, r8, r10                 ; s = (s==4)*-1
+    ;sel            lr, r11, r9
+    ;usub8      r8, r10, r8
+    ;sel            r8, r11, r9
+    ;and            r8, r8, lr                  ; -1 for each element that equals 4 -- r8: s
+
+    ;calculate output
+    ;qadd8      lr, r8, r7                  ; u = vp8_signed_char_clamp(s + vp8_filter)
+
+    ldr         r8, [sp]                    ; load qs0
+    ldr         r9, [sp, #4]                ; load ps0
+
+    ldr         r10, c0x01010101
+
+    qsub8       r8, r8, r7                  ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
+    qadd8       r9, r9, lr                  ; u = vp8_signed_char_clamp(ps0 + Filter2)
+    ;end of modification for vp8
+
+    eor         r8, r8, r12
+    eor         r9, r9, r12
+
+    mov         lr, #0
+
+    sadd8       r7, r7, r10
+    shadd8      r7, r7, lr
+
+    ldr         r10, [sp, #8]               ; load qs1
+    ldr         r11, [sp, #12]              ; load ps1
+
+    bic         r7, r7, r6                  ; r7: vp8_filter
+
+    qsub8       r10 , r10, r7               ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
+    qadd8       r11, r11, r7                ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
+    eor         r10, r10, r12
+    eor         r11, r11, r12
+
+    sub         src, src, pstep, lsl #2
+
+    ;we can use TRANSPOSE_MATRIX macro to transpose output - input: q1, q0, p0, p1
+    ;output is b0, b1, b2, b3
+    ;b0: 03 02 01 00
+    ;b1: 13 12 11 10
+    ;b2: 23 22 21 20
+    ;b3: 33 32 31 30
+    ;    p1 p0 q0 q1
+    ;   (a3 a2 a1 a0)
+    TRANSPOSE_MATRIX r11, r9, r8, r10, r6, r7, r12, lr
+
+    strh        r6, [src, #-2]              ; store the result
+    mov         r6, r6, lsr #16
+    strh        r6, [src], pstep
+
+    strh        r7, [src, #-2]
+    mov         r7, r7, lsr #16
+    strh        r7, [src], pstep
+
+    strh        r12, [src, #-2]
+    mov         r12, r12, lsr #16
+    strh        r12, [src], pstep
+
+    strh        lr, [src, #-2]
+    mov         lr, lr, lsr #16
+    strh        lr, [src], pstep
+
+|vskip_filter|
+    sub         src, src, #4
+    subs        count, count, #1
+
+    ldrne       r6, [src], pstep            ; load source data
+    ldrne       r7, [src], pstep
+    ldrne       r8, [src], pstep
+    ldrne       lr, [src], pstep
+
+    bne         Vnext8
+
+    add         sp, sp, #16
+
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_loop_filter_vertical_edge_armv6|
+
+
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+|vp8_mbloop_filter_vertical_edge_armv6| PROC
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+    stmdb       sp!, {r4 - r11, lr}
+
+    sub         src, src, #4                ; move src pointer down by 4
+    ldr         count, [sp, #40]            ; count for 8-in-parallel
+    ldr         r12, [sp, #36]              ; load thresh address
+    sub         sp, sp, #16                 ; create temp buffer
+
+    ldr         r6, [src], pstep            ; load source data
+    ldr         r4, [r2], #4                ; flimit
+    ldr         r7, [src], pstep
+    ldr         r2, [r3], #4                ; limit
+    ldr         r8, [src], pstep
+    uadd8       r4, r4, r4                  ; flimit * 2
+    ldr         r3, [r12], #4               ; thresh
+    ldr         lr, [src], pstep
+    mov         count, count, lsl #1        ; 4-in-parallel
+    uadd8       r4, r4, r2                  ; flimit * 2 + limit
+
+|MBVnext8|
+    ; vp8_filter_mask() function
+    ; calculate breakout conditions
+    ; transpose the source data for 4-in-parallel operation
+    TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
+
+    uqsub8      r7, r9, r10                 ; p3 - p2
+    uqsub8      r8, r10, r9                 ; p2 - p3
+    uqsub8      r9, r10, r11                ; p2 - p1
+    uqsub8      r10, r11, r10               ; p1 - p2
+    orr         r7, r7, r8                  ; abs (p3-p2)
+    orr         r10, r9, r10                ; abs (p2-p1)
+    uqsub8      lr, r7, r2                  ; compare to limit. lr: vp8_filter_mask
+    uqsub8      r10, r10, r2                ; compare to limit
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+
+    orr         lr, lr, r10
+
+    uqsub8      r6, r11, r12                ; p1 - p0
+    uqsub8      r7, r12, r11                ; p0 - p1
+    add         src, src, #4                ; move src pointer up by 4
+    orr         r6, r6, r7                  ; abs (p1-p0)
+    str         r11, [sp, #12]              ; save p1
+    uqsub8      r10, r6, r2                 ; compare to limit
+    uqsub8      r11, r6, r3                 ; compare to thresh
+    orr         lr, lr, r10
+
+    ; transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now
+    ; transpose the source data for 4-in-parallel operation
+    ldr         r6, [src], pstep            ; load source data
+    str         r11, [sp]                   ; push r11 to stack
+    ldr         r7, [src], pstep
+    str         r12, [sp, #4]               ; save current reg before load q0 - q3 data
+    ldr         r8, [src], pstep
+    str         lr, [sp, #8]
+    ldr         lr, [src], pstep
+
+    TRANSPOSE_MATRIX r6, r7, r8, lr, r9, r10, r11, r12
+
+    ldr         lr, [sp, #8]                ; load back (f)limit accumulator
+
+    uqsub8      r6, r12, r11                ; q3 - q2
+    uqsub8      r7, r11, r12                ; q2 - q3
+    uqsub8      r12, r11, r10               ; q2 - q1
+    uqsub8      r11, r10, r11               ; q1 - q2
+    orr         r6, r6, r7                  ; abs (q3-q2)
+    orr         r7, r12, r11                ; abs (q2-q1)
+    uqsub8      r6, r6, r2                  ; compare to limit
+    uqsub8      r7, r7, r2                  ; compare to limit
+    ldr         r11, [sp, #4]               ; load back p0
+    ldr         r12, [sp, #12]              ; load back p1
+    orr         lr, lr, r6
+    orr         lr, lr, r7
+
+    uqsub8      r6, r11, r9                 ; p0 - q0
+    uqsub8      r7, r9, r11                 ; q0 - p0
+    uqsub8      r8, r12, r10                ; p1 - q1
+    uqsub8      r11, r10, r12               ; q1 - p1
+    orr         r6, r6, r7                  ; abs (p0-q0)
+    ldr         r7, c0x7F7F7F7F
+    orr         r8, r8, r11                 ; abs (p1-q1)
+    uqadd8      r6, r6, r6                  ; abs (p0-q0) * 2
+    and         r8, r7, r8, lsr #1          ; abs (p1-q1) / 2
+    uqsub8      r11, r10, r9                ; q1 - q0
+    uqadd8      r6, r8, r6                  ; abs (p0-q0)*2 + abs (p1-q1)/2
+    uqsub8      r12, r9, r10                ; q0 - q1
+    uqsub8      r6, r6, r4                  ; compare to flimit
+
+    orr         r9, r11, r12                ; abs (q1-q0)
+    uqsub8      r8, r9, r2                  ; compare to limit
+    uqsub8      r10, r9, r3                 ; compare to thresh
+    orr         lr, lr, r6
+    orr         lr, lr, r8
+
+    mvn         r11, #0                     ; r11 == -1
+    mov         r12, #0
+
+    usub8       lr, r12, lr
+    ldr         r9, [sp]                    ; load the compared result
+    sel         lr, r11, r12                ; filter mask: lr
+
+    cmp         lr, #0
+    beq         mbvskip_filter               ; skip filtering
+
+
+    ;vp8_hevmask() function
+    ;calculate high edge variance
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+
+    orr         r9, r9, r10
+
+    ldrh        r7, [src, #-2]
+    ldrh        r8, [src], pstep
+
+    usub8       r9, r12, r9
+    sel         r6, r12, r11                ; hev mask: r6
+
+
+    ; vp8_mbfilter() function
+    ; p2, q2 are only needed at the end. Don't need to load them in now.
+    ; Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first
+    ; load soure data to r6, r11, r12, lr
+    ldrh        r9, [src, #-2]
+    ldrh        r10, [src], pstep
+
+    pkhbt       r12, r7, r8, lsl #16
+
+    ldrh        r7, [src, #-2]
+    ldrh        r8, [src], pstep
+
+    pkhbt       r11, r9, r10, lsl #16
+
+    ldrh        r9, [src, #-2]
+    ldrh        r10, [src], pstep
+
+    str         r6, [sp]                    ; save r6
+    str         lr, [sp, #4]                ; save lr
+
+    pkhbt       r6, r7, r8, lsl #16
+    pkhbt       lr, r9, r10, lsl #16
+
+    ;transpose r12, r11, r6, lr to p1, p0, q0, q1
+    TRANSPOSE_MATRIX r12, r11, r6, lr, r7, r8, r9, r10
+
+    ;load back hev_mask r6 and filter_mask lr
+    ldr         r12, c0x80808080
+    ldr         r6, [sp]
+    ldr         lr, [sp, #4]
+
+    eor         r7, r7, r12                 ; ps1
+    eor         r8, r8, r12                 ; ps0
+    eor         r9, r9, r12                 ; qs0
+    eor         r10, r10, r12               ; qs1
+
+    qsub8       r12, r9, r8                 ; vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    str         r7, [sp, #12]               ; store ps1 temporarily
+    qsub8       r7, r7, r10                 ; vp8_signed_char_clamp(ps1-qs1)
+    str         r10, [sp, #8]               ; store qs1 temporarily
+    qadd8       r7, r7, r12
+    str         r9, [sp]                    ; store qs0 temporarily
+    qadd8       r7, r7, r12
+    str         r8, [sp, #4]                ; store ps0 temporarily
+    qadd8       r7, r7, r12                 ; vp8_filter: r7
+
+    ldr         r10, c0x03030303            ; r10 = 3 --modified for vp8
+    ldr         r9, c0x04040404
+    ;mvn         r11, #0                     ; r11 == -1
+
+    and         r7, r7, lr                  ; vp8_filter &= mask (lr is free)
+
+    mov         r12, r7                     ; Filter2: r12
+    and         r12, r12, r6                ; Filter2 &= hev
+
+    ;modify code for vp8
+    ;save bottom 3 bits so that we round one side +4 and the other +3
+    qadd8       r8 , r12 , r9               ; Filter1 (r8) = vp8_signed_char_clamp(Filter2+4)
+    qadd8       r12 , r12 , r10             ; Filter2 (r12) = vp8_signed_char_clamp(Filter2+3)
+
+    mov         r10, #0
+    shadd8      r8 , r8 , r10               ; Filter1 >>= 3
+    shadd8      r12 , r12 , r10             ; Filter2 >>= 3
+    shadd8      r8 , r8 , r10
+    shadd8      r12 , r12 , r10
+    shadd8      r8 , r8 , r10               ; r8: Filter1
+    shadd8      r12 , r12 , r10             ; r12: Filter2
+
+    ldr         r9, [sp]                    ; load qs0
+    ldr         r11, [sp, #4]               ; load ps0
+
+    qsub8       r9 , r9, r8                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
+    qadd8       r11, r11, r12               ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
+
+    ;save bottom 3 bits so that we round one side +4 and the other +3
+    ;and            r8, r12, r10                ; s = Filter2 & 7 (s: r8)
+    ;qadd8      r12 , r12 , r9              ; Filter2 = vp8_signed_char_clamp(Filter2+4)
+    ;mov            r10, #0
+    ;shadd8     r12 , r12 , r10             ; Filter2 >>= 3
+    ;usub8      lr, r8, r9                  ; s = (s==4)*-1
+    ;sel            lr, r11, r10
+    ;shadd8     r12 , r12 , r10
+    ;usub8      r8, r9, r8
+    ;sel            r8, r11, r10
+    ;ldr            r9, [sp]                    ; load qs0
+    ;ldr            r11, [sp, #4]               ; load ps0
+    ;shadd8     r12 , r12 , r10
+    ;and            r8, r8, lr                  ; -1 for each element that equals 4
+    ;qadd8      r10, r8, r12                ; u = vp8_signed_char_clamp(s + Filter2)
+    ;qsub8      r9 , r9, r12                ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
+    ;qadd8      r11, r11, r10               ; ps0 = vp8_signed_char_clamp(ps0 + u)
+
+    ;end of modification for vp8
+
+    bic         r12, r7, r6                 ;vp8_filter &= ~hev    ( r6 is free)
+    ;mov            r12, r7
+
+    ;roughly 3/7th difference across boundary
+    mov         lr, #0x1b                   ; 27
+    mov         r7, #0x3f                   ; 63
+
+    sxtb16      r6, r12
+    sxtb16      r10, r12, ror #8
+    smlabb      r8, r6, lr, r7
+    smlatb      r6, r6, lr, r7
+    smlabb      r7, r10, lr, r7
+    smultb      r10, r10, lr
+    ssat        r8, #8, r8, asr #7
+    ssat        r6, #8, r6, asr #7
+    add         r10, r10, #63
+    ssat        r7, #8, r7, asr #7
+    ssat        r10, #8, r10, asr #7
+
+    ldr         lr, c0x80808080
+
+    pkhbt       r6, r8, r6, lsl #16
+    pkhbt       r10, r7, r10, lsl #16
+    uxtb16      r6, r6
+    uxtb16      r10, r10
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+
+    orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
+
+    qsub8       r8, r9, r10                 ; s = vp8_signed_char_clamp(qs0 - u)
+    qadd8       r10, r11, r10               ; s = vp8_signed_char_clamp(ps0 + u)
+    eor         r8, r8, lr                  ; *oq0 = s^0x80
+    eor         r10, r10, lr                ; *op0 = s^0x80
+
+    strb        r10, [src, #-1]             ; store op0 result
+    strb        r8, [src], pstep            ; store oq0 result
+    mov         r10, r10, lsr #8
+    mov         r8, r8, lsr #8
+    strb        r10, [src, #-1]
+    strb        r8, [src], pstep
+    mov         r10, r10, lsr #8
+    mov         r8, r8, lsr #8
+    strb        r10, [src, #-1]
+    strb        r8, [src], pstep
+    mov         r10, r10, lsr #8
+    mov         r8, r8, lsr #8
+    strb        r10, [src, #-1]
+    strb        r8, [src], pstep
+
+    ;roughly 2/7th difference across boundary
+    mov         lr, #0x12                   ; 18
+    mov         r7, #0x3f                   ; 63
+
+    sxtb16      r6, r12
+    sxtb16      r10, r12, ror #8
+    smlabb      r8, r6, lr, r7
+    smlatb      r6, r6, lr, r7
+    smlabb      r9, r10, lr, r7
+    smlatb      r10, r10, lr, r7
+    ssat        r8, #8, r8, asr #7
+    ssat        r6, #8, r6, asr #7
+    ssat        r9, #8, r9, asr #7
+    ssat        r10, #8, r10, asr #7
+
+    sub         src, src, pstep, lsl #2     ; move src pointer down by 4 lines
+
+    pkhbt       r6, r8, r6, lsl #16
+    pkhbt       r10, r9, r10, lsl #16
+
+    ldr         r9, [sp, #8]                ; load qs1
+    ldr         r11, [sp, #12]              ; load ps1
+    ldr         lr, c0x80808080
+
+    uxtb16      r6, r6
+    uxtb16      r10, r10
+
+    add         src, src, #2
+
+    orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
+
+    qsub8       r8, r9, r10                 ; s = vp8_signed_char_clamp(qs1 - u)
+    qadd8       r10, r11, r10               ; s = vp8_signed_char_clamp(ps1 + u)
+    eor         r8, r8, lr                  ; *oq1 = s^0x80
+    eor         r10, r10, lr                ; *op1 = s^0x80
+
+    ldrb        r11, [src, #-5]             ; load p2 for 1/7th difference across boundary
+    strb        r10, [src, #-4]             ; store op1
+    strb        r8, [src, #-1]              ; store oq1
+    ldrb        r9, [src], pstep            ; load q2 for 1/7th difference across boundary
+
+    mov         r10, r10, lsr #8
+    mov         r8, r8, lsr #8
+
+    ldrb        r6, [src, #-5]
+    strb        r10, [src, #-4]
+    strb        r8, [src, #-1]
+    ldrb        r7, [src], pstep
+
+    mov         r10, r10, lsr #8
+    mov         r8, r8, lsr #8
+    orr         r11, r11, r6, lsl #8
+    orr         r9, r9, r7, lsl #8
+
+    ldrb        r6, [src, #-5]
+    strb        r10, [src, #-4]
+    strb        r8, [src, #-1]
+    ldrb        r7, [src], pstep
+
+    mov         r10, r10, lsr #8
+    mov         r8, r8, lsr #8
+    orr         r11, r11, r6, lsl #16
+    orr         r9, r9, r7, lsl #16
+
+    ldrb        r6, [src, #-5]
+    strb        r10, [src, #-4]
+    strb        r8, [src, #-1]
+    ldrb        r7, [src], pstep
+    orr         r11, r11, r6, lsl #24
+    orr         r9, r9, r7, lsl #24
+
+    ;roughly 1/7th difference across boundary
+    eor         r9, r9, lr
+    eor         r11, r11, lr
+
+    mov         lr, #0x9                    ; 9
+    mov         r7, #0x3f                   ; 63
+
+    sxtb16      r6, r12
+    sxtb16      r10, r12, ror #8
+    smlabb      r8, r6, lr, r7
+    smlatb      r6, r6, lr, r7
+    smlabb      r12, r10, lr, r7
+    smlatb      r10, r10, lr, r7
+    ssat        r8, #8, r8, asr #7
+    ssat        r6, #8, r6, asr #7
+    ssat        r12, #8, r12, asr #7
+    ssat        r10, #8, r10, asr #7
+
+    sub         src, src, pstep, lsl #2
+
+    pkhbt       r6, r8, r6, lsl #16
+    pkhbt       r10, r12, r10, lsl #16
+
+    uxtb16      r6, r6
+    uxtb16      r10, r10
+
+    ldr         lr, c0x80808080
+
+    orr         r10, r6, r10, lsl #8        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
+
+    qadd8       r8, r11, r10                ; s = vp8_signed_char_clamp(ps2 + u)
+    qsub8       r10, r9, r10                ; s = vp8_signed_char_clamp(qs2 - u)
+    eor         r8, r8, lr                  ; *op2 = s^0x80
+    eor         r10, r10, lr                ; *oq2 = s^0x80
+
+    strb        r8, [src, #-5]              ; store *op2
+    strb        r10, [src], pstep           ; store *oq2
+    mov         r8, r8, lsr #8
+    mov         r10, r10, lsr #8
+    strb        r8, [src, #-5]
+    strb        r10, [src], pstep
+    mov         r8, r8, lsr #8
+    mov         r10, r10, lsr #8
+    strb        r8, [src, #-5]
+    strb        r10, [src], pstep
+    mov         r8, r8, lsr #8
+    mov         r10, r10, lsr #8
+    strb        r8, [src, #-5]
+    strb        r10, [src], pstep
+
+    ;adjust src pointer for next loop
+    sub         src, src, #2
+
+|mbvskip_filter|
+    sub         src, src, #4
+    subs        count, count, #1
+
+    ldrne       r6, [src], pstep            ; load source data
+    ldrne       r7, [src], pstep
+    ldrne       r8, [src], pstep
+    ldrne       lr, [src], pstep
+
+    bne         MBVnext8
+
+    add         sp, sp, #16
+
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_mbloop_filter_vertical_edge_armv6|
+
+; Constant Pool
+c0x80808080 DCD     0x80808080
+c0x03030303 DCD     0x03030303
+c0x04040404 DCD     0x04040404
+c0x01010101 DCD     0x01010101
+c0x7F7F7F7F DCD     0x7F7F7F7F
+
+    END
diff --git a/vp8/common/arm/armv6/recon_v6.asm b/vp8/common/arm/armv6/recon_v6.asm
new file mode 100644 (file)
index 0000000..085ff80
--- /dev/null
@@ -0,0 +1,280 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_recon_b_armv6|
+    EXPORT  |vp8_recon2b_armv6|
+    EXPORT  |vp8_recon4b_armv6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+prd     RN  r0
+dif     RN  r1
+dst     RN  r2
+stride      RN  r3
+
+;void recon_b(unsigned char *pred_ptr, short *diff_ptr, unsigned char *dst_ptr, int stride)
+; R0 char* pred_ptr
+; R1 short * dif_ptr
+; R2 char * dst_ptr
+; R3 int stride
+
+; Description:
+; Loop through the block adding the Pred and Diff together.  Clamp and then
+; store back into the Dst.
+
+; Restrictions :
+; all buffers are expected to be 4 byte aligned coming in and
+; going out.
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+;
+;
+;
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_recon_b_armv6| PROC
+    stmdb   sp!, {r4 - r9, lr}
+
+    ;0, 1, 2, 3
+    ldr     r4, [prd], #16          ; 3 | 2 | 1 | 0
+    ldr     r6, [dif, #0]           ;     1 |     0
+    ldr     r7, [dif, #4]           ;     3 |     2
+
+    pkhbt   r8, r6, r7, lsl #16     ;     2 |     0
+    pkhtb   r9, r7, r6, asr #16     ;     3 |     1
+
+    uxtab16 r8, r8, r4              ;     2 |     0  +  3 | 2 | 2 | 0
+    uxtab16 r9, r9, r4, ror #8      ;     3 |     1  +  0 | 3 | 2 | 1
+
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    add     dif, dif, #32
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst], stride
+
+    ;0, 1, 2, 3
+    ldr     r4, [prd], #16          ; 3 | 2 | 1 | 0
+;;  ldr     r6, [dif, #8]           ;     1 |     0
+;;  ldr     r7, [dif, #12]          ;     3 |     2
+    ldr     r6, [dif, #0]           ;     1 |     0
+    ldr     r7, [dif, #4]           ;     3 |     2
+
+    pkhbt   r8, r6, r7, lsl #16     ;     2 |     0
+    pkhtb   r9, r7, r6, asr #16     ;     3 |     1
+
+    uxtab16 r8, r8, r4              ;     2 |     0  +  3 | 2 | 2 | 0
+    uxtab16 r9, r9, r4, ror #8      ;     3 |     1  +  0 | 3 | 2 | 1
+
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    add     dif, dif, #32
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst], stride
+
+    ;0, 1, 2, 3
+    ldr     r4, [prd], #16          ; 3 | 2 | 1 | 0
+;;  ldr     r6, [dif, #16]          ;     1 |     0
+;;  ldr     r7, [dif, #20]          ;     3 |     2
+    ldr     r6, [dif, #0]           ;     1 |     0
+    ldr     r7, [dif, #4]           ;     3 |     2
+
+    pkhbt   r8, r6, r7, lsl #16     ;     2 |     0
+    pkhtb   r9, r7, r6, asr #16     ;     3 |     1
+
+    uxtab16 r8, r8, r4              ;     2 |     0  +  3 | 2 | 2 | 0
+    uxtab16 r9, r9, r4, ror #8      ;     3 |     1  +  0 | 3 | 2 | 1
+
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    add     dif, dif, #32
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst], stride
+
+    ;0, 1, 2, 3
+    ldr     r4, [prd], #16          ; 3 | 2 | 1 | 0
+;;  ldr     r6, [dif, #24]          ;     1 |     0
+;;  ldr     r7, [dif, #28]          ;     3 |     2
+    ldr     r6, [dif, #0]           ;     1 |     0
+    ldr     r7, [dif, #4]           ;     3 |     2
+
+    pkhbt   r8, r6, r7, lsl #16     ;     2 |     0
+    pkhtb   r9, r7, r6, asr #16     ;     3 |     1
+
+    uxtab16 r8, r8, r4              ;     2 |     0  +  3 | 2 | 2 | 0
+    uxtab16 r9, r9, r4, ror #8      ;     3 |     1  +  0 | 3 | 2 | 1
+
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst], stride
+
+    ldmia   sp!, {r4 - r9, pc}
+
+    ENDP    ; |recon_b|
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+;
+;
+;
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+; R0 char  *pred_ptr
+; R1 short *dif_ptr
+; R2 char  *dst_ptr
+; R3 int stride
+|vp8_recon4b_armv6| PROC
+    stmdb   sp!, {r4 - r9, lr}
+
+    mov     lr, #4
+
+recon4b_loop
+    ;0, 1, 2, 3
+    ldr     r4, [prd], #4           ; 3 | 2 | 1 | 0
+    ldr     r6, [dif, #0]           ;     1 |     0
+    ldr     r7, [dif, #4]           ;     3 |     2
+
+    pkhbt   r8, r6, r7, lsl #16     ;     2 |     0
+    pkhtb   r9, r7, r6, asr #16     ;     3 |     1
+
+    uxtab16 r8, r8, r4              ;     2 |     0  +  3 | 2 | 2 | 0
+    uxtab16 r9, r9, r4, ror #8      ;     3 |     1  +  0 | 3 | 2 | 1
+
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst]
+
+    ;4, 5, 6, 7
+    ldr     r4, [prd], #4
+;;  ldr     r6, [dif, #32]
+;;  ldr     r7, [dif, #36]
+    ldr     r6, [dif, #8]
+    ldr     r7, [dif, #12]
+
+    pkhbt   r8, r6, r7, lsl #16
+    pkhtb   r9, r7, r6, asr #16
+
+    uxtab16 r8, r8, r4
+    uxtab16 r9, r9, r4, ror #8
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst, #4]
+
+    ;8, 9, 10, 11
+    ldr     r4, [prd], #4
+;;  ldr     r6, [dif, #64]
+;;  ldr     r7, [dif, #68]
+    ldr     r6, [dif, #16]
+    ldr     r7, [dif, #20]
+
+    pkhbt   r8, r6, r7, lsl #16
+    pkhtb   r9, r7, r6, asr #16
+
+    uxtab16 r8, r8, r4
+    uxtab16 r9, r9, r4, ror #8
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst, #8]
+
+    ;12, 13, 14, 15
+    ldr     r4, [prd], #4
+;;  ldr     r6, [dif, #96]
+;;  ldr     r7, [dif, #100]
+    ldr     r6, [dif, #24]
+    ldr     r7, [dif, #28]
+
+    pkhbt   r8, r6, r7, lsl #16
+    pkhtb   r9, r7, r6, asr #16
+
+    uxtab16 r8, r8, r4
+    uxtab16 r9, r9, r4, ror #8
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst, #12]
+
+    add     dst, dst, stride
+;;  add     dif, dif, #8
+    add     dif, dif, #32
+
+    subs    lr, lr, #1
+    bne     recon4b_loop
+
+    ldmia   sp!, {r4 - r9, pc}
+
+    ENDP    ; |Recon4B|
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+;
+;
+;
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+; R0 char  *pred_ptr
+; R1 short *dif_ptr
+; R2 char  *dst_ptr
+; R3 int stride
+|vp8_recon2b_armv6| PROC
+    stmdb   sp!, {r4 - r9, lr}
+
+    mov     lr, #4
+
+recon2b_loop
+    ;0, 1, 2, 3
+    ldr     r4, [prd], #4
+    ldr     r6, [dif, #0]
+    ldr     r7, [dif, #4]
+
+    pkhbt   r8, r6, r7, lsl #16
+    pkhtb   r9, r7, r6, asr #16
+
+    uxtab16 r8, r8, r4
+    uxtab16 r9, r9, r4, ror #8
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst]
+
+    ;4, 5, 6, 7
+    ldr     r4, [prd], #4
+;;  ldr     r6, [dif, #32]
+;;  ldr     r7, [dif, #36]
+    ldr     r6, [dif, #8]
+    ldr     r7, [dif, #12]
+
+    pkhbt   r8, r6, r7, lsl #16
+    pkhtb   r9, r7, r6, asr #16
+
+    uxtab16 r8, r8, r4
+    uxtab16 r9, r9, r4, ror #8
+    usat16  r8, #8, r8
+    usat16  r9, #8, r9
+    orr     r8, r8, r9, lsl #8
+
+    str     r8, [dst, #4]
+
+    add     dst, dst, stride
+;;  add     dif, dif, #8
+    add     dif, dif, #16
+
+    subs    lr, lr, #1
+    bne     recon2b_loop
+
+    ldmia   sp!, {r4 - r9, pc}
+
+    ENDP    ; |Recon2B|
+
+    END
diff --git a/vp8/common/arm/armv6/simpleloopfilter_v6.asm b/vp8/common/arm/armv6/simpleloopfilter_v6.asm
new file mode 100644 (file)
index 0000000..15c6c7d
--- /dev/null
@@ -0,0 +1,321 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8_loop_filter_simple_horizontal_edge_armv6|
+    EXPORT |vp8_loop_filter_simple_vertical_edge_armv6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+    MACRO
+    TRANSPOSE_MATRIX $a0, $a1, $a2, $a3, $b0, $b1, $b2, $b3
+    ; input: $a0, $a1, $a2, $a3; output: $b0, $b1, $b2, $b3
+    ; a0: 03 02 01 00
+    ; a1: 13 12 11 10
+    ; a2: 23 22 21 20
+    ; a3: 33 32 31 30
+    ;     b3 b2 b1 b0
+
+    uxtb16      $b1, $a1                    ; xx 12 xx 10
+    uxtb16      $b0, $a0                    ; xx 02 xx 00
+    uxtb16      $b3, $a3                    ; xx 32 xx 30
+    uxtb16      $b2, $a2                    ; xx 22 xx 20
+    orr         $b1, $b0, $b1, lsl #8       ; 12 02 10 00
+    orr         $b3, $b2, $b3, lsl #8       ; 32 22 30 20
+
+    uxtb16      $a1, $a1, ror #8            ; xx 13 xx 11
+    uxtb16      $a3, $a3, ror #8            ; xx 33 xx 31
+    uxtb16      $a0, $a0, ror #8            ; xx 03 xx 01
+    uxtb16      $a2, $a2, ror #8            ; xx 23 xx 21
+    orr         $a0, $a0, $a1, lsl #8       ; 13 03 11 01
+    orr         $a2, $a2, $a3, lsl #8       ; 33 23 31 21
+
+    pkhtb       $b2, $b3, $b1, asr #16      ; 32 22 12 02   -- p1
+    pkhbt       $b0, $b1, $b3, lsl #16      ; 30 20 10 00   -- p3
+
+    pkhtb       $b3, $a2, $a0, asr #16      ; 33 23 13 03   -- p0
+    pkhbt       $b1, $a0, $a2, lsl #16      ; 31 21 11 01   -- p2
+    MEND
+
+
+src         RN  r0
+pstep       RN  r1
+
+;r0     unsigned char *src_ptr,
+;r1     int src_pixel_step,
+;r2     const char *flimit,
+;r3     const char *limit,
+;stack  const char *thresh,
+;stack  int  count
+
+;Note: All 16 elements in flimit are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+|vp8_loop_filter_simple_horizontal_edge_armv6| PROC
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+    stmdb       sp!, {r4 - r11, lr}
+
+    sub         src, src, pstep, lsl #1     ; move src pointer down by 2 lines
+
+    ldr         r12, [r3], #4               ; limit
+    ldr         r3, [src], pstep            ; p1
+
+    ldr         r9, [sp, #36]               ; count for 8-in-parallel
+    ldr         r4, [src], pstep            ; p0
+
+    ldr         r7, [r2], #4                ; flimit
+    ldr         r5, [src], pstep            ; q0
+    ldr         r2, c0x80808080
+
+    ldr         r6, [src]                   ; q1
+
+    uadd8       r7, r7, r7                  ; flimit * 2
+    mov         r9, r9, lsl #1              ; 4-in-parallel
+    uadd8       r12, r7, r12                ; flimit * 2 + limit
+
+|simple_hnext8|
+    ; vp8_simple_filter_mask() function
+
+    uqsub8      r7, r3, r6                  ; p1 - q1
+    uqsub8      r8, r6, r3                  ; q1 - p1
+    uqsub8      r10, r4, r5                 ; p0 - q0
+    uqsub8      r11, r5, r4                 ; q0 - p0
+    orr         r8, r8, r7                  ; abs(p1 - q1)
+    ldr         lr, c0x7F7F7F7F             ; 01111111 mask
+    orr         r10, r10, r11               ; abs(p0 - q0)
+    and         r8, lr, r8, lsr #1          ; abs(p1 - q1) / 2
+    uqadd8      r10, r10, r10               ; abs(p0 - q0) * 2
+    mvn         lr, #0                      ; r10 == -1
+    uqadd8      r10, r10, r8                ; abs(p0 - q0)*2 + abs(p1 - q1)/2
+    ; STALL waiting on r10 :(
+    uqsub8      r10, r10, r12               ; compare to flimit
+    mov         r8, #0
+
+    usub8       r10, r8, r10                ; use usub8 instead of ssub8
+    ; STALL (maybe?) when are flags set? :/
+    sel         r10, lr, r8                 ; filter mask: lr
+
+    cmp         r10, #0
+    beq         simple_hskip_filter         ; skip filtering
+
+    ;vp8_simple_filter() function
+
+    eor         r3, r3, r2                  ; p1 offset to convert to a signed value
+    eor         r6, r6, r2                  ; q1 offset to convert to a signed value
+    eor         r4, r4, r2                  ; p0 offset to convert to a signed value
+    eor         r5, r5, r2                  ; q0 offset to convert to a signed value
+
+    qsub8       r3, r3, r6                  ; vp8_filter (r3) = vp8_signed_char_clamp(p1-q1)
+    qsub8       r6, r5, r4                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( q0 - p0))
+
+    qadd8       r3, r3, r6
+    ldr         r8, c0x03030303             ; r8 = 3
+
+    qadd8       r3, r3, r6
+    ldr         r7, c0x04040404
+
+    qadd8       r3, r3, r6
+    and         r3, r3, lr                  ; vp8_filter &= mask;
+
+    ;save bottom 3 bits so that we round one side +4 and the other +3
+    qadd8       r8 , r3 , r8                ; Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
+    qadd8       r3 , r3 , r7                ; Filter1 (r3) = vp8_signed_char_clamp(vp8_filter+4)
+
+    mov         r7, #0
+    shadd8      r8 , r8 , r7                ; Filter2 >>= 3
+    shadd8      r3 , r3 , r7                ; Filter1 >>= 3
+    shadd8      r8 , r8 , r7
+    shadd8      r3 , r3 , r7
+    shadd8      r8 , r8 , r7                ; r8: Filter2
+    shadd8      r3 , r3 , r7                ; r7: filter1
+
+    ;calculate output
+    sub         src, src, pstep, lsl #1
+
+    qadd8       r4, r4, r8                  ; u = vp8_signed_char_clamp(p0 + Filter2)
+    qsub8       r5 ,r5, r3                  ; u = vp8_signed_char_clamp(q0 - Filter1)
+    eor         r4, r4, r2                  ; *op0 = u^0x80
+    str         r4, [src], pstep            ; store op0 result
+    eor         r5, r5, r2                  ; *oq0 = u^0x80
+    str         r5, [src], pstep            ; store oq0 result
+
+|simple_hskip_filter|
+    add         src, src, #4
+    sub         src, src, pstep
+    sub         src, src, pstep, lsl #1
+
+    subs        r9, r9, #1
+
+    ;pld            [src]
+    ;pld            [src, pstep]
+    ;pld            [src, pstep, lsl #1]
+
+    ldrne           r3, [src], pstep            ; p1
+    ldrne           r4, [src], pstep            ; p0
+    ldrne           r5, [src], pstep            ; q0
+    ldrne           r6, [src]                   ; q1
+
+    bne         simple_hnext8
+
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_loop_filter_simple_horizontal_edge_armv6|
+
+
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+|vp8_loop_filter_simple_vertical_edge_armv6| PROC
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+    stmdb       sp!, {r4 - r11, lr}
+
+    ldr         r12, [r2], #4               ; r12: flimit
+    ldr         r2, c0x80808080
+    ldr         r7, [r3], #4                ; limit
+
+    ; load soure data to r7, r8, r9, r10
+    ldrh        r3, [src, #-2]
+    ldrh        r4, [src], pstep
+    uadd8       r12, r12, r12               ; flimit * 2
+
+    ldrh        r5, [src, #-2]
+    ldrh        r6, [src], pstep
+    uadd8       r12, r12, r7                ; flimit * 2 + limit
+
+    pkhbt       r7, r3, r4, lsl #16
+
+    ldrh        r3, [src, #-2]
+    ldrh        r4, [src], pstep
+    ldr         r11, [sp, #40]              ; count (r11) for 8-in-parallel
+
+    pkhbt       r8, r5, r6, lsl #16
+
+    ldrh        r5, [src, #-2]
+    ldrh        r6, [src], pstep
+    mov         r11, r11, lsl #1            ; 4-in-parallel
+
+|simple_vnext8|
+    ; vp8_simple_filter_mask() function
+    pkhbt       r9, r3, r4, lsl #16
+    pkhbt       r10, r5, r6, lsl #16
+
+    ;transpose r7, r8, r9, r10 to r3, r4, r5, r6
+    TRANSPOSE_MATRIX r7, r8, r9, r10, r3, r4, r5, r6
+
+    uqsub8      r7, r3, r6                  ; p1 - q1
+    uqsub8      r8, r6, r3                  ; q1 - p1
+    uqsub8      r9, r4, r5                  ; p0 - q0
+    uqsub8      r10, r5, r4                 ; q0 - p0
+    orr         r7, r7, r8                  ; abs(p1 - q1)
+    orr         r9, r9, r10                 ; abs(p0 - q0)
+    ldr         lr, c0x7F7F7F7F             ; 0111 1111 mask
+    uqadd8      r9, r9, r9                  ; abs(p0 - q0) * 2
+    and         r7, lr, r7, lsr #1          ; abs(p1 - q1) / 2
+    mov         r8, #0
+    uqadd8      r7, r7, r9                  ; abs(p0 - q0)*2 + abs(p1 - q1)/2
+    mvn         r10, #0                     ; r10 == -1
+    uqsub8      r7, r7, r12                 ; compare to flimit
+
+    usub8       r7, r8, r7
+    sel         r7, r10, r8                 ; filter mask: lr
+
+    cmp         lr, #0
+    beq         simple_vskip_filter         ; skip filtering
+
+    ;vp8_simple_filter() function
+    eor         r3, r3, r2                  ; p1 offset to convert to a signed value
+    eor         r6, r6, r2                  ; q1 offset to convert to a signed value
+    eor         r4, r4, r2                  ; p0 offset to convert to a signed value
+    eor         r5, r5, r2                  ; q0 offset to convert to a signed value
+
+    qsub8       r3, r3, r6                  ; vp8_filter (r3) = vp8_signed_char_clamp(p1-q1)
+    qsub8       r6, r5, r4                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( q0 - p0))
+
+    qadd8       r3, r3, r6
+    ldr         r8, c0x03030303             ; r8 = 3
+
+    qadd8       r3, r3, r6
+    ldr         r7, c0x04040404
+
+    qadd8       r3, r3, r6
+    and         r3, r3, lr                  ; vp8_filter &= mask
+
+    ;save bottom 3 bits so that we round one side +4 and the other +3
+    qadd8       r8 , r3 , r8                ; Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3)
+    qadd8       r3 , r3 , r7                ; Filter1 (r3) = vp8_signed_char_clamp(vp8_filter+4)
+
+    mov         r7, #0
+    shadd8      r8 , r8 , r7                ; Filter2 >>= 3
+    shadd8      r3 , r3 , r7                ; Filter1 >>= 3
+    shadd8      r8 , r8 , r7
+    shadd8      r3 , r3 , r7
+    shadd8      r8 , r8 , r7                ; r8: filter2
+    shadd8      r3 , r3 , r7                ; r7: filter1
+
+    ;calculate output
+    sub         src, src, pstep, lsl #2
+
+    qadd8       r4, r4, r8                  ; u = vp8_signed_char_clamp(p0 + Filter2)
+    qsub8       r5, r5, r3                  ; u = vp8_signed_char_clamp(q0 - Filter1)
+    eor         r4, r4, r2                  ; *op0 = u^0x80
+    eor         r5, r5, r2                  ; *oq0 = u^0x80
+
+    strb        r4, [src, #-1]              ; store the result
+    mov         r4, r4, lsr #8
+    strb        r5, [src], pstep
+    mov         r5, r5, lsr #8
+
+    strb        r4, [src, #-1]
+    mov         r4, r4, lsr #8
+    strb        r5, [src], pstep
+    mov         r5, r5, lsr #8
+
+    strb        r4, [src, #-1]
+    mov         r4, r4, lsr #8
+    strb        r5, [src], pstep
+    mov         r5, r5, lsr #8
+
+    strb        r4, [src, #-1]
+    strb        r5, [src], pstep
+
+|simple_vskip_filter|
+    subs        r11, r11, #1
+
+    ;pld            [src]
+    ;pld            [src, pstep]
+    ;pld            [src, pstep, lsl #1]
+
+    ; load soure data to r7, r8, r9, r10
+    ldrneh      r3, [src, #-2]
+    ldrneh      r4, [src], pstep
+
+    ldrneh      r5, [src, #-2]
+    ldrneh      r6, [src], pstep
+
+    pkhbt       r7, r3, r4, lsl #16
+
+    ldrneh      r3, [src, #-2]
+    ldrneh      r4, [src], pstep
+
+    pkhbt       r8, r5, r6, lsl #16
+
+    ldrneh      r5, [src, #-2]
+    ldrneh      r6, [src], pstep
+
+    bne         simple_vnext8
+
+    ldmia       sp!, {r4 - r12, pc}
+    ENDP        ; |vp8_loop_filter_simple_vertical_edge_armv6|
+
+; Constant Pool
+c0x80808080 DCD     0x80808080
+c0x03030303 DCD     0x03030303
+c0x04040404 DCD     0x04040404
+c0x01010101 DCD     0x01010101
+c0x7F7F7F7F DCD     0x7F7F7F7F
+
+    END
diff --git a/vp8/common/arm/armv6/sixtappredict8x4_v6.asm b/vp8/common/arm/armv6/sixtappredict8x4_v6.asm
new file mode 100644 (file)
index 0000000..551d863
--- /dev/null
@@ -0,0 +1,277 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sixtap_predict8x4_armv6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+;-------------------------------------
+; r0    unsigned char *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; stack unsigned char *dst_ptr,
+; stack int  dst_pitch
+;-------------------------------------
+;note: In first pass, store the result in transpose(8linesx9columns) on stack. Temporary stack size is 184.
+;Line width is 20 that is 9 short data plus 2 to make it 4bytes aligned. In second pass, load data from stack,
+;and the result is stored in transpose.
+|vp8_sixtap_predict8x4_armv6| PROC
+    stmdb       sp!, {r4 - r11, lr}
+    sub         sp, sp, #184                ;reserve space on stack for temporary storage: 20x(8+1) +4
+
+    cmp         r2, #0                      ;skip first_pass filter if xoffset=0
+    str         r3, [sp], #4                ;store yoffset
+    beq         skip_firstpass_filter
+
+;first-pass filter
+    ldr         r12, _filter8_coeff_
+    sub         r0, r0, r1, lsl #1
+
+    add         r2, r12, r2, lsl #4         ;calculate filter location
+    add         r0, r0, #3                  ;adjust src only for loading convinience
+
+    ldr         r3, [r2]                    ; load up packed filter coefficients
+    ldr         r4, [r2, #4]
+    ldr         r5, [r2, #8]
+
+    mov         r2, #0x90000                ; height=9 is top part of counter
+
+    sub         r1, r1, #8
+    mov         lr, #20
+
+|first_pass_hloop_v6|
+    ldrb        r6, [r0, #-5]               ; load source data
+    ldrb        r7, [r0, #-4]
+    ldrb        r8, [r0, #-3]
+    ldrb        r9, [r0, #-2]
+    ldrb        r10, [r0, #-1]
+
+    orr         r2, r2, #0x4                ; construct loop counter. width=8=4x2
+
+    pkhbt       r6, r6, r7, lsl #16         ; r7 | r6
+    pkhbt       r7, r7, r8, lsl #16         ; r8 | r7
+
+    pkhbt       r8, r8, r9, lsl #16         ; r9 | r8
+    pkhbt       r9, r9, r10, lsl #16        ; r10 | r9
+
+|first_pass_wloop_v6|
+    smuad       r11, r6, r3                 ; vp8_filter[0], vp8_filter[1]
+    smuad       r12, r7, r3
+
+    ldrb        r6, [r0], #1
+
+    smlad       r11, r8, r4, r11            ; vp8_filter[2], vp8_filter[3]
+    ldrb        r7, [r0], #1
+    smlad       r12, r9, r4, r12
+
+    pkhbt       r10, r10, r6, lsl #16       ; r10 | r9
+    pkhbt       r6, r6, r7, lsl #16         ; r11 | r10
+    smlad       r11, r10, r5, r11           ; vp8_filter[4], vp8_filter[5]
+    smlad       r12, r6, r5, r12
+
+    sub         r2, r2, #1
+
+    add         r11, r11, #0x40             ; round_shift_and_clamp
+    tst         r2, #0xff                   ; test loop counter
+    usat        r11, #8, r11, asr #7
+    add         r12, r12, #0x40
+    strh        r11, [sp], lr               ; result is transposed and stored, which
+    usat        r12, #8, r12, asr #7
+
+    strh        r12, [sp], lr
+
+    movne       r11, r6
+    movne       r12, r7
+
+    movne       r6, r8
+    movne       r7, r9
+    movne       r8, r10
+    movne       r9, r11
+    movne       r10, r12
+
+    bne         first_pass_wloop_v6
+
+    ;;add       r9, ppl, #30                ; attempt to load 2 adjacent cache lines
+    ;;IF ARCHITECTURE=6
+    ;pld        [src, ppl]
+    ;;pld       [src, r9]
+    ;;ENDIF
+
+    subs        r2, r2, #0x10000
+
+    mov         r6, #158
+    sub         sp, sp, r6
+
+    add         r0, r0, r1                  ; move to next input line
+
+    bne         first_pass_hloop_v6
+
+;second pass filter
+secondpass_filter
+    mov         r1, #18
+    sub         sp, sp, r1                  ; 18+4
+
+    ldr         r3, [sp, #-4]               ; load back yoffset
+    ldr         r0, [sp, #216]              ; load dst address from stack 180+36
+    ldr         r1, [sp, #220]              ; load dst stride from stack 180+40
+
+    cmp         r3, #0
+    beq         skip_secondpass_filter
+
+    ldr         r12, _filter8_coeff_
+    add         lr, r12, r3, lsl #4         ;calculate filter location
+
+    mov         r2, #0x00080000
+
+    ldr         r3, [lr]                    ; load up packed filter coefficients
+    ldr         r4, [lr, #4]
+    ldr         r5, [lr, #8]
+
+    pkhbt       r12, r4, r3                 ; pack the filter differently
+    pkhbt       r11, r5, r4
+
+second_pass_hloop_v6
+    ldr         r6, [sp]                    ; load the data
+    ldr         r7, [sp, #4]
+
+    orr         r2, r2, #2                  ; loop counter
+
+second_pass_wloop_v6
+    smuad       lr, r3, r6                  ; apply filter
+    smulbt      r10, r3, r6
+
+    ldr         r8, [sp, #8]
+
+    smlad       lr, r4, r7, lr
+    smladx      r10, r12, r7, r10
+
+    ldrh        r9, [sp, #12]
+
+    smlad       lr, r5, r8, lr
+    smladx      r10, r11, r8, r10
+
+    add         sp, sp, #4
+    smlatb      r10, r5, r9, r10
+
+    sub         r2, r2, #1
+
+    add         lr, lr, #0x40               ; round_shift_and_clamp
+    tst         r2, #0xff
+    usat        lr, #8, lr, asr #7
+    add         r10, r10, #0x40
+    strb        lr, [r0], r1                ; the result is transposed back and stored
+    usat        r10, #8, r10, asr #7
+
+    strb        r10, [r0],r1
+
+    movne       r6, r7
+    movne       r7, r8
+
+    bne         second_pass_wloop_v6
+
+    subs        r2, r2, #0x10000
+    add         sp, sp, #12                 ; updata src for next loop (20-8)
+    sub         r0, r0, r1, lsl #2
+    add         r0, r0, #1
+
+    bne         second_pass_hloop_v6
+
+    add         sp, sp, #20
+    ldmia       sp!, {r4 - r11, pc}
+
+;--------------------
+skip_firstpass_filter
+    sub         r0, r0, r1, lsl #1
+    sub         r1, r1, #8
+    mov         r2, #9
+    mov         r3, #20
+
+skip_firstpass_hloop
+    ldrb        r4, [r0], #1                ; load data
+    subs        r2, r2, #1
+    ldrb        r5, [r0], #1
+    strh        r4, [sp], r3                ; store it to immediate buffer
+    ldrb        r6, [r0], #1                ; load data
+    strh        r5, [sp], r3
+    ldrb        r7, [r0], #1
+    strh        r6, [sp], r3
+    ldrb        r8, [r0], #1
+    strh        r7, [sp], r3
+    ldrb        r9, [r0], #1
+    strh        r8, [sp], r3
+    ldrb        r10, [r0], #1
+    strh        r9, [sp], r3
+    ldrb        r11, [r0], #1
+    strh        r10, [sp], r3
+    add         r0, r0, r1                  ; move to next input line
+    strh        r11, [sp], r3
+
+    mov         r4, #158
+    sub         sp, sp, r4                  ; move over to next column
+    bne         skip_firstpass_hloop
+
+    b           secondpass_filter
+
+;--------------------
+skip_secondpass_filter
+    mov         r2, #8
+    add         sp, sp, #4                  ;start from src[0] instead of src[-2]
+
+skip_secondpass_hloop
+    ldr         r6, [sp], #4
+    subs        r2, r2, #1
+    ldr         r8, [sp], #4
+
+    mov         r7, r6, lsr #16             ; unpack
+    strb        r6, [r0], r1
+    mov         r9, r8, lsr #16
+    strb        r7, [r0], r1
+    add         sp, sp, #12                 ; 20-8
+    strb        r8, [r0], r1
+    strb        r9, [r0], r1
+
+    sub         r0, r0, r1, lsl #2
+    add         r0, r0, #1
+
+    bne         skip_secondpass_hloop
+
+    add         sp, sp, #16                 ; 180 - (160 +4)
+
+    ldmia       sp!, {r4 - r11, pc}
+
+    ENDP
+
+;-----------------
+    AREA    subpelfilters8_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_filter8_coeff_
+    DCD     filter8_coeff
+filter8_coeff
+    DCD     0x00000000,     0x00000080,     0x00000000,     0x00000000
+    DCD     0xfffa0000,     0x000c007b,     0x0000ffff,     0x00000000
+    DCD     0xfff50002,     0x0024006c,     0x0001fff8,     0x00000000
+    DCD     0xfff70000,     0x0032005d,     0x0000fffa,     0x00000000
+    DCD     0xfff00003,     0x004d004d,     0x0003fff0,     0x00000000
+    DCD     0xfffa0000,     0x005d0032,     0x0000fff7,     0x00000000
+    DCD     0xfff80001,     0x006c0024,     0x0002fff5,     0x00000000
+    DCD     0xffff0000,     0x007b000c,     0x0000fffa,     0x00000000
+
+    ;DCD        0,  0,  128,    0,   0,  0
+    ;DCD        0, -6,  123,   12,  -1,  0
+    ;DCD        2, -11, 108,   36,  -8,  1
+    ;DCD        0, -9,   93,   50,  -6,  0
+    ;DCD        3, -16,  77,   77, -16,  3
+    ;DCD        0, -6,   50,   93,  -9,  0
+    ;DCD        1, -8,   36,  108, -11,  2
+    ;DCD        0, -1,   12,  123,  -6,  0
+
+    END
diff --git a/vp8/common/arm/bilinearfilter_arm.c b/vp8/common/arm/bilinearfilter_arm.c
new file mode 100644 (file)
index 0000000..bf972a3
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <math.h>
+#include "subpixel.h"
+
+#define BLOCK_HEIGHT_WIDTH 4
+#define VP8_FILTER_WEIGHT 128
+#define VP8_FILTER_SHIFT  7
+
+static const short bilinear_filters[8][2] =
+{
+    { 128,   0 },
+    { 112,  16 },
+    {  96,  32 },
+    {  80,  48 },
+    {  64,  64 },
+    {  48,  80 },
+    {  32,  96 },
+    {  16, 112 }
+};
+
+
+extern void vp8_filter_block2d_bil_first_pass_armv6
+(
+    unsigned char *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int output_height,
+    unsigned int output_width,
+    const short *vp8_filter
+);
+
+extern void vp8_filter_block2d_bil_second_pass_armv6
+(
+    unsigned short *src_ptr,
+    unsigned char  *output_ptr,
+    int output_pitch,
+    unsigned int  output_height,
+    unsigned int  output_width,
+    const short *vp8_filter
+);
+
+/*
+void vp8_filter_block2d_bil_first_pass_6
+(
+    unsigned char *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int output_height,
+    unsigned int output_width,
+    const short *vp8_filter
+)
+{
+    unsigned int i, j;
+
+    for ( i=0; i<output_height; i++ )
+    {
+        for ( j=0; j<output_width; j++ )
+        {
+            // Apply bilinear filter
+            output_ptr[j] = ( ( (int)src_ptr[0]          * vp8_filter[0]) +
+                               ((int)src_ptr[1] * vp8_filter[1]) +
+                                (VP8_FILTER_WEIGHT/2) ) >> VP8_FILTER_SHIFT;
+            src_ptr++;
+        }
+
+        // Next row...
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_width;
+    }
+}
+
+void vp8_filter_block2d_bil_second_pass_6
+(
+    unsigned short *src_ptr,
+    unsigned char  *output_ptr,
+    int output_pitch,
+    unsigned int  output_height,
+    unsigned int  output_width,
+    const short *vp8_filter
+)
+{
+    unsigned int  i,j;
+    int  Temp;
+
+    for ( i=0; i<output_height; i++ )
+    {
+        for ( j=0; j<output_width; j++ )
+        {
+            // Apply filter
+            Temp =  ((int)src_ptr[0]         * vp8_filter[0]) +
+                    ((int)src_ptr[output_width] * vp8_filter[1]) +
+                    (VP8_FILTER_WEIGHT/2);
+            output_ptr[j] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);
+            src_ptr++;
+        }
+
+        // Next row...
+        //src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_pitch;
+    }
+}
+*/
+
+void vp8_filter_block2d_bil_armv6
+(
+    unsigned char *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int   src_pixels_per_line,
+    unsigned int   dst_pitch,
+    const short      *HFilter,
+    const short      *VFilter,
+    int            Width,
+    int            Height
+)
+{
+
+    unsigned short FData[36*16]; // Temp data bufffer used in filtering
+
+    // First filter 1-D horizontally...
+    // pixel_step = 1;
+    vp8_filter_block2d_bil_first_pass_armv6(src_ptr, FData, src_pixels_per_line, Height + 1, Width, HFilter);
+
+    // then 1-D vertically...
+    vp8_filter_block2d_bil_second_pass_armv6(FData, output_ptr, dst_pitch, Height, Width, VFilter);
+}
+
+
+void vp8_bilinear_predict4x4_armv6
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil_armv6(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 4, 4);
+}
+
+void vp8_bilinear_predict8x8_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil_armv6(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 8, 8);
+}
+
+void vp8_bilinear_predict8x4_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil_armv6(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 8, 4);
+}
+
+void vp8_bilinear_predict16x16_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil_armv6(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 16, 16);
+}
diff --git a/vp8/common/arm/filter_arm.c b/vp8/common/arm/filter_arm.c
new file mode 100644 (file)
index 0000000..2a4640c
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include <math.h>
+#include "subpixel.h"
+#include "vpx_ports/mem.h"
+
+#define BLOCK_HEIGHT_WIDTH 4
+#define VP8_FILTER_WEIGHT 128
+#define VP8_FILTER_SHIFT  7
+
+DECLARE_ALIGNED(16, static const short, sub_pel_filters[8][6]) =
+{
+    { 0,  0,  128,    0,   0,  0 },         // note that 1/8 pel positions are just as per alpha -0.5 bicubic
+    { 0, -6,  123,   12,  -1,  0 },
+    { 2, -11, 108,   36,  -8,  1 },         // New 1/4 pel 6 tap filter
+    { 0, -9,   93,   50,  -6,  0 },
+    { 3, -16,  77,   77, -16,  3 },         // New 1/2 pel 6 tap filter
+    { 0, -6,   50,   93,  -9,  0 },
+    { 1, -8,   36,  108, -11,  2 },         // New 1/4 pel 6 tap filter
+    { 0, -1,   12,  123,  -6,  0 },
+};
+
+
+extern void vp8_filter_block2d_first_pass_armv6
+(
+    unsigned char *src_ptr,
+    short         *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int output_width,
+    unsigned int output_height,
+    const short *vp8_filter
+);
+
+extern void vp8_filter_block2d_second_pass_armv6
+(
+    short         *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int output_pitch,
+    unsigned int cnt,
+    const short *vp8_filter
+);
+
+extern void vp8_filter_block2d_first_pass_only_armv6
+(
+    unsigned char *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int cnt,
+    unsigned int output_pitch,
+    const short *vp8_filter
+);
+
+
+extern void vp8_filter_block2d_second_pass_only_armv6
+(
+    unsigned char *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int cnt,
+    unsigned int output_pitch,
+    const short *vp8_filter
+);
+
+#if HAVE_ARMV6
+void vp8_sixtap_predict_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    DECLARE_ALIGNED_ARRAY(4, short, FData, 12*4); // Temp data bufffer used in filtering
+
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];       // 6 tap
+
+    // Vfilter is null. First pass only
+    if (xoffset && !yoffset)
+    {
+        //vp8_filter_block2d_first_pass_armv6 ( src_ptr, FData+2, src_pixels_per_line, 4, 4, HFilter );
+        //vp8_filter_block2d_second_pass_armv6 ( FData+2, dst_ptr, dst_pitch, 4, VFilter );
+
+        vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 4, dst_pitch, HFilter);
+    }
+    // Hfilter is null. Second pass only
+    else if (!xoffset && yoffset)
+    {
+        vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 4, dst_pitch, VFilter);
+    }
+    else
+    {
+        // Vfilter is a 4 tap filter
+        if (yoffset & 0x1)
+            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 4, 7, HFilter);
+        // Vfilter is 6 tap filter
+        else
+            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 4, 9, HFilter);
+
+        vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 4, VFilter);
+    }
+}
+
+/*
+void vp8_sixtap_predict8x4_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    DECLARE_ALIGNED_ARRAY(4, short, FData, 16*8); // Temp data bufffer used in filtering
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];       // 6 tap
+
+
+//  if (xoffset && !yoffset)
+//  {
+//      vp8_filter_block2d_first_pass_only_armv6 (  src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, HFilter );
+//  }
+    // Hfilter is null. Second pass only
+//  else if (!xoffset && yoffset)
+//  {
+//      vp8_filter_block2d_second_pass_only_armv6 ( src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, VFilter );
+//  }
+//  else
+//  {
+//      if (yoffset & 0x1)
+    //      vp8_filter_block2d_first_pass_armv6 ( src_ptr-src_pixels_per_line, FData+1, src_pixels_per_line, 8, 7, HFilter );
+    //  else
+
+        vp8_filter_block2d_first_pass_armv6 ( src_ptr-(2*src_pixels_per_line), FData, src_pixels_per_line, 8, 9, HFilter );
+
+        vp8_filter_block2d_second_pass_armv6 ( FData+2, dst_ptr, dst_pitch, 4, 8, VFilter );
+//  }
+}
+*/
+
+void vp8_sixtap_predict8x8_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    DECLARE_ALIGNED_ARRAY(4, short, FData, 16*8); // Temp data bufffer used in filtering
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];       // 6 tap
+
+    if (xoffset && !yoffset)
+    {
+        vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, HFilter);
+    }
+    // Hfilter is null. Second pass only
+    else if (!xoffset && yoffset)
+    {
+        vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, VFilter);
+    }
+    else
+    {
+        if (yoffset & 0x1)
+            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 8, 11, HFilter);
+        else
+            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 8, 13, HFilter);
+
+        vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
+    }
+}
+
+
+void vp8_sixtap_predict16x16_armv6
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    DECLARE_ALIGNED_ARRAY(4, short, FData, 24*16);    // Temp data bufffer used in filtering
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];       // 6 tap
+
+    if (xoffset && !yoffset)
+    {
+        vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 16, dst_pitch, HFilter);
+    }
+    // Hfilter is null. Second pass only
+    else if (!xoffset && yoffset)
+    {
+        vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 16, dst_pitch, VFilter);
+    }
+    else
+    {
+        if (yoffset & 0x1)
+            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 16, 19, HFilter);
+        else
+            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 16, 21, HFilter);
+
+        vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
+    }
+
+}
+#endif
diff --git a/vp8/common/arm/idct_arm.h b/vp8/common/arm/idct_arm.h
new file mode 100644 (file)
index 0000000..f9ed21e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef IDCT_ARM_H
+#define IDCT_ARM_H
+
+#if HAVE_ARMV6
+extern prototype_idct(vp8_short_idct4x4llm_1_v6);
+extern prototype_idct(vp8_short_idct4x4llm_v6_dual);
+extern prototype_idct_scalar(vp8_dc_only_idct_armv6);
+extern prototype_second_order(vp8_short_inv_walsh4x4_1_armv6);
+extern prototype_second_order(vp8_short_inv_walsh4x4_armv6);
+
+#undef  vp8_idct_idct1
+#define vp8_idct_idct1 vp8_short_idct4x4llm_1_v6
+
+#undef  vp8_idct_idct16
+#define vp8_idct_idct16 vp8_short_idct4x4llm_v6_dual
+
+#undef  vp8_idct_idct1_scalar
+#define vp8_idct_idct1_scalar vp8_dc_only_idct_armv6
+
+#undef  vp8_idct_iwalsh1
+#define vp8_idct_iwalsh1 vp8_short_inv_walsh4x4_1_armv6
+
+#undef  vp8_idct_iwalsh16
+#define vp8_idct_iwalsh16 vp8_short_inv_walsh4x4_armv6
+#endif
+
+#if HAVE_ARMV7
+extern prototype_idct(vp8_short_idct4x4llm_1_neon);
+extern prototype_idct(vp8_short_idct4x4llm_neon);
+extern prototype_idct_scalar(vp8_dc_only_idct_neon);
+extern prototype_second_order(vp8_short_inv_walsh4x4_1_neon);
+extern prototype_second_order(vp8_short_inv_walsh4x4_neon);
+
+#undef  vp8_idct_idct1
+#define vp8_idct_idct1 vp8_short_idct4x4llm_1_neon
+
+#undef  vp8_idct_idct16
+#define vp8_idct_idct16 vp8_short_idct4x4llm_neon
+
+#undef  vp8_idct_idct1_scalar
+#define vp8_idct_idct1_scalar vp8_dc_only_idct_neon
+
+#undef  vp8_idct_iwalsh1
+#define vp8_idct_iwalsh1 vp8_short_inv_walsh4x4_1_neon
+
+#undef  vp8_idct_iwalsh16
+#define vp8_idct_iwalsh16 vp8_short_inv_walsh4x4_neon
+#endif
+
+#endif
diff --git a/vp8/common/arm/loopfilter_arm.c b/vp8/common/arm/loopfilter_arm.c
new file mode 100644 (file)
index 0000000..fa7c626
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include <math.h>
+#include "loopfilter.h"
+#include "onyxc_int.h"
+
+typedef void loop_filter_uvfunction
+(
+    unsigned char *u,   // source pointer
+    int p,              // pitch
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    unsigned char *v
+);
+
+extern prototype_loopfilter(vp8_loop_filter_horizontal_edge_armv6);
+extern prototype_loopfilter(vp8_loop_filter_vertical_edge_armv6);
+extern prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_armv6);
+extern prototype_loopfilter(vp8_mbloop_filter_vertical_edge_armv6);
+extern prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_armv6);
+extern prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_armv6);
+
+extern prototype_loopfilter(vp8_loop_filter_horizontal_edge_y_neon);
+extern prototype_loopfilter(vp8_loop_filter_vertical_edge_y_neon);
+extern prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_y_neon);
+extern prototype_loopfilter(vp8_mbloop_filter_vertical_edge_y_neon);
+extern prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_neon);
+extern prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_neon);
+
+extern loop_filter_uvfunction vp8_loop_filter_horizontal_edge_uv_neon;
+extern loop_filter_uvfunction vp8_loop_filter_vertical_edge_uv_neon;
+extern loop_filter_uvfunction vp8_mbloop_filter_horizontal_edge_uv_neon;
+extern loop_filter_uvfunction vp8_mbloop_filter_vertical_edge_uv_neon;
+
+
+#if HAVE_ARMV6
+//ARMV6 loopfilter functions
+// Horizontal MB filtering
+void vp8_loop_filter_mbh_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_horizontal_edge_armv6(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_horizontal_edge_armv6(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_horizontal_edge_armv6(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+void vp8_loop_filter_mbhs_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                                int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+// Vertical MB Filtering
+void vp8_loop_filter_mbv_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_vertical_edge_armv6(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_vertical_edge_armv6(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_vertical_edge_armv6(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+void vp8_loop_filter_mbvs_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                                int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+// Horizontal B Filtering
+void vp8_loop_filter_bh_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_horizontal_edge_armv6(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_armv6(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_armv6(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_horizontal_edge_armv6(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_horizontal_edge_armv6(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+void vp8_loop_filter_bhs_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+// Vertical B Filtering
+void vp8_loop_filter_bv_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_vertical_edge_armv6(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_armv6(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_armv6(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_vertical_edge_armv6(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_vertical_edge_armv6(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+void vp8_loop_filter_bvs_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+#endif
+
+#if HAVE_ARMV7
+// NEON loopfilter functions
+// Horizontal MB filtering
+void vp8_loop_filter_mbh_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_horizontal_edge_y_neon(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_horizontal_edge_uv_neon(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, v_ptr);
+}
+
+void vp8_loop_filter_mbhs_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_neon(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+// Vertical MB Filtering
+void vp8_loop_filter_mbv_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_vertical_edge_y_neon(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_vertical_edge_uv_neon(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, v_ptr);
+}
+
+void vp8_loop_filter_mbvs_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_neon(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+// Horizontal B Filtering
+void vp8_loop_filter_bh_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_horizontal_edge_uv_neon(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, v_ptr + 4 * uv_stride);
+}
+
+void vp8_loop_filter_bhs_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_neon(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_neon(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_neon(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+// Vertical B Filtering
+void vp8_loop_filter_bv_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_vertical_edge_y_neon(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_y_neon(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_y_neon(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_vertical_edge_uv_neon(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, v_ptr + 4);
+}
+
+void vp8_loop_filter_bvs_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_neon(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_neon(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_neon(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+#endif
diff --git a/vp8/common/arm/loopfilter_arm.h b/vp8/common/arm/loopfilter_arm.h
new file mode 100644 (file)
index 0000000..4bb4945
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef LOOPFILTER_ARM_H
+#define LOOPFILTER_ARM_H
+
+#if HAVE_ARMV6
+extern prototype_loopfilter_block(vp8_loop_filter_mbv_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_bv_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_mbh_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_bh_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_mbvs_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_bvs_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_mbhs_armv6);
+extern prototype_loopfilter_block(vp8_loop_filter_bhs_armv6);
+
+#undef  vp8_lf_normal_mb_v
+#define vp8_lf_normal_mb_v vp8_loop_filter_mbv_armv6
+
+#undef  vp8_lf_normal_b_v
+#define vp8_lf_normal_b_v vp8_loop_filter_bv_armv6
+
+#undef  vp8_lf_normal_mb_h
+#define vp8_lf_normal_mb_h vp8_loop_filter_mbh_armv6
+
+#undef  vp8_lf_normal_b_h
+#define vp8_lf_normal_b_h vp8_loop_filter_bh_armv6
+
+#undef  vp8_lf_simple_mb_v
+#define vp8_lf_simple_mb_v vp8_loop_filter_mbvs_armv6
+
+#undef  vp8_lf_simple_b_v
+#define vp8_lf_simple_b_v vp8_loop_filter_bvs_armv6
+
+#undef  vp8_lf_simple_mb_h
+#define vp8_lf_simple_mb_h vp8_loop_filter_mbhs_armv6
+
+#undef  vp8_lf_simple_b_h
+#define vp8_lf_simple_b_h vp8_loop_filter_bhs_armv6
+#endif
+
+#if HAVE_ARMV7
+extern prototype_loopfilter_block(vp8_loop_filter_mbv_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_bv_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_mbh_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_bh_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_mbvs_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_bvs_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_mbhs_neon);
+extern prototype_loopfilter_block(vp8_loop_filter_bhs_neon);
+
+#undef  vp8_lf_normal_mb_v
+#define vp8_lf_normal_mb_v vp8_loop_filter_mbv_neon
+
+#undef  vp8_lf_normal_b_v
+#define vp8_lf_normal_b_v vp8_loop_filter_bv_neon
+
+#undef  vp8_lf_normal_mb_h
+#define vp8_lf_normal_mb_h vp8_loop_filter_mbh_neon
+
+#undef  vp8_lf_normal_b_h
+#define vp8_lf_normal_b_h vp8_loop_filter_bh_neon
+
+#undef  vp8_lf_simple_mb_v
+#define vp8_lf_simple_mb_v vp8_loop_filter_mbvs_neon
+
+#undef  vp8_lf_simple_b_v
+#define vp8_lf_simple_b_v vp8_loop_filter_bvs_neon
+
+#undef  vp8_lf_simple_mb_h
+#define vp8_lf_simple_mb_h vp8_loop_filter_mbhs_neon
+
+#undef  vp8_lf_simple_b_h
+#define vp8_lf_simple_b_h vp8_loop_filter_bhs_neon
+#endif
+
+#endif
diff --git a/vp8/common/arm/neon/bilinearpredict16x16_neon.asm b/vp8/common/arm/neon/bilinearpredict16x16_neon.asm
new file mode 100644 (file)
index 0000000..a2fea2b
--- /dev/null
@@ -0,0 +1,361 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_bilinear_predict16x16_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; r4    unsigned char *dst_ptr,
+; stack(r5) int  dst_pitch
+
+|vp8_bilinear_predict16x16_neon| PROC
+    push            {r4-r5, lr}
+
+    ldr             r12, _bifilter16_coeff_
+    ldr             r4, [sp, #12]           ;load parameters from stack
+    ldr             r5, [sp, #16]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_bfilter16x16_only
+
+    add             r2, r12, r2, lsl #3     ;calculate filter location
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+
+    vld1.s32        {d31}, [r2]             ;load first_pass filter
+
+    beq             firstpass_bfilter16x16_only
+
+    sub             sp, sp, #272            ;reserve space on stack for temporary storage
+    vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
+    mov             lr, sp
+    vld1.u8         {d5, d6, d7}, [r0], r1
+
+    mov             r2, #3                  ;loop counter
+    vld1.u8         {d8, d9, d10}, [r0], r1
+
+    vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
+    vld1.u8         {d11, d12, d13}, [r0], r1
+
+    vdup.8          d1, d31[4]
+
+;First Pass: output_height lines x output_width columns (17x16)
+filt_blk2d_fp16x16_loop_neon
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q8, d3, d0
+    vmull.u8        q9, d5, d0
+    vmull.u8        q10, d6, d0
+    vmull.u8        q11, d8, d0
+    vmull.u8        q12, d9, d0
+    vmull.u8        q13, d11, d0
+    vmull.u8        q14, d12, d0
+
+    vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
+    vext.8          d5, d5, d6, #1
+    vext.8          d8, d8, d9, #1
+    vext.8          d11, d11, d12, #1
+
+    vmlal.u8        q7, d2, d1              ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q9, d5, d1
+    vmlal.u8        q11, d8, d1
+    vmlal.u8        q13, d11, d1
+
+    vext.8          d3, d3, d4, #1
+    vext.8          d6, d6, d7, #1
+    vext.8          d9, d9, d10, #1
+    vext.8          d12, d12, d13, #1
+
+    vmlal.u8        q8, d3, d1              ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q10, d6, d1
+    vmlal.u8        q12, d9, d1
+    vmlal.u8        q14, d12, d1
+
+    subs            r2, r2, #1
+
+    vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d15, q8, #7
+    vqrshrn.u16    d16, q9, #7
+    vqrshrn.u16    d17, q10, #7
+    vqrshrn.u16    d18, q11, #7
+    vqrshrn.u16    d19, q12, #7
+    vqrshrn.u16    d20, q13, #7
+
+    vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
+    vqrshrn.u16    d21, q14, #7
+    vld1.u8         {d5, d6, d7}, [r0], r1
+
+    vst1.u8         {d14, d15, d16, d17}, [lr]!     ;store result
+    vld1.u8         {d8, d9, d10}, [r0], r1
+    vst1.u8         {d18, d19, d20, d21}, [lr]!
+    vld1.u8         {d11, d12, d13}, [r0], r1
+
+    bne             filt_blk2d_fp16x16_loop_neon
+
+;First-pass filtering for rest 5 lines
+    vld1.u8         {d14, d15, d16}, [r0], r1
+
+    vmull.u8        q9, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q10, d3, d0
+    vmull.u8        q11, d5, d0
+    vmull.u8        q12, d6, d0
+    vmull.u8        q13, d8, d0
+    vmull.u8        q14, d9, d0
+
+    vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
+    vext.8          d5, d5, d6, #1
+    vext.8          d8, d8, d9, #1
+
+    vmlal.u8        q9, d2, d1              ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q11, d5, d1
+    vmlal.u8        q13, d8, d1
+
+    vext.8          d3, d3, d4, #1
+    vext.8          d6, d6, d7, #1
+    vext.8          d9, d9, d10, #1
+
+    vmlal.u8        q10, d3, d1             ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q12, d6, d1
+    vmlal.u8        q14, d9, d1
+
+    vmull.u8        q1, d11, d0
+    vmull.u8        q2, d12, d0
+    vmull.u8        q3, d14, d0
+    vmull.u8        q4, d15, d0
+
+    vext.8          d11, d11, d12, #1       ;construct src_ptr[1]
+    vext.8          d14, d14, d15, #1
+
+    vmlal.u8        q1, d11, d1             ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q3, d14, d1
+
+    vext.8          d12, d12, d13, #1
+    vext.8          d15, d15, d16, #1
+
+    vmlal.u8        q2, d12, d1             ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q4, d15, d1
+
+    vqrshrn.u16    d10, q9, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d11, q10, #7
+    vqrshrn.u16    d12, q11, #7
+    vqrshrn.u16    d13, q12, #7
+    vqrshrn.u16    d14, q13, #7
+    vqrshrn.u16    d15, q14, #7
+    vqrshrn.u16    d16, q1, #7
+    vqrshrn.u16    d17, q2, #7
+    vqrshrn.u16    d18, q3, #7
+    vqrshrn.u16    d19, q4, #7
+
+    vst1.u8         {d10, d11, d12, d13}, [lr]!         ;store result
+    vst1.u8         {d14, d15, d16, d17}, [lr]!
+    vst1.u8         {d18, d19}, [lr]!
+
+;Second pass: 16x16
+;secondpass_filter
+    add             r3, r12, r3, lsl #3
+    sub             lr, lr, #272
+
+    vld1.u32        {d31}, [r3]             ;load second_pass filter
+
+    vld1.u8         {d22, d23}, [lr]!       ;load src data
+
+    vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+    mov             r12, #4                 ;loop counter
+
+filt_blk2d_sp16x16_loop_neon
+    vld1.u8         {d24, d25}, [lr]!
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
+    vld1.u8         {d26, d27}, [lr]!
+    vmull.u8        q2, d23, d0
+    vld1.u8         {d28, d29}, [lr]!
+    vmull.u8        q3, d24, d0
+    vld1.u8         {d30, d31}, [lr]!
+
+    vmull.u8        q4, d25, d0
+    vmull.u8        q5, d26, d0
+    vmull.u8        q6, d27, d0
+    vmull.u8        q7, d28, d0
+    vmull.u8        q8, d29, d0
+
+    vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
+    vmlal.u8        q2, d25, d1
+    vmlal.u8        q3, d26, d1
+    vmlal.u8        q4, d27, d1
+    vmlal.u8        q5, d28, d1
+    vmlal.u8        q6, d29, d1
+    vmlal.u8        q7, d30, d1
+    vmlal.u8        q8, d31, d1
+
+    subs            r12, r12, #1
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+    vqrshrn.u16    d4, q3, #7
+    vqrshrn.u16    d5, q4, #7
+    vqrshrn.u16    d6, q5, #7
+    vqrshrn.u16    d7, q6, #7
+    vqrshrn.u16    d8, q7, #7
+    vqrshrn.u16    d9, q8, #7
+
+    vst1.u8         {d2, d3}, [r4], r5      ;store result
+    vst1.u8         {d4, d5}, [r4], r5
+    vst1.u8         {d6, d7}, [r4], r5
+    vmov            q11, q15
+    vst1.u8         {d8, d9}, [r4], r5
+
+    bne             filt_blk2d_sp16x16_loop_neon
+
+    add             sp, sp, #272
+
+    pop             {r4-r5,pc}
+
+;--------------------
+firstpass_bfilter16x16_only
+    mov             r2, #4                      ;loop counter
+    vdup.8          d0, d31[0]                  ;first_pass filter (d0 d1)
+    vdup.8          d1, d31[4]
+
+;First Pass: output_height lines x output_width columns (16x16)
+filt_blk2d_fpo16x16_loop_neon
+    vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
+    vld1.u8         {d5, d6, d7}, [r0], r1
+    vld1.u8         {d8, d9, d10}, [r0], r1
+    vld1.u8         {d11, d12, d13}, [r0], r1
+
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q8, d3, d0
+    vmull.u8        q9, d5, d0
+    vmull.u8        q10, d6, d0
+    vmull.u8        q11, d8, d0
+    vmull.u8        q12, d9, d0
+    vmull.u8        q13, d11, d0
+    vmull.u8        q14, d12, d0
+
+    vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
+    vext.8          d5, d5, d6, #1
+    vext.8          d8, d8, d9, #1
+    vext.8          d11, d11, d12, #1
+
+    vmlal.u8        q7, d2, d1              ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q9, d5, d1
+    vmlal.u8        q11, d8, d1
+    vmlal.u8        q13, d11, d1
+
+    vext.8          d3, d3, d4, #1
+    vext.8          d6, d6, d7, #1
+    vext.8          d9, d9, d10, #1
+    vext.8          d12, d12, d13, #1
+
+    vmlal.u8        q8, d3, d1              ;(src_ptr[0] * vp8_filter[1])
+    vmlal.u8        q10, d6, d1
+    vmlal.u8        q12, d9, d1
+    vmlal.u8        q14, d12, d1
+
+    subs            r2, r2, #1
+
+    vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d15, q8, #7
+    vqrshrn.u16    d16, q9, #7
+    vqrshrn.u16    d17, q10, #7
+    vqrshrn.u16    d18, q11, #7
+    vqrshrn.u16    d19, q12, #7
+    vqrshrn.u16    d20, q13, #7
+    vst1.u8         {d14, d15}, [r4], r5        ;store result
+    vqrshrn.u16    d21, q14, #7
+
+    vst1.u8         {d16, d17}, [r4], r5
+    vst1.u8         {d18, d19}, [r4], r5
+    vst1.u8         {d20, d21}, [r4], r5
+
+    bne             filt_blk2d_fpo16x16_loop_neon
+    pop             {r4-r5,pc}
+
+;---------------------
+secondpass_bfilter16x16_only
+;Second pass: 16x16
+;secondpass_filter
+    add             r3, r12, r3, lsl #3
+    mov             r12, #4                     ;loop counter
+    vld1.u32        {d31}, [r3]                 ;load second_pass filter
+    vld1.u8         {d22, d23}, [r0], r1        ;load src data
+
+    vdup.8          d0, d31[0]                  ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+
+filt_blk2d_spo16x16_loop_neon
+    vld1.u8         {d24, d25}, [r0], r1
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
+    vld1.u8         {d26, d27}, [r0], r1
+    vmull.u8        q2, d23, d0
+    vld1.u8         {d28, d29}, [r0], r1
+    vmull.u8        q3, d24, d0
+    vld1.u8         {d30, d31}, [r0], r1
+
+    vmull.u8        q4, d25, d0
+    vmull.u8        q5, d26, d0
+    vmull.u8        q6, d27, d0
+    vmull.u8        q7, d28, d0
+    vmull.u8        q8, d29, d0
+
+    vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
+    vmlal.u8        q2, d25, d1
+    vmlal.u8        q3, d26, d1
+    vmlal.u8        q4, d27, d1
+    vmlal.u8        q5, d28, d1
+    vmlal.u8        q6, d29, d1
+    vmlal.u8        q7, d30, d1
+    vmlal.u8        q8, d31, d1
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+    vqrshrn.u16    d4, q3, #7
+    vqrshrn.u16    d5, q4, #7
+    vqrshrn.u16    d6, q5, #7
+    vqrshrn.u16    d7, q6, #7
+    vqrshrn.u16    d8, q7, #7
+    vqrshrn.u16    d9, q8, #7
+
+    vst1.u8         {d2, d3}, [r4], r5      ;store result
+    subs            r12, r12, #1
+    vst1.u8         {d4, d5}, [r4], r5
+    vmov            q11, q15
+    vst1.u8         {d6, d7}, [r4], r5
+    vst1.u8         {d8, d9}, [r4], r5
+
+    bne             filt_blk2d_spo16x16_loop_neon
+    pop             {r4-r5,pc}
+
+    ENDP
+
+;-----------------
+    AREA    bifilters16_dat, DATA, READWRITE            ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_bifilter16_coeff_
+    DCD     bifilter16_coeff
+bifilter16_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+    END
diff --git a/vp8/common/arm/neon/bilinearpredict4x4_neon.asm b/vp8/common/arm/neon/bilinearpredict4x4_neon.asm
new file mode 100644 (file)
index 0000000..74d2db5
--- /dev/null
@@ -0,0 +1,134 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_bilinear_predict4x4_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; r4    unsigned char *dst_ptr,
+; stack(lr) int  dst_pitch
+
+|vp8_bilinear_predict4x4_neon| PROC
+    push            {r4, lr}
+
+    ldr             r12, _bifilter4_coeff_
+    ldr             r4, [sp, #8]            ;load parameters from stack
+    ldr             lr, [sp, #12]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             skip_firstpass_filter
+
+;First pass: output_height lines x output_width columns (5x4)
+    vld1.u8         {d2}, [r0], r1          ;load src data
+    add             r2, r12, r2, lsl #3     ;calculate Hfilter location (2coeffsx4bytes=8bytes)
+
+    vld1.u8         {d3}, [r0], r1
+    vld1.u32        {d31}, [r2]             ;first_pass filter
+
+    vld1.u8         {d4}, [r0], r1
+    vdup.8          d0, d31[0]              ;first_pass filter (d0-d1)
+    vld1.u8         {d5}, [r0], r1
+    vdup.8          d1, d31[4]
+    vld1.u8         {d6}, [r0], r1
+
+    vshr.u64        q4, q1, #8              ;construct src_ptr[1]
+    vshr.u64        q5, q2, #8
+    vshr.u64        d12, d6, #8
+
+    vzip.32         d2, d3                  ;put 2-line data in 1 register (src_ptr[0])
+    vzip.32         d4, d5
+    vzip.32         d8, d9                  ;put 2-line data in 1 register (src_ptr[1])
+    vzip.32         d10, d11
+
+    vmull.u8        q7, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q8, d4, d0
+    vmull.u8        q9, d6, d0
+
+    vmlal.u8        q7, d8, d1              ;(src_ptr[1] * vp8_filter[1])
+    vmlal.u8        q8, d10, d1
+    vmlal.u8        q9, d12, d1
+
+    vqrshrn.u16    d28, q7, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d29, q8, #7
+    vqrshrn.u16    d30, q9, #7
+
+;Second pass: 4x4
+secondpass_filter
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+    beq             skip_secondpass_filter
+
+    add             r3, r12, r3, lsl #3 ;calculate Vfilter location
+    vld1.u32        {d31}, [r3]         ;load second_pass filter
+
+    vdup.8          d0, d31[0]              ;second_pass filter parameters (d0-d5)
+    vdup.8          d1, d31[4]
+
+    vmull.u8        q1, d28, d0
+    vmull.u8        q2, d29, d0
+
+    vext.8          d26, d28, d29, #4       ;construct src_ptr[pixel_step]
+    vext.8          d27, d29, d30, #4
+
+    vmlal.u8        q1, d26, d1
+    vmlal.u8        q2, d27, d1
+
+    add             r0, r4, lr
+    add             r1, r0, lr
+    add             r2, r1, lr
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+
+    vst1.32         {d2[0]}, [r4]           ;store result
+    vst1.32         {d2[1]}, [r0]
+    vst1.32         {d3[0]}, [r1]
+    vst1.32         {d3[1]}, [r2]
+
+    pop             {r4, pc}
+
+;--------------------
+skip_firstpass_filter
+
+    vld1.32         {d28[0]}, [r0], r1      ;load src data
+    vld1.32         {d28[1]}, [r0], r1
+    vld1.32         {d29[0]}, [r0], r1
+    vld1.32         {d29[1]}, [r0], r1
+    vld1.32         {d30[0]}, [r0], r1
+
+    b               secondpass_filter
+
+;---------------------
+skip_secondpass_filter
+    vst1.32         {d28[0]}, [r4], lr      ;store result
+    vst1.32         {d28[1]}, [r4], lr
+    vst1.32         {d29[0]}, [r4], lr
+    vst1.32         {d29[1]}, [r4], lr
+
+    pop             {r4, pc}
+
+    ENDP
+
+;-----------------
+    AREA    bilinearfilters4_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_bifilter4_coeff_
+    DCD     bifilter4_coeff
+bifilter4_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+    END
diff --git a/vp8/common/arm/neon/bilinearpredict8x4_neon.asm b/vp8/common/arm/neon/bilinearpredict8x4_neon.asm
new file mode 100644 (file)
index 0000000..46ebb0e
--- /dev/null
@@ -0,0 +1,139 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_bilinear_predict8x4_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; r4    unsigned char *dst_ptr,
+; stack(lr) int  dst_pitch
+
+|vp8_bilinear_predict8x4_neon| PROC
+    push            {r4, lr}
+
+    ldr             r12, _bifilter8x4_coeff_
+    ldr             r4, [sp, #8]            ;load parameters from stack
+    ldr             lr, [sp, #12]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             skip_firstpass_filter
+
+;First pass: output_height lines x output_width columns (5x8)
+    add             r2, r12, r2, lsl #3     ;calculate filter location
+
+    vld1.u8         {q1}, [r0], r1          ;load src data
+    vld1.u32        {d31}, [r2]             ;load first_pass filter
+    vld1.u8         {q2}, [r0], r1
+    vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
+    vld1.u8         {q3}, [r0], r1
+    vdup.8          d1, d31[4]
+    vld1.u8         {q4}, [r0], r1
+
+    vmull.u8        q6, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vld1.u8         {q5}, [r0], r1
+    vmull.u8        q7, d4, d0
+    vmull.u8        q8, d6, d0
+    vmull.u8        q9, d8, d0
+    vmull.u8        q10, d10, d0
+
+    vext.8          d3, d2, d3, #1          ;construct src_ptr[-1]
+    vext.8          d5, d4, d5, #1
+    vext.8          d7, d6, d7, #1
+    vext.8          d9, d8, d9, #1
+    vext.8          d11, d10, d11, #1
+
+    vmlal.u8        q6, d3, d1              ;(src_ptr[1] * vp8_filter[1])
+    vmlal.u8        q7, d5, d1
+    vmlal.u8        q8, d7, d1
+    vmlal.u8        q9, d9, d1
+    vmlal.u8        q10, d11, d1
+
+    vqrshrn.u16    d22, q6, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d23, q7, #7
+    vqrshrn.u16    d24, q8, #7
+    vqrshrn.u16    d25, q9, #7
+    vqrshrn.u16    d26, q10, #7
+
+;Second pass: 4x8
+secondpass_filter
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+    beq             skip_secondpass_filter
+
+    add             r3, r12, r3, lsl #3
+    add             r0, r4, lr
+
+    vld1.u32        {d31}, [r3]             ;load second_pass filter
+    add             r1, r0, lr
+
+    vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q2, d23, d0
+    vmull.u8        q3, d24, d0
+    vmull.u8        q4, d25, d0
+
+    vmlal.u8        q1, d23, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
+    vmlal.u8        q2, d24, d1
+    vmlal.u8        q3, d25, d1
+    vmlal.u8        q4, d26, d1
+
+    add             r2, r1, lr
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+    vqrshrn.u16    d4, q3, #7
+    vqrshrn.u16    d5, q4, #7
+
+    vst1.u8         {d2}, [r4]              ;store result
+    vst1.u8         {d3}, [r0]
+    vst1.u8         {d4}, [r1]
+    vst1.u8         {d5}, [r2]
+
+    pop             {r4, pc}
+
+;--------------------
+skip_firstpass_filter
+    vld1.u8         {d22}, [r0], r1         ;load src data
+    vld1.u8         {d23}, [r0], r1
+    vld1.u8         {d24}, [r0], r1
+    vld1.u8         {d25}, [r0], r1
+    vld1.u8         {d26}, [r0], r1
+
+    b               secondpass_filter
+
+;---------------------
+skip_secondpass_filter
+    vst1.u8         {d22}, [r4], lr         ;store result
+    vst1.u8         {d23}, [r4], lr
+    vst1.u8         {d24}, [r4], lr
+    vst1.u8         {d25}, [r4], lr
+
+    pop             {r4, pc}
+
+    ENDP
+
+;-----------------
+    AREA    bifilters8x4_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_bifilter8x4_coeff_
+    DCD     bifilter8x4_coeff
+bifilter8x4_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+    END
diff --git a/vp8/common/arm/neon/bilinearpredict8x8_neon.asm b/vp8/common/arm/neon/bilinearpredict8x8_neon.asm
new file mode 100644 (file)
index 0000000..80728d4
--- /dev/null
@@ -0,0 +1,187 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_bilinear_predict8x8_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; r4    unsigned char *dst_ptr,
+; stack(lr) int  dst_pitch
+
+|vp8_bilinear_predict8x8_neon| PROC
+    push            {r4, lr}
+
+    ldr             r12, _bifilter8_coeff_
+    ldr             r4, [sp, #8]            ;load parameters from stack
+    ldr             lr, [sp, #12]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             skip_firstpass_filter
+
+;First pass: output_height lines x output_width columns (9x8)
+    add             r2, r12, r2, lsl #3     ;calculate filter location
+
+    vld1.u8         {q1}, [r0], r1          ;load src data
+    vld1.u32        {d31}, [r2]             ;load first_pass filter
+    vld1.u8         {q2}, [r0], r1
+    vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
+    vld1.u8         {q3}, [r0], r1
+    vdup.8          d1, d31[4]
+    vld1.u8         {q4}, [r0], r1
+
+    vmull.u8        q6, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q7, d4, d0
+    vmull.u8        q8, d6, d0
+    vmull.u8        q9, d8, d0
+
+    vext.8          d3, d2, d3, #1          ;construct src_ptr[-1]
+    vext.8          d5, d4, d5, #1
+    vext.8          d7, d6, d7, #1
+    vext.8          d9, d8, d9, #1
+
+    vmlal.u8        q6, d3, d1              ;(src_ptr[1] * vp8_filter[1])
+    vmlal.u8        q7, d5, d1
+    vmlal.u8        q8, d7, d1
+    vmlal.u8        q9, d9, d1
+
+    vld1.u8         {q1}, [r0], r1          ;load src data
+    vqrshrn.u16    d22, q6, #7              ;shift/round/saturate to u8
+    vld1.u8         {q2}, [r0], r1
+    vqrshrn.u16    d23, q7, #7
+    vld1.u8         {q3}, [r0], r1
+    vqrshrn.u16    d24, q8, #7
+    vld1.u8         {q4}, [r0], r1
+    vqrshrn.u16    d25, q9, #7
+
+    ;first_pass filtering on the rest 5-line data
+    vld1.u8         {q5}, [r0], r1
+
+    vmull.u8        q6, d2, d0              ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q7, d4, d0
+    vmull.u8        q8, d6, d0
+    vmull.u8        q9, d8, d0
+    vmull.u8        q10, d10, d0
+
+    vext.8          d3, d2, d3, #1          ;construct src_ptr[-1]
+    vext.8          d5, d4, d5, #1
+    vext.8          d7, d6, d7, #1
+    vext.8          d9, d8, d9, #1
+    vext.8          d11, d10, d11, #1
+
+    vmlal.u8        q6, d3, d1              ;(src_ptr[1] * vp8_filter[1])
+    vmlal.u8        q7, d5, d1
+    vmlal.u8        q8, d7, d1
+    vmlal.u8        q9, d9, d1
+    vmlal.u8        q10, d11, d1
+
+    vqrshrn.u16    d26, q6, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d27, q7, #7
+    vqrshrn.u16    d28, q8, #7
+    vqrshrn.u16    d29, q9, #7
+    vqrshrn.u16    d30, q10, #7
+
+;Second pass: 8x8
+secondpass_filter
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+    beq             skip_secondpass_filter
+
+    add             r3, r12, r3, lsl #3
+    add             r0, r4, lr
+
+    vld1.u32        {d31}, [r3]             ;load second_pass filter
+    add             r1, r0, lr
+
+    vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * vp8_filter[0])
+    vmull.u8        q2, d23, d0
+    vmull.u8        q3, d24, d0
+    vmull.u8        q4, d25, d0
+    vmull.u8        q5, d26, d0
+    vmull.u8        q6, d27, d0
+    vmull.u8        q7, d28, d0
+    vmull.u8        q8, d29, d0
+
+    vmlal.u8        q1, d23, d1             ;(src_ptr[pixel_step] * vp8_filter[1])
+    vmlal.u8        q2, d24, d1
+    vmlal.u8        q3, d25, d1
+    vmlal.u8        q4, d26, d1
+    vmlal.u8        q5, d27, d1
+    vmlal.u8        q6, d28, d1
+    vmlal.u8        q7, d29, d1
+    vmlal.u8        q8, d30, d1
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+    vqrshrn.u16    d4, q3, #7
+    vqrshrn.u16    d5, q4, #7
+    vqrshrn.u16    d6, q5, #7
+    vqrshrn.u16    d7, q6, #7
+    vqrshrn.u16    d8, q7, #7
+    vqrshrn.u16    d9, q8, #7
+
+    vst1.u8         {d2}, [r4]              ;store result
+    vst1.u8         {d3}, [r0]
+    vst1.u8         {d4}, [r1], lr
+    vst1.u8         {d5}, [r1], lr
+    vst1.u8         {d6}, [r1], lr
+    vst1.u8         {d7}, [r1], lr
+    vst1.u8         {d8}, [r1], lr
+    vst1.u8         {d9}, [r1], lr
+
+    pop             {r4, pc}
+
+;--------------------
+skip_firstpass_filter
+    vld1.u8         {d22}, [r0], r1         ;load src data
+    vld1.u8         {d23}, [r0], r1
+    vld1.u8         {d24}, [r0], r1
+    vld1.u8         {d25}, [r0], r1
+    vld1.u8         {d26}, [r0], r1
+    vld1.u8         {d27}, [r0], r1
+    vld1.u8         {d28}, [r0], r1
+    vld1.u8         {d29}, [r0], r1
+    vld1.u8         {d30}, [r0], r1
+
+    b               secondpass_filter
+
+;---------------------
+skip_secondpass_filter
+    vst1.u8         {d22}, [r4], lr         ;store result
+    vst1.u8         {d23}, [r4], lr
+    vst1.u8         {d24}, [r4], lr
+    vst1.u8         {d25}, [r4], lr
+    vst1.u8         {d26}, [r4], lr
+    vst1.u8         {d27}, [r4], lr
+    vst1.u8         {d28}, [r4], lr
+    vst1.u8         {d29}, [r4], lr
+
+    pop             {r4, pc}
+
+    ENDP
+
+;-----------------
+    AREA    bifilters8_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_bifilter8_coeff_
+    DCD     bifilter8_coeff
+bifilter8_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+    END
diff --git a/vp8/common/arm/neon/buildintrapredictorsmby_neon.asm b/vp8/common/arm/neon/buildintrapredictorsmby_neon.asm
new file mode 100644 (file)
index 0000000..f42ac63
--- /dev/null
@@ -0,0 +1,583 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_build_intra_predictors_mby_neon_func|
+    EXPORT  |vp8_build_intra_predictors_mby_s_neon_func|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char *y_buffer
+; r1    unsigned char *ypred_ptr
+; r2    int y_stride
+; r3    int mode
+; stack int Up
+; stack int Left
+
+|vp8_build_intra_predictors_mby_neon_func| PROC
+    push            {r4-r8, lr}
+
+    cmp             r3, #0
+    beq             case_dc_pred
+    cmp             r3, #1
+    beq             case_v_pred
+    cmp             r3, #2
+    beq             case_h_pred
+    cmp             r3, #3
+    beq             case_tm_pred
+
+case_dc_pred
+    ldr             r4, [sp, #24]       ; Up
+    ldr             r5, [sp, #28]       ; Left
+
+    ; Default the DC average to 128
+    mov             r12, #128
+    vdup.u8         q0, r12
+
+    ; Zero out running sum
+    mov             r12, #0
+
+    ; compute shift and jump
+    adds            r7, r4, r5
+    beq             skip_dc_pred_up_left
+
+    ; Load above row, if it exists
+    cmp             r4, #0
+    beq             skip_dc_pred_up
+
+    sub             r6, r0, r2
+    vld1.8          {q1}, [r6]
+    vpaddl.u8       q2, q1
+    vpaddl.u16      q3, q2
+    vpaddl.u32      q4, q3
+
+    vmov.32         r4, d8[0]
+    vmov.32         r6, d9[0]
+
+    add             r12, r4, r6
+
+    ; Move back to interger registers
+
+skip_dc_pred_up
+
+    cmp             r5, #0
+    beq             skip_dc_pred_left
+
+    sub             r0, r0, #1
+
+    ; Load left row, if it exists
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0]
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+skip_dc_pred_left
+    add             r7, r7, #3          ; Shift
+    sub             r4, r7, #1
+    mov             r5, #1
+    add             r12, r12, r5, lsl r4
+    mov             r5, r12, lsr r7     ; expected_dc
+
+    vdup.u8         q0, r5
+
+skip_dc_pred_up_left
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+
+    pop             {r4-r8,pc}
+case_v_pred
+    ; Copy down above row
+    sub             r6, r0, r2
+    vld1.8          {q0}, [r6]
+
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q0}, [r1]!
+    pop             {r4-r8,pc}
+
+case_h_pred
+    ; Load 4x yleft_col
+    sub             r0, r0, #1
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q1}, [r1]!
+    vst1.u8         {q2}, [r1]!
+    vst1.u8         {q3}, [r1]!
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q1}, [r1]!
+    vst1.u8         {q2}, [r1]!
+    vst1.u8         {q3}, [r1]!
+
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q1}, [r1]!
+    vst1.u8         {q2}, [r1]!
+    vst1.u8         {q3}, [r1]!
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q1}, [r1]!
+    vst1.u8         {q2}, [r1]!
+    vst1.u8         {q3}, [r1]!
+
+    pop             {r4-r8,pc}
+
+case_tm_pred
+    ; Load yabove_row
+    sub             r3, r0, r2
+    vld1.8          {q8}, [r3]
+
+    ; Load ytop_left
+    sub             r3, r3, #1
+    ldrb            r7, [r3]
+
+    vdup.u16        q7, r7
+
+    ; Compute yabove_row - ytop_left
+    mov             r3, #1
+    vdup.u8         q0, r3
+
+    vmull.u8        q4, d16, d0
+    vmull.u8        q5, d17, d0
+
+    vsub.s16        q4, q4, q7
+    vsub.s16        q5, q5, q7
+
+    ; Load 4x yleft_col
+    sub             r0, r0, #1
+    mov             r12, #4
+
+case_tm_pred_loop
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u16        q0, r3
+    vdup.u16        q1, r4
+    vdup.u16        q2, r5
+    vdup.u16        q3, r6
+
+    vqadd.s16       q8, q0, q4
+    vqadd.s16       q9, q0, q5
+
+    vqadd.s16       q10, q1, q4
+    vqadd.s16       q11, q1, q5
+
+    vqadd.s16       q12, q2, q4
+    vqadd.s16       q13, q2, q5
+
+    vqadd.s16       q14, q3, q4
+    vqadd.s16       q15, q3, q5
+
+    vqshrun.s16     d0, q8, #0
+    vqshrun.s16     d1, q9, #0
+
+    vqshrun.s16     d2, q10, #0
+    vqshrun.s16     d3, q11, #0
+
+    vqshrun.s16     d4, q12, #0
+    vqshrun.s16     d5, q13, #0
+
+    vqshrun.s16     d6, q14, #0
+    vqshrun.s16     d7, q15, #0
+
+    vst1.u8         {q0}, [r1]!
+    vst1.u8         {q1}, [r1]!
+    vst1.u8         {q2}, [r1]!
+    vst1.u8         {q3}, [r1]!
+
+    subs            r12, r12, #1
+    bne             case_tm_pred_loop
+
+    pop             {r4-r8,pc}
+
+    ENDP
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; r0    unsigned char *y_buffer
+; r1    unsigned char *ypred_ptr
+; r2    int y_stride
+; r3    int mode
+; stack int Up
+; stack int Left
+
+|vp8_build_intra_predictors_mby_s_neon_func| PROC
+    push            {r4-r8, lr}
+
+    mov             r1, r0      ;   unsigned char *ypred_ptr = x->dst.y_buffer; //x->Predictor;
+
+    cmp             r3, #0
+    beq             case_dc_pred_s
+    cmp             r3, #1
+    beq             case_v_pred_s
+    cmp             r3, #2
+    beq             case_h_pred_s
+    cmp             r3, #3
+    beq             case_tm_pred_s
+
+case_dc_pred_s
+    ldr             r4, [sp, #24]       ; Up
+    ldr             r5, [sp, #28]       ; Left
+
+    ; Default the DC average to 128
+    mov             r12, #128
+    vdup.u8         q0, r12
+
+    ; Zero out running sum
+    mov             r12, #0
+
+    ; compute shift and jump
+    adds            r7, r4, r5
+    beq             skip_dc_pred_up_left_s
+
+    ; Load above row, if it exists
+    cmp             r4, #0
+    beq             skip_dc_pred_up_s
+
+    sub             r6, r0, r2
+    vld1.8          {q1}, [r6]
+    vpaddl.u8       q2, q1
+    vpaddl.u16      q3, q2
+    vpaddl.u32      q4, q3
+
+    vmov.32         r4, d8[0]
+    vmov.32         r6, d9[0]
+
+    add             r12, r4, r6
+
+    ; Move back to interger registers
+
+skip_dc_pred_up_s
+
+    cmp             r5, #0
+    beq             skip_dc_pred_left_s
+
+    sub             r0, r0, #1
+
+    ; Load left row, if it exists
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0]
+
+    add             r12, r12, r3
+    add             r12, r12, r4
+    add             r12, r12, r5
+    add             r12, r12, r6
+
+skip_dc_pred_left_s
+    add             r7, r7, #3          ; Shift
+    sub             r4, r7, #1
+    mov             r5, #1
+    add             r12, r12, r5, lsl r4
+    mov             r5, r12, lsr r7     ; expected_dc
+
+    vdup.u8         q0, r5
+
+skip_dc_pred_up_left_s
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+
+    pop             {r4-r8,pc}
+case_v_pred_s
+    ; Copy down above row
+    sub             r6, r0, r2
+    vld1.8          {q0}, [r6]
+
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q0}, [r1], r2
+    pop             {r4-r8,pc}
+
+case_h_pred_s
+    ; Load 4x yleft_col
+    sub             r0, r0, #1
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q1}, [r1], r2
+    vst1.u8         {q2}, [r1], r2
+    vst1.u8         {q3}, [r1], r2
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q1}, [r1], r2
+    vst1.u8         {q2}, [r1], r2
+    vst1.u8         {q3}, [r1], r2
+
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q1}, [r1], r2
+    vst1.u8         {q2}, [r1], r2
+    vst1.u8         {q3}, [r1], r2
+
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u8         q0, r3
+    vdup.u8         q1, r4
+    vdup.u8         q2, r5
+    vdup.u8         q3, r6
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q1}, [r1], r2
+    vst1.u8         {q2}, [r1], r2
+    vst1.u8         {q3}, [r1], r2
+
+    pop             {r4-r8,pc}
+
+case_tm_pred_s
+    ; Load yabove_row
+    sub             r3, r0, r2
+    vld1.8          {q8}, [r3]
+
+    ; Load ytop_left
+    sub             r3, r3, #1
+    ldrb            r7, [r3]
+
+    vdup.u16        q7, r7
+
+    ; Compute yabove_row - ytop_left
+    mov             r3, #1
+    vdup.u8         q0, r3
+
+    vmull.u8        q4, d16, d0
+    vmull.u8        q5, d17, d0
+
+    vsub.s16        q4, q4, q7
+    vsub.s16        q5, q5, q7
+
+    ; Load 4x yleft_col
+    sub             r0, r0, #1
+    mov             r12, #4
+
+case_tm_pred_loop_s
+    ldrb            r3, [r0], r2
+    ldrb            r4, [r0], r2
+    ldrb            r5, [r0], r2
+    ldrb            r6, [r0], r2
+    vdup.u16        q0, r3
+    vdup.u16        q1, r4
+    vdup.u16        q2, r5
+    vdup.u16        q3, r6
+
+    vqadd.s16       q8, q0, q4
+    vqadd.s16       q9, q0, q5
+
+    vqadd.s16       q10, q1, q4
+    vqadd.s16       q11, q1, q5
+
+    vqadd.s16       q12, q2, q4
+    vqadd.s16       q13, q2, q5
+
+    vqadd.s16       q14, q3, q4
+    vqadd.s16       q15, q3, q5
+
+    vqshrun.s16     d0, q8, #0
+    vqshrun.s16     d1, q9, #0
+
+    vqshrun.s16     d2, q10, #0
+    vqshrun.s16     d3, q11, #0
+
+    vqshrun.s16     d4, q12, #0
+    vqshrun.s16     d5, q13, #0
+
+    vqshrun.s16     d6, q14, #0
+    vqshrun.s16     d7, q15, #0
+
+    vst1.u8         {q0}, [r1], r2
+    vst1.u8         {q1}, [r1], r2
+    vst1.u8         {q2}, [r1], r2
+    vst1.u8         {q3}, [r1], r2
+
+    subs            r12, r12, #1
+    bne             case_tm_pred_loop_s
+
+    pop             {r4-r8,pc}
+
+    ENDP
+
+
+    END
diff --git a/vp8/common/arm/neon/copymem16x16_neon.asm b/vp8/common/arm/neon/copymem16x16_neon.asm
new file mode 100644 (file)
index 0000000..89d5e10
--- /dev/null
@@ -0,0 +1,58 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_copy_mem16x16_neon|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    Block, CODE, READONLY ; name this block of code
+;void copy_mem16x16_neon( unsigned char *src, int src_stride, unsigned char *dst, int dst_stride)
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_copy_mem16x16_neon| PROC
+
+    vld1.u8     {q0}, [r0], r1
+    vld1.u8     {q1}, [r0], r1
+    vld1.u8     {q2}, [r0], r1
+    vst1.u8     {q0}, [r2], r3
+    vld1.u8     {q3}, [r0], r1
+    vst1.u8     {q1}, [r2], r3
+    vld1.u8     {q4}, [r0], r1
+    vst1.u8     {q2}, [r2], r3
+    vld1.u8     {q5}, [r0], r1
+    vst1.u8     {q3}, [r2], r3
+    vld1.u8     {q6}, [r0], r1
+    vst1.u8     {q4}, [r2], r3
+    vld1.u8     {q7}, [r0], r1
+    vst1.u8     {q5}, [r2], r3
+    vld1.u8     {q8}, [r0], r1
+    vst1.u8     {q6}, [r2], r3
+    vld1.u8     {q9}, [r0], r1
+    vst1.u8     {q7}, [r2], r3
+    vld1.u8     {q10}, [r0], r1
+    vst1.u8     {q8}, [r2], r3
+    vld1.u8     {q11}, [r0], r1
+    vst1.u8     {q9}, [r2], r3
+    vld1.u8     {q12}, [r0], r1
+    vst1.u8     {q10}, [r2], r3
+    vld1.u8     {q13}, [r0], r1
+    vst1.u8     {q11}, [r2], r3
+    vld1.u8     {q14}, [r0], r1
+    vst1.u8     {q12}, [r2], r3
+    vld1.u8     {q15}, [r0], r1
+    vst1.u8     {q13}, [r2], r3
+    vst1.u8     {q14}, [r2], r3
+    vst1.u8     {q15}, [r2], r3
+
+    mov     pc, lr
+
+    ENDP  ; |vp8_copy_mem16x16_neon|
+
+    END
diff --git a/vp8/common/arm/neon/copymem8x4_neon.asm b/vp8/common/arm/neon/copymem8x4_neon.asm
new file mode 100644 (file)
index 0000000..302f734
--- /dev/null
@@ -0,0 +1,33 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_copy_mem8x4_neon|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    Block, CODE, READONLY ; name this block of code
+;void copy_mem8x4_neon( unsigned char *src, int src_stride, unsigned char *dst, int dst_stride)
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_copy_mem8x4_neon| PROC
+    vld1.u8     {d0}, [r0], r1
+    vld1.u8     {d1}, [r0], r1
+    vst1.u8     {d0}, [r2], r3
+    vld1.u8     {d2}, [r0], r1
+    vst1.u8     {d1}, [r2], r3
+    vld1.u8     {d3}, [r0], r1
+    vst1.u8     {d2}, [r2], r3
+    vst1.u8     {d3}, [r2], r3
+
+    mov     pc, lr
+
+    ENDP  ; |vp8_copy_mem8x4_neon|
+
+    END
diff --git a/vp8/common/arm/neon/copymem8x8_neon.asm b/vp8/common/arm/neon/copymem8x8_neon.asm
new file mode 100644 (file)
index 0000000..50d39ef
--- /dev/null
@@ -0,0 +1,42 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_copy_mem8x8_neon|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    Block, CODE, READONLY ; name this block of code
+;void copy_mem8x8_neon( unsigned char *src, int src_stride, unsigned char *dst, int dst_stride)
+;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+|vp8_copy_mem8x8_neon| PROC
+
+    vld1.u8     {d0}, [r0], r1
+    vld1.u8     {d1}, [r0], r1
+    vst1.u8     {d0}, [r2], r3
+    vld1.u8     {d2}, [r0], r1
+    vst1.u8     {d1}, [r2], r3
+    vld1.u8     {d3}, [r0], r1
+    vst1.u8     {d2}, [r2], r3
+    vld1.u8     {d4}, [r0], r1
+    vst1.u8     {d3}, [r2], r3
+    vld1.u8     {d5}, [r0], r1
+    vst1.u8     {d4}, [r2], r3
+    vld1.u8     {d6}, [r0], r1
+    vst1.u8     {d5}, [r2], r3
+    vld1.u8     {d7}, [r0], r1
+    vst1.u8     {d6}, [r2], r3
+    vst1.u8     {d7}, [r2], r3
+
+    mov     pc, lr
+
+    ENDP  ; |vp8_copy_mem8x8_neon|
+
+    END
diff --git a/vp8/common/arm/neon/iwalsh_neon.asm b/vp8/common/arm/neon/iwalsh_neon.asm
new file mode 100644 (file)
index 0000000..4fc744c
--- /dev/null
@@ -0,0 +1,95 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+    EXPORT  |vp8_short_inv_walsh4x4_neon|
+    EXPORT  |vp8_short_inv_walsh4x4_1_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+;short vp8_short_inv_walsh4x4_neon(short *input, short *output)
+|vp8_short_inv_walsh4x4_neon| PROC
+
+    ; read in all four lines of values: d0->d3
+    vldm.64 r0, {q0, q1}
+
+    ; first for loop
+
+    vadd.s16 d4, d0, d3 ;a = [0] + [12]
+    vadd.s16 d5, d1, d2 ;b = [4] + [8]
+    vsub.s16 d6, d1, d2 ;c = [4] - [8]
+    vsub.s16 d7, d0, d3 ;d = [0] - [12]
+
+    vadd.s16 d0, d4, d5 ;a + b
+    vadd.s16 d1, d6, d7 ;c + d
+    vsub.s16 d2, d4, d5 ;a - b
+    vsub.s16 d3, d7, d6 ;d - c
+
+    vtrn.32 d0, d2 ;d0:  0  1  8  9
+                   ;d2:  2  3 10 11
+    vtrn.32 d1, d3 ;d1:  4  5 12 13
+                   ;d3:  6  7 14 15
+
+    vtrn.16 d0, d1 ;d0:  0  4  8 12
+                   ;d1:  1  5  9 13
+    vtrn.16 d2, d3 ;d2:  2  6 10 14
+                   ;d3:  3  7 11 15
+
+    ; second for loop
+
+    vadd.s16 d4, d0, d3 ;a = [0] + [3]
+    vadd.s16 d5, d1, d2 ;b = [1] + [2]
+    vsub.s16 d6, d1, d2 ;c = [1] - [2]
+    vsub.s16 d7, d0, d3 ;d = [0] - [3]
+
+    vadd.s16 d0, d4, d5 ;e = a + b
+    vadd.s16 d1, d6, d7 ;f = c + d
+    vsub.s16 d2, d4, d5 ;g = a - b
+    vsub.s16 d3, d7, d6 ;h = d - c
+
+    vmov.i16 q2, #3
+    vadd.i16 q0, q0, q2 ;e/f += 3
+    vadd.i16 q1, q1, q2 ;g/h += 3
+
+    vshr.s16 q0, q0, #3 ;e/f >> 3
+    vshr.s16 q1, q1, #3 ;g/h >> 3
+
+    vtrn.32 d0, d2
+    vtrn.32 d1, d3
+    vtrn.16 d0, d1
+    vtrn.16 d2, d3
+
+    vstmia.16 r1!, {q0}
+    vstmia.16 r1!, {q1}
+
+    bx lr
+    ENDP    ; |vp8_short_inv_walsh4x4_neon|
+
+
+;short vp8_short_inv_walsh4x4_1_neon(short *input, short *output)
+|vp8_short_inv_walsh4x4_1_neon| PROC
+    ; load a full line into a neon register
+    vld1.16  {q0}, [r0]
+    ; extract first element and replicate
+    vdup.16 q1, d0[0]
+    ; add 3 to all values
+    vmov.i16 q2, #3
+    vadd.i16 q3, q1, q2
+    ; right shift
+    vshr.s16 q3, q3, #3
+    ; write it back
+    vstmia.16 r1!, {q3}
+    vstmia.16 r1!, {q3}
+
+    bx lr
+    ENDP    ; |vp8_short_inv_walsh4x4_1_neon|
+
+    END
diff --git a/vp8/common/arm/neon/loopfilterhorizontaledge_uv_neon.asm b/vp8/common/arm/neon/loopfilterhorizontaledge_uv_neon.asm
new file mode 100644 (file)
index 0000000..e3e8e8a
--- /dev/null
@@ -0,0 +1,205 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_loop_filter_horizontal_edge_uv_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *u,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; stack(r5) unsigned char *v
+
+|vp8_loop_filter_horizontal_edge_uv_neon| PROC
+    sub         r0, r0, r1, lsl #2          ; move u pointer down by 4 lines
+    vld1.s8     {d0[], d1[]}, [r2]          ; flimit
+
+    ldr         r2, [sp, #4]                ; load v ptr
+    ldr         r12, [sp, #0]               ; load thresh pointer
+
+    sub         r2, r2, r1, lsl #2          ; move v pointer down by 4 lines
+
+    vld1.u8     {d6}, [r0], r1              ; p3
+    vld1.u8     {d7}, [r2], r1              ; p3
+    vld1.u8     {d8}, [r0], r1              ; p2
+    vld1.u8     {d9}, [r2], r1              ; p2
+    vld1.u8     {d10}, [r0], r1             ; p1
+    vld1.u8     {d11}, [r2], r1             ; p1
+    vld1.u8     {d12}, [r0], r1             ; p0
+    vld1.u8     {d13}, [r2], r1             ; p0
+    vld1.u8     {d14}, [r0], r1             ; q0
+    vld1.u8     {d15}, [r2], r1             ; q0
+    vld1.u8     {d16}, [r0], r1             ; q1
+    vld1.u8     {d17}, [r2], r1             ; q1
+    vld1.u8     {d18}, [r0], r1             ; q2
+    vld1.u8     {d19}, [r2], r1             ; q2
+    vld1.u8     {d20}, [r0], r1             ; q3
+    vld1.u8     {d21}, [r2], r1             ; q3
+
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+
+    ldr         r12, _lfhuv_coeff_
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q4, q10, q9                 ; abs(q3 - q2)
+    vabd.u8     q9, q6, q7                  ; abs(p0 - q0)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q4, q1, q4                  ; (abs(q3 - q2) > limit)*-1
+    vadd.u8     q0, q0, q0                  ; flimit * 2
+    vadd.u8     q0, q0, q1                  ; flimit * 2 + limit
+
+    vand        q15, q15, q12
+    vand        q10, q10, q11
+    vand        q3, q3, q4
+
+    vabd.u8     q2, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q9, q9, q9                  ; abs(p0 - q0) * 2
+    vshr.u8     q2, q2, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q9, q9, q2                  ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q9, q0, q9                  ; (abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
+
+    vld1.u8     {q0}, [r12]!
+
+    vand        q15, q15, q10
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+;;;;;;;;;;;;;;
+    vld1.u8     {q10}, [r12]!
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q11, d15, d13
+
+    vand        q3, q3, q9
+    vmovl.u8    q4, d20
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vmul.i8    q2, q2, q10                 ; 3 * ( qs0 - ps0)
+    vmul.i16    q2, q2, q4                  ; 3 * ( qs0 - ps0)
+    vmul.i16    q11, q11, q4
+
+    vand        q1, q1, q14                 ; vp8_filter &= hev
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    ;;
+    ;vld1.u8        {q4}, [r12]!            ;no need 7 any more
+
+    ;vqadd.s8   q1, q1, q2
+    vaddw.s8    q2, q2, d2
+    vaddw.s8    q11, q11, d3
+
+    vld1.u8     {q9}, [r12]!
+    ;
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q11
+    ;;
+
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+    ;;
+;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q1, q4                  ; s = vp8_filter & 7
+;   vqadd.s8    q1, q1, q9                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
+    ;;;;
+;   vshr.s8     q1, q1, #3                  ; vp8_filter >>= 3
+;   vceq.i8     q2, q2, q9                  ; s = (s==4)*-1
+    ;;
+;   ;calculate output
+;   vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
+;   vqadd.s8    q11, q2, q1                 ; u = vp8_signed_char_clamp(s + vp8_filter)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; q10=3
+    vqadd.s8    q2, q1, q10                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
+    vqadd.s8    q1, q1, q9                  ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
+    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
+    vshr.s8     q1, q1, #3                  ; Filter1 >>= 3
+
+    ;calculate output
+    vqadd.s8    q11, q6, q2             ; u = vp8_signed_char_clamp(ps0 + Filter2)
+    vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vrshr.s8    q1, q1, #1                  ;round/shift:  vp8_filter += 1; vp8_filter >>= 1
+
+    sub         r0, r0, r1, lsl #2
+    sub         r0, r0, r1, lsl #1
+    ;
+
+    vbic        q1, q1, q14                 ; vp8_filter &= ~hev
+
+    sub         r2, r2, r1, lsl #2
+    sub         r2, r2, r1, lsl #1
+    ;;
+
+    vqadd.s8    q13, q5, q1                 ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
+    ;vqadd.s8   q11, q6, q11                ; u = vp8_signed_char_clamp(ps0 + u)
+    vqsub.s8    q12, q8, q1                 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
+    ;
+
+    veor        q5, q13, q0                 ; *op1 = u^0x80
+    veor        q6, q11, q0                 ; *op0 = u^0x80
+    veor        q7, q10, q0                 ; *oq0 = u^0x80
+    veor        q8, q12, q0                 ; *oq1 = u^0x80
+    ;
+
+    vst1.u8     {d10}, [r0], r1             ; store u op1
+    vst1.u8     {d11}, [r2], r1             ; store v op1
+    vst1.u8     {d12}, [r0], r1             ; store u op0
+    vst1.u8     {d13}, [r2], r1             ; store v op0
+    vst1.u8     {d14}, [r0], r1             ; store u oq0
+    vst1.u8     {d15}, [r2], r1             ; store v oq0
+    vst1.u8     {d16}, [r0], r1             ; store u oq1
+    vst1.u8     {d17}, [r2], r1             ; store v oq1
+
+    bx          lr
+    ENDP        ; |vp8_loop_filter_horizontal_edge_uv_neon|
+
+;-----------------
+    AREA    hloopfilteruv_dat, DATA, READWRITE          ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_lfhuv_coeff_
+    DCD     lfhuv_coeff
+lfhuv_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x01010101, 0x01010101, 0x01010101, 0x01010101
+
+    END
diff --git a/vp8/common/arm/neon/loopfilterhorizontaledge_y_neon.asm b/vp8/common/arm/neon/loopfilterhorizontaledge_y_neon.asm
new file mode 100644 (file)
index 0000000..f11055d
--- /dev/null
@@ -0,0 +1,188 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_loop_filter_horizontal_edge_y_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *s,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; //stack(r5)   int count --unused
+
+|vp8_loop_filter_horizontal_edge_y_neon| PROC
+    sub         r0, r0, r1, lsl #2          ; move src pointer down by 4 lines
+    ldr         r12, [sp, #0]               ; load thresh pointer
+
+    vld1.u8     {q3}, [r0], r1              ; p3
+    vld1.s8     {d0[], d1[]}, [r2]          ; flimit
+    vld1.u8     {q4}, [r0], r1              ; p2
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    vld1.u8     {q5}, [r0], r1              ; p1
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+    vld1.u8     {q6}, [r0], r1              ; p0
+    ldr         r12, _lfhy_coeff_
+    vld1.u8     {q7}, [r0], r1              ; q0
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vld1.u8     {q8}, [r0], r1              ; q1
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vld1.u8     {q9}, [r0], r1              ; q2
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vld1.u8     {q10}, [r0], r1             ; q3
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q4, q10, q9                 ; abs(q3 - q2)
+    vabd.u8     q9, q6, q7                  ; abs(p0 - q0)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q4, q1, q4                  ; (abs(q3 - q2) > limit)*-1
+    vadd.u8     q0, q0, q0                  ; flimit * 2
+    vadd.u8     q0, q0, q1                  ; flimit * 2 + limit
+
+    vand        q15, q15, q12
+    vand        q10, q10, q11
+    vand        q3, q3, q4
+
+    vabd.u8     q2, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q9, q9, q9                  ; abs(p0 - q0) * 2
+    vshr.u8     q2, q2, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q9, q9, q2                  ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q9, q0, q9                  ; (abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
+
+    vld1.u8     {q0}, [r12]!
+
+    vand        q15, q15, q10
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+;;;;;;;;;;;;;;
+    vld1.u8     {q10}, [r12]!
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q11, d15, d13
+
+    vand        q3, q3, q9
+    vmovl.u8    q4, d20
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vmul.i8    q2, q2, q10                 ; 3 * ( qs0 - ps0)
+    vmul.i16    q2, q2, q4                  ; 3 * ( qs0 - ps0)
+    vmul.i16    q11, q11, q4
+
+    vand        q1, q1, q14                 ; vp8_filter &= hev
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    ;;
+    ;vld1.u8        {q4}, [r12]!            ;no need 7 any more
+
+    ;vqadd.s8   q1, q1, q2
+    vaddw.s8    q2, q2, d2
+    vaddw.s8    q11, q11, d3
+
+    vld1.u8     {q9}, [r12]!
+    ;
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q11
+    ;;
+
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+    ;;
+;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q1, q4                  ; s = vp8_filter & 7
+;   vqadd.s8    q1, q1, q9                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
+    ;;;;
+;   vshr.s8     q1, q1, #3                  ; vp8_filter >>= 3
+;   vceq.i8     q2, q2, q9                  ; s = (s==4)*-1
+    ;;
+;   ;calculate output
+;   vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
+;   vqadd.s8    q11, q2, q1                 ; u = vp8_signed_char_clamp(s + vp8_filter)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; q10=3
+    vqadd.s8    q2, q1, q10                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
+    vqadd.s8    q1, q1, q9                  ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
+    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
+    vshr.s8     q1, q1, #3                  ; Filter1 >>= 3
+
+    ;calculate output
+    vqadd.s8    q11, q6, q2                 ; u = vp8_signed_char_clamp(ps0 + Filter2)
+    vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vrshr.s8    q1, q1, #1                  ;round/shift:  vp8_filter += 1; vp8_filter >>= 1
+
+    sub         r0, r0, r1, lsl #2
+    sub         r0, r0, r1, lsl #1
+    ;
+
+    vbic        q1, q1, q14                 ; vp8_filter &= ~hev
+    ;
+    add         r2, r1, r0
+
+    vqadd.s8    q13, q5, q1                 ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
+    ;vqadd.s8   q11, q6, q11                ; u = vp8_signed_char_clamp(ps0 + u)
+    vqsub.s8    q12, q8, q1                 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
+
+    add         r3, r2, r1
+
+    veor        q5, q13, q0                 ; *op1 = u^0x80
+    veor        q6, q11, q0                 ; *op0 = u^0x80
+    veor        q7, q10, q0                 ; *oq0 = u^0x80
+    veor        q8, q12, q0                 ; *oq1 = u^0x80
+
+    add         r12, r3, r1
+
+    vst1.u8     {q5}, [r0]                  ; store op1
+    vst1.u8     {q6}, [r2]                  ; store op0
+    vst1.u8     {q7}, [r3]                  ; store oq0
+    vst1.u8     {q8}, [r12]                 ; store oq1
+
+    bx          lr
+    ENDP        ; |vp8_loop_filter_horizontal_edge_y_neon|
+
+;-----------------
+    AREA    hloopfiltery_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_lfhy_coeff_
+    DCD     lfhy_coeff
+lfhy_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x01010101, 0x01010101, 0x01010101, 0x01010101
+
+    END
diff --git a/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.asm b/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.asm
new file mode 100644 (file)
index 0000000..6d74fab
--- /dev/null
@@ -0,0 +1,117 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_loop_filter_simple_horizontal_edge_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *s,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; //stack(r5)   int count --unused
+
+|vp8_loop_filter_simple_horizontal_edge_neon| PROC
+    sub         r0, r0, r1, lsl #1          ; move src pointer down by 2 lines
+
+    ldr         r12, _lfhy_coeff_
+    vld1.u8     {q5}, [r0], r1              ; p1
+    vld1.s8     {d2[], d3[]}, [r2]          ; flimit
+    vld1.s8     {d26[], d27[]}, [r3]        ; limit -> q13
+    vld1.u8     {q6}, [r0], r1              ; p0
+    vld1.u8     {q0}, [r12]!                ; 0x80
+    vld1.u8     {q7}, [r0], r1              ; q0
+    vld1.u8     {q10}, [r12]!               ; 0x03
+    vld1.u8     {q8}, [r0]                  ; q1
+
+    ;vp8_filter_mask() function
+    vabd.u8     q15, q6, q7                 ; abs(p0 - q0)
+    vabd.u8     q14, q5, q8                 ; abs(p1 - q1)
+    vqadd.u8    q15, q15, q15               ; abs(p0 - q0) * 2
+    vshr.u8     q14, q14, #1                ; abs(p1 - q1) / 2
+    vqadd.u8    q15, q15, q14               ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+
+    vadd.u8     q1, q1, q1                  ; flimit * 2
+    vadd.u8     q1, q1, q13                 ; flimit * 2 + limit
+    vcge.u8     q15, q1, q15                ; (abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
+
+;;;;;;;;;;
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q3, d15, d13
+
+    vqsub.s8    q4, q5, q8                  ; q4: vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+
+    ;vmul.i8    q2, q2, q10                 ;  3 * ( qs0 - ps0)
+    vadd.s16    q11, q2, q2                 ;  3 * ( qs0 - ps0)
+    vadd.s16    q12, q3, q3
+
+    vld1.u8     {q9}, [r12]!                ; 0x04
+
+    vadd.s16    q2, q2, q11
+    vadd.s16    q3, q3, q12
+
+    vaddw.s8    q2, q2, d8                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q3, q3, d9
+
+    ;vqadd.s8   q4, q4, q2                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d8, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d9, q3
+;;;;;;;;;;;;;
+
+    vand        q4, q4, q15                 ; vp8_filter &= mask
+
+    vqadd.s8    q2, q4, q10                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
+    vqadd.s8    q4, q4, q9                  ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
+    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
+    vshr.s8     q4, q4, #3                  ; Filter1 >>= 3
+
+    sub         r0, r0, r1, lsl #1
+
+    ;calculate output
+    vqadd.s8    q11, q6, q2                 ; u = vp8_signed_char_clamp(ps0 + Filter2)
+    vqsub.s8    q10, q7, q4                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
+
+    add         r3, r0, r1
+
+    veor        q6, q11, q0                 ; *op0 = u^0x80
+    veor        q7, q10, q0                 ; *oq0 = u^0x80
+
+    vst1.u8     {q6}, [r0]                  ; store op0
+    vst1.u8     {q7}, [r3]                  ; store oq0
+
+    bx          lr
+    ENDP        ; |vp8_loop_filter_simple_horizontal_edge_neon|
+
+;-----------------
+    AREA    hloopfiltery_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_lfhy_coeff_
+    DCD     lfhy_coeff
+lfhy_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+
+    END
diff --git a/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.asm b/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.asm
new file mode 100644 (file)
index 0000000..2bb6222
--- /dev/null
@@ -0,0 +1,158 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_loop_filter_simple_vertical_edge_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh should be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *s,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; //stack(r5)   int count --unused
+
+|vp8_loop_filter_simple_vertical_edge_neon| PROC
+    sub         r0, r0, #2                  ; move src pointer down by 2 columns
+
+    vld4.8      {d6[0], d7[0], d8[0], d9[0]}, [r0], r1
+    vld1.s8     {d2[], d3[]}, [r2]          ; flimit
+    vld1.s8     {d26[], d27[]}, [r3]        ; limit -> q13
+    vld4.8      {d6[1], d7[1], d8[1], d9[1]}, [r0], r1
+    ldr         r12, _vlfy_coeff_
+    vld4.8      {d6[2], d7[2], d8[2], d9[2]}, [r0], r1
+    vld4.8      {d6[3], d7[3], d8[3], d9[3]}, [r0], r1
+    vld4.8      {d6[4], d7[4], d8[4], d9[4]}, [r0], r1
+    vld4.8      {d6[5], d7[5], d8[5], d9[5]}, [r0], r1
+    vld4.8      {d6[6], d7[6], d8[6], d9[6]}, [r0], r1
+    vld4.8      {d6[7], d7[7], d8[7], d9[7]}, [r0], r1
+
+    vld4.8      {d10[0], d11[0], d12[0], d13[0]}, [r0], r1
+    vld1.u8     {q0}, [r12]!                ; 0x80
+    vld4.8      {d10[1], d11[1], d12[1], d13[1]}, [r0], r1
+    vld1.u8     {q11}, [r12]!               ; 0x03
+    vld4.8      {d10[2], d11[2], d12[2], d13[2]}, [r0], r1
+    vld1.u8     {q12}, [r12]!               ; 0x04
+    vld4.8      {d10[3], d11[3], d12[3], d13[3]}, [r0], r1
+    vld4.8      {d10[4], d11[4], d12[4], d13[4]}, [r0], r1
+    vld4.8      {d10[5], d11[5], d12[5], d13[5]}, [r0], r1
+    vld4.8      {d10[6], d11[6], d12[6], d13[6]}, [r0], r1
+    vld4.8      {d10[7], d11[7], d12[7], d13[7]}, [r0], r1
+
+    vswp        d7, d10
+    vswp        d12, d9
+    ;vswp       q4, q5                      ; p1:q3, p0:q5, q0:q4, q1:q6
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    sub         r0, r0, r1, lsl #4
+    vabd.u8     q15, q5, q4                 ; abs(p0 - q0)
+    vabd.u8     q14, q3, q6                 ; abs(p1 - q1)
+    vqadd.u8    q15, q15, q15               ; abs(p0 - q0) * 2
+    vshr.u8     q14, q14, #1                ; abs(p1 - q1) / 2
+    vqadd.u8    q15, q15, q14               ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+
+    veor        q4, q4, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q3, q3, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q6, q6, q0                  ; qs1: q1 offset to convert to a signed value
+
+    vadd.u8     q1, q1, q1                  ; flimit * 2
+    vadd.u8     q1, q1, q13                 ; flimit * 2 + limit
+    vcge.u8     q15, q1, q15                ; abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
+
+    ;vp8_filter() function
+;;;;;;;;;;
+    ;vqsub.s8   q2, q5, q4                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d8, d10                 ; ( qs0 - ps0)
+    vsubl.s8    q13, d9, d11
+
+    vqsub.s8    q1, q3, q6                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+
+    ;vmul.i8    q2, q2, q11                 ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vadd.s16    q10, q2, q2                 ;  3 * ( qs0 - ps0)
+    vadd.s16    q14, q13, q13
+    vadd.s16    q2, q2, q10
+    vadd.s16    q13, q13, q14
+
+    ;vqadd.s8   q1, q1, q2
+    vaddw.s8    q2, q2, d2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q13, q13, d3
+
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q13
+
+    add         r0, r0, #1
+    add         r2, r0, r1
+;;;;;;;;;;;
+
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+
+    vqadd.s8    q2, q1, q11                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
+    vqadd.s8    q1, q1, q12                 ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
+    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
+    vshr.s8     q1, q1, #3                  ; Filter1 >>= 3
+
+    ;calculate output
+    vqsub.s8    q10, q4, q1                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
+    vqadd.s8    q11, q5, q2                 ; u = vp8_signed_char_clamp(ps0 + Filter2)
+
+    veor        q7, q10, q0                 ; *oq0 = u^0x80
+    veor        q6, q11, q0                 ; *op0 = u^0x80
+
+    add         r3, r2, r1
+    vswp        d13, d14
+    add         r12, r3, r1
+
+    ;store op1, op0, oq0, oq1
+    vst2.8      {d12[0], d13[0]}, [r0]
+    vst2.8      {d12[1], d13[1]}, [r2]
+    vst2.8      {d12[2], d13[2]}, [r3]
+    vst2.8      {d12[3], d13[3]}, [r12], r1
+    add         r0, r12, r1
+    vst2.8      {d12[4], d13[4]}, [r12]
+    vst2.8      {d12[5], d13[5]}, [r0], r1
+    add         r2, r0, r1
+    vst2.8      {d12[6], d13[6]}, [r0]
+    vst2.8      {d12[7], d13[7]}, [r2], r1
+    add         r3, r2, r1
+    vst2.8      {d14[0], d15[0]}, [r2]
+    vst2.8      {d14[1], d15[1]}, [r3], r1
+    add         r12, r3, r1
+    vst2.8      {d14[2], d15[2]}, [r3]
+    vst2.8      {d14[3], d15[3]}, [r12], r1
+    add         r0, r12, r1
+    vst2.8      {d14[4], d15[4]}, [r12]
+    vst2.8      {d14[5], d15[5]}, [r0], r1
+    add         r2, r0, r1
+    vst2.8      {d14[6], d15[6]}, [r0]
+    vst2.8      {d14[7], d15[7]}, [r2]
+
+    bx          lr
+    ENDP        ; |vp8_loop_filter_simple_vertical_edge_neon|
+
+;-----------------
+    AREA    vloopfiltery_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_vlfy_coeff_
+    DCD     vlfy_coeff
+vlfy_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+
+    END
diff --git a/vp8/common/arm/neon/loopfilterverticaledge_uv_neon.asm b/vp8/common/arm/neon/loopfilterverticaledge_uv_neon.asm
new file mode 100644 (file)
index 0000000..d79cc68
--- /dev/null
@@ -0,0 +1,231 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_loop_filter_vertical_edge_uv_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *u,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; stack(r5) unsigned char *v
+
+|vp8_loop_filter_vertical_edge_uv_neon| PROC
+    sub         r0, r0, #4          ; move u pointer down by 4 columns
+    vld1.s8     {d0[], d1[]}, [r2]          ; flimit
+
+    ldr         r2, [sp, #4]                ; load v ptr
+    ldr         r12, [sp, #0]               ; load thresh pointer
+
+    sub         r2, r2, #4          ; move v pointer down by 4 columns
+
+    vld1.u8     {d6}, [r0], r1              ;load u data
+    vld1.u8     {d7}, [r2], r1              ;load v data
+    vld1.u8     {d8}, [r0], r1
+    vld1.u8     {d9}, [r2], r1
+    vld1.u8     {d10}, [r0], r1
+    vld1.u8     {d11}, [r2], r1
+    vld1.u8     {d12}, [r0], r1
+    vld1.u8     {d13}, [r2], r1
+    vld1.u8     {d14}, [r0], r1
+    vld1.u8     {d15}, [r2], r1
+    vld1.u8     {d16}, [r0], r1
+    vld1.u8     {d17}, [r2], r1
+    vld1.u8     {d18}, [r0], r1
+    vld1.u8     {d19}, [r2], r1
+    vld1.u8     {d20}, [r0], r1
+    vld1.u8     {d21}, [r2], r1
+
+    ;transpose to 8x16 matrix
+    vtrn.32     q3, q7
+    vtrn.32     q4, q8
+    vtrn.32     q5, q9
+    vtrn.32     q6, q10
+
+    vtrn.16     q3, q5
+    vtrn.16     q4, q6
+    vtrn.16     q7, q9
+    vtrn.16     q8, q10
+
+    vtrn.8      q3, q4
+    vtrn.8      q5, q6
+    vtrn.8      q7, q8
+    vtrn.8      q9, q10
+
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+
+    ldr         r12, _vlfuv_coeff_
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q4, q10, q9                 ; abs(q3 - q2)
+    vabd.u8     q9, q6, q7                  ; abs(p0 - q0)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q4, q1, q4                  ; (abs(q3 - q2) > limit)*-1
+    vadd.u8     q0, q0, q0                  ; flimit * 2
+    vadd.u8     q0, q0, q1                  ; flimit * 2 + limit
+
+    vand        q15, q15, q12
+    vand        q10, q10, q11
+    vand        q3, q3, q4
+
+    vabd.u8     q2, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q9, q9, q9                  ; abs(p0 - q0) * 2
+    vshr.u8     q2, q2, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q9, q9, q2                  ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q9, q0, q9                  ; (abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
+
+    vld1.u8     {q0}, [r12]!
+
+    vand        q15, q15, q10
+
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+;;;;;;;;;;;;;;
+    vld1.u8     {q10}, [r12]!
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q11, d15, d13
+
+    vand        q3, q3, q9
+    vmovl.u8    q4, d20
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vmul.i8    q2, q2, q10                 ; 3 * ( qs0 - ps0)
+    vmul.i16    q2, q2, q4                  ; 3 * ( qs0 - ps0)
+    vmul.i16    q11, q11, q4
+
+    vand        q1, q1, q14                 ; vp8_filter &= hev
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    ;;
+    ;vld1.u8        {q4}, [r12]!            ;no need 7 any more
+
+    ;vqadd.s8   q1, q1, q2
+    vaddw.s8    q2, q2, d2
+    vaddw.s8    q11, q11, d3
+
+    vld1.u8     {q9}, [r12]!
+    ;
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q11
+    ;;
+
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+    ;;
+;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q1, q4                  ; s = vp8_filter & 7
+;   vqadd.s8    q1, q1, q9                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
+    ;;;;
+;   vshr.s8     q1, q1, #3                  ; vp8_filter >>= 3
+;   vceq.i8     q2, q2, q9                  ; s = (s==4)*-1
+    ;;
+;   ;calculate output
+;   vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
+;   vqadd.s8    q11, q2, q1                 ; u = vp8_signed_char_clamp(s + vp8_filter)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; q10=3
+    vqadd.s8    q2, q1, q10                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
+    vqadd.s8    q1, q1, q9                  ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
+    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
+    vshr.s8     q1, q1, #3                  ; Filter1 >>= 3
+    ;calculate output
+    vqadd.s8    q11, q6, q2             ; u = vp8_signed_char_clamp(ps0 + Filter2)
+    vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vrshr.s8    q1, q1, #1                  ;round/shift:  vp8_filter += 1; vp8_filter >>= 1
+
+    sub         r0, r0, r1, lsl #3
+    add         r0, r0, #2
+
+    vbic        q1, q1, q14                 ; vp8_filter &= ~hev
+
+    sub         r2, r2, r1, lsl #3
+    add         r2, r2, #2
+
+    vqadd.s8    q13, q5, q1                 ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
+    ;vqadd.s8   q11, q6, q11                ; u = vp8_signed_char_clamp(ps0 + u)
+    vqsub.s8    q12, q8, q1                 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
+
+    veor        q7, q10, q0                 ; *oq0 = u^0x80
+    veor        q5, q13, q0                 ; *op1 = u^0x80
+    veor        q6, q11, q0                 ; *op0 = u^0x80
+    veor        q8, q12, q0                 ; *oq1 = u^0x80
+
+    vswp        d12, d11
+    vswp        d16, d13
+    vswp        d14, d12
+    vswp        d16, d15
+
+    ;store op1, op0, oq0, oq1
+    vst4.8      {d10[0], d11[0], d12[0], d13[0]}, [r0], r1
+    vst4.8      {d14[0], d15[0], d16[0], d17[0]}, [r2], r1
+    vst4.8      {d10[1], d11[1], d12[1], d13[1]}, [r0], r1
+    vst4.8      {d14[1], d15[1], d16[1], d17[1]}, [r2], r1
+    vst4.8      {d10[2], d11[2], d12[2], d13[2]}, [r0], r1
+    vst4.8      {d14[2], d15[2], d16[2], d17[2]}, [r2], r1
+    vst4.8      {d10[3], d11[3], d12[3], d13[3]}, [r0], r1
+    vst4.8      {d14[3], d15[3], d16[3], d17[3]}, [r2], r1
+    vst4.8      {d10[4], d11[4], d12[4], d13[4]}, [r0], r1
+    vst4.8      {d14[4], d15[4], d16[4], d17[4]}, [r2], r1
+    vst4.8      {d10[5], d11[5], d12[5], d13[5]}, [r0], r1
+    vst4.8      {d14[5], d15[5], d16[5], d17[5]}, [r2], r1
+    vst4.8      {d10[6], d11[6], d12[6], d13[6]}, [r0], r1
+    vst4.8      {d14[6], d15[6], d16[6], d17[6]}, [r2], r1
+    vst4.8      {d10[7], d11[7], d12[7], d13[7]}, [r0], r1
+    vst4.8      {d14[7], d15[7], d16[7], d17[7]}, [r2], r1
+
+    bx          lr
+    ENDP        ; |vp8_loop_filter_vertical_edge_uv_neon|
+
+;-----------------
+    AREA    vloopfilteruv_dat, DATA, READWRITE          ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_vlfuv_coeff_
+    DCD     vlfuv_coeff
+vlfuv_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x01010101, 0x01010101, 0x01010101, 0x01010101
+
+    END
diff --git a/vp8/common/arm/neon/loopfilterverticaledge_y_neon.asm b/vp8/common/arm/neon/loopfilterverticaledge_y_neon.asm
new file mode 100644 (file)
index 0000000..3a230a9
--- /dev/null
@@ -0,0 +1,235 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_loop_filter_vertical_edge_y_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *s,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; //stack(r5)   int count --unused
+
+|vp8_loop_filter_vertical_edge_y_neon| PROC
+    sub         r0, r0, #4                  ; move src pointer down by 4 columns
+    ldr         r12, [sp, #0]               ; load thresh pointer
+
+    vld1.u8     {d6}, [r0], r1              ; load first 8-line src data
+    vld1.s8     {d0[], d1[]}, [r2]          ; flimit
+    vld1.u8     {d8}, [r0], r1
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    vld1.u8     {d10}, [r0], r1
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+    vld1.u8     {d12}, [r0], r1
+    ldr         r12, _vlfy_coeff_
+    vld1.u8     {d14}, [r0], r1
+    vld1.u8     {d16}, [r0], r1
+    vld1.u8     {d18}, [r0], r1
+    vld1.u8     {d20}, [r0], r1
+
+    vld1.u8     {d7}, [r0], r1              ; load second 8-line src data
+    vld1.u8     {d9}, [r0], r1
+    vld1.u8     {d11}, [r0], r1
+    vld1.u8     {d13}, [r0], r1
+    vld1.u8     {d15}, [r0], r1
+    vld1.u8     {d17}, [r0], r1
+    vld1.u8     {d19}, [r0], r1
+    vld1.u8     {d21}, [r0], r1
+
+    ;transpose to 8x16 matrix
+    vtrn.32     q3, q7
+    vtrn.32     q4, q8
+    vtrn.32     q5, q9
+    vtrn.32     q6, q10
+
+    vtrn.16     q3, q5
+    vtrn.16     q4, q6
+    vtrn.16     q7, q9
+    vtrn.16     q8, q10
+
+    vtrn.8      q3, q4
+    vtrn.8      q5, q6
+    vtrn.8      q7, q8
+    vtrn.8      q9, q10
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q4, q10, q9                 ; abs(q3 - q2)
+    vabd.u8     q9, q6, q7                  ; abs(p0 - q0)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q4, q1, q4                  ; (abs(q3 - q2) > limit)*-1
+    vadd.u8     q0, q0, q0                  ; flimit * 2
+    vadd.u8     q0, q0, q1                  ; flimit * 2 + limit
+
+    vand        q15, q15, q12
+    vand        q10, q10, q11
+    vand        q3, q3, q4
+
+    vabd.u8     q2, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q9, q9, q9                  ; abs(p0 - q0) * 2
+    vshr.u8     q2, q2, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q9, q9, q2                  ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q9, q0, q9                  ; (abs(p0 - q0)*2 + abs(p1-q1)/2 > flimit*2 + limit)*-1
+
+    vld1.u8     {q0}, [r12]!
+
+    vand        q15, q15, q10
+
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+;;;;;;;;;;;;;;
+    vld1.u8     {q10}, [r12]!
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q11, d15, d13
+
+    vand        q3, q3, q9
+    vmovl.u8    q4, d20
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vmul.i8    q2, q2, q10                 ; 3 * ( qs0 - ps0)
+    vmul.i16    q2, q2, q4                  ; 3 * ( qs0 - ps0)
+    vmul.i16    q11, q11, q4
+
+    vand        q1, q1, q14                 ; vp8_filter &= hev
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    ;;
+    ;vld1.u8        {q4}, [r12]!            ;no need 7 any more
+
+    ;vqadd.s8   q1, q1, q2
+    vaddw.s8    q2, q2, d2
+    vaddw.s8    q11, q11, d3
+
+    vld1.u8     {q9}, [r12]!
+    ;
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q11
+    ;;
+
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+    ;;
+;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q1, q4                  ; s = vp8_filter & 7
+;   vqadd.s8    q1, q1, q9                  ; vp8_filter = vp8_signed_char_clamp(vp8_filter+4)
+    ;;;;
+;   vshr.s8     q1, q1, #3                  ; vp8_filter >>= 3
+;   vceq.i8     q2, q2, q9                  ; s = (s==4)*-1
+    ;;
+;   ;calculate output
+;   vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - vp8_filter)
+;   vqadd.s8    q11, q2, q1                 ; u = vp8_signed_char_clamp(s + vp8_filter)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; q10=3
+    vqadd.s8    q2, q1, q10                 ; Filter2 = vp8_signed_char_clamp(vp8_filter+3)
+    vqadd.s8    q1, q1, q9                  ; Filter1 = vp8_signed_char_clamp(vp8_filter+4)
+    vshr.s8     q2, q2, #3                  ; Filter2 >>= 3
+    vshr.s8     q1, q1, #3                  ; Filter1 >>= 3
+    ;calculate output
+    vqadd.s8    q11, q6, q2             ; u = vp8_signed_char_clamp(ps0 + Filter2)
+    vqsub.s8    q10, q7, q1                 ; u = vp8_signed_char_clamp(qs0 - Filter1)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vrshr.s8    q1, q1, #1                  ;round/shift:  vp8_filter += 1; vp8_filter >>= 1
+
+    sub         r0, r0, r1, lsl #4
+    add         r0, r0, #2
+    ;
+
+    vbic        q1, q1, q14                 ; vp8_filter &= ~hev
+    add         r2, r0, r1
+    ;
+
+    vqadd.s8    q13, q5, q1                 ; u = vp8_signed_char_clamp(ps1 + vp8_filter)
+    ;vqadd.s8   q11, q6, q11                ; u = vp8_signed_char_clamp(ps0 + u)
+    vqsub.s8    q12, q8, q1                 ; u = vp8_signed_char_clamp(qs1 - vp8_filter)
+
+    veor        q7, q10, q0                 ; *oq0 = u^0x80
+    veor        q5, q13, q0                 ; *op1 = u^0x80
+    veor        q6, q11, q0                 ; *op0 = u^0x80
+    veor        q8, q12, q0                 ; *oq1 = u^0x80
+    add         r3, r2, r1
+    ;
+    vswp        d12, d11
+    vswp        d16, d13
+    add         r12, r3, r1
+    vswp        d14, d12
+    vswp        d16, d15
+
+    ;store op1, op0, oq0, oq1
+    vst4.8      {d10[0], d11[0], d12[0], d13[0]}, [r0]
+    vst4.8      {d10[1], d11[1], d12[1], d13[1]}, [r2]
+    vst4.8      {d10[2], d11[2], d12[2], d13[2]}, [r3]
+    vst4.8      {d10[3], d11[3], d12[3], d13[3]}, [r12], r1
+    add         r0, r12, r1
+    vst4.8      {d10[4], d11[4], d12[4], d13[4]}, [r12]
+    vst4.8      {d10[5], d11[5], d12[5], d13[5]}, [r0], r1
+    add         r2, r0, r1
+    vst4.8      {d10[6], d11[6], d12[6], d13[6]}, [r0]
+    vst4.8      {d10[7], d11[7], d12[7], d13[7]}, [r2], r1
+    add         r3, r2, r1
+    vst4.8      {d14[0], d15[0], d16[0], d17[0]}, [r2]
+    vst4.8      {d14[1], d15[1], d16[1], d17[1]}, [r3], r1
+    add         r12, r3, r1
+    vst4.8      {d14[2], d15[2], d16[2], d17[2]}, [r3]
+    vst4.8      {d14[3], d15[3], d16[3], d17[3]}, [r12], r1
+    add         r0, r12, r1
+    vst4.8      {d14[4], d15[4], d16[4], d17[4]}, [r12]
+    vst4.8      {d14[5], d15[5], d16[5], d17[5]}, [r0], r1
+    add         r2, r0, r1
+    vst4.8      {d14[6], d15[6], d16[6], d17[6]}, [r0]
+    vst4.8      {d14[7], d15[7], d16[7], d17[7]}, [r2]
+
+    bx          lr
+    ENDP        ; |vp8_loop_filter_vertical_edge_y_neon|
+
+;-----------------
+    AREA    vloopfiltery_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_vlfy_coeff_
+    DCD     vlfy_coeff
+vlfy_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x01010101, 0x01010101, 0x01010101, 0x01010101
+
+    END
diff --git a/vp8/common/arm/neon/mbloopfilterhorizontaledge_uv_neon.asm b/vp8/common/arm/neon/mbloopfilterhorizontaledge_uv_neon.asm
new file mode 100644 (file)
index 0000000..86eddaa
--- /dev/null
@@ -0,0 +1,257 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_mbloop_filter_horizontal_edge_uv_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *u,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; stack(r5) unsigned char *v
+|vp8_mbloop_filter_horizontal_edge_uv_neon| PROC
+    sub         r0, r0, r1, lsl #2          ; move u pointer down by 4 lines
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    ldr         r3, [sp, #4]                ; load v ptr
+    ldr         r12, [sp, #0]               ; load thresh pointer
+    sub         r3, r3, r1, lsl #2          ; move v pointer down by 4 lines
+
+    vld1.u8     {d6}, [r0], r1              ; p3
+    vld1.u8     {d7}, [r3], r1              ; p3
+    vld1.u8     {d8}, [r0], r1              ; p2
+    vld1.u8     {d9}, [r3], r1              ; p2
+    vld1.u8     {d10}, [r0], r1             ; p1
+    vld1.u8     {d11}, [r3], r1             ; p1
+    vld1.u8     {d12}, [r0], r1             ; p0
+    vld1.u8     {d13}, [r3], r1             ; p0
+    vld1.u8     {d14}, [r0], r1             ; q0
+    vld1.u8     {d15}, [r3], r1             ; q0
+    vld1.u8     {d16}, [r0], r1             ; q1
+    vld1.u8     {d17}, [r3], r1             ; q1
+    vld1.u8     {d18}, [r0], r1             ; q2
+    vld1.u8     {d19}, [r3], r1             ; q2
+    vld1.u8     {d20}, [r0], r1             ; q3
+    vld1.u8     {d21}, [r3], r1             ; q3
+
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+
+    ldr         r12, _mbhlfuv_coeff_
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q0, q10, q9                 ; abs(q3 - q2)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q0, q1, q0                  ; (abs(q3 - q2) > limit)*-1
+
+    vand        q15, q15, q12
+
+    vabd.u8     q12, q6, q7                 ; abs(p0 - q0)
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vld1.s8     {d4[], d5[]}, [r2]          ; flimit
+
+    vand        q10, q10, q11
+    vand        q3, q3, q0
+
+    vld1.u8     {q0}, [r12]!
+
+    vadd.u8     q2, q2, q2                  ; flimit * 2
+    vadd.u8     q2, q2, q1                  ; flimit * 2 +  limit
+
+    vabd.u8     q1, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q12, q12, q12               ; abs(p0 - q0) * 2
+    vshr.u8     q1, q1, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q12, q12, q1                ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q12, q2, q12                ; (abs(p0 - q0)*2 + abs(p1 - q1)/2 > flimit*2 + limit)*-1
+
+    vand        q15, q15, q10
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+    veor        q4, q4, q0                  ; ps2: p2 offset to convert to a signed value
+    veor        q9, q9, q0                  ; qs2: q2 offset to convert to a signed value
+;;;;;;;;;;;;;
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q13, d15, d13
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+
+    ;vadd.s8    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q11, q13, q13
+
+    vand        q3, q3, q12
+
+    ;vadd.s8    q2, q2, q10
+    vadd.s16    q2, q2, q10
+    vadd.s16    q13, q13, q11
+
+    vld1.u8     {q12}, [r12]!               ;#3
+
+    ;vqadd.s8   q1, q1, q2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q2, q2, d2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q13, q13, d3
+
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    vld1.u8     {q11}, [r12]!               ;#4
+
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q13
+
+;;;;;;;;;;;;;;
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+
+    vld1.u8     {q15}, [r12]!               ;#63
+    ;
+    vand        q13, q1, q14                ; Filter2: q13; Filter2 &= hev
+
+    vld1.u8     {d7}, [r12]!                ;#9
+    ;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q13, q12                ; s = Filter2 & 7
+
+;   vqadd.s8    q13, q13, q11               ; Filter2 = vp8_signed_char_clamp(Filter2+4)
+;   vld1.u8     {d6}, [r12]!                ;#18
+
+;   sub         r0, r0, r1, lsl #3
+;   sub         r3, r3, r1, lsl #3
+
+;   vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+;   vceq.i8     q2, q2, q11                 ; s = (s==4)*-1
+
+;   add         r0, r0, r1
+;   add         r3, r3, r1
+
+;   vqsub.s8    q7, q7, q13                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
+;   vqadd.s8    q11, q2, q13                ; u = vp8_signed_char_clamp(s + Filter2)
+
+;   vld1.u8     {d5}, [r12]!                ;#27
+;   vmov        q10, q15
+;   vmov        q12, q15
+
+;   vqadd.s8    q6, q6, q11                 ; ps0 = vp8_signed_char_clamp(ps0 + u)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    vqadd.s8    q2, q13, q11                ; Filter1 = vp8_signed_char_clamp(Filter2+4)
+    vqadd.s8    q13, q13, q12               ; Filter2 = vp8_signed_char_clamp(Filter2+3)
+
+    vld1.u8     {d6}, [r12]!                ;#18
+
+    sub         r0, r0, r1, lsl #3
+    sub         r3, r3, r1, lsl #3
+
+    vshr.s8     q2, q2, #3                  ; Filter1 >>= 3
+    vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+
+    vmov        q10, q15
+    vmov        q12, q15
+
+    vqsub.s8    q7, q7, q2                  ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
+
+    vld1.u8     {d5}, [r12]!                ;#27
+
+    add         r0, r0, r1
+    add         r3, r3, r1
+
+    vqadd.s8    q6, q6, q13                 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vbic        q1, q1, q14                 ; Filter2: q1; vp8_filter &= ~hev; Filter2 = vp8_filter
+
+    ; roughly 1/7th difference across boundary
+    ; roughly 2/7th difference across boundary
+    ; roughly 3/7th difference across boundary
+    vmov        q11, q15
+    vmov        q13, q15
+    vmov        q14, q15
+
+    vmlal.s8    q10, d2, d7                 ; Filter2 * 9
+    vmlal.s8    q11, d3, d7
+    vmlal.s8    q12, d2, d6                 ; Filter2 * 18
+    vmlal.s8    q13, d3, d6
+    vmlal.s8    q14, d2, d5                 ; Filter2 * 27
+    vmlal.s8    q15, d3, d5
+    vqshrn.s16  d20, q10, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
+    vqshrn.s16  d21, q11, #7
+    vqshrn.s16  d24, q12, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
+    vqshrn.s16  d25, q13, #7
+    vqshrn.s16  d28, q14, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
+    vqshrn.s16  d29, q15, #7
+
+    vqsub.s8    q11, q9, q10                ; s = vp8_signed_char_clamp(qs2 - u)
+    vqadd.s8    q10, q4, q10                ; s = vp8_signed_char_clamp(ps2 + u)
+    vqsub.s8    q13, q8, q12                ; s = vp8_signed_char_clamp(qs1 - u)
+    vqadd.s8    q12, q5, q12                ; s = vp8_signed_char_clamp(ps1 + u)
+    vqsub.s8    q15, q7, q14                ; s = vp8_signed_char_clamp(qs0 - u)
+    vqadd.s8    q14, q6, q14                ; s = vp8_signed_char_clamp(ps0 + u)
+    veor        q9, q11, q0                 ; *oq2 = s^0x80
+    veor        q4, q10, q0                 ; *op2 = s^0x80
+    veor        q8, q13, q0                 ; *oq1 = s^0x80
+    veor        q5, q12, q0                 ; *op2 = s^0x80
+    veor        q7, q15, q0                 ; *oq0 = s^0x80
+    veor        q6, q14, q0                 ; *op0 = s^0x80
+
+    vst1.u8     {d8}, [r0], r1              ; store u op2
+    vst1.u8     {d9}, [r3], r1              ; store v op2
+    vst1.u8     {d10}, [r0], r1             ; store u op1
+    vst1.u8     {d11}, [r3], r1             ; store v op1
+    vst1.u8     {d12}, [r0], r1             ; store u op0
+    vst1.u8     {d13}, [r3], r1             ; store v op0
+    vst1.u8     {d14}, [r0], r1             ; store u oq0
+    vst1.u8     {d15}, [r3], r1             ; store v oq0
+    vst1.u8     {d16}, [r0], r1             ; store u oq1
+    vst1.u8     {d17}, [r3], r1             ; store v oq1
+    vst1.u8     {d18}, [r0], r1             ; store u oq2
+    vst1.u8     {d19}, [r3], r1             ; store v oq2
+
+    bx          lr
+    ENDP        ; |vp8_mbloop_filter_horizontal_edge_uv_neon|
+
+;-----------------
+    AREA    mbhloopfilteruv_dat, DATA, READWRITE            ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_mbhlfuv_coeff_
+    DCD     mbhlfuv_coeff
+mbhlfuv_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x003f003f, 0x003f003f, 0x003f003f, 0x003f003f
+    DCD     0x09090909, 0x09090909, 0x12121212, 0x12121212
+    DCD     0x1b1b1b1b, 0x1b1b1b1b
+
+    END
diff --git a/vp8/common/arm/neon/mbloopfilterhorizontaledge_y_neon.asm b/vp8/common/arm/neon/mbloopfilterhorizontaledge_y_neon.asm
new file mode 100644 (file)
index 0000000..2ab0fc2
--- /dev/null
@@ -0,0 +1,236 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_mbloop_filter_horizontal_edge_y_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *s,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; //stack(r5)   int count --unused
+|vp8_mbloop_filter_horizontal_edge_y_neon| PROC
+    sub         r0, r0, r1, lsl #2          ; move src pointer down by 4 lines
+    ldr         r12, [sp, #0]               ; load thresh pointer
+
+    vld1.u8     {q3}, [r0], r1              ; p3
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    vld1.u8     {q4}, [r0], r1              ; p2
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+    vld1.u8     {q5}, [r0], r1              ; p1
+    ldr         r12, _mbhlfy_coeff_
+    vld1.u8     {q6}, [r0], r1              ; p0
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vld1.u8     {q7}, [r0], r1              ; q0
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vld1.u8     {q8}, [r0], r1              ; q1
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vld1.u8     {q9}, [r0], r1              ; q2
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vld1.u8     {q10}, [r0], r1             ; q3
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q0, q10, q9                 ; abs(q3 - q2)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q0, q1, q0                  ; (abs(q3 - q2) > limit)*-1
+
+    vand        q15, q15, q12
+
+    vabd.u8     q12, q6, q7                 ; abs(p0 - q0)
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vld1.s8     {d4[], d5[]}, [r2]          ; flimit
+
+    vand        q10, q10, q11
+    vand        q3, q3, q0
+
+    vld1.u8     {q0}, [r12]!
+
+    vadd.u8     q2, q2, q2                  ; flimit * 2
+    vadd.u8     q2, q2, q1                  ; flimit * 2 + limit
+
+    vabd.u8     q1, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q12, q12, q12               ; abs(p0 - q0) * 2
+    vshr.u8     q1, q1, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q12, q12, q1                ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q12, q2, q12                ; (abs(p0 - q0)*2 + abs(p1 - q1)/2 > flimit*2 + limit)*-1
+
+    vand        q15, q15, q10
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+    veor        q4, q4, q0                  ; ps2: p2 offset to convert to a signed value
+    veor        q9, q9, q0                  ; qs2: q2 offset to convert to a signed value
+;;;;;;;;;;;;;
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q13, d15, d13
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+
+    ;vadd.s8    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q11, q13, q13
+
+    vand        q3, q3, q12
+
+    ;vadd.s8    q2, q2, q10
+    vadd.s16    q2, q2, q10
+    vadd.s16    q13, q13, q11
+
+    vld1.u8     {q12}, [r12]!               ;#3
+
+    ;vqadd.s8   q1, q1, q2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q2, q2, d2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q13, q13, d3
+
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    vld1.u8     {q11}, [r12]!               ;#4
+
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q13
+
+;;;;;;;;;;;;;;
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+
+    vld1.u8     {q15}, [r12]!               ;#63
+    ;
+    vand        q13, q1, q14                ; Filter2: q13; Filter2 &= hev
+
+    vld1.u8     {d7}, [r12]!                ;#9
+    sub         r0, r0, r1, lsl #3
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q13, q12                ; s = Filter2 & 7
+
+;   vqadd.s8    q13, q13, q11               ; Filter2 = vp8_signed_char_clamp(Filter2+4)
+;   vld1.u8     {d6}, [r12]!                ;#18
+
+;   add         r0, r0, r1
+;   add         r2, r0, r1
+
+;   vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+;   vceq.i8     q2, q2, q11                 ; s = (s==4)*-1
+
+;   add         r3, r2, r1
+
+;   vqsub.s8    q7, q7, q13                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
+;   vqadd.s8    q11, q2, q13                ; u = vp8_signed_char_clamp(s + Filter2)
+
+;   vld1.u8     {d5}, [r12]!                ;#27
+;   vmov        q10, q15
+;   vmov        q12, q15
+
+;   vqadd.s8    q6, q6, q11                 ; ps0 = vp8_signed_char_clamp(ps0 + u)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    vqadd.s8    q2, q13, q11                ; Filter1 = vp8_signed_char_clamp(Filter2+4)
+    vqadd.s8    q13, q13, q12               ; Filter2 = vp8_signed_char_clamp(Filter2+3)
+
+    vld1.u8     {d6}, [r12]!                ;#18
+    add         r0, r0, r1
+    add         r2, r0, r1
+
+    vshr.s8     q2, q2, #3                  ; Filter1 >>= 3
+    vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+
+    vmov        q10, q15
+    vmov        q12, q15
+
+    vqsub.s8    q7, q7, q2                  ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
+
+    vld1.u8     {d5}, [r12]!                ;#27
+    add         r3, r2, r1
+
+    vqadd.s8    q6, q6, q13                 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vbic        q1, q1, q14                 ; Filter2: q1; vp8_filter &= ~hev; Filter2 = vp8_filter
+
+    ; roughly 1/7th difference across boundary
+    ; roughly 2/7th difference across boundary
+    ; roughly 3/7th difference across boundary
+    vmov        q11, q15
+    vmov        q13, q15
+    vmov        q14, q15
+
+    vmlal.s8    q10, d2, d7                 ; Filter2 * 9
+    vmlal.s8    q11, d3, d7
+    vmlal.s8    q12, d2, d6                 ; Filter2 * 18
+    vmlal.s8    q13, d3, d6
+    vmlal.s8    q14, d2, d5                 ; Filter2 * 27
+    vmlal.s8    q15, d3, d5
+    vqshrn.s16  d20, q10, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
+    vqshrn.s16  d21, q11, #7
+    vqshrn.s16  d24, q12, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
+    vqshrn.s16  d25, q13, #7
+    vqshrn.s16  d28, q14, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
+    vqshrn.s16  d29, q15, #7
+
+    vqsub.s8    q11, q9, q10                ; s = vp8_signed_char_clamp(qs2 - u)
+    vqadd.s8    q10, q4, q10                ; s = vp8_signed_char_clamp(ps2 + u)
+    vqsub.s8    q13, q8, q12                ; s = vp8_signed_char_clamp(qs1 - u)
+    vqadd.s8    q12, q5, q12                ; s = vp8_signed_char_clamp(ps1 + u)
+    vqsub.s8    q15, q7, q14                ; s = vp8_signed_char_clamp(qs0 - u)
+    vqadd.s8    q14, q6, q14                ; s = vp8_signed_char_clamp(ps0 + u)
+    veor        q9, q11, q0                 ; *oq2 = s^0x80
+    veor        q4, q10, q0                 ; *op2 = s^0x80
+    veor        q5, q12, q0                 ; *op2 = s^0x80
+    veor        q6, q14, q0                 ; *op0 = s^0x80
+    veor        q8, q13, q0                 ; *oq1 = s^0x80
+    veor        q7, q15, q0                 ; *oq0 = s^0x80
+
+    vst1.u8     {q4}, [r0]                  ; store op2
+    vst1.u8     {q5}, [r2]                  ; store op1
+    vst1.u8     {q6}, [r3], r1              ; store op0
+    add         r12, r3, r1
+    vst1.u8     {q7}, [r3]                  ; store oq0
+    vst1.u8     {q8}, [r12], r1             ; store oq1
+    vst1.u8     {q9}, [r12]             ; store oq2
+
+    bx          lr
+    ENDP        ; |vp8_mbloop_filter_horizontal_edge_y_neon|
+
+;-----------------
+    AREA    mbhloopfiltery_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_mbhlfy_coeff_
+    DCD     mbhlfy_coeff
+mbhlfy_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x003f003f, 0x003f003f, 0x003f003f, 0x003f003f
+    DCD     0x09090909, 0x09090909, 0x12121212, 0x12121212
+    DCD     0x1b1b1b1b, 0x1b1b1b1b
+
+    END
diff --git a/vp8/common/arm/neon/mbloopfilterverticaledge_uv_neon.asm b/vp8/common/arm/neon/mbloopfilterverticaledge_uv_neon.asm
new file mode 100644 (file)
index 0000000..ad5afba
--- /dev/null
@@ -0,0 +1,296 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_mbloop_filter_vertical_edge_uv_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *u,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; stack(r5) unsigned char *v
+|vp8_mbloop_filter_vertical_edge_uv_neon| PROC
+    sub         r0, r0, #4                  ; move src pointer down by 4 columns
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    ldr         r3, [sp, #4]                ; load v ptr
+    ldr         r12, [sp, #0]               ; load thresh pointer
+
+    sub         r3, r3, #4                  ; move v pointer down by 4 columns
+
+    vld1.u8     {d6}, [r0], r1              ;load u data
+    vld1.u8     {d7}, [r3], r1              ;load v data
+    vld1.u8     {d8}, [r0], r1
+    vld1.u8     {d9}, [r3], r1
+    vld1.u8     {d10}, [r0], r1
+    vld1.u8     {d11}, [r3], r1
+    vld1.u8     {d12}, [r0], r1
+    vld1.u8     {d13}, [r3], r1
+    vld1.u8     {d14}, [r0], r1
+    vld1.u8     {d15}, [r3], r1
+    vld1.u8     {d16}, [r0], r1
+    vld1.u8     {d17}, [r3], r1
+    vld1.u8     {d18}, [r0], r1
+    vld1.u8     {d19}, [r3], r1
+    vld1.u8     {d20}, [r0], r1
+    vld1.u8     {d21}, [r3], r1
+
+    ;transpose to 8x16 matrix
+    vtrn.32     q3, q7
+    vtrn.32     q4, q8
+    vtrn.32     q5, q9
+    vtrn.32     q6, q10
+
+    vtrn.16     q3, q5
+    vtrn.16     q4, q6
+    vtrn.16     q7, q9
+    vtrn.16     q8, q10
+
+    vtrn.8      q3, q4
+    vtrn.8      q5, q6
+    vtrn.8      q7, q8
+    vtrn.8      q9, q10
+
+    sub         sp, sp, #32
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+    vst1.u8     {q3}, [sp]!
+    ldr         r12, _mbvlfuv_coeff_
+    vst1.u8     {q10}, [sp]!
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q0, q10, q9                 ; abs(q3 - q2)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q0, q1, q0                  ; (abs(q3 - q2) > limit)*-1
+
+    vand        q15, q15, q12
+
+    vabd.u8     q12, q6, q7                 ; abs(p0 - q0)
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vld1.s8     {d4[], d5[]}, [r2]          ; flimit
+
+    vand        q10, q10, q11
+    vand        q3, q3, q0
+
+    vld1.u8     {q0}, [r12]!
+
+    vadd.u8     q2, q2, q2                  ; flimit * 2
+    vadd.u8     q2, q2, q1                  ; flimit * 2 + limit
+
+    vabd.u8     q1, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q12, q12, q12               ; abs(p0 - q0) * 2
+    vshr.u8     q1, q1, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q12, q12, q1                ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q12, q2, q12                ; (abs(p0 - q0)*2 + abs(p1 - q1)/2 > flimit*2 + limit)*-1
+
+    vand        q15, q15, q10
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+    veor        q4, q4, q0                  ; ps2: p2 offset to convert to a signed value
+    veor        q9, q9, q0                  ; qs2: q2 offset to convert to a signed value
+;;;;;;;;;;;;;
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q13, d15, d13
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+
+    ;vadd.s8    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q11, q13, q13
+
+    vand        q3, q3, q12
+
+    ;vadd.s8    q2, q2, q10
+    vadd.s16    q2, q2, q10
+    vadd.s16    q13, q13, q11
+
+    vld1.u8     {q12}, [r12]!               ;#3
+
+    ;vqadd.s8   q1, q1, q2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q2, q2, d2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q13, q13, d3
+
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    vld1.u8     {q11}, [r12]!               ;#4
+
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q13
+
+;;;;;;;;;;;;;;
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+
+    vld1.u8     {q15}, [r12]!               ;#63
+    ;
+    vand        q13, q1, q14                ; Filter2: q13; Filter2 &= hev
+
+    vld1.u8     {d7}, [r12]!                ;#9
+    ;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q13, q12                ; s = Filter2 & 7
+
+;   vqadd.s8    q13, q13, q11               ; Filter2 = vp8_signed_char_clamp(Filter2+4)
+;   vld1.u8     {d6}, [r12]!                ;#18
+
+;   sub         r0, r0, r1, lsl #3
+;   sub         r3, r3, r1, lsl #3
+;   sub         sp, sp, #32
+
+;   vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+;   vceq.i8     q2, q2, q11                 ; s = (s==4)*-1
+
+;   vqsub.s8    q7, q7, q13                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
+;   vqadd.s8    q11, q2, q13                ; u = vp8_signed_char_clamp(s + Filter2)
+
+;   vld1.u8     {d5}, [r12]!                ;#27
+;   vmov        q10, q15
+;   vmov        q12, q15
+
+;   vqadd.s8    q6, q6, q11                 ; ps0 = vp8_signed_char_clamp(ps0 + u)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    vqadd.s8    q2, q13, q11                ; Filter1 = vp8_signed_char_clamp(Filter2+4)
+    vqadd.s8    q13, q13, q12               ; Filter2 = vp8_signed_char_clamp(Filter2+3)
+
+    vld1.u8     {d6}, [r12]!                ;#18
+
+    sub         r0, r0, r1, lsl #3
+    sub         r3, r3, r1, lsl #3
+
+    vshr.s8     q2, q2, #3                  ; Filter1 >>= 3
+    vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+
+    vmov        q10, q15
+    vmov        q12, q15
+
+    vqsub.s8    q7, q7, q2                  ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
+
+    vld1.u8     {d5}, [r12]!                ;#27
+
+    sub         sp, sp, #32
+
+    vqadd.s8    q6, q6, q13                 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vbic        q1, q1, q14                 ; Filter2: q1; vp8_filter &= ~hev; Filter2 = vp8_filter
+
+    ; roughly 1/7th difference across boundary
+    ; roughly 2/7th difference across boundary
+    ; roughly 3/7th difference across boundary
+    vmov        q11, q15
+    vmov        q13, q15
+    vmov        q14, q15
+
+    vmlal.s8    q10, d2, d7                 ; Filter2 * 9
+    vmlal.s8    q11, d3, d7
+    vmlal.s8    q12, d2, d6                 ; Filter2 * 18
+    vmlal.s8    q13, d3, d6
+    vmlal.s8    q14, d2, d5                 ; Filter2 * 27
+    vmlal.s8    q15, d3, d5
+    vqshrn.s16  d20, q10, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
+    vqshrn.s16  d21, q11, #7
+    vqshrn.s16  d24, q12, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
+    vqshrn.s16  d25, q13, #7
+    vqshrn.s16  d28, q14, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
+    vqshrn.s16  d29, q15, #7
+
+    vqsub.s8    q11, q9, q10                ; s = vp8_signed_char_clamp(qs2 - u)
+    vqadd.s8    q10, q4, q10                ; s = vp8_signed_char_clamp(ps2 + u)
+    vqsub.s8    q13, q8, q12                ; s = vp8_signed_char_clamp(qs1 - u)
+    vqadd.s8    q12, q5, q12                ; s = vp8_signed_char_clamp(ps1 + u)
+    vqsub.s8    q15, q7, q14                ; s = vp8_signed_char_clamp(qs0 - u)
+    vqadd.s8    q14, q6, q14                ; s = vp8_signed_char_clamp(ps0 + u)
+    veor        q9, q11, q0                 ; *oq2 = s^0x80
+    veor        q4, q10, q0                 ; *op2 = s^0x80
+    veor        q8, q13, q0                 ; *oq1 = s^0x80
+    veor        q5, q12, q0                 ; *op2 = s^0x80
+    veor        q7, q15, q0                 ; *oq0 = s^0x80
+    vld1.u8     {q3}, [sp]!
+    veor        q6, q14, q0                 ; *op0 = s^0x80
+    vld1.u8     {q10}, [sp]!
+
+    ;transpose to 16x8 matrix
+    vtrn.32     q3, q7
+    vtrn.32     q4, q8
+    vtrn.32     q5, q9
+    vtrn.32     q6, q10
+
+    vtrn.16     q3, q5
+    vtrn.16     q4, q6
+    vtrn.16     q7, q9
+    vtrn.16     q8, q10
+
+    vtrn.8      q3, q4
+    vtrn.8      q5, q6
+    vtrn.8      q7, q8
+    vtrn.8      q9, q10
+
+    ;store op2, op1, op0, oq0, oq1, oq2
+    vst1.8      {d6}, [r0], r1
+    vst1.8      {d7}, [r3], r1
+    vst1.8      {d8}, [r0], r1
+    vst1.8      {d9}, [r3], r1
+    vst1.8      {d10}, [r0], r1
+    vst1.8      {d11}, [r3], r1
+    vst1.8      {d12}, [r0], r1
+    vst1.8      {d13}, [r3], r1
+    vst1.8      {d14}, [r0], r1
+    vst1.8      {d15}, [r3], r1
+    vst1.8      {d16}, [r0], r1
+    vst1.8      {d17}, [r3], r1
+    vst1.8      {d18}, [r0], r1
+    vst1.8      {d19}, [r3], r1
+    vst1.8      {d20}, [r0], r1
+    vst1.8      {d21}, [r3], r1
+
+    bx          lr
+    ENDP        ; |vp8_mbloop_filter_vertical_edge_uv_neon|
+
+;-----------------
+    AREA    mbvloopfilteruv_dat, DATA, READWRITE            ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_mbvlfuv_coeff_
+    DCD     mbvlfuv_coeff
+mbvlfuv_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x003f003f, 0x003f003f, 0x003f003f, 0x003f003f
+    DCD     0x09090909, 0x09090909, 0x12121212, 0x12121212
+    DCD     0x1b1b1b1b, 0x1b1b1b1b
+
+    END
diff --git a/vp8/common/arm/neon/mbloopfilterverticaledge_y_neon.asm b/vp8/common/arm/neon/mbloopfilterverticaledge_y_neon.asm
new file mode 100644 (file)
index 0000000..60e5175
--- /dev/null
@@ -0,0 +1,303 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_mbloop_filter_vertical_edge_y_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: flimit, limit, and thresh shpuld be positive numbers. All 16 elements in flimit
+;are equal. So, in the code, only one load is needed
+;for flimit. Same way applies to limit and thresh.
+; r0    unsigned char *s,
+; r1    int p, //pitch
+; r2    const signed char *flimit,
+; r3    const signed char *limit,
+; stack(r4) const signed char *thresh,
+; //stack(r5)   int count --unused
+|vp8_mbloop_filter_vertical_edge_y_neon| PROC
+    sub         r0, r0, #4                  ; move src pointer down by 4 columns
+
+    vld1.u8     {d6}, [r0], r1              ; load first 8-line src data
+    ldr         r12, [sp, #0]               ; load thresh pointer
+    vld1.u8     {d8}, [r0], r1
+    sub         sp, sp, #32
+    vld1.u8     {d10}, [r0], r1
+    vld1.u8     {d12}, [r0], r1
+    vld1.u8     {d14}, [r0], r1
+    vld1.u8     {d16}, [r0], r1
+    vld1.u8     {d18}, [r0], r1
+    vld1.u8     {d20}, [r0], r1
+
+    vld1.u8     {d7}, [r0], r1              ; load second 8-line src data
+    vld1.u8     {d9}, [r0], r1
+    vld1.u8     {d11}, [r0], r1
+    vld1.u8     {d13}, [r0], r1
+    vld1.u8     {d15}, [r0], r1
+    vld1.u8     {d17}, [r0], r1
+    vld1.u8     {d19}, [r0], r1
+    vld1.u8     {d21}, [r0], r1
+
+    ;transpose to 8x16 matrix
+    vtrn.32     q3, q7
+    vtrn.32     q4, q8
+    vtrn.32     q5, q9
+    vtrn.32     q6, q10
+
+    vtrn.16     q3, q5
+    vtrn.16     q4, q6
+    vtrn.16     q7, q9
+    vtrn.16     q8, q10
+
+    vtrn.8      q3, q4
+    vtrn.8      q5, q6
+    vtrn.8      q7, q8
+    vtrn.8      q9, q10
+
+    vld1.s8     {d2[], d3[]}, [r3]          ; limit
+    vst1.u8     {q3}, [sp]!
+    vld1.s8     {d4[], d5[]}, [r12]         ; thresh
+    ldr         r12, _mbvlfy_coeff_
+    vst1.u8     {q10}, [sp]!
+
+    ;vp8_filter_mask() function
+    ;vp8_hevmask() function
+    vabd.u8     q11, q3, q4                 ; abs(p3 - p2)
+    vabd.u8     q12, q4, q5                 ; abs(p2 - p1)
+    vabd.u8     q13, q5, q6                 ; abs(p1 - p0)
+    vabd.u8     q14, q8, q7                 ; abs(q1 - q0)
+    vabd.u8     q3, q9, q8                  ; abs(q2 - q1)
+    vabd.u8     q0, q10, q9                 ; abs(q3 - q2)
+
+    vcge.u8     q15, q1, q11                ; (abs(p3 - p2) > limit)*-1
+    vcge.u8     q12, q1, q12                ; (abs(p2 - p1) > limit)*-1
+    vcge.u8     q10, q1, q13                ; (abs(p1 - p0) > limit)*-1
+    vcge.u8     q11, q1, q14                ; (abs(q1 - q0) > limit)*-1
+    vcge.u8     q3, q1, q3                  ; (abs(q2 - q1) > limit)*-1
+    vcge.u8     q0, q1, q0                  ; (abs(q3 - q2) > limit)*-1
+
+    vand        q15, q15, q12
+
+    vabd.u8     q12, q6, q7                 ; abs(p0 - q0)
+
+    vcgt.u8     q13, q13, q2                ; (abs(p1 - p0) > thresh)*-1
+    vcgt.u8     q14, q14, q2                ; (abs(q1 - q0) > thresh)*-1
+
+    vld1.s8     {d4[], d5[]}, [r2]          ; flimit
+
+    vand        q10, q10, q11
+    vand        q3, q3, q0
+
+    vld1.u8     {q0}, [r12]!
+
+    vadd.u8     q2, q2, q2                  ; flimit * 2
+    vadd.u8     q2, q2, q1                  ; flimit * 2 + limit
+
+    vabd.u8     q1, q5, q8                  ; abs(p1 - q1)
+    vqadd.u8    q12, q12, q12               ; abs(p0 - q0) * 2
+    vshr.u8     q1, q1, #1                  ; abs(p1 - q1) / 2
+    vqadd.u8    q12, q12, q1                ; abs(p0 - q0) * 2 + abs(p1 - q1) / 2
+    vcge.u8     q12, q2, q12                ; (abs(p0 - q0)*2 + abs(p1 - q1)/2 > flimit*2 + limit)*-1
+
+    vand        q15, q15, q10
+
+    ;vp8_filter() function
+    veor        q7, q7, q0                  ; qs0: q0 offset to convert to a signed value
+    veor        q6, q6, q0                  ; ps0: p0 offset to convert to a signed value
+    veor        q5, q5, q0                  ; ps1: p1 offset to convert to a signed value
+    veor        q8, q8, q0                  ; qs1: q1 offset to convert to a signed value
+    veor        q4, q4, q0                  ; ps2: p2 offset to convert to a signed value
+    veor        q9, q9, q0                  ; qs2: q2 offset to convert to a signed value
+;;;;;;;;;;;;;
+    vorr        q14, q13, q14               ; q14: vp8_hevmask
+
+    ;vqsub.s8   q2, q7, q6                  ; ( qs0 - ps0)
+    vsubl.s8    q2, d14, d12                ; ( qs0 - ps0)
+    vsubl.s8    q13, d15, d13
+
+    vqsub.s8    q1, q5, q8                  ; vp8_filter = vp8_signed_char_clamp(ps1-qs1)
+
+    ;vadd.s8    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q10, q2, q2                 ; 3 * ( qs0 - ps0)
+    vadd.s16    q11, q13, q13
+
+    vand        q3, q3, q12
+
+    ;vadd.s8    q2, q2, q10
+    vadd.s16    q2, q2, q10
+    vadd.s16    q13, q13, q11
+
+    vld1.u8     {q12}, [r12]!               ;#3
+
+    ;vqadd.s8   q1, q1, q2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q2, q2, d2                  ; vp8_filter + 3 * ( qs0 - ps0)
+    vaddw.s8    q13, q13, d3
+
+    vand        q15, q15, q3                ; q15: vp8_filter_mask
+    vld1.u8     {q11}, [r12]!               ;#4
+
+    vqmovn.s16  d2, q2                      ; vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0))
+    vqmovn.s16  d3, q13
+
+;;;;;;;;;;;;;;
+    vand        q1, q1, q15                 ; vp8_filter &= mask
+
+    vld1.u8     {q15}, [r12]!               ;#63
+    ;
+    vand        q13, q1, q14                ; Filter2: q13; Filter2 &= hev
+
+    vld1.u8     {d7}, [r12]!                ;#9
+    ;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Change for VP8 from VP7
+;   vand        q2, q13, q12                ; s = Filter2 & 7
+
+;   vqadd.s8    q13, q13, q11               ; Filter2 = vp8_signed_char_clamp(Filter2+4)
+;   vld1.u8     {d6}, [r12]!                ;#18
+
+;   sub         r0, r0, r1, lsl #4
+;   sub         sp, sp, #32
+;   add         r2, r0, r1
+
+;   vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+;   vceq.i8     q2, q2, q11                 ; s = (s==4)*-1
+
+;   add         r3, r2, r1
+
+;   vqsub.s8    q7, q7, q13                 ; qs0 = vp8_signed_char_clamp(qs0 - Filter2)
+;   vqadd.s8    q11, q2, q13                ; u = vp8_signed_char_clamp(s + Filter2)
+
+;   vld1.u8     {d5}, [r12]!                ;#27
+;   vmov        q10, q15
+;   vmov        q12, q15
+
+;   vqadd.s8    q6, q6, q11                 ; ps0 = vp8_signed_char_clamp(ps0 + u)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    vqadd.s8    q2, q13, q11                ; Filter1 = vp8_signed_char_clamp(Filter2+4)
+    vqadd.s8    q13, q13, q12               ; Filter2 = vp8_signed_char_clamp(Filter2+3)
+
+    vld1.u8     {d6}, [r12]!                ;#18
+    sub         r0, r0, r1, lsl #4
+    sub         sp, sp, #32
+
+    add         r2, r0, r1
+
+    vshr.s8     q2, q2, #3                  ; Filter1 >>= 3
+    vshr.s8     q13, q13, #3                ; Filter2 >>= 3
+
+    vmov        q10, q15
+    vmov        q12, q15
+
+    vqsub.s8    q7, q7, q2                  ; qs0 = vp8_signed_char_clamp(qs0 - Filter1)
+
+    vld1.u8     {d5}, [r12]!                ;#27
+    add         r3, r2, r1
+
+    vqadd.s8    q6, q6, q13                 ; ps0 = vp8_signed_char_clamp(ps0 + Filter2)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    vbic        q1, q1, q14                 ; Filter2: q1; vp8_filter &= ~hev; Filter2 = vp8_filter
+
+    ; roughly 1/7th difference across boundary
+    ; roughly 2/7th difference across boundary
+    ; roughly 3/7th difference across boundary
+    vmov        q11, q15
+    vmov        q13, q15
+    vmov        q14, q15
+
+    vmlal.s8    q10, d2, d7                 ; Filter2 * 9
+    vmlal.s8    q11, d3, d7
+    vmlal.s8    q12, d2, d6                 ; Filter2 * 18
+    vmlal.s8    q13, d3, d6
+    vmlal.s8    q14, d2, d5                 ; Filter2 * 27
+    vmlal.s8    q15, d3, d5
+    vqshrn.s16  d20, q10, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7)
+    vqshrn.s16  d21, q11, #7
+    vqshrn.s16  d24, q12, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7)
+    vqshrn.s16  d25, q13, #7
+    vqshrn.s16  d28, q14, #7                ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7)
+    vqshrn.s16  d29, q15, #7
+
+    vqsub.s8    q11, q9, q10                ; s = vp8_signed_char_clamp(qs2 - u)
+    vqadd.s8    q10, q4, q10                ; s = vp8_signed_char_clamp(ps2 + u)
+    vqsub.s8    q13, q8, q12                ; s = vp8_signed_char_clamp(qs1 - u)
+    vqadd.s8    q12, q5, q12                ; s = vp8_signed_char_clamp(ps1 + u)
+    vqsub.s8    q15, q7, q14                ; s = vp8_signed_char_clamp(qs0 - u)
+    vqadd.s8    q14, q6, q14                ; s = vp8_signed_char_clamp(ps0 + u)
+    veor        q9, q11, q0                 ; *oq2 = s^0x80
+    veor        q4, q10, q0                 ; *op2 = s^0x80
+    veor        q8, q13, q0                 ; *oq1 = s^0x80
+    veor        q5, q12, q0                 ; *op2 = s^0x80
+    veor        q7, q15, q0                 ; *oq0 = s^0x80
+    vld1.u8     {q3}, [sp]!
+    veor        q6, q14, q0                 ; *op0 = s^0x80
+    vld1.u8     {q10}, [sp]!
+
+    ;transpose to 16x8 matrix
+    vtrn.32     q3, q7
+    vtrn.32     q4, q8
+    vtrn.32     q5, q9
+    vtrn.32     q6, q10
+    add         r12, r3, r1
+
+    vtrn.16     q3, q5
+    vtrn.16     q4, q6
+    vtrn.16     q7, q9
+    vtrn.16     q8, q10
+
+    vtrn.8      q3, q4
+    vtrn.8      q5, q6
+    vtrn.8      q7, q8
+    vtrn.8      q9, q10
+
+    ;store op2, op1, op0, oq0, oq1, oq2
+    vst1.8      {d6}, [r0]
+    vst1.8      {d8}, [r2]
+    vst1.8      {d10}, [r3]
+    vst1.8      {d12}, [r12], r1
+    add         r0, r12, r1
+    vst1.8      {d14}, [r12]
+    vst1.8      {d16}, [r0], r1
+    add         r2, r0, r1
+    vst1.8      {d18}, [r0]
+    vst1.8      {d20}, [r2], r1
+    add         r3, r2, r1
+    vst1.8      {d7}, [r2]
+    vst1.8      {d9}, [r3], r1
+    add         r12, r3, r1
+    vst1.8      {d11}, [r3]
+    vst1.8      {d13}, [r12], r1
+    add         r0, r12, r1
+    vst1.8      {d15}, [r12]
+    vst1.8      {d17}, [r0], r1
+    add         r2, r0, r1
+    vst1.8      {d19}, [r0]
+    vst1.8      {d21}, [r2]
+
+    bx          lr
+    ENDP        ; |vp8_mbloop_filter_vertical_edge_y_neon|
+
+;-----------------
+    AREA    mbvloopfiltery_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 16 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_mbvlfy_coeff_
+    DCD     mbvlfy_coeff
+mbvlfy_coeff
+    DCD     0x80808080, 0x80808080, 0x80808080, 0x80808080
+    DCD     0x03030303, 0x03030303, 0x03030303, 0x03030303
+    DCD     0x04040404, 0x04040404, 0x04040404, 0x04040404
+    DCD     0x003f003f, 0x003f003f, 0x003f003f, 0x003f003f
+    DCD     0x09090909, 0x09090909, 0x12121212, 0x12121212
+    DCD     0x1b1b1b1b, 0x1b1b1b1b
+
+    END
diff --git a/vp8/common/arm/neon/recon16x16mb_neon.asm b/vp8/common/arm/neon/recon16x16mb_neon.asm
new file mode 100644 (file)
index 0000000..b9ba1cb
--- /dev/null
@@ -0,0 +1,130 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_recon16x16mb_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    unsigned char  *pred_ptr,
+; r1    short *diff_ptr,
+; r2    unsigned char *dst_ptr,
+; r3    int ystride,
+; stack unsigned char *udst_ptr,
+; stack unsigned char *vdst_ptr
+
+|vp8_recon16x16mb_neon| PROC
+    mov             r12, #4             ;loop counter for Y loop
+
+recon16x16mb_loop_y
+    vld1.u8         {q12, q13}, [r0]!   ;load data from pred_ptr
+    vld1.16         {q8, q9}, [r1]!     ;load data from diff_ptr
+    vld1.u8         {q14, q15}, [r0]!
+    vld1.16         {q10, q11}, [r1]!
+
+    vmovl.u8        q0, d24             ;modify Pred data from 8 bits to 16 bits
+    vmovl.u8        q1, d25
+    vmovl.u8        q2, d26
+    vmovl.u8        q3, d27
+    vmovl.u8        q4, d28
+    vmovl.u8        q5, d29
+    vmovl.u8        q6, d30
+    vld1.16         {q12, q13}, [r1]!
+    vmovl.u8        q7, d31
+    vld1.16         {q14, q15}, [r1]!
+
+    pld             [r0]
+    pld             [r1]
+    pld             [r1, #64]
+
+    vadd.s16        q0, q0, q8          ;add Diff data and Pred data together
+    vadd.s16        q1, q1, q9
+    vadd.s16        q2, q2, q10
+    vadd.s16        q3, q3, q11
+    vadd.s16        q4, q4, q12
+    vadd.s16        q5, q5, q13
+    vadd.s16        q6, q6, q14
+    vadd.s16        q7, q7, q15
+
+    vqmovun.s16     d0, q0              ;CLAMP() saturation
+    vqmovun.s16     d1, q1
+    vqmovun.s16     d2, q2
+    vqmovun.s16     d3, q3
+    vqmovun.s16     d4, q4
+    vqmovun.s16     d5, q5
+    vst1.u8         {q0}, [r2], r3      ;store result
+    vqmovun.s16     d6, q6
+    vst1.u8         {q1}, [r2], r3
+    vqmovun.s16     d7, q7
+    vst1.u8         {q2}, [r2], r3
+    subs            r12, r12, #1
+
+    moveq           r12, #2             ;loop counter for UV loop
+
+    vst1.u8         {q3}, [r2], r3
+    bne             recon16x16mb_loop_y
+
+    mov             r3, r3, lsr #1      ;uv_stride = ystride>>1
+    ldr             r2, [sp]            ;load upred_ptr
+
+recon16x16mb_loop_uv
+    vld1.u8         {q12, q13}, [r0]!   ;load data from pred_ptr
+    vld1.16         {q8, q9}, [r1]!     ;load data from diff_ptr
+    vld1.u8         {q14, q15}, [r0]!
+    vld1.16         {q10, q11}, [r1]!
+
+    vmovl.u8        q0, d24             ;modify Pred data from 8 bits to 16 bits
+    vmovl.u8        q1, d25
+    vmovl.u8        q2, d26
+    vmovl.u8        q3, d27
+    vmovl.u8        q4, d28
+    vmovl.u8        q5, d29
+    vmovl.u8        q6, d30
+    vld1.16         {q12, q13}, [r1]!
+    vmovl.u8        q7, d31
+    vld1.16         {q14, q15}, [r1]!
+
+    vadd.s16        q0, q0, q8          ;add Diff data and Pred data together
+    vadd.s16        q1, q1, q9
+    vadd.s16        q2, q2, q10
+    vadd.s16        q3, q3, q11
+    vadd.s16        q4, q4, q12
+    vadd.s16        q5, q5, q13
+    vadd.s16        q6, q6, q14
+
+    vqmovun.s16     d0, q0              ;CLAMP() saturation
+    vadd.s16        q7, q7, q15
+    vqmovun.s16     d1, q1
+    vqmovun.s16     d2, q2
+    vqmovun.s16     d3, q3
+    vst1.u8         {d0}, [r2], r3      ;store result
+    vqmovun.s16     d4, q4
+    vst1.u8         {d1}, [r2], r3
+    vqmovun.s16     d5, q5
+    vst1.u8         {d2}, [r2], r3
+    vqmovun.s16     d6, q6
+    vst1.u8         {d3}, [r2], r3
+    vqmovun.s16     d7, q7
+    vst1.u8         {d4}, [r2], r3
+    subs            r12, r12, #1
+
+    vst1.u8         {d5}, [r2], r3
+    vst1.u8         {d6}, [r2], r3
+    vst1.u8         {d7}, [r2], r3
+
+    ldrne           r2, [sp, #4]        ;load vpred_ptr
+    bne             recon16x16mb_loop_uv
+
+    bx             lr
+
+    ENDP
+    END
diff --git a/vp8/common/arm/neon/recon2b_neon.asm b/vp8/common/arm/neon/recon2b_neon.asm
new file mode 100644 (file)
index 0000000..25aaf8c
--- /dev/null
@@ -0,0 +1,53 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_recon2b_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    unsigned char  *pred_ptr,
+; r1    short *diff_ptr,
+; r2    unsigned char *dst_ptr,
+; r3    int stride
+
+|vp8_recon2b_neon| PROC
+    vld1.u8         {q8, q9}, [r0]      ;load data from pred_ptr
+    vld1.16         {q4, q5}, [r1]!     ;load data from diff_ptr
+
+    vmovl.u8        q0, d16             ;modify Pred data from 8 bits to 16 bits
+    vld1.16         {q6, q7}, [r1]!
+    vmovl.u8        q1, d17
+    vmovl.u8        q2, d18
+    vmovl.u8        q3, d19
+
+    vadd.s16        q0, q0, q4          ;add Diff data and Pred data together
+    vadd.s16        q1, q1, q5
+    vadd.s16        q2, q2, q6
+    vadd.s16        q3, q3, q7
+
+    vqmovun.s16     d0, q0              ;CLAMP() saturation
+    vqmovun.s16     d1, q1
+    vqmovun.s16     d2, q2
+    vqmovun.s16     d3, q3
+    add             r0, r2, r3
+
+    vst1.u8         {d0}, [r2]          ;store result
+    vst1.u8         {d1}, [r0], r3
+    add             r2, r0, r3
+    vst1.u8         {d2}, [r0]
+    vst1.u8         {d3}, [r2], r3
+
+    bx             lr
+
+    ENDP
+    END
diff --git a/vp8/common/arm/neon/recon4b_neon.asm b/vp8/common/arm/neon/recon4b_neon.asm
new file mode 100644 (file)
index 0000000..a4f5b80
--- /dev/null
@@ -0,0 +1,68 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_recon4b_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    unsigned char  *pred_ptr,
+; r1    short *diff_ptr,
+; r2    unsigned char *dst_ptr,
+; r3    int stride
+
+|vp8_recon4b_neon| PROC
+    vld1.u8         {q12, q13}, [r0]!   ;load data from pred_ptr
+    vld1.16         {q8, q9}, [r1]!     ;load data from diff_ptr
+    vld1.u8         {q14, q15}, [r0]
+    vld1.16         {q10, q11}, [r1]!
+
+    vmovl.u8        q0, d24             ;modify Pred data from 8 bits to 16 bits
+    vmovl.u8        q1, d25
+    vmovl.u8        q2, d26
+    vmovl.u8        q3, d27
+    vmovl.u8        q4, d28
+    vmovl.u8        q5, d29
+    vmovl.u8        q6, d30
+    vld1.16         {q12, q13}, [r1]!
+    vmovl.u8        q7, d31
+    vld1.16         {q14, q15}, [r1]
+
+    vadd.s16        q0, q0, q8          ;add Diff data and Pred data together
+    vadd.s16        q1, q1, q9
+    vadd.s16        q2, q2, q10
+    vadd.s16        q3, q3, q11
+    vadd.s16        q4, q4, q12
+    vadd.s16        q5, q5, q13
+    vadd.s16        q6, q6, q14
+    vadd.s16        q7, q7, q15
+
+    vqmovun.s16     d0, q0              ;CLAMP() saturation
+    vqmovun.s16     d1, q1
+    vqmovun.s16     d2, q2
+    vqmovun.s16     d3, q3
+    vqmovun.s16     d4, q4
+    vqmovun.s16     d5, q5
+    vqmovun.s16     d6, q6
+    vqmovun.s16     d7, q7
+    add             r0, r2, r3
+
+    vst1.u8         {q0}, [r2]          ;store result
+    vst1.u8         {q1}, [r0], r3
+    add             r2, r0, r3
+    vst1.u8         {q2}, [r0]
+    vst1.u8         {q3}, [r2], r3
+
+    bx             lr
+
+    ENDP
+    END
diff --git a/vp8/common/arm/neon/reconb_neon.asm b/vp8/common/arm/neon/reconb_neon.asm
new file mode 100644 (file)
index 0000000..16d85a0
--- /dev/null
@@ -0,0 +1,60 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_recon_b_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    unsigned char  *pred_ptr,
+; r1    short *diff_ptr,
+; r2    unsigned char *dst_ptr,
+; r3    int stride
+
+|vp8_recon_b_neon| PROC
+    mov             r12, #16
+
+    vld1.u8         {d28}, [r0], r12    ;load 4 data/line from pred_ptr
+    vld1.16         {q10, q11}, [r1]!   ;load data from diff_ptr
+    vld1.u8         {d29}, [r0], r12
+    vld1.16         {q11, q12}, [r1]!
+    vld1.u8         {d30}, [r0], r12
+    vld1.16         {q12, q13}, [r1]!
+    vld1.u8         {d31}, [r0], r12
+    vld1.16         {q13}, [r1]
+
+    vmovl.u8        q0, d28             ;modify Pred data from 8 bits to 16 bits
+    vmovl.u8        q1, d29             ;Pred data in d0, d2, d4, d6
+    vmovl.u8        q2, d30
+    vmovl.u8        q3, d31
+
+    vadd.s16        d0, d0, d20         ;add Diff data and Pred data together
+    vadd.s16        d2, d2, d22
+    vadd.s16        d4, d4, d24
+    vadd.s16        d6, d6, d26
+
+    vqmovun.s16     d0, q0              ;CLAMP() saturation
+    vqmovun.s16     d1, q1
+    vqmovun.s16     d2, q2
+    vqmovun.s16     d3, q3
+    add             r1, r2, r3
+
+    vst1.32         {d0[0]}, [r2]       ;store result
+    vst1.32         {d1[0]}, [r1], r3
+    add             r2, r1, r3
+    vst1.32         {d2[0]}, [r1]
+    vst1.32         {d3[0]}, [r2], r3
+
+    bx             lr
+
+    ENDP
+    END
diff --git a/vp8/common/arm/neon/save_neon_reg.asm b/vp8/common/arm/neon/save_neon_reg.asm
new file mode 100644 (file)
index 0000000..4873e44
--- /dev/null
@@ -0,0 +1,35 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_push_neon|
+    EXPORT  |vp8_pop_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+|vp8_push_neon| PROC
+    vst1.i64            {d8, d9, d10, d11}, [r0]!
+    vst1.i64            {d12, d13, d14, d15}, [r0]!
+    bx              lr
+
+    ENDP
+
+|vp8_pop_neon| PROC
+    vld1.i64            {d8, d9, d10, d11}, [r0]!
+    vld1.i64            {d12, d13, d14, d15}, [r0]!
+    bx              lr
+
+    ENDP
+
+    END
+
diff --git a/vp8/common/arm/neon/shortidct4x4llm_1_neon.asm b/vp8/common/arm/neon/shortidct4x4llm_1_neon.asm
new file mode 100644 (file)
index 0000000..7d06ff9
--- /dev/null
@@ -0,0 +1,66 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_short_idct4x4llm_1_neon|
+    EXPORT  |vp8_dc_only_idct_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch);
+; r0    short *input;
+; r1    short *output;
+; r2    int pitch;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+|vp8_short_idct4x4llm_1_neon| PROC
+    vld1.16         {d0[]}, [r0]            ;load input[0]
+
+    add             r3, r1, r2
+    add             r12, r3, r2
+
+    vrshr.s16       d0, d0, #3
+
+    add             r0, r12, r2
+
+    vst1.16         {d0}, [r1]
+    vst1.16         {d0}, [r3]
+    vst1.16         {d0}, [r12]
+    vst1.16         {d0}, [r0]
+
+    bx             lr
+    ENDP
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;void vp8_dc_only_idct_c(short input_dc, short *output, int pitch);
+; r0    short input_dc;
+; r1    short *output;
+; r2    int pitch;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+|vp8_dc_only_idct_neon| PROC
+    vdup.16         d0, r0
+
+    add             r3, r1, r2
+    add             r12, r3, r2
+
+    vrshr.s16       d0, d0, #3
+
+    add             r0, r12, r2
+
+    vst1.16         {d0}, [r1]
+    vst1.16         {d0}, [r3]
+    vst1.16         {d0}, [r12]
+    vst1.16         {d0}, [r0]
+
+    bx             lr
+
+    ENDP
+    END
diff --git a/vp8/common/arm/neon/shortidct4x4llm_neon.asm b/vp8/common/arm/neon/shortidct4x4llm_neon.asm
new file mode 100644 (file)
index 0000000..ffecfbf
--- /dev/null
@@ -0,0 +1,126 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_short_idct4x4llm_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+;*************************************************************
+;void vp8_short_idct4x4llm_c(short *input, short *output, int pitch)
+;r0 short * input
+;r1 short * output
+;r2 int pitch
+;*************************************************************
+;static const int cospi8sqrt2minus1=20091;
+;static const int sinpi8sqrt2      =35468;
+;static const int rounding = 0;
+;Optimization note: The resulted data from dequantization are signed 13-bit data that is
+;in the range of [-4096, 4095]. This allows to use "vqdmulh"(neon) instruction since
+;it won't go out of range (13+16+1=30bits<32bits). This instruction gives the high half
+;result of the multiplication that is needed in IDCT.
+
+|vp8_short_idct4x4llm_neon| PROC
+    ldr             r12, _idct_coeff_
+    vld1.16         {q1, q2}, [r0]
+    vld1.16         {d0}, [r12]
+
+    vswp            d3, d4                  ;q2(vp[4] vp[12])
+
+    vqdmulh.s16     q3, q2, d0[2]
+    vqdmulh.s16     q4, q2, d0[0]
+
+    vqadd.s16       d12, d2, d3             ;a1
+    vqsub.s16       d13, d2, d3             ;b1
+
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vqadd.s16       q3, q3, q2              ;modify since sinpi8sqrt2 > 65536/2 (negtive number)
+    vqadd.s16       q4, q4, q2
+
+    ;d6 - c1:temp1
+    ;d7 - d1:temp2
+    ;d8 - d1:temp1
+    ;d9 - c1:temp2
+
+    vqsub.s16       d10, d6, d9             ;c1
+    vqadd.s16       d11, d7, d8             ;d1
+
+    vqadd.s16       d2, d12, d11
+    vqadd.s16       d3, d13, d10
+    vqsub.s16       d4, d13, d10
+    vqsub.s16       d5, d12, d11
+
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vswp            d3, d4
+
+    vqdmulh.s16     q3, q2, d0[2]
+    vqdmulh.s16     q4, q2, d0[0]
+
+    vqadd.s16       d12, d2, d3             ;a1
+    vqsub.s16       d13, d2, d3             ;b1
+
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vqadd.s16       q3, q3, q2              ;modify since sinpi8sqrt2 > 65536/2 (negtive number)
+    vqadd.s16       q4, q4, q2
+
+    vqsub.s16       d10, d6, d9             ;c1
+    vqadd.s16       d11, d7, d8             ;d1
+
+    vqadd.s16       d2, d12, d11
+    vqadd.s16       d3, d13, d10
+    vqsub.s16       d4, d13, d10
+    vqsub.s16       d5, d12, d11
+
+    vrshr.s16       d2, d2, #3
+    vrshr.s16       d3, d3, #3
+    vrshr.s16       d4, d4, #3
+    vrshr.s16       d5, d5, #3
+
+    add             r3, r1, r2
+    add             r12, r3, r2
+    add             r0, r12, r2
+
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vst1.16         {d2}, [r1]
+    vst1.16         {d3}, [r3]
+    vst1.16         {d4}, [r12]
+    vst1.16         {d5}, [r0]
+
+    bx             lr
+
+    ENDP
+
+;-----------------
+    AREA    idct4x4_dat, DATA, READWRITE            ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_idct_coeff_
+    DCD     idct_coeff
+idct_coeff
+    DCD     0x4e7b4e7b, 0x8a8c8a8c
+
+;20091, 20091, 35468, 35468
+
+    END
diff --git a/vp8/common/arm/neon/sixtappredict16x16_neon.asm b/vp8/common/arm/neon/sixtappredict16x16_neon.asm
new file mode 100644 (file)
index 0000000..9f5f0d2
--- /dev/null
@@ -0,0 +1,494 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sixtap_predict16x16_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; r4    unsigned char *dst_ptr,
+; stack(r5) int  dst_pitch
+
+;Note: To take advantage of 8-bit mulplication instruction in NEON. First apply abs() to
+; filter coeffs to make them u8. Then, use vmlsl for negtive coeffs. After multiplication,
+; the result can be negtive. So, I treat the result as s16. But, since it is also possible
+; that the result can be a large positive number (> 2^15-1), which could be confused as a
+; negtive number. To avoid that error, apply filter coeffs in the order of 0, 1, 4 ,5 ,2,
+; which ensures that the result stays in s16 range. Finally, saturated add the result by
+; applying 3rd filter coeff. Same applys to other filter functions.
+
+|vp8_sixtap_predict16x16_neon| PROC
+    push            {r4-r5, lr}
+
+    ldr             r12, _filter16_coeff_
+    ldr             r4, [sp, #12]           ;load parameters from stack
+    ldr             r5, [sp, #16]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_filter16x16_only
+
+    add             r2, r12, r2, lsl #5     ;calculate filter location
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+
+    vld1.s32        {q14, q15}, [r2]        ;load first_pass filter
+
+    beq             firstpass_filter16x16_only
+
+    sub             sp, sp, #336            ;reserve space on stack for temporary storage
+    mov             lr, sp
+
+    vabs.s32        q12, q14
+    vabs.s32        q13, q15
+
+    mov             r2, #7                  ;loop counter
+    sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
+    sub             r0, r0, r1, lsl #1
+
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vdup.8          d1, d24[4]
+    vdup.8          d2, d25[0]
+    vdup.8          d3, d25[4]
+    vdup.8          d4, d26[0]
+    vdup.8          d5, d26[4]
+
+;First Pass: output_height lines x output_width columns (21x16)
+filt_blk2d_fp16x16_loop_neon
+    vld1.u8         {d6, d7, d8}, [r0], r1      ;load src data
+    vld1.u8         {d9, d10, d11}, [r0], r1
+    vld1.u8         {d12, d13, d14}, [r0], r1
+
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q8, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q9, d7, d0
+    vmull.u8        q10, d9, d0
+    vmull.u8        q11, d10, d0
+    vmull.u8        q12, d12, d0
+    vmull.u8        q13, d13, d0
+
+    vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d29, d9, d10, #1
+    vext.8          d30, d12, d13, #1
+
+    vmlsl.u8        q8, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q10, d29, d1
+    vmlsl.u8        q12, d30, d1
+
+    vext.8          d28, d7, d8, #1
+    vext.8          d29, d10, d11, #1
+    vext.8          d30, d13, d14, #1
+
+    vmlsl.u8        q9, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q11, d29, d1
+    vmlsl.u8        q13, d30, d1
+
+    vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d29, d9, d10, #4
+    vext.8          d30, d12, d13, #4
+
+    vmlsl.u8        q8, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q10, d29, d4
+    vmlsl.u8        q12, d30, d4
+
+    vext.8          d28, d7, d8, #4
+    vext.8          d29, d10, d11, #4
+    vext.8          d30, d13, d14, #4
+
+    vmlsl.u8        q9, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q11, d29, d4
+    vmlsl.u8        q13, d30, d4
+
+    vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d29, d9, d10, #5
+    vext.8          d30, d12, d13, #5
+
+    vmlal.u8        q8, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q10, d29, d5
+    vmlal.u8        q12, d30, d5
+
+    vext.8          d28, d7, d8, #5
+    vext.8          d29, d10, d11, #5
+    vext.8          d30, d13, d14, #5
+
+    vmlal.u8        q9, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q11, d29, d5
+    vmlal.u8        q13, d30, d5
+
+    vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d29, d9, d10, #2
+    vext.8          d30, d12, d13, #2
+
+    vmlal.u8        q8, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q10, d29, d2
+    vmlal.u8        q12, d30, d2
+
+    vext.8          d28, d7, d8, #2
+    vext.8          d29, d10, d11, #2
+    vext.8          d30, d13, d14, #2
+
+    vmlal.u8        q9, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q11, d29, d2
+    vmlal.u8        q13, d30, d2
+
+    vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d29, d9, d10, #3
+    vext.8          d30, d12, d13, #3
+
+    vext.8          d15, d7, d8, #3
+    vext.8          d31, d10, d11, #3
+    vext.8          d6, d13, d14, #3
+
+    vmull.u8        q4, d28, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q5, d29, d3
+    vmull.u8        q6, d30, d3
+
+    vqadd.s16       q8, q4                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q10, q5
+    vqadd.s16       q12, q6
+
+    vmull.u8        q6, d15, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q7, d31, d3
+    vmull.u8        q3, d6, d3
+
+    subs            r2, r2, #1
+
+    vqadd.s16       q9, q6
+    vqadd.s16       q11, q7
+    vqadd.s16       q13, q3
+
+    vqrshrun.s16    d6, q8, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q9, #7
+    vqrshrun.s16    d8, q10, #7
+    vqrshrun.s16    d9, q11, #7
+    vqrshrun.s16    d10, q12, #7
+    vqrshrun.s16    d11, q13, #7
+
+    vst1.u8         {d6, d7, d8}, [lr]!     ;store result
+    vst1.u8         {d9, d10, d11}, [lr]!
+
+    bne             filt_blk2d_fp16x16_loop_neon
+
+;Second pass: 16x16
+;secondpass_filter - do first 8-columns and then second 8-columns
+    add             r3, r12, r3, lsl #5
+    sub             lr, lr, #336
+
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+    mov             r3, #2                  ;loop counter
+
+    vabs.s32        q7, q5
+    vabs.s32        q8, q6
+
+    mov             r2, #16
+
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vdup.8          d1, d14[4]
+    vdup.8          d2, d15[0]
+    vdup.8          d3, d15[4]
+    vdup.8          d4, d16[0]
+    vdup.8          d5, d16[4]
+
+filt_blk2d_sp16x16_outloop_neon
+    vld1.u8         {d18}, [lr], r2         ;load src data
+    vld1.u8         {d19}, [lr], r2
+    vld1.u8         {d20}, [lr], r2
+    vld1.u8         {d21}, [lr], r2
+    mov             r12, #4                 ;loop counter
+    vld1.u8         {d22}, [lr], r2
+
+secondpass_inner_loop_neon
+    vld1.u8         {d23}, [lr], r2         ;load src data
+    vld1.u8         {d24}, [lr], r2
+    vld1.u8         {d25}, [lr], r2
+    vld1.u8         {d26}, [lr], r2
+
+    vmull.u8        q3, d18, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d19, d0
+    vmull.u8        q5, d20, d0
+    vmull.u8        q6, d21, d0
+
+    vmlsl.u8        q3, d19, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q4, d20, d1
+    vmlsl.u8        q5, d21, d1
+    vmlsl.u8        q6, d22, d1
+
+    vmlsl.u8        q3, d22, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d23, d4
+    vmlsl.u8        q5, d24, d4
+    vmlsl.u8        q6, d25, d4
+
+    vmlal.u8        q3, d20, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d21, d2
+    vmlal.u8        q5, d22, d2
+    vmlal.u8        q6, d23, d2
+
+    vmlal.u8        q3, d23, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q4, d24, d5
+    vmlal.u8        q5, d25, d5
+    vmlal.u8        q6, d26, d5
+
+    vmull.u8        q7, d21, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q8, d22, d3
+    vmull.u8        q9, d23, d3
+    vmull.u8        q10, d24, d3
+
+    subs            r12, r12, #1
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q8, #7
+    vqrshrun.s16    d8, q9, #7
+    vqrshrun.s16    d9, q10, #7
+
+    vst1.u8         {d6}, [r4], r5          ;store result
+    vmov            q9, q11
+    vst1.u8         {d7}, [r4], r5
+    vmov            q10, q12
+    vst1.u8         {d8}, [r4], r5
+    vmov            d22, d26
+    vst1.u8         {d9}, [r4], r5
+
+    bne             secondpass_inner_loop_neon
+
+    subs            r3, r3, #1
+    sub             lr, lr, #336
+    add             lr, lr, #8
+
+    sub             r4, r4, r5, lsl #4
+    add             r4, r4, #8
+
+    bne filt_blk2d_sp16x16_outloop_neon
+
+    add             sp, sp, #336
+    pop             {r4-r5,pc}
+
+;--------------------
+firstpass_filter16x16_only
+    vabs.s32        q12, q14
+    vabs.s32        q13, q15
+
+    mov             r2, #8                  ;loop counter
+    sub             r0, r0, #2              ;move srcptr back to (column-2)
+
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vdup.8          d1, d24[4]
+    vdup.8          d2, d25[0]
+    vdup.8          d3, d25[4]
+    vdup.8          d4, d26[0]
+    vdup.8          d5, d26[4]
+
+;First Pass: output_height lines x output_width columns (16x16)
+filt_blk2d_fpo16x16_loop_neon
+    vld1.u8         {d6, d7, d8}, [r0], r1      ;load src data
+    vld1.u8         {d9, d10, d11}, [r0], r1
+
+    pld             [r0]
+    pld             [r0, r1]
+
+    vmull.u8        q6, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q7, d7, d0
+    vmull.u8        q8, d9, d0
+    vmull.u8        q9, d10, d0
+
+    vext.8          d20, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d21, d9, d10, #1
+    vext.8          d22, d7, d8, #1
+    vext.8          d23, d10, d11, #1
+    vext.8          d24, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d25, d9, d10, #4
+    vext.8          d26, d7, d8, #4
+    vext.8          d27, d10, d11, #4
+    vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d29, d9, d10, #5
+
+    vmlsl.u8        q6, d20, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d21, d1
+    vmlsl.u8        q7, d22, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q9, d23, d1
+    vmlsl.u8        q6, d24, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d25, d4
+    vmlsl.u8        q7, d26, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q9, d27, d4
+    vmlal.u8        q6, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q8, d29, d5
+
+    vext.8          d20, d7, d8, #5
+    vext.8          d21, d10, d11, #5
+    vext.8          d22, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d23, d9, d10, #2
+    vext.8          d24, d7, d8, #2
+    vext.8          d25, d10, d11, #2
+
+    vext.8          d26, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d27, d9, d10, #3
+    vext.8          d28, d7, d8, #3
+    vext.8          d29, d10, d11, #3
+
+    vmlal.u8        q7, d20, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q9, d21, d5
+    vmlal.u8        q6, d22, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d23, d2
+    vmlal.u8        q7, d24, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q9, d25, d2
+
+    vmull.u8        q10, d26, d3            ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q11, d27, d3
+    vmull.u8        q12, d28, d3            ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q15, d29, d3
+
+    vqadd.s16       q6, q10                 ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q11
+    vqadd.s16       q7, q12
+    vqadd.s16       q9, q15
+
+    subs            r2, r2, #1
+
+    vqrshrun.s16    d6, q6, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q7, #7
+    vqrshrun.s16    d8, q8, #7
+    vqrshrun.s16    d9, q9, #7
+
+    vst1.u8         {q3}, [r4], r5              ;store result
+    vst1.u8         {q4}, [r4], r5
+
+    bne             filt_blk2d_fpo16x16_loop_neon
+
+    pop             {r4-r5,pc}
+
+;--------------------
+secondpass_filter16x16_only
+;Second pass: 16x16
+    add             r3, r12, r3, lsl #5
+    sub             r0, r0, r1, lsl #1
+
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+    mov             r3, #2                  ;loop counter
+
+    vabs.s32        q7, q5
+    vabs.s32        q8, q6
+
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vdup.8          d1, d14[4]
+    vdup.8          d2, d15[0]
+    vdup.8          d3, d15[4]
+    vdup.8          d4, d16[0]
+    vdup.8          d5, d16[4]
+
+filt_blk2d_spo16x16_outloop_neon
+    vld1.u8         {d18}, [r0], r1         ;load src data
+    vld1.u8         {d19}, [r0], r1
+    vld1.u8         {d20}, [r0], r1
+    vld1.u8         {d21}, [r0], r1
+    mov             r12, #4                 ;loop counter
+    vld1.u8         {d22}, [r0], r1
+
+secondpass_only_inner_loop_neon
+    vld1.u8         {d23}, [r0], r1         ;load src data
+    vld1.u8         {d24}, [r0], r1
+    vld1.u8         {d25}, [r0], r1
+    vld1.u8         {d26}, [r0], r1
+
+    vmull.u8        q3, d18, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d19, d0
+    vmull.u8        q5, d20, d0
+    vmull.u8        q6, d21, d0
+
+    vmlsl.u8        q3, d19, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q4, d20, d1
+    vmlsl.u8        q5, d21, d1
+    vmlsl.u8        q6, d22, d1
+
+    vmlsl.u8        q3, d22, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d23, d4
+    vmlsl.u8        q5, d24, d4
+    vmlsl.u8        q6, d25, d4
+
+    vmlal.u8        q3, d20, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d21, d2
+    vmlal.u8        q5, d22, d2
+    vmlal.u8        q6, d23, d2
+
+    vmlal.u8        q3, d23, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q4, d24, d5
+    vmlal.u8        q5, d25, d5
+    vmlal.u8        q6, d26, d5
+
+    vmull.u8        q7, d21, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q8, d22, d3
+    vmull.u8        q9, d23, d3
+    vmull.u8        q10, d24, d3
+
+    subs            r12, r12, #1
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q8, #7
+    vqrshrun.s16    d8, q9, #7
+    vqrshrun.s16    d9, q10, #7
+
+    vst1.u8         {d6}, [r4], r5          ;store result
+    vmov            q9, q11
+    vst1.u8         {d7}, [r4], r5
+    vmov            q10, q12
+    vst1.u8         {d8}, [r4], r5
+    vmov            d22, d26
+    vst1.u8         {d9}, [r4], r5
+
+    bne             secondpass_only_inner_loop_neon
+
+    subs            r3, r3, #1
+    sub             r0, r0, r1, lsl #4
+    sub             r0, r0, r1, lsl #2
+    sub             r0, r0, r1
+    add             r0, r0, #8
+
+    sub             r4, r4, r5, lsl #4
+    add             r4, r4, #8
+
+    bne filt_blk2d_spo16x16_outloop_neon
+
+    pop             {r4-r5,pc}
+
+    ENDP
+
+;-----------------
+    AREA    subpelfilters16_dat, DATA, READWRITE            ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_filter16_coeff_
+    DCD     filter16_coeff
+filter16_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
+    END
diff --git a/vp8/common/arm/neon/sixtappredict4x4_neon.asm b/vp8/common/arm/neon/sixtappredict4x4_neon.asm
new file mode 100644 (file)
index 0000000..c23a9db
--- /dev/null
@@ -0,0 +1,425 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sixtap_predict_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; stack(r4) unsigned char *dst_ptr,
+; stack(lr) int  dst_pitch
+
+|vp8_sixtap_predict_neon| PROC
+    push            {r4, lr}
+
+    ldr             r12, _filter4_coeff_
+    ldr             r4, [sp, #8]            ;load parameters from stack
+    ldr             lr, [sp, #12]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_filter4x4_only
+
+    add             r2, r12, r2, lsl #5     ;calculate filter location
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+    vld1.s32        {q14, q15}, [r2]        ;load first_pass filter
+
+    beq             firstpass_filter4x4_only
+
+    vabs.s32        q12, q14                ;get abs(filer_parameters)
+    vabs.s32        q13, q15
+
+    sub             r0, r0, #2              ;go back 2 columns of src data
+    sub             r0, r0, r1, lsl #1      ;go back 2 lines of src data
+
+;First pass: output_height lines x output_width columns (9x4)
+    vld1.u8         {q3}, [r0], r1          ;load first 4-line src data
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vld1.u8         {q4}, [r0], r1
+    vdup.8          d1, d24[4]
+    vld1.u8         {q5}, [r0], r1
+    vdup.8          d2, d25[0]
+    vld1.u8         {q6}, [r0], r1
+    vdup.8          d3, d25[4]
+    vdup.8          d4, d26[0]
+    vdup.8          d5, d26[4]
+
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vext.8          d18, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d19, d8, d9, #5
+    vext.8          d20, d10, d11, #5
+    vext.8          d21, d12, d13, #5
+
+    vswp            d7, d8                  ;discard 2nd half data after src_ptr[3] is done
+    vswp            d11, d12
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[3])
+    vzip.32         d20, d21
+    vmull.u8        q7, d18, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmull.u8        q8, d20, d5
+
+    vmov            q4, q3                  ;keep original src data in q4 q6
+    vmov            q6, q5
+
+    vzip.32         d6, d7                  ;construct src_ptr[-2], and put 2-line data together
+    vzip.32         d10, d11
+    vshr.u64        q9, q4, #8              ;construct src_ptr[-1]
+    vshr.u64        q10, q6, #8
+    vmlal.u8        q7, d6, d0              ;+(src_ptr[-2] * vp8_filter[0])
+    vmlal.u8        q8, d10, d0
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[-1])
+    vzip.32         d20, d21
+    vshr.u64        q3, q4, #32             ;construct src_ptr[2]
+    vshr.u64        q5, q6, #32
+    vmlsl.u8        q7, d18, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d20, d1
+
+    vzip.32         d6, d7                  ;put 2-line data in 1 register (src_ptr[2])
+    vzip.32         d10, d11
+    vshr.u64        q9, q4, #16             ;construct src_ptr[0]
+    vshr.u64        q10, q6, #16
+    vmlsl.u8        q7, d6, d4              ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d10, d4
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[0])
+    vzip.32         d20, d21
+    vshr.u64        q3, q4, #24             ;construct src_ptr[1]
+    vshr.u64        q5, q6, #24
+    vmlal.u8        q7, d18, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d20, d2
+
+    vzip.32         d6, d7                  ;put 2-line data in 1 register (src_ptr[1])
+    vzip.32         d10, d11
+    vmull.u8        q9, d6, d3              ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q10, d10, d3
+
+    vld1.u8         {q3}, [r0], r1          ;load rest 5-line src data
+    vld1.u8         {q4}, [r0], r1
+
+    vqadd.s16       q7, q9                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q10
+
+    vld1.u8         {q5}, [r0], r1
+    vld1.u8         {q6}, [r0], r1
+
+    vqrshrun.s16    d27, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d28, q8, #7
+
+    ;First Pass on rest 5-line data
+    vld1.u8         {q11}, [r0], r1
+
+    vext.8          d18, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d19, d8, d9, #5
+    vext.8          d20, d10, d11, #5
+    vext.8          d21, d12, d13, #5
+
+    vswp            d7, d8                  ;discard 2nd half data after src_ptr[3] is done
+    vswp            d11, d12
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[3])
+    vzip.32         d20, d21
+    vext.8          d31, d22, d23, #5       ;construct src_ptr[3]
+    vmull.u8        q7, d18, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmull.u8        q8, d20, d5
+    vmull.u8        q12, d31, d5            ;(src_ptr[3] * vp8_filter[5])
+
+    vmov            q4, q3                  ;keep original src data in q4 q6
+    vmov            q6, q5
+
+    vzip.32         d6, d7                  ;construct src_ptr[-2], and put 2-line data together
+    vzip.32         d10, d11
+    vshr.u64        q9, q4, #8              ;construct src_ptr[-1]
+    vshr.u64        q10, q6, #8
+
+    vmlal.u8        q7, d6, d0              ;+(src_ptr[-2] * vp8_filter[0])
+    vmlal.u8        q8, d10, d0
+    vmlal.u8        q12, d22, d0            ;(src_ptr[-2] * vp8_filter[0])
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[-1])
+    vzip.32         d20, d21
+    vshr.u64        q3, q4, #32             ;construct src_ptr[2]
+    vshr.u64        q5, q6, #32
+    vext.8          d31, d22, d23, #1       ;construct src_ptr[-1]
+
+    vmlsl.u8        q7, d18, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d20, d1
+    vmlsl.u8        q12, d31, d1            ;-(src_ptr[-1] * vp8_filter[1])
+
+    vzip.32         d6, d7                  ;put 2-line data in 1 register (src_ptr[2])
+    vzip.32         d10, d11
+    vshr.u64        q9, q4, #16             ;construct src_ptr[0]
+    vshr.u64        q10, q6, #16
+    vext.8          d31, d22, d23, #4       ;construct src_ptr[2]
+
+    vmlsl.u8        q7, d6, d4              ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d10, d4
+    vmlsl.u8        q12, d31, d4            ;-(src_ptr[2] * vp8_filter[4])
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[0])
+    vzip.32         d20, d21
+    vshr.u64        q3, q4, #24             ;construct src_ptr[1]
+    vshr.u64        q5, q6, #24
+    vext.8          d31, d22, d23, #2       ;construct src_ptr[0]
+
+    vmlal.u8        q7, d18, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d20, d2
+    vmlal.u8        q12, d31, d2            ;(src_ptr[0] * vp8_filter[2])
+
+    vzip.32         d6, d7                  ;put 2-line data in 1 register (src_ptr[1])
+    vzip.32         d10, d11
+    vext.8          d31, d22, d23, #3       ;construct src_ptr[1]
+    vmull.u8        q9, d6, d3              ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q10, d10, d3
+    vmull.u8        q11, d31, d3            ;(src_ptr[1] * vp8_filter[3])
+
+    add             r3, r12, r3, lsl #5
+
+    vqadd.s16       q7, q9                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q10
+    vqadd.s16       q12, q11
+
+    vext.8          d23, d27, d28, #4
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+
+    vqrshrun.s16    d29, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d30, q8, #7
+    vqrshrun.s16    d31, q12, #7
+
+;Second pass: 4x4
+    vabs.s32        q7, q5
+    vabs.s32        q8, q6
+
+    vext.8          d24, d28, d29, #4
+    vext.8          d25, d29, d30, #4
+    vext.8          d26, d30, d31, #4
+
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vdup.8          d1, d14[4]
+    vdup.8          d2, d15[0]
+    vdup.8          d3, d15[4]
+    vdup.8          d4, d16[0]
+    vdup.8          d5, d16[4]
+
+    vmull.u8        q3, d27, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d28, d0
+
+    vmull.u8        q5, d25, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmull.u8        q6, d26, d5
+
+    vmlsl.u8        q3, d29, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d30, d4
+
+    vmlsl.u8        q5, d23, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q6, d24, d1
+
+    vmlal.u8        q3, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d29, d2
+
+    vmlal.u8        q5, d24, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmlal.u8        q6, d25, d3
+
+    add             r0, r4, lr
+    add             r1, r0, lr
+    add             r2, r1, lr
+
+    vqadd.s16       q5, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q6, q4
+
+    vqrshrun.s16    d3, q5, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d4, q6, #7
+
+    vst1.32         {d3[0]}, [r4]           ;store result
+    vst1.32         {d3[1]}, [r0]
+    vst1.32         {d4[0]}, [r1]
+    vst1.32         {d4[1]}, [r2]
+
+    pop             {r4, pc}
+
+
+;---------------------
+firstpass_filter4x4_only
+    vabs.s32        q12, q14                ;get abs(filer_parameters)
+    vabs.s32        q13, q15
+
+    sub             r0, r0, #2              ;go back 2 columns of src data
+
+;First pass: output_height lines x output_width columns (4x4)
+    vld1.u8         {q3}, [r0], r1          ;load first 4-line src data
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vld1.u8         {q4}, [r0], r1
+    vdup.8          d1, d24[4]
+    vld1.u8         {q5}, [r0], r1
+    vdup.8          d2, d25[0]
+    vld1.u8         {q6}, [r0], r1
+
+    vdup.8          d3, d25[4]
+    vdup.8          d4, d26[0]
+    vdup.8          d5, d26[4]
+
+    vext.8          d18, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d19, d8, d9, #5
+    vext.8          d20, d10, d11, #5
+    vext.8          d21, d12, d13, #5
+
+    vswp            d7, d8                  ;discard 2nd half data after src_ptr[3] is done
+    vswp            d11, d12
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[3])
+    vzip.32         d20, d21
+    vmull.u8        q7, d18, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmull.u8        q8, d20, d5
+
+    vmov            q4, q3                  ;keep original src data in q4 q6
+    vmov            q6, q5
+
+    vzip.32         d6, d7                  ;construct src_ptr[-2], and put 2-line data together
+    vzip.32         d10, d11
+    vshr.u64        q9, q4, #8              ;construct src_ptr[-1]
+    vshr.u64        q10, q6, #8
+    vmlal.u8        q7, d6, d0              ;+(src_ptr[-2] * vp8_filter[0])
+    vmlal.u8        q8, d10, d0
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[-1])
+    vzip.32         d20, d21
+    vshr.u64        q3, q4, #32             ;construct src_ptr[2]
+    vshr.u64        q5, q6, #32
+    vmlsl.u8        q7, d18, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d20, d1
+
+    vzip.32         d6, d7                  ;put 2-line data in 1 register (src_ptr[2])
+    vzip.32         d10, d11
+    vshr.u64        q9, q4, #16             ;construct src_ptr[0]
+    vshr.u64        q10, q6, #16
+    vmlsl.u8        q7, d6, d4              ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d10, d4
+
+    vzip.32         d18, d19                ;put 2-line data in 1 register (src_ptr[0])
+    vzip.32         d20, d21
+    vshr.u64        q3, q4, #24             ;construct src_ptr[1]
+    vshr.u64        q5, q6, #24
+    vmlal.u8        q7, d18, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d20, d2
+
+    vzip.32         d6, d7                  ;put 2-line data in 1 register (src_ptr[1])
+    vzip.32         d10, d11
+    vmull.u8        q9, d6, d3              ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q10, d10, d3
+
+    add             r0, r4, lr
+    add             r1, r0, lr
+    add             r2, r1, lr
+
+    vqadd.s16       q7, q9                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q10
+
+    vqrshrun.s16    d27, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d28, q8, #7
+
+    vst1.32         {d27[0]}, [r4]          ;store result
+    vst1.32         {d27[1]}, [r0]
+    vst1.32         {d28[0]}, [r1]
+    vst1.32         {d28[1]}, [r2]
+
+    pop             {r4, pc}
+
+
+;---------------------
+secondpass_filter4x4_only
+    sub             r0, r0, r1, lsl #1
+    add             r3, r12, r3, lsl #5
+
+    vld1.32         {d27[0]}, [r0], r1      ;load src data
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+    vld1.32         {d27[1]}, [r0], r1
+    vabs.s32        q7, q5
+    vld1.32         {d28[0]}, [r0], r1
+    vabs.s32        q8, q6
+    vld1.32         {d28[1]}, [r0], r1
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vld1.32         {d29[0]}, [r0], r1
+    vdup.8          d1, d14[4]
+    vld1.32         {d29[1]}, [r0], r1
+    vdup.8          d2, d15[0]
+    vld1.32         {d30[0]}, [r0], r1
+    vdup.8          d3, d15[4]
+    vld1.32         {d30[1]}, [r0], r1
+    vdup.8          d4, d16[0]
+    vld1.32         {d31[0]}, [r0], r1
+    vdup.8          d5, d16[4]
+
+    vext.8          d23, d27, d28, #4
+    vext.8          d24, d28, d29, #4
+    vext.8          d25, d29, d30, #4
+    vext.8          d26, d30, d31, #4
+
+    vmull.u8        q3, d27, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d28, d0
+
+    vmull.u8        q5, d25, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmull.u8        q6, d26, d5
+
+    vmlsl.u8        q3, d29, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d30, d4
+
+    vmlsl.u8        q5, d23, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q6, d24, d1
+
+    vmlal.u8        q3, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d29, d2
+
+    vmlal.u8        q5, d24, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmlal.u8        q6, d25, d3
+
+    add             r0, r4, lr
+    add             r1, r0, lr
+    add             r2, r1, lr
+
+    vqadd.s16       q5, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q6, q4
+
+    vqrshrun.s16    d3, q5, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d4, q6, #7
+
+    vst1.32         {d3[0]}, [r4]           ;store result
+    vst1.32         {d3[1]}, [r0]
+    vst1.32         {d4[0]}, [r1]
+    vst1.32         {d4[1]}, [r2]
+
+    pop             {r4, pc}
+
+    ENDP
+
+;-----------------
+    AREA    subpelfilters4_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_filter4_coeff_
+    DCD     filter4_coeff
+filter4_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
+    END
diff --git a/vp8/common/arm/neon/sixtappredict8x4_neon.asm b/vp8/common/arm/neon/sixtappredict8x4_neon.asm
new file mode 100644 (file)
index 0000000..18e19f9
--- /dev/null
@@ -0,0 +1,476 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sixtap_predict8x4_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; r4    unsigned char *dst_ptr,
+; stack(r5) int  dst_pitch
+
+|vp8_sixtap_predict8x4_neon| PROC
+    push            {r4-r5, lr}
+
+    ldr             r12, _filter8_coeff_
+    ldr             r4, [sp, #12]           ;load parameters from stack
+    ldr             r5, [sp, #16]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_filter8x4_only
+
+    add             r2, r12, r2, lsl #5     ;calculate filter location
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+
+    vld1.s32        {q14, q15}, [r2]        ;load first_pass filter
+
+    beq             firstpass_filter8x4_only
+
+    sub             sp, sp, #32             ;reserve space on stack for temporary storage
+    vabs.s32        q12, q14
+    vabs.s32        q13, q15
+
+    sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
+    mov             lr, sp
+    sub             r0, r0, r1, lsl #1
+
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vdup.8          d1, d24[4]
+    vdup.8          d2, d25[0]
+
+;First pass: output_height lines x output_width columns (9x8)
+    vld1.u8         {q3}, [r0], r1          ;load src data
+    vdup.8          d3, d25[4]
+    vld1.u8         {q4}, [r0], r1
+    vdup.8          d4, d26[0]
+    vld1.u8         {q5}, [r0], r1
+    vdup.8          d5, d26[4]
+    vld1.u8         {q6}, [r0], r1
+
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q8, d8, d0
+    vmull.u8        q9, d10, d0
+    vmull.u8        q10, d12, d0
+
+    vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d29, d8, d9, #1
+    vext.8          d30, d10, d11, #1
+    vext.8          d31, d12, d13, #1
+
+    vmlsl.u8        q7, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d29, d1
+    vmlsl.u8        q9, d30, d1
+    vmlsl.u8        q10, d31, d1
+
+    vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d29, d8, d9, #4
+    vext.8          d30, d10, d11, #4
+    vext.8          d31, d12, d13, #4
+
+    vmlsl.u8        q7, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d29, d4
+    vmlsl.u8        q9, d30, d4
+    vmlsl.u8        q10, d31, d4
+
+    vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d29, d8, d9, #2
+    vext.8          d30, d10, d11, #2
+    vext.8          d31, d12, d13, #2
+
+    vmlal.u8        q7, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d29, d2
+    vmlal.u8        q9, d30, d2
+    vmlal.u8        q10, d31, d2
+
+    vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d29, d8, d9, #5
+    vext.8          d30, d10, d11, #5
+    vext.8          d31, d12, d13, #5
+
+    vmlal.u8        q7, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q8, d29, d5
+    vmlal.u8        q9, d30, d5
+    vmlal.u8        q10, d31, d5
+
+    vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d29, d8, d9, #3
+    vext.8          d30, d10, d11, #3
+    vext.8          d31, d12, d13, #3
+
+    vmull.u8        q3, d28, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q4, d29, d3
+    vmull.u8        q5, d30, d3
+    vmull.u8        q6, d31, d3
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vld1.u8         {q3}, [r0], r1          ;load src data
+
+    vqrshrun.s16    d22, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d23, q8, #7
+    vqrshrun.s16    d24, q9, #7
+    vqrshrun.s16    d25, q10, #7
+
+    vld1.u8         {q4}, [r0], r1
+    vst1.u8         {d22}, [lr]!            ;store result
+    vld1.u8         {q5}, [r0], r1
+    vst1.u8         {d23}, [lr]!
+    vld1.u8         {q6}, [r0], r1
+    vst1.u8         {d24}, [lr]!
+    vld1.u8         {q7}, [r0], r1
+    vst1.u8         {d25}, [lr]!
+
+    ;first_pass filtering on the rest 5-line data
+    vmull.u8        q8, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q9, d8, d0
+    vmull.u8        q10, d10, d0
+    vmull.u8        q11, d12, d0
+    vmull.u8        q12, d14, d0
+
+    vext.8          d27, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d28, d8, d9, #1
+    vext.8          d29, d10, d11, #1
+    vext.8          d30, d12, d13, #1
+    vext.8          d31, d14, d15, #1
+
+    vmlsl.u8        q8, d27, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q9, d28, d1
+    vmlsl.u8        q10, d29, d1
+    vmlsl.u8        q11, d30, d1
+    vmlsl.u8        q12, d31, d1
+
+    vext.8          d27, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d28, d8, d9, #4
+    vext.8          d29, d10, d11, #4
+    vext.8          d30, d12, d13, #4
+    vext.8          d31, d14, d15, #4
+
+    vmlsl.u8        q8, d27, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q9, d28, d4
+    vmlsl.u8        q10, d29, d4
+    vmlsl.u8        q11, d30, d4
+    vmlsl.u8        q12, d31, d4
+
+    vext.8          d27, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d28, d8, d9, #2
+    vext.8          d29, d10, d11, #2
+    vext.8          d30, d12, d13, #2
+    vext.8          d31, d14, d15, #2
+
+    vmlal.u8        q8, d27, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q9, d28, d2
+    vmlal.u8        q10, d29, d2
+    vmlal.u8        q11, d30, d2
+    vmlal.u8        q12, d31, d2
+
+    vext.8          d27, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d28, d8, d9, #5
+    vext.8          d29, d10, d11, #5
+    vext.8          d30, d12, d13, #5
+    vext.8          d31, d14, d15, #5
+
+    vmlal.u8        q8, d27, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q9, d28, d5
+    vmlal.u8        q10, d29, d5
+    vmlal.u8        q11, d30, d5
+    vmlal.u8        q12, d31, d5
+
+    vext.8          d27, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d28, d8, d9, #3
+    vext.8          d29, d10, d11, #3
+    vext.8          d30, d12, d13, #3
+    vext.8          d31, d14, d15, #3
+
+    vmull.u8        q3, d27, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q4, d28, d3
+    vmull.u8        q5, d29, d3
+    vmull.u8        q6, d30, d3
+    vmull.u8        q7, d31, d3
+
+    vqadd.s16       q8, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q9, q4
+    vqadd.s16       q10, q5
+    vqadd.s16       q11, q6
+    vqadd.s16       q12, q7
+
+    vqrshrun.s16    d26, q8, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d27, q9, #7
+    vqrshrun.s16    d28, q10, #7
+    vqrshrun.s16    d29, q11, #7                ;load intermediate data from stack
+    vqrshrun.s16    d30, q12, #7
+
+;Second pass: 8x4
+;secondpass_filter
+    add             r3, r12, r3, lsl #5
+    sub             lr, lr, #32
+
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+    vld1.u8         {q11}, [lr]!
+
+    vabs.s32        q7, q5
+    vabs.s32        q8, q6
+
+    vld1.u8         {q12}, [lr]!
+
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vdup.8          d1, d14[4]
+    vdup.8          d2, d15[0]
+    vdup.8          d3, d15[4]
+    vdup.8          d4, d16[0]
+    vdup.8          d5, d16[4]
+
+    vmull.u8        q3, d22, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d23, d0
+    vmull.u8        q5, d24, d0
+    vmull.u8        q6, d25, d0
+
+    vmlsl.u8        q3, d23, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q4, d24, d1
+    vmlsl.u8        q5, d25, d1
+    vmlsl.u8        q6, d26, d1
+
+    vmlsl.u8        q3, d26, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d27, d4
+    vmlsl.u8        q5, d28, d4
+    vmlsl.u8        q6, d29, d4
+
+    vmlal.u8        q3, d24, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d25, d2
+    vmlal.u8        q5, d26, d2
+    vmlal.u8        q6, d27, d2
+
+    vmlal.u8        q3, d27, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q4, d28, d5
+    vmlal.u8        q5, d29, d5
+    vmlal.u8        q6, d30, d5
+
+    vmull.u8        q7, d25, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q8, d26, d3
+    vmull.u8        q9, d27, d3
+    vmull.u8        q10, d28, d3
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q8, #7
+    vqrshrun.s16    d8, q9, #7
+    vqrshrun.s16    d9, q10, #7
+
+    vst1.u8         {d6}, [r4], r5          ;store result
+    vst1.u8         {d7}, [r4], r5
+    vst1.u8         {d8}, [r4], r5
+    vst1.u8         {d9}, [r4], r5
+
+    add             sp, sp, #32
+    pop             {r4-r5,pc}
+
+;--------------------
+firstpass_filter8x4_only
+    vabs.s32        q12, q14
+    vabs.s32        q13, q15
+
+    sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
+    vld1.u8         {q3}, [r0], r1          ;load src data
+
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vld1.u8         {q4}, [r0], r1
+    vdup.8          d1, d24[4]
+    vld1.u8         {q5}, [r0], r1
+    vdup.8          d2, d25[0]
+    vld1.u8         {q6}, [r0], r1
+    vdup.8          d3, d25[4]
+    vdup.8          d4, d26[0]
+    vdup.8          d5, d26[4]
+
+;First pass: output_height lines x output_width columns (4x8)
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q8, d8, d0
+    vmull.u8        q9, d10, d0
+    vmull.u8        q10, d12, d0
+
+    vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d29, d8, d9, #1
+    vext.8          d30, d10, d11, #1
+    vext.8          d31, d12, d13, #1
+
+    vmlsl.u8        q7, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d29, d1
+    vmlsl.u8        q9, d30, d1
+    vmlsl.u8        q10, d31, d1
+
+    vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d29, d8, d9, #4
+    vext.8          d30, d10, d11, #4
+    vext.8          d31, d12, d13, #4
+
+    vmlsl.u8        q7, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d29, d4
+    vmlsl.u8        q9, d30, d4
+    vmlsl.u8        q10, d31, d4
+
+    vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d29, d8, d9, #2
+    vext.8          d30, d10, d11, #2
+    vext.8          d31, d12, d13, #2
+
+    vmlal.u8        q7, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d29, d2
+    vmlal.u8        q9, d30, d2
+    vmlal.u8        q10, d31, d2
+
+    vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d29, d8, d9, #5
+    vext.8          d30, d10, d11, #5
+    vext.8          d31, d12, d13, #5
+
+    vmlal.u8        q7, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q8, d29, d5
+    vmlal.u8        q9, d30, d5
+    vmlal.u8        q10, d31, d5
+
+    vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d29, d8, d9, #3
+    vext.8          d30, d10, d11, #3
+    vext.8          d31, d12, d13, #3
+
+    vmull.u8        q3, d28, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q4, d29, d3
+    vmull.u8        q5, d30, d3
+    vmull.u8        q6, d31, d3
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d22, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d23, q8, #7
+    vqrshrun.s16    d24, q9, #7
+    vqrshrun.s16    d25, q10, #7
+
+    vst1.u8         {d22}, [r4], r5         ;store result
+    vst1.u8         {d23}, [r4], r5
+    vst1.u8         {d24}, [r4], r5
+    vst1.u8         {d25}, [r4], r5
+
+    pop             {r4-r5,pc}
+
+;---------------------
+secondpass_filter8x4_only
+;Second pass: 8x4
+    add             r3, r12, r3, lsl #5
+    sub             r0, r0, r1, lsl #1
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+    vabs.s32        q7, q5
+    vabs.s32        q8, q6
+
+    vld1.u8         {d22}, [r0], r1
+    vld1.u8         {d23}, [r0], r1
+    vld1.u8         {d24}, [r0], r1
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vld1.u8         {d25}, [r0], r1
+    vdup.8          d1, d14[4]
+    vld1.u8         {d26}, [r0], r1
+    vdup.8          d2, d15[0]
+    vld1.u8         {d27}, [r0], r1
+    vdup.8          d3, d15[4]
+    vld1.u8         {d28}, [r0], r1
+    vdup.8          d4, d16[0]
+    vld1.u8         {d29}, [r0], r1
+    vdup.8          d5, d16[4]
+    vld1.u8         {d30}, [r0], r1
+
+    vmull.u8        q3, d22, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d23, d0
+    vmull.u8        q5, d24, d0
+    vmull.u8        q6, d25, d0
+
+    vmlsl.u8        q3, d23, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q4, d24, d1
+    vmlsl.u8        q5, d25, d1
+    vmlsl.u8        q6, d26, d1
+
+    vmlsl.u8        q3, d26, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d27, d4
+    vmlsl.u8        q5, d28, d4
+    vmlsl.u8        q6, d29, d4
+
+    vmlal.u8        q3, d24, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d25, d2
+    vmlal.u8        q5, d26, d2
+    vmlal.u8        q6, d27, d2
+
+    vmlal.u8        q3, d27, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q4, d28, d5
+    vmlal.u8        q5, d29, d5
+    vmlal.u8        q6, d30, d5
+
+    vmull.u8        q7, d25, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q8, d26, d3
+    vmull.u8        q9, d27, d3
+    vmull.u8        q10, d28, d3
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q8, #7
+    vqrshrun.s16    d8, q9, #7
+    vqrshrun.s16    d9, q10, #7
+
+    vst1.u8         {d6}, [r4], r5          ;store result
+    vst1.u8         {d7}, [r4], r5
+    vst1.u8         {d8}, [r4], r5
+    vst1.u8         {d9}, [r4], r5
+
+    pop             {r4-r5,pc}
+
+    ENDP
+
+;-----------------
+    AREA    subpelfilters8_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_filter8_coeff_
+    DCD     filter8_coeff
+filter8_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
+    END
diff --git a/vp8/common/arm/neon/sixtappredict8x8_neon.asm b/vp8/common/arm/neon/sixtappredict8x8_neon.asm
new file mode 100644 (file)
index 0000000..d27485e
--- /dev/null
@@ -0,0 +1,527 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sixtap_predict8x8_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; stack(r4) unsigned char *dst_ptr,
+; stack(r5) int  dst_pitch
+
+|vp8_sixtap_predict8x8_neon| PROC
+    push            {r4-r5, lr}
+
+    ldr             r12, _filter8_coeff_
+
+    ldr             r4, [sp, #12]           ;load parameters from stack
+    ldr             r5, [sp, #16]           ;load parameters from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_filter8x8_only
+
+    add             r2, r12, r2, lsl #5     ;calculate filter location
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+
+    vld1.s32        {q14, q15}, [r2]        ;load first_pass filter
+
+    beq             firstpass_filter8x8_only
+
+    sub             sp, sp, #64             ;reserve space on stack for temporary storage
+    mov             lr, sp
+
+    vabs.s32        q12, q14
+    vabs.s32        q13, q15
+
+    mov             r2, #2                  ;loop counter
+    sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
+    sub             r0, r0, r1, lsl #1
+
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vdup.8          d1, d24[4]
+    vdup.8          d2, d25[0]
+
+;First pass: output_height lines x output_width columns (13x8)
+    vld1.u8         {q3}, [r0], r1          ;load src data
+    vdup.8          d3, d25[4]
+    vld1.u8         {q4}, [r0], r1
+    vdup.8          d4, d26[0]
+    vld1.u8         {q5}, [r0], r1
+    vdup.8          d5, d26[4]
+    vld1.u8         {q6}, [r0], r1
+
+filt_blk2d_fp8x8_loop_neon
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q8, d8, d0
+    vmull.u8        q9, d10, d0
+    vmull.u8        q10, d12, d0
+
+    vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d29, d8, d9, #1
+    vext.8          d30, d10, d11, #1
+    vext.8          d31, d12, d13, #1
+
+    vmlsl.u8        q7, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d29, d1
+    vmlsl.u8        q9, d30, d1
+    vmlsl.u8        q10, d31, d1
+
+    vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d29, d8, d9, #4
+    vext.8          d30, d10, d11, #4
+    vext.8          d31, d12, d13, #4
+
+    vmlsl.u8        q7, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d29, d4
+    vmlsl.u8        q9, d30, d4
+    vmlsl.u8        q10, d31, d4
+
+    vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d29, d8, d9, #2
+    vext.8          d30, d10, d11, #2
+    vext.8          d31, d12, d13, #2
+
+    vmlal.u8        q7, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d29, d2
+    vmlal.u8        q9, d30, d2
+    vmlal.u8        q10, d31, d2
+
+    vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d29, d8, d9, #5
+    vext.8          d30, d10, d11, #5
+    vext.8          d31, d12, d13, #5
+
+    vmlal.u8        q7, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q8, d29, d5
+    vmlal.u8        q9, d30, d5
+    vmlal.u8        q10, d31, d5
+
+    vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d29, d8, d9, #3
+    vext.8          d30, d10, d11, #3
+    vext.8          d31, d12, d13, #3
+
+    vmull.u8        q3, d28, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q4, d29, d3
+    vmull.u8        q5, d30, d3
+    vmull.u8        q6, d31, d3
+
+    subs            r2, r2, #1
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vld1.u8         {q3}, [r0], r1          ;load src data
+
+    vqrshrun.s16    d22, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d23, q8, #7
+    vqrshrun.s16    d24, q9, #7
+    vqrshrun.s16    d25, q10, #7
+
+    vst1.u8         {d22}, [lr]!            ;store result
+    vld1.u8         {q4}, [r0], r1
+    vst1.u8         {d23}, [lr]!
+    vld1.u8         {q5}, [r0], r1
+    vst1.u8         {d24}, [lr]!
+    vld1.u8         {q6}, [r0], r1
+    vst1.u8         {d25}, [lr]!
+
+    bne             filt_blk2d_fp8x8_loop_neon
+
+    ;first_pass filtering on the rest 5-line data
+    ;vld1.u8            {q3}, [r0], r1          ;load src data
+    ;vld1.u8            {q4}, [r0], r1
+    ;vld1.u8            {q5}, [r0], r1
+    ;vld1.u8            {q6}, [r0], r1
+    vld1.u8         {q7}, [r0], r1
+
+    vmull.u8        q8, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q9, d8, d0
+    vmull.u8        q10, d10, d0
+    vmull.u8        q11, d12, d0
+    vmull.u8        q12, d14, d0
+
+    vext.8          d27, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d28, d8, d9, #1
+    vext.8          d29, d10, d11, #1
+    vext.8          d30, d12, d13, #1
+    vext.8          d31, d14, d15, #1
+
+    vmlsl.u8        q8, d27, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q9, d28, d1
+    vmlsl.u8        q10, d29, d1
+    vmlsl.u8        q11, d30, d1
+    vmlsl.u8        q12, d31, d1
+
+    vext.8          d27, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d28, d8, d9, #4
+    vext.8          d29, d10, d11, #4
+    vext.8          d30, d12, d13, #4
+    vext.8          d31, d14, d15, #4
+
+    vmlsl.u8        q8, d27, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q9, d28, d4
+    vmlsl.u8        q10, d29, d4
+    vmlsl.u8        q11, d30, d4
+    vmlsl.u8        q12, d31, d4
+
+    vext.8          d27, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d28, d8, d9, #2
+    vext.8          d29, d10, d11, #2
+    vext.8          d30, d12, d13, #2
+    vext.8          d31, d14, d15, #2
+
+    vmlal.u8        q8, d27, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q9, d28, d2
+    vmlal.u8        q10, d29, d2
+    vmlal.u8        q11, d30, d2
+    vmlal.u8        q12, d31, d2
+
+    vext.8          d27, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d28, d8, d9, #5
+    vext.8          d29, d10, d11, #5
+    vext.8          d30, d12, d13, #5
+    vext.8          d31, d14, d15, #5
+
+    vmlal.u8        q8, d27, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q9, d28, d5
+    vmlal.u8        q10, d29, d5
+    vmlal.u8        q11, d30, d5
+    vmlal.u8        q12, d31, d5
+
+    vext.8          d27, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d28, d8, d9, #3
+    vext.8          d29, d10, d11, #3
+    vext.8          d30, d12, d13, #3
+    vext.8          d31, d14, d15, #3
+
+    vmull.u8        q3, d27, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q4, d28, d3
+    vmull.u8        q5, d29, d3
+    vmull.u8        q6, d30, d3
+    vmull.u8        q7, d31, d3
+
+    vqadd.s16       q8, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q9, q4
+    vqadd.s16       q10, q5
+    vqadd.s16       q11, q6
+    vqadd.s16       q12, q7
+
+    add             r3, r12, r3, lsl #5
+
+    vqrshrun.s16    d26, q8, #7             ;shift/round/saturate to u8
+    sub             lr, lr, #64
+    vqrshrun.s16    d27, q9, #7
+    vld1.u8         {q9}, [lr]!             ;load intermediate data from stack
+    vqrshrun.s16    d28, q10, #7
+    vld1.u8         {q10}, [lr]!
+
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+
+    vqrshrun.s16    d29, q11, #7
+    vld1.u8         {q11}, [lr]!
+
+    vabs.s32        q7, q5
+    vabs.s32        q8, q6
+
+    vqrshrun.s16    d30, q12, #7
+    vld1.u8         {q12}, [lr]!
+
+;Second pass: 8x8
+    mov             r3, #2                  ;loop counter
+
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vdup.8          d1, d14[4]
+    vdup.8          d2, d15[0]
+    vdup.8          d3, d15[4]
+    vdup.8          d4, d16[0]
+    vdup.8          d5, d16[4]
+
+filt_blk2d_sp8x8_loop_neon
+    vmull.u8        q3, d18, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d19, d0
+    vmull.u8        q5, d20, d0
+    vmull.u8        q6, d21, d0
+
+    vmlsl.u8        q3, d19, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q4, d20, d1
+    vmlsl.u8        q5, d21, d1
+    vmlsl.u8        q6, d22, d1
+
+    vmlsl.u8        q3, d22, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d23, d4
+    vmlsl.u8        q5, d24, d4
+    vmlsl.u8        q6, d25, d4
+
+    vmlal.u8        q3, d20, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d21, d2
+    vmlal.u8        q5, d22, d2
+    vmlal.u8        q6, d23, d2
+
+    vmlal.u8        q3, d23, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q4, d24, d5
+    vmlal.u8        q5, d25, d5
+    vmlal.u8        q6, d26, d5
+
+    vmull.u8        q7, d21, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q8, d22, d3
+    vmull.u8        q9, d23, d3
+    vmull.u8        q10, d24, d3
+
+    subs            r3, r3, #1
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q8, #7
+    vqrshrun.s16    d8, q9, #7
+    vqrshrun.s16    d9, q10, #7
+
+    vmov            q9, q11
+    vst1.u8         {d6}, [r4], r5          ;store result
+    vmov            q10, q12
+    vst1.u8         {d7}, [r4], r5
+    vmov            q11, q13
+    vst1.u8         {d8}, [r4], r5
+    vmov            q12, q14
+    vst1.u8         {d9}, [r4], r5
+    vmov            d26, d30
+
+    bne filt_blk2d_sp8x8_loop_neon
+
+    add             sp, sp, #64
+    pop             {r4-r5,pc}
+
+;---------------------
+firstpass_filter8x8_only
+    ;add                r2, r12, r2, lsl #5     ;calculate filter location
+    ;vld1.s32       {q14, q15}, [r2]        ;load first_pass filter
+    vabs.s32        q12, q14
+    vabs.s32        q13, q15
+
+    mov             r2, #2                  ;loop counter
+    sub             r0, r0, #2              ;move srcptr back to (line-2) and (column-2)
+
+    vdup.8          d0, d24[0]              ;first_pass filter (d0-d5)
+    vdup.8          d1, d24[4]
+    vdup.8          d2, d25[0]
+    vdup.8          d3, d25[4]
+    vdup.8          d4, d26[0]
+    vdup.8          d5, d26[4]
+
+;First pass: output_height lines x output_width columns (8x8)
+filt_blk2d_fpo8x8_loop_neon
+    vld1.u8         {q3}, [r0], r1          ;load src data
+    vld1.u8         {q4}, [r0], r1
+    vld1.u8         {q5}, [r0], r1
+    vld1.u8         {q6}, [r0], r1
+
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d6, d0              ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q8, d8, d0
+    vmull.u8        q9, d10, d0
+    vmull.u8        q10, d12, d0
+
+    vext.8          d28, d6, d7, #1         ;construct src_ptr[-1]
+    vext.8          d29, d8, d9, #1
+    vext.8          d30, d10, d11, #1
+    vext.8          d31, d12, d13, #1
+
+    vmlsl.u8        q7, d28, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q8, d29, d1
+    vmlsl.u8        q9, d30, d1
+    vmlsl.u8        q10, d31, d1
+
+    vext.8          d28, d6, d7, #4         ;construct src_ptr[2]
+    vext.8          d29, d8, d9, #4
+    vext.8          d30, d10, d11, #4
+    vext.8          d31, d12, d13, #4
+
+    vmlsl.u8        q7, d28, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q8, d29, d4
+    vmlsl.u8        q9, d30, d4
+    vmlsl.u8        q10, d31, d4
+
+    vext.8          d28, d6, d7, #2         ;construct src_ptr[0]
+    vext.8          d29, d8, d9, #2
+    vext.8          d30, d10, d11, #2
+    vext.8          d31, d12, d13, #2
+
+    vmlal.u8        q7, d28, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q8, d29, d2
+    vmlal.u8        q9, d30, d2
+    vmlal.u8        q10, d31, d2
+
+    vext.8          d28, d6, d7, #5         ;construct src_ptr[3]
+    vext.8          d29, d8, d9, #5
+    vext.8          d30, d10, d11, #5
+    vext.8          d31, d12, d13, #5
+
+    vmlal.u8        q7, d28, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q8, d29, d5
+    vmlal.u8        q9, d30, d5
+    vmlal.u8        q10, d31, d5
+
+    vext.8          d28, d6, d7, #3         ;construct src_ptr[1]
+    vext.8          d29, d8, d9, #3
+    vext.8          d30, d10, d11, #3
+    vext.8          d31, d12, d13, #3
+
+    vmull.u8        q3, d28, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q4, d29, d3
+    vmull.u8        q5, d30, d3
+    vmull.u8        q6, d31, d3
+ ;
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    subs            r2, r2, #1
+
+    vqrshrun.s16    d22, q7, #7             ;shift/round/saturate to u8
+    vqrshrun.s16    d23, q8, #7
+    vqrshrun.s16    d24, q9, #7
+    vqrshrun.s16    d25, q10, #7
+
+    vst1.u8         {d22}, [r4], r5         ;store result
+    vst1.u8         {d23}, [r4], r5
+    vst1.u8         {d24}, [r4], r5
+    vst1.u8         {d25}, [r4], r5
+
+    bne             filt_blk2d_fpo8x8_loop_neon
+
+    pop             {r4-r5,pc}
+
+;---------------------
+secondpass_filter8x8_only
+    sub             r0, r0, r1, lsl #1
+    add             r3, r12, r3, lsl #5
+
+    vld1.u8         {d18}, [r0], r1         ;load src data
+    vld1.s32        {q5, q6}, [r3]          ;load second_pass filter
+    vld1.u8         {d19}, [r0], r1
+    vabs.s32        q7, q5
+    vld1.u8         {d20}, [r0], r1
+    vabs.s32        q8, q6
+    vld1.u8         {d21}, [r0], r1
+    mov             r3, #2                  ;loop counter
+    vld1.u8         {d22}, [r0], r1
+    vdup.8          d0, d14[0]              ;second_pass filter parameters (d0-d5)
+    vld1.u8         {d23}, [r0], r1
+    vdup.8          d1, d14[4]
+    vld1.u8         {d24}, [r0], r1
+    vdup.8          d2, d15[0]
+    vld1.u8         {d25}, [r0], r1
+    vdup.8          d3, d15[4]
+    vld1.u8         {d26}, [r0], r1
+    vdup.8          d4, d16[0]
+    vld1.u8         {d27}, [r0], r1
+    vdup.8          d5, d16[4]
+    vld1.u8         {d28}, [r0], r1
+    vld1.u8         {d29}, [r0], r1
+    vld1.u8         {d30}, [r0], r1
+
+;Second pass: 8x8
+filt_blk2d_spo8x8_loop_neon
+    vmull.u8        q3, d18, d0             ;(src_ptr[-2] * vp8_filter[0])
+    vmull.u8        q4, d19, d0
+    vmull.u8        q5, d20, d0
+    vmull.u8        q6, d21, d0
+
+    vmlsl.u8        q3, d19, d1             ;-(src_ptr[-1] * vp8_filter[1])
+    vmlsl.u8        q4, d20, d1
+    vmlsl.u8        q5, d21, d1
+    vmlsl.u8        q6, d22, d1
+
+    vmlsl.u8        q3, d22, d4             ;-(src_ptr[2] * vp8_filter[4])
+    vmlsl.u8        q4, d23, d4
+    vmlsl.u8        q5, d24, d4
+    vmlsl.u8        q6, d25, d4
+
+    vmlal.u8        q3, d20, d2             ;(src_ptr[0] * vp8_filter[2])
+    vmlal.u8        q4, d21, d2
+    vmlal.u8        q5, d22, d2
+    vmlal.u8        q6, d23, d2
+
+    vmlal.u8        q3, d23, d5             ;(src_ptr[3] * vp8_filter[5])
+    vmlal.u8        q4, d24, d5
+    vmlal.u8        q5, d25, d5
+    vmlal.u8        q6, d26, d5
+
+    vmull.u8        q7, d21, d3             ;(src_ptr[1] * vp8_filter[3])
+    vmull.u8        q8, d22, d3
+    vmull.u8        q9, d23, d3
+    vmull.u8        q10, d24, d3
+
+    subs            r3, r3, #1
+
+    vqadd.s16       q7, q3                  ;sum of all (src_data*filter_parameters)
+    vqadd.s16       q8, q4
+    vqadd.s16       q9, q5
+    vqadd.s16       q10, q6
+
+    vqrshrun.s16    d6, q7, #7              ;shift/round/saturate to u8
+    vqrshrun.s16    d7, q8, #7
+    vqrshrun.s16    d8, q9, #7
+    vqrshrun.s16    d9, q10, #7
+
+    vmov            q9, q11
+    vst1.u8         {d6}, [r4], r5          ;store result
+    vmov            q10, q12
+    vst1.u8         {d7}, [r4], r5
+    vmov            q11, q13
+    vst1.u8         {d8}, [r4], r5
+    vmov            q12, q14
+    vst1.u8         {d9}, [r4], r5
+    vmov            d26, d30
+
+    bne filt_blk2d_spo8x8_loop_neon
+
+    pop             {r4-r5,pc}
+
+    ENDP
+
+;-----------------
+    AREA    subpelfilters8_dat, DATA, READWRITE         ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_filter8_coeff_
+    DCD     filter8_coeff
+filter8_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
+    END
diff --git a/vp8/common/arm/recon_arm.c b/vp8/common/arm/recon_arm.c
new file mode 100644 (file)
index 0000000..130059e
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "recon.h"
+#include "blockd.h"
+
+extern void vp8_recon16x16mb_neon(unsigned char *pred_ptr, short *diff_ptr, unsigned char *dst_ptr, int ystride, unsigned char *udst_ptr, unsigned char *vdst_ptr);
+
+/*
+void vp8_recon16x16mby(MACROBLOCKD *x)
+{
+    int i;
+    for(i=0;i<16;i+=4)
+    {
+        //vp8_recon4b(&x->block[i]);
+        BLOCKD *b = &x->block[i];
+        vp8_recon4b (b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+}
+*/
+void vp8_recon16x16mby(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    BLOCKD *b = &x->block[0];
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+
+    //b = &x->block[4];
+    b += 4;
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+
+    //b = &x->block[8];
+    b += 4;
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+
+    //b = &x->block[12];
+    b += 4;
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+}
+
+#if HAVE_ARMV7
+void vp8_recon16x16mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    unsigned char *pred_ptr = &x->predictor[0];
+    short *diff_ptr = &x->diff[0];
+    unsigned char *dst_ptr = x->dst.y_buffer;
+    unsigned char *udst_ptr = x->dst.u_buffer;
+    unsigned char *vdst_ptr = x->dst.v_buffer;
+    int ystride = x->dst.y_stride;
+    //int uv_stride = x->dst.uv_stride;
+
+    vp8_recon16x16mb_neon(pred_ptr, diff_ptr, dst_ptr, ystride, udst_ptr, vdst_ptr);
+}
+
+#else
+/*
+void vp8_recon16x16mb(MACROBLOCKD *x)
+{
+    int i;
+
+    for(i=0;i<16;i+=4)
+    {
+//      vp8_recon4b(&x->block[i]);
+        BLOCKD *b = &x->block[i];
+        vp8_recon4b (b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+
+    }
+    for(i=16;i<24;i+=2)
+    {
+//      vp8_recon2b(&x->block[i]);
+        BLOCKD *b = &x->block[i];
+        vp8_recon2b (b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+}
+*/
+void vp8_recon16x16mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    BLOCKD *b = &x->block[0];
+
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b += 4;
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b += 4;
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b += 4;
+    RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b += 4;
+
+    //b = &x->block[16];
+
+    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b++;
+    b++;
+    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b++;
+    b++;
+    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    b++;
+    b++;
+    RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+}
+#endif
diff --git a/vp8/common/arm/recon_arm.h b/vp8/common/arm/recon_arm.h
new file mode 100644 (file)
index 0000000..fd9f85e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef RECON_ARM_H
+#define RECON_ARM_H
+
+#if HAVE_ARMV6
+extern prototype_recon_block(vp8_recon_b_armv6);
+extern prototype_recon_block(vp8_recon2b_armv6);
+extern prototype_recon_block(vp8_recon4b_armv6);
+
+extern prototype_copy_block(vp8_copy_mem8x8_v6);
+extern prototype_copy_block(vp8_copy_mem8x4_v6);
+extern prototype_copy_block(vp8_copy_mem16x16_v6);
+
+#undef  vp8_recon_recon
+#define vp8_recon_recon vp8_recon_b_armv6
+
+#undef  vp8_recon_recon2
+#define vp8_recon_recon2 vp8_recon2b_armv6
+
+#undef  vp8_recon_recon4
+#define vp8_recon_recon4 vp8_recon4b_armv6
+
+#undef  vp8_recon_copy8x8
+#define vp8_recon_copy8x8 vp8_copy_mem8x8_v6
+
+#undef  vp8_recon_copy8x4
+#define vp8_recon_copy8x4 vp8_copy_mem8x4_v6
+
+#undef  vp8_recon_copy16x16
+#define vp8_recon_copy16x16 vp8_copy_mem16x16_v6
+#endif
+
+#if HAVE_ARMV7
+extern prototype_recon_block(vp8_recon_b_neon);
+extern prototype_recon_block(vp8_recon2b_neon);
+extern prototype_recon_block(vp8_recon4b_neon);
+
+extern prototype_copy_block(vp8_copy_mem8x8_neon);
+extern prototype_copy_block(vp8_copy_mem8x4_neon);
+extern prototype_copy_block(vp8_copy_mem16x16_neon);
+
+#undef  vp8_recon_recon
+#define vp8_recon_recon vp8_recon_b_neon
+
+#undef  vp8_recon_recon2
+#define vp8_recon_recon2 vp8_recon2b_neon
+
+#undef  vp8_recon_recon4
+#define vp8_recon_recon4 vp8_recon4b_neon
+
+#undef  vp8_recon_copy8x8
+#define vp8_recon_copy8x8 vp8_copy_mem8x8_neon
+
+#undef  vp8_recon_copy8x4
+#define vp8_recon_copy8x4 vp8_copy_mem8x4_neon
+
+#undef  vp8_recon_copy16x16
+#define vp8_recon_copy16x16 vp8_copy_mem16x16_neon
+#endif
+
+#endif
diff --git a/vp8/common/arm/reconintra4x4_arm.c b/vp8/common/arm/reconintra4x4_arm.c
new file mode 100644 (file)
index 0000000..334d352
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "recon.h"
+#include "vpx_mem/vpx_mem.h"
+#include "reconintra.h"
+
+void vp8_predict_intra4x4(BLOCKD *x,
+                          int b_mode,
+                          unsigned char *predictor)
+{
+    int i, r, c;
+
+    unsigned char *Above = *(x->base_dst) + x->dst - x->dst_stride;
+    unsigned char Left[4];
+    unsigned char top_left = Above[-1];
+
+    Left[0] = (*(x->base_dst))[x->dst - 1];
+    Left[1] = (*(x->base_dst))[x->dst - 1 + x->dst_stride];
+    Left[2] = (*(x->base_dst))[x->dst - 1 + 2 * x->dst_stride];
+    Left[3] = (*(x->base_dst))[x->dst - 1 + 3 * x->dst_stride];
+
+    switch (b_mode)
+    {
+    case B_DC_PRED:
+    {
+        int expected_dc = 0;
+
+        for (i = 0; i < 4; i++)
+        {
+            expected_dc += Above[i];
+            expected_dc += Left[i];
+        }
+
+        expected_dc = (expected_dc + 4) >> 3;
+
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+                predictor[c] = expected_dc;
+            }
+
+            predictor += 16;
+        }
+    }
+    break;
+    case B_TM_PRED:
+    {
+        // prediction similar to true_motion prediction
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+                int pred = Above[c] - top_left + Left[r];
+
+                if (pred < 0)
+                    pred = 0;
+
+                if (pred > 255)
+                    pred = 255;
+
+                predictor[c] = pred;
+            }
+
+            predictor += 16;
+        }
+    }
+    break;
+
+    case B_VE_PRED:
+    {
+
+        unsigned int ap[4];
+        ap[0] = (top_left  + 2 * Above[0] + Above[1] + 2) >> 2;
+        ap[1] = (Above[0] + 2 * Above[1] + Above[2] + 2) >> 2;
+        ap[2] = (Above[1] + 2 * Above[2] + Above[3] + 2) >> 2;
+        ap[3] = (Above[2] + 2 * Above[3] + Above[4] + 2) >> 2;
+
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+
+                predictor[c] = ap[c];
+            }
+
+            predictor += 16;
+        }
+
+    }
+    break;
+
+
+    case B_HE_PRED:
+    {
+
+        unsigned int lp[4];
+        lp[0] = (top_left + 2 * Left[0] + Left[1] + 2) >> 2;
+        lp[1] = (Left[0] + 2 * Left[1] + Left[2] + 2) >> 2;
+        lp[2] = (Left[1] + 2 * Left[2] + Left[3] + 2) >> 2;
+        lp[3] = (Left[2] + 2 * Left[3] + Left[3] + 2) >> 2;
+
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+                predictor[c] = lp[r];
+            }
+
+            predictor += 16;
+        }
+    }
+    break;
+    case B_LD_PRED:
+    {
+        unsigned char *ptr = Above;
+        predictor[0 * 16 + 0] = (ptr[0] + ptr[1] * 2 + ptr[2] + 2) >> 2;
+        predictor[0 * 16 + 1] =
+            predictor[1 * 16 + 0] = (ptr[1] + ptr[2] * 2 + ptr[3] + 2) >> 2;
+        predictor[0 * 16 + 2] =
+            predictor[1 * 16 + 1] =
+                predictor[2 * 16 + 0] = (ptr[2] + ptr[3] * 2 + ptr[4] + 2) >> 2;
+        predictor[0 * 16 + 3] =
+            predictor[1 * 16 + 2] =
+                predictor[2 * 16 + 1] =
+                    predictor[3 * 16 + 0] = (ptr[3] + ptr[4] * 2 + ptr[5] + 2) >> 2;
+        predictor[1 * 16 + 3] =
+            predictor[2 * 16 + 2] =
+                predictor[3 * 16 + 1] = (ptr[4] + ptr[5] * 2 + ptr[6] + 2) >> 2;
+        predictor[2 * 16 + 3] =
+            predictor[3 * 16 + 2] = (ptr[5] + ptr[6] * 2 + ptr[7] + 2) >> 2;
+        predictor[3 * 16 + 3] = (ptr[6] + ptr[7] * 2 + ptr[7] + 2) >> 2;
+
+    }
+    break;
+    case B_RD_PRED:
+    {
+
+        unsigned char pp[9];
+
+        pp[0] = Left[3];
+        pp[1] = Left[2];
+        pp[2] = Left[1];
+        pp[3] = Left[0];
+        pp[4] = top_left;
+        pp[5] = Above[0];
+        pp[6] = Above[1];
+        pp[7] = Above[2];
+        pp[8] = Above[3];
+
+        predictor[3 * 16 + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[3 * 16 + 1] =
+            predictor[2 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[3 * 16 + 2] =
+            predictor[2 * 16 + 1] =
+                predictor[1 * 16 + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[3 * 16 + 3] =
+            predictor[2 * 16 + 2] =
+                predictor[1 * 16 + 1] =
+                    predictor[0 * 16 + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[2 * 16 + 3] =
+            predictor[1 * 16 + 2] =
+                predictor[0 * 16 + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[1 * 16 + 3] =
+            predictor[0 * 16 + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+        predictor[0 * 16 + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
+
+    }
+    break;
+    case B_VR_PRED:
+    {
+
+        unsigned char pp[9];
+
+        pp[0] = Left[3];
+        pp[1] = Left[2];
+        pp[2] = Left[1];
+        pp[3] = Left[0];
+        pp[4] = top_left;
+        pp[5] = Above[0];
+        pp[6] = Above[1];
+        pp[7] = Above[2];
+        pp[8] = Above[3];
+
+
+        predictor[3 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[3 * 16 + 1] =
+            predictor[1 * 16 + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[2 * 16 + 1] =
+            predictor[0 * 16 + 0] = (pp[4] + pp[5] + 1) >> 1;
+        predictor[3 * 16 + 2] =
+            predictor[1 * 16 + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[2 * 16 + 2] =
+            predictor[0 * 16 + 1] = (pp[5] + pp[6] + 1) >> 1;
+        predictor[3 * 16 + 3] =
+            predictor[1 * 16 + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+        predictor[2 * 16 + 3] =
+            predictor[0 * 16 + 2] = (pp[6] + pp[7] + 1) >> 1;
+        predictor[1 * 16 + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
+        predictor[0 * 16 + 3] = (pp[7] + pp[8] + 1) >> 1;
+
+    }
+    break;
+    case B_VL_PRED:
+    {
+
+        unsigned char *pp = Above;
+
+        predictor[0 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
+        predictor[1 * 16 + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[2 * 16 + 0] =
+            predictor[0 * 16 + 1] = (pp[1] + pp[2] + 1) >> 1;
+        predictor[1 * 16 + 1] =
+            predictor[3 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 1] =
+            predictor[0 * 16 + 2] = (pp[2] + pp[3] + 1) >> 1;
+        predictor[3 * 16 + 1] =
+            predictor[1 * 16 + 2] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[0 * 16 + 3] =
+            predictor[2 * 16 + 2] = (pp[3] + pp[4] + 1) >> 1;
+        predictor[1 * 16 + 3] =
+            predictor[3 * 16 + 2] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[2 * 16 + 3] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[3 * 16 + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+    }
+    break;
+
+    case B_HD_PRED:
+    {
+        unsigned char pp[9];
+        pp[0] = Left[3];
+        pp[1] = Left[2];
+        pp[2] = Left[1];
+        pp[3] = Left[0];
+        pp[4] = top_left;
+        pp[5] = Above[0];
+        pp[6] = Above[1];
+        pp[7] = Above[2];
+        pp[8] = Above[3];
+
+
+        predictor[3 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
+        predictor[3 * 16 + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[2 * 16 + 0] =
+            predictor[3 * 16 + 2] = (pp[1] + pp[2] + 1) >> 1;
+        predictor[2 * 16 + 1] =
+            predictor[3 * 16 + 3] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 2] =
+            predictor[1 * 16 + 0] = (pp[2] + pp[3] + 1) >> 1;
+        predictor[2 * 16 + 3] =
+            predictor[1 * 16 + 1] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[1 * 16 + 2] =
+            predictor[0 * 16 + 0] = (pp[3] + pp[4] + 1) >> 1;
+        predictor[1 * 16 + 3] =
+            predictor[0 * 16 + 1] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[0 * 16 + 2] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[0 * 16 + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+    }
+    break;
+
+
+    case B_HU_PRED:
+    {
+        unsigned char *pp = Left;
+        predictor[0 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
+        predictor[0 * 16 + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[0 * 16 + 2] =
+            predictor[1 * 16 + 0] = (pp[1] + pp[2] + 1) >> 1;
+        predictor[0 * 16 + 3] =
+            predictor[1 * 16 + 1] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[1 * 16 + 2] =
+            predictor[2 * 16 + 0] = (pp[2] + pp[3] + 1) >> 1;
+        predictor[1 * 16 + 3] =
+            predictor[2 * 16 + 1] = (pp[2] + pp[3] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 2] =
+            predictor[2 * 16 + 3] =
+                predictor[3 * 16 + 0] =
+                    predictor[3 * 16 + 1] =
+                        predictor[3 * 16 + 2] =
+                            predictor[3 * 16 + 3] = pp[3];
+    }
+    break;
+
+
+    }
+}
+// copy 4 bytes from the above right down so that the 4x4 prediction modes using pixels above and
+// to the right prediction have filled in pixels to use.
+void vp8_intra_prediction_down_copy(MACROBLOCKD *x)
+{
+    unsigned char *above_right = *(x->block[0].base_dst) + x->block[0].dst - x->block[0].dst_stride + 16;
+
+    unsigned int *src_ptr = (unsigned int *)above_right;
+    unsigned int *dst_ptr0 = (unsigned int *)(above_right + 4 * x->block[0].dst_stride);
+    unsigned int *dst_ptr1 = (unsigned int *)(above_right + 8 * x->block[0].dst_stride);
+    unsigned int *dst_ptr2 = (unsigned int *)(above_right + 12 * x->block[0].dst_stride);
+
+    *dst_ptr0 = *src_ptr;
+    *dst_ptr1 = *src_ptr;
+    *dst_ptr2 = *src_ptr;
+}
+
+
+
+/*
+void vp8_recon_intra4x4mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    vp8_intra_prediction_down_copy(x);
+
+    for(i=0;i<16;i++)
+    {
+        BLOCKD *b = &x->block[i];
+
+        vp8_predict_intra4x4(b, x->block[i].bmi.mode,x->block[i].predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+
+    vp8_recon_intra_mbuv(x);
+
+}
+*/
+void vp8_recon_intra4x4mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+    BLOCKD *b = &x->block[0];
+
+    vp8_intra_prediction_down_copy(x);
+
+    {
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+        b += 1;
+
+        vp8_predict_intra4x4(b, b->bmi.mode, b->predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+
+    vp8_recon_intra_mbuv(rtcd, x);
+
+}
diff --git a/vp8/common/arm/reconintra_arm.c b/vp8/common/arm/reconintra_arm.c
new file mode 100644 (file)
index 0000000..d7ee1dd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "blockd.h"
+#include "reconintra.h"
+#include "vpx_mem/vpx_mem.h"
+#include "recon.h"
+
+#if HAVE_ARMV7
+extern void vp8_build_intra_predictors_mby_neon_func(
+    unsigned char *y_buffer,
+    unsigned char *ypred_ptr,
+    int y_stride,
+    int mode,
+    int Up,
+    int Left);
+
+void vp8_build_intra_predictors_mby_neon(MACROBLOCKD *x)
+{
+    unsigned char *y_buffer = x->dst.y_buffer;
+    unsigned char *ypred_ptr = x->predictor;
+    int y_stride = x->dst.y_stride;
+    int mode = x->mbmi.mode;
+    int Up = x->up_available;
+    int Left = x->left_available;
+
+    vp8_build_intra_predictors_mby_neon_func(y_buffer, ypred_ptr, y_stride, mode, Up, Left);
+}
+#endif
+
+
+#if HAVE_ARMV7
+extern void vp8_build_intra_predictors_mby_s_neon_func(
+    unsigned char *y_buffer,
+    unsigned char *ypred_ptr,
+    int y_stride,
+    int mode,
+    int Up,
+    int Left);
+
+void vp8_build_intra_predictors_mby_s_neon(MACROBLOCKD *x)
+{
+    unsigned char *y_buffer = x->dst.y_buffer;
+    unsigned char *ypred_ptr = x->predictor;
+    int y_stride = x->dst.y_stride;
+    int mode = x->mbmi.mode;
+    int Up = x->up_available;
+    int Left = x->left_available;
+
+    vp8_build_intra_predictors_mby_s_neon_func(y_buffer, ypred_ptr, y_stride, mode, Up, Left);
+}
+
+#endif
diff --git a/vp8/common/arm/subpixel_arm.h b/vp8/common/arm/subpixel_arm.h
new file mode 100644 (file)
index 0000000..56aec55
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef SUBPIXEL_ARM_H
+#define SUBPIXEL_ARM_H
+
+#if HAVE_ARMV6
+extern prototype_subpixel_predict(vp8_sixtap_predict16x16_armv6);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x8_armv6);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x4_armv6);
+extern prototype_subpixel_predict(vp8_sixtap_predict_armv6);
+extern prototype_subpixel_predict(vp8_bilinear_predict16x16_armv6);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x8_armv6);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x4_armv6);
+extern prototype_subpixel_predict(vp8_bilinear_predict4x4_armv6);
+
+#undef  vp8_subpix_sixtap16x16
+#define vp8_subpix_sixtap16x16 vp8_sixtap_predict16x16_armv6
+
+#undef  vp8_subpix_sixtap8x8
+#define vp8_subpix_sixtap8x8 vp8_sixtap_predict8x8_armv6
+
+#undef  vp8_subpix_sixtap8x4
+#define vp8_subpix_sixtap8x4 vp8_sixtap_predict8x4_armv6
+
+#undef  vp8_subpix_sixtap4x4
+#define vp8_subpix_sixtap4x4 vp8_sixtap_predict_armv6
+
+#undef  vp8_subpix_bilinear16x16
+#define vp8_subpix_bilinear16x16 vp8_bilinear_predict16x16_armv6
+
+#undef  vp8_subpix_bilinear8x8
+#define vp8_subpix_bilinear8x8 vp8_bilinear_predict8x8_armv6
+
+#undef  vp8_subpix_bilinear8x4
+#define vp8_subpix_bilinear8x4 vp8_bilinear_predict8x4_armv6
+
+#undef  vp8_subpix_bilinear4x4
+#define vp8_subpix_bilinear4x4 vp8_bilinear_predict4x4_armv6
+#endif
+
+#if HAVE_ARMV7
+extern prototype_subpixel_predict(vp8_sixtap_predict16x16_neon);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x8_neon);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x4_neon);
+extern prototype_subpixel_predict(vp8_sixtap_predict_neon);
+extern prototype_subpixel_predict(vp8_bilinear_predict16x16_neon);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x8_neon);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x4_neon);
+extern prototype_subpixel_predict(vp8_bilinear_predict4x4_neon);
+
+#undef  vp8_subpix_sixtap16x16
+#define vp8_subpix_sixtap16x16 vp8_sixtap_predict16x16_neon
+
+#undef  vp8_subpix_sixtap8x8
+#define vp8_subpix_sixtap8x8 vp8_sixtap_predict8x8_neon
+
+#undef  vp8_subpix_sixtap8x4
+#define vp8_subpix_sixtap8x4 vp8_sixtap_predict8x4_neon
+
+#undef  vp8_subpix_sixtap4x4
+#define vp8_subpix_sixtap4x4 vp8_sixtap_predict_neon
+
+#undef  vp8_subpix_bilinear16x16
+#define vp8_subpix_bilinear16x16 vp8_bilinear_predict16x16_neon
+
+#undef  vp8_subpix_bilinear8x8
+#define vp8_subpix_bilinear8x8 vp8_bilinear_predict8x8_neon
+
+#undef  vp8_subpix_bilinear8x4
+#define vp8_subpix_bilinear8x4 vp8_bilinear_predict8x4_neon
+
+#undef  vp8_subpix_bilinear4x4
+#define vp8_subpix_bilinear4x4 vp8_bilinear_predict4x4_neon
+#endif
+
+#endif
diff --git a/vp8/common/arm/systemdependent.c b/vp8/common/arm/systemdependent.c
new file mode 100644 (file)
index 0000000..ecc6929
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "g_common.h"
+#include "pragmas.h"
+#include "subpixel.h"
+#include "loopfilter.h"
+#include "recon.h"
+#include "idct.h"
+#include "onyxc_int.h"
+
+void (*vp8_build_intra_predictors_mby_ptr)(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_neon(MACROBLOCKD *x);
+
+void (*vp8_build_intra_predictors_mby_s_ptr)(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_s_neon(MACROBLOCKD *x);
+
+void vp8_machine_specific_config(VP8_COMMON *ctx)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    VP8_COMMON_RTCD *rtcd = &ctx->rtcd;
+
+#if HAVE_ARMV7
+    rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_neon;
+    rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_neon;
+    rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_neon;
+    rtcd->subpix.sixtap4x4     = vp8_sixtap_predict_neon;
+    rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_neon;
+    rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_neon;
+    rtcd->subpix.bilinear8x4   = vp8_bilinear_predict8x4_neon;
+    rtcd->subpix.bilinear4x4   = vp8_bilinear_predict4x4_neon;
+
+    rtcd->idct.idct1        = vp8_short_idct4x4llm_1_neon;
+    rtcd->idct.idct16       = vp8_short_idct4x4llm_neon;
+    rtcd->idct.idct1_scalar = vp8_dc_only_idct_neon;
+    rtcd->idct.iwalsh1      = vp8_short_inv_walsh4x4_1_neon;
+    rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_neon;
+
+    rtcd->loopfilter.normal_mb_v = vp8_loop_filter_mbv_neon;
+    rtcd->loopfilter.normal_b_v  = vp8_loop_filter_bv_neon;
+    rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_neon;
+    rtcd->loopfilter.normal_b_h  = vp8_loop_filter_bh_neon;
+    rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_neon;
+    rtcd->loopfilter.simple_b_v  = vp8_loop_filter_bvs_neon;
+    rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_neon;
+    rtcd->loopfilter.simple_b_h  = vp8_loop_filter_bhs_neon;
+
+    rtcd->recon.copy16x16   = vp8_copy_mem16x16_neon;
+    rtcd->recon.copy8x8     = vp8_copy_mem8x8_neon;
+    rtcd->recon.copy8x4     = vp8_copy_mem8x4_neon;
+    rtcd->recon.recon       = vp8_recon_b_neon;
+    rtcd->recon.recon2      = vp8_recon2b_neon;
+    rtcd->recon.recon4      = vp8_recon4b_neon;
+#elif HAVE_ARMV6
+
+    rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_armv6;
+    rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_armv6;
+    rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_armv6;
+    rtcd->subpix.sixtap4x4     = vp8_sixtap_predict_armv6;
+    rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_armv6;
+    rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_armv6;
+    rtcd->subpix.bilinear8x4   = vp8_bilinear_predict8x4_armv6;
+    rtcd->subpix.bilinear4x4   = vp8_bilinear_predict4x4_armv6;
+
+    rtcd->idct.idct1        = vp8_short_idct4x4llm_1_v6;
+    rtcd->idct.idct16       = vp8_short_idct4x4llm_v6_dual;
+    rtcd->idct.idct1_scalar = vp8_dc_only_idct_armv6;
+    rtcd->idct.iwalsh1      = vp8_short_inv_walsh4x4_1_armv6;
+    rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_armv6;
+
+    rtcd->loopfilter.normal_mb_v = vp8_loop_filter_mbv_armv6;
+    rtcd->loopfilter.normal_b_v  = vp8_loop_filter_bv_armv6;
+    rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_armv6;
+    rtcd->loopfilter.normal_b_h  = vp8_loop_filter_bh_armv6;
+    rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_armv6;
+    rtcd->loopfilter.simple_b_v  = vp8_loop_filter_bvs_armv6;
+    rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_armv6;
+    rtcd->loopfilter.simple_b_h  = vp8_loop_filter_bhs_armv6;
+
+    rtcd->recon.copy16x16   = vp8_copy_mem16x16_v6;
+    rtcd->recon.copy8x8     = vp8_copy_mem8x8_v6;
+    rtcd->recon.copy8x4     = vp8_copy_mem8x4_v6;
+    rtcd->recon.recon       = vp8_recon_b_armv6;
+    rtcd->recon.recon2      = vp8_recon2b_armv6;
+    rtcd->recon.recon4      = vp8_recon4b_armv6;
+#else
+//pure c
+    rtcd->idct.idct1        = vp8_short_idct4x4llm_1_c;
+    rtcd->idct.idct16       = vp8_short_idct4x4llm_c;
+    rtcd->idct.idct1_scalar = vp8_dc_only_idct_c;
+    rtcd->idct.iwalsh1      = vp8_short_inv_walsh4x4_1_c;
+    rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_c;
+
+    rtcd->recon.copy16x16   = vp8_copy_mem16x16_c;
+    rtcd->recon.copy8x8     = vp8_copy_mem8x8_c;
+    rtcd->recon.copy8x4     = vp8_copy_mem8x4_c;
+    rtcd->recon.recon      = vp8_recon_b_c;
+    rtcd->recon.recon2      = vp8_recon2b_c;
+    rtcd->recon.recon4     = vp8_recon4b_c;
+
+    rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_c;
+    rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_c;
+    rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_c;
+    rtcd->subpix.sixtap4x4     = vp8_sixtap_predict_c;
+    rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_c;
+    rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_c;
+    rtcd->subpix.bilinear8x4   = vp8_bilinear_predict8x4_c;
+    rtcd->subpix.bilinear4x4   = vp8_bilinear_predict4x4_c;
+
+    rtcd->loopfilter.normal_mb_v = vp8_loop_filter_mbv_c;
+    rtcd->loopfilter.normal_b_v  = vp8_loop_filter_bv_c;
+    rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_c;
+    rtcd->loopfilter.normal_b_h  = vp8_loop_filter_bh_c;
+    rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_c;
+    rtcd->loopfilter.simple_b_v  = vp8_loop_filter_bvs_c;
+    rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_c;
+    rtcd->loopfilter.simple_b_h  = vp8_loop_filter_bhs_c;
+#endif
+
+    rtcd->postproc.down        = vp8_mbpost_proc_down_c;
+    rtcd->postproc.across      = vp8_mbpost_proc_across_ip_c;
+    rtcd->postproc.downacross  = vp8_post_proc_down_and_across_c;
+    rtcd->postproc.addnoise    = vp8_plane_add_noise_c;
+#endif
+
+#if HAVE_ARMV7
+    vp8_build_intra_predictors_mby_ptr = vp8_build_intra_predictors_mby_neon;
+    vp8_build_intra_predictors_mby_s_ptr = vp8_build_intra_predictors_mby_s_neon;
+#elif HAVE_ARMV6
+    vp8_build_intra_predictors_mby_ptr = vp8_build_intra_predictors_mby;
+    vp8_build_intra_predictors_mby_s_ptr = vp8_build_intra_predictors_mby_s;
+#else
+    vp8_build_intra_predictors_mby_ptr = vp8_build_intra_predictors_mby;
+    vp8_build_intra_predictors_mby_s_ptr = vp8_build_intra_predictors_mby_s;
+
+#endif
+
+}
diff --git a/vp8/common/arm/vpx_asm_offsets.c b/vp8/common/arm/vpx_asm_offsets.c
new file mode 100644 (file)
index 0000000..68634bf
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include <stddef.h>
+
+#if CONFIG_VP8_ENCODER
+#include "vpx_scale/yv12config.h"
+#endif
+
+#if CONFIG_VP8_DECODER
+#include "onyxd_int.h"
+#endif
+
+#define DEFINE(sym, val) int sym = val;
+
+/*
+#define BLANK() asm volatile("\n->" : : )
+*/
+
+/*
+ * int main(void)
+ * {
+ */
+
+#if CONFIG_VP8_DECODER || CONFIG_VP8_ENCODER
+DEFINE(yv12_buffer_config_y_width,               offsetof(YV12_BUFFER_CONFIG, y_width));
+DEFINE(yv12_buffer_config_y_height,              offsetof(YV12_BUFFER_CONFIG, y_height));
+DEFINE(yv12_buffer_config_y_stride,              offsetof(YV12_BUFFER_CONFIG, y_stride));
+DEFINE(yv12_buffer_config_uv_width,               offsetof(YV12_BUFFER_CONFIG, uv_width));
+DEFINE(yv12_buffer_config_uv_height,              offsetof(YV12_BUFFER_CONFIG, uv_height));
+DEFINE(yv12_buffer_config_uv_stride,              offsetof(YV12_BUFFER_CONFIG, uv_stride));
+DEFINE(yv12_buffer_config_y_buffer,              offsetof(YV12_BUFFER_CONFIG, y_buffer));
+DEFINE(yv12_buffer_config_u_buffer,              offsetof(YV12_BUFFER_CONFIG, u_buffer));
+DEFINE(yv12_buffer_config_v_buffer,              offsetof(YV12_BUFFER_CONFIG, v_buffer));
+DEFINE(yv12_buffer_config_border,               offsetof(YV12_BUFFER_CONFIG, border));
+#endif
+
+#if CONFIG_VP8_DECODER
+DEFINE(mb_diff,                                 offsetof(MACROBLOCKD, diff));
+DEFINE(mb_predictor,                            offsetof(MACROBLOCKD, predictor));
+DEFINE(mb_dst_y_stride,                          offsetof(MACROBLOCKD, dst.y_stride));
+DEFINE(mb_dst_y_buffer,                          offsetof(MACROBLOCKD, dst.y_buffer));
+DEFINE(mb_dst_u_buffer,                          offsetof(MACROBLOCKD, dst.u_buffer));
+DEFINE(mb_dst_v_buffer,                          offsetof(MACROBLOCKD, dst.v_buffer));
+DEFINE(mb_mbmi_mode,                            offsetof(MACROBLOCKD, mbmi.mode));
+DEFINE(mb_up_available,                          offsetof(MACROBLOCKD, up_available));
+DEFINE(mb_left_available,                        offsetof(MACROBLOCKD, left_available));
+
+DEFINE(detok_scan,                              offsetof(DETOK, scan));
+DEFINE(detok_ptr_onyxblock2context_leftabove,    offsetof(DETOK, ptr_onyxblock2context_leftabove));
+DEFINE(detok_onyx_coef_tree_ptr,                  offsetof(DETOK, vp8_coef_tree_ptr));
+DEFINE(detok_teb_base_ptr,                        offsetof(DETOK, teb_base_ptr));
+DEFINE(detok_norm_ptr,                           offsetof(DETOK, norm_ptr));
+DEFINE(detok_ptr_onyx_coef_bands_x,                offsetof(DETOK, ptr_onyx_coef_bands_x));
+
+DEFINE(DETOK_A,                                 offsetof(DETOK, A));
+DEFINE(DETOK_L,                                 offsetof(DETOK, L));
+
+DEFINE(detok_qcoeff_start_ptr,                    offsetof(DETOK, qcoeff_start_ptr));
+DEFINE(detok_current_bc,                         offsetof(DETOK, current_bc));
+DEFINE(detok_coef_probs,                         offsetof(DETOK, coef_probs));
+DEFINE(detok_eob,                               offsetof(DETOK, eob));
+
+DEFINE(bool_decoder_lowvalue,                   offsetof(BOOL_DECODER, lowvalue));
+DEFINE(bool_decoder_range,                      offsetof(BOOL_DECODER, range));
+DEFINE(bool_decoder_value,                      offsetof(BOOL_DECODER, value));
+DEFINE(bool_decoder_count,                      offsetof(BOOL_DECODER, count));
+DEFINE(bool_decoder_user_buffer,                offsetof(BOOL_DECODER, user_buffer));
+DEFINE(bool_decoder_user_buffer_sz,             offsetof(BOOL_DECODER, user_buffer_sz));
+DEFINE(bool_decoder_decode_buffer,              offsetof(BOOL_DECODER, decode_buffer));
+DEFINE(bool_decoder_read_ptr,                   offsetof(BOOL_DECODER, read_ptr));
+DEFINE(bool_decoder_write_ptr,                  offsetof(BOOL_DECODER, write_ptr));
+
+DEFINE(tokenextrabits_min_val,                   offsetof(TOKENEXTRABITS, min_val));
+DEFINE(tokenextrabits_length,                   offsetof(TOKENEXTRABITS, Length));
+#endif
+
+//add asserts for any offset that is not supported by assembly code
+//add asserts for any size that is not supported by assembly code
+/*
+ * return 0;
+ * }
+ */
diff --git a/vp8/common/bigend.h b/vp8/common/bigend.h
new file mode 100644 (file)
index 0000000..6a91ba1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _bigend_h
+#define _bigend_h
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define invert2(x) ( (((x)>>8)&0x00ff) | (((x)<<8)&0xff00) )
+#define invert4(x) ( ((invert2(x)&0x0000ffff)<<16) | (invert2((x>>16))&0x0000ffff) )
+
+#define high_byte(x) (unsigned char)x
+#define mid2Byte(x) (unsigned char)(x >> 8)
+#define mid1Byte(x) (unsigned char)(x >> 16)
+#define low_byte(x) (unsigned char)(x >> 24)
+
+#define SWAPENDS 1
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/vp8/common/blockd.c b/vp8/common/blockd.c
new file mode 100644 (file)
index 0000000..53f5e72
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "blockd.h"
+#include "vpx_mem/vpx_mem.h"
+
+void vp8_setup_temp_context(TEMP_CONTEXT *t, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, int count)
+{
+    vpx_memcpy(t->l, l, sizeof(ENTROPY_CONTEXT) * count);
+    vpx_memcpy(t->a, a, sizeof(ENTROPY_CONTEXT) * count);
+}
+
+const int vp8_block2left[25] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 1, 1, 0};
+const int vp8_block2above[25] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 0};
+const int vp8_block2type[25] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1};
+const int vp8_block2context[25] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3};
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
new file mode 100644 (file)
index 0000000..84ed53a
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_BLOCKD_H
+#define __INC_BLOCKD_H
+
+void vpx_log(const char *format, ...);
+
+#include "vpx_ports/config.h"
+#include "vpx_scale/yv12config.h"
+#include "mv.h"
+#include "treecoder.h"
+#include "subpixel.h"
+#include "vpx_ports/mem.h"
+
+#define TRUE    1
+#define FALSE   0
+
+//#define DCPRED 1
+#define DCPREDSIMTHRESH 0
+#define DCPREDCNTTHRESH 3
+
+#define Y1CONTEXT 0
+#define UCONTEXT 1
+#define VCONTEXT 2
+#define Y2CONTEXT 3
+
+#define MB_FEATURE_TREE_PROBS   3
+#define MAX_MB_SEGMENTS         4
+
+#define MAX_REF_LF_DELTAS       4
+#define MAX_MODE_LF_DELTAS      4
+
+// Segment Feature Masks
+#define SEGMENT_DELTADATA   0
+#define SEGMENT_ABSDATA     1
+
+typedef struct
+{
+    int r, c;
+} POS;
+
+
+typedef int ENTROPY_CONTEXT;
+
+typedef struct
+{
+    ENTROPY_CONTEXT l[4];
+    ENTROPY_CONTEXT a[4];
+} TEMP_CONTEXT;
+
+extern void vp8_setup_temp_context(TEMP_CONTEXT *t, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, int count);
+extern const int vp8_block2left[25];
+extern const int vp8_block2above[25];
+extern const int vp8_block2type[25];
+extern const int vp8_block2context[25];
+
+#define VP8_COMBINEENTROPYCONTEXTS( Dest, A, B) \
+    Dest = ((A)!=0) + ((B)!=0);
+
+
+typedef enum
+{
+    KEY_FRAME = 0,
+    INTER_FRAME = 1
+} FRAME_TYPE;
+
+typedef enum
+{
+    DC_PRED,            // average of above and left pixels
+    V_PRED,             // vertical prediction
+    H_PRED,             // horizontal prediction
+    TM_PRED,            // Truemotion prediction
+    B_PRED,             // block based prediction, each block has its own prediction mode
+
+    NEARESTMV,
+    NEARMV,
+    ZEROMV,
+    NEWMV,
+    SPLITMV,
+
+    MB_MODE_COUNT
+} MB_PREDICTION_MODE;
+
+// Macroblock level features
+typedef enum
+{
+    MB_LVL_ALT_Q = 0,               // Use alternate Quantizer ....
+    MB_LVL_ALT_LF = 1,              // Use alternate loop filter value...
+    MB_LVL_MAX = 2,                 // Number of MB level features supported
+
+} MB_LVL_FEATURES;
+
+// Segment Feature Masks
+#define SEGMENT_ALTQ    0x01
+#define SEGMENT_ALT_LF  0x02
+
+#define VP8_YMODES  (B_PRED + 1)
+#define VP8_UV_MODES (TM_PRED + 1)
+
+#define VP8_MVREFS (1 + SPLITMV - NEARESTMV)
+
+typedef enum
+{
+    B_DC_PRED,          // average of above and left pixels
+    B_TM_PRED,
+
+    B_VE_PRED,           // vertical prediction
+    B_HE_PRED,           // horizontal prediction
+
+    B_LD_PRED,
+    B_RD_PRED,
+
+    B_VR_PRED,
+    B_VL_PRED,
+    B_HD_PRED,
+    B_HU_PRED,
+
+    LEFT4X4,
+    ABOVE4X4,
+    ZERO4X4,
+    NEW4X4,
+
+    B_MODE_COUNT
+} B_PREDICTION_MODE;
+
+#define VP8_BINTRAMODES (B_HU_PRED + 1)  /* 10 */
+#define VP8_SUBMVREFS (1 + NEW4X4 - LEFT4X4)
+
+/* For keyframes, intra block modes are predicted by the (already decoded)
+   modes for the Y blocks to the left and above us; for interframes, there
+   is a single probability table. */
+
+typedef struct
+{
+    B_PREDICTION_MODE mode;
+    union
+    {
+        int as_int;
+        MV  as_mv;
+    } mv;
+} B_MODE_INFO;
+
+
+typedef enum
+{
+    INTRA_FRAME = 0,
+    LAST_FRAME = 1,
+    GOLDEN_FRAME = 2,
+    ALTREF_FRAME = 3,
+    MAX_REF_FRAMES = 4
+} MV_REFERENCE_FRAME;
+
+typedef struct
+{
+    MB_PREDICTION_MODE mode, uv_mode;
+    MV_REFERENCE_FRAME ref_frame;
+    union
+    {
+        int as_int;
+        MV  as_mv;
+    } mv;
+    int partitioning;
+    int partition_count;
+    int mb_skip_coeff;                                //does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens
+    int dc_diff;
+    unsigned char   segment_id;                  // Which set of segmentation parameters should be used for this MB
+    int force_no_skip;
+
+    B_MODE_INFO partition_bmi[16];
+
+} MB_MODE_INFO;
+
+
+typedef struct
+{
+    MB_MODE_INFO mbmi;
+    B_MODE_INFO bmi[16];
+} MODE_INFO;
+
+
+typedef struct
+{
+    short *qcoeff;
+    short *dqcoeff;
+    unsigned char  *predictor;
+    short *diff;
+    short *reference;
+
+    short(*dequant)[4];
+
+    // 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries
+    unsigned char **base_pre;
+    int pre;
+    int pre_stride;
+
+    unsigned char **base_dst;
+    int dst;
+    int dst_stride;
+
+    int eob;
+
+    B_MODE_INFO bmi;
+
+} BLOCKD;
+
+typedef struct
+{
+    DECLARE_ALIGNED(16, short, diff[400]);      // from idct diff
+    DECLARE_ALIGNED(16, unsigned char,  predictor[384]);
+    DECLARE_ALIGNED(16, short, reference[384]);
+    DECLARE_ALIGNED(16, short, qcoeff[400]);
+    DECLARE_ALIGNED(16, short, dqcoeff[400]);
+
+    // 16 Y blocks, 4 U, 4 V, 1 DC 2nd order block, each with 16 entries.
+    BLOCKD block[25];
+
+    YV12_BUFFER_CONFIG pre; // Filtered copy of previous frame reconstruction
+    YV12_BUFFER_CONFIG dst;
+
+    MODE_INFO *mode_info_context;
+    MODE_INFO *mode_info;
+
+    int mode_info_stride;
+
+    FRAME_TYPE frame_type;
+
+    MB_MODE_INFO mbmi;
+
+    int up_available;
+    int left_available;
+
+    // Y,U,V,Y2
+    ENTROPY_CONTEXT *above_context[4];   // row of context for each plane
+    ENTROPY_CONTEXT(*left_context)[4];   // (up to) 4 contexts ""
+
+    // 0 indicates segmentation at MB level is not enabled. Otherwise the individual bits indicate which features are active.
+    unsigned char segmentation_enabled;
+
+    // 0 (do not update) 1 (update) the macroblock segmentation map.
+    unsigned char update_mb_segmentation_map;
+
+    // 0 (do not update) 1 (update) the macroblock segmentation feature data.
+    unsigned char update_mb_segmentation_data;
+
+    // 0 (do not update) 1 (update) the macroblock segmentation feature data.
+    unsigned char mb_segement_abs_delta;
+
+    // Per frame flags that define which MB level features (such as quantizer or loop filter level)
+    // are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO
+    vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];         // Probability Tree used to code Segment number
+
+    signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];            // Segment parameters
+
+    // mode_based Loop filter adjustment
+    unsigned char mode_ref_lf_delta_enabled;
+    unsigned char mode_ref_lf_delta_update;
+
+    // Delta values have the range +/- MAX_LOOP_FILTER
+    //char ref_lf_deltas[MAX_REF_LF_DELTAS];                      // 0 = Intra, Last, GF, ARF
+    //char mode_lf_deltas[MAX_MODE_LF_DELTAS];                            // 0 = BPRED, ZERO_MV, MV, SPLIT
+    signed char ref_lf_deltas[MAX_REF_LF_DELTAS];                     // 0 = Intra, Last, GF, ARF
+    signed char mode_lf_deltas[MAX_MODE_LF_DELTAS];                           // 0 = BPRED, ZERO_MV, MV, SPLIT
+
+    // Distance of MB away from frame edges
+    int mb_to_left_edge;
+    int mb_to_right_edge;
+    int mb_to_top_edge;
+    int mb_to_bottom_edge;
+
+    //char * gf_active_ptr;
+    signed char *gf_active_ptr;
+
+    unsigned int frames_since_golden;
+    unsigned int frames_till_alt_ref_frame;
+    vp8_subpix_fn_t  subpixel_predict;
+    vp8_subpix_fn_t  subpixel_predict8x4;
+    vp8_subpix_fn_t  subpixel_predict8x8;
+    vp8_subpix_fn_t  subpixel_predict16x16;
+
+    void *current_bc;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+    struct VP8_COMMON_RTCD  *rtcd;
+#endif
+} MACROBLOCKD;
+
+
+extern void vp8_build_block_doffsets(MACROBLOCKD *x);
+extern void vp8_setup_block_dptrs(MACROBLOCKD *x);
+
+#endif  /* __INC_BLOCKD_H */
diff --git a/vp8/common/boolcoder.h b/vp8/common/boolcoder.h
new file mode 100644 (file)
index 0000000..0659d48
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef bool_coder_h
+#define bool_coder_h 1
+
+/* Arithmetic bool coder with largish probability range.
+   Timothy S Murphy  6 August 2004 */
+
+/* So as not to force users to drag in too much of my idiosyncratic C++ world,
+   I avoid fancy storage management. */
+
+#include <assert.h>
+
+#include <stddef.h>
+#include <stdio.h>
+
+typedef unsigned char vp8bc_index_t; // probability index
+
+/* There are a couple of slight variants in the details of finite-precision
+   arithmetic coding.  May be safely ignored by most users. */
+
+enum vp8bc_rounding
+{
+    vp8bc_down = 0,     // just like VP8
+    vp8bc_down_full = 1, // handles minimum probability correctly
+    vp8bc_up = 2
+};
+
+#if _MSC_VER
+
+/* Note that msvc by default does not inline _anything_ (regardless of the
+   setting of inline_depth) and that a command-line option (-Ob1 or -Ob2)
+   is required to inline even the smallest functions. */
+
+#   pragma inline_depth( 255)           // I mean it when I inline something
+#   pragma warning( disable : 4099)     // No class vs. struct harassment
+#   pragma warning( disable : 4250)     // dominance complaints
+#   pragma warning( disable : 4284)     // operator-> in templates
+#   pragma warning( disable : 4800)     // bool conversion
+
+// don't let prefix ++,-- stand in for postfix, disaster would ensue
+
+#   pragma warning( error : 4620 4621)
+
+#endif  // _MSC_VER
+
+
+#if __cplusplus
+
+// Sometimes one wishes to be definite about integer lengths.
+
+struct int_types
+{
+    typedef const bool cbool;
+    typedef const signed char cchar;
+    typedef const short cshort;
+    typedef const int cint;
+    typedef const int clong;
+
+    typedef const double cdouble;
+    typedef const size_t csize_t;
+
+    typedef unsigned char uchar;    // 8 bits
+    typedef const uchar cuchar;
+
+    typedef short int16;
+    typedef unsigned short uint16;
+    typedef const int16 cint16;
+    typedef const uint16 cuint16;
+
+    typedef int int32;
+    typedef unsigned int uint32;
+    typedef const int32 cint32;
+    typedef const uint32 cuint32;
+
+    typedef unsigned int uint;
+    typedef unsigned int ulong;
+    typedef const uint cuint;
+    typedef const ulong culong;
+
+
+    // All structs consume space, may as well have a vptr.
+
+    virtual ~int_types();
+};
+
+
+struct bool_coder_spec;
+struct bool_coder;
+struct bool_writer;
+struct bool_reader;
+
+
+struct bool_coder_namespace : int_types
+{
+    typedef vp8bc_index_t Index;
+    typedef bool_coder_spec Spec;
+    typedef const Spec c_spec;
+
+    enum Rounding
+    {
+        Down = vp8bc_down,
+        down_full = vp8bc_down_full,
+        Up = vp8bc_up
+    };
+};
+
+
+// Archivable specification of a bool coder includes rounding spec
+// and probability mapping table.  The latter replaces a uchar j
+// (0 <= j < 256) with an arbitrary uint16 tbl[j] = p.
+// p/65536 is then the probability of a zero.
+
+struct bool_coder_spec : bool_coder_namespace
+{
+    friend struct bool_coder;
+    friend struct bool_writer;
+    friend struct bool_reader;
+    friend struct bool_coder_spec_float;
+    friend struct bool_coder_spec_explicit_table;
+    friend struct bool_coder_spec_exponential_table;
+    friend struct BPsrc;
+private:
+    uint w;                 // precision
+    Rounding r;
+
+    uint ebits, mbits, ebias;
+    uint32 mmask;
+
+    Index max_index, half_index;
+
+    uint32 mantissa(Index i) const
+    {
+        assert(i < half_index);
+        return (1 << mbits) + (i & mmask);
+    }
+    uint exponent(Index i) const
+    {
+        assert(i < half_index);
+        return ebias - (i >> mbits);
+    }
+
+    uint16 Ptbl[256];       // kinda clunky, but so is storage management.
+
+    /* Cost in bits of encoding a zero at every probability, scaled by 2^20.
+       Assumes that index is at most 8 bits wide. */
+
+    uint32 Ctbl[256];
+
+    uint32 split(Index i, uint32 R) const    // 1 <= split <= max( 1, R-1)
+    {
+        if (!ebias)
+            return 1 + (((R - 1) * Ptbl[i]) >> 16);
+
+        if (i >= half_index)
+            return R - split(max_index - i, R);
+
+        return 1 + (((R - 1) * mantissa(i)) >> exponent(i));
+    }
+
+    uint32 max_range() const
+    {
+        return (1 << w) - (r == down_full ? 0 : 1);
+    }
+    uint32 min_range() const
+    {
+        return (1 << (w - 1)) + (r == down_full ? 1 : 0);
+    }
+    uint32 Rinc() const
+    {
+        return r == Up ? 1 : 0;
+    }
+
+    void check_prec() const;
+
+    bool float_init(uint Ebits, uint Mbits);
+
+    void cost_init();
+
+    bool_coder_spec(
+        uint prec, Rounding rr, uint Ebits = 0, uint Mbits = 0
+    )
+        : w(prec), r(rr)
+    {
+        float_init(Ebits, Mbits);
+    }
+public:
+    // Read complete spec from file.
+    bool_coder_spec(FILE *);
+
+    // Write spec to file.
+    void dump(FILE *) const;
+
+    // return probability index best approximating prob.
+    Index operator()(double prob) const;
+
+    // probability corresponding to index
+    double operator()(Index i) const;
+
+    Index complement(Index i) const
+    {
+        return max_index - i;
+    }
+
+    Index max_index() const
+    {
+        return max_index;
+    }
+    Index half_index() const
+    {
+        return half_index;
+    }
+
+    uint32 cost_zero(Index i) const
+    {
+        return Ctbl[i];
+    }
+    uint32 cost_one(Index i) const
+    {
+        return Ctbl[ max_index - i];
+    }
+    uint32 cost_bit(Index i, bool b) const
+    {
+        return Ctbl[b? max_index-i:i];
+    }
+};
+
+
+/* Pseudo floating-point probability specification.
+
+   At least one of Ebits and Mbits must be nonzero.
+
+   Since all arithmetic is done at 32 bits, Ebits is at most 5.
+
+   Total significant bits in index is Ebits + Mbits + 1.
+
+   Below the halfway point (i.e. when the top significant bit is 0),
+   the index is (e << Mbits) + m.
+
+   The exponent e is between 0 and (2**Ebits) - 1,
+   the mantissa m is between 0 and (2**Mbits) - 1.
+
+   Prepending an implicit 1 to the mantissa, the probability is then
+
+        (2**Mbits + m) >> (e - 2**Ebits - 1 - Mbits),
+
+   which has (1/2)**(2**Ebits + 1) as a minimum
+   and (1/2) * [1 - 2**(Mbits + 1)] as a maximum.
+
+   When the index is above the halfway point, the probability is the
+   complement of the probability associated to the complement of the index.
+
+   Note that the probability increases with the index and that, because of
+   the symmetry, we cannot encode probability exactly 1/2; though we
+   can get as close to 1/2 as we like, provided we have enough Mbits.
+
+   The latter is of course not a problem in practice, one never has
+   exact probabilities and entropy errors are second order, that is, the
+   "overcoding" of a zero will be largely compensated for by the
+   "undercoding" of a one (or vice-versa).
+
+   Compared to arithmetic probability specs (a la VP8), this will do better
+   at very high and low probabilities and worse at probabilities near 1/2,
+   as well as facilitating the usage of wider or narrower probability indices.
+*/
+
+struct bool_coder_spec_float : bool_coder_spec
+{
+    bool_coder_spec_float(
+        uint Ebits = 3, uint Mbits = 4, Rounding rr = down_full, uint prec = 12
+    )
+        : bool_coder_spec(prec, rr, Ebits, Mbits)
+    {
+        cost_init();
+    }
+};
+
+
+struct bool_coder_spec_explicit_table : bool_coder_spec
+{
+    bool_coder_spec_explicit_table(
+        cuint16 probability_table[256] = 0,  // default is tbl[i] = i << 8.
+        Rounding = down_full,
+        uint precision = 16
+    );
+};
+
+// Contruct table via multiplicative interpolation between
+// p[128] = 1/2  and p[0] = (1/2)^x.
+// Since we are working with 16-bit precision, x is at most 16.
+// For probabilities to increase with i, we must have x > 1.
+// For 0 <= i <= 128, p[i] = (1/2)^{ 1 + [1 - (i/128)]*[x-1] }.
+// Finally, p[128+i] = 1 - p[128 - i].
+
+struct bool_coder_spec_exponential_table : bool_coder_spec
+{
+    bool_coder_spec_exponential_table(uint x, Rounding = down_full, uint prec = 16);
+};
+
+
+// Commonalities between writer and reader.
+
+struct bool_coder : bool_coder_namespace
+{
+    friend struct bool_writer;
+    friend struct bool_reader;
+    friend struct BPsrc;
+private:
+    uint32 Low, Range;
+    cuint32 min_range;
+    cuint32 rinc;
+    c_spec spec;
+
+    void _reset()
+    {
+        Low = 0;
+        Range = spec.max_range();
+    }
+
+    bool_coder(c_spec &s)
+        :  min_range(s.min_range()),
+           rinc(s.Rinc()),
+           spec(s)
+    {
+        _reset();
+    }
+
+    uint32 half() const
+    {
+        return 1 + ((Range - 1) >> 1);
+    }
+public:
+    c_spec &Spec() const
+    {
+        return spec;
+    }
+};
+
+
+struct bool_writer : bool_coder
+{
+    friend struct BPsrc;
+private:
+    uchar *Bstart, *Bend, *B;
+    int bit_lag;
+    bool is_toast;
+    void carry();
+    void reset()
+    {
+        _reset();
+        bit_lag = 32 - spec.w;
+        is_toast = 0;
+    }
+    void raw(bool value, uint32 split);
+public:
+    bool_writer(c_spec &, uchar *Dest, size_t Len);
+    virtual ~bool_writer();
+
+    void operator()(Index p, bool v)
+    {
+        raw(v, spec.split(p, Range));
+    }
+
+    uchar *buf() const
+    {
+        return Bstart;
+    }
+    size_t bytes_written() const
+    {
+        return B - Bstart;
+    }
+
+    // Call when done with input, flushes internal state.
+    // DO NOT write any more data after calling this.
+
+    bool_writer &flush();
+
+    void write_bits(int n, uint val)
+    {
+        if (n)
+        {
+            uint m = 1 << (n - 1);
+
+            do
+            {
+                raw((bool)(val & m), half());
+            }
+            while (m >>= 1);
+        }
+    }
+
+#   if 0
+    // We are agnostic about storage management.
+    // By default, overflows throw an assert but user can
+    // override to provide an expanding buffer using ...
+
+    virtual void overflow(uint Len) const;
+
+    // ... this function copies already-written data into new buffer
+    // and retains new buffer location.
+
+    void new_buffer(uchar *dest, uint Len);
+
+    // Note that storage management is the user's responsibility.
+#   endif
+};
+
+
+// This could be adjusted to use a little less lookahead.
+
+struct bool_reader : bool_coder
+{
+    friend struct BPsrc;
+private:
+    cuchar *const Bstart;   // for debugging
+    cuchar *B;
+    cuchar *const Bend;
+    cuint shf;
+    uint bct;
+    bool raw(uint32 split);
+public:
+    bool_reader(c_spec &s, cuchar *src, size_t Len);
+
+    bool operator()(Index p)
+    {
+        return raw(spec.split(p, Range));
+    }
+
+    uint read_bits(int num_bits)
+    {
+        uint v = 0;
+
+        while (--num_bits >= 0)
+            v += v + (raw(half()) ? 1 : 0);
+
+        return v;
+    }
+};
+
+extern "C" {
+
+#endif /*  __cplusplus */
+
+
+    /* C interface */
+
+    typedef struct bool_coder_spec bool_coder_spec;
+    typedef struct bool_writer bool_writer;
+    typedef struct bool_reader bool_reader;
+
+    typedef const bool_coder_spec c_bool_coder_spec;
+    typedef const bool_writer c_bool_writer;
+    typedef const bool_reader c_bool_reader;
+
+
+    /* Optionally override default precision when constructing coder_specs.
+       Just pass a zero pointer if you don't care.
+       Precision is at most 16 bits for table specs, at most 23 otherwise. */
+
+    struct vp8bc_prec
+    {
+        enum vp8bc_rounding r;      /* see top header file for def */
+        unsigned int prec;          /* range precision in bits */
+    };
+
+    typedef const struct vp8bc_prec vp8bc_c_prec;
+
+    /* bool_coder_spec contains mapping of uchars to actual probabilities
+       (16 bit uints) as well as (usually immaterial) selection of
+       exact finite-precision algorithm used (for now, the latter can only
+       be overridden using the C++ interface).
+       See comments above the corresponding C++ constructors for discussion,
+       especially of exponential probability table generation. */
+
+    bool_coder_spec *vp8bc_vp8spec(); // just like vp8
+
+    bool_coder_spec *vp8bc_literal_spec(
+        const unsigned short prob_map[256],  // 0 is like vp8 w/more precision
+        vp8bc_c_prec*
+    );
+
+    bool_coder_spec *vp8bc_float_spec(
+        unsigned int exponent_bits, unsigned int mantissa_bits, vp8bc_c_prec*
+    );
+
+    bool_coder_spec *vp8bc_exponential_spec(unsigned int min_exp, vp8bc_c_prec *);
+
+    bool_coder_spec *vp8bc_spec_from_file(FILE *);
+
+
+    void vp8bc_destroy_spec(c_bool_coder_spec *);
+
+    void vp8bc_spec_to_file(c_bool_coder_spec *, FILE *);
+
+
+    /* Nearest index to supplied probability of zero, 0 <= prob <= 1. */
+
+    vp8bc_index_t vp8bc_index(c_bool_coder_spec *, double prob);
+
+    vp8bc_index_t vp8bc_index_from_counts(
+        c_bool_coder_spec *p, unsigned int zero_ct, unsigned int one_ct
+    );
+
+    /* In case you want to look */
+
+    double vp8bc_probability(c_bool_coder_spec *, vp8bc_index_t);
+
+    /* Opposite index */
+
+    vp8bc_index_t vp8bc_complement(c_bool_coder_spec *, vp8bc_index_t);
+
+    /* Cost in bits of encoding a zero at given probability, scaled by 2^20.
+       (assumes that an int holds at least 32 bits). */
+
+    unsigned int vp8bc_cost_zero(c_bool_coder_spec *, vp8bc_index_t);
+
+    unsigned int vp8bc_cost_one(c_bool_coder_spec *, vp8bc_index_t);
+    unsigned int vp8bc_cost_bit(c_bool_coder_spec *, vp8bc_index_t, int);
+
+
+    /* bool_writer interface */
+
+    /* Length = 0 disables checking for writes beyond buffer end. */
+
+    bool_writer *vp8bc_create_writer(
+        c_bool_coder_spec *, unsigned char *Destination, size_t Length
+    );
+
+    /* Flushes out any buffered data and returns total # of bytes written. */
+
+    size_t vp8bc_destroy_writer(bool_writer *);
+
+    void vp8bc_write_bool(bool_writer *, int boolean_val, vp8bc_index_t false_prob);
+
+    void vp8bc_write_bits(
+        bool_writer *, unsigned int integer_value, int number_of_bits
+    );
+
+    c_bool_coder_spec *vp8bc_writer_spec(c_bool_writer *);
+
+
+    /* bool_reader interface */
+
+    /* Length = 0 disables checking for reads beyond buffer end. */
+
+    bool_reader *vp8bc_create_reader(
+        c_bool_coder_spec *, const unsigned char *Source, size_t Length
+    );
+    void vp8bc_destroy_reader(bool_reader *);
+
+    int vp8bc_read_bool(bool_reader *, vp8bc_index_t false_prob);
+
+    unsigned int vp8bc_read_bits(bool_reader *, int number_of_bits);
+
+    c_bool_coder_spec *vp8bc_reader_spec(c_bool_reader *);
+
+#if __cplusplus
+}
+#endif
+
+#endif  /* bool_coder_h */
diff --git a/vp8/common/codec_common_interface.h b/vp8/common/codec_common_interface.h
new file mode 100644 (file)
index 0000000..7881b0a
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+#ifndef CODEC_COMMON_INTERFACE_H
+#define CODEC_COMMON_INTERFACE_H
+
+#define __export
+#define _export
+#define dll_export   __declspec( dllexport )
+#define dll_import   __declspec( dllimport )
+
+// Playback ERROR Codes.
+#define NO_DECODER_ERROR            0
+#define REMOTE_DECODER_ERROR        -1
+
+#define DFR_BAD_DCT_COEFF           -100
+#define DFR_ZERO_LENGTH_FRAME       -101
+#define DFR_FRAME_SIZE_INVALID      -102
+#define DFR_OUTPUT_BUFFER_OVERFLOW  -103
+#define DFR_INVALID_FRAME_HEADER    -104
+#define FR_INVALID_MODE_TOKEN       -110
+#define ETR_ALLOCATION_ERROR        -200
+#define ETR_INVALID_ROOT_PTR        -201
+#define SYNCH_ERROR                 -400
+#define BUFFER_UNDERFLOW_ERROR      -500
+#define PB_IB_OVERFLOW_ERROR        -501
+
+// External error triggers
+#define PB_HEADER_CHECKSUM_ERROR    -601
+#define PB_DATA_CHECKSUM_ERROR      -602
+
+// DCT Error Codes
+#define DDCT_EXPANSION_ERROR        -700
+#define DDCT_INVALID_TOKEN_ERROR    -701
+
+// exception_errors
+#define GEN_EXCEPTIONS              -800
+#define EX_UNQUAL_ERROR             -801
+
+// Unrecoverable error codes
+#define FATAL_PLAYBACK_ERROR        -1000
+#define GEN_ERROR_CREATING_CDC      -1001
+#define GEN_THREAD_CREATION_ERROR   -1002
+#define DFR_CREATE_BMP_FAILED       -1003
+
+// YUV buffer configuration structure
+typedef struct
+{
+    int     y_width;
+    int     y_height;
+    int     y_stride;
+
+    int     uv_width;
+    int     uv_height;
+    int     uv_stride;
+
+    unsigned char   *y_buffer;
+    unsigned char   *u_buffer;
+    unsigned char   *v_buffer;
+
+} YUV_BUFFER_CONFIG;
+typedef enum
+{
+    C_SET_KEY_FRAME,
+    C_SET_FIXED_Q,
+    C_SET_FIRSTPASS_FILE,
+    C_SET_EXPERIMENTAL_MIN,
+    C_SET_EXPERIMENTAL_MAX = C_SET_EXPERIMENTAL_MIN + 255,
+    C_SET_CHECKPROTECT,
+    C_SET_TESTMODE,
+    C_SET_INTERNAL_SIZE,
+    C_SET_RECOVERY_FRAME,
+    C_SET_REFERENCEFRAME,
+    C_SET_GOLDENFRAME
+
+#ifndef VP50_COMP_INTERFACE
+    // Specialist test facilities.
+//    C_VCAP_PARAMS,              // DO NOT USE FOR NOW WITH VFW CODEC
+#endif
+
+} C_SETTING;
+
+typedef unsigned long C_SET_VALUE;
+
+
+#endif
diff --git a/vp8/common/coefupdateprobs.h b/vp8/common/coefupdateprobs.h
new file mode 100644 (file)
index 0000000..99affd6
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* Update probabilities for the nodes in the token entropy tree.
+   Generated file included by entropy.c */
+
+const vp8_prob vp8_coef_update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] =
+{
+    {
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, },
+            {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+    {
+        {
+            {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, },
+            {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, },
+        },
+        {
+            {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+    {
+        {
+            {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+    {
+        {
+            {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, },
+            {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+};
diff --git a/vp8/common/common.h b/vp8/common/common.h
new file mode 100644 (file)
index 0000000..29f6d37
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef common_h
+#define common_h 1
+
+#include <assert.h>
+
+/* Interface header for common constant data structures and lookup tables */
+
+#include "vpx_mem/vpx_mem.h"
+
+#include "common_types.h"
+
+/* Only need this for fixed-size arrays, for structs just assign. */
+
+#define vp8_copy( Dest, Src) { \
+        assert( sizeof( Dest) == sizeof( Src)); \
+        vpx_memcpy( Dest, Src, sizeof( Src)); \
+    }
+
+/* Use this for variably-sized arrays. */
+
+#define vp8_copy_array( Dest, Src, N) { \
+        assert( sizeof( *Dest) == sizeof( *Src)); \
+        vpx_memcpy( Dest, Src, N * sizeof( *Src)); \
+    }
+
+#define vp8_zero( Dest)  vpx_memset( &Dest, 0, sizeof( Dest));
+
+#define vp8_zero_array( Dest, N)  vpx_memset( Dest, 0, N * sizeof( *Dest));
+
+
+#endif  /* common_h */
diff --git a/vp8/common/common_types.h b/vp8/common/common_types.h
new file mode 100644 (file)
index 0000000..deb5ed8
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_COMMON_TYPES
+#define __INC_COMMON_TYPES
+
+#define TRUE    1
+#define FALSE   0
+
+#endif
diff --git a/vp8/common/context.c b/vp8/common/context.c
new file mode 100644 (file)
index 0000000..17ee8c3
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "entropy.h"
+
+/* *** GENERATED FILE: DO NOT EDIT *** */
+
+#if 0
+int Contexts[vp8_coef_counter_dimen];
+
+const int default_contexts[vp8_coef_counter_dimen] =
+{
+    {
+        // Block Type ( 0 )
+        {
+            // Coeff Band ( 0 )
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {30190, 26544, 225,  24,   4,   0,   0,   0,   0,   0,   0, 4171593,},
+            {26846, 25157, 1241, 130,  26,   6,   1,   0,   0,   0,   0, 149987,},
+            {10484, 9538, 1006, 160,  36,  18,   0,   0,   0,   0,   0, 15104,},
+        },
+        {
+            // Coeff Band ( 2 )
+            {25842, 40456, 1126,  83,  11,   2,   0,   0,   0,   0,   0,   0,},
+            {9338, 8010, 512,  73,   7,   3,   2,   0,   0,   0,   0, 43294,},
+            {1047, 751, 149,  31,  13,   6,   1,   0,   0,   0,   0, 879,},
+        },
+        {
+            // Coeff Band ( 3 )
+            {26136, 9826, 252,  13,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {8134, 5574, 191,  14,   2,   0,   0,   0,   0,   0,   0, 35302,},
+            { 605, 677, 116,   9,   1,   0,   0,   0,   0,   0,   0, 611,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {10263, 15463, 283,  17,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {2773, 2191, 128,   9,   2,   2,   0,   0,   0,   0,   0, 10073,},
+            { 134, 125,  32,   4,   0,   2,   0,   0,   0,   0,   0,  50,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {10483, 2663,  23,   1,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {2137, 1251,  27,   1,   1,   0,   0,   0,   0,   0,   0, 14362,},
+            { 116, 156,  14,   2,   1,   0,   0,   0,   0,   0,   0, 190,},
+        },
+        {
+            // Coeff Band ( 6 )
+            {40977, 27614, 412,  28,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {6113, 5213, 261,  22,   3,   0,   0,   0,   0,   0,   0, 26164,},
+            { 382, 312,  50,  14,   2,   0,   0,   0,   0,   0,   0, 345,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,  13,   0,   0,   0,   0,   0,   0,   0,   0,   0, 319,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,},
+        },
+    },
+    {
+        // Block Type ( 1 )
+        {
+            // Coeff Band ( 0 )
+            {3268, 19382, 1043, 250,  93,  82,  49,  26,  17,   8,  25, 82289,},
+            {8758, 32110, 5436, 1832, 827, 668, 420, 153,  24,   0,   3, 52914,},
+            {9337, 23725, 8487, 3954, 2107, 1836, 1069, 399,  59,   0,   0, 18620,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {12419, 8420, 452,  62,   9,   1,   0,   0,   0,   0,   0,   0,},
+            {11715, 8705, 693,  92,  15,   7,   2,   0,   0,   0,   0, 53988,},
+            {7603, 8585, 2306, 778, 270, 145,  39,   5,   0,   0,   0, 9136,},
+        },
+        {
+            // Coeff Band ( 2 )
+            {15938, 14335, 1207, 184,  55,  13,   4,   1,   0,   0,   0,   0,},
+            {7415, 6829, 1138, 244,  71,  26,   7,   0,   0,   0,   0, 9980,},
+            {1580, 1824, 655, 241,  89,  46,  10,   2,   0,   0,   0, 429,},
+        },
+        {
+            // Coeff Band ( 3 )
+            {19453, 5260, 201,  19,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {9173, 3758, 213,  22,   1,   1,   0,   0,   0,   0,   0, 9820,},
+            {1689, 1277, 276,  51,  17,   4,   0,   0,   0,   0,   0, 679,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {12076, 10667, 620,  85,  19,   9,   5,   0,   0,   0,   0,   0,},
+            {4665, 3625, 423,  55,  19,   9,   0,   0,   0,   0,   0, 5127,},
+            { 415, 440, 143,  34,  20,   7,   2,   0,   0,   0,   0, 101,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {12183, 4846, 115,  11,   1,   0,   0,   0,   0,   0,   0,   0,},
+            {4226, 3149, 177,  21,   2,   0,   0,   0,   0,   0,   0, 7157,},
+            { 375, 621, 189,  51,  11,   4,   1,   0,   0,   0,   0, 198,},
+        },
+        {
+            // Coeff Band ( 6 )
+            {61658, 37743, 1203,  94,  10,   3,   0,   0,   0,   0,   0,   0,},
+            {15514, 11563, 903, 111,  14,   5,   0,   0,   0,   0,   0, 25195,},
+            { 929, 1077, 291,  78,  14,   7,   1,   0,   0,   0,   0, 507,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0, 990,  15,   3,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0, 412,  13,   0,   0,   0,   0,   0,   0,   0,   0, 1641,},
+            {   0,  18,   7,   1,   0,   0,   0,   0,   0,   0,   0,  30,},
+        },
+    },
+    {
+        // Block Type ( 2 )
+        {
+            // Coeff Band ( 0 )
+            { 953, 24519, 628, 120,  28,  12,   4,   0,   0,   0,   0, 2248798,},
+            {1525, 25654, 2647, 617, 239, 143,  42,   5,   0,   0,   0, 66837,},
+            {1180, 11011, 3001, 1237, 532, 448, 239,  54,   5,   0,   0, 7122,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {1356, 2220,  67,  10,   4,   1,   0,   0,   0,   0,   0,   0,},
+            {1450, 2544, 102,  18,   4,   3,   0,   0,   0,   0,   0, 57063,},
+            {1182, 2110, 470, 130,  41,  21,   0,   0,   0,   0,   0, 6047,},
+        },
+        {
+            // Coeff Band ( 2 )
+            { 370, 3378, 200,  30,   5,   4,   1,   0,   0,   0,   0,   0,},
+            { 293, 1006, 131,  29,  11,   0,   0,   0,   0,   0,   0, 5404,},
+            { 114, 387,  98,  23,   4,   8,   1,   0,   0,   0,   0, 236,},
+        },
+        {
+            // Coeff Band ( 3 )
+            { 579, 194,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            { 395, 213,   5,   1,   0,   0,   0,   0,   0,   0,   0, 4157,},
+            { 119, 122,   4,   0,   0,   0,   0,   0,   0,   0,   0, 300,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {  38, 557,  19,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  21, 114,  12,   1,   0,   0,   0,   0,   0,   0,   0, 427,},
+            {   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {  52,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  18,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0, 652,},
+            {   1,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  30,},
+        },
+        {
+            // Coeff Band ( 6 )
+            { 640, 569,  10,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  25,  77,   2,   0,   0,   0,   0,   0,   0,   0,   0, 517,},
+            {   4,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+        },
+    },
+    {
+        // Block Type ( 3 )
+        {
+            // Coeff Band ( 0 )
+            {2506, 20161, 2707, 767, 261, 178, 107,  30,  14,   3,   0, 100694,},
+            {8806, 36478, 8817, 3268, 1280, 850, 401, 114,  42,   0,   0, 58572,},
+            {11003, 27214, 11798, 5716, 2482, 2072, 1048, 175,  32,   0,   0, 19284,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {9738, 11313, 959, 205,  70,  18,  11,   1,   0,   0,   0,   0,},
+            {12628, 15085, 1507, 273,  52,  19,   9,   0,   0,   0,   0, 54280,},
+            {10701, 15846, 5561, 1926, 813, 570, 249,  36,   0,   0,   0, 6460,},
+        },
+        {
+            // Coeff Band ( 2 )
+            {6781, 22539, 2784, 634, 182, 123,  20,   4,   0,   0,   0,   0,},
+            {6263, 11544, 2649, 790, 259, 168,  27,   5,   0,   0,   0, 20539,},
+            {3109, 4075, 2031, 896, 457, 386, 158,  29,   0,   0,   0, 1138,},
+        },
+        {
+            // Coeff Band ( 3 )
+            {11515, 4079, 465,  73,   5,  14,   2,   0,   0,   0,   0,   0,},
+            {9361, 5834, 650,  96,  24,   8,   4,   0,   0,   0,   0, 22181,},
+            {4343, 3974, 1360, 415, 132,  96,  14,   1,   0,   0,   0, 1267,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {4787, 9297, 823, 168,  44,  12,   4,   0,   0,   0,   0,   0,},
+            {3619, 4472, 719, 198,  60,  31,   3,   0,   0,   0,   0, 8401,},
+            {1157, 1175, 483, 182,  88,  31,   8,   0,   0,   0,   0, 268,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {8299, 1226,  32,   5,   1,   0,   0,   0,   0,   0,   0,   0,},
+            {3502, 1568,  57,   4,   1,   1,   0,   0,   0,   0,   0, 9811,},
+            {1055, 1070, 166,  29,   6,   1,   0,   0,   0,   0,   0, 527,},
+        },
+        {
+            // Coeff Band ( 6 )
+            {27414, 27927, 1989, 347,  69,  26,   0,   0,   0,   0,   0,   0,},
+            {5876, 10074, 1574, 341,  91,  24,   4,   0,   0,   0,   0, 21954,},
+            {1571, 2171, 778, 324, 124,  65,  16,   0,   0,   0,   0, 979,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0,  29,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,  23,   0,   0,   0,   0,   0,   0,   0,   0,   0, 459,},
+            {   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  13,},
+        },
+    },
+};
+
+//Update probabilities for the nodes in the token entropy tree.
+const vp8_prob tree_update_probs[vp8_coef_tree_dimen] =
+{
+    {
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, },
+            {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+    {
+        {
+            {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, },
+            {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, },
+        },
+        {
+            {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+    {
+        {
+            {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+    {
+        {
+            {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, },
+            {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+        {
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+            {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, },
+        },
+    },
+};
+#endif
diff --git a/vp8/common/debugmodes.c b/vp8/common/debugmodes.c
new file mode 100644 (file)
index 0000000..e2d2d2c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdio.h>
+#include "blockd.h"
+
+
+void vp8_print_modes_and_motion_vectors(MODE_INFO *mi, int rows, int cols, int frame)
+{
+
+    int mb_row;
+    int mb_col;
+    int mb_index = 0;
+    FILE *mvs = fopen("mvs.stt", "a");
+
+    // print out the macroblock Y modes
+    mb_index = 0;
+    fprintf(mvs, "Mb Modes for Frame %d\n", frame);
+
+    for (mb_row = 0; mb_row < rows; mb_row++)
+    {
+        for (mb_col = 0; mb_col < cols; mb_col++)
+        {
+
+            fprintf(mvs, "%2d ", mi[mb_index].mbmi.mode);
+
+            mb_index++;
+        }
+
+        fprintf(mvs, "\n");
+        mb_index++;
+    }
+
+    fprintf(mvs, "\n");
+
+    mb_index = 0;
+    fprintf(mvs, "Mb mv ref for Frame %d\n", frame);
+
+    for (mb_row = 0; mb_row < rows; mb_row++)
+    {
+        for (mb_col = 0; mb_col < cols; mb_col++)
+        {
+
+            fprintf(mvs, "%2d ", mi[mb_index].mbmi.ref_frame);
+
+            mb_index++;
+        }
+
+        fprintf(mvs, "\n");
+        mb_index++;
+    }
+
+    fprintf(mvs, "\n");
+
+    // print out the macroblock UV modes
+    mb_index = 0;
+    fprintf(mvs, "UV Modes for Frame %d\n", frame);
+
+    for (mb_row = 0; mb_row < rows; mb_row++)
+    {
+        for (mb_col = 0; mb_col < cols; mb_col++)
+        {
+
+            fprintf(mvs, "%2d ", mi[mb_index].mbmi.uv_mode);
+
+            mb_index++;
+        }
+
+        mb_index++;
+        fprintf(mvs, "\n");
+    }
+
+    fprintf(mvs, "\n");
+
+    // print out the block modes
+    mb_index = 0;
+    fprintf(mvs, "Mbs for Frame %d\n", frame);
+    {
+        int b_row;
+
+        for (b_row = 0; b_row < 4 * rows; b_row++)
+        {
+            int b_col;
+            int bindex;
+
+            for (b_col = 0; b_col < 4 * cols; b_col++)
+            {
+                mb_index = (b_row >> 2) * (cols + 1) + (b_col >> 2);
+                bindex = (b_row & 3) * 4 + (b_col & 3);
+
+                if (mi[mb_index].mbmi.mode == B_PRED)
+                    fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].mode);
+                else
+                    fprintf(mvs, "xx ");
+
+            }
+
+            fprintf(mvs, "\n");
+        }
+    }
+    fprintf(mvs, "\n");
+
+    // print out the macroblock mvs
+    mb_index = 0;
+    fprintf(mvs, "MVs for Frame %d\n", frame);
+
+    for (mb_row = 0; mb_row < rows; mb_row++)
+    {
+        for (mb_col = 0; mb_col < cols; mb_col++)
+        {
+            fprintf(mvs, "%5d:%-5d", mi[mb_index].mbmi.mv.as_mv.row / 2, mi[mb_index].mbmi.mv.as_mv.col / 2);
+
+            mb_index++;
+        }
+
+        mb_index++;
+        fprintf(mvs, "\n");
+    }
+
+    fprintf(mvs, "\n");
+
+
+    // print out the block modes
+    mb_index = 0;
+    fprintf(mvs, "MVs for Frame %d\n", frame);
+    {
+        int b_row;
+
+        for (b_row = 0; b_row < 4 * rows; b_row++)
+        {
+            int b_col;
+            int bindex;
+
+            for (b_col = 0; b_col < 4 * cols; b_col++)
+            {
+                mb_index = (b_row >> 2) * (cols + 1) + (b_col >> 2);
+                bindex = (b_row & 3) * 4 + (b_col & 3);
+                fprintf(mvs, "%3d:%-3d ", mi[mb_index].bmi[bindex].mv.as_mv.row, mi[mb_index].bmi[bindex].mv.as_mv.col);
+
+            }
+
+            fprintf(mvs, "\n");
+        }
+    }
+    fprintf(mvs, "\n");
+
+
+    fclose(mvs);
+}
diff --git a/vp8/common/defaultcoefcounts.h b/vp8/common/defaultcoefcounts.h
new file mode 100644 (file)
index 0000000..ccdf326
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* Generated file, included by entropy.c */
+
+static const unsigned int default_coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] =
+{
+
+    {
+        // Block Type ( 0 )
+        {
+            // Coeff Band ( 0 )
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {30190, 26544, 225,  24,   4,   0,   0,   0,   0,   0,   0, 4171593,},
+            {26846, 25157, 1241, 130,  26,   6,   1,   0,   0,   0,   0, 149987,},
+            {10484, 9538, 1006, 160,  36,  18,   0,   0,   0,   0,   0, 15104,},
+        },
+        {
+            // Coeff Band ( 2 )
+            {25842, 40456, 1126,  83,  11,   2,   0,   0,   0,   0,   0,   0,},
+            {9338, 8010, 512,  73,   7,   3,   2,   0,   0,   0,   0, 43294,},
+            {1047, 751, 149,  31,  13,   6,   1,   0,   0,   0,   0, 879,},
+        },
+        {
+            // Coeff Band ( 3 )
+            {26136, 9826, 252,  13,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {8134, 5574, 191,  14,   2,   0,   0,   0,   0,   0,   0, 35302,},
+            { 605, 677, 116,   9,   1,   0,   0,   0,   0,   0,   0, 611,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {10263, 15463, 283,  17,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {2773, 2191, 128,   9,   2,   2,   0,   0,   0,   0,   0, 10073,},
+            { 134, 125,  32,   4,   0,   2,   0,   0,   0,   0,   0,  50,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {10483, 2663,  23,   1,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {2137, 1251,  27,   1,   1,   0,   0,   0,   0,   0,   0, 14362,},
+            { 116, 156,  14,   2,   1,   0,   0,   0,   0,   0,   0, 190,},
+        },
+        {
+            // Coeff Band ( 6 )
+            {40977, 27614, 412,  28,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {6113, 5213, 261,  22,   3,   0,   0,   0,   0,   0,   0, 26164,},
+            { 382, 312,  50,  14,   2,   0,   0,   0,   0,   0,   0, 345,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,  13,   0,   0,   0,   0,   0,   0,   0,   0,   0, 319,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,},
+        },
+    },
+    {
+        // Block Type ( 1 )
+        {
+            // Coeff Band ( 0 )
+            {3268, 19382, 1043, 250,  93,  82,  49,  26,  17,   8,  25, 82289,},
+            {8758, 32110, 5436, 1832, 827, 668, 420, 153,  24,   0,   3, 52914,},
+            {9337, 23725, 8487, 3954, 2107, 1836, 1069, 399,  59,   0,   0, 18620,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {12419, 8420, 452,  62,   9,   1,   0,   0,   0,   0,   0,   0,},
+            {11715, 8705, 693,  92,  15,   7,   2,   0,   0,   0,   0, 53988,},
+            {7603, 8585, 2306, 778, 270, 145,  39,   5,   0,   0,   0, 9136,},
+        },
+        {
+            // Coeff Band ( 2 )
+            {15938, 14335, 1207, 184,  55,  13,   4,   1,   0,   0,   0,   0,},
+            {7415, 6829, 1138, 244,  71,  26,   7,   0,   0,   0,   0, 9980,},
+            {1580, 1824, 655, 241,  89,  46,  10,   2,   0,   0,   0, 429,},
+        },
+        {
+            // Coeff Band ( 3 )
+            {19453, 5260, 201,  19,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {9173, 3758, 213,  22,   1,   1,   0,   0,   0,   0,   0, 9820,},
+            {1689, 1277, 276,  51,  17,   4,   0,   0,   0,   0,   0, 679,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {12076, 10667, 620,  85,  19,   9,   5,   0,   0,   0,   0,   0,},
+            {4665, 3625, 423,  55,  19,   9,   0,   0,   0,   0,   0, 5127,},
+            { 415, 440, 143,  34,  20,   7,   2,   0,   0,   0,   0, 101,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {12183, 4846, 115,  11,   1,   0,   0,   0,   0,   0,   0,   0,},
+            {4226, 3149, 177,  21,   2,   0,   0,   0,   0,   0,   0, 7157,},
+            { 375, 621, 189,  51,  11,   4,   1,   0,   0,   0,   0, 198,},
+        },
+        {
+            // Coeff Band ( 6 )
+            {61658, 37743, 1203,  94,  10,   3,   0,   0,   0,   0,   0,   0,},
+            {15514, 11563, 903, 111,  14,   5,   0,   0,   0,   0,   0, 25195,},
+            { 929, 1077, 291,  78,  14,   7,   1,   0,   0,   0,   0, 507,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0, 990,  15,   3,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0, 412,  13,   0,   0,   0,   0,   0,   0,   0,   0, 1641,},
+            {   0,  18,   7,   1,   0,   0,   0,   0,   0,   0,   0,  30,},
+        },
+    },
+    {
+        // Block Type ( 2 )
+        {
+            // Coeff Band ( 0 )
+            { 953, 24519, 628, 120,  28,  12,   4,   0,   0,   0,   0, 2248798,},
+            {1525, 25654, 2647, 617, 239, 143,  42,   5,   0,   0,   0, 66837,},
+            {1180, 11011, 3001, 1237, 532, 448, 239,  54,   5,   0,   0, 7122,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {1356, 2220,  67,  10,   4,   1,   0,   0,   0,   0,   0,   0,},
+            {1450, 2544, 102,  18,   4,   3,   0,   0,   0,   0,   0, 57063,},
+            {1182, 2110, 470, 130,  41,  21,   0,   0,   0,   0,   0, 6047,},
+        },
+        {
+            // Coeff Band ( 2 )
+            { 370, 3378, 200,  30,   5,   4,   1,   0,   0,   0,   0,   0,},
+            { 293, 1006, 131,  29,  11,   0,   0,   0,   0,   0,   0, 5404,},
+            { 114, 387,  98,  23,   4,   8,   1,   0,   0,   0,   0, 236,},
+        },
+        {
+            // Coeff Band ( 3 )
+            { 579, 194,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            { 395, 213,   5,   1,   0,   0,   0,   0,   0,   0,   0, 4157,},
+            { 119, 122,   4,   0,   0,   0,   0,   0,   0,   0,   0, 300,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {  38, 557,  19,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  21, 114,  12,   1,   0,   0,   0,   0,   0,   0,   0, 427,},
+            {   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {  52,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  18,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0, 652,},
+            {   1,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  30,},
+        },
+        {
+            // Coeff Band ( 6 )
+            { 640, 569,  10,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  25,  77,   2,   0,   0,   0,   0,   0,   0,   0,   0, 517,},
+            {   4,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+        },
+    },
+    {
+        // Block Type ( 3 )
+        {
+            // Coeff Band ( 0 )
+            {2506, 20161, 2707, 767, 261, 178, 107,  30,  14,   3,   0, 100694,},
+            {8806, 36478, 8817, 3268, 1280, 850, 401, 114,  42,   0,   0, 58572,},
+            {11003, 27214, 11798, 5716, 2482, 2072, 1048, 175,  32,   0,   0, 19284,},
+        },
+        {
+            // Coeff Band ( 1 )
+            {9738, 11313, 959, 205,  70,  18,  11,   1,   0,   0,   0,   0,},
+            {12628, 15085, 1507, 273,  52,  19,   9,   0,   0,   0,   0, 54280,},
+            {10701, 15846, 5561, 1926, 813, 570, 249,  36,   0,   0,   0, 6460,},
+        },
+        {
+            // Coeff Band ( 2 )
+            {6781, 22539, 2784, 634, 182, 123,  20,   4,   0,   0,   0,   0,},
+            {6263, 11544, 2649, 790, 259, 168,  27,   5,   0,   0,   0, 20539,},
+            {3109, 4075, 2031, 896, 457, 386, 158,  29,   0,   0,   0, 1138,},
+        },
+        {
+            // Coeff Band ( 3 )
+            {11515, 4079, 465,  73,   5,  14,   2,   0,   0,   0,   0,   0,},
+            {9361, 5834, 650,  96,  24,   8,   4,   0,   0,   0,   0, 22181,},
+            {4343, 3974, 1360, 415, 132,  96,  14,   1,   0,   0,   0, 1267,},
+        },
+        {
+            // Coeff Band ( 4 )
+            {4787, 9297, 823, 168,  44,  12,   4,   0,   0,   0,   0,   0,},
+            {3619, 4472, 719, 198,  60,  31,   3,   0,   0,   0,   0, 8401,},
+            {1157, 1175, 483, 182,  88,  31,   8,   0,   0,   0,   0, 268,},
+        },
+        {
+            // Coeff Band ( 5 )
+            {8299, 1226,  32,   5,   1,   0,   0,   0,   0,   0,   0,   0,},
+            {3502, 1568,  57,   4,   1,   1,   0,   0,   0,   0,   0, 9811,},
+            {1055, 1070, 166,  29,   6,   1,   0,   0,   0,   0,   0, 527,},
+        },
+        {
+            // Coeff Band ( 6 )
+            {27414, 27927, 1989, 347,  69,  26,   0,   0,   0,   0,   0,   0,},
+            {5876, 10074, 1574, 341,  91,  24,   4,   0,   0,   0,   0, 21954,},
+            {1571, 2171, 778, 324, 124,  65,  16,   0,   0,   0,   0, 979,},
+        },
+        {
+            // Coeff Band ( 7 )
+            {   0,  29,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,  23,   0,   0,   0,   0,   0,   0,   0,   0,   0, 459,},
+            {   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  13,},
+        },
+    },
+};
diff --git a/vp8/common/dma_desc.h b/vp8/common/dma_desc.h
new file mode 100644 (file)
index 0000000..5e6fa0c
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _dma_desc_h
+#define _dma_desc_h
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#define NDSIZE_LG   0x00000900  // Next Descriptor Size
+#define NDSIZE_SM   0x00000800  // Next Descriptor Size
+#define NDSIZE_7    0x00000700  // Next Descriptor Size
+#define NDSIZE_6    0x00000600  // Next Descriptor Size
+#define NDSIZE_5    0x00000500  // Next Descriptor Size
+#define NDSIZE_4    0x00000400  // Next Descriptor Size
+#define NDSIZE_3    0x00000300  // Next Descriptor Size
+#define NDSIZE_2    0x00000200  // Next Descriptor Size
+#define NDSIZE_1    0x00000100  // Next Descriptor Size
+
+#define FLOW_STOP       0x0000
+#define FLOW_AUTO       0x1000
+#define FLOW_DESC_AR    0x4000
+#define FLOW_DESC_SM    0x6000
+#define FLOW_DESC_LG    0x7000
+
+    typedef struct
+    {
+        unsigned int ndp;
+        //unsigned short ndpl;
+        //unsigned short ndph;
+        unsigned int sa;
+        //unsigned short sal;
+        //unsigned short sah;
+
+        unsigned short dmacfg;
+        unsigned short xcnt;
+        unsigned short xmod;
+        unsigned short ycnt;
+        unsigned short ymod;
+
+    } LARGE_DESC;
+
+    typedef struct
+    {
+        unsigned short ndpl;
+        unsigned short sal;
+        unsigned short sah;
+        unsigned short dmacfg;
+        unsigned short xcnt;
+        unsigned short xmod;
+        unsigned short ycnt;
+        unsigned short ymod;
+    } SMALL_DESC;
+
+    typedef struct
+    {
+        unsigned short sal;
+        unsigned short sah;
+        unsigned short dmacfg;
+        unsigned short xcnt;
+        unsigned short xmod;
+        unsigned short ycnt;
+        unsigned short ymod;
+    } ARRAY_DESC_7;
+
+    typedef struct
+    {
+        unsigned short sal;
+        unsigned short sah;
+        unsigned short dmacfg;
+        unsigned short xcnt;
+        unsigned short xmod;
+        unsigned short ycnt;
+    } ARRAY_DESC_6;
+
+    typedef struct
+    {
+        unsigned short sal;
+        unsigned short sah;
+        unsigned short dmacfg;
+        unsigned short xcnt;
+        unsigned short xmod;
+    } ARRAY_DESC_5;
+
+    typedef struct
+    {
+        unsigned short sal;
+        unsigned short sah;
+        unsigned short dmacfg;
+        unsigned short xcnt;
+    } ARRAY_DESC_4;
+
+    typedef struct
+    {
+        unsigned short sal;
+        unsigned short sah;
+        unsigned short dmacfg;
+    } ARRAY_DESC_3;
+
+    typedef struct
+    {
+        unsigned short sal;
+        unsigned short sah;
+    } ARRAY_DESC_2;
+
+    typedef struct
+    {
+        unsigned short sal;
+    } ARRAY_DESC_1;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //_dma_desc_h
diff --git a/vp8/common/duck_io.h b/vp8/common/duck_io.h
new file mode 100644 (file)
index 0000000..f63a5cd
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _duck_io_h
+#define _duck_io_h
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined (_WIN32)
+    typedef __int64 int64_t;
+#elif defined(__MWERKS__)
+    typedef long long int64_t;
+#elif defined(__APPLE__) || defined(__POWERPC)
+#include <ppc/types.h>
+#else
+    typedef long long int64_t;
+#endif
+
+    typedef struct
+    {
+        int64_t  offset;     // offset to start from
+        int    blocking;    // non-zero for blocking
+    } re_open_t;
+
+
+    typedef enum
+    {
+        SAL_ERR_MAX                 = -10,
+        SAL_ERROR                   = -11, // Default error
+        SAL_ERR_WSASTARTUP          = -12,
+        SAL_ERR_SOCKET_CREATE       = -13,
+        SAL_ERR_RESOLVING_HOSTNAME  = -14,
+        SAL_ERR_SERVER_CONNECTION   = -15,
+        SAL_ERR_SENDING_DATA        = -16,
+        SAL_ERR_RECEIVING_DATA      = -17,
+        SAL_ERR_404_FILE_NOT_FOUND  = -18,
+        SAL_ERR_PARSING_HTTP_HEADER = -19,
+        SAL_ERR_PARSING_CONTENT_LEN = -20,
+        SAL_ERR_CONNECTION_TIMEOUT  = -21,
+        SAL_ERR_FILE_OPEN_FAILED    = -22,
+        SAL_ERR_MIN                 = -23
+    } SAL_ERR; /* EMH 1-15-03 */
+
+
+    typedef struct sal_err_map_temp
+    {
+        SAL_ERR code;
+        const char *decode;
+
+    } sal_err_map_t;
+
+
+    static char *sal_err_text(SAL_ERR e)
+    {
+        int t;
+        const sal_err_map_t g_sal_err_map[] =
+        {
+            {   SAL_ERR_WSASTARTUP,             "Error with WSAStartup"         },
+            {   SAL_ERR_SOCKET_CREATE,          "Error creating socket"         },
+            {   SAL_ERR_RESOLVING_HOSTNAME,     "Error resolving hostname"      },
+            {   SAL_ERR_SERVER_CONNECTION,      "Error connecting to server"    },
+            {   SAL_ERR_SENDING_DATA,           "Error sending data"            },
+            {   SAL_ERR_RECEIVING_DATA,         "Error receiving data"          },
+            {   SAL_ERR_404_FILE_NOT_FOUND,     "Error file not found "         },
+            {   SAL_ERR_PARSING_HTTP_HEADER,    "Error parsing http header"     },
+            {   SAL_ERR_PARSING_CONTENT_LEN,    "Error parsing content length"  },
+            {   SAL_ERR_CONNECTION_TIMEOUT,     "Error Connection timed out"    },
+            {   SAL_ERR_FILE_OPEN_FAILED,       "Error opening file"            }
+        };
+
+        for (t = 0; t < sizeof(g_sal_err_map) / sizeof(sal_err_map_t); t++)
+        {
+            if (e == g_sal_err_map[t].code)
+                return (char *) g_sal_err_map[t].decode;
+        }
+
+        return 0;
+    }
+
+
+
+
+
+
+
+    int duck_open(const char *fname, unsigned long user_data);
+
+    void duck_close(int ghndl);
+
+    int duck_read(int ghndl, unsigned char *buf, int nbytes);
+
+    int64_t duck_seek(int g_hndl, int64_t offs, int origin);
+
+    int duck_read_finished(int han, int flag); /* FWG 7-9-99 */
+
+    int duck_name(int handle, char name[], size_t max_len); /* EMH 9-23-03 */
+
+    int duck_read_blocking(int handle, unsigned char *buffer, int bytes); /* EMH 9-23-03 */
+
+    int64_t duck_available_data(int handle); /* EMH 10-23-03 */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/vp8/common/entropy.c b/vp8/common/entropy.c
new file mode 100644 (file)
index 0000000..e524c2a
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdio.h>
+
+#include "entropy.h"
+#include "string.h"
+#include "blockd.h"
+#include "onyxc_int.h"
+
+#define uchar unsigned char     /* typedefs can clash */
+#define uint  unsigned int
+
+typedef const uchar cuchar;
+typedef const uint cuint;
+
+typedef vp8_prob Prob;
+
+#include "coefupdateprobs.h"
+
+DECLARE_ALIGNED(16, cuchar, vp8_coef_bands[16]) = { 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7};
+DECLARE_ALIGNED(16, cuchar, vp8_prev_token_class[MAX_ENTROPY_TOKENS]) = { 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0};
+DECLARE_ALIGNED(16, const int, vp8_default_zig_zag1d[16]) =
+{
+    0,  1,  4,  8,
+    5,  2,  3,  6,
+    9, 12, 13, 10,
+    7, 11, 14, 15,
+};
+
+DECLARE_ALIGNED(16, short, vp8_default_zig_zag_mask[16]);
+
+const int vp8_mb_feature_data_bits[MB_LVL_MAX] = {7, 6};
+
+/* Array indices are identical to previously-existing CONTEXT_NODE indices */
+
+const vp8_tree_index vp8_coef_tree[ 22] =     /* corresponding _CONTEXT_NODEs */
+{
+    -DCT_EOB_TOKEN, 2,                             /* 0 = EOB */
+    -ZERO_TOKEN, 4,                               /* 1 = ZERO */
+    -ONE_TOKEN, 6,                               /* 2 = ONE */
+    8, 12,                                      /* 3 = LOW_VAL */
+    -TWO_TOKEN, 10,                            /* 4 = TWO */
+    -THREE_TOKEN, -FOUR_TOKEN,                /* 5 = THREE */
+    14, 16,                                    /* 6 = HIGH_LOW */
+    -DCT_VAL_CATEGORY1, -DCT_VAL_CATEGORY2,   /* 7 = CAT_ONE */
+    18, 20,                                   /* 8 = CAT_THREEFOUR */
+    -DCT_VAL_CATEGORY3, -DCT_VAL_CATEGORY4,  /* 9 = CAT_THREE */
+    -DCT_VAL_CATEGORY5, -DCT_VAL_CATEGORY6   /* 10 = CAT_FIVE */
+};
+
+struct vp8_token_struct vp8_coef_encodings[vp8_coef_tokens];
+
+/* Trees for extra bits.  Probabilities are constant and
+   do not depend on previously encoded bits */
+
+static const Prob Pcat1[] = { 159};
+static const Prob Pcat2[] = { 165, 145};
+static const Prob Pcat3[] = { 173, 148, 140};
+static const Prob Pcat4[] = { 176, 155, 140, 135};
+static const Prob Pcat5[] = { 180, 157, 141, 134, 130};
+static const Prob Pcat6[] =
+{ 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129};
+
+static vp8_tree_index cat1[2], cat2[4], cat3[6], cat4[8], cat5[10], cat6[22];
+
+void vp8_init_scan_order_mask()
+{
+    int i;
+
+    for (i = 0; i < 16; i++)
+    {
+        vp8_default_zig_zag_mask[vp8_default_zig_zag1d[i]] = 1 << i;
+    }
+
+}
+
+static void init_bit_tree(vp8_tree_index *p, int n)
+{
+    int i = 0;
+
+    while (++i < n)
+    {
+        p[0] = p[1] = i << 1;
+        p += 2;
+    }
+
+    p[0] = p[1] = 0;
+}
+
+static void init_bit_trees()
+{
+    init_bit_tree(cat1, 1);
+    init_bit_tree(cat2, 2);
+    init_bit_tree(cat3, 3);
+    init_bit_tree(cat4, 4);
+    init_bit_tree(cat5, 5);
+    init_bit_tree(cat6, 11);
+}
+
+
+static vp8bc_index_t bcc1[1], bcc2[2], bcc3[3], bcc4[4], bcc5[5], bcc6[11];
+
+vp8_extra_bit_struct vp8_extra_bits[12] =
+{
+    { 0, 0, 0, 0, 0},
+    { 0, 0, 0, 0, 1},
+    { 0, 0, 0, 0, 2},
+    { 0, 0, 0, 0, 3},
+    { 0, 0, 0, 0, 4},
+    { cat1, Pcat1, bcc1, 1, 5},
+    { cat2, Pcat2, bcc2, 2, 7},
+    { cat3, Pcat3, bcc3, 3, 11},
+    { cat4, Pcat4, bcc4, 4, 19},
+    { cat5, Pcat5, bcc5, 5, 35},
+    { cat6, Pcat6, bcc6, 11, 67},
+    { 0, 0, 0, 0, 0}
+};
+#include "defaultcoefcounts.h"
+
+void vp8_default_coef_probs(VP8_COMMON *pc)
+{
+    int h = 0;
+
+    do
+    {
+        int i = 0;
+
+        do
+        {
+            int k = 0;
+
+            do
+            {
+                unsigned int branch_ct [vp8_coef_tokens-1] [2];
+                vp8_tree_probs_from_distribution(
+                    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree,
+                    pc->fc.coef_probs [h][i][k], branch_ct, default_coef_counts [h][i][k],
+                    256, 1);
+
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+        }
+        while (++i < COEF_BANDS);
+    }
+    while (++h < BLOCK_TYPES);
+}
+
+
+void vp8_coef_tree_initialize()
+{
+    init_bit_trees();
+    vp8_tokens_from_tree(vp8_coef_encodings, vp8_coef_tree);
+}
diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h
new file mode 100644 (file)
index 0000000..1415832
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_ENTROPY_H
+#define __INC_ENTROPY_H
+
+#include "treecoder.h"
+#include "blockd.h"
+
+/* Coefficient token alphabet */
+
+#define ZERO_TOKEN              0       //0         Extra Bits 0+0
+#define ONE_TOKEN               1       //1         Extra Bits 0+1
+#define TWO_TOKEN               2       //2         Extra Bits 0+1
+#define THREE_TOKEN             3       //3         Extra Bits 0+1
+#define FOUR_TOKEN              4       //4         Extra Bits 0+1
+#define DCT_VAL_CATEGORY1       5       //5-6       Extra Bits 1+1
+#define DCT_VAL_CATEGORY2       6       //7-10      Extra Bits 2+1
+#define DCT_VAL_CATEGORY3       7       //11-26     Extra Bits 4+1
+#define DCT_VAL_CATEGORY4       8       //11-26     Extra Bits 5+1
+#define DCT_VAL_CATEGORY5       9       //27-58     Extra Bits 5+1
+#define DCT_VAL_CATEGORY6       10      //59+       Extra Bits 11+1
+#define DCT_EOB_TOKEN           11      //EOB       Extra Bits 0+0
+
+#define vp8_coef_tokens 12
+#define MAX_ENTROPY_TOKENS vp8_coef_tokens
+#define ENTROPY_NODES 11
+
+extern const vp8_tree_index vp8_coef_tree[];
+
+extern struct vp8_token_struct vp8_coef_encodings[vp8_coef_tokens];
+
+typedef struct
+{
+    vp8_tree_p tree;
+    const vp8_prob *prob;
+    vp8bc_index_t *prob_bc;
+    int Len;
+    int base_val;
+} vp8_extra_bit_struct;
+
+extern vp8_extra_bit_struct vp8_extra_bits[12];    /* indexed by token value */
+
+#define PROB_UPDATE_BASELINE_COST   7
+
+#define MAX_PROB                255
+#define DCT_MAX_VALUE           2048
+
+
+/* Coefficients are predicted via a 3-dimensional probability table. */
+
+/* Outside dimension.  0 = Y no DC, 1 = Y2, 2 = UV, 3 = Y with DC */
+
+#define BLOCK_TYPES 4
+
+/* Middle dimension is a coarsening of the coefficient's
+   position within the 4x4 DCT. */
+
+#define COEF_BANDS 8
+extern DECLARE_ALIGNED(16, const unsigned char, vp8_coef_bands[16]);
+
+/* Inside dimension is 3-valued measure of nearby complexity, that is,
+   the extent to which nearby coefficients are nonzero.  For the first
+   coefficient (DC, unless block type is 0), we look at the (already encoded)
+   blocks above and to the left of the current block.  The context index is
+   then the number (0,1,or 2) of these blocks having nonzero coefficients.
+   After decoding a coefficient, the measure is roughly the size of the
+   most recently decoded coefficient (0 for 0, 1 for 1, 2 for >1).
+   Note that the intuitive meaning of this measure changes as coefficients
+   are decoded, e.g., prior to the first token, a zero means that my neighbors
+   are empty while, after the first token, because of the use of end-of-block,
+   a zero means we just decoded a zero and hence guarantees that a non-zero
+   coefficient will appear later in this block.  However, this shift
+   in meaning is perfectly OK because our context depends also on the
+   coefficient band (and since zigzag positions 0, 1, and 2 are in
+   distinct bands). */
+
+/*# define DC_TOKEN_CONTEXTS        3 // 00, 0!0, !0!0 */
+#   define PREV_COEF_CONTEXTS       3
+
+extern DECLARE_ALIGNED(16, const unsigned char, vp8_prev_token_class[vp8_coef_tokens]);
+
+extern const vp8_prob vp8_coef_update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
+
+
+struct VP8Common;
+void vp8_default_coef_probs(struct VP8Common *);
+
+extern DECLARE_ALIGNED(16, const int, vp8_default_zig_zag1d[16]);
+extern short vp8_default_zig_zag_mask[16];
+extern const int vp8_mb_feature_data_bits[MB_LVL_MAX];
+
+void vp8_coef_tree_initialize(void);
+#endif
diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
new file mode 100644 (file)
index 0000000..7dc1acd
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "entropymode.h"
+#include "entropy.h"
+#include "vpx_mem/vpx_mem.h"
+
+static const unsigned int kf_y_mode_cts[VP8_YMODES] = { 1607, 915, 812, 811, 5455};
+static const unsigned int y_mode_cts  [VP8_YMODES] = { 8080, 1908, 1582, 1007, 5874};
+
+static const unsigned int uv_mode_cts  [VP8_UV_MODES] = { 59483, 13605, 16492, 4230};
+static const unsigned int kf_uv_mode_cts[VP8_UV_MODES] = { 5319, 1904, 1703, 674};
+
+static const unsigned int bmode_cts[VP8_BINTRAMODES] =
+{
+    43891, 17694, 10036, 3920, 3363, 2546, 5119, 3221, 2471, 1723
+};
+
+typedef enum
+{
+    SUBMVREF_NORMAL,
+    SUBMVREF_LEFT_ZED,
+    SUBMVREF_ABOVE_ZED,
+    SUBMVREF_LEFT_ABOVE_SAME,
+    SUBMVREF_LEFT_ABOVE_ZED
+} sumvfref_t;
+
+int vp8_mv_cont(const MV *l, const MV *a)
+{
+    int lez = (l->row == 0 && l->col == 0);
+    int aez = (a->row == 0 && a->col == 0);
+    int lea = (l->row == a->row && l->col == a->col);
+
+    if (lea && lez)
+        return SUBMVREF_LEFT_ABOVE_ZED;
+
+    if (lea)
+        return SUBMVREF_LEFT_ABOVE_SAME;
+
+    if (aez)
+        return SUBMVREF_ABOVE_ZED;
+
+    if (lez)
+        return SUBMVREF_LEFT_ZED;
+
+    return SUBMVREF_NORMAL;
+}
+
+static const vp8_prob sub_mv_ref_prob [VP8_SUBMVREFS-1] = { 180, 162, 25};
+
+const vp8_prob vp8_sub_mv_ref_prob2 [SUBMVREF_COUNT][VP8_SUBMVREFS-1] =
+{
+    { 147, 136, 18 },
+    { 106, 145, 1  },
+    { 179, 121, 1  },
+    { 223, 1  , 34 },
+    { 208, 1  , 1  }
+};
+
+
+
+vp8_mbsplit vp8_mbsplits [VP8_NUMMBSPLITS] =
+{
+    {
+        0,  0,  0,  0,
+        0,  0,  0,  0,
+        1,  1,  1,  1,
+        1,  1,  1,  1,
+    },
+    {
+        0,  0,  1,  1,
+        0,  0,  1,  1,
+        0,  0,  1,  1,
+        0,  0,  1,  1,
+    },
+    {
+        0,  0,  1,  1,
+        0,  0,  1,  1,
+        2,  2,  3,  3,
+        2,  2,  3,  3,
+    },
+    {
+        0,  1,  2,  3,
+        4,  5,  6,  7,
+        8,  9,  10, 11,
+        12, 13, 14, 15,
+    },
+};
+
+const int vp8_mbsplit_count [VP8_NUMMBSPLITS] = { 2, 2, 4, 16};
+
+const vp8_prob vp8_mbsplit_probs [VP8_NUMMBSPLITS-1] = { 110, 111, 150};
+
+
+/* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
+
+const vp8_tree_index vp8_bmode_tree[18] =     /* INTRAMODECONTEXTNODE value */
+{
+    -B_DC_PRED, 2,                             /* 0 = DC_NODE */
+    -B_TM_PRED, 4,                            /* 1 = TM_NODE */
+    -B_VE_PRED, 6,                           /* 2 = VE_NODE */
+    8, 12,                                  /* 3 = COM_NODE */
+    -B_HE_PRED, 10,                        /* 4 = HE_NODE */
+    -B_RD_PRED, -B_VR_PRED,               /* 5 = RD_NODE */
+    -B_LD_PRED, 14,                        /* 6 = LD_NODE */
+    -B_VL_PRED, 16,                      /* 7 = VL_NODE */
+    -B_HD_PRED, -B_HU_PRED             /* 8 = HD_NODE */
+};
+
+/* Again, these trees use the same probability indices as their
+   explicitly-programmed predecessors. */
+
+const vp8_tree_index vp8_ymode_tree[8] =
+{
+    -DC_PRED, 2,
+    4, 6,
+    -V_PRED, -H_PRED,
+    -TM_PRED, -B_PRED
+};
+
+const vp8_tree_index vp8_kf_ymode_tree[8] =
+{
+    -B_PRED, 2,
+    4, 6,
+    -DC_PRED, -V_PRED,
+    -H_PRED, -TM_PRED
+};
+
+const vp8_tree_index vp8_uv_mode_tree[6] =
+{
+    -DC_PRED, 2,
+    -V_PRED, 4,
+    -H_PRED, -TM_PRED
+};
+
+const vp8_tree_index vp8_mbsplit_tree[6] =
+{
+    -3, 2,
+    -2, 4,
+    -0, -1
+};
+
+const vp8_tree_index vp8_mv_ref_tree[8] =
+{
+    -ZEROMV, 2,
+    -NEARESTMV, 4,
+    -NEARMV, 6,
+    -NEWMV, -SPLITMV
+};
+
+const vp8_tree_index vp8_sub_mv_ref_tree[6] =
+{
+    -LEFT4X4, 2,
+    -ABOVE4X4, 4,
+    -ZERO4X4, -NEW4X4
+};
+
+
+struct vp8_token_struct vp8_bmode_encodings   [VP8_BINTRAMODES];
+struct vp8_token_struct vp8_ymode_encodings   [VP8_YMODES];
+struct vp8_token_struct vp8_kf_ymode_encodings [VP8_YMODES];
+struct vp8_token_struct vp8_uv_mode_encodings  [VP8_UV_MODES];
+struct vp8_token_struct vp8_mbsplit_encodings [VP8_NUMMBSPLITS];
+
+struct vp8_token_struct vp8_mv_ref_encoding_array    [VP8_MVREFS];
+struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
+
+
+const vp8_tree_index vp8_small_mvtree [14] =
+{
+    2, 8,
+    4, 6,
+    -0, -1,
+    -2, -3,
+    10, 12,
+    -4, -5,
+    -6, -7
+};
+
+struct vp8_token_struct vp8_small_mvencodings [8];
+
+void vp8_init_mbmode_probs(VP8_COMMON *x)
+{
+    unsigned int bct [VP8_YMODES] [2];      /* num Ymodes > num UV modes */
+
+    vp8_tree_probs_from_distribution(
+        VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree,
+        x->fc.ymode_prob, bct, y_mode_cts,
+        256, 1
+    );
+    vp8_tree_probs_from_distribution(
+        VP8_YMODES, vp8_kf_ymode_encodings, vp8_kf_ymode_tree,
+        x->kf_ymode_prob, bct, kf_y_mode_cts,
+        256, 1
+    );
+    vp8_tree_probs_from_distribution(
+        VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
+        x->fc.uv_mode_prob, bct, uv_mode_cts,
+        256, 1
+    );
+    vp8_tree_probs_from_distribution(
+        VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
+        x->kf_uv_mode_prob, bct, kf_uv_mode_cts,
+        256, 1
+    );
+    vpx_memcpy(x->fc.sub_mv_ref_prob, sub_mv_ref_prob, sizeof(sub_mv_ref_prob));
+}
+
+
+static void intra_bmode_probs_from_distribution(
+    vp8_prob p [VP8_BINTRAMODES-1],
+    unsigned int branch_ct [VP8_BINTRAMODES-1] [2],
+    const unsigned int events [VP8_BINTRAMODES]
+)
+{
+    vp8_tree_probs_from_distribution(
+        VP8_BINTRAMODES, vp8_bmode_encodings, vp8_bmode_tree,
+        p, branch_ct, events,
+        256, 1
+    );
+}
+
+void vp8_default_bmode_probs(vp8_prob p [VP8_BINTRAMODES-1])
+{
+    unsigned int branch_ct [VP8_BINTRAMODES-1] [2];
+    intra_bmode_probs_from_distribution(p, branch_ct, bmode_cts);
+}
+
+void vp8_kf_default_bmode_probs(vp8_prob p [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1])
+{
+    unsigned int branch_ct [VP8_BINTRAMODES-1] [2];
+
+    int i = 0;
+
+    do
+    {
+        int j = 0;
+
+        do
+        {
+            intra_bmode_probs_from_distribution(
+                p[i][j], branch_ct, vp8_kf_default_bmode_counts[i][j]);
+
+        }
+        while (++j < VP8_BINTRAMODES);
+    }
+    while (++i < VP8_BINTRAMODES);
+}
+
+
+void vp8_entropy_mode_init()
+{
+    vp8_tokens_from_tree(vp8_bmode_encodings,   vp8_bmode_tree);
+    vp8_tokens_from_tree(vp8_ymode_encodings,   vp8_ymode_tree);
+    vp8_tokens_from_tree(vp8_kf_ymode_encodings, vp8_kf_ymode_tree);
+    vp8_tokens_from_tree(vp8_uv_mode_encodings,  vp8_uv_mode_tree);
+    vp8_tokens_from_tree(vp8_mbsplit_encodings, vp8_mbsplit_tree);
+
+    vp8_tokens_from_tree(VP8_MVREFENCODINGS,   vp8_mv_ref_tree);
+    vp8_tokens_from_tree(VP8_SUBMVREFENCODINGS, vp8_sub_mv_ref_tree);
+
+    vp8_tokens_from_tree(vp8_small_mvencodings, vp8_small_mvtree);
+}
diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h
new file mode 100644 (file)
index 0000000..ff630a4
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_ENTROPYMODE_H
+#define __INC_ENTROPYMODE_H
+
+#include "onyxc_int.h"
+#include "treecoder.h"
+
+typedef const int vp8_mbsplit[16];
+
+#define VP8_NUMMBSPLITS 4
+
+extern vp8_mbsplit vp8_mbsplits [VP8_NUMMBSPLITS];
+
+extern const int vp8_mbsplit_count [VP8_NUMMBSPLITS];    /* # of subsets */
+
+extern const vp8_prob vp8_mbsplit_probs [VP8_NUMMBSPLITS-1];
+
+extern int vp8_mv_cont(const MV *l, const MV *a);
+#define SUBMVREF_COUNT 5
+extern const vp8_prob vp8_sub_mv_ref_prob2 [SUBMVREF_COUNT][VP8_SUBMVREFS-1];
+
+
+extern const unsigned int vp8_kf_default_bmode_counts [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES];
+
+
+extern const vp8_tree_index vp8_bmode_tree[];
+
+extern const vp8_tree_index  vp8_ymode_tree[];
+extern const vp8_tree_index  vp8_kf_ymode_tree[];
+extern const vp8_tree_index  vp8_uv_mode_tree[];
+
+extern const vp8_tree_index  vp8_mbsplit_tree[];
+extern const vp8_tree_index  vp8_mv_ref_tree[];
+extern const vp8_tree_index  vp8_sub_mv_ref_tree[];
+
+extern struct vp8_token_struct vp8_bmode_encodings   [VP8_BINTRAMODES];
+extern struct vp8_token_struct vp8_ymode_encodings   [VP8_YMODES];
+extern struct vp8_token_struct vp8_kf_ymode_encodings [VP8_YMODES];
+extern struct vp8_token_struct vp8_uv_mode_encodings  [VP8_UV_MODES];
+extern struct vp8_token_struct vp8_mbsplit_encodings  [VP8_NUMMBSPLITS];
+
+/* Inter mode values do not start at zero */
+
+extern struct vp8_token_struct vp8_mv_ref_encoding_array    [VP8_MVREFS];
+extern struct vp8_token_struct vp8_sub_mv_ref_encoding_array [VP8_SUBMVREFS];
+
+#define VP8_MVREFENCODINGS      (vp8_mv_ref_encoding_array - NEARESTMV)
+#define VP8_SUBMVREFENCODINGS   (vp8_sub_mv_ref_encoding_array - LEFT4X4)
+
+
+extern const vp8_tree_index vp8_small_mvtree[];
+
+extern struct vp8_token_struct vp8_small_mvencodings [8];
+
+void vp8_entropy_mode_init(void);
+
+void vp8_init_mbmode_probs(VP8_COMMON *x);
+
+void   vp8_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES-1]);
+void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1]);
+
+#endif
diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c
new file mode 100644 (file)
index 0000000..2b00c17
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "entropymv.h"
+
+const MV_CONTEXT vp8_mv_update_probs[2] =
+{
+    {{
+        237,
+        246,
+        253, 253, 254, 254, 254, 254, 254,
+        254, 254, 254, 254, 254, 250, 250, 252, 254, 254
+    }},
+    {{
+        231,
+        243,
+        245, 253, 254, 254, 254, 254, 254,
+        254, 254, 254, 254, 254, 251, 251, 254, 254, 254
+    }}
+};
+const MV_CONTEXT vp8_default_mv_context[2] =
+{
+    {{
+        // row
+        162,                                        // is short
+        128,                                        // sign
+        225, 146, 172, 147, 214,  39, 156,          // short tree
+        128, 129, 132,  75, 145, 178, 206, 239, 254, 254 // long bits
+    }},
+
+
+
+    {{
+        // same for column
+        164,                                        // is short
+        128,
+        204, 170, 119, 235, 140, 230, 228,
+        128, 130, 130,  74, 148, 180, 203, 236, 254, 254 // long bits
+
+    }}
+};
diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h
new file mode 100644 (file)
index 0000000..d940c59
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_ENTROPYMV_H
+#define __INC_ENTROPYMV_H
+
+#include "treecoder.h"
+
+enum
+{
+    mv_max  = 1023,              /* max absolute value of a MV component */
+    MVvals = (2 * mv_max) + 1,   /* # possible values "" */
+
+    mvlong_width = 10,       /* Large MVs have 9 bit magnitudes */
+    mvnum_short = 8,         /* magnitudes 0 through 7 */
+
+    /* probability offsets for coding each MV component */
+
+    mvpis_short = 0,         /* short (<= 7) vs long (>= 8) */
+    MVPsign,                /* sign for non-zero */
+    MVPshort,               /* 8 short values = 7-position tree */
+
+    MVPbits = MVPshort + mvnum_short - 1, /* mvlong_width long value bits */
+    MVPcount = MVPbits + mvlong_width    /* (with independent probabilities) */
+};
+
+typedef struct mv_context
+{
+    vp8_prob prob[MVPcount];  /* often come in row, col pairs */
+} MV_CONTEXT;
+
+extern const MV_CONTEXT vp8_mv_update_probs[2], vp8_default_mv_context[2];
+
+#endif
diff --git a/vp8/common/extend.c b/vp8/common/extend.c
new file mode 100644 (file)
index 0000000..7407952
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "extend.h"
+#include "vpx_mem/vpx_mem.h"
+
+
+static void extend_plane_borders
+(
+    unsigned char *s, // source
+    int sp,           // pitch
+    int h,            // height
+    int w,            // width
+    int et,           // extend top border
+    int el,           // extend left border
+    int eb,           // extend bottom border
+    int er            // extend right border
+)
+{
+
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+    int linesize;
+
+    // copy the left and right most columns out
+    src_ptr1 = s;
+    src_ptr2 = s + w - 1;
+    dest_ptr1 = s - el;
+    dest_ptr2 = s + w;
+
+    for (i = 0; i < h - 0 + 1; i++)
+    {
+        vpx_memset(dest_ptr1, src_ptr1[0], el);
+        vpx_memset(dest_ptr2, src_ptr2[0], er);
+        src_ptr1  += sp;
+        src_ptr2  += sp;
+        dest_ptr1 += sp;
+        dest_ptr2 += sp;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = s - el;
+    src_ptr2 = s + sp * (h - 1) - el;
+    dest_ptr1 = s + sp * (-et) - el;
+    dest_ptr2 = s + sp * (h) - el;
+    linesize = el + er + w + 1;
+
+    for (i = 0; i < (int)et; i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, linesize);
+        dest_ptr1 += sp;
+    }
+
+    for (i = 0; i < (int)eb; i++)
+    {
+        vpx_memcpy(dest_ptr2, src_ptr2, linesize);
+        dest_ptr2 += sp;
+    }
+}
+
+
+void vp8_extend_to_multiple_of16(YV12_BUFFER_CONFIG *ybf, int width, int height)
+{
+    int er = 0xf & (16 - (width & 0xf));
+    int eb = 0xf & (16 - (height & 0xf));
+
+    // check for non multiples of 16
+    if (er != 0 || eb != 0)
+    {
+        extend_plane_borders(ybf->y_buffer, ybf->y_stride, height, width, 0, 0, eb, er);
+
+        //adjust for uv
+        height = (height + 1) >> 1;
+        width  = (width  + 1) >> 1;
+        er = 0x7 & (8 - (width  & 0x7));
+        eb = 0x7 & (8 - (height & 0x7));
+
+        if (er || eb)
+        {
+            extend_plane_borders(ybf->u_buffer, ybf->uv_stride, height, width, 0, 0, eb, er);
+            extend_plane_borders(ybf->v_buffer, ybf->uv_stride, height, width, 0, 0, eb, er);
+        }
+    }
+}
+
+// note the extension is only for the last row, for intra prediction purpose
+void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr, unsigned char *UPtr, unsigned char *VPtr)
+{
+    int i;
+
+    YPtr += ybf->y_stride * 14;
+    UPtr += ybf->uv_stride * 6;
+    VPtr += ybf->uv_stride * 6;
+
+    for (i = 0; i < 4; i++)
+    {
+        YPtr[i] = YPtr[-1];
+        UPtr[i] = UPtr[-1];
+        VPtr[i] = VPtr[-1];
+    }
+
+    YPtr += ybf->y_stride;
+    UPtr += ybf->uv_stride;
+    VPtr += ybf->uv_stride;
+
+    for (i = 0; i < 4; i++)
+    {
+        YPtr[i] = YPtr[-1];
+        UPtr[i] = UPtr[-1];
+        VPtr[i] = VPtr[-1];
+    }
+}
diff --git a/vp8/common/extend.h b/vp8/common/extend.h
new file mode 100644 (file)
index 0000000..6809ae7
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_EXTEND_H
+#define __INC_EXTEND_H
+
+#include "vpx_scale/yv12config.h"
+
+void Extend(YV12_BUFFER_CONFIG *ybf);
+void vp8_extend_mb_row(YV12_BUFFER_CONFIG *ybf, unsigned char *YPtr, unsigned char *UPtr, unsigned char *VPtr);
+void vp8_extend_to_multiple_of16(YV12_BUFFER_CONFIG *ybf, int width, int height);
+
+#endif
diff --git a/vp8/common/filter_c.c b/vp8/common/filter_c.c
new file mode 100644 (file)
index 0000000..38991cb
--- /dev/null
@@ -0,0 +1,539 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+
+#define BLOCK_HEIGHT_WIDTH 4
+#define VP8_FILTER_WEIGHT 128
+#define VP8_FILTER_SHIFT  7
+
+
+static const int bilinear_filters[8][2] =
+{
+    { 128,   0 },
+    { 112,  16 },
+    {  96,  32 },
+    {  80,  48 },
+    {  64,  64 },
+    {  48,  80 },
+    {  32,  96 },
+    {  16, 112 }
+};
+
+
+static const short sub_pel_filters[8][6] =
+{
+
+    { 0,  0,  128,    0,   0,  0 },         // note that 1/8 pel positions are just as per alpha -0.5 bicubic
+    { 0, -6,  123,   12,  -1,  0 },
+    { 2, -11, 108,   36,  -8,  1 },         // New 1/4 pel 6 tap filter
+    { 0, -9,   93,   50,  -6,  0 },
+    { 3, -16,  77,   77, -16,  3 },         // New 1/2 pel 6 tap filter
+    { 0, -6,   50,   93,  -9,  0 },
+    { 1, -8,   36,  108, -11,  2 },         // New 1/4 pel 6 tap filter
+    { 0, -1,   12,  123,  -6,  0 },
+
+
+
+};
+
+void vp8_filter_block2d_first_pass
+(
+    unsigned char *src_ptr,
+    int *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    const short *vp8_filter
+)
+{
+    unsigned int i, j;
+    int  Temp;
+
+    for (i = 0; i < output_height; i++)
+    {
+        for (j = 0; j < output_width; j++)
+        {
+            Temp = ((int)src_ptr[-2 * (int)pixel_step] * vp8_filter[0]) +
+                   ((int)src_ptr[-1 * (int)pixel_step] * vp8_filter[1]) +
+                   ((int)src_ptr[0]                 * vp8_filter[2]) +
+                   ((int)src_ptr[pixel_step]         * vp8_filter[3]) +
+                   ((int)src_ptr[2*pixel_step]       * vp8_filter[4]) +
+                   ((int)src_ptr[3*pixel_step]       * vp8_filter[5]) +
+                   (VP8_FILTER_WEIGHT >> 1);      // Rounding
+
+            // Normalize back to 0-255
+            Temp = Temp >> VP8_FILTER_SHIFT;
+
+            if (Temp < 0)
+                Temp = 0;
+            else if (Temp > 255)
+                Temp = 255;
+
+            output_ptr[j] = Temp;
+            src_ptr++;
+        }
+
+        // Next row...
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_width;
+    }
+}
+
+void vp8_filter_block2d_second_pass
+(
+    int *src_ptr,
+    unsigned char *output_ptr,
+    int output_pitch,
+    unsigned int src_pixels_per_line,
+    unsigned int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    const short *vp8_filter
+)
+{
+    unsigned int i, j;
+    int  Temp;
+
+    for (i = 0; i < output_height; i++)
+    {
+        for (j = 0; j < output_width; j++)
+        {
+            // Apply filter
+            Temp = ((int)src_ptr[-2 * (int)pixel_step] * vp8_filter[0]) +
+                   ((int)src_ptr[-1 * (int)pixel_step] * vp8_filter[1]) +
+                   ((int)src_ptr[0]                 * vp8_filter[2]) +
+                   ((int)src_ptr[pixel_step]         * vp8_filter[3]) +
+                   ((int)src_ptr[2*pixel_step]       * vp8_filter[4]) +
+                   ((int)src_ptr[3*pixel_step]       * vp8_filter[5]) +
+                   (VP8_FILTER_WEIGHT >> 1);   // Rounding
+
+            // Normalize back to 0-255
+            Temp = Temp >> VP8_FILTER_SHIFT;
+
+            if (Temp < 0)
+                Temp = 0;
+            else if (Temp > 255)
+                Temp = 255;
+
+            output_ptr[j] = (unsigned char)Temp;
+            src_ptr++;
+        }
+
+        // Start next row
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_pitch;
+    }
+}
+
+
+void vp8_filter_block2d
+(
+    unsigned char  *src_ptr,
+    unsigned char  *output_ptr,
+    unsigned int src_pixels_per_line,
+    int output_pitch,
+    const short  *HFilter,
+    const short  *VFilter
+)
+{
+    int FData[9*4]; // Temp data bufffer used in filtering
+
+    // First filter 1-D horizontally...
+    vp8_filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 1, 9, 4, HFilter);
+
+    // then filter verticaly...
+    vp8_filter_block2d_second_pass(FData + 8, output_ptr, output_pitch, 4, 4, 4, 4, VFilter);
+}
+
+
+void vp8_block_variation_c
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int *HVar,
+    int *VVar
+)
+{
+    int i, j;
+    unsigned char *Ptr = src_ptr;
+
+    for (i = 0; i < 4; i++)
+    {
+        for (j = 0; j < 4; j++)
+        {
+            *HVar += abs((int)Ptr[j] - (int)Ptr[j+1]);
+            *VVar += abs((int)Ptr[j] - (int)Ptr[j+src_pixels_per_line]);
+        }
+
+        Ptr += src_pixels_per_line;
+    }
+}
+
+
+
+
+void vp8_sixtap_predict_c
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];   // 6 tap
+
+    vp8_filter_block2d(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter);
+}
+void vp8_sixtap_predict8x8_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    int FData[13*16];   // Temp data bufffer used in filtering
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];   // 6 tap
+
+    // First filter 1-D horizontally...
+    vp8_filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 1, 13, 8, HFilter);
+
+
+    // then filter verticaly...
+    vp8_filter_block2d_second_pass(FData + 16, dst_ptr, dst_pitch, 8, 8, 8, 8, VFilter);
+
+}
+
+void vp8_sixtap_predict8x4_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    int FData[13*16];   // Temp data bufffer used in filtering
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];   // 6 tap
+
+    // First filter 1-D horizontally...
+    vp8_filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 1, 9, 8, HFilter);
+
+
+    // then filter verticaly...
+    vp8_filter_block2d_second_pass(FData + 16, dst_ptr, dst_pitch, 8, 8, 4, 8, VFilter);
+
+}
+
+void vp8_sixtap_predict16x16_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const short  *HFilter;
+    const short  *VFilter;
+    int FData[21*24];   // Temp data bufffer used in filtering
+
+
+    HFilter = sub_pel_filters[xoffset];   // 6 tap
+    VFilter = sub_pel_filters[yoffset];   // 6 tap
+
+    // First filter 1-D horizontally...
+    vp8_filter_block2d_first_pass(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 1, 21, 16, HFilter);
+
+    // then filter verticaly...
+    vp8_filter_block2d_second_pass(FData + 32, dst_ptr, dst_pitch, 16, 16, 16, 16, VFilter);
+
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : filter_block2d_bil_first_pass
+ *
+ *  INPUTS        : UINT8  *src_ptr          : Pointer to source block.
+ *                  UINT32 src_pixels_per_line : Stride of input block.
+ *                  UINT32 pixel_step        : Offset between filter input samples (see notes).
+ *                  UINT32 output_height     : Input block height.
+ *                  UINT32 output_width      : Input block width.
+ *                  INT32  *vp8_filter          : Array of 2 bi-linear filter taps.
+ *
+ *  OUTPUTS       : INT32 *output_ptr        : Pointer to filtered block.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
+ *                  either horizontal or vertical direction to produce the
+ *                  filtered output block. Used to implement first-pass
+ *                  of 2-D separable filter.
+ *
+ *  SPECIAL NOTES : Produces INT32 output to retain precision for next pass.
+ *                  Two filter taps should sum to VP8_FILTER_WEIGHT.
+ *                  pixel_step defines whether the filter is applied
+ *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
+ *                  It defines the offset required to move from one input
+ *                  to the next.
+ *
+ ****************************************************************************/
+void vp8_filter_block2d_bil_first_pass
+(
+    unsigned char *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int src_pixels_per_line,
+    int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    const int *vp8_filter
+)
+{
+    unsigned int i, j;
+
+    for (i = 0; i < output_height; i++)
+    {
+        for (j = 0; j < output_width; j++)
+        {
+            // Apply bilinear filter
+            output_ptr[j] = (((int)src_ptr[0]          * vp8_filter[0]) +
+                             ((int)src_ptr[pixel_step] * vp8_filter[1]) +
+                             (VP8_FILTER_WEIGHT / 2)) >> VP8_FILTER_SHIFT;
+            src_ptr++;
+        }
+
+        // Next row...
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_width;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : filter_block2d_bil_second_pass
+ *
+ *  INPUTS        : INT32  *src_ptr          : Pointer to source block.
+ *                  UINT32 src_pixels_per_line : Stride of input block.
+ *                  UINT32 pixel_step        : Offset between filter input samples (see notes).
+ *                  UINT32 output_height     : Input block height.
+ *                  UINT32 output_width      : Input block width.
+ *                  INT32  *vp8_filter          : Array of 2 bi-linear filter taps.
+ *
+ *  OUTPUTS       : UINT16 *output_ptr       : Pointer to filtered block.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
+ *                  either horizontal or vertical direction to produce the
+ *                  filtered output block. Used to implement second-pass
+ *                  of 2-D separable filter.
+ *
+ *  SPECIAL NOTES : Requires 32-bit input as produced by filter_block2d_bil_first_pass.
+ *                  Two filter taps should sum to VP8_FILTER_WEIGHT.
+ *                  pixel_step defines whether the filter is applied
+ *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
+ *                  It defines the offset required to move from one input
+ *                  to the next.
+ *
+ ****************************************************************************/
+void vp8_filter_block2d_bil_second_pass
+(
+    unsigned short *src_ptr,
+    unsigned char  *output_ptr,
+    int output_pitch,
+    unsigned int  src_pixels_per_line,
+    unsigned int  pixel_step,
+    unsigned int  output_height,
+    unsigned int  output_width,
+    const int *vp8_filter
+)
+{
+    unsigned int  i, j;
+    int  Temp;
+
+    for (i = 0; i < output_height; i++)
+    {
+        for (j = 0; j < output_width; j++)
+        {
+            // Apply filter
+            Temp = ((int)src_ptr[0]         * vp8_filter[0]) +
+                   ((int)src_ptr[pixel_step] * vp8_filter[1]) +
+                   (VP8_FILTER_WEIGHT / 2);
+            output_ptr[j] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);
+            src_ptr++;
+        }
+
+        // Next row...
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_pitch;
+    }
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : filter_block2d_bil
+ *
+ *  INPUTS        : UINT8  *src_ptr          : Pointer to source block.
+ *                  UINT32 src_pixels_per_line : Stride of input block.
+ *                  INT32  *HFilter         : Array of 2 horizontal filter taps.
+ *                  INT32  *VFilter         : Array of 2 vertical filter taps.
+ *
+ *  OUTPUTS       : UINT16 *output_ptr       : Pointer to filtered block.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 2-D filters an input block by applying a 2-tap
+ *                  bi-linear filter horizontally followed by a 2-tap
+ *                  bi-linear filter vertically on the result.
+ *
+ *  SPECIAL NOTES : The largest block size can be handled here is 16x16
+ *
+ ****************************************************************************/
+void vp8_filter_block2d_bil
+(
+    unsigned char *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int   src_pixels_per_line,
+    unsigned int   dst_pitch,
+    const int      *HFilter,
+    const int      *VFilter,
+    int            Width,
+    int            Height
+)
+{
+
+    unsigned short FData[17*16];    // Temp data bufffer used in filtering
+
+    // First filter 1-D horizontally...
+    vp8_filter_block2d_bil_first_pass(src_ptr, FData, src_pixels_per_line, 1, Height + 1, Width, HFilter);
+
+    // then 1-D vertically...
+    vp8_filter_block2d_bil_second_pass(FData, output_ptr, dst_pitch, Width, Width, Height, Width, VFilter);
+}
+
+
+void vp8_bilinear_predict4x4_c
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    const int  *HFilter;
+    const int  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+#if 0
+    {
+        int i;
+        unsigned char temp1[16];
+        unsigned char temp2[16];
+
+        bilinear_predict4x4_mmx(src_ptr, src_pixels_per_line, xoffset, yoffset, temp1, 4);
+        vp8_filter_block2d_bil(src_ptr, temp2, src_pixels_per_line, 4, HFilter, VFilter, 4, 4);
+
+        for (i = 0; i < 16; i++)
+        {
+            if (temp1[i] != temp2[i])
+            {
+                bilinear_predict4x4_mmx(src_ptr, src_pixels_per_line, xoffset, yoffset, temp1, 4);
+                vp8_filter_block2d_bil(src_ptr, temp2, src_pixels_per_line, 4, HFilter, VFilter, 4, 4);
+            }
+        }
+    }
+#endif
+    vp8_filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 4, 4);
+
+}
+
+void vp8_bilinear_predict8x8_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const int  *HFilter;
+    const int  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 8, 8);
+
+}
+
+void vp8_bilinear_predict8x4_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const int  *HFilter;
+    const int  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 8, 4);
+
+}
+
+void vp8_bilinear_predict16x16_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int  dst_pitch
+)
+{
+    const int  *HFilter;
+    const int  *VFilter;
+
+    HFilter = bilinear_filters[xoffset];
+    VFilter = bilinear_filters[yoffset];
+
+    vp8_filter_block2d_bil(src_ptr, dst_ptr, src_pixels_per_line, dst_pitch, HFilter, VFilter, 16, 16);
+}
diff --git a/vp8/common/findnearmv.c b/vp8/common/findnearmv.c
new file mode 100644 (file)
index 0000000..fcb1f20
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "findnearmv.h"
+
+#define FINDNEAR_SEARCH_SITES   3
+
+/* Predict motion vectors using those from already-decoded nearby blocks.
+   Note that we only consider one 4x4 subblock from each candidate 16x16
+   macroblock.   */
+
+typedef union
+{
+    unsigned int as_int;
+    MV           as_mv;
+} int_mv;        /* facilitates rapid equality tests */
+
+static void mv_bias(const MODE_INFO *x, int refframe, int_mv *mvp, const int *ref_frame_sign_bias)
+{
+    MV xmv;
+    xmv = x->mbmi.mv.as_mv;
+
+    if (ref_frame_sign_bias[x->mbmi.ref_frame] != ref_frame_sign_bias[refframe])
+    {
+        xmv.row *= -1;
+        xmv.col *= -1;
+    }
+
+    mvp->as_mv = xmv;
+}
+
+
+void vp8_clamp_mv(MV *mv, const MACROBLOCKD *xd)
+{
+    if (mv->col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
+        mv->col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
+    else if (mv->col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
+        mv->col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
+
+    if (mv->row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
+        mv->row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
+    else if (mv->row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
+        mv->row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
+}
+
+
+void vp8_find_near_mvs
+(
+    MACROBLOCKD *xd,
+    const MODE_INFO *here,
+    MV *nearest,
+    MV *nearby,
+    MV *best_mv,
+    int cnt[4],
+    int refframe,
+    int *ref_frame_sign_bias
+)
+{
+    const MODE_INFO *above = here - xd->mode_info_stride;
+    const MODE_INFO *left = here - 1;
+    const MODE_INFO *aboveleft = above - 1;
+    int_mv            near_mvs[4];
+    int_mv           *mv = near_mvs;
+    int             *cntx = cnt;
+    enum {CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV};
+
+    /* Zero accumulators */
+    mv[0].as_int = mv[1].as_int = mv[2].as_int = 0;
+    cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
+
+    /* Process above */
+    if (above->mbmi.ref_frame != INTRA_FRAME)
+    {
+        if (above->mbmi.mv.as_int)
+        {
+            (++mv)->as_int = above->mbmi.mv.as_int;
+            mv_bias(above, refframe, mv, ref_frame_sign_bias);
+            ++cntx;
+        }
+
+        *cntx += 2;
+    }
+
+    /* Process left */
+    if (left->mbmi.ref_frame != INTRA_FRAME)
+    {
+        if (left->mbmi.mv.as_int)
+        {
+            int_mv this_mv;
+
+            this_mv.as_int = left->mbmi.mv.as_int;
+            mv_bias(left, refframe, &this_mv, ref_frame_sign_bias);
+
+            if (this_mv.as_int != mv->as_int)
+            {
+                (++mv)->as_int = this_mv.as_int;
+                ++cntx;
+            }
+
+            *cntx += 2;
+        }
+        else
+            cnt[CNT_INTRA] += 2;
+    }
+
+    /* Process above left */
+    if (aboveleft->mbmi.ref_frame != INTRA_FRAME)
+    {
+        if (aboveleft->mbmi.mv.as_int)
+        {
+            int_mv this_mv;
+
+            this_mv.as_int = aboveleft->mbmi.mv.as_int;
+            mv_bias(aboveleft, refframe, &this_mv, ref_frame_sign_bias);
+
+            if (this_mv.as_int != mv->as_int)
+            {
+                (++mv)->as_int = this_mv.as_int;
+                ++cntx;
+            }
+
+            *cntx += 1;
+        }
+        else
+            cnt[CNT_INTRA] += 1;
+    }
+
+    /* If we have three distinct MV's ... */
+    if (cnt[CNT_SPLITMV])
+    {
+        /* See if above-left MV can be merged with NEAREST */
+        if (mv->as_int == near_mvs[CNT_NEAREST].as_int)
+            cnt[CNT_NEAREST] += 1;
+    }
+
+    cnt[CNT_SPLITMV] = ((above->mbmi.mode == SPLITMV)
+                        + (left->mbmi.mode == SPLITMV)) * 2
+                       + (aboveleft->mbmi.mode == SPLITMV);
+
+    /* Swap near and nearest if necessary */
+    if (cnt[CNT_NEAR] > cnt[CNT_NEAREST])
+    {
+        int tmp;
+        tmp = cnt[CNT_NEAREST];
+        cnt[CNT_NEAREST] = cnt[CNT_NEAR];
+        cnt[CNT_NEAR] = tmp;
+        tmp = near_mvs[CNT_NEAREST].as_int;
+        near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int;
+        near_mvs[CNT_NEAR].as_int = tmp;
+    }
+
+    /* Use near_mvs[0] to store the "best" MV */
+    if (cnt[CNT_NEAREST] >= cnt[CNT_INTRA])
+        near_mvs[CNT_INTRA] = near_mvs[CNT_NEAREST];
+
+    /* Set up return values */
+    *best_mv = near_mvs[0].as_mv;
+    *nearest = near_mvs[CNT_NEAREST].as_mv;
+    *nearby = near_mvs[CNT_NEAR].as_mv;
+
+    vp8_clamp_mv(nearest, xd);
+    vp8_clamp_mv(nearby, xd);
+    vp8_clamp_mv(best_mv, xd); //TODO: move this up before the copy
+}
+
+vp8_prob *vp8_mv_ref_probs(
+    vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
+)
+{
+    p[0] = vp8_mode_contexts [near_mv_ref_ct[0]] [0];
+    p[1] = vp8_mode_contexts [near_mv_ref_ct[1]] [1];
+    p[2] = vp8_mode_contexts [near_mv_ref_ct[2]] [2];
+    p[3] = vp8_mode_contexts [near_mv_ref_ct[3]] [3];
+    //p[3] = vp8_mode_contexts [near_mv_ref_ct[1] + near_mv_ref_ct[2] + near_mv_ref_ct[3]] [3];
+    return p;
+}
+
+const B_MODE_INFO *vp8_left_bmi(const MODE_INFO *cur_mb, int b)
+{
+    if (!(b & 3))
+    {
+        /* On L edge, get from MB to left of us */
+        --cur_mb;
+        b += 4;
+    }
+
+    return cur_mb->bmi + b - 1;
+}
+
+const B_MODE_INFO *vp8_above_bmi(const MODE_INFO *cur_mb, int b, int mi_stride)
+{
+    if (!(b >> 2))
+    {
+        /* On top edge, get from MB above us */
+        cur_mb -= mi_stride;
+        b += 16;
+    }
+
+    return cur_mb->bmi + b - 4;
+}
diff --git a/vp8/common/findnearmv.h b/vp8/common/findnearmv.h
new file mode 100644 (file)
index 0000000..2c02033
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_FINDNEARMV_H
+#define __INC_FINDNEARMV_H
+
+#include "mv.h"
+#include "blockd.h"
+#include "modecont.h"
+#include "treecoder.h"
+
+void vp8_find_near_mvs
+(
+    MACROBLOCKD *xd,
+    const MODE_INFO *here,
+    MV *nearest, MV *nearby, MV *best,
+    int near_mv_ref_cts[4],
+    int refframe,
+    int *ref_frame_sign_bias
+);
+
+vp8_prob *vp8_mv_ref_probs(
+    vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
+);
+
+const B_MODE_INFO *vp8_left_bmi(const MODE_INFO *cur_mb, int b);
+
+const B_MODE_INFO *vp8_above_bmi(const MODE_INFO *cur_mb, int b, int mi_stride);
+
+#define LEFT_TOP_MARGIN (16 << 3)
+#define RIGHT_BOTTOM_MARGIN (16 << 3)
+
+
+#endif
diff --git a/vp8/common/fourcc.hpp b/vp8/common/fourcc.hpp
new file mode 100644 (file)
index 0000000..5f1faed
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef FOURCC_HPP
+#define FOURCC_HPP
+
+#include <iosfwd>
+#include <cstring>
+
+
+#if defined(__POWERPC__) || defined(__APPLE__) || defined(__MERKS__)
+using namespace std;
+#endif
+
+class four_cc
+{
+public:
+
+    four_cc();
+    four_cc(const char*);
+    explicit four_cc(unsigned long);
+
+    bool operator==(const four_cc&) const;
+    bool operator!=(const four_cc&) const;
+
+    bool operator==(const char*) const;
+    bool operator!=(const char*) const;
+
+    operator unsigned long() const;
+    unsigned long as_long() const;
+
+    four_cc& operator=(unsigned long);
+
+    char operator[](int) const;
+
+    std::ostream& put(std::ostream&) const;
+
+    bool printable() const;
+
+private:
+
+    union
+    {
+        char code[4];
+        unsigned long code_as_long;
+    };
+
+};
+
+
+inline four_cc::four_cc()
+{
+}
+
+inline four_cc::four_cc(unsigned long x)
+    : code_as_long(x)
+{
+}
+
+inline four_cc::four_cc(const char* str)
+{
+    memcpy(code, str, 4);
+}
+
+
+inline bool four_cc::operator==(const four_cc& rhs) const
+{
+    return code_as_long == rhs.code_as_long;
+}
+
+inline bool four_cc::operator!=(const four_cc& rhs) const
+{
+    return !operator==(rhs);
+}
+
+inline bool four_cc::operator==(const char* rhs) const
+{
+    return (memcmp(code, rhs, 4) == 0);
+}
+
+inline bool four_cc::operator!=(const char* rhs) const
+{
+    return !operator==(rhs);
+}
+
+
+inline four_cc::operator unsigned long() const
+{
+    return code_as_long;
+}
+
+inline unsigned long four_cc::as_long() const
+{
+    return code_as_long;
+}
+
+inline char four_cc::operator[](int i) const
+{
+    return code[i];
+}
+
+inline four_cc& four_cc::operator=(unsigned long val)
+{
+    code_as_long = val;
+    return *this;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const four_cc& rhs)
+{
+    return rhs.put(os);
+}
+
+#endif
diff --git a/vp8/common/g_common.h b/vp8/common/g_common.h
new file mode 100644 (file)
index 0000000..e68c53e
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+extern void (*vp8_clear_system_state)(void);
+extern void (*vp8_plane_add_noise)(unsigned char *Start, unsigned int Width, unsigned int Height, int Pitch, int DPitch, int q);
+extern void (*de_interlace)
+(
+    unsigned char *src_ptr,
+    unsigned char *dst_ptr,
+    int Width,
+    int Height,
+    int Stride
+);
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
new file mode 100644 (file)
index 0000000..0011ae0
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "g_common.h"
+#include "subpixel.h"
+#include "loopfilter.h"
+#include "recon.h"
+#include "idct.h"
+#include "onyxc_int.h"
+
+extern void vp8_arch_x86_common_init(VP8_COMMON *ctx);
+
+void (*vp8_build_intra_predictors_mby_ptr)(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby(MACROBLOCKD *x);
+
+void (*vp8_build_intra_predictors_mby_s_ptr)(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x);
+
+void vp8_machine_specific_config(VP8_COMMON *ctx)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    VP8_COMMON_RTCD *rtcd = &ctx->rtcd;
+
+    rtcd->idct.idct1        = vp8_short_idct4x4llm_1_c;
+    rtcd->idct.idct16       = vp8_short_idct4x4llm_c;
+    rtcd->idct.idct1_scalar = vp8_dc_only_idct_c;
+    rtcd->idct.iwalsh1      = vp8_short_inv_walsh4x4_1_c;
+    rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_c;
+
+    rtcd->recon.copy16x16   = vp8_copy_mem16x16_c;
+    rtcd->recon.copy8x8     = vp8_copy_mem8x8_c;
+    rtcd->recon.copy8x4     = vp8_copy_mem8x4_c;
+    rtcd->recon.recon      = vp8_recon_b_c;
+    rtcd->recon.recon2      = vp8_recon2b_c;
+    rtcd->recon.recon4     = vp8_recon4b_c;
+
+    rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_c;
+    rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_c;
+    rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_c;
+    rtcd->subpix.sixtap4x4     = vp8_sixtap_predict_c;
+    rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_c;
+    rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_c;
+    rtcd->subpix.bilinear8x4   = vp8_bilinear_predict8x4_c;
+    rtcd->subpix.bilinear4x4   = vp8_bilinear_predict4x4_c;
+
+    rtcd->loopfilter.normal_mb_v = vp8_loop_filter_mbv_c;
+    rtcd->loopfilter.normal_b_v  = vp8_loop_filter_bv_c;
+    rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_c;
+    rtcd->loopfilter.normal_b_h  = vp8_loop_filter_bh_c;
+    rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_c;
+    rtcd->loopfilter.simple_b_v  = vp8_loop_filter_bvs_c;
+    rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_c;
+    rtcd->loopfilter.simple_b_h  = vp8_loop_filter_bhs_c;
+
+#if CONFIG_POSTPROC || CONFIG_VP8_ENCODER
+    rtcd->postproc.down        = vp8_mbpost_proc_down_c;
+    rtcd->postproc.across      = vp8_mbpost_proc_across_ip_c;
+    rtcd->postproc.downacross  = vp8_post_proc_down_and_across_c;
+    rtcd->postproc.addnoise    = vp8_plane_add_noise_c;
+#endif
+
+#endif
+    // Pure C:
+    vp8_build_intra_predictors_mby_ptr = vp8_build_intra_predictors_mby;
+    vp8_build_intra_predictors_mby_s_ptr = vp8_build_intra_predictors_mby_s;
+
+#if ARCH_X86 || ARCH_X86_64
+    vp8_arch_x86_common_init(ctx);
+#endif
+
+}
diff --git a/vp8/common/header.h b/vp8/common/header.h
new file mode 100644 (file)
index 0000000..8b2b009
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_HEADER_H
+#define __INC_HEADER_H
+
+/* 24 bits total */
+typedef struct
+{
+    unsigned int type: 1;
+    unsigned int version: 3;
+    unsigned int show_frame: 1;
+
+    /* Allow 2^20 bytes = 8 megabits for first partition */
+
+    unsigned int first_partition_length_in_bytes: 19;
+
+#ifdef PACKET_TESTING
+    unsigned int frame_number;
+    unsigned int update_gold: 1;
+    unsigned int uses_gold: 1;
+    unsigned int update_last: 1;
+    unsigned int uses_last: 1;
+#endif
+
+} VP8_HEADER;
+
+#ifdef PACKET_TESTING
+#define VP8_HEADER_SIZE 8
+#else
+#define VP8_HEADER_SIZE 3
+#endif
+
+
+#endif
diff --git a/vp8/common/idct.h b/vp8/common/idct.h
new file mode 100644 (file)
index 0000000..47b5f05
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_IDCT_H
+#define __INC_IDCT_H
+
+#define prototype_second_order(sym) \
+    void sym(short *input, short *output)
+
+#define prototype_idct(sym) \
+    void sym(short *input, short *output, int pitch)
+
+#define prototype_idct_scalar(sym) \
+    void sym(short input, short *output, int pitch)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/idct_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/idct_arm.h"
+#endif
+
+#ifndef vp8_idct_idct1
+#define vp8_idct_idct1 vp8_short_idct4x4llm_1_c
+#endif
+extern prototype_idct(vp8_idct_idct1);
+
+#ifndef vp8_idct_idct16
+#define vp8_idct_idct16 vp8_short_idct4x4llm_c
+#endif
+extern prototype_idct(vp8_idct_idct16);
+
+#ifndef vp8_idct_idct1_scalar
+#define vp8_idct_idct1_scalar vp8_dc_only_idct_c
+#endif
+extern prototype_idct_scalar(vp8_idct_idct1_scalar);
+
+
+#ifndef vp8_idct_iwalsh1
+#define vp8_idct_iwalsh1 vp8_short_inv_walsh4x4_1_c
+#endif
+extern prototype_second_order(vp8_idct_iwalsh1);
+
+#ifndef vp8_idct_iwalsh16
+#define vp8_idct_iwalsh16 vp8_short_inv_walsh4x4_c
+#endif
+extern prototype_second_order(vp8_idct_iwalsh16);
+
+typedef prototype_idct((*vp8_idct_fn_t));
+typedef prototype_idct_scalar((*vp8_idct_scalar_fn_t));
+typedef prototype_second_order((*vp8_second_order_fn_t));
+
+typedef struct
+{
+    vp8_idct_fn_t         idct1;
+    vp8_idct_fn_t         idct16;
+    vp8_idct_scalar_fn_t  idct1_scalar;
+
+    vp8_second_order_fn_t iwalsh1;
+    vp8_second_order_fn_t iwalsh16;
+} vp8_idct_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IDCT_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define IDCT_INVOKE(ctx,fn) vp8_idct_##fn
+#endif
+
+#endif
diff --git a/vp8/common/idctllm.c b/vp8/common/idctllm.c
new file mode 100644 (file)
index 0000000..57cf858
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ * Notes:
+ *
+ * This implementation makes use of 16 bit fixed point verio of two multiply
+ * constants:
+ *         1.   sqrt(2) * cos (pi/8)
+ *         2.   sqrt(2) * sin (pi/8)
+ * Becuase the first constant is bigger than 1, to maintain the same 16 bit
+ * fixed point precision as the second one, we use a trick of
+ *         x * a = x + x*(a-1)
+ * so
+ *         x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1).
+ **************************************************************************/
+static const int cospi8sqrt2minus1 = 20091;
+static const int sinpi8sqrt2      = 35468;
+static const int rounding = 0;
+void vp8_short_idct4x4llm_c(short *input, short *output, int pitch)
+{
+    int i;
+    int a1, b1, c1, d1;
+
+    short *ip = input;
+    short *op = output;
+    int temp1, temp2;
+    int shortpitch = pitch >> 1;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = ip[0] + ip[8];
+        b1 = ip[0] - ip[8];
+
+        temp1 = (ip[4] * sinpi8sqrt2 + rounding) >> 16;
+        temp2 = ip[12] + ((ip[12] * cospi8sqrt2minus1 + rounding) >> 16);
+        c1 = temp1 - temp2;
+
+        temp1 = ip[4] + ((ip[4] * cospi8sqrt2minus1 + rounding) >> 16);
+        temp2 = (ip[12] * sinpi8sqrt2 + rounding) >> 16;
+        d1 = temp1 + temp2;
+
+        op[shortpitch*0] = a1 + d1;
+        op[shortpitch*3] = a1 - d1;
+
+        op[shortpitch*1] = b1 + c1;
+        op[shortpitch*2] = b1 - c1;
+
+        ip++;
+        op++;
+    }
+
+    ip = output;
+    op = output;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = ip[0] + ip[2];
+        b1 = ip[0] - ip[2];
+
+        temp1 = (ip[1] * sinpi8sqrt2 + rounding) >> 16;
+        temp2 = ip[3] + ((ip[3] * cospi8sqrt2minus1 + rounding) >> 16);
+        c1 = temp1 - temp2;
+
+        temp1 = ip[1] + ((ip[1] * cospi8sqrt2minus1 + rounding) >> 16);
+        temp2 = (ip[3] * sinpi8sqrt2 + rounding) >> 16;
+        d1 = temp1 + temp2;
+
+
+        op[0] = (a1 + d1 + 4) >> 3;
+        op[3] = (a1 - d1 + 4) >> 3;
+
+        op[1] = (b1 + c1 + 4) >> 3;
+        op[2] = (b1 - c1 + 4) >> 3;
+
+        ip += shortpitch;
+        op += shortpitch;
+    }
+}
+
+void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch)
+{
+    int i;
+    int a1;
+    short *op = output;
+    int shortpitch = pitch >> 1;
+    a1 = ((input[0] + 4) >> 3);
+
+    for (i = 0; i < 4; i++)
+    {
+        op[0] = a1;
+        op[1] = a1;
+        op[2] = a1;
+        op[3] = a1;
+        op += shortpitch;
+    }
+}
+
+
+void vp8_dc_only_idct_c(short input_dc, short *output, int pitch)
+{
+    int i;
+    int a1;
+    short *op = output;
+    int shortpitch = pitch >> 1;
+    a1 = ((input_dc + 4) >> 3);
+
+    for (i = 0; i < 4; i++)
+    {
+        op[0] = a1;
+        op[1] = a1;
+        op[2] = a1;
+        op[3] = a1;
+        op += shortpitch;
+    }
+}
+
+void vp8_short_inv_walsh4x4_c(short *input, short *output)
+{
+    int i;
+    int a1, b1, c1, d1;
+    int a2, b2, c2, d2;
+    short *ip = input;
+    short *op = output;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = ip[0] + ip[12];
+        b1 = ip[4] + ip[8];
+        c1 = ip[4] - ip[8];
+        d1 = ip[0] - ip[12];
+
+        op[0] = a1 + b1;
+        op[4] = c1 + d1;
+        op[8] = a1 - b1;
+        op[12] = d1 - c1;
+        ip++;
+        op++;
+    }
+
+    ip = output;
+    op = output;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = ip[0] + ip[3];
+        b1 = ip[1] + ip[2];
+        c1 = ip[1] - ip[2];
+        d1 = ip[0] - ip[3];
+
+        a2 = a1 + b1;
+        b2 = c1 + d1;
+        c2 = a1 - b1;
+        d2 = d1 - c1;
+
+        op[0] = (a2 + 3) >> 3;
+        op[1] = (b2 + 3) >> 3;
+        op[2] = (c2 + 3) >> 3;
+        op[3] = (d2 + 3) >> 3;
+
+        ip += 4;
+        op += 4;
+    }
+}
+
+void vp8_short_inv_walsh4x4_1_c(short *input, short *output)
+{
+    int i;
+    int a1;
+    short *op = output;
+
+    a1 = ((input[0] + 3) >> 3);
+
+    for (i = 0; i < 4; i++)
+    {
+        op[0] = a1;
+        op[1] = a1;
+        op[2] = a1;
+        op[3] = a1;
+        op += 4;
+    }
+}
diff --git a/vp8/common/invtrans.c b/vp8/common/invtrans.c
new file mode 100644 (file)
index 0000000..1ff596e
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "invtrans.h"
+
+
+
+static void recon_dcblock(MACROBLOCKD *x)
+{
+    BLOCKD *b = &x->block[24];
+    int i;
+
+    for (i = 0; i < 16; i++)
+    {
+        x->block[i].dqcoeff[0] = b->diff[i];
+    }
+
+}
+
+void vp8_inverse_transform_b(const vp8_idct_rtcd_vtable_t *rtcd, BLOCKD *b, int pitch)
+{
+    if (b->eob > 1)
+        IDCT_INVOKE(rtcd, idct16)(b->dqcoeff, b->diff, pitch);
+    else
+        IDCT_INVOKE(rtcd, idct1)(b->dqcoeff, b->diff, pitch);
+}
+
+
+void vp8_inverse_transform_mby(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    // do 2nd order transform on the dc block
+    IDCT_INVOKE(rtcd, iwalsh16)(x->block[24].dqcoeff, x->block[24].diff);
+
+    recon_dcblock(x);
+
+    for (i = 0; i < 16; i++)
+    {
+        vp8_inverse_transform_b(rtcd, &x->block[i], 32);
+    }
+
+}
+void vp8_inverse_transform_mbuv(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    for (i = 16; i < 24; i++)
+    {
+        vp8_inverse_transform_b(rtcd, &x->block[i], 16);
+    }
+
+}
+
+
+void vp8_inverse_transform_mb(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        // do 2nd order transform on the dc block
+
+        IDCT_INVOKE(rtcd, iwalsh16)(&x->block[24].dqcoeff[0], x->block[24].diff);
+        recon_dcblock(x);
+    }
+
+    for (i = 0; i < 16; i++)
+    {
+        vp8_inverse_transform_b(rtcd, &x->block[i], 32);
+    }
+
+
+    for (i = 16; i < 24; i++)
+    {
+        vp8_inverse_transform_b(rtcd, &x->block[i], 16);
+    }
+
+}
diff --git a/vp8/common/invtrans.h b/vp8/common/invtrans.h
new file mode 100644 (file)
index 0000000..93a40f9
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_INVTRANS_H
+#define __INC_INVTRANS_H
+
+#include "vpx_ports/config.h"
+#include "idct.h"
+#include "blockd.h"
+extern void vp8_inverse_transform_b(const vp8_idct_rtcd_vtable_t *rtcd, BLOCKD *b, int pitch);
+extern void vp8_inverse_transform_mb(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+extern void vp8_inverse_transform_mby(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+extern void vp8_inverse_transform_mbuv(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+
+#endif
diff --git a/vp8/common/littlend.h b/vp8/common/littlend.h
new file mode 100644 (file)
index 0000000..08c525c
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _littlend_h
+#define _littlend_h
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define invert2(x) (x)
+#define invert4(x) (x)
+
+#define low_byte(x) (unsigned char)x
+#define mid1Byte(x) (unsigned char)(x >> 8)
+#define mid2Byte(x) (unsigned char)(x >> 16)
+#define high_byte(x) (unsigned char)(x >> 24)
+
+#define SWAPENDS 0
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/vp8/common/loopfilter.c b/vp8/common/loopfilter.c
new file mode 100644 (file)
index 0000000..79e6177
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "loopfilter.h"
+#include "onyxc_int.h"
+
+typedef unsigned char uc;
+
+
+prototype_loopfilter(vp8_loop_filter_horizontal_edge_c);
+prototype_loopfilter(vp8_loop_filter_vertical_edge_c);
+prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c);
+prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c);
+prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
+prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c);
+
+// Horizontal MB filtering
+void vp8_loop_filter_mbh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_horizontal_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_horizontal_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+void vp8_loop_filter_mbhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+// Vertical MB Filtering
+void vp8_loop_filter_mbv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_vertical_edge_c(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_vertical_edge_c(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+void vp8_loop_filter_mbvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_c(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+// Horizontal B Filtering
+void vp8_loop_filter_bh_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                          int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_horizontal_edge_c(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_horizontal_edge_c(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+void vp8_loop_filter_bhs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_c(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+// Vertical B Filtering
+void vp8_loop_filter_bv_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                          int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_vertical_edge_c(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_vertical_edge_c(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+void vp8_loop_filter_bvs_c(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                           int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_c(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_c(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_c(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+void vp8_init_loop_filter(VP8_COMMON *cm)
+{
+    loop_filter_info *lfi = cm->lf_info;
+    LOOPFILTERTYPE lft = cm->filter_type;
+    int sharpness_lvl = cm->sharpness_level;
+    int frame_type = cm->frame_type;
+    int i, j;
+
+    int block_inside_limit = 0;
+    int HEVThresh;
+    const int yhedge_boost  = 2;
+    const int uvhedge_boost = 2;
+
+    // For each possible value for the loop filter fill out a "loop_filter_info" entry.
+    for (i = 0; i <= MAX_LOOP_FILTER; i++)
+    {
+        int filt_lvl = i;
+
+        if (frame_type == KEY_FRAME)
+        {
+            if (filt_lvl >= 40)
+                HEVThresh = 2;
+            else if (filt_lvl >= 15)
+                HEVThresh = 1;
+            else
+                HEVThresh = 0;
+        }
+        else
+        {
+            if (filt_lvl >= 40)
+                HEVThresh = 3;
+            else if (filt_lvl >= 20)
+                HEVThresh = 2;
+            else if (filt_lvl >= 15)
+                HEVThresh = 1;
+            else
+                HEVThresh = 0;
+        }
+
+        // Set loop filter paramaeters that control sharpness.
+        block_inside_limit = filt_lvl >> (sharpness_lvl > 0);
+        block_inside_limit = block_inside_limit >> (sharpness_lvl > 4);
+
+        if (sharpness_lvl > 0)
+        {
+            if (block_inside_limit > (9 - sharpness_lvl))
+                block_inside_limit = (9 - sharpness_lvl);
+        }
+
+        if (block_inside_limit < 1)
+            block_inside_limit = 1;
+
+        for (j = 0; j < 16; j++)
+        {
+            lfi[i].lim[j] = block_inside_limit;
+            lfi[i].mbflim[j] = filt_lvl + yhedge_boost;
+            lfi[i].mbthr[j] = HEVThresh;
+            lfi[i].flim[j] = filt_lvl;
+            lfi[i].thr[j] = HEVThresh;
+            lfi[i].uvlim[j] = block_inside_limit;
+            lfi[i].uvmbflim[j] = filt_lvl + uvhedge_boost;
+            lfi[i].uvmbthr[j] = HEVThresh;
+            lfi[i].uvflim[j] = filt_lvl;
+            lfi[i].uvthr[j] = HEVThresh;
+        }
+
+    }
+
+    // Set up the function pointers depending on the type of loop filtering selected
+    if (lft == NORMAL_LOOPFILTER)
+    {
+        cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_v);
+        cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_v);
+        cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, normal_mb_h);
+        cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, normal_b_h);
+    }
+    else
+    {
+        cm->lf_mbv = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_v);
+        cm->lf_bv  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_v);
+        cm->lf_mbh = LF_INVOKE(&cm->rtcd.loopfilter, simple_mb_h);
+        cm->lf_bh  = LF_INVOKE(&cm->rtcd.loopfilter, simple_b_h);
+    }
+}
+
+// Put vp8_init_loop_filter() in vp8dx_create_decompressor(). Only call vp8_frame_init_loop_filter() while decoding
+// each frame. Check last_frame_type to skip the function most of times.
+void vp8_frame_init_loop_filter(loop_filter_info *lfi, int frame_type)
+{
+    int HEVThresh;
+    int i, j;
+
+    // For each possible value for the loop filter fill out a "loop_filter_info" entry.
+    for (i = 0; i <= MAX_LOOP_FILTER; i++)
+    {
+        int filt_lvl = i;
+
+        if (frame_type == KEY_FRAME)
+        {
+            if (filt_lvl >= 40)
+                HEVThresh = 2;
+            else if (filt_lvl >= 15)
+                HEVThresh = 1;
+            else
+                HEVThresh = 0;
+        }
+        else
+        {
+            if (filt_lvl >= 40)
+                HEVThresh = 3;
+            else if (filt_lvl >= 20)
+                HEVThresh = 2;
+            else if (filt_lvl >= 15)
+                HEVThresh = 1;
+            else
+                HEVThresh = 0;
+        }
+
+        for (j = 0; j < 16; j++)
+        {
+            //lfi[i].lim[j] = block_inside_limit;
+            //lfi[i].mbflim[j] = filt_lvl+yhedge_boost;
+            lfi[i].mbthr[j] = HEVThresh;
+            //lfi[i].flim[j] = filt_lvl;
+            lfi[i].thr[j] = HEVThresh;
+            //lfi[i].uvlim[j] = block_inside_limit;
+            //lfi[i].uvmbflim[j] = filt_lvl+uvhedge_boost;
+            lfi[i].uvmbthr[j] = HEVThresh;
+            //lfi[i].uvflim[j] = filt_lvl;
+            lfi[i].uvthr[j] = HEVThresh;
+        }
+    }
+}
+
+
+void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level)
+{
+    MB_MODE_INFO *mbmi = &mbd->mode_info_context->mbmi;
+
+    if (mbd->mode_ref_lf_delta_enabled)
+    {
+        // Aplly delta for reference frame
+        *filter_level += mbd->ref_lf_deltas[mbmi->ref_frame];
+
+        // Apply delta for mode
+        if (mbmi->ref_frame == INTRA_FRAME)
+        {
+            // Only the split mode BPRED has a further special case
+            if (mbmi->mode == B_PRED)
+                *filter_level +=  mbd->mode_lf_deltas[0];
+        }
+        else
+        {
+            // Zero motion mode
+            if (mbmi->mode == ZEROMV)
+                *filter_level +=  mbd->mode_lf_deltas[1];
+
+            // Split MB motion mode
+            else if (mbmi->mode == SPLITMV)
+                *filter_level +=  mbd->mode_lf_deltas[3];
+
+            // All other inter motion modes (Nearest, Near, New)
+            else
+                *filter_level +=  mbd->mode_lf_deltas[2];
+        }
+
+        // Range check
+        if (*filter_level > MAX_LOOP_FILTER)
+            *filter_level = MAX_LOOP_FILTER;
+        else if (*filter_level < 0)
+            *filter_level = 0;
+    }
+}
+
+
+void vp8_loop_filter_frame
+(
+    VP8_COMMON *cm,
+    MACROBLOCKD *mbd,
+    int default_filt_lvl
+)
+{
+    YV12_BUFFER_CONFIG *post = cm->frame_to_show;
+    loop_filter_info *lfi = cm->lf_info;
+    int frame_type = cm->frame_type;
+
+    int mb_row;
+    int mb_col;
+
+
+    int baseline_filter_level[MAX_MB_SEGMENTS];
+    int filter_level;
+    int alt_flt_enabled = mbd->segmentation_enabled;
+
+    int i;
+    unsigned char *y_ptr, *u_ptr, *v_ptr;
+
+    mbd->mode_info_context = cm->mi;          // Point at base of Mb MODE_INFO list
+
+    // Note the baseline filter values for each segment
+    if (alt_flt_enabled)
+    {
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+        {
+            // Abs value
+            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+                baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+            // Delta Value
+            else
+            {
+                baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+                baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
+            }
+        }
+    }
+    else
+    {
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+            baseline_filter_level[i] = default_filt_lvl;
+    }
+
+    // Initialize the loop filter for this frame.
+    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
+        vp8_init_loop_filter(cm);
+    else if (frame_type != cm->last_frame_type)
+        vp8_frame_init_loop_filter(lfi, frame_type);
+
+    // Set up the buffer pointers
+    y_ptr = post->y_buffer;
+    u_ptr = post->u_buffer;
+    v_ptr = post->v_buffer;
+
+    // vp8_filter each macro block
+    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+    {
+        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+        {
+            int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
+
+            filter_level = baseline_filter_level[Segment];
+
+            // Distance of Mb to the various image edges.
+            // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
+            // Apply any context driven MB level adjustment
+            vp8_adjust_mb_lf_value(mbd, &filter_level);
+
+            if (filter_level)
+            {
+                if (mb_col > 0)
+                    cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+
+                if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                    cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+
+                // don't apply across umv border
+                if (mb_row > 0)
+                    cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+
+                if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                    cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+            }
+
+            y_ptr += 16;
+            u_ptr += 8;
+            v_ptr += 8;
+
+            mbd->mode_info_context++;     // step to next MB
+        }
+
+        y_ptr += post->y_stride  * 16 - post->y_width;
+        u_ptr += post->uv_stride *  8 - post->uv_width;
+        v_ptr += post->uv_stride *  8 - post->uv_width;
+
+        mbd->mode_info_context++;         // Skip border mb
+    }
+}
+
+
+void vp8_loop_filter_frame_yonly
+(
+    VP8_COMMON *cm,
+    MACROBLOCKD *mbd,
+    int default_filt_lvl,
+    int sharpness_lvl
+)
+{
+    YV12_BUFFER_CONFIG *post = cm->frame_to_show;
+
+    int i;
+    unsigned char *y_ptr;
+    int mb_row;
+    int mb_col;
+
+    loop_filter_info *lfi = cm->lf_info;
+    int baseline_filter_level[MAX_MB_SEGMENTS];
+    int filter_level;
+    int alt_flt_enabled = mbd->segmentation_enabled;
+    int frame_type = cm->frame_type;
+
+    (void) sharpness_lvl;
+
+    //MODE_INFO * this_mb_mode_info = cm->mi;  // Point at base of Mb MODE_INFO list
+    mbd->mode_info_context = cm->mi;          // Point at base of Mb MODE_INFO list
+
+    // Note the baseline filter values for each segment
+    if (alt_flt_enabled)
+    {
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+        {
+            // Abs value
+            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+                baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+            // Delta Value
+            else
+            {
+                baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+                baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
+            }
+        }
+    }
+    else
+    {
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+            baseline_filter_level[i] = default_filt_lvl;
+    }
+
+    // Initialize the loop filter for this frame.
+    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
+        vp8_init_loop_filter(cm);
+    else if (frame_type != cm->last_frame_type)
+        vp8_frame_init_loop_filter(lfi, frame_type);
+
+    // Set up the buffer pointers
+    y_ptr = post->y_buffer;
+
+    // vp8_filter each macro block
+    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+    {
+        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+        {
+            int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
+            filter_level = baseline_filter_level[Segment];
+
+            // Apply any context driven MB level adjustment
+            vp8_adjust_mb_lf_value(mbd, &filter_level);
+
+            if (filter_level)
+            {
+                if (mb_col > 0)
+                    cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+
+                if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                    cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+
+                // don't apply across umv border
+                if (mb_row > 0)
+                    cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+
+                if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                    cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+            }
+
+            y_ptr += 16;
+            mbd->mode_info_context ++;        // step to next MB
+
+        }
+
+        y_ptr += post->y_stride  * 16 - post->y_width;
+        mbd->mode_info_context ++;            // Skip border mb
+    }
+
+}
+
+
+void vp8_loop_filter_partial_frame
+(
+    VP8_COMMON *cm,
+    MACROBLOCKD *mbd,
+    int default_filt_lvl,
+    int sharpness_lvl,
+    int Fraction
+)
+{
+    YV12_BUFFER_CONFIG *post = cm->frame_to_show;
+
+    int i;
+    unsigned char *y_ptr;
+    int mb_row;
+    int mb_col;
+    //int mb_rows = post->y_height >> 4;
+    int mb_cols = post->y_width  >> 4;
+
+    int linestocopy;
+
+    loop_filter_info *lfi = cm->lf_info;
+    int baseline_filter_level[MAX_MB_SEGMENTS];
+    int filter_level;
+    int alt_flt_enabled = mbd->segmentation_enabled;
+    int frame_type = cm->frame_type;
+
+    (void) sharpness_lvl;
+
+    //MODE_INFO * this_mb_mode_info = cm->mi + (post->y_height>>5) * (mb_cols + 1);  // Point at base of Mb MODE_INFO list
+    mbd->mode_info_context = cm->mi + (post->y_height >> 5) * (mb_cols + 1);        // Point at base of Mb MODE_INFO list
+
+    linestocopy = (post->y_height >> (4 + Fraction));
+
+    if (linestocopy < 1)
+        linestocopy = 1;
+
+    linestocopy <<= 4;
+
+    // Note the baseline filter values for each segment
+    if (alt_flt_enabled)
+    {
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+        {
+            // Abs value
+            if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+                baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+            // Delta Value
+            else
+            {
+                baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+                baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
+            }
+        }
+    }
+    else
+    {
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+            baseline_filter_level[i] = default_filt_lvl;
+    }
+
+    // Initialize the loop filter for this frame.
+    if ((cm->last_filter_type != cm->filter_type) || (cm->last_sharpness_level != cm->sharpness_level))
+        vp8_init_loop_filter(cm);
+    else if (frame_type != cm->last_frame_type)
+        vp8_frame_init_loop_filter(lfi, frame_type);
+
+    // Set up the buffer pointers
+    y_ptr = post->y_buffer + (post->y_height >> 5) * 16 * post->y_stride;
+
+    // vp8_filter each macro block
+    for (mb_row = 0; mb_row<(linestocopy >> 4); mb_row++)
+    {
+        for (mb_col = 0; mb_col < mb_cols; mb_col++)
+        {
+            int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
+            filter_level = baseline_filter_level[Segment];
+
+            if (filter_level)
+            {
+                if (mb_col > 0)
+                    cm->lf_mbv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+
+                if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                    cm->lf_bv(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+
+                cm->lf_mbh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+
+                if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                    cm->lf_bh(y_ptr, 0, 0, post->y_stride, 0, &lfi[filter_level], 0);
+            }
+
+            y_ptr += 16;
+            mbd->mode_info_context += 1;      // step to next MB
+        }
+
+        y_ptr += post->y_stride  * 16 - post->y_width;
+        mbd->mode_info_context += 1;          // Skip border mb
+    }
+}
diff --git a/vp8/common/loopfilter.h b/vp8/common/loopfilter.h
new file mode 100644 (file)
index 0000000..c6ce508
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef loopfilter_h
+#define loopfilter_h
+
+#include "vpx_ports/mem.h"
+
+#define MAX_LOOP_FILTER 63
+
+typedef enum
+{
+    NORMAL_LOOPFILTER = 0,
+    SIMPLE_LOOPFILTER = 1
+} LOOPFILTERTYPE;
+
+// FRK
+// Need to align this structure so when it is declared and
+// passed it can be loaded into vector registers.
+// FRK
+typedef struct
+{
+    DECLARE_ALIGNED(16, signed char, lim[16]);
+    DECLARE_ALIGNED(16, signed char, flim[16]);
+    DECLARE_ALIGNED(16, signed char, thr[16]);
+    DECLARE_ALIGNED(16, signed char, mbflim[16]);
+    DECLARE_ALIGNED(16, signed char, mbthr[16]);
+    DECLARE_ALIGNED(16, signed char, uvlim[16]);
+    DECLARE_ALIGNED(16, signed char, uvflim[16]);
+    DECLARE_ALIGNED(16, signed char, uvthr[16]);
+    DECLARE_ALIGNED(16, signed char, uvmbflim[16]);
+    DECLARE_ALIGNED(16, signed char, uvmbthr[16]);
+} loop_filter_info;
+
+
+#define prototype_loopfilter(sym) \
+    void sym(unsigned char *src, int pitch, const signed char *flimit,\
+             const signed char *limit, const signed char *thresh, int count)
+
+#define prototype_loopfilter_block(sym) \
+    void sym(unsigned char *y, unsigned char *u, unsigned char *v,\
+             int ystride, int uv_stride, loop_filter_info *lfi, int simpler)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/loopfilter_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/loopfilter_arm.h"
+#endif
+
+#ifndef vp8_lf_normal_mb_v
+#define vp8_lf_normal_mb_v vp8_loop_filter_mbv_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_normal_mb_v);
+
+#ifndef vp8_lf_normal_b_v
+#define vp8_lf_normal_b_v vp8_loop_filter_bv_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_normal_b_v);
+
+#ifndef vp8_lf_normal_mb_h
+#define vp8_lf_normal_mb_h vp8_loop_filter_mbh_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_normal_mb_h);
+
+#ifndef vp8_lf_normal_b_h
+#define vp8_lf_normal_b_h vp8_loop_filter_bh_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_normal_b_h);
+
+
+#ifndef vp8_lf_simple_mb_v
+#define vp8_lf_simple_mb_v vp8_loop_filter_mbvs_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_simple_mb_v);
+
+#ifndef vp8_lf_simple_b_v
+#define vp8_lf_simple_b_v vp8_loop_filter_bvs_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_simple_b_v);
+
+#ifndef vp8_lf_simple_mb_h
+#define vp8_lf_simple_mb_h vp8_loop_filter_mbhs_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_simple_mb_h);
+
+#ifndef vp8_lf_simple_b_h
+#define vp8_lf_simple_b_h vp8_loop_filter_bhs_c
+#endif
+extern prototype_loopfilter_block(vp8_lf_simple_b_h);
+
+typedef prototype_loopfilter_block((*vp8_lf_block_fn_t));
+typedef struct
+{
+    vp8_lf_block_fn_t  normal_mb_v;
+    vp8_lf_block_fn_t  normal_b_v;
+    vp8_lf_block_fn_t  normal_mb_h;
+    vp8_lf_block_fn_t  normal_b_h;
+    vp8_lf_block_fn_t  simple_mb_v;
+    vp8_lf_block_fn_t  simple_b_v;
+    vp8_lf_block_fn_t  simple_mb_h;
+    vp8_lf_block_fn_t  simple_b_h;
+} vp8_loopfilter_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define LF_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define LF_INVOKE(ctx,fn) vp8_lf_##fn
+#endif
+
+
+#endif
diff --git a/vp8/common/loopfilter_filters.c b/vp8/common/loopfilter_filters.c
new file mode 100644 (file)
index 0000000..7d16e48
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+#include "loopfilter.h"
+#include "onyxc_int.h"
+
+
+#define NEW_LOOPFILTER_MASK
+
+typedef unsigned char uc;
+
+__inline signed char vp8_signed_char_clamp(int t)
+{
+    t = (t < -128 ? -128 : t);
+    t = (t > 127 ? 127 : t);
+    return (signed char) t;
+}
+
+
+// should we apply any filter at all ( 11111111 yes, 00000000 no)
+__inline signed char vp8_filter_mask(signed char limit, signed char flimit,
+                                     uc p3, uc p2, uc p1, uc p0, uc q0, uc q1, uc q2, uc q3)
+{
+    signed char mask = 0;
+    mask |= (abs(p3 - p2) > limit) * -1;
+    mask |= (abs(p2 - p1) > limit) * -1;
+    mask |= (abs(p1 - p0) > limit) * -1;
+    mask |= (abs(q1 - q0) > limit) * -1;
+    mask |= (abs(q2 - q1) > limit) * -1;
+    mask |= (abs(q3 - q2) > limit) * -1;
+#ifndef NEW_LOOPFILTER_MASK
+    mask |= (abs(p0 - q0) > flimit) * -1;
+#else
+    mask |= (abs(p0 - q0) * 2 + abs(p1 - q1) / 2  > flimit * 2 + limit) * -1;
+#endif
+    mask = ~mask;
+    return mask;
+}
+
+// is there high variance internal edge ( 11111111 yes, 00000000 no)
+__inline signed char vp8_hevmask(signed char thresh, uc p1, uc p0, uc q0, uc q1)
+{
+    signed char hev = 0;
+    hev  |= (abs(p1 - p0) > thresh) * -1;
+    hev  |= (abs(q1 - q0) > thresh) * -1;
+    return hev;
+}
+
+__inline void vp8_filter(signed char mask, signed char hev, uc *op1, uc *op0, uc *oq0, uc *oq1)
+
+{
+    signed char ps0, qs0;
+    signed char ps1, qs1;
+    signed char vp8_filter, Filter1, Filter2;
+    signed char u;
+
+    ps1 = (signed char) * op1 ^ 0x80;
+    ps0 = (signed char) * op0 ^ 0x80;
+    qs0 = (signed char) * oq0 ^ 0x80;
+    qs1 = (signed char) * oq1 ^ 0x80;
+
+    // add outer taps if we have high edge variance
+    vp8_filter = vp8_signed_char_clamp(ps1 - qs1);
+    vp8_filter &= hev;
+
+    // inner taps
+    vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * (qs0 - ps0));
+    vp8_filter &= mask;
+
+    // save bottom 3 bits so that we round one side +4 and the other +3
+    // if it equals 4 we'll set to adjust by -1 to account for the fact
+    // we'd round 3 the other way
+    Filter1 = vp8_signed_char_clamp(vp8_filter + 4);
+    Filter2 = vp8_signed_char_clamp(vp8_filter + 3);
+    Filter1 >>= 3;
+    Filter2 >>= 3;
+    u = vp8_signed_char_clamp(qs0 - Filter1);
+    *oq0 = u ^ 0x80;
+    u = vp8_signed_char_clamp(ps0 + Filter2);
+    *op0 = u ^ 0x80;
+    vp8_filter = Filter1;
+
+    // outer tap adjustments
+    vp8_filter += 1;
+    vp8_filter >>= 1;
+    vp8_filter &= ~hev;
+
+    u = vp8_signed_char_clamp(qs1 - vp8_filter);
+    *oq1 = u ^ 0x80;
+    u = vp8_signed_char_clamp(ps1 + vp8_filter);
+    *op1 = u ^ 0x80;
+
+}
+void vp8_loop_filter_horizontal_edge_c
+(
+    unsigned char *s,
+    int p, //pitch
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    int count
+)
+{
+    int  hev = 0; // high edge variance
+    signed char mask = 0;
+    int i = 0;
+
+    // loop filter designed to work using chars so that we can make maximum use
+    // of 8 bit simd instructions.
+    do
+    {
+        mask = vp8_filter_mask(limit[i], flimit[i],
+                               s[-4*p], s[-3*p], s[-2*p], s[-1*p],
+                               s[0*p], s[1*p], s[2*p], s[3*p]);
+
+        hev = vp8_hevmask(thresh[i], s[-2*p], s[-1*p], s[0*p], s[1*p]);
+
+        vp8_filter(mask, hev, s - 2 * p, s - 1 * p, s, s + 1 * p);
+
+        ++s;
+    }
+    while (++i < count * 8);
+}
+
+void vp8_loop_filter_vertical_edge_c
+(
+    unsigned char *s,
+    int p,
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    int count
+)
+{
+    int  hev = 0; // high edge variance
+    signed char mask = 0;
+    int i = 0;
+
+    // loop filter designed to work using chars so that we can make maximum use
+    // of 8 bit simd instructions.
+    do
+    {
+        mask = vp8_filter_mask(limit[i], flimit[i],
+                               s[-4], s[-3], s[-2], s[-1], s[0], s[1], s[2], s[3]);
+
+        hev = vp8_hevmask(thresh[i], s[-2], s[-1], s[0], s[1]);
+
+        vp8_filter(mask, hev, s - 2, s - 1, s, s + 1);
+
+        s += p;
+    }
+    while (++i < count * 8);
+}
+
+__inline void vp8_mbfilter(signed char mask, signed char hev,
+                           uc *op2, uc *op1, uc *op0, uc *oq0, uc *oq1, uc *oq2)
+{
+    signed char s, u;
+    signed char vp8_filter, Filter1, Filter2;
+    signed char ps2 = (signed char) * op2 ^ 0x80;
+    signed char ps1 = (signed char) * op1 ^ 0x80;
+    signed char ps0 = (signed char) * op0 ^ 0x80;
+    signed char qs0 = (signed char) * oq0 ^ 0x80;
+    signed char qs1 = (signed char) * oq1 ^ 0x80;
+    signed char qs2 = (signed char) * oq2 ^ 0x80;
+
+    // add outer taps if we have high edge variance
+    vp8_filter = vp8_signed_char_clamp(ps1 - qs1);
+    vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * (qs0 - ps0));
+    vp8_filter &= mask;
+
+    Filter2 = vp8_filter;
+    Filter2 &= hev;
+
+    // save bottom 3 bits so that we round one side +4 and the other +3
+    Filter1 = vp8_signed_char_clamp(Filter2 + 4);
+    Filter2 = vp8_signed_char_clamp(Filter2 + 3);
+    Filter1 >>= 3;
+    Filter2 >>= 3;
+    qs0 = vp8_signed_char_clamp(qs0 - Filter1);
+    ps0 = vp8_signed_char_clamp(ps0 + Filter2);
+
+
+    // only apply wider filter if not high edge variance
+    vp8_filter &= ~hev;
+    Filter2 = vp8_filter;
+
+    // roughly 3/7th difference across boundary
+    u = vp8_signed_char_clamp((63 + Filter2 * 27) >> 7);
+    s = vp8_signed_char_clamp(qs0 - u);
+    *oq0 = s ^ 0x80;
+    s = vp8_signed_char_clamp(ps0 + u);
+    *op0 = s ^ 0x80;
+
+    // roughly 2/7th difference across boundary
+    u = vp8_signed_char_clamp((63 + Filter2 * 18) >> 7);
+    s = vp8_signed_char_clamp(qs1 - u);
+    *oq1 = s ^ 0x80;
+    s = vp8_signed_char_clamp(ps1 + u);
+    *op1 = s ^ 0x80;
+
+    // roughly 1/7th difference across boundary
+    u = vp8_signed_char_clamp((63 + Filter2 * 9) >> 7);
+    s = vp8_signed_char_clamp(qs2 - u);
+    *oq2 = s ^ 0x80;
+    s = vp8_signed_char_clamp(ps2 + u);
+    *op2 = s ^ 0x80;
+}
+
+void vp8_mbloop_filter_horizontal_edge_c
+(
+    unsigned char *s,
+    int p,
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    int count
+)
+{
+    signed char hev = 0; // high edge variance
+    signed char mask = 0;
+    int i = 0;
+
+    // loop filter designed to work using chars so that we can make maximum use
+    // of 8 bit simd instructions.
+    do
+    {
+
+        mask = vp8_filter_mask(limit[i], flimit[i],
+                               s[-4*p], s[-3*p], s[-2*p], s[-1*p],
+                               s[0*p], s[1*p], s[2*p], s[3*p]);
+
+        hev = vp8_hevmask(thresh[i], s[-2*p], s[-1*p], s[0*p], s[1*p]);
+
+        vp8_mbfilter(mask, hev, s - 3 * p, s - 2 * p, s - 1 * p, s, s + 1 * p, s + 2 * p);
+
+        ++s;
+    }
+    while (++i < count * 8);
+
+}
+
+
+void vp8_mbloop_filter_vertical_edge_c
+(
+    unsigned char *s,
+    int p,
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    int count
+)
+{
+    signed char hev = 0; // high edge variance
+    signed char mask = 0;
+    int i = 0;
+
+    do
+    {
+
+        mask = vp8_filter_mask(limit[i], flimit[i],
+                               s[-4], s[-3], s[-2], s[-1], s[0], s[1], s[2], s[3]);
+
+        hev = vp8_hevmask(thresh[i], s[-2], s[-1], s[0], s[1]);
+
+        vp8_mbfilter(mask, hev, s - 3, s - 2, s - 1, s, s + 1, s + 2);
+
+        s += p;
+    }
+    while (++i < count * 8);
+
+}
+
+// should we apply any filter at all ( 11111111 yes, 00000000 no)
+__inline signed char vp8_simple_filter_mask(signed char limit, signed char flimit, uc p1, uc p0, uc q0, uc q1)
+{
+// Why does this cause problems for win32?
+// error C2143: syntax error : missing ';' before 'type'
+//  (void) limit;
+#ifndef NEW_LOOPFILTER_MASK
+    signed char mask = (abs(p0 - q0) <= flimit) * -1;
+#else
+    signed char mask = (abs(p0 - q0) * 2 + abs(p1 - q1) / 2  <= flimit * 2 + limit) * -1;
+#endif
+    return mask;
+}
+
+__inline void vp8_simple_filter(signed char mask, uc *op1, uc *op0, uc *oq0, uc *oq1)
+{
+    signed char vp8_filter, Filter1, Filter2;
+    signed char p1 = (signed char) * op1 ^ 0x80;
+    signed char p0 = (signed char) * op0 ^ 0x80;
+    signed char q0 = (signed char) * oq0 ^ 0x80;
+    signed char q1 = (signed char) * oq1 ^ 0x80;
+    signed char u;
+
+    vp8_filter = vp8_signed_char_clamp(p1 - q1);
+    vp8_filter = vp8_signed_char_clamp(vp8_filter + 3 * (q0 - p0));
+    vp8_filter &= mask;
+
+    // save bottom 3 bits so that we round one side +4 and the other +3
+    Filter1 = vp8_signed_char_clamp(vp8_filter + 4);
+    Filter1 >>= 3;
+    u = vp8_signed_char_clamp(q0 - Filter1);
+    *oq0  = u ^ 0x80;
+
+    Filter2 = vp8_signed_char_clamp(vp8_filter + 3);
+    Filter2 >>= 3;
+    u = vp8_signed_char_clamp(p0 + Filter2);
+    *op0 = u ^ 0x80;
+}
+
+void vp8_loop_filter_simple_horizontal_edge_c
+(
+    unsigned char *s,
+    int p,
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    int count
+)
+{
+    signed char mask = 0;
+    int i = 0;
+    (void) thresh;
+
+    do
+    {
+        //mask = vp8_simple_filter_mask( limit[i], flimit[i],s[-1*p],s[0*p]);
+        mask = vp8_simple_filter_mask(limit[i], flimit[i], s[-2*p], s[-1*p], s[0*p], s[1*p]);
+        vp8_simple_filter(mask, s - 2 * p, s - 1 * p, s, s + 1 * p);
+        ++s;
+    }
+    while (++i < count * 8);
+}
+
+void vp8_loop_filter_simple_vertical_edge_c
+(
+    unsigned char *s,
+    int p,
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh,
+    int count
+)
+{
+    signed char mask = 0;
+    int i = 0;
+    (void) thresh;
+
+    do
+    {
+        //mask = vp8_simple_filter_mask( limit[i], flimit[i],s[-1],s[0]);
+        mask = vp8_simple_filter_mask(limit[i], flimit[i], s[-2], s[-1], s[0], s[1]);
+        vp8_simple_filter(mask, s - 2, s - 1, s, s + 1);
+        s += p;
+    }
+    while (++i < count * 8);
+
+}
diff --git a/vp8/common/mac_specs.h b/vp8/common/mac_specs.h
new file mode 100644 (file)
index 0000000..97bffc7
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if !defined(_mac_specs_h)
+#define _mac_specs_h
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+    extern unsigned int vp8_read_tsc();
+
+    extern unsigned int vp8_get_processor_freq();
+
+    extern unsigned int vpx_has_altivec();
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif
diff --git a/vp8/common/mbpitch.c b/vp8/common/mbpitch.c
new file mode 100644 (file)
index 0000000..a7e0ce9
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "blockd.h"
+
+typedef enum
+{
+    PRED = 0,
+    DEST = 1,
+} BLOCKSET;
+
+void vp8_setup_block
+(
+    BLOCKD *b,
+    int mv_stride,
+    unsigned char **base,
+    int Stride,
+    int offset,
+    BLOCKSET bs
+)
+{
+
+    if (bs == DEST)
+    {
+        b->dst_stride = Stride;
+        b->dst = offset;
+        b->base_dst = base;
+    }
+    else
+    {
+        b->pre_stride = Stride;
+        b->pre = offset;
+        b->base_pre = base;
+    }
+
+}
+
+void vp8_setup_macroblock(MACROBLOCKD *x, BLOCKSET bs)
+{
+    int block;
+
+    unsigned char **y, **u, **v;
+
+    if (bs == DEST)
+    {
+        y = &x->dst.y_buffer;
+        u = &x->dst.u_buffer;
+        v = &x->dst.v_buffer;
+    }
+    else
+    {
+        y = &x->pre.y_buffer;
+        u = &x->pre.u_buffer;
+        v = &x->pre.v_buffer;
+    }
+
+    for (block = 0; block < 16; block++) // y blocks
+    {
+        vp8_setup_block(&x->block[block], x->dst.y_stride, y, x->dst.y_stride,
+                        (block >> 2) * 4 * x->dst.y_stride + (block & 3) * 4, bs);
+    }
+
+    for (block = 16; block < 20; block++) // U and V blocks
+    {
+        vp8_setup_block(&x->block[block], x->dst.uv_stride, u, x->dst.uv_stride,
+                        ((block - 16) >> 1) * 4 * x->dst.uv_stride + (block & 1) * 4, bs);
+
+        vp8_setup_block(&x->block[block+4], x->dst.uv_stride, v, x->dst.uv_stride,
+                        ((block - 16) >> 1) * 4 * x->dst.uv_stride + (block & 1) * 4, bs);
+    }
+}
+
+void vp8_setup_block_dptrs(MACROBLOCKD *x)
+{
+    int r, c;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 4; c++)
+        {
+            x->block[r*4+c].diff      = &x->diff[r * 4 * 16 + c * 4];
+            x->block[r*4+c].predictor = x->predictor + r * 4 * 16 + c * 4;
+        }
+    }
+
+    for (r = 0; r < 2; r++)
+    {
+        for (c = 0; c < 2; c++)
+        {
+            x->block[16+r*2+c].diff      = &x->diff[256 + r * 4 * 8 + c * 4];
+            x->block[16+r*2+c].predictor = x->predictor + 256 + r * 4 * 8 + c * 4;
+
+        }
+    }
+
+    for (r = 0; r < 2; r++)
+    {
+        for (c = 0; c < 2; c++)
+        {
+            x->block[20+r*2+c].diff      = &x->diff[320+ r * 4 * 8 + c * 4];
+            x->block[20+r*2+c].predictor = x->predictor + 320 + r * 4 * 8 + c * 4;
+
+        }
+    }
+
+    x->block[24].diff = &x->diff[384];
+
+    for (r = 0; r < 25; r++)
+    {
+        x->block[r].qcoeff  = x->qcoeff  + r * 16;
+        x->block[r].dqcoeff = x->dqcoeff + r * 16;
+    }
+}
+
+void vp8_build_block_doffsets(MACROBLOCKD *x)
+{
+
+    // handle the destination pitch features
+    vp8_setup_macroblock(x, DEST);
+    vp8_setup_macroblock(x, PRED);
+}
diff --git a/vp8/common/modecont.c b/vp8/common/modecont.c
new file mode 100644 (file)
index 0000000..9301a25
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "entropy.h"
+
+const int vp8_mode_contexts[6][4] =
+{
+    {
+        // 0
+        7,     1,     1,   143,
+    },
+    {
+        // 1
+        14,    18,    14,   107,
+    },
+    {
+        // 2
+        135,    64,    57,    68,
+    },
+    {
+        // 3
+        60,    56,   128,    65,
+    },
+    {
+        // 4
+        159,   134,   128,    34,
+    },
+    {
+        // 5
+        234,   188,   128,    28,
+    },
+};
diff --git a/vp8/common/modecont.h b/vp8/common/modecont.h
new file mode 100644 (file)
index 0000000..0c57651
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_MODECONT_H
+#define __INC_MODECONT_H
+
+extern const int vp8_mode_contexts[6][4];
+
+#endif
diff --git a/vp8/common/modecontext.c b/vp8/common/modecontext.c
new file mode 100644 (file)
index 0000000..ceee74c
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "entropymode.h"
+
+const unsigned int vp8_kf_default_bmode_counts [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES] =
+{
+    {
+        //Above Mode :  0
+        { 43438,   2195,    470,    316,    615,    171,    217,    412,    124,    160, }, // left_mode 0
+        {  5722,   2751,    296,    291,     81,     68,     80,    101,    100,    170, }, // left_mode 1
+        {  1629,    201,    307,     25,     47,     16,     34,     72,     19,     28, }, // left_mode 2
+        {   332,    266,     36,    500,     20,     65,     23,     14,    154,    106, }, // left_mode 3
+        {   450,     97,     10,     24,    117,     10,      2,     12,      8,     71, }, // left_mode 4
+        {   384,     49,     29,     44,     12,    162,     51,      5,     87,     42, }, // left_mode 5
+        {   495,     53,    157,     27,     14,     57,    180,     17,     17,     34, }, // left_mode 6
+        {   695,     64,     62,      9,     27,      5,      3,    147,     10,     26, }, // left_mode 7
+        {   230,     54,     20,    124,     16,    125,     29,     12,    283,     37, }, // left_mode 8
+        {   260,     87,     21,    120,     32,     16,     33,     16,     33,    203, }, // left_mode 9
+    },
+    {
+        //Above Mode :  1
+        {  3934,   2573,    355,    137,    128,     87,    133,    117,     37,     27, }, // left_mode 0
+        {  1036,   1929,    278,    135,     27,     37,     48,     55,     41,     91, }, // left_mode 1
+        {   223,    256,    253,     15,     13,      9,     28,     64,      3,      3, }, // left_mode 2
+        {   120,    129,     17,    316,     15,     11,      9,      4,     53,     74, }, // left_mode 3
+        {   129,     58,      6,     11,     38,      2,      0,      5,      2,     67, }, // left_mode 4
+        {    53,     22,     11,     16,      8,     26,     14,      3,     19,     12, }, // left_mode 5
+        {    59,     26,     61,     11,      4,      9,     35,     13,      8,      8, }, // left_mode 6
+        {   101,     52,     40,      8,      5,      2,      8,     59,      2,     20, }, // left_mode 7
+        {    48,     34,     10,     52,      8,     15,      6,      6,     63,     20, }, // left_mode 8
+        {    96,     48,     22,     63,     11,     14,      5,      8,      9,     96, }, // left_mode 9
+    },
+    {
+        //Above Mode :  2
+        {   709,    461,    506,     36,     27,     33,    151,     98,     24,      6, }, // left_mode 0
+        {   201,    375,    442,     27,     13,      8,     46,     58,      6,     19, }, // left_mode 1
+        {   122,    140,    417,      4,     13,      3,     33,     59,      4,      2, }, // left_mode 2
+        {    36,     17,     22,     16,      6,      8,     12,     17,      9,     21, }, // left_mode 3
+        {    51,     15,      7,      1,     14,      0,      4,      5,      3,     22, }, // left_mode 4
+        {    18,     11,     30,      9,      7,     20,     11,      5,      2,      6, }, // left_mode 5
+        {    38,     21,    103,      9,      4,     12,     79,     13,      2,      5, }, // left_mode 6
+        {    64,     17,     66,      2,     12,      4,      2,     65,      4,      5, }, // left_mode 7
+        {    14,      7,      7,     16,      3,     11,      4,     13,     15,     16, }, // left_mode 8
+        {    36,      8,     32,      9,      9,      4,     14,      7,      6,     24, }, // left_mode 9
+    },
+    {
+        //Above Mode :  3
+        {  1340,    173,     36,    119,     30,     10,     13,     10,     20,     26, }, // left_mode 0
+        {   156,    293,     26,    108,      5,     16,      2,      4,     23,     30, }, // left_mode 1
+        {    60,     34,     13,      7,      3,      3,      0,      8,      4,      5, }, // left_mode 2
+        {    72,     64,      1,    235,      3,      9,      2,      7,     28,     38, }, // left_mode 3
+        {    29,     14,      1,      3,      5,      0,      2,      2,      5,     13, }, // left_mode 4
+        {    22,      7,      4,     11,      2,      5,      1,      2,      6,      4, }, // left_mode 5
+        {    18,     14,      5,      6,      4,      3,     14,      0,      9,      2, }, // left_mode 6
+        {    41,     10,      7,      1,      2,      0,      0,     10,      2,      1, }, // left_mode 7
+        {    23,     19,      2,     33,      1,      5,      2,      0,     51,      8, }, // left_mode 8
+        {    33,     26,      7,     53,      3,      9,      3,      3,      9,     19, }, // left_mode 9
+    },
+    {
+        //Above Mode :  4
+        {   410,    165,     43,     31,     66,     15,     30,     54,      8,     17, }, // left_mode 0
+        {   115,     64,     27,     18,     30,      7,     11,     15,      4,     19, }, // left_mode 1
+        {    31,     23,     25,      1,      7,      2,      2,     10,      0,      5, }, // left_mode 2
+        {    17,      4,      1,      6,      8,      2,      7,      5,      5,     21, }, // left_mode 3
+        {   120,     12,      1,      2,     83,      3,      0,      4,      1,     40, }, // left_mode 4
+        {     4,      3,      1,      2,      1,      2,      5,      0,      3,      6, }, // left_mode 5
+        {    10,      2,     13,      6,      6,      6,      8,      2,      4,      5, }, // left_mode 6
+        {    58,     10,      5,      1,     28,      1,      1,     33,      1,      9, }, // left_mode 7
+        {     8,      2,      1,      4,      2,      5,      1,      1,      2,     10, }, // left_mode 8
+        {    76,      7,      5,      7,     18,      2,      2,      0,      5,     45, }, // left_mode 9
+    },
+    {
+        //Above Mode :  5
+        {   444,     46,     47,     20,     14,    110,     60,     14,     60,      7, }, // left_mode 0
+        {    59,     57,     25,     18,      3,     17,     21,      6,     14,      6, }, // left_mode 1
+        {    24,     17,     20,      6,      4,     13,      7,      2,      3,      2, }, // left_mode 2
+        {    13,     11,      5,     14,      4,      9,      2,      4,     15,      7, }, // left_mode 3
+        {     8,      5,      2,      1,      4,      0,      1,      1,      2,     12, }, // left_mode 4
+        {    19,      5,      5,      7,      4,     40,      6,      3,     10,      4, }, // left_mode 5
+        {    16,      5,      9,      1,      1,     16,     26,      2,     10,      4, }, // left_mode 6
+        {    11,      4,      8,      1,      1,      4,      4,      5,      4,      1, }, // left_mode 7
+        {    15,      1,      3,      7,      3,     21,      7,      1,     34,      5, }, // left_mode 8
+        {    18,      5,      1,      3,      4,      3,      7,      1,      2,      9, }, // left_mode 9
+    },
+    {
+        //Above Mode :  6
+        {   476,    149,     94,     13,     14,     77,    291,     27,     23,      3, }, // left_mode 0
+        {    79,     83,     42,     14,      2,     12,     63,      2,      4,     14, }, // left_mode 1
+        {    43,     36,     55,      1,      3,      8,     42,     11,      5,      1, }, // left_mode 2
+        {     9,      9,      6,     16,      1,      5,      6,      3,     11,     10, }, // left_mode 3
+        {    10,      3,      1,      3,     10,      1,      0,      1,      1,      4, }, // left_mode 4
+        {    14,      6,     15,      5,      1,     20,     25,      2,      5,      0, }, // left_mode 5
+        {    28,      7,     51,      1,      0,      8,    127,      6,      2,      5, }, // left_mode 6
+        {    13,      3,      3,      2,      3,      1,      2,      8,      1,      2, }, // left_mode 7
+        {    10,      3,      3,      3,      3,      8,      2,      2,      9,      3, }, // left_mode 8
+        {    13,      7,     11,      4,      0,      4,      6,      2,      5,      8, }, // left_mode 9
+    },
+    {
+        //Above Mode :  7
+        {   376,    135,    119,      6,     32,      8,     31,    224,      9,      3, }, // left_mode 0
+        {    93,     60,     54,      6,     13,      7,      8,     92,      2,     12, }, // left_mode 1
+        {    74,     36,     84,      0,      3,      2,      9,     67,      2,      1, }, // left_mode 2
+        {    19,      4,      4,      8,      8,      2,      4,      7,      6,     16, }, // left_mode 3
+        {    51,      7,      4,      1,     77,      3,      0,     14,      1,     15, }, // left_mode 4
+        {     7,      7,      5,      7,      4,      7,      4,      5,      0,      3, }, // left_mode 5
+        {    18,      2,     19,      2,      2,      4,     12,     11,      1,      2, }, // left_mode 6
+        {   129,      6,     27,      1,     21,      3,      0,    189,      0,      6, }, // left_mode 7
+        {     9,      1,      2,      8,      3,      7,      0,      5,      3,      3, }, // left_mode 8
+        {    20,      4,      5,     10,      4,      2,      7,     17,      3,     16, }, // left_mode 9
+    },
+    {
+        //Above Mode :  8
+        {   617,     68,     34,     79,     11,     27,     25,     14,     75,     13, }, // left_mode 0
+        {    51,     82,     21,     26,      6,     12,     13,      1,     26,     16, }, // left_mode 1
+        {    29,      9,     12,     11,      3,      7,      1,     10,      2,      2, }, // left_mode 2
+        {    17,     19,     11,     74,      4,      3,      2,      0,     58,     13, }, // left_mode 3
+        {    10,      1,      1,      3,      4,      1,      0,      2,      1,      8, }, // left_mode 4
+        {    14,      4,      5,      5,      1,     13,      2,      0,     27,      8, }, // left_mode 5
+        {    10,      3,      5,      4,      1,      7,      6,      4,      5,      1, }, // left_mode 6
+        {    10,      2,      6,      2,      1,      1,      1,      4,      2,      1, }, // left_mode 7
+        {    14,      8,      5,     23,      2,     12,      6,      2,    117,      5, }, // left_mode 8
+        {     9,      6,      2,     19,      1,      6,      3,      2,      9,      9, }, // left_mode 9
+    },
+    {
+        //Above Mode :  9
+        {   680,     73,     22,     38,     42,      5,     11,      9,      6,     28, }, // left_mode 0
+        {   113,    112,     21,     22,     10,      2,      8,      4,      6,     42, }, // left_mode 1
+        {    44,     20,     24,      6,      5,      4,      3,      3,      1,      2, }, // left_mode 2
+        {    40,     23,      7,     71,      5,      2,      4,      1,      7,     22, }, // left_mode 3
+        {    85,      9,      4,      4,     17,      2,      0,      3,      2,     23, }, // left_mode 4
+        {    13,      4,      2,      6,      1,      7,      0,      1,      7,      6, }, // left_mode 5
+        {    26,      6,      8,      3,      2,      3,      8,      1,      5,      4, }, // left_mode 6
+        {    54,      8,      9,      6,      7,      0,      1,     11,      1,      3, }, // left_mode 7
+        {     9,     10,      4,     13,      2,      5,      4,      2,     14,      8, }, // left_mode 8
+        {    92,      9,      5,     19,     15,      3,      3,      1,      6,     58, }, // left_mode 9
+    },
+};
diff --git a/vp8/common/mv.h b/vp8/common/mv.h
new file mode 100644 (file)
index 0000000..3d84181
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_MV_H
+#define __INC_MV_H
+
+typedef struct
+{
+    short row;
+    short col;
+} MV;
+
+#endif
diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h
new file mode 100644 (file)
index 0000000..b66c400
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_VP8_H
+#define __INC_VP8_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "vpx_codec/internal/vpx_codec_internal.h"
+#include "vpx_scale/yv12config.h"
+#include "type_aliases.h"
+#include "ppflags.h"
+    typedef int *VP8_PTR;
+
+    /* Create/destroy static data structures. */
+
+    typedef enum
+    {
+        NORMAL      = 0,
+        FOURFIVE    = 1,
+        THREEFIVE   = 2,
+        ONETWO      = 3
+
+    } VPX_SCALING;
+
+    typedef enum
+    {
+        VP8_LAST_FLAG = 1,
+        VP8_GOLD_FLAG = 2,
+        VP8_ALT_FLAG = 4
+    } VP8_REFFRAME;
+
+
+    typedef enum
+    {
+        USAGE_STREAM_FROM_SERVER    = 0x0,
+        USAGE_LOCAL_FILE_PLAYBACK   = 0x1
+    } END_USAGE;
+
+
+    typedef enum
+    {
+        MODE_REALTIME       = 0x0,
+        MODE_GOODQUALITY    = 0x1,
+        MODE_BESTQUALITY    = 0x2,
+        MODE_FIRSTPASS      = 0x3,
+        MODE_SECONDPASS     = 0x4,
+        MODE_SECONDPASS_BEST = 0x5,
+    } MODE;
+
+    typedef enum
+    {
+        FRAMEFLAGS_KEY    = 1,
+        FRAMEFLAGS_GOLDEN = 2,
+        FRAMEFLAGS_ALTREF = 4,
+    } FRAMETYPE_FLAGS;
+
+
+#include <assert.h>
+    static __inline void Scale2Ratio(int mode, int *hr, int *hs)
+    {
+        switch (mode)
+        {
+        case    NORMAL:
+            *hr = 1;
+            *hs = 1;
+            break;
+        case    FOURFIVE:
+            *hr = 4;
+            *hs = 5;
+            break;
+        case    THREEFIVE:
+            *hr = 3;
+            *hs = 5;
+            break;
+        case    ONETWO:
+            *hr = 1;
+            *hs = 2;
+            break;
+        default:
+            *hr = 1;
+            *hs = 1;
+            assert(0);
+            break;
+        }
+    }
+
+    typedef struct
+    {
+        int Version;            // 4 versions of bitstream defined 0 best quality/slowest decode, 3 lowest quality/fastest decode
+        int Width;              // width of data passed to the compressor
+        int Height;             // height of data passed to the compressor
+        double frame_rate;       // set to passed in framerate
+        int target_bandwidth;    // bandwidth to be used in kilobits per second
+
+        int noise_sensitivity;   // parameter used for applying pre processing blur: recommendation 0
+        int Sharpness;          // parameter used for sharpening output: recommendation 0:
+        int cpu_used;
+
+        // mode ->
+        //(0)=Realtime/Live Encoding. This mode is optimized for realtim encoding (for example, capturing
+        //    a television signal or feed from a live camera). ( speed setting controls how fast )
+        //(1)=Good Quality Fast Encoding. The encoder balances quality with the amount of time it takes to
+        //    encode the output. ( speed setting controls how fast )
+        //(2)=One Pass - Best Quality. The encoder places priority on the quality of the output over encoding
+        //    speed. The output is compressed at the highest possible quality. This option takes the longest
+        //    amount of time to encode. ( speed setting ignored )
+        //(3)=Two Pass - First Pass. The encoder generates a file of statistics for use in the second encoding
+        //    pass. ( speed setting controls how fast )
+        //(4)=Two Pass - Second Pass. The encoder uses the statistics that were generated in the first encoding
+        //    pass to create the compressed output. ( speed setting controls how fast )
+        //(5)=Two Pass - Second Pass Best.  The encoder uses the statistics that were generated in the first
+        //    encoding pass to create the compressed output using the highest possible quality, and taking a
+        //    longer amount of time to encode.. ( speed setting ignored )
+        int Mode;               //
+
+        // Key Framing Operations
+        int auto_key;            // automatically detect cut scenes and set the keyframes
+        int key_freq;            // maximum distance to key frame.
+
+        int allow_lag;           // allow lagged compression (if 0 lagin frames is ignored)
+        int lag_in_frames;        // how many frames lag before we start encoding
+
+        //----------------------------------------------------------------
+        // DATARATE CONTROL OPTIONS
+
+        int end_usage; // vbr or cbr
+
+        // shoot to keep buffer full at all times by undershooting a bit 95 recommended
+        int under_shoot_pct;
+
+        // buffering parameters
+        int starting_buffer_level;  // in seconds
+        int optimal_buffer_level;
+        int maximum_buffer_size;
+
+        // controlling quality
+        int fixed_q;
+        int worst_allowed_q;
+        int best_allowed_q;
+
+        // allow internal resizing ( currently disabled in the build !!!!!)
+        int allow_spatial_resampling;
+        int resample_down_water_mark;
+        int resample_up_water_mark;
+
+        // allow internal frame rate alterations
+        int allow_df;
+        int drop_frames_water_mark;
+
+        // two pass datarate control
+        int two_pass_vbrbias;        // two pass datarate control tweaks
+        int two_pass_vbrmin_section;
+        int two_pass_vbrmax_section;
+        // END DATARATE CONTROL OPTIONS
+        //----------------------------------------------------------------
+
+
+        // these parameters aren't to be used in final build don't use!!!
+        int play_alternate;
+        int alt_freq;
+        int alt_q;
+        int key_q;
+        int gold_q;
+
+
+        int multi_threaded;   // how many threads to run the encoder on
+        int token_partitions; // how many token partitions to create for multi core decoding
+        int encode_breakout;  // early breakout encode threshold : for video conf recommend 800
+
+        int error_resilient_mode;  // if running over udp networks provides decodable frames after a
+        // dropped packet
+
+        int arnr_max_frames;
+        int arnr_strength ;
+        int arnr_type     ;
+
+
+        struct vpx_fixed_buf         two_pass_stats_in;
+        struct vpx_codec_pkt_list  *output_pkt_list;
+    } VP8_CONFIG;
+
+
+    void vp8_initialize();
+
+    VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf);
+    void vp8_remove_compressor(VP8_PTR *comp);
+
+    void vp8_init_config(VP8_PTR onyx, VP8_CONFIG *oxcf);
+    void vp8_change_config(VP8_PTR onyx, VP8_CONFIG *oxcf);
+
+// receive a frames worth of data caller can assume that a copy of this frame is made
+// and not just a copy of the pointer..
+    int vp8_receive_raw_frame(VP8_PTR comp, unsigned int frame_flags, YV12_BUFFER_CONFIG *sd, INT64 time_stamp, INT64 end_time_stamp);
+    int vp8_get_compressed_data(VP8_PTR comp, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, INT64 *time_stamp, INT64 *time_end, int flush);
+    int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags);
+
+    int vp8_use_as_reference(VP8_PTR comp, int ref_frame_flags);
+    int vp8_update_reference(VP8_PTR comp, int ref_frame_flags);
+    int vp8_get_reference(VP8_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    int vp8_set_reference(VP8_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    int vp8_update_entropy(VP8_PTR comp, int update);
+    int vp8_set_roimap(VP8_PTR comp, unsigned char *map, unsigned int rows, unsigned int cols, int delta_q[4], int delta_lf[4], unsigned int threshold[4]);
+    int vp8_set_active_map(VP8_PTR comp, unsigned char *map, unsigned int rows, unsigned int cols);
+    int vp8_set_internal_size(VP8_PTR comp, VPX_SCALING horiz_mode, VPX_SCALING vert_mode);
+    int vp8_get_quantizer(VP8_PTR c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
new file mode 100644 (file)
index 0000000..a40ffb9
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_VP8C_INT_H
+#define __INC_VP8C_INT_H
+
+#include "vpx_ports/config.h"
+#include "vpx_codec/internal/vpx_codec_internal.h"
+#include "loopfilter.h"
+#include "entropymv.h"
+#include "entropy.h"
+#include "idct.h"
+#include "recon.h"
+#include "postproc.h"
+
+//#ifdef PACKET_TESTING
+#include "header.h"
+//#endif
+
+/* Create/destroy static data structures. */
+
+void vp8_initialize_common(void);
+
+#define MINQ 0
+#define MAXQ 127
+#define QINDEX_RANGE (MAXQ + 1)
+
+
+typedef struct frame_contexts
+{
+    vp8_prob bmode_prob [VP8_BINTRAMODES-1];
+    vp8_prob ymode_prob [VP8_YMODES-1];   /* interframe intra mode probs */
+    vp8_prob uv_mode_prob [VP8_UV_MODES-1];
+    vp8_prob sub_mv_ref_prob [VP8_SUBMVREFS-1];
+    vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
+    MV_CONTEXT mvc[2];
+    MV_CONTEXT pre_mvc[2];  //not to caculate the mvcost for the frame if mvc doesn't change.
+} FRAME_CONTEXT;
+
+typedef enum
+{
+    ONE_PARTITION  = 0,
+    TWO_PARTITION  = 1,
+    FOUR_PARTITION = 2,
+    EIGHT_PARTITION = 3
+} TOKEN_PARTITION;
+
+typedef enum
+{
+    RECON_CLAMP_REQUIRED        = 0,
+    RECON_CLAMP_NOTREQUIRED     = 1
+} CLAMP_TYPE;
+
+typedef enum
+{
+    SIXTAP   = 0,
+    BILINEAR = 1
+} INTERPOLATIONFILTERTYPE;
+
+typedef struct VP8_COMMON_RTCD
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    vp8_idct_rtcd_vtable_t        idct;
+    vp8_recon_rtcd_vtable_t       recon;
+    vp8_subpix_rtcd_vtable_t      subpix;
+    vp8_loopfilter_rtcd_vtable_t  loopfilter;
+    vp8_postproc_rtcd_vtable_t    postproc;
+#else
+    int unused;
+#endif
+} VP8_COMMON_RTCD;
+
+typedef struct VP8Common
+{
+    struct vpx_internal_error_info  error;
+
+    DECLARE_ALIGNED(16, short, Y1dequant[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, Y2dequant[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, UVdequant[QINDEX_RANGE][4][4]);
+
+    int Width;
+    int Height;
+    int horiz_scale;
+    int vert_scale;
+
+    YUV_TYPE clr_type;
+    CLAMP_TYPE  clamp_type;
+
+    YV12_BUFFER_CONFIG last_frame;
+    YV12_BUFFER_CONFIG golden_frame;
+    YV12_BUFFER_CONFIG alt_ref_frame;
+    YV12_BUFFER_CONFIG new_frame;
+    YV12_BUFFER_CONFIG *frame_to_show;
+    YV12_BUFFER_CONFIG post_proc_buffer;
+    YV12_BUFFER_CONFIG temp_scale_frame;
+
+    FRAME_TYPE last_frame_type;  //Add to check if vp8_frame_init_loop_filter() can be skiped.
+    FRAME_TYPE frame_type;
+
+    int show_frame;
+
+    int frame_flags;
+    int MBs;
+    int mb_rows;
+    int mb_cols;
+    int mode_info_stride;
+
+    // prfile settings
+    int mb_no_coeff_skip;
+    int no_lpf;
+    int simpler_lpf;
+    int use_bilinear_mc_filter;
+    int full_pixel;
+
+    int base_qindex;
+    int last_kf_gf_q;  // Q used on the last GF or KF
+
+    int y1dc_delta_q;
+    int y2dc_delta_q;
+    int y2ac_delta_q;
+    int uvdc_delta_q;
+    int uvac_delta_q;
+
+    unsigned int frames_since_golden;
+    unsigned int frames_till_alt_ref_frame;
+    unsigned char *gf_active_flags;   // Record of which MBs still refer to last golden frame either directly or through 0,0
+    int gf_active_count;
+
+    /* We allocate a MODE_INFO struct for each macroblock, together with
+       an extra row on top and column on the left to simplify prediction. */
+
+    MODE_INFO *mip; /* Base of allocated array */
+    MODE_INFO *mi;  /* Corresponds to upper left visible macroblock */
+
+
+    INTERPOLATIONFILTERTYPE mcomp_filter_type;
+    LOOPFILTERTYPE last_filter_type;
+    LOOPFILTERTYPE filter_type;
+    loop_filter_info lf_info[MAX_LOOP_FILTER+1];
+    prototype_loopfilter_block((*lf_mbv));
+    prototype_loopfilter_block((*lf_mbh));
+    prototype_loopfilter_block((*lf_bv));
+    prototype_loopfilter_block((*lf_bh));
+    int filter_level;
+    int last_sharpness_level;
+    int sharpness_level;
+
+    int refresh_last_frame;       // Two state 0 = NO, 1 = YES
+    int refresh_golden_frame;     // Two state 0 = NO, 1 = YES
+    int refresh_alt_ref_frame;     // Two state 0 = NO, 1 = YES
+
+    int copy_buffer_to_gf;         // 0 none, 1 Last to GF, 2 ARF to GF
+    int copy_buffer_to_arf;        // 0 none, 1 Last to ARF, 2 GF to ARF
+
+    int refresh_entropy_probs;    // Two state 0 = NO, 1 = YES
+
+    int ref_frame_sign_bias[MAX_REF_FRAMES];    // Two state 0, 1
+
+    // Y,U,V,Y2
+    ENTROPY_CONTEXT *above_context[4];   // row of context for each plane
+    ENTROPY_CONTEXT left_context[4][4];  // (up to) 4 contexts ""
+
+
+    // keyframe block modes are predicted by their above, left neighbors
+
+    vp8_prob kf_bmode_prob [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1];
+    vp8_prob kf_ymode_prob [VP8_YMODES-1];  /* keyframe "" */
+    vp8_prob kf_uv_mode_prob [VP8_UV_MODES-1];
+
+
+    FRAME_CONTEXT lfc; // last frame entropy
+    FRAME_CONTEXT fc;  // this frame entropy
+
+    unsigned int current_video_frame;
+
+    int near_boffset[3];
+    int version;
+
+    TOKEN_PARTITION multi_token_partition;
+
+#ifdef PACKET_TESTING
+    VP8_HEADER oh;
+#endif
+    double bitrate;
+    double framerate;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+    VP8_COMMON_RTCD rtcd;
+#endif
+    struct postproc_state  postproc_state;
+} VP8_COMMON;
+
+
+void vp8_adjust_mb_lf_value(MACROBLOCKD *mbd, int *filter_level);
+void vp8_init_loop_filter(VP8_COMMON *cm);
+extern void vp8_loop_filter_frame(VP8_COMMON *cm,    MACROBLOCKD *mbd,  int filt_val);
+
+#endif
diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h
new file mode 100644 (file)
index 0000000..644c0ec
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_VP8D_H
+#define __INC_VP8D_H
+
+
+/* Create/destroy static data structures. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "type_aliases.h"
+#include "vpx_scale/yv12config.h"
+#include "ppflags.h"
+#include "vpx_ports/mem.h"
+
+    typedef void   *VP8D_PTR;
+    typedef struct
+    {
+        int     Width;
+        int     Height;
+        int     Version;
+        int     postprocess;
+        int     max_threads;
+    } VP8D_CONFIG;
+    typedef enum
+    {
+        VP8_LAST_FLAG = 1,
+        VP8_GOLD_FLAG = 2,
+        VP8_ALT_FLAG = 4
+    } VP8_REFFRAME;
+
+    typedef enum
+    {
+        VP8D_OK = 0
+    } VP8D_SETTING;
+
+    void vp8dx_initialize(void);
+
+    void vp8dx_set_setting(VP8D_PTR comp, VP8D_SETTING oxst, int x);
+
+    int vp8dx_get_setting(VP8D_PTR comp, VP8D_SETTING oxst);
+
+    int vp8dx_receive_compressed_data(VP8D_PTR comp, unsigned long size, const unsigned char *dest, INT64 time_stamp);
+    int vp8dx_get_raw_frame(VP8D_PTR comp, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level,  int noise_level, int flags);
+
+    int vp8dx_get_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    int vp8dx_set_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+
+    VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf);
+
+    void vp8dx_remove_decompressor(VP8D_PTR comp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/vp8/common/partialgfupdate.h b/vp8/common/partialgfupdate.h
new file mode 100644 (file)
index 0000000..32a55ee
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_PARTIALGFUPDATE_H
+#define __INC_PARTIALGFUPDATE_H
+
+#include "onyxc_int.h"
+
+extern void update_gf_selective(ONYX_COMMON *cm, MACROBLOCKD *x);
+
+#endif
diff --git a/vp8/common/postproc.c b/vp8/common/postproc.c
new file mode 100644 (file)
index 0000000..f019925
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "vpx_scale/yv12config.h"
+#include "postproc.h"
+#include "vpx_scale/yv12extend.h"
+#include "vpx_scale/vpxscale.h"
+#include "systemdependent.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+// global constants
+
+static const short kernel5[] =
+{
+    1, 1, 4, 1, 1
+};
+
+const short vp8_rv[] =
+{
+    8, 5, 2, 2, 8, 12, 4, 9, 8, 3,
+    0, 3, 9, 0, 0, 0, 8, 3, 14, 4,
+    10, 1, 11, 14, 1, 14, 9, 6, 12, 11,
+    8, 6, 10, 0, 0, 8, 9, 0, 3, 14,
+    8, 11, 13, 4, 2, 9, 0, 3, 9, 6,
+    1, 2, 3, 14, 13, 1, 8, 2, 9, 7,
+    3, 3, 1, 13, 13, 6, 6, 5, 2, 7,
+    11, 9, 11, 8, 7, 3, 2, 0, 13, 13,
+    14, 4, 12, 5, 12, 10, 8, 10, 13, 10,
+    4, 14, 4, 10, 0, 8, 11, 1, 13, 7,
+    7, 14, 6, 14, 13, 2, 13, 5, 4, 4,
+    0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
+    8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
+    3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
+    3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
+    13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
+    5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
+    9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
+    4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
+    3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
+    11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
+    5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
+    0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
+    10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
+    4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
+    0, 10, 0, 5, 13, 2, 12, 7, 11, 13,
+    8, 0, 4, 10, 7, 2, 7, 2, 2, 5,
+    3, 4, 7, 3, 3, 14, 14, 5, 9, 13,
+    3, 14, 3, 6, 3, 0, 11, 8, 13, 1,
+    13, 1, 12, 0, 10, 9, 7, 6, 2, 8,
+    5, 2, 13, 7, 1, 13, 14, 7, 6, 7,
+    9, 6, 10, 11, 7, 8, 7, 5, 14, 8,
+    4, 4, 0, 8, 7, 10, 0, 8, 14, 11,
+    3, 12, 5, 7, 14, 3, 14, 5, 2, 6,
+    11, 12, 12, 8, 0, 11, 13, 1, 2, 0,
+    5, 10, 14, 7, 8, 0, 4, 11, 0, 8,
+    0, 3, 10, 5, 8, 0, 11, 6, 7, 8,
+    10, 7, 13, 9, 2, 5, 1, 5, 10, 2,
+    4, 3, 5, 6, 10, 8, 9, 4, 11, 14,
+    3, 8, 3, 7, 8, 5, 11, 4, 12, 3,
+    11, 9, 14, 8, 14, 13, 4, 3, 1, 2,
+    14, 6, 5, 4, 4, 11, 4, 6, 2, 1,
+    5, 8, 8, 12, 13, 5, 14, 10, 12, 13,
+    0, 9, 5, 5, 11, 10, 13, 9, 10, 13,
+};
+
+
+extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch);
+
+/***********************************************************************************************************
+ */
+void vp8_post_proc_down_and_across_c
+(
+    unsigned char *src_ptr,
+    unsigned char *dst_ptr,
+    int src_pixels_per_line,
+    int dst_pixels_per_line,
+    int rows,
+    int cols,
+    int flimit
+)
+{
+    unsigned char *p_src, *p_dst;
+    int row;
+    int col;
+    int i;
+    int v;
+    int pitch = src_pixels_per_line;
+    unsigned char d[8];
+    (void)dst_pixels_per_line;
+
+    for (row = 0; row < rows; row++)
+    {
+        // post_proc_down for one row
+        p_src = src_ptr;
+        p_dst = dst_ptr;
+
+        for (col = 0; col < cols; col++)
+        {
+
+            int kernel = 4;
+            int v = p_src[col];
+
+            for (i = -2; i <= 2; i++)
+            {
+                if (abs(v - p_src[col+i*pitch]) > flimit)
+                    goto down_skip_convolve;
+
+                kernel += kernel5[2+i] * p_src[col+i*pitch];
+            }
+
+            v = (kernel >> 3);
+        down_skip_convolve:
+            p_dst[col] = v;
+        }
+
+        // now post_proc_across
+        p_src = dst_ptr;
+        p_dst = dst_ptr;
+
+        for (i = 0; i < 8; i++)
+            d[i] = p_src[i];
+
+        for (col = 0; col < cols; col++)
+        {
+            int kernel = 4;
+            v = p_src[col];
+
+            d[col&7] = v;
+
+            for (i = -2; i <= 2; i++)
+            {
+                if (abs(v - p_src[col+i]) > flimit)
+                    goto across_skip_convolve;
+
+                kernel += kernel5[2+i] * p_src[col+i];
+            }
+
+            d[col&7] = (kernel >> 3);
+        across_skip_convolve:
+
+            if (col >= 2)
+                p_dst[col-2] = d[(col-2)&7];
+        }
+
+        //handle the last two pixels
+        p_dst[col-2] = d[(col-2)&7];
+        p_dst[col-1] = d[(col-1)&7];
+
+
+        //next row
+        src_ptr += pitch;
+        dst_ptr += pitch;
+    }
+}
+
+int vp8_q2mbl(int x)
+{
+    if (x < 20) x = 20;
+
+    x = 50 + (x - 50) * 10 / 8;
+    return x * x / 3;
+}
+void vp8_mbpost_proc_across_ip_c(unsigned char *src, int pitch, int rows, int cols, int flimit)
+{
+    int r, c, i;
+
+    unsigned char *s = src;
+    unsigned char d[16];
+
+
+    for (r = 0; r < rows; r++)
+    {
+        int sumsq = 0;
+        int sum   = 0;
+
+        for (i = -8; i <= 6; i++)
+        {
+            sumsq += s[i] * s[i];
+            sum   += s[i];
+            d[i+8] = 0;
+        }
+
+        for (c = 0; c < cols + 8; c++)
+        {
+            int x = s[c+7] - s[c-8];
+            int y = s[c+7] + s[c-8];
+
+            sum  += x;
+            sumsq += x * y;
+
+            d[c&15] = s[c];
+
+            if (sumsq * 15 - sum * sum < flimit)
+            {
+                d[c&15] = (8 + sum + s[c]) >> 4;
+            }
+
+            s[c-8] = d[(c-8)&15];
+        }
+
+        s += pitch;
+    }
+}
+
+
+
+
+
+void vp8_mbpost_proc_down_c(unsigned char *dst, int pitch, int rows, int cols, int flimit)
+{
+    int r, c, i;
+    const short *rv3 = &vp8_rv[63&rand()];
+
+    for (c = 0; c < cols; c++)
+    {
+        unsigned char *s = &dst[c];
+        int sumsq = 0;
+        int sum   = 0;
+        unsigned char d[16];
+        const short *rv2 = rv3 + ((c * 17) & 127);
+
+        for (i = -8; i <= 6; i++)
+        {
+            sumsq += s[i*pitch] * s[i*pitch];
+            sum   += s[i*pitch];
+        }
+
+        for (r = 0; r < rows + 8; r++)
+        {
+            sumsq += s[7*pitch] * s[ 7*pitch] - s[-8*pitch] * s[-8*pitch];
+            sum  += s[7*pitch] - s[-8*pitch];
+            d[r&15] = s[0];
+
+            if (sumsq * 15 - sum * sum < flimit)
+            {
+                d[r&15] = (rv2[r&127] + sum + s[0]) >> 4;
+            }
+
+            s[-8*pitch] = d[(r-8)&15];
+            s += pitch;
+        }
+    }
+}
+
+
+static void vp8_deblock_and_de_macro_block(YV12_BUFFER_CONFIG         *source,
+        YV12_BUFFER_CONFIG         *post,
+        int                         q,
+        int                         low_var_thresh,
+        int                         flag,
+        vp8_postproc_rtcd_vtable_t *rtcd)
+{
+    double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
+    int ppl = (int)(level + .5);
+    (void) low_var_thresh;
+    (void) flag;
+
+    POSTPROC_INVOKE(rtcd, downacross)(source->y_buffer, post->y_buffer, source->y_stride,  post->y_stride, source->y_height, source->y_width,  ppl);
+    POSTPROC_INVOKE(rtcd, across)(post->y_buffer, post->y_stride, post->y_height, post->y_width, vp8_q2mbl(q));
+    POSTPROC_INVOKE(rtcd, down)(post->y_buffer, post->y_stride, post->y_height, post->y_width, vp8_q2mbl(q));
+
+    POSTPROC_INVOKE(rtcd, downacross)(source->u_buffer, post->u_buffer, source->uv_stride, post->uv_stride, source->uv_height, source->uv_width, ppl);
+    POSTPROC_INVOKE(rtcd, downacross)(source->v_buffer, post->v_buffer, source->uv_stride, post->uv_stride, source->uv_height, source->uv_width, ppl);
+
+}
+
+extern void vp8_deblock(YV12_BUFFER_CONFIG         *source,
+                        YV12_BUFFER_CONFIG         *post,
+                        int                         q,
+                        int                         low_var_thresh,
+                        int                         flag,
+                        vp8_postproc_rtcd_vtable_t *rtcd)
+{
+    double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
+    int ppl = (int)(level + .5);
+    (void) low_var_thresh;
+    (void) flag;
+
+    POSTPROC_INVOKE(rtcd, downacross)(source->y_buffer, post->y_buffer, source->y_stride,  post->y_stride, source->y_height, source->y_width,   ppl);
+    POSTPROC_INVOKE(rtcd, downacross)(source->u_buffer, post->u_buffer, source->uv_stride, post->uv_stride,  source->uv_height, source->uv_width, ppl);
+    POSTPROC_INVOKE(rtcd, downacross)(source->v_buffer, post->v_buffer, source->uv_stride, post->uv_stride, source->uv_height, source->uv_width, ppl);
+}
+
+void vp8_de_noise(YV12_BUFFER_CONFIG         *source,
+                  YV12_BUFFER_CONFIG         *post,
+                  int                         q,
+                  int                         low_var_thresh,
+                  int                         flag,
+                  vp8_postproc_rtcd_vtable_t *rtcd)
+{
+    double level = 6.0e-05 * q * q * q - .0067 * q * q + .306 * q + .0065;
+    int ppl = (int)(level + .5);
+    (void) post;
+    (void) low_var_thresh;
+    (void) flag;
+
+    POSTPROC_INVOKE(rtcd, downacross)(
+        source->y_buffer + 2 * source->y_stride + 2,
+        source->y_buffer + 2 * source->y_stride + 2,
+        source->y_stride,
+        source->y_stride,
+        source->y_height - 4,
+        source->y_width - 4,
+        ppl);
+    POSTPROC_INVOKE(rtcd, downacross)(
+        source->u_buffer + 2 * source->uv_stride + 2,
+        source->u_buffer + 2 * source->uv_stride + 2,
+        source->uv_stride,
+        source->uv_stride,
+        source->uv_height - 4,
+        source->uv_width - 4, ppl);
+    POSTPROC_INVOKE(rtcd, downacross)(
+        source->v_buffer + 2 * source->uv_stride + 2,
+        source->v_buffer + 2 * source->uv_stride + 2,
+        source->uv_stride,
+        source->uv_stride,
+        source->uv_height - 4,
+        source->uv_width - 4, ppl);
+
+}
+
+
+//Notes: It is better to change CHAR to unsigned or signed to
+//avoid error on ARM platform.
+char vp8_an[8][64][3072];
+int vp8_cd[8][64];
+
+
+double vp8_gaussian(double sigma, double mu, double x)
+{
+    return 1 / (sigma * sqrt(2.0 * 3.14159265)) *
+           (exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)));
+}
+
+extern void (*vp8_clear_system_state)(void);
+
+
+static void fillrd(struct postproc_state *state, int q, int a)
+{
+    char char_dist[300];
+
+    double sigma;
+    int ai = a, qi = q, i;
+
+    vp8_clear_system_state();
+
+
+    sigma = ai + .5 + .6 * (63 - qi) / 63.0;
+
+    // set up a lookup table of 256 entries that matches
+    // a gaussian distribution with sigma determined by q.
+    //
+    {
+        double i;
+        int next, j;
+
+        next = 0;
+
+        for (i = -32; i < 32; i++)
+        {
+            int a = (int)(.5 + 256 * vp8_gaussian(sigma, 0, i));
+
+            if (a)
+            {
+                for (j = 0; j < a; j++)
+                {
+                    char_dist[next+j] = (char) i;
+                }
+
+                next = next + j;
+            }
+
+        }
+
+        for (next = next; next < 256; next++)
+            char_dist[next] = 0;
+
+    }
+
+    for (i = 0; i < 3072; i++)
+    {
+        state->noise[i] = char_dist[rand() & 0xff];
+    }
+
+    for (i = 0; i < 16; i++)
+    {
+        state->blackclamp[i] = -char_dist[0];
+        state->whiteclamp[i] = -char_dist[0];
+        state->bothclamp[i] = -2 * char_dist[0];
+    }
+
+    state->last_q = q;
+    state->last_noise = a;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : plane_add_noise_c
+ *
+ *  INPUTS        : unsigned char *Start    starting address of buffer to add gaussian
+ *                                  noise to
+ *                  unsigned int Width    width of plane
+ *                  unsigned int Height   height of plane
+ *                  int  Pitch    distance between subsequent lines of frame
+ *                  int  q        quantizer used to determine amount of noise
+ *                                  to add
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void.
+ *
+ *  FUNCTION      : adds gaussian noise to a plane of pixels
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_plane_add_noise_c(unsigned char *Start, char *noise,
+                           char blackclamp[16],
+                           char whiteclamp[16],
+                           char bothclamp[16],
+                           unsigned int Width, unsigned int Height, int Pitch)
+{
+    unsigned int i, j;
+
+    for (i = 0; i < Height; i++)
+    {
+        unsigned char *Pos = Start + i * Pitch;
+        char  *Ref = (char *)(noise + (rand() & 0xff));
+
+        for (j = 0; j < Width; j++)
+        {
+            if (Pos[j] < blackclamp[0])
+                Pos[j] = blackclamp[0];
+
+            if (Pos[j] > 255 + whiteclamp[0])
+                Pos[j] = 255 + whiteclamp[0];
+
+            Pos[j] += Ref[j];
+        }
+    }
+}
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define RTCD_VTABLE(oci) (&(oci)->rtcd.postproc)
+#else
+#define RTCD_VTABLE(oci) NULL
+#endif
+
+int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags)
+{
+    char message[512];
+    int q = oci->filter_level * 10 / 6;
+
+    if (!oci->frame_to_show)
+        return -1;
+
+    if (q > 63)
+        q = 63;
+
+    if (!flags)
+    {
+        *dest = *oci->frame_to_show;
+
+        // handle problem with extending borders
+        dest->y_width = oci->Width;
+        dest->y_height = oci->Height;
+        dest->uv_height = dest->y_height / 2;
+        return 0;
+
+    }
+
+#if ARCH_X86||ARCH_X86_64
+    vpx_reset_mmx_state();
+#endif
+
+    if (flags & VP8D_DEMACROBLOCK)
+    {
+        vp8_deblock_and_de_macro_block(oci->frame_to_show, &oci->post_proc_buffer,
+                                       q + (deblock_level - 5) * 10, 1, 0, RTCD_VTABLE(oci));
+    }
+    else if (flags & VP8D_DEBLOCK)
+    {
+        vp8_deblock(oci->frame_to_show, &oci->post_proc_buffer,
+                    q, 1, 0, RTCD_VTABLE(oci));
+    }
+    else
+    {
+        vp8_yv12_copy_frame_ptr(oci->frame_to_show, &oci->post_proc_buffer);
+    }
+
+    if (flags & VP8D_ADDNOISE)
+    {
+        if (oci->postproc_state.last_q != q
+            || oci->postproc_state.last_noise != noise_level)
+        {
+            fillrd(&oci->postproc_state, 63 - q, noise_level);
+        }
+
+        POSTPROC_INVOKE(RTCD_VTABLE(oci), addnoise)
+        (oci->post_proc_buffer.y_buffer,
+         oci->postproc_state.noise,
+         oci->postproc_state.blackclamp,
+         oci->postproc_state.whiteclamp,
+         oci->postproc_state.bothclamp,
+         oci->post_proc_buffer.y_width, oci->post_proc_buffer.y_height,
+         oci->post_proc_buffer.y_stride);
+    }
+
+    if (flags & VP8D_DEBUG_LEVEL1)
+    {
+        sprintf(message, "F%1dG%1dQ%3dF%3dP%d_s%dx%d",
+                (oci->frame_type == KEY_FRAME),
+                oci->refresh_golden_frame,
+                oci->base_qindex,
+                oci->filter_level,
+                flags,
+                oci->mb_cols, oci->mb_rows);
+        vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride);
+    }
+    else if (flags & VP8D_DEBUG_LEVEL2)
+    {
+        int i, j;
+        unsigned char *y_ptr;
+        YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
+        int mb_rows = post->y_height >> 4;
+        int mb_cols = post->y_width  >> 4;
+        int mb_index = 0;
+        MODE_INFO *mi = oci->mi;
+
+        y_ptr = post->y_buffer + 4 * post->y_stride + 4;
+
+        // vp8_filter each macro block
+        for (i = 0; i < mb_rows; i++)
+        {
+            for (j = 0; j < mb_cols; j++)
+            {
+                char zz[4];
+
+                sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
+
+                vp8_blit_text(zz, y_ptr, post->y_stride);
+                mb_index ++;
+                y_ptr += 16;
+            }
+
+            mb_index ++; //border
+            y_ptr += post->y_stride  * 16 - post->y_width;
+
+        }
+    }
+    else if (flags & VP8D_DEBUG_LEVEL3)
+    {
+        int i, j;
+        unsigned char *y_ptr;
+        YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
+        int mb_rows = post->y_height >> 4;
+        int mb_cols = post->y_width  >> 4;
+        int mb_index = 0;
+        MODE_INFO *mi = oci->mi;
+
+        y_ptr = post->y_buffer + 4 * post->y_stride + 4;
+
+        // vp8_filter each macro block
+        for (i = 0; i < mb_rows; i++)
+        {
+            for (j = 0; j < mb_cols; j++)
+            {
+                char zz[4];
+
+                if (oci->frame_type == KEY_FRAME)
+                    sprintf(zz, "a");
+                else
+                    sprintf(zz, "%c", mi[mb_index].mbmi.dc_diff + '0');
+
+                vp8_blit_text(zz, y_ptr, post->y_stride);
+                mb_index ++;
+                y_ptr += 16;
+            }
+
+            mb_index ++; //border
+            y_ptr += post->y_stride  * 16 - post->y_width;
+
+        }
+    }
+    else if (flags & VP8D_DEBUG_LEVEL4)
+    {
+        sprintf(message, "Bitrate: %10.2f frame_rate: %10.2f ", oci->bitrate, oci->framerate);
+        vp8_blit_text(message, oci->post_proc_buffer.y_buffer, oci->post_proc_buffer.y_stride);
+#if 0
+        int i, j;
+        unsigned char *y_ptr;
+        YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
+        int mb_rows = post->y_height >> 4;
+        int mb_cols = post->y_width  >> 4;
+        int mb_index = 0;
+        MODE_INFO *mi = oci->mi;
+
+        y_ptr = post->y_buffer + 4 * post->y_stride + 4;
+
+        // vp8_filter each macro block
+        for (i = 0; i < mb_rows; i++)
+        {
+            for (j = 0; j < mb_cols; j++)
+            {
+                char zz[4];
+
+                sprintf(zz, "%c", mi[mb_index].mbmi.dc_diff + '0');
+                vp8_blit_text(zz, y_ptr, post->y_stride);
+                mb_index ++;
+                y_ptr += 16;
+            }
+
+            mb_index ++; //border
+            y_ptr += post->y_stride  * 16 - post->y_width;
+
+        }
+
+#endif
+
+    }
+
+
+
+    *dest = oci->post_proc_buffer;
+
+    // handle problem with extending borders
+    dest->y_width = oci->Width;
+    dest->y_height = oci->Height;
+    dest->uv_height = dest->y_height / 2;
+    return 0;
+}
diff --git a/vp8/common/postproc.h b/vp8/common/postproc.h
new file mode 100644 (file)
index 0000000..c45fe92
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef POSTPROC_H
+#define POSTPROC_H
+
+#define prototype_postproc_inplace(sym)\
+    void sym (unsigned char *dst, int pitch, int rows, int cols,int flimit)
+
+#define prototype_postproc(sym)\
+    void sym (unsigned char *src, unsigned char *dst, int src_pitch,\
+              int dst_pitch, int rows, int cols, int flimit)
+
+#define prototype_postproc_addnoise(sym) \
+    void sym (unsigned char *s, char *noise, char blackclamp[16],\
+              char whiteclamp[16], char bothclamp[16],\
+              unsigned int w, unsigned int h, int pitch)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/postproc_x86.h"
+#endif
+
+#ifndef vp8_postproc_down
+#define vp8_postproc_down vp8_mbpost_proc_down_c
+#endif
+extern prototype_postproc_inplace(vp8_postproc_down);
+
+#ifndef vp8_postproc_across
+#define vp8_postproc_across vp8_mbpost_proc_across_ip_c
+#endif
+extern prototype_postproc_inplace(vp8_postproc_across);
+
+#ifndef vp8_postproc_downacross
+#define vp8_postproc_downacross vp8_post_proc_down_and_across_c
+#endif
+extern prototype_postproc(vp8_postproc_downacross);
+
+#ifndef vp8_postproc_addnoise
+#define vp8_postproc_addnoise vp8_plane_add_noise_c
+#endif
+extern prototype_postproc_addnoise(vp8_postproc_addnoise);
+
+
+typedef prototype_postproc((*vp8_postproc_fn_t));
+typedef prototype_postproc_inplace((*vp8_postproc_inplace_fn_t));
+typedef prototype_postproc_addnoise((*vp8_postproc_addnoise_fn_t));
+typedef struct
+{
+    vp8_postproc_inplace_fn_t   down;
+    vp8_postproc_inplace_fn_t   across;
+    vp8_postproc_fn_t           downacross;
+    vp8_postproc_addnoise_fn_t  addnoise;
+} vp8_postproc_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define POSTPROC_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define POSTPROC_INVOKE(ctx,fn) vp8_postproc_##fn
+#endif
+
+#include "vpx_ports/mem.h"
+struct postproc_state
+{
+    int           last_q;
+    int           last_noise;
+    char          noise[3072];
+    DECLARE_ALIGNED(16, char, blackclamp[16]);
+    DECLARE_ALIGNED(16, char, whiteclamp[16]);
+    DECLARE_ALIGNED(16, char, bothclamp[16]);
+};
+#include "onyxc_int.h"
+#include "ppflags.h"
+int vp8_post_proc_frame(struct VP8Common *oci, YV12_BUFFER_CONFIG *dest,
+                        int deblock_level, int noise_level, int flags);
+
+
+void vp8_de_noise(YV12_BUFFER_CONFIG         *source,
+                  YV12_BUFFER_CONFIG         *post,
+                  int                         q,
+                  int                         low_var_thresh,
+                  int                         flag,
+                  vp8_postproc_rtcd_vtable_t *rtcd);
+#endif
diff --git a/vp8/common/ppc/copy_altivec.asm b/vp8/common/ppc/copy_altivec.asm
new file mode 100644 (file)
index 0000000..e87eb21
--- /dev/null
@@ -0,0 +1,46 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl copy_mem16x16_ppc
+
+;# r3 unsigned char *src
+;# r4 int src_stride
+;# r5 unsigned char *dst
+;# r6 int dst_stride
+
+;# Make the assumption that input will not be aligned,
+;#  but the output will be.  So two reads and a perm
+;#  for the input, but only one store for the output.
+copy_mem16x16_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xe000
+    mtspr   256, r12            ;# set VRSAVE
+
+    li      r10, 16
+    mtctr   r10
+
+cp_16x16_loop:
+    lvsl    v0,  0, r3          ;# permutate value for alignment
+
+    lvx     v1,   0, r3
+    lvx     v2, r10, r3
+
+    vperm   v1, v1, v2, v0
+
+    stvx    v1,  0, r5
+
+    add     r3, r3, r4          ;# increment source pointer
+    add     r5, r5, r6          ;# increment destination pointer
+
+    bdnz    cp_16x16_loop
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
diff --git a/vp8/common/ppc/filter_altivec.asm b/vp8/common/ppc/filter_altivec.asm
new file mode 100644 (file)
index 0000000..2a35507
--- /dev/null
@@ -0,0 +1,1012 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl sixtap_predict_ppc
+    .globl sixtap_predict8x4_ppc
+    .globl sixtap_predict8x8_ppc
+    .globl sixtap_predict16x16_ppc
+
+.macro load_c V, LABEL, OFF, R0, R1
+    lis     \R0, \LABEL@ha
+    la      \R1, \LABEL@l(\R0)
+    lvx     \V, \OFF, \R1
+.endm
+
+.macro load_hfilter V0, V1
+    load_c \V0, HFilter, r5, r9, r10
+
+    addi    r5,  r5, 16
+    lvx     \V1, r5, r10
+.endm
+
+;# Vertical filtering
+.macro Vprolog
+    load_c v0, VFilter, r6, r3, r10
+
+    vspltish v5, 8
+    vspltish v6, 3
+    vslh    v6, v5, v6      ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    vspltb  v1, v0, 1
+    vspltb  v2, v0, 2
+    vspltb  v3, v0, 3
+    vspltb  v4, v0, 4
+    vspltb  v5, v0, 5
+    vspltb  v0, v0, 0
+.endm
+
+.macro vpre_load
+    Vprolog
+    li      r10,  16
+    lvx     v10,   0, r9    ;# v10..v14 = first 5 rows
+    lvx     v11, r10, r9
+    addi    r9,   r9, 32
+    lvx     v12,   0, r9
+    lvx     v13, r10, r9
+    addi    r9,   r9, 32
+    lvx     v14,   0, r9
+.endm
+
+.macro Msum Re, Ro, V, T, TMP
+                                ;# (Re,Ro) += (V*T)
+    vmuleub \TMP, \V, \T        ;# trashes v8
+    vadduhm \Re, \Re, \TMP      ;# Re = evens, saturation unnecessary
+    vmuloub \TMP, \V, \T
+    vadduhm \Ro, \Ro, \TMP      ;# Ro = odds
+.endm
+
+.macro vinterp_no_store P0 P1 P2 P3 P4 P5
+    vmuleub  v8, \P0, v0        ;# 64 + 4 positive taps
+    vadduhm v16, v6, v8
+    vmuloub  v8, \P0, v0
+    vadduhm v17, v6, v8
+    Msum v16, v17, \P2, v2, v8
+    Msum v16, v17, \P3, v3, v8
+    Msum v16, v17, \P5, v5, v8
+
+    vmuleub v18, \P1, v1        ;# 2 negative taps
+    vmuloub v19, \P1, v1
+    Msum v18, v19, \P4, v4, v8
+
+    vsubuhs v16, v16, v18       ;# subtract neg from pos
+    vsubuhs v17, v17, v19
+    vsrh    v16, v16, v7        ;# divide by 128
+    vsrh    v17, v17, v7        ;# v16 v17 = evens, odds
+    vmrghh  v18, v16, v17       ;# v18 v19 = 16-bit result in order
+    vmrglh  v19, v16, v17
+    vpkuhus  \P0, v18, v19      ;# P0 = 8-bit result
+.endm
+
+.macro vinterp_no_store_8x8 P0 P1 P2 P3 P4 P5
+    vmuleub v24, \P0, v13       ;# 64 + 4 positive taps
+    vadduhm v21, v20, v24
+    vmuloub v24, \P0, v13
+    vadduhm v22, v20, v24
+    Msum v21, v22, \P2, v15, v25
+    Msum v21, v22, \P3, v16, v25
+    Msum v21, v22, \P5, v18, v25
+
+    vmuleub v23, \P1, v14       ;# 2 negative taps
+    vmuloub v24, \P1, v14
+    Msum v23, v24, \P4, v17, v25
+
+    vsubuhs v21, v21, v23       ;# subtract neg from pos
+    vsubuhs v22, v22, v24
+    vsrh    v21, v21, v19       ;# divide by 128
+    vsrh    v22, v22, v19       ;# v16 v17 = evens, odds
+    vmrghh  v23, v21, v22       ;# v18 v19 = 16-bit result in order
+    vmrglh  v24, v21, v22
+    vpkuhus \P0, v23, v24       ;# P0 = 8-bit result
+.endm
+
+
+.macro Vinterp P0 P1 P2 P3 P4 P5
+    vinterp_no_store \P0, \P1, \P2, \P3, \P4, \P5
+    stvx    \P0, 0, r7
+    add     r7, r7, r8      ;# 33 ops per 16 pels
+.endm
+
+
+.macro luma_v P0, P1, P2, P3, P4, P5
+    addi    r9,   r9, 16        ;# P5 = newest input row
+    lvx     \P5,   0, r9
+    Vinterp \P0, \P1, \P2, \P3, \P4, \P5
+.endm
+
+.macro luma_vtwo
+    luma_v v10, v11, v12, v13, v14, v15
+    luma_v v11, v12, v13, v14, v15, v10
+.endm
+
+.macro luma_vfour
+    luma_vtwo
+    luma_v v12, v13, v14, v15, v10, v11
+    luma_v v13, v14, v15, v10, v11, v12
+.endm
+
+.macro luma_vsix
+    luma_vfour
+    luma_v v14, v15, v10, v11, v12, v13
+    luma_v v15, v10, v11, v12, v13, v14
+.endm
+
+.macro Interp4 R I I4
+    vmsummbm \R, v13, \I, v15
+    vmsummbm \R, v14, \I4, \R
+.endm
+
+.macro Read8x8 VD, RS, RP, increment_counter
+    lvsl    v21,  0, \RS        ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     \VD,   0, \RS
+    lvx     v20, r10, \RS
+
+.if \increment_counter
+    add     \RS, \RS, \RP
+.endif
+
+    vperm   \VD, \VD, v20, v21
+.endm
+
+.macro interp_8x8 R
+    vperm   v20, \R, \R, v16    ;# v20 = 0123 1234 2345 3456
+    vperm   v21, \R, \R, v17    ;# v21 = 4567 5678 6789 789A
+    Interp4 v20, v20,  v21      ;# v20 = result 0 1 2 3
+    vperm   \R, \R, \R, v18     ;# R   = 89AB 9ABC ABCx BCxx
+    Interp4 v21, v21, \R        ;# v21 = result 4 5 6 7
+
+    vpkswus \R, v20, v21        ;#  R = 0 1 2 3 4 5 6 7
+    vsrh    \R, \R, v19
+
+    vpkuhus \R, \R, \R          ;# saturate and pack
+
+.endm
+
+.macro Read4x4 VD, RS, RP, increment_counter
+    lvsl    v21,  0, \RS        ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v20,   0, \RS
+
+.if \increment_counter
+    add     \RS, \RS, \RP
+.endif
+
+    vperm   \VD, v20, v20, v21
+.endm
+    .text
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+sixtap_predict_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xff87
+    ori     r12, r12, 0xffc0
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    slwi.   r5, r5, 5           ;# index into horizontal filter array
+
+    vspltish v19, 7
+
+    ;# If there isn't any filtering to be done for the horizontal, then
+    ;#  just skip to the second pass.
+    beq-    vertical_only_4x4
+
+    ;# load up horizontal filter
+    load_hfilter v13, v14
+
+    ;# rounding added in on the multiply
+    vspltisw v16, 8
+    vspltisw v15, 3
+    vslw    v15, v16, v15       ;# 0x00000040000000400000004000000040
+
+    ;# Load up permutation constants
+    load_c v16, B_0123, 0, r9, r10
+    load_c v17, B_4567, 0, r9, r10
+    load_c v18, B_89AB, 0, r9, r10
+
+    ;# Back off input buffer by 2 bytes.  Need 2 before and 3 after
+    addi    r3, r3, -2
+
+    addi    r9, r3, 0
+    li      r10, 16
+    Read8x8 v2, r3, r4, 1
+    Read8x8 v3, r3, r4, 1
+    Read8x8 v4, r3, r4, 1
+    Read8x8 v5, r3, r4, 1
+
+    slwi.   r6, r6, 4           ;# index into vertical filter array
+
+    ;# filter a line
+    interp_8x8 v2
+    interp_8x8 v3
+    interp_8x8 v4
+    interp_8x8 v5
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional 5 lines that are needed
+    ;#  for the vertical filter.
+    beq-    store_4x4
+
+    ;# only needed if there is a vertical filter present
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r9, r9, r4
+    sub     r9, r9, r4
+
+    Read8x8 v0, r9, r4, 1
+    Read8x8 v1, r9, r4, 0
+    Read8x8 v6, r3, r4, 1
+    Read8x8 v7, r3, r4, 1
+    Read8x8 v8, r3, r4, 0
+
+    interp_8x8 v0
+    interp_8x8 v1
+    interp_8x8 v6
+    interp_8x8 v7
+    interp_8x8 v8
+
+    b       second_pass_4x4
+
+vertical_only_4x4:
+    ;# only needed if there is a vertical filter present
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r3, r3, r4
+    sub     r3, r3, r4
+    li      r10, 16
+
+    Read8x8 v0, r3, r4, 1
+    Read8x8 v1, r3, r4, 1
+    Read8x8 v2, r3, r4, 1
+    Read8x8 v3, r3, r4, 1
+    Read8x8 v4, r3, r4, 1
+    Read8x8 v5, r3, r4, 1
+    Read8x8 v6, r3, r4, 1
+    Read8x8 v7, r3, r4, 1
+    Read8x8 v8, r3, r4, 0
+
+    slwi    r6, r6, 4           ;# index into vertical filter array
+
+second_pass_4x4:
+    load_c   v20, b_hilo_4x4, 0, r9, r10
+    load_c   v21, b_hilo, 0, r9, r10
+
+    ;# reposition input so that it can go through the
+    ;# filtering phase with one pass.
+    vperm   v0, v0, v1, v20     ;# 0 1 x x
+    vperm   v2, v2, v3, v20     ;# 2 3 x x
+    vperm   v4, v4, v5, v20     ;# 4 5 x x
+    vperm   v6, v6, v7, v20     ;# 6 7 x x
+
+    vperm   v0, v0, v2, v21     ;# 0 1 2 3
+    vperm   v4, v4, v6, v21     ;# 4 5 6 7
+
+    vsldoi  v1, v0, v4, 4
+    vsldoi  v2, v0, v4, 8
+    vsldoi  v3, v0, v4, 12
+
+    vsldoi  v5, v4, v8, 4
+
+    load_c   v13, VFilter, r6, r9, r10
+
+    vspltish v15, 8
+    vspltish v20, 3
+    vslh    v20, v15, v20       ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    vspltb  v14, v13, 1
+    vspltb  v15, v13, 2
+    vspltb  v16, v13, 3
+    vspltb  v17, v13, 4
+    vspltb  v18, v13, 5
+    vspltb  v13, v13, 0
+
+    vinterp_no_store_8x8 v0, v1, v2, v3, v4, v5
+
+    stvx    v0, 0, r1
+
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    lwz     r0, 4(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    lwz     r0, 8(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    lwz     r0, 12(r1)
+    stw     r0, 0(r7)
+
+    b       exit_4x4
+
+store_4x4:
+
+    stvx    v2, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    stvx    v3, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    stvx    v4, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    stvx    v5, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+
+exit_4x4:
+
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+.macro w_8x8 V, D, R, P
+    stvx    \V, 0, r1
+    lwz     \R, 0(r1)
+    stw     \R, 0(r7)
+    lwz     \R, 4(r1)
+    stw     \R, 4(r7)
+    add     \D, \D, \P
+.endm
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+
+sixtap_predict8x4_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xffc0
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    slwi.   r5, r5, 5           ;# index into horizontal filter array
+
+    vspltish v19, 7
+
+    ;# If there isn't any filtering to be done for the horizontal, then
+    ;#  just skip to the second pass.
+    beq-    second_pass_pre_copy_8x4
+
+    load_hfilter v13, v14
+
+    ;# rounding added in on the multiply
+    vspltisw v16, 8
+    vspltisw v15, 3
+    vslw    v15, v16, v15       ;# 0x00000040000000400000004000000040
+
+    ;# Load up permutation constants
+    load_c v16, B_0123, 0, r9, r10
+    load_c v17, B_4567, 0, r9, r10
+    load_c v18, B_89AB, 0, r9, r10
+
+    ;# Back off input buffer by 2 bytes.  Need 2 before and 3 after
+    addi    r3, r3, -2
+
+    addi    r9, r3, 0
+    li      r10, 16
+    Read8x8 v2, r3, r4, 1
+    Read8x8 v3, r3, r4, 1
+    Read8x8 v4, r3, r4, 1
+    Read8x8 v5, r3, r4, 1
+
+    slwi.   r6, r6, 4           ;# index into vertical filter array
+
+    ;# filter a line
+    interp_8x8 v2
+    interp_8x8 v3
+    interp_8x8 v4
+    interp_8x8 v5
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional 5 lines that are needed
+    ;#  for the vertical filter.
+    beq-    store_8x4
+
+    ;# only needed if there is a vertical filter present
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r9, r9, r4
+    sub     r9, r9, r4
+
+    Read8x8 v0, r9, r4, 1
+    Read8x8 v1, r9, r4, 0
+    Read8x8 v6, r3, r4, 1
+    Read8x8 v7, r3, r4, 1
+    Read8x8 v8, r3, r4, 0
+
+    interp_8x8 v0
+    interp_8x8 v1
+    interp_8x8 v6
+    interp_8x8 v7
+    interp_8x8 v8
+
+    b       second_pass_8x4
+
+second_pass_pre_copy_8x4:
+    ;# only needed if there is a vertical filter present
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r3, r3, r4
+    sub     r3, r3, r4
+    li      r10, 16
+
+    Read8x8 v0,  r3, r4, 1
+    Read8x8 v1,  r3, r4, 1
+    Read8x8 v2,  r3, r4, 1
+    Read8x8 v3,  r3, r4, 1
+    Read8x8 v4,  r3, r4, 1
+    Read8x8 v5,  r3, r4, 1
+    Read8x8 v6,  r3, r4, 1
+    Read8x8 v7,  r3, r4, 1
+    Read8x8 v8,  r3, r4, 1
+
+    slwi    r6, r6, 4           ;# index into vertical filter array
+
+second_pass_8x4:
+    load_c v13, VFilter, r6, r9, r10
+
+    vspltish v15, 8
+    vspltish v20, 3
+    vslh    v20, v15, v20       ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    vspltb  v14, v13, 1
+    vspltb  v15, v13, 2
+    vspltb  v16, v13, 3
+    vspltb  v17, v13, 4
+    vspltb  v18, v13, 5
+    vspltb  v13, v13, 0
+
+    vinterp_no_store_8x8 v0, v1, v2, v3,  v4,  v5
+    vinterp_no_store_8x8 v1, v2, v3, v4,  v5,  v6
+    vinterp_no_store_8x8 v2, v3, v4, v5,  v6,  v7
+    vinterp_no_store_8x8 v3, v4, v5, v6,  v7,  v8
+
+    cmpi    cr0, r8, 8
+    beq     cr0, store_aligned_8x4
+
+    w_8x8   v0, r7, r0, r8
+    w_8x8   v1, r7, r0, r8
+    w_8x8   v2, r7, r0, r8
+    w_8x8   v3, r7, r0, r8
+
+    b       exit_8x4
+
+store_aligned_8x4:
+
+    load_c v10, b_hilo, 0, r9, r10
+
+    vperm   v0, v0, v1, v10
+    vperm   v2, v2, v3, v10
+
+    stvx    v0, 0, r7
+    addi    r7, r7, 16
+    stvx    v2, 0, r7
+
+    b       exit_8x4
+
+store_8x4:
+    cmpi    cr0, r8, 8
+    beq     cr0, store_aligned2_8x4
+
+    w_8x8   v2, r7, r0, r8
+    w_8x8   v3, r7, r0, r8
+    w_8x8   v4, r7, r0, r8
+    w_8x8   v5, r7, r0, r8
+
+    b       exit_8x4
+
+store_aligned2_8x4:
+    load_c v10, b_hilo, 0, r9, r10
+
+    vperm   v2, v2, v3, v10
+    vperm   v4, v4, v5, v10
+
+    stvx    v2, 0, r7
+    addi    r7, r7, 16
+    stvx    v4, 0, r7
+
+exit_8x4:
+
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+
+    blr
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+
+;# Because the width that needs to be filtered will fit in a single altivec
+;#  register there is no need to loop.  Everything can stay in registers.
+sixtap_predict8x8_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xffc0
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    slwi.   r5, r5, 5           ;# index into horizontal filter array
+
+    vspltish v19, 7
+
+    ;# If there isn't any filtering to be done for the horizontal, then
+    ;#  just skip to the second pass.
+    beq-    second_pass_pre_copy_8x8
+
+    load_hfilter v13, v14
+
+    ;# rounding added in on the multiply
+    vspltisw v16, 8
+    vspltisw v15, 3
+    vslw    v15, v16, v15       ;# 0x00000040000000400000004000000040
+
+    ;# Load up permutation constants
+    load_c v16, B_0123, 0, r9, r10
+    load_c v17, B_4567, 0, r9, r10
+    load_c v18, B_89AB, 0, r9, r10
+
+    ;# Back off input buffer by 2 bytes.  Need 2 before and 3 after
+    addi    r3, r3, -2
+
+    addi    r9, r3, 0
+    li      r10, 16
+    Read8x8 v2, r3, r4, 1
+    Read8x8 v3, r3, r4, 1
+    Read8x8 v4, r3, r4, 1
+    Read8x8 v5, r3, r4, 1
+    Read8x8 v6, r3, r4, 1
+    Read8x8 v7, r3, r4, 1
+    Read8x8 v8, r3, r4, 1
+    Read8x8 v9, r3, r4, 1
+
+    slwi.   r6, r6, 4           ;# index into vertical filter array
+
+    ;# filter a line
+    interp_8x8 v2
+    interp_8x8 v3
+    interp_8x8 v4
+    interp_8x8 v5
+    interp_8x8 v6
+    interp_8x8 v7
+    interp_8x8 v8
+    interp_8x8 v9
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional 5 lines that are needed
+    ;#  for the vertical filter.
+    beq-    store_8x8
+
+    ;# only needed if there is a vertical filter present
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r9, r9, r4
+    sub     r9, r9, r4
+
+    Read8x8 v0,  r9, r4, 1
+    Read8x8 v1,  r9, r4, 0
+    Read8x8 v10, r3, r4, 1
+    Read8x8 v11, r3, r4, 1
+    Read8x8 v12, r3, r4, 0
+
+    interp_8x8 v0
+    interp_8x8 v1
+    interp_8x8 v10
+    interp_8x8 v11
+    interp_8x8 v12
+
+    b       second_pass_8x8
+
+second_pass_pre_copy_8x8:
+    ;# only needed if there is a vertical filter present
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r3, r3, r4
+    sub     r3, r3, r4
+    li      r10, 16
+
+    Read8x8 v0,  r3, r4, 1
+    Read8x8 v1,  r3, r4, 1
+    Read8x8 v2,  r3, r4, 1
+    Read8x8 v3,  r3, r4, 1
+    Read8x8 v4,  r3, r4, 1
+    Read8x8 v5,  r3, r4, 1
+    Read8x8 v6,  r3, r4, 1
+    Read8x8 v7,  r3, r4, 1
+    Read8x8 v8,  r3, r4, 1
+    Read8x8 v9,  r3, r4, 1
+    Read8x8 v10, r3, r4, 1
+    Read8x8 v11, r3, r4, 1
+    Read8x8 v12, r3, r4, 0
+
+    slwi    r6, r6, 4           ;# index into vertical filter array
+
+second_pass_8x8:
+    load_c v13, VFilter, r6, r9, r10
+
+    vspltish v15, 8
+    vspltish v20, 3
+    vslh    v20, v15, v20       ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    vspltb  v14, v13, 1
+    vspltb  v15, v13, 2
+    vspltb  v16, v13, 3
+    vspltb  v17, v13, 4
+    vspltb  v18, v13, 5
+    vspltb  v13, v13, 0
+
+    vinterp_no_store_8x8 v0, v1, v2, v3,  v4,  v5
+    vinterp_no_store_8x8 v1, v2, v3, v4,  v5,  v6
+    vinterp_no_store_8x8 v2, v3, v4, v5,  v6,  v7
+    vinterp_no_store_8x8 v3, v4, v5, v6,  v7,  v8
+    vinterp_no_store_8x8 v4, v5, v6, v7,  v8,  v9
+    vinterp_no_store_8x8 v5, v6, v7, v8,  v9,  v10
+    vinterp_no_store_8x8 v6, v7, v8, v9,  v10, v11
+    vinterp_no_store_8x8 v7, v8, v9, v10, v11, v12
+
+    cmpi    cr0, r8, 8
+    beq     cr0, store_aligned_8x8
+
+    w_8x8   v0, r7, r0, r8
+    w_8x8   v1, r7, r0, r8
+    w_8x8   v2, r7, r0, r8
+    w_8x8   v3, r7, r0, r8
+    w_8x8   v4, r7, r0, r8
+    w_8x8   v5, r7, r0, r8
+    w_8x8   v6, r7, r0, r8
+    w_8x8   v7, r7, r0, r8
+
+    b       exit_8x8
+
+store_aligned_8x8:
+
+    load_c v10, b_hilo, 0, r9, r10
+
+    vperm   v0, v0, v1, v10
+    vperm   v2, v2, v3, v10
+    vperm   v4, v4, v5, v10
+    vperm   v6, v6, v7, v10
+
+    stvx    v0, 0, r7
+    addi    r7, r7, 16
+    stvx    v2, 0, r7
+    addi    r7, r7, 16
+    stvx    v4, 0, r7
+    addi    r7, r7, 16
+    stvx    v6, 0, r7
+
+    b       exit_8x8
+
+store_8x8:
+    cmpi    cr0, r8, 8
+    beq     cr0, store_aligned2_8x8
+
+    w_8x8   v2, r7, r0, r8
+    w_8x8   v3, r7, r0, r8
+    w_8x8   v4, r7, r0, r8
+    w_8x8   v5, r7, r0, r8
+    w_8x8   v6, r7, r0, r8
+    w_8x8   v7, r7, r0, r8
+    w_8x8   v8, r7, r0, r8
+    w_8x8   v9, r7, r0, r8
+
+    b       exit_8x8
+
+store_aligned2_8x8:
+    load_c v10, b_hilo, 0, r9, r10
+
+    vperm   v2, v2, v3, v10
+    vperm   v4, v4, v5, v10
+    vperm   v6, v6, v7, v10
+    vperm   v8, v8, v9, v10
+
+    stvx    v2, 0, r7
+    addi    r7, r7, 16
+    stvx    v4, 0, r7
+    addi    r7, r7, 16
+    stvx    v6, 0, r7
+    addi    r7, r7, 16
+    stvx    v8, 0, r7
+
+exit_8x8:
+
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+
+;# Two pass filtering.  First pass is Horizontal edges, second pass is vertical
+;#  edges.  One of the filters can be null, but both won't be.  Needs to use a
+;#  temporary buffer because the source buffer can't be modified and the buffer
+;#  for the destination is not large enough to hold the temporary data.
+sixtap_predict16x16_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xf000
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-416(r1)         ;# create space on the stack
+
+    ;# Three possiblities
+    ;#  1. First filter is null.  Don't use a temp buffer.
+    ;#  2. Second filter is null.  Don't use a temp buffer.
+    ;#  3. Neither are null, use temp buffer.
+
+    ;# First Pass (horizontal edge)
+    ;#  setup pointers for src
+    ;#  if possiblity (1) then setup the src pointer to be the orginal and jump
+    ;#  to second pass.  this is based on if x_offset is 0.
+
+    ;# load up horizontal filter
+    slwi.   r5, r5, 5           ;# index into horizontal filter array
+
+    load_hfilter v4, v5
+
+    beq-    copy_horizontal_16x21
+
+    ;# Back off input buffer by 2 bytes.  Need 2 before and 3 after
+    addi    r3, r3, -2
+
+    slwi.   r6, r6, 4           ;# index into vertical filter array
+
+    ;# setup constants
+    ;# v14 permutation value for alignment
+    load_c v14, b_hperm, 0, r9, r10
+
+    ;# These statements are guessing that there won't be a second pass,
+    ;#  but if there is then inside the bypass they need to be set
+    li      r0, 16              ;# prepare for no vertical filter
+
+    ;# Change the output pointer and pitch to be the actual
+    ;#  desination instead of a temporary buffer.
+    addi    r9, r7, 0
+    addi    r5, r8, 0
+
+    ;# no vertical filter, so write the output from the first pass
+    ;#  directly into the output buffer.
+    beq-    no_vertical_filter_bypass
+
+    ;# if the second filter is not null then need to back off by 2*pitch
+    sub     r3, r3, r4
+    sub     r3, r3, r4
+
+    ;# setup counter for the number of lines that are going to be filtered
+    li      r0, 21
+
+    ;# use the stack as temporary storage
+    la      r9, 48(r1)
+    li      r5, 16
+
+no_vertical_filter_bypass:
+
+    mtctr   r0
+
+    ;# rounding added in on the multiply
+    vspltisw v10, 8
+    vspltisw v12, 3
+    vslw    v12, v10, v12       ;# 0x00000040000000400000004000000040
+
+    ;# downshift by 7 ( divide by 128 ) at the end
+    vspltish v13, 7
+
+    ;# index to the next set of vectors in the row.
+    li      r10, 16
+    li      r12, 32
+
+horizontal_loop_16x16:
+
+    lvsl    v15,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v1,   0, r3
+    lvx     v2, r10, r3
+    lvx     v3, r12, r3
+
+    vperm   v8, v1, v2, v15
+    vperm   v9, v2, v3, v15     ;# v8 v9 = 21 input pixels left-justified
+
+    vsldoi  v11, v8, v9, 4
+
+    ;# set 0
+    vmsummbm v6, v4, v8, v12    ;# taps times elements
+    vmsummbm v0, v5, v11, v6
+
+    ;# set 1
+    vsldoi  v10, v8, v9, 1
+    vsldoi  v11, v8, v9, 5
+
+    vmsummbm v6, v4, v10, v12
+    vmsummbm v1, v5, v11, v6
+
+    ;# set 2
+    vsldoi  v10, v8, v9, 2
+    vsldoi  v11, v8, v9, 6
+
+    vmsummbm v6, v4, v10, v12
+    vmsummbm v2, v5, v11, v6
+
+    ;# set 3
+    vsldoi  v10, v8, v9, 3
+    vsldoi  v11, v8, v9, 7
+
+    vmsummbm v6, v4, v10, v12
+    vmsummbm v3, v5, v11, v6
+
+    vpkswus v0, v0, v1          ;# v0 = 0 4 8 C 1 5 9 D (16-bit)
+    vpkswus v1, v2, v3          ;# v1 = 2 6 A E 3 7 B F
+
+    vsrh    v0, v0, v13         ;# divide v0, v1 by 128
+    vsrh    v1, v1, v13
+
+    vpkuhus v0, v0, v1          ;# v0 = scrambled 8-bit result
+    vperm   v0, v0, v0, v14     ;# v0 = correctly-ordered result
+
+    stvx    v0,  0, r9
+    add     r9, r9, r5
+
+    add     r3, r3, r4
+
+    bdnz    horizontal_loop_16x16
+
+    ;# check again to see if vertical filter needs to be done.
+    cmpi    cr0, r6, 0
+    beq     cr0, end_16x16
+
+    ;# yes there is, so go to the second pass
+    b       second_pass_16x16
+
+copy_horizontal_16x21:
+    li      r10, 21
+    mtctr   r10
+
+    li      r10, 16
+
+    sub     r3, r3, r4
+    sub     r3, r3, r4
+
+    ;# this is done above if there is a horizontal filter,
+    ;#  if not it needs to be done down here.
+    slwi    r6, r6, 4           ;# index into vertical filter array
+
+    ;# always write to the stack when doing a horizontal copy
+    la      r9, 48(r1)
+
+copy_horizontal_loop_16x21:
+    lvsl    v15,  0, r3         ;# permutate value for alignment
+
+    lvx     v1,   0, r3
+    lvx     v2, r10, r3
+
+    vperm   v8, v1, v2, v15
+
+    stvx    v8,  0, r9
+    addi    r9, r9, 16
+
+    add     r3, r3, r4
+
+    bdnz    copy_horizontal_loop_16x21
+
+second_pass_16x16:
+
+    ;# always read from the stack when doing a vertical filter
+    la      r9, 48(r1)
+
+    ;# downshift by 7 ( divide by 128 ) at the end
+    vspltish v7, 7
+
+    vpre_load
+
+    luma_vsix
+    luma_vsix
+    luma_vfour
+
+end_16x16:
+
+    addi    r1, r1, 416         ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .data
+
+    .align 4
+HFilter:
+    .byte     0,  0,128,  0,  0,  0,128,  0,  0,  0,128,  0,  0,  0,128,  0
+    .byte     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     0, -6,123, 12,  0, -6,123, 12,  0, -6,123, 12,  0, -6,123, 12
+    .byte    -1,  0,  0,  0, -1,  0,  0,  0, -1,  0,  0,  0, -1,  0,  0,  0
+    .byte     2,-11,108, 36,  2,-11,108, 36,  2,-11,108, 36,  2,-11,108, 36
+    .byte    -8,  1,  0,  0, -8,  1,  0,  0, -8,  1,  0,  0, -8,  1,  0,  0
+    .byte     0, -9, 93, 50,  0, -9, 93, 50,  0, -9, 93, 50,  0, -9, 93, 50
+    .byte    -6,  0,  0,  0, -6,  0,  0,  0, -6,  0,  0,  0, -6,  0,  0,  0
+    .byte     3,-16, 77, 77,  3,-16, 77, 77,  3,-16, 77, 77,  3,-16, 77, 77
+    .byte   -16,  3,  0,  0,-16,  3,  0,  0,-16,  3,  0,  0,-16,  3,  0,  0
+    .byte     0, -6, 50, 93,  0, -6, 50, 93,  0, -6, 50, 93,  0, -6, 50, 93
+    .byte    -9,  0,  0,  0, -9,  0,  0,  0, -9,  0,  0,  0, -9,  0,  0,  0
+    .byte     1, -8, 36,108,  1, -8, 36,108,  1, -8, 36,108,  1, -8, 36,108
+    .byte   -11,  2,  0,  0,-11,  2,  0,  0,-11,  2,  0,  0,-11,  2,  0,  0
+    .byte     0, -1, 12,123,  0, -1, 12,123,  0, -1, 12,123,  0, -1, 12,123
+    .byte    -6,  0,  0,  0, -6,  0,  0,  0, -6,  0,  0,  0, -6,  0,  0,  0
+
+    .align 4
+VFilter:
+    .byte     0,  0,128,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     0,  6,123, 12,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     2, 11,108, 36,  8,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     0,  9, 93, 50,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     3, 16, 77, 77, 16,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     0,  6, 50, 93,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     1,  8, 36,108, 11,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte     0,  1, 12,123,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+
+    .align 4
+b_hperm:
+    .byte     0,  4,  8, 12,  1,  5,  9, 13,  2,  6, 10, 14,  3,  7, 11, 15
+
+    .align 4
+B_0123:
+    .byte     0,  1,  2,  3,  1,  2,  3,  4,  2,  3,  4,  5,  3,  4,  5,  6
+
+    .align 4
+B_4567:
+    .byte     4,  5,  6,  7,  5,  6,  7,  8,  6,  7,  8,  9,  7,  8,  9, 10
+
+    .align 4
+B_89AB:
+    .byte     8,  9, 10, 11,  9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14
+
+    .align 4
+b_hilo:
+    .byte     0,  1,  2,  3,  4,  5,  6,  7, 16, 17, 18, 19, 20, 21, 22, 23
+
+    .align 4
+b_hilo_4x4:
+    .byte     0,  1,  2,  3, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0
diff --git a/vp8/common/ppc/filter_bilinear_altivec.asm b/vp8/common/ppc/filter_bilinear_altivec.asm
new file mode 100644 (file)
index 0000000..27e02a8
--- /dev/null
@@ -0,0 +1,676 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl bilinear_predict4x4_ppc
+    .globl bilinear_predict8x4_ppc
+    .globl bilinear_predict8x8_ppc
+    .globl bilinear_predict16x16_ppc
+
+.macro load_c V, LABEL, OFF, R0, R1
+    lis     \R0, \LABEL@ha
+    la      \R1, \LABEL@l(\R0)
+    lvx     \V, \OFF, \R1
+.endm
+
+.macro load_vfilter V0, V1
+    load_c \V0, vfilter_b, r6, r9, r10
+
+    addi    r6,  r6, 16
+    lvx     \V1, r6, r10
+.endm
+
+.macro HProlog jump_label
+    ;# load up horizontal filter
+    slwi.   r5, r5, 4           ;# index into horizontal filter array
+
+    ;# index to the next set of vectors in the row.
+    li      r10, 16
+    li      r12, 32
+
+    ;# downshift by 7 ( divide by 128 ) at the end
+    vspltish v19, 7
+
+    ;# If there isn't any filtering to be done for the horizontal, then
+    ;#  just skip to the second pass.
+    beq     \jump_label
+
+    load_c v20, hfilter_b, r5, r9, r0
+
+    ;# setup constants
+    ;# v14 permutation value for alignment
+    load_c v28, b_hperm_b, 0, r9, r0
+
+    ;# rounding added in on the multiply
+    vspltisw v21, 8
+    vspltisw v18, 3
+    vslw    v18, v21, v18       ;# 0x00000040000000400000004000000040
+
+    slwi.   r6, r6, 5           ;# index into vertical filter array
+.endm
+
+;# Filters a horizontal line
+;# expects:
+;#  r3  src_ptr
+;#  r4  pitch
+;#  r10 16
+;#  r12 32
+;#  v17 perm intput
+;#  v18 rounding
+;#  v19 shift
+;#  v20 filter taps
+;#  v21 tmp
+;#  v22 tmp
+;#  v23 tmp
+;#  v24 tmp
+;#  v25 tmp
+;#  v26 tmp
+;#  v27 tmp
+;#  v28 perm output
+;#
+.macro HFilter V
+    vperm   v24, v21, v21, v10  ;# v20 = 0123 1234 2345 3456
+    vperm   v25, v21, v21, v11  ;# v21 = 4567 5678 6789 789A
+
+    vmsummbm v24, v20, v24, v18
+    vmsummbm v25, v20, v25, v18
+
+    vpkswus v24, v24, v25       ;# v24 = 0 4 8 C 1 5 9 D (16-bit)
+
+    vsrh    v24, v24, v19       ;# divide v0, v1 by 128
+
+    vpkuhus \V, v24, v24        ;# \V = scrambled 8-bit result
+.endm
+
+.macro hfilter_8 V, increment_counter
+    lvsl    v17,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 9 bytes wide, output is 8 bytes.
+    lvx     v21,   0, r3
+    lvx     v22, r10, r3
+
+.if \increment_counter
+    add     r3, r3, r4
+.endif
+    vperm   v21, v21, v22, v17
+
+    HFilter \V
+.endm
+
+
+.macro load_and_align_8 V, increment_counter
+    lvsl    v17,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v21,   0, r3
+    lvx     v22, r10, r3
+
+.if \increment_counter
+    add     r3, r3, r4
+.endif
+
+    vperm   \V, v21, v22, v17
+.endm
+
+.macro write_aligned_8 V, increment_counter
+    stvx    \V,  0, r7
+
+.if \increment_counter
+    add     r7, r7, r8
+.endif
+.endm
+
+.macro vfilter_16 P0 P1
+    vmuleub v22, \P0, v20       ;# 64 + 4 positive taps
+    vadduhm v22, v18, v22
+    vmuloub v23, \P0, v20
+    vadduhm v23, v18, v23
+
+    vmuleub v24, \P1, v21
+    vadduhm v22, v22, v24       ;# Re = evens, saturation unnecessary
+    vmuloub v25, \P1, v21
+    vadduhm v23, v23, v25       ;# Ro = odds
+
+    vsrh    v22, v22, v19       ;# divide by 128
+    vsrh    v23, v23, v19       ;# v16 v17 = evens, odds
+    vmrghh  \P0, v22, v23       ;# v18 v19 = 16-bit result in order
+    vmrglh  v23, v22, v23
+    vpkuhus \P0, \P0, v23       ;# P0 = 8-bit result
+.endm
+
+
+.macro w_8x8 V, D, R, P
+    stvx    \V, 0, r1
+    lwz     \R, 0(r1)
+    stw     \R, 0(r7)
+    lwz     \R, 4(r1)
+    stw     \R, 4(r7)
+    add     \D, \D, \P
+.endm
+
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+bilinear_predict4x4_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xf830
+    ori     r12, r12, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    HProlog second_pass_4x4_pre_copy_b
+
+    ;# Load up permutation constants
+    load_c v10, b_0123_b, 0, r9, r12
+    load_c v11, b_4567_b, 0, r9, r12
+
+    hfilter_8 v0, 1
+    hfilter_8 v1, 1
+    hfilter_8 v2, 1
+    hfilter_8 v3, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     store_out_4x4_b
+
+    hfilter_8 v4, 0
+
+    b   second_pass_4x4_b
+
+second_pass_4x4_pre_copy_b:
+    slwi    r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_8  v0, 1
+    load_and_align_8  v1, 1
+    load_and_align_8  v2, 1
+    load_and_align_8  v3, 1
+    load_and_align_8  v4, 1
+
+second_pass_4x4_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+
+store_out_4x4_b:
+
+    stvx    v0, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    stvx    v1, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    stvx    v2, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+    add     r7, r7, r8
+
+    stvx    v3, 0, r1
+    lwz     r0, 0(r1)
+    stw     r0, 0(r7)
+
+exit_4x4:
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+bilinear_predict8x4_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xf830
+    ori     r12, r12, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    HProlog second_pass_8x4_pre_copy_b
+
+    ;# Load up permutation constants
+    load_c v10, b_0123_b, 0, r9, r12
+    load_c v11, b_4567_b, 0, r9, r12
+
+    hfilter_8 v0, 1
+    hfilter_8 v1, 1
+    hfilter_8 v2, 1
+    hfilter_8 v3, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     store_out_8x4_b
+
+    hfilter_8 v4, 0
+
+    b   second_pass_8x4_b
+
+second_pass_8x4_pre_copy_b:
+    slwi    r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_8  v0, 1
+    load_and_align_8  v1, 1
+    load_and_align_8  v2, 1
+    load_and_align_8  v3, 1
+    load_and_align_8  v4, 1
+
+second_pass_8x4_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+
+store_out_8x4_b:
+
+    cmpi    cr0, r8, 8
+    beq     cr0, store_aligned_8x4_b
+
+    w_8x8   v0, r7, r0, r8
+    w_8x8   v1, r7, r0, r8
+    w_8x8   v2, r7, r0, r8
+    w_8x8   v3, r7, r0, r8
+
+    b       exit_8x4
+
+store_aligned_8x4_b:
+    load_c v10, b_hilo_b, 0, r9, r10
+
+    vperm   v0, v0, v1, v10
+    vperm   v2, v2, v3, v10
+
+    stvx    v0, 0, r7
+    addi    r7, r7, 16
+    stvx    v2, 0, r7
+
+exit_8x4:
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+bilinear_predict8x8_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xfff0
+    ori     r12, r12, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    HProlog second_pass_8x8_pre_copy_b
+
+    ;# Load up permutation constants
+    load_c v10, b_0123_b, 0, r9, r12
+    load_c v11, b_4567_b, 0, r9, r12
+
+    hfilter_8 v0, 1
+    hfilter_8 v1, 1
+    hfilter_8 v2, 1
+    hfilter_8 v3, 1
+    hfilter_8 v4, 1
+    hfilter_8 v5, 1
+    hfilter_8 v6, 1
+    hfilter_8 v7, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     store_out_8x8_b
+
+    hfilter_8 v8, 0
+
+    b   second_pass_8x8_b
+
+second_pass_8x8_pre_copy_b:
+    slwi    r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_8  v0, 1
+    load_and_align_8  v1, 1
+    load_and_align_8  v2, 1
+    load_and_align_8  v3, 1
+    load_and_align_8  v4, 1
+    load_and_align_8  v5, 1
+    load_and_align_8  v6, 1
+    load_and_align_8  v7, 1
+    load_and_align_8  v8, 0
+
+second_pass_8x8_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+    vfilter_16 v4,  v5
+    vfilter_16 v5,  v6
+    vfilter_16 v6,  v7
+    vfilter_16 v7,  v8
+
+store_out_8x8_b:
+
+    cmpi    cr0, r8, 8
+    beq     cr0, store_aligned_8x8_b
+
+    w_8x8   v0, r7, r0, r8
+    w_8x8   v1, r7, r0, r8
+    w_8x8   v2, r7, r0, r8
+    w_8x8   v3, r7, r0, r8
+    w_8x8   v4, r7, r0, r8
+    w_8x8   v5, r7, r0, r8
+    w_8x8   v6, r7, r0, r8
+    w_8x8   v7, r7, r0, r8
+
+    b       exit_8x8
+
+store_aligned_8x8_b:
+    load_c v10, b_hilo_b, 0, r9, r10
+
+    vperm   v0, v0, v1, v10
+    vperm   v2, v2, v3, v10
+    vperm   v4, v4, v5, v10
+    vperm   v6, v6, v7, v10
+
+    stvx    v0, 0, r7
+    addi    r7, r7, 16
+    stvx    v2, 0, r7
+    addi    r7, r7, 16
+    stvx    v4, 0, r7
+    addi    r7, r7, 16
+    stvx    v6, 0, r7
+
+exit_8x8:
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+;# Filters a horizontal line
+;# expects:
+;#  r3  src_ptr
+;#  r4  pitch
+;#  r10 16
+;#  r12 32
+;#  v17 perm intput
+;#  v18 rounding
+;#  v19 shift
+;#  v20 filter taps
+;#  v21 tmp
+;#  v22 tmp
+;#  v23 tmp
+;#  v24 tmp
+;#  v25 tmp
+;#  v26 tmp
+;#  v27 tmp
+;#  v28 perm output
+;#
+.macro hfilter_16 V, increment_counter
+
+    lvsl    v17,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v21,   0, r3
+    lvx     v22, r10, r3
+    lvx     v23, r12, r3
+
+.if \increment_counter
+    add     r3, r3, r4
+.endif
+    vperm   v21, v21, v22, v17
+    vperm   v22, v22, v23, v17  ;# v8 v9 = 21 input pixels left-justified
+
+    ;# set 0
+    vmsummbm v24, v20, v21, v18 ;# taps times elements
+
+    ;# set 1
+    vsldoi  v23, v21, v22, 1
+    vmsummbm v25, v20, v23, v18
+
+    ;# set 2
+    vsldoi  v23, v21, v22, 2
+    vmsummbm v26, v20, v23, v18
+
+    ;# set 3
+    vsldoi  v23, v21, v22, 3
+    vmsummbm v27, v20, v23, v18
+
+    vpkswus v24, v24, v25       ;# v24 = 0 4 8 C 1 5 9 D (16-bit)
+    vpkswus v25, v26, v27       ;# v25 = 2 6 A E 3 7 B F
+
+    vsrh    v24, v24, v19       ;# divide v0, v1 by 128
+    vsrh    v25, v25, v19
+
+    vpkuhus \V, v24, v25        ;# \V = scrambled 8-bit result
+    vperm   \V, \V, v0, v28     ;# \V = correctly-ordered result
+.endm
+
+.macro load_and_align_16 V, increment_counter
+    lvsl    v17,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v21,   0, r3
+    lvx     v22, r10, r3
+
+.if \increment_counter
+    add     r3, r3, r4
+.endif
+
+    vperm   \V, v21, v22, v17
+.endm
+
+.macro write_16 V, increment_counter
+    stvx    \V,  0, r7
+
+.if \increment_counter
+    add     r7, r7, r8
+.endif
+.endm
+
+    .align 2
+;# r3 unsigned char * src
+;# r4 int src_pitch
+;# r5 int x_offset
+;# r6 int y_offset
+;# r7 unsigned char * dst
+;# r8 int dst_pitch
+bilinear_predict16x16_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    HProlog second_pass_16x16_pre_copy_b
+
+    hfilter_16 v0,  1
+    hfilter_16 v1,  1
+    hfilter_16 v2,  1
+    hfilter_16 v3,  1
+    hfilter_16 v4,  1
+    hfilter_16 v5,  1
+    hfilter_16 v6,  1
+    hfilter_16 v7,  1
+    hfilter_16 v8,  1
+    hfilter_16 v9,  1
+    hfilter_16 v10, 1
+    hfilter_16 v11, 1
+    hfilter_16 v12, 1
+    hfilter_16 v13, 1
+    hfilter_16 v14, 1
+    hfilter_16 v15, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     store_out_16x16_b
+
+    hfilter_16 v16, 0
+
+    b   second_pass_16x16_b
+
+second_pass_16x16_pre_copy_b:
+    slwi    r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_16  v0,  1
+    load_and_align_16  v1,  1
+    load_and_align_16  v2,  1
+    load_and_align_16  v3,  1
+    load_and_align_16  v4,  1
+    load_and_align_16  v5,  1
+    load_and_align_16  v6,  1
+    load_and_align_16  v7,  1
+    load_and_align_16  v8,  1
+    load_and_align_16  v9,  1
+    load_and_align_16  v10, 1
+    load_and_align_16  v11, 1
+    load_and_align_16  v12, 1
+    load_and_align_16  v13, 1
+    load_and_align_16  v14, 1
+    load_and_align_16  v15, 1
+    load_and_align_16  v16, 0
+
+second_pass_16x16_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+    vfilter_16 v4,  v5
+    vfilter_16 v5,  v6
+    vfilter_16 v6,  v7
+    vfilter_16 v7,  v8
+    vfilter_16 v8,  v9
+    vfilter_16 v9,  v10
+    vfilter_16 v10, v11
+    vfilter_16 v11, v12
+    vfilter_16 v12, v13
+    vfilter_16 v13, v14
+    vfilter_16 v14, v15
+    vfilter_16 v15, v16
+
+store_out_16x16_b:
+
+    write_16 v0,  1
+    write_16 v1,  1
+    write_16 v2,  1
+    write_16 v3,  1
+    write_16 v4,  1
+    write_16 v5,  1
+    write_16 v6,  1
+    write_16 v7,  1
+    write_16 v8,  1
+    write_16 v9,  1
+    write_16 v10, 1
+    write_16 v11, 1
+    write_16 v12, 1
+    write_16 v13, 1
+    write_16 v14, 1
+    write_16 v15, 0
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .data
+
+    .align 4
+hfilter_b:
+    .byte   128,  0,  0,  0,128,  0,  0,  0,128,  0,  0,  0,128,  0,  0,  0
+    .byte   112, 16,  0,  0,112, 16,  0,  0,112, 16,  0,  0,112, 16,  0,  0
+    .byte    96, 32,  0,  0, 96, 32,  0,  0, 96, 32,  0,  0, 96, 32,  0,  0
+    .byte    80, 48,  0,  0, 80, 48,  0,  0, 80, 48,  0,  0, 80, 48,  0,  0
+    .byte    64, 64,  0,  0, 64, 64,  0,  0, 64, 64,  0,  0, 64, 64,  0,  0
+    .byte    48, 80,  0,  0, 48, 80,  0,  0, 48, 80,  0,  0, 48, 80,  0,  0
+    .byte    32, 96,  0,  0, 32, 96,  0,  0, 32, 96,  0,  0, 32, 96,  0,  0
+    .byte    16,112,  0,  0, 16,112,  0,  0, 16,112,  0,  0, 16,112,  0,  0
+
+    .align 4
+vfilter_b:
+    .byte   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
+    .byte     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte   112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112
+    .byte    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+    .byte    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96
+    .byte    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
+    .byte    80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
+    .byte    48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
+    .byte    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+    .byte    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+    .byte    48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
+    .byte    80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
+    .byte    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
+    .byte    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96
+    .byte    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+    .byte   112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112
+
+    .align 4
+b_hperm_b:
+    .byte     0,  4,  8, 12,  1,  5,  9, 13,  2,  6, 10, 14,  3,  7, 11, 15
+
+    .align 4
+b_0123_b:
+    .byte     0,  1,  2,  3,  1,  2,  3,  4,  2,  3,  4,  5,  3,  4,  5,  6
+
+    .align 4
+b_4567_b:
+    .byte     4,  5,  6,  7,  5,  6,  7,  8,  6,  7,  8,  9,  7,  8,  9, 10
+
+b_hilo_b:
+    .byte     0,  1,  2,  3,  4,  5,  6,  7, 16, 17, 18, 19, 20, 21, 22, 23
diff --git a/vp8/common/ppc/idctllm_altivec.asm b/vp8/common/ppc/idctllm_altivec.asm
new file mode 100644 (file)
index 0000000..e88af8d
--- /dev/null
@@ -0,0 +1,188 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl short_idct4x4llm_ppc
+
+.macro load_c V, LABEL, OFF, R0, R1
+    lis     \R0, \LABEL@ha
+    la      \R1, \LABEL@l(\R0)
+    lvx     \V, \OFF, \R1
+.endm
+
+;# r3 short *input
+;# r4 short *output
+;# r5 int pitch
+    .align 2
+short_idct4x4llm_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    load_c v8, sinpi8sqrt2, 0, r9, r10
+    load_c v9, cospi8sqrt2minus1, 0, r9, r10
+    load_c v10, hi_hi, 0, r9, r10
+    load_c v11, lo_lo, 0, r9, r10
+    load_c v12, shift_16, 0, r9, r10
+
+    li      r10,  16
+    lvx     v0,   0, r3         ;# input ip[0], ip[ 4]
+    lvx     v1, r10, r3         ;# input ip[8], ip[12]
+
+    ;# first pass
+    vupkhsh v2, v0
+    vupkhsh v3, v1
+    vaddsws v6, v2, v3          ;# a1 = ip[0]+ip[8]
+    vsubsws v7, v2, v3          ;# b1 = ip[0]-ip[8]
+
+    vupklsh v0, v0
+    vmulosh v4, v0, v8
+    vsraw   v4, v4, v12
+    vaddsws v4, v4, v0          ;# ip[ 4] * sin(pi/8) * sqrt(2)
+
+    vupklsh v1, v1
+    vmulosh v5, v1, v9
+    vsraw   v5, v5, v12         ;# ip[12] * cos(pi/8) * sqrt(2)
+    vaddsws v5, v5, v1
+
+    vsubsws v4, v4, v5          ;# c1
+
+    vmulosh v3, v1, v8
+    vsraw   v3, v3, v12
+    vaddsws v3, v3, v1          ;# ip[12] * sin(pi/8) * sqrt(2)
+
+    vmulosh v5, v0, v9
+    vsraw   v5, v5, v12         ;# ip[ 4] * cos(pi/8) * sqrt(2)
+    vaddsws v5, v5, v0
+
+    vaddsws v3, v3, v5          ;# d1
+
+    vaddsws v0, v6, v3          ;# a1 + d1
+    vsubsws v3, v6, v3          ;# a1 - d1
+
+    vaddsws v1, v7, v4          ;# b1 + c1
+    vsubsws v2, v7, v4          ;# b1 - c1
+
+    ;# transpose input
+    vmrghw  v4, v0, v1          ;# a0 b0 a1 b1
+    vmrghw  v5, v2, v3          ;# c0 d0 c1 d1
+
+    vmrglw  v6, v0, v1          ;# a2 b2 a3 b3
+    vmrglw  v7, v2, v3          ;# c2 d2 c3 d3
+
+    vperm   v0, v4, v5, v10     ;# a0 b0 c0 d0
+    vperm   v1, v4, v5, v11     ;# a1 b1 c1 d1
+
+    vperm   v2, v6, v7, v10     ;# a2 b2 c2 d2
+    vperm   v3, v6, v7, v11     ;# a3 b3 c3 d3
+
+    ;# second pass
+    vaddsws v6, v0, v2          ;# a1 = ip[0]+ip[8]
+    vsubsws v7, v0, v2          ;# b1 = ip[0]-ip[8]
+
+    vmulosh v4, v1, v8
+    vsraw   v4, v4, v12
+    vaddsws v4, v4, v1          ;# ip[ 4] * sin(pi/8) * sqrt(2)
+
+    vmulosh v5, v3, v9
+    vsraw   v5, v5, v12         ;# ip[12] * cos(pi/8) * sqrt(2)
+    vaddsws v5, v5, v3
+
+    vsubsws v4, v4, v5          ;# c1
+
+    vmulosh v2, v3, v8
+    vsraw   v2, v2, v12
+    vaddsws v2, v2, v3          ;# ip[12] * sin(pi/8) * sqrt(2)
+
+    vmulosh v5, v1, v9
+    vsraw   v5, v5, v12         ;# ip[ 4] * cos(pi/8) * sqrt(2)
+    vaddsws v5, v5, v1
+
+    vaddsws v3, v2, v5          ;# d1
+
+    vaddsws v0, v6, v3          ;# a1 + d1
+    vsubsws v3, v6, v3          ;# a1 - d1
+
+    vaddsws v1, v7, v4          ;# b1 + c1
+    vsubsws v2, v7, v4          ;# b1 - c1
+
+    vspltish v6, 4
+    vspltish v7, 3
+
+    vpkswss v0, v0, v1
+    vpkswss v1, v2, v3
+
+    vaddshs v0, v0, v6
+    vaddshs v1, v1, v6
+
+    vsrah   v0, v0, v7
+    vsrah   v1, v1, v7
+
+    ;# transpose output
+    vmrghh  v2, v0, v1          ;# a0 c0 a1 c1 a2 c2 a3 c3
+    vmrglh  v3, v0, v1          ;# b0 d0 b1 d1 b2 d2 b3 d3
+
+    vmrghh  v0, v2, v3          ;# a0 b0 c0 d0 a1 b1 c1 d1
+    vmrglh  v1, v2, v3          ;# a2 b2 c2 d2 a3 b3 c3 d3
+
+    stwu    r1,-416(r1)         ;# create space on the stack
+
+    stvx    v0,  0, r1
+    lwz     r6, 0(r1)
+    stw     r6, 0(r4)
+    lwz     r6, 4(r1)
+    stw     r6, 4(r4)
+
+    add     r4, r4, r5
+
+    lwz     r6,  8(r1)
+    stw     r6,  0(r4)
+    lwz     r6, 12(r1)
+    stw     r6,  4(r4)
+
+    add     r4, r4, r5
+
+    stvx    v1,  0, r1
+    lwz     r6, 0(r1)
+    stw     r6, 0(r4)
+    lwz     r6, 4(r1)
+    stw     r6, 4(r4)
+
+    add     r4, r4, r5
+
+    lwz     r6,  8(r1)
+    stw     r6,  0(r4)
+    lwz     r6, 12(r1)
+    stw     r6,  4(r4)
+
+    addi    r1, r1, 416         ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 4
+sinpi8sqrt2:
+    .short  35468, 35468, 35468, 35468, 35468, 35468, 35468, 35468
+
+    .align 4
+cospi8sqrt2minus1:
+    .short  20091, 20091, 20091, 20091, 20091, 20091, 20091, 20091
+
+    .align 4
+shift_16:
+    .long      16,    16,    16,    16
+
+    .align 4
+hi_hi:
+    .byte     0,  1,  2,  3,  4,  5,  6,  7, 16, 17, 18, 19, 20, 21, 22, 23
+
+    .align 4
+lo_lo:
+    .byte     8,  9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31
diff --git a/vp8/common/ppc/loopfilter_altivec.c b/vp8/common/ppc/loopfilter_altivec.c
new file mode 100644 (file)
index 0000000..586eed4
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "loopfilter.h"
+#include "onyxc_int.h"
+
+typedef void loop_filter_function_y_ppc
+(
+    unsigned char *s,   // source pointer
+    int p,              // pitch
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh
+);
+
+typedef void loop_filter_function_uv_ppc
+(
+    unsigned char *u,   // source pointer
+    unsigned char *v,   // source pointer
+    int p,              // pitch
+    const signed char *flimit,
+    const signed char *limit,
+    const signed char *thresh
+);
+
+typedef void loop_filter_function_s_ppc
+(
+    unsigned char *s,   // source pointer
+    int p,              // pitch
+    const signed char *flimit
+);
+
+loop_filter_function_y_ppc mbloop_filter_horizontal_edge_y_ppc;
+loop_filter_function_y_ppc mbloop_filter_vertical_edge_y_ppc;
+loop_filter_function_y_ppc loop_filter_horizontal_edge_y_ppc;
+loop_filter_function_y_ppc loop_filter_vertical_edge_y_ppc;
+
+loop_filter_function_uv_ppc mbloop_filter_horizontal_edge_uv_ppc;
+loop_filter_function_uv_ppc mbloop_filter_vertical_edge_uv_ppc;
+loop_filter_function_uv_ppc loop_filter_horizontal_edge_uv_ppc;
+loop_filter_function_uv_ppc loop_filter_vertical_edge_uv_ppc;
+
+loop_filter_function_s_ppc loop_filter_simple_horizontal_edge_ppc;
+loop_filter_function_s_ppc loop_filter_simple_vertical_edge_ppc;
+
+// Horizontal MB filtering
+void loop_filter_mbh_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                         int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    mbloop_filter_horizontal_edge_y_ppc(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr);
+
+    if (u_ptr)
+        mbloop_filter_horizontal_edge_uv_ppc(u_ptr, v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr);
+}
+
+void loop_filter_mbhs_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                          int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    (void)u_ptr;
+    (void)v_ptr;
+    (void)uv_stride;
+    loop_filter_simple_horizontal_edge_ppc(y_ptr, y_stride, lfi->mbflim);
+}
+
+// Vertical MB Filtering
+void loop_filter_mbv_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                         int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    mbloop_filter_vertical_edge_y_ppc(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr);
+
+    if (u_ptr)
+        mbloop_filter_vertical_edge_uv_ppc(u_ptr, v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr);
+}
+
+void loop_filter_mbvs_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                          int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    (void)u_ptr;
+    (void)v_ptr;
+    (void)uv_stride;
+    loop_filter_simple_vertical_edge_ppc(y_ptr, y_stride, lfi->mbflim);
+}
+
+// Horizontal B Filtering
+void loop_filter_bh_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                        int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    // These should all be done at once with one call, instead of 3
+    loop_filter_horizontal_edge_y_ppc(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr);
+    loop_filter_horizontal_edge_y_ppc(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr);
+    loop_filter_horizontal_edge_y_ppc(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr);
+
+    if (u_ptr)
+        loop_filter_horizontal_edge_uv_ppc(u_ptr + 4 * uv_stride, v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr);
+}
+
+void loop_filter_bhs_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                         int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    (void)u_ptr;
+    (void)v_ptr;
+    (void)uv_stride;
+    loop_filter_simple_horizontal_edge_ppc(y_ptr + 4 * y_stride, y_stride, lfi->flim);
+    loop_filter_simple_horizontal_edge_ppc(y_ptr + 8 * y_stride, y_stride, lfi->flim);
+    loop_filter_simple_horizontal_edge_ppc(y_ptr + 12 * y_stride, y_stride, lfi->flim);
+}
+
+// Vertical B Filtering
+void loop_filter_bv_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                        int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    loop_filter_vertical_edge_y_ppc(y_ptr, y_stride, lfi->flim, lfi->lim, lfi->thr);
+
+    if (u_ptr)
+        loop_filter_vertical_edge_uv_ppc(u_ptr + 4, v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr);
+}
+
+void loop_filter_bvs_ppc(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                         int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void)simpler_lpf;
+    (void)u_ptr;
+    (void)v_ptr;
+    (void)uv_stride;
+    loop_filter_simple_vertical_edge_ppc(y_ptr + 4,  y_stride, lfi->flim);
+    loop_filter_simple_vertical_edge_ppc(y_ptr + 8,  y_stride, lfi->flim);
+    loop_filter_simple_vertical_edge_ppc(y_ptr + 12, y_stride, lfi->flim);
+}
diff --git a/vp8/common/ppc/loopfilter_filters_altivec.asm b/vp8/common/ppc/loopfilter_filters_altivec.asm
new file mode 100644 (file)
index 0000000..78a5cf9
--- /dev/null
@@ -0,0 +1,1252 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl mbloop_filter_horizontal_edge_y_ppc
+    .globl loop_filter_horizontal_edge_y_ppc
+    .globl mbloop_filter_vertical_edge_y_ppc
+    .globl loop_filter_vertical_edge_y_ppc
+
+    .globl mbloop_filter_horizontal_edge_uv_ppc
+    .globl loop_filter_horizontal_edge_uv_ppc
+    .globl mbloop_filter_vertical_edge_uv_ppc
+    .globl loop_filter_vertical_edge_uv_ppc
+
+    .globl loop_filter_simple_horizontal_edge_ppc
+    .globl loop_filter_simple_vertical_edge_ppc
+
+    .text
+;# We often need to perform transposes (and other transpose-like operations)
+;#   on matrices of data.  This is simplified by the fact that we usually
+;#   operate on hunks of data whose dimensions are powers of 2, or at least
+;#   divisible by highish powers of 2.
+;#
+;#   These operations can be very confusing.  They become more straightforward
+;#   when we think of them as permutations of address bits: Concatenate a
+;#   group of vector registers and think of it as occupying a block of
+;#   memory beginning at address zero.  The low four bits 0...3 of the
+;#   address then correspond to position within a register, the higher-order
+;#   address bits select the register.
+;#
+;#   Although register selection, at the code level, is arbitrary, things
+;#   are simpler if we use contiguous ranges of register numbers, simpler
+;#   still if the low-order bits of the register number correspond to
+;#   conceptual address bits.  We do this whenever reasonable.
+;#
+;#   A 16x16 transpose can then be thought of as an operation on
+;#   a 256-element block of memory.  It takes 8 bits 0...7 to address this
+;#   memory and the effect of a transpose is to interchange address bit
+;#   0 with 4, 1 with 5, 2 with 6, and 3 with 7.  Bits 0...3 index the
+;#   column, which is interchanged with the row addressed by bits 4..7.
+;#
+;#   The altivec merge instructions provide a rapid means of effecting
+;#   many of these transforms.  They operate at three widths (8,16,32).
+;#   Writing V(x) for vector register #x, paired merges permute address
+;#   indices as follows.
+;#
+;#   0->1  1->2  2->3  3->(4+d)  (4+s)->0:
+;#
+;#      vmrghb  V( x),          V( y), V( y + (1<<s))
+;#      vmrglb  V( x + (1<<d)), V( y), V( y + (1<<s))
+;#
+;#
+;#   =0=   1->2  2->3  3->(4+d)  (4+s)->1:
+;#
+;#      vmrghh  V( x),          V( y), V( y + (1<<s))
+;#      vmrglh  V( x + (1<<d)), V( y), V( y + (1<<s))
+;#
+;#
+;#   =0=   =1=   2->3  3->(4+d)  (4+s)->2:
+;#
+;#      vmrghw  V( x),          V( y), V( y + (1<<s))
+;#      vmrglw  V( x + (1<<d)), V( y), V( y + (1<<s))
+;#
+;#
+;#   Unfortunately, there is no doubleword merge instruction.
+;#   The following sequence uses "vperm" is a substitute.
+;#   Assuming that the selection masks b_hihi and b_lolo (defined in LFppc.c)
+;#   are in registers Vhihi and Vlolo, we can also effect the permutation
+;#
+;#   =0=   =1=   =2=   3->(4+d)  (4+s)->3   by the sequence:
+;#
+;#      vperm   V( x),          V( y), V( y + (1<<s)), Vhihi
+;#      vperm   V( x + (1<<d)), V( y), V( y + (1<<s)), Vlolo
+;#
+;#
+;#   Except for bits s and d, the other relationships between register
+;#   number (= high-order part of address) bits are at the disposal of
+;#   the programmer.
+;#
+
+;# To avoid excess transposes, we filter all 3 vertical luma subblock
+;#   edges together.  This requires a single 16x16 transpose, which, in
+;#   the above language, amounts to the following permutation of address
+;#   indices:  0<->4   1<->5  2<->6  3<->7, which we accomplish by
+;#   4 iterations of the cyclic transform 0->1->2->3->4->5->6->7->0.
+;#
+;#   Except for the fact that the destination registers get written
+;#   before we are done referencing the old contents, the cyclic transform
+;#   is effected by
+;#
+;#      x = 0;  do {
+;#          vmrghb V(2x),   V(x), V(x+8);
+;#          vmrghb V(2x+1), V(x), V(x+8);
+;#      } while( ++x < 8);
+;#
+;#   For clarity, and because we can afford it, we do this transpose
+;#   using all 32 registers, alternating the banks 0..15  and  16 .. 31,
+;#   leaving the final result in 16 .. 31, as the lower registers are
+;#   used in the filtering itself.
+;#
+.macro Tpair A, B, X, Y
+    vmrghb  \A, \X, \Y
+    vmrglb  \B, \X, \Y
+.endm
+
+;# Each step takes 8*2 = 16 instructions
+
+.macro t16_even
+    Tpair v16,v17,  v0,v8
+    Tpair v18,v19,  v1,v9
+    Tpair v20,v21,  v2,v10
+    Tpair v22,v23,  v3,v11
+    Tpair v24,v25,  v4,v12
+    Tpair v26,v27,  v5,v13
+    Tpair v28,v29,  v6,v14
+    Tpair v30,v31,  v7,v15
+.endm
+
+.macro t16_odd
+    Tpair v0,v1, v16,v24
+    Tpair v2,v3, v17,v25
+    Tpair v4,v5, v18,v26
+    Tpair v6,v7, v19,v27
+    Tpair v8,v9, v20,v28
+    Tpair v10,v11, v21,v29
+    Tpair v12,v13, v22,v30
+    Tpair v14,v15, v23,v31
+.endm
+
+;# Whole transpose takes 4*16 = 64 instructions
+
+.macro t16_full
+    t16_odd
+    t16_even
+    t16_odd
+    t16_even
+.endm
+
+;# Vertical edge filtering requires transposes.  For the simple filter,
+;#   we need to convert 16 rows of 4 pels each into 4 registers of 16 pels
+;#   each.  Writing 0 ... 63 for the pixel indices, the desired result is:
+;#
+;#  v0 =  0  1 ... 14 15
+;#  v1 = 16 17 ... 30 31
+;#  v2 = 32 33 ... 47 48
+;#  v3 = 49 50 ... 62 63
+;#
+;#  In frame-buffer memory, the layout is:
+;#
+;#     0  16  32  48
+;#     1  17  33  49
+;#     ...
+;#    15  31  47  63.
+;#
+;#  We begin by reading the data 32 bits at a time (using scalar operations)
+;#  into a temporary array, reading the rows of the array into vector registers,
+;#  with the following layout:
+;#
+;#  v0 =  0 16 32 48  4 20 36 52  8 24 40 56  12 28 44 60
+;#  v1 =  1 17 33 49  5 21 ...                      45 61
+;#  v2 =  2 18 ...                                  46 62
+;#  v3 =  3 19 ...                                  47 63
+;#
+;#  From the "address-bit" perspective discussed above, we simply need to
+;#  interchange bits 0 <-> 4 and 1 <-> 5, leaving bits 2 and 3 alone.
+;#  In other words, we transpose each of the four 4x4 submatrices.
+;#
+;#  This transformation is its own inverse, and we need to perform it
+;#  again before writing the pixels back into the frame buffer.
+;#
+;#  It acts in place on registers v0...v3, uses v4...v7 as temporaries,
+;#  and assumes that v14/v15 contain the b_hihi/b_lolo selectors
+;#  defined above.  We think of both groups of 4 registers as having
+;#  "addresses" {0,1,2,3} * 16.
+;#
+.macro Transpose4times4x4 Vlo, Vhi
+
+    ;# d=s=0        0->1  1->2  2->3  3->4  4->0  =5=
+
+    vmrghb  v4, v0, v1
+    vmrglb  v5, v0, v1
+    vmrghb  v6, v2, v3
+    vmrglb  v7, v2, v3
+
+    ;# d=0 s=1      =0=   1->2  2->3  3->4  4->5  5->1
+
+    vmrghh  v0, v4, v6
+    vmrglh  v1, v4, v6
+    vmrghh  v2, v5, v7
+    vmrglh  v3, v5, v7
+
+    ;# d=s=0        =0=   =1=   2->3  3->4  4->2  =5=
+
+    vmrghw  v4, v0, v1
+    vmrglw  v5, v0, v1
+    vmrghw  v6, v2, v3
+    vmrglw  v7, v2, v3
+
+    ;# d=0  s=1     =0=   =1=   =2=   3->4  4->5  5->3
+
+    vperm   v0, v4, v6, \Vlo
+    vperm   v1, v4, v6, \Vhi
+    vperm   v2, v5, v7, \Vlo
+    vperm   v3, v5, v7, \Vhi
+.endm
+;# end Transpose4times4x4
+
+
+;# Normal mb vertical edge filter transpose.
+;#
+;#   We read 8 columns of data, initially in the following pattern:
+;#
+;#  (0,0)  (1,0) ... (7,0)  (0,1)  (1,1) ... (7,1)
+;#  (0,2)  (1,2) ... (7,2)  (0,3)  (1,3) ... (7,3)
+;#  ...
+;#  (0,14) (1,14) .. (7,14) (0,15) (1,15) .. (7,15)
+;#
+;#   and wish to convert to:
+;#
+;#  (0,0) ... (0,15)
+;#  (1,0) ... (1,15)
+;#  ...
+;#  (7,0) ... (7,15).
+;#
+;#  In "address bit" language, we wish to map
+;#
+;#  0->4  1->5  2->6  3->0  4->1  5->2  6->3, i.e., I -> (I+4) mod 7.
+;#
+;#  This can be accomplished by 4 iterations of the cyclic transform
+;#
+;#  I -> (I+1) mod 7;
+;#
+;#  each iteration can be realized by (d=0, s=2):
+;#
+;#  x = 0;  do  Tpair( V(2x),V(2x+1),  V(x),V(x+4))  while( ++x < 4);
+;#
+;#  The input/output is in registers v0...v7.  We use v10...v17 as mirrors;
+;#  preserving v8 = sign converter.
+;#
+;#  Inverse transpose is similar, except here I -> (I+3) mod 7 and the
+;#  result lands in the "mirror" registers v10...v17
+;#
+.macro t8x16_odd
+    Tpair v10, v11,  v0, v4
+    Tpair v12, v13,  v1, v5
+    Tpair v14, v15,  v2, v6
+    Tpair v16, v17,  v3, v7
+.endm
+
+.macro t8x16_even
+    Tpair v0, v1,  v10, v14
+    Tpair v2, v3,  v11, v15
+    Tpair v4, v5,  v12, v16
+    Tpair v6, v7,  v13, v17
+.endm
+
+.macro transpose8x16_fwd
+    t8x16_odd
+    t8x16_even
+    t8x16_odd
+    t8x16_even
+.endm
+
+.macro transpose8x16_inv
+    t8x16_odd
+    t8x16_even
+    t8x16_odd
+.endm
+
+.macro Transpose16x16
+    vmrghb  v0, v16, v24
+    vmrglb  v1, v16, v24
+    vmrghb  v2, v17, v25
+    vmrglb  v3, v17, v25
+    vmrghb  v4, v18, v26
+    vmrglb  v5, v18, v26
+    vmrghb  v6, v19, v27
+    vmrglb  v7, v19, v27
+    vmrghb  v8, v20, v28
+    vmrglb  v9, v20, v28
+    vmrghb  v10, v21, v29
+    vmrglb  v11, v21, v29
+    vmrghb  v12, v22, v30
+    vmrglb  v13, v22, v30
+    vmrghb  v14, v23, v31
+    vmrglb  v15, v23, v31
+    vmrghb  v16, v0, v8
+    vmrglb  v17, v0, v8
+    vmrghb  v18, v1, v9
+    vmrglb  v19, v1, v9
+    vmrghb  v20, v2, v10
+    vmrglb  v21, v2, v10
+    vmrghb  v22, v3, v11
+    vmrglb  v23, v3, v11
+    vmrghb  v24, v4, v12
+    vmrglb  v25, v4, v12
+    vmrghb  v26, v5, v13
+    vmrglb  v27, v5, v13
+    vmrghb  v28, v6, v14
+    vmrglb  v29, v6, v14
+    vmrghb  v30, v7, v15
+    vmrglb  v31, v7, v15
+    vmrghb  v0, v16, v24
+    vmrglb  v1, v16, v24
+    vmrghb  v2, v17, v25
+    vmrglb  v3, v17, v25
+    vmrghb  v4, v18, v26
+    vmrglb  v5, v18, v26
+    vmrghb  v6, v19, v27
+    vmrglb  v7, v19, v27
+    vmrghb  v8, v20, v28
+    vmrglb  v9, v20, v28
+    vmrghb  v10, v21, v29
+    vmrglb  v11, v21, v29
+    vmrghb  v12, v22, v30
+    vmrglb  v13, v22, v30
+    vmrghb  v14, v23, v31
+    vmrglb  v15, v23, v31
+    vmrghb  v16, v0, v8
+    vmrglb  v17, v0, v8
+    vmrghb  v18, v1, v9
+    vmrglb  v19, v1, v9
+    vmrghb  v20, v2, v10
+    vmrglb  v21, v2, v10
+    vmrghb  v22, v3, v11
+    vmrglb  v23, v3, v11
+    vmrghb  v24, v4, v12
+    vmrglb  v25, v4, v12
+    vmrghb  v26, v5, v13
+    vmrglb  v27, v5, v13
+    vmrghb  v28, v6, v14
+    vmrglb  v29, v6, v14
+    vmrghb  v30, v7, v15
+    vmrglb  v31, v7, v15
+.endm
+
+;# load_g loads a global vector (whose address is in the local variable Gptr)
+;#   into vector register Vreg.  Trashes r0
+.macro load_g Vreg, Gptr
+    lwz     r0, \Gptr
+    lvx     \Vreg, 0, r0
+.endm
+
+;# exploit the saturation here.  if the answer is negative
+;# it will be clamped to 0.  orring 0 with a positive
+;# number will be the positive number (abs)
+;# RES = abs( A-B), trashes TMP
+.macro Abs RES, TMP, A, B
+    vsububs \RES, \A, \B
+    vsububs \TMP, \B, \A
+    vor     \RES, \RES, \TMP
+.endm
+
+;# RES = Max( RES, abs( A-B)), trashes TMP
+.macro max_abs RES, TMP, A, B
+    vsububs \TMP, \A, \B
+    vmaxub  \RES, \RES, \TMP
+    vsububs \TMP, \B, \A
+    vmaxub  \RES, \RES, \TMP
+.endm
+
+.macro Masks
+    ;# build masks
+    ;# input is all 8 bit unsigned (0-255).  need to
+    ;# do abs(vala-valb) > limit.  but no need to compare each
+    ;# value to the limit.  find the max of the absolute differences
+    ;# and compare that to the limit.
+    ;# First hev
+    Abs     v14, v13, v2, v3    ;# |P1 - P0|
+    max_abs  v14, v13, v5, v4    ;# |Q1 - Q0|
+
+    vcmpgtub v10, v14, v10      ;# HEV = true if thresh exceeded
+
+    ;# Next limit
+    max_abs  v14, v13, v0, v1    ;# |P3 - P2|
+    max_abs  v14, v13, v1, v2    ;# |P2 - P1|
+    max_abs  v14, v13, v6, v5    ;# |Q2 - Q1|
+    max_abs  v14, v13, v7, v6    ;# |Q3 - Q2|
+
+    vcmpgtub v9, v14, v9        ;# R = true if limit exceeded
+
+    ;# flimit
+    Abs     v14, v13, v3, v4    ;# |P0 - Q0|
+
+    vcmpgtub v8, v14, v8        ;# X = true if flimit exceeded
+
+    vor     v8, v8, v9          ;# R = true if flimit or limit exceeded
+    ;# done building masks
+.endm
+
+.macro build_constants RFL, RLI, RTH, FL, LI, TH
+    ;# build constants
+    lvx     \FL, 0, \RFL        ;# flimit
+    lvx     \LI, 0, \RLI        ;# limit
+    lvx     \TH, 0, \RTH        ;# thresh
+
+    vspltisb v11, 8
+    vspltisb v12, 4
+    vslb    v11, v11, v12       ;# 0x80808080808080808080808080808080
+.endm
+
+.macro load_data_y
+    ;# setup strides/pointers to be able to access
+    ;# all of the data
+    add     r5, r4, r4          ;# r5 = 2 * stride
+    sub     r6, r3, r5          ;# r6 -> 2 rows back
+    neg     r7, r4              ;# r7 = -stride
+
+    ;# load 16 pixels worth of data to work on
+    sub     r0, r6, r5          ;# r0 -> 4 rows back (temp)
+    lvx     v0,  0, r0          ;# P3  (read only)
+    lvx     v1, r7, r6          ;# P2
+    lvx     v2,  0, r6          ;# P1
+    lvx     v3, r7, r3          ;# P0
+    lvx     v4,  0, r3          ;# Q0
+    lvx     v5, r4, r3          ;# Q1
+    lvx     v6, r5, r3          ;# Q2
+    add     r0, r3, r5          ;# r0 -> 2 rows fwd (temp)
+    lvx     v7, r4, r0          ;# Q3  (read only)
+.endm
+
+;# Expects
+;#  v10 == HEV
+;#  v13 == tmp
+;#  v14 == tmp
+.macro common_adjust P0, Q0, P1, Q1, HEV_PRESENT
+    vxor    \P1, \P1, v11       ;# SP1
+    vxor    \P0, \P0, v11       ;# SP0
+    vxor    \Q0, \Q0, v11       ;# SQ0
+    vxor    \Q1, \Q1, v11       ;# SQ1
+
+    vsubsbs v13, \P1, \Q1       ;# f  = c (P1 - Q1)
+.if \HEV_PRESENT
+    vand    v13, v13, v10       ;# f &= hev
+.endif
+    vsubsbs v14, \Q0, \P0       ;# -126 <=  X = Q0-P0  <= +126
+    vaddsbs v13, v13, v14
+    vaddsbs v13, v13, v14
+    vaddsbs v13, v13, v14       ;# A = c( c(P1-Q1) + 3*(Q0-P0))
+
+    vandc   v13, v13, v8        ;# f &= mask
+
+    vspltisb v8, 3
+    vspltisb v9, 4
+
+    vaddsbs v14, v13, v9        ;# f1 = c (f+4)
+    vaddsbs v15, v13, v8        ;# f2 = c (f+3)
+
+    vsrab   v13, v14, v8        ;# f1 >>= 3
+    vsrab   v15, v15, v8        ;# f2 >>= 3
+
+    vsubsbs \Q0, \Q0, v13       ;# u1 = c (SQ0 - f1)
+    vaddsbs \P0, \P0, v15       ;# u2 = c (SP0 + f2)
+.endm
+
+.macro vp8_mbfilter
+    Masks
+
+    ;# start the fitering here
+    vxor    v1, v1, v11         ;# SP2
+    vxor    v2, v2, v11         ;# SP1
+    vxor    v3, v3, v11         ;# SP0
+    vxor    v4, v4, v11         ;# SQ0
+    vxor    v5, v5, v11         ;# SQ1
+    vxor    v6, v6, v11         ;# SQ2
+
+    ;# add outer taps if we have high edge variance
+    vsubsbs v13, v2, v5         ;# f  = c (SP1-SQ1)
+
+    vsubsbs v14, v4, v3         ;# SQ0-SP0
+    vaddsbs v13, v13, v14
+    vaddsbs v13, v13, v14
+    vaddsbs v13, v13, v14       ;# f  = c( c(SP1-SQ1) + 3*(SQ0-SP0))
+
+    vandc   v13, v13, v8        ;# f &= mask
+    vand    v15, v13, v10       ;# f2 = f & hev
+
+    ;# save bottom 3 bits so that we round one side +4 and the other +3
+    vspltisb v8, 3
+    vspltisb v9, 4
+
+    vaddsbs v14, v15, v9        ;# f1 = c (f+4)
+    vaddsbs v15, v15, v8        ;# f2 = c (f+3)
+
+    vsrab   v14, v14, v8        ;# f1 >>= 3
+    vsrab   v15, v15, v8        ;# f2 >>= 3
+
+    vsubsbs v4, v4, v14         ;# u1 = c (SQ0 - f1)
+    vaddsbs v3, v3, v15         ;# u2 = c (SP0 + f2)
+
+    ;# only apply wider filter if not high edge variance
+    vandc   v13, v13, v10       ;# f &= ~hev
+
+    vspltisb v9, 2
+    vnor    v8, v8, v8
+    vsrb    v9, v8, v9          ;# 0x3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f
+    vupkhsb v9, v9              ;# 0x003f003f003f003f003f003f003f003f
+    vspltisb v8, 9
+
+    ;# roughly 1/7th difference across boundary
+    vspltish v10, 7
+    vmulosb v14, v8, v13        ;# A = c( c(P1-Q1) + 3*(Q0-P0))
+    vmulesb v15, v8, v13
+    vaddshs v14, v14, v9        ;# +=  63
+    vaddshs v15, v15, v9
+    vsrah   v14, v14, v10       ;# >>= 7
+    vsrah   v15, v15, v10
+    vmrglh  v10, v15, v14
+    vmrghh  v15, v15, v14
+
+    vpkshss v10, v15, v10       ;# X = saturated down to bytes
+
+    vsubsbs v6, v6, v10         ;# subtract from Q and add to P
+    vaddsbs v1, v1, v10
+
+    vxor    v6, v6, v11
+    vxor    v1, v1, v11
+
+    ;# roughly 2/7th difference across boundary
+    vspltish v10, 7
+    vaddubm v12, v8, v8
+    vmulosb v14, v12, v13       ;# A = c( c(P1-Q1) + 3*(Q0-P0))
+    vmulesb v15, v12, v13
+    vaddshs v14, v14, v9
+    vaddshs v15, v15, v9
+    vsrah   v14, v14, v10       ;# >>= 7
+    vsrah   v15, v15, v10
+    vmrglh  v10, v15, v14
+    vmrghh  v15, v15, v14
+
+    vpkshss v10, v15, v10       ;# X = saturated down to bytes
+
+    vsubsbs v5, v5, v10         ;# subtract from Q and add to P
+    vaddsbs v2, v2, v10
+
+    vxor    v5, v5, v11
+    vxor    v2, v2, v11
+
+    ;# roughly 3/7th difference across boundary
+    vspltish v10, 7
+    vaddubm v12, v12, v8
+    vmulosb v14, v12, v13       ;# A = c( c(P1-Q1) + 3*(Q0-P0))
+    vmulesb v15, v12, v13
+    vaddshs v14, v14, v9
+    vaddshs v15, v15, v9
+    vsrah   v14, v14, v10       ;# >>= 7
+    vsrah   v15, v15, v10
+    vmrglh  v10, v15, v14
+    vmrghh  v15, v15, v14
+
+    vpkshss v10, v15, v10       ;# X = saturated down to bytes
+
+    vsubsbs v4, v4, v10         ;# subtract from Q and add to P
+    vaddsbs v3, v3, v10
+
+    vxor    v4, v4, v11
+    vxor    v3, v3, v11
+.endm
+
+.macro SBFilter
+    Masks
+
+    common_adjust v3, v4, v2, v5, 1
+
+    ;# outer tap adjustments
+    vspltisb v8, 1
+
+    vaddubm v13, v13, v8        ;# f  += 1
+    vsrab   v13, v13, v8        ;# f >>= 1
+
+    vandc   v13, v13, v10       ;# f &= ~hev
+
+    vsubsbs v5, v5, v13         ;# u1 = c (SQ1 - f)
+    vaddsbs v2, v2, v13         ;# u2 = c (SP1 + f)
+
+    vxor    v2, v2, v11
+    vxor    v3, v3, v11
+    vxor    v4, v4, v11
+    vxor    v5, v5, v11
+.endm
+
+    .align 2
+mbloop_filter_horizontal_edge_y_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    build_constants r5, r6, r7, v8, v9, v10
+
+    load_data_y
+
+    vp8_mbfilter
+
+    stvx     v1, r7, r6         ;# P2
+    stvx     v2,  0, r6         ;# P1
+    stvx     v3, r7, r3         ;# P0
+    stvx     v4,  0, r3         ;# Q0
+    stvx     v5, r4, r3         ;# Q1
+    stvx     v6, r5, r3         ;# Q2
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;#  r3 unsigned char *s
+;#  r4 int p
+;#  r5 const signed char *flimit
+;#  r6 const signed char *limit
+;#  r7 const signed char *thresh
+loop_filter_horizontal_edge_y_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    build_constants r5, r6, r7, v8, v9, v10
+
+    load_data_y
+
+    SBFilter
+
+    stvx     v2,  0, r6         ;# P1
+    stvx     v3, r7, r3         ;# P0
+    stvx     v4,  0, r3         ;# Q0
+    stvx     v5, r4, r3         ;# Q1
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+;# Filtering a vertical mb.  Each mb is aligned on a 16 byte boundary.
+;#  So we can read in an entire mb aligned.  However if we want to filter the mb
+;#  edge we run into problems.  For the loopfilter we require 4 bytes before the mb
+;#  and 4 after for a total of 8 bytes.  Reading 16 bytes inorder to get 4 is a bit
+;#  of a waste.  So this is an even uglier way to get around that.
+;# Using the regular register file words are read in and then saved back out to
+;#  memory to align and order them up.  Then they are read in using the
+;#  vector register file.
+.macro RLVmb V, R
+    lwzux   r0, r3, r4
+    stw     r0, 4(\R)
+    lwz     r0,-4(r3)
+    stw     r0, 0(\R)
+    lwzux   r0, r3, r4
+    stw     r0,12(\R)
+    lwz     r0,-4(r3)
+    stw     r0, 8(\R)
+    lvx     \V, 0, \R
+.endm
+
+.macro WLVmb V, R
+    stvx    \V, 0, \R
+    lwz     r0,12(\R)
+    stwux   r0, r3, r4
+    lwz     r0, 8(\R)
+    stw     r0,-4(r3)
+    lwz     r0, 4(\R)
+    stwux   r0, r3, r4
+    lwz     r0, 0(\R)
+    stw     r0,-4(r3)
+.endm
+
+    .align 2
+;#  r3 unsigned char *s
+;#  r4 int p
+;#  r5 const signed char *flimit
+;#  r6 const signed char *limit
+;#  r7 const signed char *thresh
+mbloop_filter_vertical_edge_y_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xc000
+    mtspr   256, r12            ;# set VRSAVE
+
+    la      r9, -48(r1)         ;# temporary space for reading in vectors
+    sub     r3, r3, r4
+
+    RLVmb v0, r9
+    RLVmb v1, r9
+    RLVmb v2, r9
+    RLVmb v3, r9
+    RLVmb v4, r9
+    RLVmb v5, r9
+    RLVmb v6, r9
+    RLVmb v7, r9
+
+    transpose8x16_fwd
+
+    build_constants r5, r6, r7, v8, v9, v10
+
+    vp8_mbfilter
+
+    transpose8x16_inv
+
+    add r3, r3, r4
+    neg r4, r4
+
+    WLVmb v17, r9
+    WLVmb v16, r9
+    WLVmb v15, r9
+    WLVmb v14, r9
+    WLVmb v13, r9
+    WLVmb v12, r9
+    WLVmb v11, r9
+    WLVmb v10, r9
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+.macro RL V, R, P
+    lvx     \V, 0,  \R
+    add     \R, \R, \P
+.endm
+
+.macro WL V, R, P
+    stvx    \V, 0,  \R
+    add     \R, \R, \P
+.endm
+
+.macro Fil P3, P2, P1, P0, Q0, Q1, Q2, Q3
+                                ;# K = |P0-P1| already
+    Abs     v14, v13, \Q0, \Q1  ;# M = |Q0-Q1|
+    vmaxub  v14, v14, v4        ;# M = max( |P0-P1|, |Q0-Q1|)
+    vcmpgtub v10, v14, v0
+
+    Abs     v4, v5, \Q2, \Q3    ;# K = |Q2-Q3| = next |P0-P1]
+
+    max_abs  v14, v13, \Q1, \Q2  ;# M = max( M, |Q1-Q2|)
+    max_abs  v14, v13, \P1, \P2  ;# M = max( M, |P1-P2|)
+    max_abs  v14, v13, \P2, \P3  ;# M = max( M, |P2-P3|)
+
+    vmaxub   v14, v14, v4       ;# M = max interior abs diff
+    vcmpgtub v9, v14, v2        ;# M = true if int_l exceeded
+
+    Abs     v14, v13, \P0, \Q0  ;# X = Abs( P0-Q0)
+    vcmpgtub v8, v14, v3        ;# X = true if edge_l exceeded
+    vor     v8, v8, v9          ;# M = true if edge_l or int_l exceeded
+
+    ;# replace P1,Q1 w/signed versions
+    common_adjust \P0, \Q0, \P1, \Q1, 1
+
+    vaddubm v13, v13, v1        ;# -16 <= M <= 15, saturation irrelevant
+    vsrab   v13, v13, v1
+    vandc   v13, v13, v10       ;# adjust P1,Q1 by (M+1)>>1  if ! hev
+    vsubsbs \Q1, \Q1, v13
+    vaddsbs \P1, \P1, v13
+
+    vxor    \P1, \P1, v11       ;# P1
+    vxor    \P0, \P0, v11       ;# P0
+    vxor    \Q0, \Q0, v11       ;# Q0
+    vxor    \Q1, \Q1, v11       ;# Q1
+.endm
+
+
+    .align 2
+;#  r3 unsigned char *s
+;#  r4 int p
+;#  r5 const signed char *flimit
+;#  r6 const signed char *limit
+;#  r7 const signed char *thresh
+loop_filter_vertical_edge_y_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    addi    r9, r3, 0
+    RL      v16, r9, r4
+    RL      v17, r9, r4
+    RL      v18, r9, r4
+    RL      v19, r9, r4
+    RL      v20, r9, r4
+    RL      v21, r9, r4
+    RL      v22, r9, r4
+    RL      v23, r9, r4
+    RL      v24, r9, r4
+    RL      v25, r9, r4
+    RL      v26, r9, r4
+    RL      v27, r9, r4
+    RL      v28, r9, r4
+    RL      v29, r9, r4
+    RL      v30, r9, r4
+    lvx     v31, 0, r9
+
+    Transpose16x16
+
+    vspltisb v1, 1
+
+    build_constants r5, r6, r7, v3, v2, v0
+
+    Abs v4, v5, v19, v18                            ;# K(v14) = first |P0-P1|
+
+    Fil v16, v17, v18, v19,  v20, v21, v22, v23
+    Fil v20, v21, v22, v23,  v24, v25, v26, v27
+    Fil v24, v25, v26, v27,  v28, v29, v30, v31
+
+    Transpose16x16
+
+    addi    r9, r3, 0
+    WL      v16, r9, r4
+    WL      v17, r9, r4
+    WL      v18, r9, r4
+    WL      v19, r9, r4
+    WL      v20, r9, r4
+    WL      v21, r9, r4
+    WL      v22, r9, r4
+    WL      v23, r9, r4
+    WL      v24, r9, r4
+    WL      v25, r9, r4
+    WL      v26, r9, r4
+    WL      v27, r9, r4
+    WL      v28, r9, r4
+    WL      v29, r9, r4
+    WL      v30, r9, r4
+    stvx    v31, 0, r9
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+;# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- UV FILTERING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.macro active_chroma_sel V
+    andi.   r7, r3, 8       ;# row origin modulo 16
+    add     r7, r7, r7      ;# selects selectors
+    lis     r12, _chromaSelectors@ha
+    la      r0,  _chromaSelectors@l(r12)
+    lwzux   r0, r7, r0      ;# leave selector addr in r7
+
+    lvx     \V, 0, r0       ;# mask to concatenate active U,V pels
+.endm
+
+.macro hread_uv Dest, U, V, Offs, VMask
+    lvx     \U, \Offs, r3
+    lvx     \V, \Offs, r4
+    vperm   \Dest, \U, \V, \VMask   ;# Dest = active part of U then V
+.endm
+
+.macro hwrite_uv New, U, V, Offs, Umask, Vmask
+    vperm   \U, \New, \U, \Umask    ;# Combine new pels with siblings
+    vperm   \V, \New, \V, \Vmask
+    stvx    \U, \Offs, r3           ;# Write to frame buffer
+    stvx    \V, \Offs, r4
+.endm
+
+;# Process U,V in parallel.
+.macro load_chroma_h
+    neg     r9, r5          ;# r9 = -1 * stride
+    add     r8, r9, r9      ;# r8 = -2 * stride
+    add     r10, r5, r5     ;# r10 = 2 * stride
+
+    active_chroma_sel v12
+
+    ;# P3, Q3 are read-only; need not save addresses or sibling pels
+    add     r6, r8, r8      ;# r6 = -4 * stride
+    hread_uv v0, v14, v15, r6, v12
+    add     r6, r10, r5     ;# r6 =  3 * stride
+    hread_uv v7, v14, v15, r6, v12
+
+    ;# Others are read/write; save addresses and sibling pels
+
+    add     r6, r8, r9      ;# r6 = -3 * stride
+    hread_uv v1, v16, v17, r6,  v12
+    hread_uv v2, v18, v19, r8,  v12
+    hread_uv v3, v20, v21, r9,  v12
+    hread_uv v4, v22, v23, 0,   v12
+    hread_uv v5, v24, v25, r5,  v12
+    hread_uv v6, v26, v27, r10, v12
+.endm
+
+.macro uresult_sel V
+    load_g   \V, 4(r7)
+.endm
+
+.macro vresult_sel V
+    load_g   \V, 8(r7)
+.endm
+
+;# always write P1,P0,Q0,Q1
+.macro store_chroma_h
+    uresult_sel v11
+    vresult_sel v12
+    hwrite_uv v2, v18, v19, r8, v11, v12
+    hwrite_uv v3, v20, v21, r9, v11, v12
+    hwrite_uv v4, v22, v23, 0,  v11, v12
+    hwrite_uv v5, v24, v25, r5, v11, v12
+.endm
+
+    .align 2
+;#  r3 unsigned char *u
+;#  r4 unsigned char *v
+;#  r5 int p
+;#  r6 const signed char *flimit
+;#  r7 const signed char *limit
+;#  r8 const signed char *thresh
+mbloop_filter_horizontal_edge_uv_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    build_constants r6, r7, r8, v8, v9, v10
+
+    load_chroma_h
+
+    vp8_mbfilter
+
+    store_chroma_h
+
+    hwrite_uv v1, v16, v17, r6,  v11, v12    ;# v1 == P2
+    hwrite_uv v6, v26, v27, r10, v11, v12    ;# v6 == Q2
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;#  r3 unsigned char *u
+;#  r4 unsigned char *v
+;#  r5 int p
+;#  r6 const signed char *flimit
+;#  r7 const signed char *limit
+;#  r8 const signed char *thresh
+loop_filter_horizontal_edge_uv_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    build_constants r6, r7, r8, v8, v9, v10
+
+    load_chroma_h
+
+    SBFilter
+
+    store_chroma_h
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+.macro R V, R
+    lwzux   r0, r3, r5
+    stw     r0, 4(\R)
+    lwz     r0,-4(r3)
+    stw     r0, 0(\R)
+    lwzux   r0, r4, r5
+    stw     r0,12(\R)
+    lwz     r0,-4(r4)
+    stw     r0, 8(\R)
+    lvx     \V, 0, \R
+.endm
+
+
+.macro W V, R
+    stvx    \V, 0, \R
+    lwz     r0,12(\R)
+    stwux   r0, r4, r5
+    lwz     r0, 8(\R)
+    stw     r0,-4(r4)
+    lwz     r0, 4(\R)
+    stwux   r0, r3, r5
+    lwz     r0, 0(\R)
+    stw     r0,-4(r3)
+.endm
+
+.macro chroma_vread R
+    sub r3, r3, r5          ;# back up one line for simplicity
+    sub r4, r4, r5
+
+    R v0, \R
+    R v1, \R
+    R v2, \R
+    R v3, \R
+    R v4, \R
+    R v5, \R
+    R v6, \R
+    R v7, \R
+
+    transpose8x16_fwd
+.endm
+
+.macro chroma_vwrite R
+
+    transpose8x16_inv
+
+    add     r3, r3, r5
+    add     r4, r4, r5
+    neg     r5, r5          ;# Write rows back in reverse order
+
+    W v17, \R
+    W v16, \R
+    W v15, \R
+    W v14, \R
+    W v13, \R
+    W v12, \R
+    W v11, \R
+    W v10, \R
+.endm
+
+    .align 2
+;#  r3 unsigned char *u
+;#  r4 unsigned char *v
+;#  r5 int p
+;#  r6 const signed char *flimit
+;#  r7 const signed char *limit
+;#  r8 const signed char *thresh
+mbloop_filter_vertical_edge_uv_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xc000
+    mtspr   256, r12            ;# set VRSAVE
+
+    la      r9, -48(r1)         ;# temporary space for reading in vectors
+
+    chroma_vread r9
+
+    build_constants r6, r7, r8, v8, v9, v10
+
+    vp8_mbfilter
+
+    chroma_vwrite r9
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;#  r3 unsigned char *u
+;#  r4 unsigned char *v
+;#  r5 int p
+;#  r6 const signed char *flimit
+;#  r7 const signed char *limit
+;#  r8 const signed char *thresh
+loop_filter_vertical_edge_uv_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xc000
+    mtspr   256, r12            ;# set VRSAVE
+
+    la      r9, -48(r1)         ;# temporary space for reading in vectors
+
+    chroma_vread r9
+
+    build_constants r6, r7, r8, v8, v9, v10
+
+    SBFilter
+
+    chroma_vwrite r9
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+;# -=-=-=-=-=-=-=-=-=-=-=-=-=-= SIMPLE LOOP FILTER =-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+.macro vp8_simple_filter
+    Abs v14, v13, v1, v2    ;# M = abs( P0 - Q0)
+    vcmpgtub v8, v14, v8    ;# v5 = true if _over_ limit
+
+    ;# preserve unsigned v0 and v3
+    common_adjust v1, v2, v0, v3, 0
+
+    vxor v1, v1, v11
+    vxor v2, v2, v11        ;# cvt Q0, P0 back to pels
+.endm
+
+.macro simple_vertical
+    addi    r8,  0, 16
+    addi    r7, r5, 32
+
+    lvx     v0,  0, r5
+    lvx     v1, r8, r5
+    lvx     v2,  0, r7
+    lvx     v3, r8, r7
+
+    lis     r12, _B_hihi@ha
+    la      r0,  _B_hihi@l(r12)
+    lvx     v16, 0, r0
+
+    lis     r12, _B_lolo@ha
+    la      r0,  _B_lolo@l(r12)
+    lvx     v17, 0, r0
+
+    Transpose4times4x4 v16, v17
+    vp8_simple_filter
+
+    vxor v0, v0, v11
+    vxor v3, v3, v11        ;# cvt Q0, P0 back to pels
+
+    Transpose4times4x4 v16, v17
+
+    stvx    v0,  0, r5
+    stvx    v1, r8, r5
+    stvx    v2,  0, r7
+    stvx    v3, r8, r7
+.endm
+
+    .align 2
+;#  r3 unsigned char *s
+;#  r4 int p
+;#  r5 const signed char *flimit
+loop_filter_simple_horizontal_edge_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    ;# build constants
+    lvx     v8, 0, r5           ;# flimit
+
+    vspltisb v11, 8
+    vspltisb v12, 4
+    vslb    v11, v11, v12       ;# 0x80808080808080808080808080808080
+
+    neg     r5, r4              ;# r5 = -1 * stride
+    add     r6, r5, r5          ;# r6 = -2 * stride
+
+    lvx     v0, r6, r3          ;# v0 = P1 = 16 pels two rows above edge
+    lvx     v1, r5, r3          ;# v1 = P0 = 16 pels one row  above edge
+    lvx     v2,  0, r3          ;# v2 = Q0 = 16 pels one row  below edge
+    lvx     v3, r4, r3          ;# v3 = Q1 = 16 pels two rows below edge
+
+    vp8_simple_filter
+
+    stvx    v1, r5, r3          ;# store P0
+    stvx    v2,  0, r3          ;# store Q0
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+.macro RLV Offs
+    stw     r0, (\Offs*4)(r5)
+    lwzux   r0, r7, r4
+.endm
+
+.macro WLV Offs
+    lwz     r0, (\Offs*4)(r5)
+    stwux   r0, r7, r4
+.endm
+
+    .align 2
+;#  r3 unsigned char *s
+;#  r4 int p
+;#  r5 const signed char *flimit
+loop_filter_simple_vertical_edge_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xc000
+    mtspr   256, r12            ;# set VRSAVE
+
+    ;# build constants
+    lvx     v8, 0, r5           ;# flimit
+
+    vspltisb v11, 8
+    vspltisb v12, 4
+    vslb    v11, v11, v12       ;# 0x80808080808080808080808080808080
+
+    la r5, -96(r1)              ;# temporary space for reading in vectors
+
+    ;# Store 4 pels at word "Offs" in temp array, then advance r7
+    ;#   to next row and read another 4 pels from the frame buffer.
+
+    subi    r7, r3,  2          ;# r7 -> 2 pels before start
+    lwzx    r0,  0, r7          ;# read first 4 pels
+
+    ;# 16 unaligned word accesses
+    RLV 0
+    RLV 4
+    RLV 8
+    RLV 12
+    RLV 1
+    RLV 5
+    RLV 9
+    RLV 13
+    RLV 2
+    RLV 6
+    RLV 10
+    RLV 14
+    RLV 3
+    RLV 7
+    RLV 11
+
+    stw     r0, (15*4)(r5)      ;# write last 4 pels
+
+    simple_vertical
+
+    ;# Read temp array, write frame buffer.
+    subi    r7, r3,  2          ;# r7 -> 2 pels before start
+    lwzx    r0,  0, r5          ;# read/write first 4 pels
+    stwx    r0,  0, r7
+
+    WLV 4
+    WLV 8
+    WLV 12
+    WLV 1
+    WLV 5
+    WLV 9
+    WLV 13
+    WLV 2
+    WLV 6
+    WLV 10
+    WLV 14
+    WLV 3
+    WLV 7
+    WLV 11
+    WLV 15
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .data
+
+_chromaSelectors:
+    .long   _B_hihi
+    .long   _B_Ures0
+    .long   _B_Vres0
+    .long   0
+    .long   _B_lolo
+    .long   _B_Ures8
+    .long   _B_Vres8
+    .long   0
+
+    .align 4
+_B_Vres8:
+    .byte   16, 17, 18, 19, 20, 21, 22, 23,  8,  9, 10, 11, 12, 13, 14, 15
+
+    .align 4
+_B_Ures8:
+    .byte   16, 17, 18, 19, 20, 21, 22, 23,  0,  1,  2,  3,  4,  5,  6,  7
+
+    .align 4
+_B_lolo:
+    .byte    8,  9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31
+
+    .align 4
+_B_Vres0:
+    .byte    8,  9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31
+    .align 4
+_B_Ures0:
+    .byte    0,  1,  2,  3,  4,  5,  6,  7, 24, 25, 26, 27, 28, 29, 30, 31
+
+    .align 4
+_B_hihi:
+    .byte    0,  1,  2,  3,  4,  5,  6,  7, 16, 17, 18, 19, 20, 21, 22, 23
diff --git a/vp8/common/ppc/platform_altivec.asm b/vp8/common/ppc/platform_altivec.asm
new file mode 100644 (file)
index 0000000..227ef2a
--- /dev/null
@@ -0,0 +1,58 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl save_platform_context
+    .globl restore_platform_context
+
+.macro W V P
+    stvx    \V,  0, \P
+    addi    \P, \P, 16
+.endm
+
+.macro R V P
+    lvx     \V,  0, \P
+    addi    \P, \P, 16
+.endm
+
+;# r3 context_ptr
+    .align 2
+save_platform_contex:
+    W v20, r3
+    W v21, r3
+    W v22, r3
+    W v23, r3
+    W v24, r3
+    W v25, r3
+    W v26, r3
+    W v27, r3
+    W v28, r3
+    W v29, r3
+    W v30, r3
+    W v31, r3
+
+    blr
+
+;# r3 context_ptr
+    .align 2
+restore_platform_context:
+    R v20, r3
+    R v21, r3
+    R v22, r3
+    R v23, r3
+    R v24, r3
+    R v25, r3
+    R v26, r3
+    R v27, r3
+    R v28, r3
+    R v29, r3
+    R v30, r3
+    R v31, r3
+
+    blr
diff --git a/vp8/common/ppc/recon_altivec.asm b/vp8/common/ppc/recon_altivec.asm
new file mode 100644 (file)
index 0000000..f478b95
--- /dev/null
@@ -0,0 +1,174 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl recon4b_ppc
+    .globl recon2b_ppc
+    .globl recon_b_ppc
+
+.macro row_of16 Diff Pred Dst Stride
+    lvx     v1,  0, \Pred           ;# v1 = pred = p0..p15
+    addi    \Pred, \Pred, 16        ;# next pred
+    vmrghb  v2, v0, v1              ;# v2 = 16-bit p0..p7
+    lvx     v3,  0, \Diff           ;# v3 = d0..d7
+    vaddshs v2, v2, v3              ;# v2 = r0..r7
+    vmrglb  v1, v0, v1              ;# v1 = 16-bit p8..p15
+    lvx     v3, r8, \Diff           ;# v3 = d8..d15
+    addi    \Diff, \Diff, 32        ;# next diff
+    vaddshs v3, v3, v1              ;# v3 = r8..r15
+    vpkshus v2, v2, v3              ;# v2 = 8-bit r0..r15
+    stvx    v2,  0, \Dst            ;# to dst
+    add     \Dst, \Dst, \Stride     ;# next dst
+.endm
+
+    .text
+    .align 2
+;#  r3 = short *diff_ptr,
+;#  r4 = unsigned char *pred_ptr,
+;#  r5 = unsigned char *dst_ptr,
+;#  r6 = int stride
+recon4b_ppc:
+    mfspr   r0, 256                     ;# get old VRSAVE
+    stw     r0, -8(r1)                  ;# save old VRSAVE to stack
+    oris    r0, r0, 0xf000
+    mtspr   256,r0                      ;# set VRSAVE
+
+    vxor    v0, v0, v0
+    li      r8, 16
+
+    row_of16 r3, r4, r5, r6
+    row_of16 r3, r4, r5, r6
+    row_of16 r3, r4, r5, r6
+    row_of16 r3, r4, r5, r6
+
+    lwz     r12, -8(r1)                 ;# restore old VRSAVE from stack
+    mtspr   256, r12                    ;# reset old VRSAVE
+
+    blr
+
+.macro two_rows_of8 Diff Pred Dst Stride write_first_four_pels
+    lvx     v1,  0, \Pred       ;# v1 = pred = p0..p15
+    vmrghb  v2, v0, v1          ;# v2 = 16-bit p0..p7
+    lvx     v3,  0, \Diff       ;# v3 = d0..d7
+    vaddshs v2, v2, v3          ;# v2 = r0..r7
+    vmrglb  v1, v0, v1          ;# v1 = 16-bit p8..p15
+    lvx     v3, r8, \Diff       ;# v2 = d8..d15
+    vaddshs v3, v3, v1          ;# v3 = r8..r15
+    vpkshus v2, v2, v3          ;# v3 = 8-bit r0..r15
+    stvx    v2,  0, r10         ;# 2 rows to dst from buf
+    lwz     r0, 0(r10)
+.if \write_first_four_pels
+    stw     r0, 0(\Dst)
+    .else
+    stwux   r0, \Dst, \Stride
+.endif
+    lwz     r0, 4(r10)
+    stw     r0, 4(\Dst)
+    lwz     r0, 8(r10)
+    stwux   r0, \Dst, \Stride       ;# advance dst to next row
+    lwz     r0, 12(r10)
+    stw     r0, 4(\Dst)
+.endm
+
+    .align 2
+;#  r3 = short *diff_ptr,
+;#  r4 = unsigned char *pred_ptr,
+;#  r5 = unsigned char *dst_ptr,
+;#  r6 = int stride
+
+recon2b_ppc:
+    mfspr   r0, 256                     ;# get old VRSAVE
+    stw     r0, -8(r1)                  ;# save old VRSAVE to stack
+    oris    r0, r0, 0xf000
+    mtspr   256,r0                      ;# set VRSAVE
+
+    vxor    v0, v0, v0
+    li      r8, 16
+
+    la      r10, -48(r1)                ;# buf
+
+    two_rows_of8 r3, r4, r5, r6, 1
+
+    addi    r4, r4, 16;                 ;# next pred
+    addi    r3, r3, 32;                 ;# next diff
+
+    two_rows_of8 r3, r4, r5, r6, 0
+
+    lwz     r12, -8(r1)                 ;# restore old VRSAVE from stack
+    mtspr   256, r12                    ;# reset old VRSAVE
+
+    blr
+
+.macro get_two_diff_rows
+    stw     r0, 0(r10)
+    lwz     r0, 4(r3)
+    stw     r0, 4(r10)
+    lwzu    r0, 32(r3)
+    stw     r0, 8(r10)
+    lwz     r0, 4(r3)
+    stw     r0, 12(r10)
+    lvx     v3, 0, r10
+.endm
+
+    .align 2
+;#  r3 = short *diff_ptr,
+;#  r4 = unsigned char *pred_ptr,
+;#  r5 = unsigned char *dst_ptr,
+;#  r6 = int stride
+recon_b_ppc:
+    mfspr   r0, 256                     ;# get old VRSAVE
+    stw     r0, -8(r1)                  ;# save old VRSAVE to stack
+    oris    r0, r0, 0xf000
+    mtspr   256,r0                      ;# set VRSAVE
+
+    vxor    v0, v0, v0
+
+    la      r10, -48(r1)    ;# buf
+
+    lwz     r0, 0(r4)
+    stw     r0, 0(r10)
+    lwz     r0, 16(r4)
+    stw     r0, 4(r10)
+    lwz     r0, 32(r4)
+    stw     r0, 8(r10)
+    lwz     r0, 48(r4)
+    stw     r0, 12(r10)
+
+    lvx     v1,  0, r10;    ;# v1 = pred = p0..p15
+
+    lwz r0, 0(r3)           ;# v3 = d0..d7
+
+    get_two_diff_rows
+
+    vmrghb  v2, v0, v1;     ;# v2 = 16-bit p0..p7
+    vaddshs v2, v2, v3;     ;# v2 = r0..r7
+
+    lwzu r0, 32(r3)         ;# v3 = d8..d15
+
+    get_two_diff_rows
+
+    vmrglb  v1, v0, v1;     ;# v1 = 16-bit p8..p15
+    vaddshs v3, v3, v1;     ;# v3 = r8..r15
+
+    vpkshus v2, v2, v3;     ;# v2 = 8-bit r0..r15
+    stvx    v2,  0, r10;    ;# 16 pels to dst from buf
+
+    lwz     r0, 0(r10)
+    stw     r0, 0(r5)
+    lwz     r0, 4(r10)
+    stwux   r0, r5, r6
+    lwz     r0, 8(r10)
+    stwux   r0, r5, r6
+    lwz     r0, 12(r10)
+    stwx    r0, r5, r6
+
+    lwz     r12, -8(r1)                 ;# restore old VRSAVE from stack
+    mtspr   256, r12                    ;# reset old VRSAVE
+
+    blr
diff --git a/vp8/common/ppc/systemdependent.c b/vp8/common/ppc/systemdependent.c
new file mode 100644 (file)
index 0000000..2847310
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "g_common.h"
+#include "subpixel.h"
+#include "loopfilter.h"
+#include "recon.h"
+#include "idct.h"
+#include "onyxc_int.h"
+
+void (*vp8_short_idct4x4)(short *input, short *output, int pitch);
+void (*vp8_short_idct4x4_1)(short *input, short *output, int pitch);
+void (*vp8_dc_only_idct)(short input_dc, short *output, int pitch);
+
+extern void (*vp8_post_proc_down_and_across)(
+    unsigned char *src_ptr,
+    unsigned char *dst_ptr,
+    int src_pixels_per_line,
+    int dst_pixels_per_line,
+    int rows,
+    int cols,
+    int flimit
+);
+
+extern void (*vp8_mbpost_proc_down)(unsigned char *dst, int pitch, int rows, int cols, int flimit);
+extern void vp8_mbpost_proc_down_c(unsigned char *dst, int pitch, int rows, int cols, int flimit);
+extern void (*vp8_mbpost_proc_across_ip)(unsigned char *src, int pitch, int rows, int cols, int flimit);
+extern void vp8_mbpost_proc_across_ip_c(unsigned char *src, int pitch, int rows, int cols, int flimit);
+
+extern void vp8_post_proc_down_and_across_c
+(
+    unsigned char *src_ptr,
+    unsigned char *dst_ptr,
+    int src_pixels_per_line,
+    int dst_pixels_per_line,
+    int rows,
+    int cols,
+    int flimit
+);
+void vp8_plane_add_noise_c(unsigned char *Start, unsigned int Width, unsigned int Height, int Pitch, int q, int a);
+
+extern copy_mem_block_function *vp8_copy_mem16x16;
+extern copy_mem_block_function *vp8_copy_mem8x8;
+extern copy_mem_block_function *vp8_copy_mem8x4;
+
+// PPC
+extern subpixel_predict_function sixtap_predict_ppc;
+extern subpixel_predict_function sixtap_predict8x4_ppc;
+extern subpixel_predict_function sixtap_predict8x8_ppc;
+extern subpixel_predict_function sixtap_predict16x16_ppc;
+extern subpixel_predict_function bilinear_predict4x4_ppc;
+extern subpixel_predict_function bilinear_predict8x4_ppc;
+extern subpixel_predict_function bilinear_predict8x8_ppc;
+extern subpixel_predict_function bilinear_predict16x16_ppc;
+
+extern copy_mem_block_function copy_mem16x16_ppc;
+
+void recon_b_ppc(short *diff_ptr, unsigned char *pred_ptr, unsigned char *dst_ptr, int stride);
+void recon2b_ppc(short *diff_ptr, unsigned char *pred_ptr, unsigned char *dst_ptr, int stride);
+void recon4b_ppc(short *diff_ptr, unsigned char *pred_ptr, unsigned char *dst_ptr, int stride);
+
+extern void short_idct4x4llm_ppc(short *input, short *output, int pitch);
+
+// Generic C
+extern subpixel_predict_function vp8_sixtap_predict_c;
+extern subpixel_predict_function vp8_sixtap_predict8x4_c;
+extern subpixel_predict_function vp8_sixtap_predict8x8_c;
+extern subpixel_predict_function vp8_sixtap_predict16x16_c;
+extern subpixel_predict_function vp8_bilinear_predict4x4_c;
+extern subpixel_predict_function vp8_bilinear_predict8x4_c;
+extern subpixel_predict_function vp8_bilinear_predict8x8_c;
+extern subpixel_predict_function vp8_bilinear_predict16x16_c;
+
+extern copy_mem_block_function vp8_copy_mem16x16_c;
+extern copy_mem_block_function vp8_copy_mem8x8_c;
+extern copy_mem_block_function vp8_copy_mem8x4_c;
+
+void vp8_recon_b_c(short *diff_ptr, unsigned char *pred_ptr, unsigned char *dst_ptr, int stride);
+void vp8_recon2b_c(short *diff_ptr, unsigned char *pred_ptr, unsigned char *dst_ptr, int stride);
+void vp8_recon4b_c(short *diff_ptr, unsigned char *pred_ptr, unsigned char *dst_ptr, int stride);
+
+extern void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch);
+extern void vp8_short_idct4x4llm_c(short *input, short *output, int pitch);
+extern void vp8_dc_only_idct_c(short input_dc, short *output, int pitch);
+
+// PPC
+extern loop_filter_block_function loop_filter_mbv_ppc;
+extern loop_filter_block_function loop_filter_bv_ppc;
+extern loop_filter_block_function loop_filter_mbh_ppc;
+extern loop_filter_block_function loop_filter_bh_ppc;
+
+extern loop_filter_block_function loop_filter_mbvs_ppc;
+extern loop_filter_block_function loop_filter_bvs_ppc;
+extern loop_filter_block_function loop_filter_mbhs_ppc;
+extern loop_filter_block_function loop_filter_bhs_ppc;
+
+// Generic C
+extern loop_filter_block_function vp8_loop_filter_mbv_c;
+extern loop_filter_block_function vp8_loop_filter_bv_c;
+extern loop_filter_block_function vp8_loop_filter_mbh_c;
+extern loop_filter_block_function vp8_loop_filter_bh_c;
+
+extern loop_filter_block_function vp8_loop_filter_mbvs_c;
+extern loop_filter_block_function vp8_loop_filter_bvs_c;
+extern loop_filter_block_function vp8_loop_filter_mbhs_c;
+extern loop_filter_block_function vp8_loop_filter_bhs_c;
+
+extern loop_filter_block_function *vp8_lf_mbvfull;
+extern loop_filter_block_function *vp8_lf_mbhfull;
+extern loop_filter_block_function *vp8_lf_bvfull;
+extern loop_filter_block_function *vp8_lf_bhfull;
+
+extern loop_filter_block_function *vp8_lf_mbvsimple;
+extern loop_filter_block_function *vp8_lf_mbhsimple;
+extern loop_filter_block_function *vp8_lf_bvsimple;
+extern loop_filter_block_function *vp8_lf_bhsimple;
+
+void vp8_clear_c(void)
+{
+}
+
+void vp8_machine_specific_config(void)
+{
+    // Pure C:
+    vp8_clear_system_state                = vp8_clear_c;
+    vp8_recon_b                          = vp8_recon_b_c;
+    vp8_recon4b                         = vp8_recon4b_c;
+    vp8_recon2b                         = vp8_recon2b_c;
+
+    vp8_bilinear_predict16x16            = bilinear_predict16x16_ppc;
+    vp8_bilinear_predict8x8              = bilinear_predict8x8_ppc;
+    vp8_bilinear_predict8x4              = bilinear_predict8x4_ppc;
+    vp8_bilinear_predict                 = bilinear_predict4x4_ppc;
+
+    vp8_sixtap_predict16x16              = sixtap_predict16x16_ppc;
+    vp8_sixtap_predict8x8                = sixtap_predict8x8_ppc;
+    vp8_sixtap_predict8x4                = sixtap_predict8x4_ppc;
+    vp8_sixtap_predict                   = sixtap_predict_ppc;
+
+    vp8_short_idct4x4_1                  = vp8_short_idct4x4llm_1_c;
+    vp8_short_idct4x4                    = short_idct4x4llm_ppc;
+    vp8_dc_only_idct                      = vp8_dc_only_idct_c;
+
+    vp8_lf_mbvfull                       = loop_filter_mbv_ppc;
+    vp8_lf_bvfull                        = loop_filter_bv_ppc;
+    vp8_lf_mbhfull                       = loop_filter_mbh_ppc;
+    vp8_lf_bhfull                        = loop_filter_bh_ppc;
+
+    vp8_lf_mbvsimple                     = loop_filter_mbvs_ppc;
+    vp8_lf_bvsimple                      = loop_filter_bvs_ppc;
+    vp8_lf_mbhsimple                     = loop_filter_mbhs_ppc;
+    vp8_lf_bhsimple                      = loop_filter_bhs_ppc;
+
+    vp8_post_proc_down_and_across           = vp8_post_proc_down_and_across_c;
+    vp8_mbpost_proc_down                  = vp8_mbpost_proc_down_c;
+    vp8_mbpost_proc_across_ip              = vp8_mbpost_proc_across_ip_c;
+    vp8_plane_add_noise                   = vp8_plane_add_noise_c;
+
+    vp8_copy_mem16x16                    = copy_mem16x16_ppc;
+    vp8_copy_mem8x8                      = vp8_copy_mem8x8_c;
+    vp8_copy_mem8x4                      = vp8_copy_mem8x4_c;
+
+}
diff --git a/vp8/common/ppflags.h b/vp8/common/ppflags.h
new file mode 100644 (file)
index 0000000..c663976
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_PPFLAGS_H
+#define __INC_PPFLAGS_H
+enum
+{
+    VP8D_NOFILTERING    = 0,
+    VP8D_DEBLOCK        = 1,
+    VP8D_DEMACROBLOCK   = 2,
+    VP8D_ADDNOISE       = 4,
+    VP8D_DEBUG_LEVEL1   = 8,
+    VP8D_DEBUG_LEVEL2   = 16,
+    VP8D_DEBUG_LEVEL3   = 32,
+    VP8D_DEBUG_LEVEL4   = 64,
+};
+
+#endif
diff --git a/vp8/common/pragmas.h b/vp8/common/pragmas.h
new file mode 100644 (file)
index 0000000..25a4b77
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+
+
+#ifdef __INTEL_COMPILER
+#pragma warning(disable:997 1011 170)
+#endif
+#ifdef _MSC_VER
+#pragma warning(disable:4799)
+#endif
diff --git a/vp8/common/predictdc.c b/vp8/common/predictdc.c
new file mode 100644 (file)
index 0000000..df4c96e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+#include "blockd.h"
+
+
+void vp8_predict_dc(short *lastdc, short *thisdc, short quant, short *cons)
+{
+    int diff;
+    int sign;
+    int last_dc = *lastdc;
+    int this_dc = *thisdc;
+
+    if (*cons  > DCPREDCNTTHRESH)
+    {
+        this_dc += last_dc;
+    }
+
+    diff = abs(last_dc - this_dc);
+    sign  = (last_dc >> 31) ^(this_dc >> 31);
+    sign |= (!last_dc | !this_dc);
+
+    if (sign)
+    {
+        *cons = 0;
+    }
+    else
+    {
+        if (diff <= DCPREDSIMTHRESH * quant)
+            (*cons)++ ;
+    }
+
+    *thisdc = this_dc;
+    *lastdc = this_dc;
+}
diff --git a/vp8/common/predictdc.h b/vp8/common/predictdc.h
new file mode 100644 (file)
index 0000000..b8871e4
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __PREDICTDC_H
+#define __PREDICTDC_H
+
+void uvvp8_predict_dc(short *lastdc, short *thisdc, short quant, short *cons);
+void vp8_predict_dc(short *lastdc, short *thisdc, short quant, short *cons);
+
+#endif
diff --git a/vp8/common/preproc.h b/vp8/common/preproc.h
new file mode 100644 (file)
index 0000000..00ec9a8
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     preproc.h
+*
+*   Description  :     simple preprocessor
+*
+****************************************************************************/
+
+#ifndef __INC_PREPROC_H
+#define __INC_PREPROC_H
+
+/****************************************************************************
+*  Types
+****************************************************************************/
+
+typedef struct
+{
+    unsigned char *frame_buffer;
+    int frame;
+    unsigned int *fixed_divide;
+
+    unsigned char *frame_buffer_alloc;
+    unsigned int *fixed_divide_alloc;
+} pre_proc_instance;
+
+/****************************************************************************
+*  Functions.
+****************************************************************************/
+void pre_proc_machine_specific_config(void);
+void delete_pre_proc(pre_proc_instance *ppi);
+int init_pre_proc(pre_proc_instance *ppi, int frame_size);
+extern void spatial_filter_c(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int width, int height, int pitch, int strength);
+extern void (*temp_filter)(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int bytes, int strength);
+
+#endif
diff --git a/vp8/common/preprocif.h b/vp8/common/preprocif.h
new file mode 100644 (file)
index 0000000..986c45b
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     preproc_if.h
+*
+*   Description  :     Pre-processor interface header file.
+*
+****************************************************************************/
+
+#ifndef __PREPROC_IF_H
+#define __PREPROC_IF_H
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "type_aliases.h"
+
+/****************************************************************************
+*  Types
+****************************************************************************/
+
+typedef struct
+{
+    UINT8 *Yuv0ptr;
+    UINT8 *Yuv1ptr;
+
+    UINT8   *frag_info;              // blocks coded : passed in
+    UINT32   frag_info_element_size;   // size of each element
+    UINT32   frag_info_coded_mask;     // mask to get at whether fragment is coded
+
+    UINT32 *region_index;            // Gives pixel index for top left of each block
+    UINT32 video_frame_height;
+    UINT32 video_frame_width;
+    UINT8 hfrag_pixels;
+    UINT8 vfrag_pixels;
+
+} SCAN_CONFIG_DATA;
+
+typedef enum
+{
+    SCP_FILTER_ON_OFF,
+    SCP_SET_SRF_OFFSET,
+    SCP_SET_EBO_ON_OFF,
+    SCP_SET_VCAP_LEVEL_OFFSET,
+    SCP_SET_SHOW_LOCAL
+
+} SCP_SETTINGS;
+
+typedef struct PP_INSTANCE *x_pp_inst;
+
+/****************************************************************************
+*  Module statics
+****************************************************************************/
+/* Controls whether Early break out is on or off in default case */
+#define EARLY_BREAKOUT_DEFAULT  TRUE
+
+/****************************************************************************
+*  Functions
+****************************************************************************/
+extern  void set_scan_param(x_pp_inst ppi, UINT32 param_id, INT32 param_value);
+extern  UINT32 yuvanalyse_frame(x_pp_inst ppi, UINT32 *KFIndicator);
+extern  x_pp_inst create_pp_instance(void);
+extern  void delete_pp_instance(x_pp_inst *);
+extern  BOOL scan_yuvinit(x_pp_inst,  SCAN_CONFIG_DATA *scan_config_ptr);
+
+#endif
diff --git a/vp8/common/proposed.h b/vp8/common/proposed.h
new file mode 100644 (file)
index 0000000..1171ede
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+typedef struct core_codec *codec_ptr;
+typedef struct interface_table *interface_ptr;
+
+typedef struct
+{
+    void (*Initialize)();
+    void (*Shutdown)();
+    codec_ptr(*Create)();
+    int (*compress_frame)(codec_ptr, unsigned int *frame_flags, YV12_BUFFER_CONFIG *sd, unsigned long *size, char *dest, INT64 time_stamp);
+    int (*show_frame)(codec_ptr , YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags);
+    void (*Remove)(codec_ptr *comp);
+    interface_ptr(*get_interface)(unsigned int id);
+
+} core_codec;
+
+typedef struct
+{
+    int (*set_bitrate)(codec_ptr, END_USAGE usage, int Datarate);
+    int (*get_bitrate)(codec_ptr, END_USAGE *usage, int *Datarate);
+    int (*set_mode)(codec_ptr, MODE mode, int Speed, char *File);
+    int (*get_mode)(codec_ptr, MODE *mode, int *Speed, char **File);
+} codec_settings_basic;
+
+typedef struct
+{
+    int (*set_bitrate)(codec_ptr, END_USAGE usage, int Datarate);
+    int (*get_bitrate)(codec_ptr, END_USAGE *usage, int *Datarate);
+    int (*set_mode)(codec_ptr, MODE  mode, int  Speed, char   *File);
+    int (*get_mode)(codec_ptr, MODE *mode, int *Speed, char **File);
+    int (*set_denoise)(codec_ptr, int  Level);
+    int (*get_denoise)(codec_ptr, int *Level);
+    int (*set_sharpness)(codec_ptr, int  sharpness);
+    int (*get_sharpness)(codec_ptr, int *sharpness);
+    int (*set_keyframing)(codec_ptr, int  Auto, int  max_distance);
+    int (*get_keyframing)(codec_ptr, int *Auto, int *max_distance);
+    int (*set_buffering)(codec_ptr, int  buffer_level, int  max_buffer_level);
+    int (*get_buffering)(codec_ptr, int *buffer_level, int *max_buffer_level);
+    int (*set_adjust_frame_rate)(codec_ptr, int Allowed, int at_buffer_level_pct);
+    int (*get_adjust_frame_rate)(codec_ptr, int *Allowed, int *at_buffer_level_pct);
+    int (*set_adjust_frame_size)(codec_ptr, int Allowed, int down_at_buffer_level_pct, int up_at_buffer_level_pct);
+    int (*get_adjust_frame_size)(codec_ptr, int *Allowed, int *down_at_buffer_level_pct, int *up_at_buffer_level_pct);
+    int (*set_adjust_quality)(codec_ptr, int Allowed, int min_quantizer, int max_quantizer);
+    int (*get_adjust_quality)(codec_ptr, int *Allowed, int *min_quantizer, int *max_quantizer);
+    int (*set_vbrparms)(codec_ptr, int Bias, int Min, int Max);
+    int (*get_vbrparms)(codec_ptr, int *Bias, int *Min, int *Max);
+
+} codec_settings_v1;
+
+typedef struct
+{
+    int (*request_recovery)(codec_ptr);
+    int (*request_droppable)(codec_ptr);
+    int (*internal_size)(codec_ptr, VPX_SCALING Vertical, VPX_SCALING Horizontal);
+    int (*update_last)(codec_ptr);
+    int (*update_gold)(codec_ptr);
+    int (*use_only_last)(codec_ptr);
+    int (*use_only_gold)(codec_ptr);
+    int (*update_entropy)(codec_ptr);
+
+} codec_realtime_requests;
diff --git a/vp8/common/quant_common.c b/vp8/common/quant_common.c
new file mode 100644 (file)
index 0000000..09fe31f
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "quant_common.h"
+
+static const int dc_qlookup[QINDEX_RANGE] =
+{
+    4,    5,    6,    7,    8,    9,   10,   10,   11,   12,   13,   14,   15,   16,   17,   17,
+    18,   19,   20,   20,   21,   21,   22,   22,   23,   23,   24,   25,   25,   26,   27,   28,
+    29,   30,   31,   32,   33,   34,   35,   36,   37,   37,   38,   39,   40,   41,   42,   43,
+    44,   45,   46,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
+    59,   60,   61,   62,   63,   64,   65,   66,   67,   68,   69,   70,   71,   72,   73,   74,
+    75,   76,   76,   77,   78,   79,   80,   81,   82,   83,   84,   85,   86,   87,   88,   89,
+    91,   93,   95,   96,   98,  100,  101,  102,  104,  106,  108,  110,  112,  114,  116,  118,
+    122,  124,  126,  128,  130,  132,  134,  136,  138,  140,  143,  145,  148,  151,  154,  157,
+};
+
+static const int ac_qlookup[QINDEX_RANGE] =
+{
+    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,
+    20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,
+    36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+    52,   53,   54,   55,   56,   57,   58,   60,   62,   64,   66,   68,   70,   72,   74,   76,
+    78,   80,   82,   84,   86,   88,   90,   92,   94,   96,   98,  100,  102,  104,  106,  108,
+    110,  112,  114,  116,  119,  122,  125,  128,  131,  134,  137,  140,  143,  146,  149,  152,
+    155,  158,  161,  164,  167,  170,  173,  177,  181,  185,  189,  193,  197,  201,  205,  209,
+    213,  217,  221,  225,  229,  234,  239,  245,  249,  254,  259,  264,  269,  274,  279,  284,
+};
+
+
+int vp8_dc_quant(int QIndex, int Delta)
+{
+    int retval;
+
+    QIndex = QIndex + Delta;
+
+    if (QIndex > 127)
+        QIndex = 127;
+    else if (QIndex < 0)
+        QIndex = 0;
+
+    retval = dc_qlookup[ QIndex ];
+    return retval;
+}
+
+int vp8_dc2quant(int QIndex, int Delta)
+{
+    int retval;
+
+    QIndex = QIndex + Delta;
+
+    if (QIndex > 127)
+        QIndex = 127;
+    else if (QIndex < 0)
+        QIndex = 0;
+
+    retval = dc_qlookup[ QIndex ] * 2;
+    return retval;
+
+}
+int vp8_dc_uv_quant(int QIndex, int Delta)
+{
+    int retval;
+
+    QIndex = QIndex + Delta;
+
+    if (QIndex > 127)
+        QIndex = 127;
+    else if (QIndex < 0)
+        QIndex = 0;
+
+    retval = dc_qlookup[ QIndex ];
+
+    if (retval > 132)
+        retval = 132;
+
+    return retval;
+}
+
+int vp8_ac_yquant(int QIndex)
+{
+    int retval;
+
+    if (QIndex > 127)
+        QIndex = 127;
+    else if (QIndex < 0)
+        QIndex = 0;
+
+    retval = ac_qlookup[ QIndex ];
+    return retval;
+}
+
+int vp8_ac2quant(int QIndex, int Delta)
+{
+    int retval;
+
+    QIndex = QIndex + Delta;
+
+    if (QIndex > 127)
+        QIndex = 127;
+    else if (QIndex < 0)
+        QIndex = 0;
+
+    retval = (ac_qlookup[ QIndex ] * 155) / 100;
+
+    if (retval < 8)
+        retval = 8;
+
+    return retval;
+}
+int vp8_ac_uv_quant(int QIndex, int Delta)
+{
+    int retval;
+
+    QIndex = QIndex + Delta;
+
+    if (QIndex > 127)
+        QIndex = 127;
+    else if (QIndex < 0)
+        QIndex = 0;
+
+    retval = ac_qlookup[ QIndex ];
+    return retval;
+}
diff --git a/vp8/common/quant_common.h b/vp8/common/quant_common.h
new file mode 100644 (file)
index 0000000..0c92ce8
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "string.h"
+#include "blockd.h"
+#include "onyxc_int.h"
+
+extern int vp8_ac_yquant(int QIndex);
+extern int vp8_dc_quant(int QIndex, int Delta);
+extern int vp8_dc2quant(int QIndex, int Delta);
+extern int vp8_ac2quant(int QIndex, int Delta);
+extern int vp8_dc_uv_quant(int QIndex, int Delta);
+extern int vp8_ac_uv_quant(int QIndex, int Delta);
diff --git a/vp8/common/recon.c b/vp8/common/recon.c
new file mode 100644 (file)
index 0000000..d1268ea
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "recon.h"
+#include "blockd.h"
+
+void vp8_recon_b_c
+(
+    unsigned char *pred_ptr,
+    short *diff_ptr,
+    unsigned char *dst_ptr,
+    int stride
+)
+{
+    int r, c;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 4; c++)
+        {
+            int a = diff_ptr[c] + pred_ptr[c] ;
+
+            if (a < 0)
+                a = 0;
+
+            if (a > 255)
+                a = 255;
+
+            dst_ptr[c] = (unsigned char) a ;
+        }
+
+        dst_ptr += stride;
+        diff_ptr += 16;
+        pred_ptr += 16;
+    }
+}
+
+void vp8_recon4b_c
+(
+    unsigned char *pred_ptr,
+    short *diff_ptr,
+    unsigned char *dst_ptr,
+    int stride
+)
+{
+    int r, c;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 16; c++)
+        {
+            int a = diff_ptr[c] + pred_ptr[c] ;
+
+            if (a < 0)
+                a = 0;
+
+            if (a > 255)
+                a = 255;
+
+            dst_ptr[c] = (unsigned char) a ;
+        }
+
+        dst_ptr += stride;
+        diff_ptr += 16;
+        pred_ptr += 16;
+    }
+}
+
+void vp8_recon2b_c
+(
+    unsigned char *pred_ptr,
+    short *diff_ptr,
+    unsigned char *dst_ptr,
+    int stride
+)
+{
+    int r, c;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 8; c++)
+        {
+            int a = diff_ptr[c] + pred_ptr[c] ;
+
+            if (a < 0)
+                a = 0;
+
+            if (a > 255)
+                a = 255;
+
+            dst_ptr[c] = (unsigned char) a ;
+        }
+
+        dst_ptr += stride;
+        diff_ptr += 8;
+        pred_ptr += 8;
+    }
+}
+
+void vp8_recon16x16mby(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 4)
+    {
+        BLOCKD *b = &x->block[i];
+
+        RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+}
+
+void vp8_recon16x16mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 4)
+    {
+        BLOCKD *b = &x->block[i];
+
+        RECON_INVOKE(rtcd, recon4)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+
+    for (i = 16; i < 24; i += 2)
+    {
+        BLOCKD *b = &x->block[i];
+
+        RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+}
diff --git a/vp8/common/recon.h b/vp8/common/recon.h
new file mode 100644 (file)
index 0000000..f65a90f
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_RECON_H
+#define __INC_RECON_H
+
+#define prototype_copy_block(sym) \
+    void sym(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch)
+
+#define prototype_recon_block(sym) \
+    void sym(unsigned char *pred, short *diff, unsigned char *dst, int pitch);
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/recon_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/recon_arm.h"
+#endif
+
+#ifndef vp8_recon_copy16x16
+#define vp8_recon_copy16x16 vp8_copy_mem16x16_c
+#endif
+extern prototype_copy_block(vp8_recon_copy16x16);
+
+#ifndef vp8_recon_copy8x8
+#define vp8_recon_copy8x8 vp8_copy_mem8x8_c
+#endif
+extern prototype_copy_block(vp8_recon_copy8x8);
+
+#ifndef vp8_recon_copy8x4
+#define vp8_recon_copy8x4 vp8_copy_mem8x4_c
+#endif
+extern prototype_copy_block(vp8_recon_copy8x4);
+
+#ifndef vp8_recon_recon
+#define vp8_recon_recon vp8_recon_b_c
+#endif
+extern prototype_recon_block(vp8_recon_recon);
+
+#ifndef vp8_recon_recon2
+#define vp8_recon_recon2 vp8_recon2b_c
+#endif
+extern prototype_recon_block(vp8_recon_recon2);
+
+#ifndef vp8_recon_recon4
+#define vp8_recon_recon4 vp8_recon4b_c
+#endif
+extern prototype_recon_block(vp8_recon_recon4);
+
+typedef prototype_copy_block((*vp8_copy_block_fn_t));
+typedef prototype_recon_block((*vp8_recon_fn_t));
+typedef struct
+{
+    vp8_copy_block_fn_t  copy16x16;
+    vp8_copy_block_fn_t  copy8x8;
+    vp8_copy_block_fn_t  copy8x4;
+    vp8_recon_fn_t       recon;
+    vp8_recon_fn_t       recon2;
+    vp8_recon_fn_t       recon4;
+} vp8_recon_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define RECON_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define RECON_INVOKE(ctx,fn) vp8_recon_##fn
+#endif
+
+#include "blockd.h"
+void vp8_recon16x16mby(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+void vp8_recon16x16mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+void vp8_recon_intra4x4mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+void vp8_recon_intra_mbuv(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x);
+#endif
diff --git a/vp8/common/reconinter.c b/vp8/common/reconinter.c
new file mode 100644 (file)
index 0000000..c48886d
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "recon.h"
+#include "subpixel.h"
+#include "blockd.h"
+#include "reconinter.h"
+#if CONFIG_RUNTIME_CPU_DETECT
+#include "onyxc_int.h"
+#endif
+
+// use this define on systems where unaligned int reads and writes are
+// not allowed, i.e. ARM architectures
+//#define MUST_BE_ALIGNED
+
+
+static const int bbb[4] = {0, 2, 8, 10};
+
+
+
+void vp8_copy_mem16x16_c(
+    unsigned char *src,
+    int src_stride,
+    unsigned char *dst,
+    int dst_stride)
+{
+
+    int r;
+
+    for (r = 0; r < 16; r++)
+    {
+#ifdef MUST_BE_ALIGNED
+        dst[0] = src[0];
+        dst[1] = src[1];
+        dst[2] = src[2];
+        dst[3] = src[3];
+        dst[4] = src[4];
+        dst[5] = src[5];
+        dst[6] = src[6];
+        dst[7] = src[7];
+        dst[8] = src[8];
+        dst[9] = src[9];
+        dst[10] = src[10];
+        dst[11] = src[11];
+        dst[12] = src[12];
+        dst[13] = src[13];
+        dst[14] = src[14];
+        dst[15] = src[15];
+
+#else
+        ((int *)dst)[0] = ((int *)src)[0] ;
+        ((int *)dst)[1] = ((int *)src)[1] ;
+        ((int *)dst)[2] = ((int *)src)[2] ;
+        ((int *)dst)[3] = ((int *)src)[3] ;
+
+#endif
+        src += src_stride;
+        dst += dst_stride;
+
+    }
+
+}
+
+void vp8_copy_mem8x8_c(
+    unsigned char *src,
+    int src_stride,
+    unsigned char *dst,
+    int dst_stride)
+{
+    int r;
+
+    for (r = 0; r < 8; r++)
+    {
+#ifdef MUST_BE_ALIGNED
+        dst[0] = src[0];
+        dst[1] = src[1];
+        dst[2] = src[2];
+        dst[3] = src[3];
+        dst[4] = src[4];
+        dst[5] = src[5];
+        dst[6] = src[6];
+        dst[7] = src[7];
+#else
+        ((int *)dst)[0] = ((int *)src)[0] ;
+        ((int *)dst)[1] = ((int *)src)[1] ;
+#endif
+        src += src_stride;
+        dst += dst_stride;
+
+    }
+
+}
+
+void vp8_copy_mem8x4_c(
+    unsigned char *src,
+    int src_stride,
+    unsigned char *dst,
+    int dst_stride)
+{
+    int r;
+
+    for (r = 0; r < 4; r++)
+    {
+#ifdef MUST_BE_ALIGNED
+        dst[0] = src[0];
+        dst[1] = src[1];
+        dst[2] = src[2];
+        dst[3] = src[3];
+        dst[4] = src[4];
+        dst[5] = src[5];
+        dst[6] = src[6];
+        dst[7] = src[7];
+#else
+        ((int *)dst)[0] = ((int *)src)[0] ;
+        ((int *)dst)[1] = ((int *)src)[1] ;
+#endif
+        src += src_stride;
+        dst += dst_stride;
+
+    }
+
+}
+
+
+
+void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf)
+{
+    int r;
+    unsigned char *ptr_base;
+    unsigned char *ptr;
+    unsigned char *pred_ptr = d->predictor;
+
+    ptr_base = *(d->base_pre);
+
+    if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
+    {
+        ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+        sppf(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
+    }
+    else
+    {
+        ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+        ptr = ptr_base;
+
+        for (r = 0; r < 4; r++)
+        {
+#ifdef MUST_BE_ALIGNED
+            pred_ptr[0]  = ptr[0];
+            pred_ptr[1]  = ptr[1];
+            pred_ptr[2]  = ptr[2];
+            pred_ptr[3]  = ptr[3];
+#else
+            *(int *)pred_ptr = *(int *)ptr ;
+#endif
+            pred_ptr     += pitch;
+            ptr         += d->pre_stride;
+        }
+    }
+}
+
+void vp8_build_inter_predictors4b(MACROBLOCKD *x, BLOCKD *d, int pitch)
+{
+    unsigned char *ptr_base;
+    unsigned char *ptr;
+    unsigned char *pred_ptr = d->predictor;
+
+    ptr_base = *(d->base_pre);
+    ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+
+    if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
+    {
+        x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
+    }
+    else
+    {
+        RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, pred_ptr, pitch);
+    }
+}
+
+void vp8_build_inter_predictors2b(MACROBLOCKD *x, BLOCKD *d, int pitch)
+{
+    unsigned char *ptr_base;
+    unsigned char *ptr;
+    unsigned char *pred_ptr = d->predictor;
+
+    ptr_base = *(d->base_pre);
+    ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+
+    if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
+    {
+        x->subpixel_predict8x4(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, pred_ptr, pitch);
+    }
+    else
+    {
+        RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d->pre_stride, pred_ptr, pitch);
+    }
+}
+
+
+void vp8_build_inter_predictors_mbuv(MACROBLOCKD *x)
+{
+    int i;
+
+    if (x->mbmi.ref_frame != INTRA_FRAME && x->mbmi.mode != SPLITMV)
+    {
+        unsigned char *uptr, *vptr;
+        unsigned char *upred_ptr = &x->predictor[256];
+        unsigned char *vpred_ptr = &x->predictor[320];
+
+        int mv_row = x->block[16].bmi.mv.as_mv.row;
+        int mv_col = x->block[16].bmi.mv.as_mv.col;
+        int offset;
+        int pre_stride = x->block[16].pre_stride;
+
+        offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
+        uptr = x->pre.u_buffer + offset;
+        vptr = x->pre.v_buffer + offset;
+
+        if ((mv_row | mv_col) & 7)
+        {
+            x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
+            x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
+        }
+        else
+        {
+            RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
+            RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
+        }
+    }
+    else
+    {
+        for (i = 16; i < 24; i += 2)
+        {
+            BLOCKD *d0 = &x->block[i];
+            BLOCKD *d1 = &x->block[i+1];
+
+            if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
+                vp8_build_inter_predictors2b(x, d0, 8);
+            else
+            {
+                vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
+                vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
+            }
+        }
+    }
+}
+
+
+void vp8_build_inter_predictors_mby(MACROBLOCKD *x)
+{
+    if (x->mbmi.ref_frame != INTRA_FRAME && x->mbmi.mode != SPLITMV)
+    {
+        unsigned char *ptr_base;
+        unsigned char *ptr;
+        unsigned char *pred_ptr = x->predictor;
+        int mv_row = x->mbmi.mv.as_mv.row;
+        int mv_col = x->mbmi.mv.as_mv.col;
+        int pre_stride = x->block[0].pre_stride;
+
+        ptr_base = x->pre.y_buffer;
+        ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
+
+        if ((mv_row | mv_col) & 7)
+        {
+            x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
+        }
+        else
+        {
+            RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
+        }
+    }
+    else
+    {
+        int i;
+
+        if (x->mbmi.partitioning < 3)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                BLOCKD *d = &x->block[bbb[i]];
+                vp8_build_inter_predictors4b(x, d, 16);
+            }
+
+        }
+        else
+        {
+            for (i = 0; i < 16; i += 2)
+            {
+                BLOCKD *d0 = &x->block[i];
+                BLOCKD *d1 = &x->block[i+1];
+
+                if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
+                    vp8_build_inter_predictors2b(x, d0, 16);
+                else
+                {
+                    vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
+                    vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
+                }
+
+            }
+        }
+    }
+}
+
+void vp8_build_inter_predictors_mb(MACROBLOCKD *x)
+{
+    if (x->mbmi.ref_frame != INTRA_FRAME && x->mbmi.mode != SPLITMV)
+    {
+        int offset;
+        unsigned char *ptr_base;
+        unsigned char *ptr;
+        unsigned char *uptr, *vptr;
+        unsigned char *pred_ptr = x->predictor;
+        unsigned char *upred_ptr = &x->predictor[256];
+        unsigned char *vpred_ptr = &x->predictor[320];
+
+        int mv_row = x->mbmi.mv.as_mv.row;
+        int mv_col = x->mbmi.mv.as_mv.col;
+        int pre_stride = x->block[0].pre_stride;
+
+        ptr_base = x->pre.y_buffer;
+        ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
+
+        if ((mv_row | mv_col) & 7)
+        {
+            x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, pred_ptr, 16);
+        }
+        else
+        {
+            RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, pred_ptr, 16);
+        }
+
+        mv_row = x->block[16].bmi.mv.as_mv.row;
+        mv_col = x->block[16].bmi.mv.as_mv.col;
+        pre_stride >>= 1;
+        offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
+        uptr = x->pre.u_buffer + offset;
+        vptr = x->pre.v_buffer + offset;
+
+        if ((mv_row | mv_col) & 7)
+        {
+            x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, 8);
+            x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, 8);
+        }
+        else
+        {
+            RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, upred_ptr, 8);
+            RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vpred_ptr, 8);
+        }
+    }
+    else
+    {
+        int i;
+
+        if (x->mbmi.partitioning < 3)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                BLOCKD *d = &x->block[bbb[i]];
+                vp8_build_inter_predictors4b(x, d, 16);
+            }
+        }
+        else
+        {
+            for (i = 0; i < 16; i += 2)
+            {
+                BLOCKD *d0 = &x->block[i];
+                BLOCKD *d1 = &x->block[i+1];
+
+                if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
+                    vp8_build_inter_predictors2b(x, d0, 16);
+                else
+                {
+                    vp8_build_inter_predictors_b(d0, 16, x->subpixel_predict);
+                    vp8_build_inter_predictors_b(d1, 16, x->subpixel_predict);
+                }
+
+            }
+
+        }
+
+        for (i = 16; i < 24; i += 2)
+        {
+            BLOCKD *d0 = &x->block[i];
+            BLOCKD *d1 = &x->block[i+1];
+
+            if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
+                vp8_build_inter_predictors2b(x, d0, 8);
+            else
+            {
+                vp8_build_inter_predictors_b(d0, 8, x->subpixel_predict);
+                vp8_build_inter_predictors_b(d1, 8, x->subpixel_predict);
+            }
+
+        }
+
+    }
+}
+
+void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel)
+{
+    int i, j;
+
+    if (x->mbmi.mode == SPLITMV)
+    {
+        for (i = 0; i < 2; i++)
+        {
+            for (j = 0; j < 2; j++)
+            {
+                int yoffset = i * 8 + j * 2;
+                int uoffset = 16 + i * 2 + j;
+                int voffset = 20 + i * 2 + j;
+
+                int temp;
+
+                temp = x->block[yoffset  ].bmi.mv.as_mv.row
+                       + x->block[yoffset+1].bmi.mv.as_mv.row
+                       + x->block[yoffset+4].bmi.mv.as_mv.row
+                       + x->block[yoffset+5].bmi.mv.as_mv.row;
+
+                if (temp < 0) temp -= 4;
+                else temp += 4;
+
+                x->block[uoffset].bmi.mv.as_mv.row = temp / 8;
+
+                if (fullpixel)
+                    x->block[uoffset].bmi.mv.as_mv.row = (temp / 8) & 0xfffffff8;
+
+                temp = x->block[yoffset  ].bmi.mv.as_mv.col
+                       + x->block[yoffset+1].bmi.mv.as_mv.col
+                       + x->block[yoffset+4].bmi.mv.as_mv.col
+                       + x->block[yoffset+5].bmi.mv.as_mv.col;
+
+                if (temp < 0) temp -= 4;
+                else temp += 4;
+
+                x->block[uoffset].bmi.mv.as_mv.col = temp / 8;
+
+                if (fullpixel)
+                    x->block[uoffset].bmi.mv.as_mv.col = (temp / 8) & 0xfffffff8;
+
+                x->block[voffset].bmi.mv.as_mv.row = x->block[uoffset].bmi.mv.as_mv.row ;
+                x->block[voffset].bmi.mv.as_mv.col = x->block[uoffset].bmi.mv.as_mv.col ;
+            }
+        }
+    }
+    else
+    {
+        int mvrow = x->mbmi.mv.as_mv.row;
+        int mvcol = x->mbmi.mv.as_mv.col;
+
+        if (mvrow < 0)
+            mvrow -= 1;
+        else
+            mvrow += 1;
+
+        if (mvcol < 0)
+            mvcol -= 1;
+        else
+            mvcol += 1;
+
+        mvrow /= 2;
+        mvcol /= 2;
+
+        for (i = 0; i < 8; i++)
+        {
+            x->block[ 16 + i].bmi.mv.as_mv.row = mvrow;
+            x->block[ 16 + i].bmi.mv.as_mv.col = mvcol;
+
+            if (fullpixel)
+            {
+                x->block[ 16 + i].bmi.mv.as_mv.row = mvrow & 0xfffffff8;
+                x->block[ 16 + i].bmi.mv.as_mv.col = mvcol & 0xfffffff8;
+            }
+        }
+    }
+}
+
+
+// The following functions are wriiten for skip_recon_mb() to call. Since there is no recon in this
+// situation, we can write the result directly to dst buffer instead of writing it to predictor
+// buffer and then copying it to dst buffer.
+static void vp8_build_inter_predictors_b_s(BLOCKD *d, unsigned char *dst_ptr, vp8_subpix_fn_t sppf)
+{
+    int r;
+    unsigned char *ptr_base;
+    unsigned char *ptr;
+    //unsigned char *pred_ptr = d->predictor;
+    int dst_stride = d->dst_stride;
+    int pre_stride = d->pre_stride;
+
+    ptr_base = *(d->base_pre);
+
+    if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
+    {
+        ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+        sppf(ptr, pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst_ptr, dst_stride);
+    }
+    else
+    {
+        ptr_base += d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+        ptr = ptr_base;
+
+        for (r = 0; r < 4; r++)
+        {
+#ifdef MUST_BE_ALIGNED
+            dst_ptr[0]   = ptr[0];
+            dst_ptr[1]   = ptr[1];
+            dst_ptr[2]   = ptr[2];
+            dst_ptr[3]   = ptr[3];
+#else
+            *(int *)dst_ptr = *(int *)ptr ;
+#endif
+            dst_ptr      += dst_stride;
+            ptr         += pre_stride;
+        }
+    }
+}
+
+
+
+void vp8_build_inter_predictors_mb_s(MACROBLOCKD *x)
+{
+    //unsigned char *pred_ptr = x->block[0].predictor;
+    //unsigned char *dst_ptr = *(x->block[0].base_dst) + x->block[0].dst;
+    unsigned char *pred_ptr = x->predictor;
+    unsigned char *dst_ptr = x->dst.y_buffer;
+
+    if (x->mbmi.mode != SPLITMV)
+    {
+        int offset;
+        unsigned char *ptr_base;
+        unsigned char *ptr;
+        unsigned char *uptr, *vptr;
+        //unsigned char *pred_ptr = x->predictor;
+        //unsigned char *upred_ptr = &x->predictor[256];
+        //unsigned char *vpred_ptr = &x->predictor[320];
+        unsigned char *udst_ptr = x->dst.u_buffer;
+        unsigned char *vdst_ptr = x->dst.v_buffer;
+
+        int mv_row = x->mbmi.mv.as_mv.row;
+        int mv_col = x->mbmi.mv.as_mv.col;
+        int pre_stride = x->dst.y_stride; //x->block[0].pre_stride;
+
+        ptr_base = x->pre.y_buffer;
+        ptr = ptr_base + (mv_row >> 3) * pre_stride + (mv_col >> 3);
+
+        if ((mv_row | mv_col) & 7)
+        {
+            x->subpixel_predict16x16(ptr, pre_stride, mv_col & 7, mv_row & 7, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
+        }
+        else
+        {
+            RECON_INVOKE(&x->rtcd->recon, copy16x16)(ptr, pre_stride, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
+        }
+
+        mv_row = x->block[16].bmi.mv.as_mv.row;
+        mv_col = x->block[16].bmi.mv.as_mv.col;
+        pre_stride >>= 1;
+        offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
+        uptr = x->pre.u_buffer + offset;
+        vptr = x->pre.v_buffer + offset;
+
+        if ((mv_row | mv_col) & 7)
+        {
+            x->subpixel_predict8x8(uptr, pre_stride, mv_col & 7, mv_row & 7, udst_ptr, x->dst.uv_stride);
+            x->subpixel_predict8x8(vptr, pre_stride, mv_col & 7, mv_row & 7, vdst_ptr, x->dst.uv_stride);
+        }
+        else
+        {
+            RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, pre_stride, udst_ptr, x->dst.uv_stride);
+            RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, pre_stride, vdst_ptr, x->dst.uv_stride);
+        }
+    }
+    else
+    {
+        //note: this whole ELSE part is not executed at all. So, no way to test the correctness of my modification. Later,
+        //if sth is wrong, go back to what it is in build_inter_predictors_mb.
+        int i;
+
+        if (x->mbmi.partitioning < 3)
+        {
+            for (i = 0; i < 4; i++)
+            {
+                BLOCKD *d = &x->block[bbb[i]];
+                //vp8_build_inter_predictors4b(x, d, 16);
+
+                {
+                    unsigned char *ptr_base;
+                    unsigned char *ptr;
+                    unsigned char *pred_ptr = d->predictor;
+
+                    ptr_base = *(d->base_pre);
+                    ptr = ptr_base + d->pre + (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+
+                    if (d->bmi.mv.as_mv.row & 7 || d->bmi.mv.as_mv.col & 7)
+                    {
+                        x->subpixel_predict8x8(ptr, d->pre_stride, d->bmi.mv.as_mv.col & 7, d->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
+                    }
+                    else
+                    {
+                        RECON_INVOKE(&x->rtcd->recon, copy8x8)(ptr, d->pre_stride, dst_ptr, x->dst.y_stride); //x->block[0].dst_stride);
+                    }
+                }
+            }
+        }
+        else
+        {
+            for (i = 0; i < 16; i += 2)
+            {
+                BLOCKD *d0 = &x->block[i];
+                BLOCKD *d1 = &x->block[i+1];
+
+                if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
+                {
+                    //vp8_build_inter_predictors2b(x, d0, 16);
+                    unsigned char *ptr_base;
+                    unsigned char *ptr;
+                    unsigned char *pred_ptr = d0->predictor;
+
+                    ptr_base = *(d0->base_pre);
+                    ptr = ptr_base + d0->pre + (d0->bmi.mv.as_mv.row >> 3) * d0->pre_stride + (d0->bmi.mv.as_mv.col >> 3);
+
+                    if (d0->bmi.mv.as_mv.row & 7 || d0->bmi.mv.as_mv.col & 7)
+                    {
+                        x->subpixel_predict8x4(ptr, d0->pre_stride, d0->bmi.mv.as_mv.col & 7, d0->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride);
+                    }
+                    else
+                    {
+                        RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d0->pre_stride, dst_ptr, x->dst.y_stride);
+                    }
+                }
+                else
+                {
+                    vp8_build_inter_predictors_b_s(d0, dst_ptr, x->subpixel_predict);
+                    vp8_build_inter_predictors_b_s(d1, dst_ptr, x->subpixel_predict);
+                }
+            }
+        }
+
+        for (i = 16; i < 24; i += 2)
+        {
+            BLOCKD *d0 = &x->block[i];
+            BLOCKD *d1 = &x->block[i+1];
+
+            if (d0->bmi.mv.as_int == d1->bmi.mv.as_int)
+            {
+                //vp8_build_inter_predictors2b(x, d0, 8);
+                unsigned char *ptr_base;
+                unsigned char *ptr;
+                unsigned char *pred_ptr = d0->predictor;
+
+                ptr_base = *(d0->base_pre);
+                ptr = ptr_base + d0->pre + (d0->bmi.mv.as_mv.row >> 3) * d0->pre_stride + (d0->bmi.mv.as_mv.col >> 3);
+
+                if (d0->bmi.mv.as_mv.row & 7 || d0->bmi.mv.as_mv.col & 7)
+                {
+                    x->subpixel_predict8x4(ptr, d0->pre_stride, d0->bmi.mv.as_mv.col & 7, d0->bmi.mv.as_mv.row & 7, dst_ptr, x->dst.y_stride);
+                }
+                else
+                {
+                    RECON_INVOKE(&x->rtcd->recon, copy8x4)(ptr, d0->pre_stride, dst_ptr, x->dst.y_stride);
+                }
+            }
+            else
+            {
+                vp8_build_inter_predictors_b_s(d0, dst_ptr, x->subpixel_predict);
+                vp8_build_inter_predictors_b_s(d1, dst_ptr, x->subpixel_predict);
+            }
+        }
+    }
+}
diff --git a/vp8/common/reconinter.h b/vp8/common/reconinter.h
new file mode 100644 (file)
index 0000000..b2d1ae9
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_RECONINTER_H
+#define __INC_RECONINTER_H
+
+extern void vp8_build_inter_predictors_mb(MACROBLOCKD *x);
+extern void vp8_build_inter_predictors_mb_s(MACROBLOCKD *x);
+
+extern void vp8_build_inter_predictors_mby(MACROBLOCKD *x);
+extern void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel);
+extern void vp8_build_inter_predictors_b(BLOCKD *d, int pitch, vp8_subpix_fn_t sppf);
+extern void vp8_build_inter_predictors_mbuv(MACROBLOCKD *x);
+
+#endif
diff --git a/vp8/common/reconintra.c b/vp8/common/reconintra.c
new file mode 100644 (file)
index 0000000..e33bce3
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "recon.h"
+#include "reconintra.h"
+#include "vpx_mem/vpx_mem.h"
+
+// For skip_recon_mb(), add vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) and
+// vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x).
+
+void vp8_recon_intra_mbuv(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    for (i = 16; i < 24; i += 2)
+    {
+        BLOCKD *b = &x->block[i];
+        RECON_INVOKE(rtcd, recon2)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+}
+
+void vp8_build_intra_predictors_mby(MACROBLOCKD *x)
+{
+
+    unsigned char *yabove_row = x->dst.y_buffer - x->dst.y_stride;
+    unsigned char yleft_col[16];
+    unsigned char ytop_left = yabove_row[-1];
+    unsigned char *ypred_ptr = x->predictor;
+    int r, c, i;
+
+    for (i = 0; i < 16; i++)
+    {
+        yleft_col[i] = x->dst.y_buffer [i* x->dst.y_stride -1];
+    }
+
+    // for Y
+    switch (x->mbmi.mode)
+    {
+    case DC_PRED:
+    {
+        int expected_dc;
+        int i;
+        int shift;
+        int average = 0;
+
+
+        if (x->up_available || x->left_available)
+        {
+            if (x->up_available)
+            {
+                for (i = 0; i < 16; i++)
+                {
+                    average += yabove_row[i];
+                }
+            }
+
+            if (x->left_available)
+            {
+
+                for (i = 0; i < 16; i++)
+                {
+                    average += yleft_col[i];
+                }
+
+            }
+
+
+
+            shift = 3 + x->up_available + x->left_available;
+            expected_dc = (average + (1 << (shift - 1))) >> shift;
+        }
+        else
+        {
+            expected_dc = 128;
+        }
+
+        vpx_memset(ypred_ptr, expected_dc, 256);
+    }
+    break;
+    case V_PRED:
+    {
+
+        for (r = 0; r < 16; r++)
+        {
+
+            ((int *)ypred_ptr)[0] = ((int *)yabove_row)[0];
+            ((int *)ypred_ptr)[1] = ((int *)yabove_row)[1];
+            ((int *)ypred_ptr)[2] = ((int *)yabove_row)[2];
+            ((int *)ypred_ptr)[3] = ((int *)yabove_row)[3];
+            ypred_ptr += 16;
+        }
+    }
+    break;
+    case H_PRED:
+    {
+
+        for (r = 0; r < 16; r++)
+        {
+
+            vpx_memset(ypred_ptr, yleft_col[r], 16);
+            ypred_ptr += 16;
+        }
+
+    }
+    break;
+    case TM_PRED:
+    {
+
+        for (r = 0; r < 16; r++)
+        {
+            for (c = 0; c < 16; c++)
+            {
+                int pred =  yleft_col[r] + yabove_row[ c] - ytop_left;
+
+                if (pred < 0)
+                    pred = 0;
+
+                if (pred > 255)
+                    pred = 255;
+
+                ypred_ptr[c] = pred;
+            }
+
+            ypred_ptr += 16;
+        }
+
+    }
+    break;
+    case B_PRED:
+    case NEARESTMV:
+    case NEARMV:
+    case ZEROMV:
+    case NEWMV:
+    case SPLITMV:
+    case MB_MODE_COUNT:
+        break;
+    }
+}
+
+void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x)
+{
+
+    unsigned char *yabove_row = x->dst.y_buffer - x->dst.y_stride;
+    unsigned char yleft_col[16];
+    unsigned char ytop_left = yabove_row[-1];
+    unsigned char *ypred_ptr = x->predictor;
+    int r, c, i;
+
+    int y_stride = x->dst.y_stride;
+    ypred_ptr = x->dst.y_buffer; //x->predictor;
+
+    for (i = 0; i < 16; i++)
+    {
+        yleft_col[i] = x->dst.y_buffer [i* x->dst.y_stride -1];
+    }
+
+    // for Y
+    switch (x->mbmi.mode)
+    {
+    case DC_PRED:
+    {
+        int expected_dc;
+        int i;
+        int shift;
+        int average = 0;
+
+
+        if (x->up_available || x->left_available)
+        {
+            if (x->up_available)
+            {
+                for (i = 0; i < 16; i++)
+                {
+                    average += yabove_row[i];
+                }
+            }
+
+            if (x->left_available)
+            {
+
+                for (i = 0; i < 16; i++)
+                {
+                    average += yleft_col[i];
+                }
+
+            }
+
+
+
+            shift = 3 + x->up_available + x->left_available;
+            expected_dc = (average + (1 << (shift - 1))) >> shift;
+        }
+        else
+        {
+            expected_dc = 128;
+        }
+
+        //vpx_memset(ypred_ptr, expected_dc, 256);
+        for (r = 0; r < 16; r++)
+        {
+            vpx_memset(ypred_ptr, expected_dc, 16);
+            ypred_ptr += y_stride; //16;
+        }
+    }
+    break;
+    case V_PRED:
+    {
+
+        for (r = 0; r < 16; r++)
+        {
+
+            ((int *)ypred_ptr)[0] = ((int *)yabove_row)[0];
+            ((int *)ypred_ptr)[1] = ((int *)yabove_row)[1];
+            ((int *)ypred_ptr)[2] = ((int *)yabove_row)[2];
+            ((int *)ypred_ptr)[3] = ((int *)yabove_row)[3];
+            ypred_ptr += y_stride; //16;
+        }
+    }
+    break;
+    case H_PRED:
+    {
+
+        for (r = 0; r < 16; r++)
+        {
+
+            vpx_memset(ypred_ptr, yleft_col[r], 16);
+            ypred_ptr += y_stride;  //16;
+        }
+
+    }
+    break;
+    case TM_PRED:
+    {
+
+        for (r = 0; r < 16; r++)
+        {
+            for (c = 0; c < 16; c++)
+            {
+                int pred =  yleft_col[r] + yabove_row[ c] - ytop_left;
+
+                if (pred < 0)
+                    pred = 0;
+
+                if (pred > 255)
+                    pred = 255;
+
+                ypred_ptr[c] = pred;
+            }
+
+            ypred_ptr += y_stride;  //16;
+        }
+
+    }
+    break;
+    case B_PRED:
+    case NEARESTMV:
+    case NEARMV:
+    case ZEROMV:
+    case NEWMV:
+    case SPLITMV:
+    case MB_MODE_COUNT:
+        break;
+    }
+}
+
+void vp8_build_intra_predictors_mbuv(MACROBLOCKD *x)
+{
+    unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;
+    unsigned char uleft_col[16];
+    unsigned char utop_left = uabove_row[-1];
+    unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;
+    unsigned char vleft_col[20];
+    unsigned char vtop_left = vabove_row[-1];
+    unsigned char *upred_ptr = &x->predictor[256];
+    unsigned char *vpred_ptr = &x->predictor[320];
+    int i, j;
+
+    for (i = 0; i < 8; i++)
+    {
+        uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1];
+        vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1];
+    }
+
+    switch (x->mbmi.uv_mode)
+    {
+    case DC_PRED:
+    {
+        int expected_udc;
+        int expected_vdc;
+        int i;
+        int shift;
+        int Uaverage = 0;
+        int Vaverage = 0;
+
+        if (x->up_available)
+        {
+            for (i = 0; i < 8; i++)
+            {
+                Uaverage += uabove_row[i];
+                Vaverage += vabove_row[i];
+            }
+        }
+
+        if (x->left_available)
+        {
+            for (i = 0; i < 8; i++)
+            {
+                Uaverage += uleft_col[i];
+                Vaverage += vleft_col[i];
+            }
+        }
+
+        if (!x->up_available && !x->left_available)
+        {
+            expected_udc = 128;
+            expected_vdc = 128;
+        }
+        else
+        {
+            shift = 2 + x->up_available + x->left_available;
+            expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
+            expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
+        }
+
+
+        vpx_memset(upred_ptr, expected_udc, 64);
+        vpx_memset(vpred_ptr, expected_vdc, 64);
+
+
+    }
+    break;
+    case V_PRED:
+    {
+        int i;
+
+        for (i = 0; i < 8; i++)
+        {
+            vpx_memcpy(upred_ptr, uabove_row, 8);
+            vpx_memcpy(vpred_ptr, vabove_row, 8);
+            upred_ptr += 8;
+            vpred_ptr += 8;
+        }
+
+    }
+    break;
+    case H_PRED:
+    {
+        int i;
+
+        for (i = 0; i < 8; i++)
+        {
+            vpx_memset(upred_ptr, uleft_col[i], 8);
+            vpx_memset(vpred_ptr, vleft_col[i], 8);
+            upred_ptr += 8;
+            vpred_ptr += 8;
+        }
+    }
+
+    break;
+    case TM_PRED:
+    {
+        int i;
+
+        for (i = 0; i < 8; i++)
+        {
+            for (j = 0; j < 8; j++)
+            {
+                int predu = uleft_col[i] + uabove_row[j] - utop_left;
+                int predv = vleft_col[i] + vabove_row[j] - vtop_left;
+
+                if (predu < 0)
+                    predu = 0;
+
+                if (predu > 255)
+                    predu = 255;
+
+                if (predv < 0)
+                    predv = 0;
+
+                if (predv > 255)
+                    predv = 255;
+
+                upred_ptr[j] = predu;
+                vpred_ptr[j] = predv;
+            }
+
+            upred_ptr += 8;
+            vpred_ptr += 8;
+        }
+
+    }
+    break;
+    case B_PRED:
+    case NEARESTMV:
+    case NEARMV:
+    case ZEROMV:
+    case NEWMV:
+    case SPLITMV:
+    case MB_MODE_COUNT:
+        break;
+    }
+}
+
+void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x)
+{
+    unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;
+    unsigned char uleft_col[16];
+    unsigned char utop_left = uabove_row[-1];
+    unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;
+    unsigned char vleft_col[20];
+    unsigned char vtop_left = vabove_row[-1];
+    unsigned char *upred_ptr = x->dst.u_buffer; //&x->predictor[256];
+    unsigned char *vpred_ptr = x->dst.v_buffer; //&x->predictor[320];
+    int uv_stride = x->dst.uv_stride;
+
+    int i, j;
+
+    for (i = 0; i < 8; i++)
+    {
+        uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1];
+        vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1];
+    }
+
+    switch (x->mbmi.uv_mode)
+    {
+    case DC_PRED:
+    {
+        int expected_udc;
+        int expected_vdc;
+        int i;
+        int shift;
+        int Uaverage = 0;
+        int Vaverage = 0;
+
+        if (x->up_available)
+        {
+            for (i = 0; i < 8; i++)
+            {
+                Uaverage += uabove_row[i];
+                Vaverage += vabove_row[i];
+            }
+        }
+
+        if (x->left_available)
+        {
+            for (i = 0; i < 8; i++)
+            {
+                Uaverage += uleft_col[i];
+                Vaverage += vleft_col[i];
+            }
+        }
+
+        if (!x->up_available && !x->left_available)
+        {
+            expected_udc = 128;
+            expected_vdc = 128;
+        }
+        else
+        {
+            shift = 2 + x->up_available + x->left_available;
+            expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
+            expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
+        }
+
+
+        //vpx_memset(upred_ptr,expected_udc,64);
+        //vpx_memset(vpred_ptr,expected_vdc,64);
+        for (i = 0; i < 8; i++)
+        {
+            vpx_memset(upred_ptr, expected_udc, 8);
+            vpx_memset(vpred_ptr, expected_vdc, 8);
+            upred_ptr += uv_stride; //8;
+            vpred_ptr += uv_stride; //8;
+        }
+    }
+    break;
+    case V_PRED:
+    {
+        int i;
+
+        for (i = 0; i < 8; i++)
+        {
+            vpx_memcpy(upred_ptr, uabove_row, 8);
+            vpx_memcpy(vpred_ptr, vabove_row, 8);
+            upred_ptr += uv_stride; //8;
+            vpred_ptr += uv_stride; //8;
+        }
+
+    }
+    break;
+    case H_PRED:
+    {
+        int i;
+
+        for (i = 0; i < 8; i++)
+        {
+            vpx_memset(upred_ptr, uleft_col[i], 8);
+            vpx_memset(vpred_ptr, vleft_col[i], 8);
+            upred_ptr += uv_stride; //8;
+            vpred_ptr += uv_stride; //8;
+        }
+    }
+
+    break;
+    case TM_PRED:
+    {
+        int i;
+
+        for (i = 0; i < 8; i++)
+        {
+            for (j = 0; j < 8; j++)
+            {
+                int predu = uleft_col[i] + uabove_row[j] - utop_left;
+                int predv = vleft_col[i] + vabove_row[j] - vtop_left;
+
+                if (predu < 0)
+                    predu = 0;
+
+                if (predu > 255)
+                    predu = 255;
+
+                if (predv < 0)
+                    predv = 0;
+
+                if (predv > 255)
+                    predv = 255;
+
+                upred_ptr[j] = predu;
+                vpred_ptr[j] = predv;
+            }
+
+            upred_ptr += uv_stride; //8;
+            vpred_ptr += uv_stride; //8;
+        }
+
+    }
+    break;
+    case B_PRED:
+    case NEARESTMV:
+    case NEARMV:
+    case ZEROMV:
+    case NEWMV:
+    case SPLITMV:
+    case MB_MODE_COUNT:
+        break;
+    }
+}
diff --git a/vp8/common/reconintra.h b/vp8/common/reconintra.h
new file mode 100644 (file)
index 0000000..d63aa15
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_RECONINTRA_H
+#define __INC_RECONINTRA_H
+
+extern void init_intra_left_above_pixels(MACROBLOCKD *x);
+
+extern void (*vp8_build_intra_predictors_mby_ptr)(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_neon(MACROBLOCKD *x);
+extern void (*vp8_build_intra_predictors_mby_s_ptr)(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mby_s_neon(MACROBLOCKD *x);
+
+extern void vp8_build_intra_predictors_mbuv(MACROBLOCKD *x);
+extern void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x);
+
+extern void vp8_predict_intra4x4(BLOCKD *x, int b_mode, unsigned char *Predictor);
+
+#endif
diff --git a/vp8/common/reconintra4x4.c b/vp8/common/reconintra4x4.c
new file mode 100644 (file)
index 0000000..d92d5c9
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "recon.h"
+#include "vpx_mem/vpx_mem.h"
+#include "reconintra.h"
+
+void vp8_predict_intra4x4(BLOCKD *x,
+                          int b_mode,
+                          unsigned char *predictor)
+{
+    int i, r, c;
+
+    unsigned char *Above = *(x->base_dst) + x->dst - x->dst_stride;
+    unsigned char Left[4];
+    unsigned char top_left = Above[-1];
+
+    Left[0] = (*(x->base_dst))[x->dst - 1];
+    Left[1] = (*(x->base_dst))[x->dst - 1 + x->dst_stride];
+    Left[2] = (*(x->base_dst))[x->dst - 1 + 2 * x->dst_stride];
+    Left[3] = (*(x->base_dst))[x->dst - 1 + 3 * x->dst_stride];
+
+    switch (b_mode)
+    {
+    case B_DC_PRED:
+    {
+        int expected_dc = 0;
+
+        for (i = 0; i < 4; i++)
+        {
+            expected_dc += Above[i];
+            expected_dc += Left[i];
+        }
+
+        expected_dc = (expected_dc + 4) >> 3;
+
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+                predictor[c] = expected_dc;
+            }
+
+            predictor += 16;
+        }
+    }
+    break;
+    case B_TM_PRED:
+    {
+        // prediction similar to true_motion prediction
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+                int pred = Above[c] - top_left + Left[r];
+
+                if (pred < 0)
+                    pred = 0;
+
+                if (pred > 255)
+                    pred = 255;
+
+                predictor[c] = pred;
+            }
+
+            predictor += 16;
+        }
+    }
+    break;
+
+    case B_VE_PRED:
+    {
+
+        unsigned int ap[4];
+        ap[0] = (top_left  + 2 * Above[0] + Above[1] + 2) >> 2;
+        ap[1] = (Above[0] + 2 * Above[1] + Above[2] + 2) >> 2;
+        ap[2] = (Above[1] + 2 * Above[2] + Above[3] + 2) >> 2;
+        ap[3] = (Above[2] + 2 * Above[3] + Above[4] + 2) >> 2;
+
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+
+                predictor[c] = ap[c];
+            }
+
+            predictor += 16;
+        }
+
+    }
+    break;
+
+
+    case B_HE_PRED:
+    {
+
+        unsigned int lp[4];
+        lp[0] = (top_left + 2 * Left[0] + Left[1] + 2) >> 2;
+        lp[1] = (Left[0] + 2 * Left[1] + Left[2] + 2) >> 2;
+        lp[2] = (Left[1] + 2 * Left[2] + Left[3] + 2) >> 2;
+        lp[3] = (Left[2] + 2 * Left[3] + Left[3] + 2) >> 2;
+
+        for (r = 0; r < 4; r++)
+        {
+            for (c = 0; c < 4; c++)
+            {
+                predictor[c] = lp[r];
+            }
+
+            predictor += 16;
+        }
+    }
+    break;
+    case B_LD_PRED:
+    {
+        unsigned char *ptr = Above;
+        predictor[0 * 16 + 0] = (ptr[0] + ptr[1] * 2 + ptr[2] + 2) >> 2;
+        predictor[0 * 16 + 1] =
+            predictor[1 * 16 + 0] = (ptr[1] + ptr[2] * 2 + ptr[3] + 2) >> 2;
+        predictor[0 * 16 + 2] =
+            predictor[1 * 16 + 1] =
+                predictor[2 * 16 + 0] = (ptr[2] + ptr[3] * 2 + ptr[4] + 2) >> 2;
+        predictor[0 * 16 + 3] =
+            predictor[1 * 16 + 2] =
+                predictor[2 * 16 + 1] =
+                    predictor[3 * 16 + 0] = (ptr[3] + ptr[4] * 2 + ptr[5] + 2) >> 2;
+        predictor[1 * 16 + 3] =
+            predictor[2 * 16 + 2] =
+                predictor[3 * 16 + 1] = (ptr[4] + ptr[5] * 2 + ptr[6] + 2) >> 2;
+        predictor[2 * 16 + 3] =
+            predictor[3 * 16 + 2] = (ptr[5] + ptr[6] * 2 + ptr[7] + 2) >> 2;
+        predictor[3 * 16 + 3] = (ptr[6] + ptr[7] * 2 + ptr[7] + 2) >> 2;
+
+    }
+    break;
+    case B_RD_PRED:
+    {
+
+        unsigned char pp[9];
+
+        pp[0] = Left[3];
+        pp[1] = Left[2];
+        pp[2] = Left[1];
+        pp[3] = Left[0];
+        pp[4] = top_left;
+        pp[5] = Above[0];
+        pp[6] = Above[1];
+        pp[7] = Above[2];
+        pp[8] = Above[3];
+
+        predictor[3 * 16 + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[3 * 16 + 1] =
+            predictor[2 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[3 * 16 + 2] =
+            predictor[2 * 16 + 1] =
+                predictor[1 * 16 + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[3 * 16 + 3] =
+            predictor[2 * 16 + 2] =
+                predictor[1 * 16 + 1] =
+                    predictor[0 * 16 + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[2 * 16 + 3] =
+            predictor[1 * 16 + 2] =
+                predictor[0 * 16 + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[1 * 16 + 3] =
+            predictor[0 * 16 + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+        predictor[0 * 16 + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
+
+    }
+    break;
+    case B_VR_PRED:
+    {
+
+        unsigned char pp[9];
+
+        pp[0] = Left[3];
+        pp[1] = Left[2];
+        pp[2] = Left[1];
+        pp[3] = Left[0];
+        pp[4] = top_left;
+        pp[5] = Above[0];
+        pp[6] = Above[1];
+        pp[7] = Above[2];
+        pp[8] = Above[3];
+
+
+        predictor[3 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 0] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[3 * 16 + 1] =
+            predictor[1 * 16 + 0] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[2 * 16 + 1] =
+            predictor[0 * 16 + 0] = (pp[4] + pp[5] + 1) >> 1;
+        predictor[3 * 16 + 2] =
+            predictor[1 * 16 + 1] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[2 * 16 + 2] =
+            predictor[0 * 16 + 1] = (pp[5] + pp[6] + 1) >> 1;
+        predictor[3 * 16 + 3] =
+            predictor[1 * 16 + 2] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+        predictor[2 * 16 + 3] =
+            predictor[0 * 16 + 2] = (pp[6] + pp[7] + 1) >> 1;
+        predictor[1 * 16 + 3] = (pp[6] + pp[7] * 2 + pp[8] + 2) >> 2;
+        predictor[0 * 16 + 3] = (pp[7] + pp[8] + 1) >> 1;
+
+    }
+    break;
+    case B_VL_PRED:
+    {
+
+        unsigned char *pp = Above;
+
+        predictor[0 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
+        predictor[1 * 16 + 0] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[2 * 16 + 0] =
+            predictor[0 * 16 + 1] = (pp[1] + pp[2] + 1) >> 1;
+        predictor[1 * 16 + 1] =
+            predictor[3 * 16 + 0] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 1] =
+            predictor[0 * 16 + 2] = (pp[2] + pp[3] + 1) >> 1;
+        predictor[3 * 16 + 1] =
+            predictor[1 * 16 + 2] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[0 * 16 + 3] =
+            predictor[2 * 16 + 2] = (pp[3] + pp[4] + 1) >> 1;
+        predictor[1 * 16 + 3] =
+            predictor[3 * 16 + 2] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[2 * 16 + 3] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[3 * 16 + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+    }
+    break;
+
+    case B_HD_PRED:
+    {
+        unsigned char pp[9];
+        pp[0] = Left[3];
+        pp[1] = Left[2];
+        pp[2] = Left[1];
+        pp[3] = Left[0];
+        pp[4] = top_left;
+        pp[5] = Above[0];
+        pp[6] = Above[1];
+        pp[7] = Above[2];
+        pp[8] = Above[3];
+
+
+        predictor[3 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
+        predictor[3 * 16 + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[2 * 16 + 0] =
+            predictor[3 * 16 + 2] = (pp[1] + pp[2] + 1) >> 1;
+        predictor[2 * 16 + 1] =
+            predictor[3 * 16 + 3] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 2] =
+            predictor[1 * 16 + 0] = (pp[2] + pp[3] + 1) >> 1;
+        predictor[2 * 16 + 3] =
+            predictor[1 * 16 + 1] = (pp[2] + pp[3] * 2 + pp[4] + 2) >> 2;
+        predictor[1 * 16 + 2] =
+            predictor[0 * 16 + 0] = (pp[3] + pp[4] + 1) >> 1;
+        predictor[1 * 16 + 3] =
+            predictor[0 * 16 + 1] = (pp[3] + pp[4] * 2 + pp[5] + 2) >> 2;
+        predictor[0 * 16 + 2] = (pp[4] + pp[5] * 2 + pp[6] + 2) >> 2;
+        predictor[0 * 16 + 3] = (pp[5] + pp[6] * 2 + pp[7] + 2) >> 2;
+    }
+    break;
+
+
+    case B_HU_PRED:
+    {
+        unsigned char *pp = Left;
+        predictor[0 * 16 + 0] = (pp[0] + pp[1] + 1) >> 1;
+        predictor[0 * 16 + 1] = (pp[0] + pp[1] * 2 + pp[2] + 2) >> 2;
+        predictor[0 * 16 + 2] =
+            predictor[1 * 16 + 0] = (pp[1] + pp[2] + 1) >> 1;
+        predictor[0 * 16 + 3] =
+            predictor[1 * 16 + 1] = (pp[1] + pp[2] * 2 + pp[3] + 2) >> 2;
+        predictor[1 * 16 + 2] =
+            predictor[2 * 16 + 0] = (pp[2] + pp[3] + 1) >> 1;
+        predictor[1 * 16 + 3] =
+            predictor[2 * 16 + 1] = (pp[2] + pp[3] * 2 + pp[3] + 2) >> 2;
+        predictor[2 * 16 + 2] =
+            predictor[2 * 16 + 3] =
+                predictor[3 * 16 + 0] =
+                    predictor[3 * 16 + 1] =
+                        predictor[3 * 16 + 2] =
+                            predictor[3 * 16 + 3] = pp[3];
+    }
+    break;
+
+
+    }
+}
+// copy 4 bytes from the above right down so that the 4x4 prediction modes using pixels above and
+// to the right prediction have filled in pixels to use.
+void vp8_intra_prediction_down_copy(MACROBLOCKD *x)
+{
+    unsigned char *above_right = *(x->block[0].base_dst) + x->block[0].dst - x->block[0].dst_stride + 16;
+
+    unsigned int *src_ptr = (unsigned int *)above_right;
+    unsigned int *dst_ptr0 = (unsigned int *)(above_right + 4 * x->block[0].dst_stride);
+    unsigned int *dst_ptr1 = (unsigned int *)(above_right + 8 * x->block[0].dst_stride);
+    unsigned int *dst_ptr2 = (unsigned int *)(above_right + 12 * x->block[0].dst_stride);
+
+    *dst_ptr0 = *src_ptr;
+    *dst_ptr1 = *src_ptr;
+    *dst_ptr2 = *src_ptr;
+}
+
+
+void vp8_recon_intra4x4mb(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x)
+{
+    int i;
+
+    vp8_intra_prediction_down_copy(x);
+
+    for (i = 0; i < 16; i++)
+    {
+        BLOCKD *b = &x->block[i];
+
+        vp8_predict_intra4x4(b, x->block[i].bmi.mode, x->block[i].predictor);
+        RECON_INVOKE(rtcd, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+    }
+
+    vp8_recon_intra_mbuv(rtcd, x);
+
+}
diff --git a/vp8/common/reconintra4x4.h b/vp8/common/reconintra4x4.h
new file mode 100644 (file)
index 0000000..788c8c4
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_RECONINTRA4x4_H
+#define __INC_RECONINTRA4x4_H
+
+extern void vp8_intra_prediction_down_copy(MACROBLOCKD *x);
+
+#endif
diff --git a/vp8/common/segmentation_common.c b/vp8/common/segmentation_common.c
new file mode 100644 (file)
index 0000000..72b8c87
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "segmentation_common.h"
+#include "vpx_mem/vpx_mem.h"
+
+void vp8_update_gf_useage_maps(VP8_COMMON *cm, MACROBLOCKD *xd)
+{
+    int mb_row, mb_col;
+
+    MODE_INFO *this_mb_mode_info = cm->mi;
+
+    xd->gf_active_ptr = (signed char *)cm->gf_active_flags;
+
+    if ((cm->frame_type == KEY_FRAME) || (cm->refresh_golden_frame))
+    {
+        // Reset Gf useage monitors
+        vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
+        cm->gf_active_count = cm->mb_rows * cm->mb_cols;
+    }
+    else
+    {
+        // for each macroblock row in image
+        for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+        {
+            // for each macroblock col in image
+            for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+            {
+
+                // If using golden then set GF active flag if not already set.
+                // If using last frame 0,0 mode then leave flag as it is
+                // else if using non 0,0 motion or intra modes then clear flag if it is currently set
+                if ((this_mb_mode_info->mbmi.ref_frame == GOLDEN_FRAME) || (this_mb_mode_info->mbmi.ref_frame == ALTREF_FRAME))
+                {
+                    if (*(xd->gf_active_ptr) == 0)
+                    {
+                        *(xd->gf_active_ptr) = 1;
+                        cm->gf_active_count ++;
+                    }
+                }
+                else if ((this_mb_mode_info->mbmi.mode != ZEROMV) && *(xd->gf_active_ptr))
+                {
+                    *(xd->gf_active_ptr) = 0;
+                    cm->gf_active_count--;
+                }
+
+                xd->gf_active_ptr++;          // Step onto next entry
+                this_mb_mode_info++;           // skip to next mb
+
+            }
+
+            // this is to account for the border
+            this_mb_mode_info++;
+        }
+    }
+}
diff --git a/vp8/common/segmentation_common.h b/vp8/common/segmentation_common.h
new file mode 100644 (file)
index 0000000..bb93533
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "string.h"
+#include "blockd.h"
+#include "onyxc_int.h"
+
+extern void vp8_update_gf_useage_maps(VP8_COMMON *cm, MACROBLOCKD *xd);
diff --git a/vp8/common/setupintrarecon.c b/vp8/common/setupintrarecon.c
new file mode 100644 (file)
index 0000000..dcaafe6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "setupintrarecon.h"
+#include "vpx_mem/vpx_mem.h"
+
+void vp8_setup_intra_recon(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+
+    // set up frame new frame for intra coded blocks
+    vpx_memset(ybf->y_buffer - 1 - 2 * ybf->y_stride, 127, ybf->y_width + 5);
+    vpx_memset(ybf->y_buffer - 1 - ybf->y_stride, 127, ybf->y_width + 5);
+
+    for (i = 0; i < ybf->y_height; i++)
+        ybf->y_buffer[ybf->y_stride *i - 1] = (unsigned char) 129;
+
+    vpx_memset(ybf->u_buffer - 1 - 2 * ybf->uv_stride, 127, ybf->uv_width + 5);
+    vpx_memset(ybf->u_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5);
+
+    for (i = 0; i < ybf->uv_height; i++)
+        ybf->u_buffer[ybf->uv_stride *i - 1] = (unsigned char) 129;
+
+    vpx_memset(ybf->v_buffer - 1 - 2 * ybf->uv_stride, 127, ybf->uv_width + 5);
+    vpx_memset(ybf->v_buffer - 1 - ybf->uv_stride, 127, ybf->uv_width + 5);
+
+    for (i = 0; i < ybf->uv_height; i++)
+        ybf->v_buffer[ybf->uv_stride *i - 1] = (unsigned char) 129;
+
+}
diff --git a/vp8/common/setupintrarecon.h b/vp8/common/setupintrarecon.h
new file mode 100644 (file)
index 0000000..6ec79b2
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/yv12config.h"
+extern void vp8_setup_intra_recon(YV12_BUFFER_CONFIG *ybf);
diff --git a/vp8/common/subpixel.h b/vp8/common/subpixel.h
new file mode 100644 (file)
index 0000000..fbd5f4d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef SUBPIXEL_H
+#define SUBPIXEL_H
+
+#define prototype_subpixel_predict(sym) \
+    void sym(unsigned char *src, int src_pitch, int xofst, int yofst, \
+             unsigned char *dst, int dst_pitch)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/subpixel_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/subpixel_arm.h"
+#endif
+
+#ifndef vp8_subpix_sixtap16x16
+#define vp8_subpix_sixtap16x16 vp8_sixtap_predict16x16_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_sixtap16x16);
+
+#ifndef vp8_subpix_sixtap8x8
+#define vp8_subpix_sixtap8x8 vp8_sixtap_predict8x8_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_sixtap8x8);
+
+#ifndef vp8_subpix_sixtap8x4
+#define vp8_subpix_sixtap8x4 vp8_sixtap_predict8x4_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_sixtap8x4);
+
+#ifndef vp8_subpix_sixtap4x4
+#define vp8_subpix_sixtap4x4 vp8_sixtap_predict_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_sixtap4x4);
+
+#ifndef vp8_subpix_bilinear16x16
+#define vp8_subpix_bilinear16x16 vp8_bilinear_predict16x16_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_bilinear16x16);
+
+#ifndef vp8_subpix_bilinear8x8
+#define vp8_subpix_bilinear8x8 vp8_bilinear_predict8x8_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_bilinear8x8);
+
+#ifndef vp8_subpix_bilinear8x4
+#define vp8_subpix_bilinear8x4 vp8_bilinear_predict8x4_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_bilinear8x4);
+
+#ifndef vp8_subpix_bilinear4x4
+#define vp8_subpix_bilinear4x4 vp8_bilinear_predict4x4_c
+#endif
+extern prototype_subpixel_predict(vp8_subpix_bilinear4x4);
+
+typedef prototype_subpixel_predict((*vp8_subpix_fn_t));
+typedef struct
+{
+    vp8_subpix_fn_t  sixtap16x16;
+    vp8_subpix_fn_t  sixtap8x8;
+    vp8_subpix_fn_t  sixtap8x4;
+    vp8_subpix_fn_t  sixtap4x4;
+    vp8_subpix_fn_t  bilinear16x16;
+    vp8_subpix_fn_t  bilinear8x8;
+    vp8_subpix_fn_t  bilinear8x4;
+    vp8_subpix_fn_t  bilinear4x4;
+} vp8_subpix_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define SUBPIX_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define SUBPIX_INVOKE(ctx,fn) vp8_subpix_##fn
+#endif
+
+#endif
diff --git a/vp8/common/swapyv12buffer.c b/vp8/common/swapyv12buffer.c
new file mode 100644 (file)
index 0000000..afe6a88
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "swapyv12buffer.h"
+
+void vp8_swap_yv12_buffer(YV12_BUFFER_CONFIG *new_frame, YV12_BUFFER_CONFIG *last_frame)
+{
+    unsigned char *temp;
+
+    temp = last_frame->buffer_alloc;
+    last_frame->buffer_alloc = new_frame->buffer_alloc;
+    new_frame->buffer_alloc = temp;
+
+    temp = last_frame->y_buffer;
+    last_frame->y_buffer = new_frame->y_buffer;
+    new_frame->y_buffer = temp;
+
+    temp = last_frame->u_buffer;
+    last_frame->u_buffer = new_frame->u_buffer;
+    new_frame->u_buffer = temp;
+
+    temp = last_frame->v_buffer;
+    last_frame->v_buffer = new_frame->v_buffer;
+    new_frame->v_buffer = temp;
+
+}
diff --git a/vp8/common/swapyv12buffer.h b/vp8/common/swapyv12buffer.h
new file mode 100644 (file)
index 0000000..caf9499
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef SWAPYV12_BUFFER_H
+#define SWAPYV12_BUFFER_H
+
+#include "vpx_scale/yv12config.h"
+
+void vp8_swap_yv12_buffer(YV12_BUFFER_CONFIG *new_frame, YV12_BUFFER_CONFIG *last_frame);
+
+#endif
diff --git a/vp8/common/systemdependent.h b/vp8/common/systemdependent.h
new file mode 100644 (file)
index 0000000..1829b64
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#if ARCH_X86 || ARCH_X86_64
+void vpx_reset_mmx_state(void);
+#define vp8_clear_system_state() vpx_reset_mmx_state()
+#else
+#define vp8_clear_system_state()
+#endif
+
+struct VP8Common;
+void vp8_machine_specific_config(struct VP8Common *);
diff --git a/vp8/common/textblit.c b/vp8/common/textblit.c
new file mode 100644 (file)
index 0000000..a45937b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+
+
+void vp8_blit_text(const char *msg, unsigned char *address, const int pitch)
+{
+    int letter_bitmap;
+    unsigned char *output_pos = address;
+    int colpos;
+    const int font[] =
+    {
+        0x0, 0x5C00, 0x8020, 0xAFABEA, 0xD7EC0, 0x1111111, 0x1855740, 0x18000,
+        0x45C0, 0x74400, 0x51140, 0x23880, 0xC4000, 0x21080, 0x80000, 0x111110,
+        0xE9D72E, 0x87E40, 0x12AD732, 0xAAD62A, 0x4F94C4, 0x4D6B7, 0x456AA,
+        0x3E8423, 0xAAD6AA, 0xAAD6A2, 0x2800, 0x2A00, 0x8A880, 0x52940, 0x22A20,
+        0x15422, 0x6AD62E, 0x1E4A53E, 0xAAD6BF, 0x8C62E, 0xE8C63F, 0x118D6BF,
+        0x1094BF, 0xCAC62E, 0x1F2109F, 0x118FE31, 0xF8C628, 0x8A89F, 0x108421F,
+        0x1F1105F, 0x1F4105F, 0xE8C62E, 0x2294BF, 0x164C62E, 0x12694BF, 0x8AD6A2,
+        0x10FC21, 0x1F8421F, 0x744107, 0xF8220F, 0x1151151, 0x117041, 0x119D731,
+        0x47E0, 0x1041041, 0xFC400, 0x10440, 0x1084210, 0x820
+    };
+    colpos = 0;
+
+    while (msg[colpos] != 0)
+    {
+        char letter = msg[colpos];
+        int fontcol, fontrow;
+
+        if (letter <= 'Z' && letter >= ' ')
+            letter_bitmap = font[letter-' '];
+        else if (letter <= 'z' && letter >= 'a')
+            letter_bitmap = font[letter-'a'+'A' - ' '];
+        else
+            letter_bitmap = font[0];
+
+        for (fontcol = 6; fontcol >= 0 ; fontcol--)
+            for (fontrow = 0; fontrow < 5; fontrow++)
+                output_pos[fontrow *pitch + fontcol] =
+                    ((letter_bitmap >> (fontcol * 5)) & (1 << fontrow) ? 255 : 0);
+
+        output_pos += 7;
+        colpos++;
+    }
+}
diff --git a/vp8/common/threading.h b/vp8/common/threading.h
new file mode 100644 (file)
index 0000000..a02cb24
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _PTHREAD_EMULATION
+#define _PTHREAD_EMULATION
+
+#define VPXINFINITE 10000       //10second.
+
+/* Thread management macros */
+#ifdef _WIN32
+/* Win32 */
+#define _WIN32_WINNT 0x500 /* WINBASE.H - Enable signal_object_and_wait */
+#include <process.h>
+#include <windows.h>
+#define THREAD_FUNCTION DWORD WINAPI
+#define THREAD_FUNCTION_RETURN DWORD
+#define THREAD_SPECIFIC_INDEX DWORD
+#define pthread_t HANDLE
+#define pthread_attr_t DWORD
+#define pthread_create(thhandle,attr,thfunc,tharg) (int)((*thhandle=(HANDLE)_beginthreadex(NULL,0,(unsigned int (__stdcall *)(void *))thfunc,tharg,0,NULL))==NULL)
+#define pthread_join(thread, result) ((WaitForSingleObject((thread),VPXINFINITE)!=WAIT_OBJECT_0) || !CloseHandle(thread))
+#define pthread_detach(thread) if(thread!=NULL)CloseHandle(thread)
+#define thread_sleep(nms) Sleep(nms)
+#define pthread_cancel(thread) terminate_thread(thread,0)
+#define ts_key_create(ts_key, destructor) {ts_key = TlsAlloc();};
+#define pthread_getspecific(ts_key) TlsGetValue(ts_key)
+#define pthread_setspecific(ts_key, value) TlsSetValue(ts_key, (void *)value)
+#define pthread_self() GetCurrentThreadId()
+#else
+#ifdef __APPLE__
+#include <mach/semaphore.h>
+#include <mach/task.h>
+#include <time.h>
+#include <unistd.h>
+
+#else
+#include <semaphore.h>
+#endif
+
+#include <pthread.h>
+/* pthreads */
+/* Nearly everything is already defined */
+#define THREAD_FUNCTION void *
+#define THREAD_FUNCTION_RETURN void *
+#define THREAD_SPECIFIC_INDEX pthread_key_t
+#define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor);
+#endif
+
+/* Syncrhronization macros: Win32 and Pthreads */
+#ifdef _WIN32
+#define sem_t HANDLE
+#define pause(voidpara) __asm PAUSE
+#define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateEvent(NULL,FALSE,FALSE,NULL))==NULL)
+#define sem_wait(sem) (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem,VPXINFINITE))
+#define sem_post(sem) SetEvent(*sem)
+#define sem_destroy(sem) if(*sem)((int)(CloseHandle(*sem))==TRUE)
+#define thread_sleep(nms) Sleep(nms)
+
+#else
+
+#ifdef __APPLE__
+#define sem_t semaphore_t
+#define sem_init(X,Y,Z) semaphore_create(mach_task_self(), X, SYNC_POLICY_FIFO, Z)
+#define sem_wait(sem) (semaphore_wait(*sem) )
+#define sem_post(sem) semaphore_signal(*sem)
+#define sem_destroy(sem) semaphore_destroy(mach_task_self(),*sem)
+#define thread_sleep(nms) // { struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);}
+#else
+#include <unistd.h>
+#define thread_sleep(nms) usleep(nms*1000);// {struct timespec ts;ts.tv_sec=0; ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);}
+#endif
+/* Not Windows. Assume pthreads */
+
+#endif
+
+#if ARCH_X86 || ARCH_X86_64
+#include "vpx_ports/x86.h"
+#else
+#define x86_pause_hint()
+#endif
+
+#endif
diff --git a/vp8/common/treecoder.c b/vp8/common/treecoder.c
new file mode 100644 (file)
index 0000000..4ad018d
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if CONFIG_DEBUG
+#include <assert.h>
+#endif
+#include <stdio.h>
+
+#include "treecoder.h"
+
+static void tree2tok(
+    struct vp8_token_struct *const p,
+    vp8_tree t,
+    int i,
+    int v,
+    int L
+)
+{
+    v += v;
+    ++L;
+
+    do
+    {
+        const vp8_tree_index j = t[i++];
+
+        if (j <= 0)
+        {
+            p[-j].value = v;
+            p[-j].Len = L;
+        }
+        else
+            tree2tok(p, t, j, v, L);
+    }
+    while (++v & 1);
+}
+
+void vp8_tokens_from_tree(struct vp8_token_struct *p, vp8_tree t)
+{
+    tree2tok(p, t, 0, 0, 0);
+}
+
+static void branch_counts(
+    int n,                      /* n = size of alphabet */
+    vp8_token tok               [ /* n */ ],
+    vp8_tree tree,
+    unsigned int branch_ct       [ /* n-1 */ ] [2],
+    const unsigned int num_events[ /* n */ ]
+)
+{
+    const int tree_len = n - 1;
+    int t = 0;
+
+#if CONFIG_DEBUG
+    assert(tree_len);
+#endif
+
+    do
+    {
+        branch_ct[t][0] = branch_ct[t][1] = 0;
+    }
+    while (++t < tree_len);
+
+    t = 0;
+
+    do
+    {
+        int L = tok[t].Len;
+        const int enc = tok[t].value;
+        const unsigned int ct = num_events[t];
+
+        vp8_tree_index i = 0;
+
+        do
+        {
+            const int b = (enc >> --L) & 1;
+            const int j = i >> 1;
+#if CONFIG_DEBUG
+            assert(j < tree_len  &&  0 <= L);
+#endif
+
+            branch_ct [j] [b] += ct;
+            i = tree[ i + b];
+        }
+        while (i > 0);
+
+#if CONFIG_DEBUG
+        assert(!L);
+#endif
+    }
+    while (++t < n);
+
+}
+
+
+void vp8_tree_probs_from_distribution(
+    int n,                      /* n = size of alphabet */
+    vp8_token tok               [ /* n */ ],
+    vp8_tree tree,
+    vp8_prob probs          [ /* n-1 */ ],
+    unsigned int branch_ct       [ /* n-1 */ ] [2],
+    const unsigned int num_events[ /* n */ ],
+    unsigned int Pfac,
+    int rd
+)
+{
+    const int tree_len = n - 1;
+    int t = 0;
+
+    branch_counts(n, tok, tree, branch_ct, num_events);
+
+    do
+    {
+        const unsigned int *const c = branch_ct[t];
+        const unsigned int tot = c[0] + c[1];
+
+#if CONFIG_DEBUG
+        assert(tot < (1 << 24));        /* no overflow below */
+#endif
+
+        if (tot)
+        {
+            const unsigned int p = ((c[0] * Pfac) + (rd ? tot >> 1 : 0)) / tot;
+            probs[t] = p < 256 ? (p ? p : 1) : 255; /* agree w/old version for now */
+        }
+        else
+            probs[t] = vp8_prob_half;
+    }
+    while (++t < tree_len);
+}
diff --git a/vp8/common/treecoder.h b/vp8/common/treecoder.h
new file mode 100644 (file)
index 0000000..0356d2b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_TREECODER_H
+#define __INC_TREECODER_H
+
+typedef unsigned char vp8bc_index_t; // probability index
+
+
+typedef unsigned char vp8_prob;
+
+#define vp8_prob_half ( (vp8_prob) 128)
+
+typedef signed char vp8_tree_index;
+struct bool_coder_spec;
+
+typedef struct bool_coder_spec bool_coder_spec;
+typedef struct bool_writer bool_writer;
+typedef struct bool_reader bool_reader;
+
+typedef const bool_coder_spec c_bool_coder_spec;
+typedef const bool_writer c_bool_writer;
+typedef const bool_reader c_bool_reader;
+
+
+
+# define vp8_complement( x) (255 - x)
+
+
+/* We build coding trees compactly in arrays.
+   Each node of the tree is a pair of vp8_tree_indices.
+   Array index often references a corresponding probability table.
+   Index <= 0 means done encoding/decoding and value = -Index,
+   Index > 0 means need another bit, specification at index.
+   Nonnegative indices are always even;  processing begins at node 0. */
+
+typedef const vp8_tree_index vp8_tree[], *vp8_tree_p;
+
+
+typedef const struct vp8_token_struct
+{
+    int value;
+    int Len;
+} vp8_token;
+
+/* Construct encoding array from tree. */
+
+void vp8_tokens_from_tree(struct vp8_token_struct *, vp8_tree);
+
+
+/* Convert array of token occurrence counts into a table of probabilities
+   for the associated binary encoding tree.  Also writes count of branches
+   taken for each node on the tree; this facilitiates decisions as to
+   probability updates. */
+
+void vp8_tree_probs_from_distribution(
+    int n,                      /* n = size of alphabet */
+    vp8_token tok               [ /* n */ ],
+    vp8_tree tree,
+    vp8_prob probs          [ /* n-1 */ ],
+    unsigned int branch_ct       [ /* n-1 */ ] [2],
+    const unsigned int num_events[ /* n */ ],
+    unsigned int Pfactor,
+    int Round
+);
+
+/* Variant of above using coder spec rather than hardwired 8-bit probs. */
+
+void vp8bc_tree_probs_from_distribution(
+    int n,                      /* n = size of alphabet */
+    vp8_token tok               [ /* n */ ],
+    vp8_tree tree,
+    vp8_prob probs          [ /* n-1 */ ],
+    unsigned int branch_ct       [ /* n-1 */ ] [2],
+    const unsigned int num_events[ /* n */ ],
+    c_bool_coder_spec *s
+);
+
+
+#endif
diff --git a/vp8/common/type_aliases.h b/vp8/common/type_aliases.h
new file mode 100644 (file)
index 0000000..addd264
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     type_aliases.h
+*
+*   Description  :     Standard type aliases
+*
+****************************************************************************/
+#ifndef __INC_TYPE_ALIASES_H
+#define __INC_TYPE_ALIASES_H
+
+/****************************************************************************
+* Macros
+****************************************************************************/
+#define EXPORT
+#define IMPORT          extern      /* Used to declare imported data & routines */
+#define PRIVATE         static      /* Used to declare & define module-local data */
+#define LOCAL           static      /* Used to define all persistent routine-local data */
+#define STD_IN_PATH     0           /* Standard input path */
+#define STD_OUT_PATH    1           /* Standard output path */
+#define STD_ERR_PATH    2           /* Standard error path */
+#define STD_IN_FILE     stdin       /* Standard input file pointer */
+#define STD_OUT_FILE    stdout      /* Standard output file pointer */
+#define STD_ERR_FILE    stderr      /* Standard error file pointer */
+#define max_int         0x7FFFFFFF
+
+#define __export
+#define _export
+
+#define CCONV
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+#ifndef FALSE
+#define FALSE   0
+#endif
+
+#ifndef TRUE
+#define TRUE    1
+#endif
+
+/****************************************************************************
+* Typedefs
+****************************************************************************/
+#ifndef TYPE_INT8
+#define TYPE_INT8
+typedef signed char     INT8;
+#endif
+
+#ifndef TYPE_INT16
+//#define TYPE_INT16
+typedef signed short    INT16;
+#endif
+
+#ifndef TYPE_INT32
+//#define TYPE_INT32
+typedef signed int      INT32;
+#endif
+
+#ifndef TYPE_UINT8
+//#define TYPE_UINT8
+typedef unsigned char   UINT8;
+#endif
+
+#ifndef TYPE_UINT32
+//#define TYPE_UINT32
+typedef unsigned int    UINT32;
+#endif
+
+#ifndef TYPE_UINT16
+//#define TYPE_UINT16
+typedef unsigned short  UINT16;
+#endif
+
+#ifndef TYPE_BOOL
+//#define TYPE_BOOL
+typedef int             BOOL;
+#endif
+
+typedef unsigned char   BOOLEAN;
+
+#ifdef _MSC_VER
+typedef __int64 INT64;
+#else
+
+#ifndef TYPE_INT64
+#ifdef _TMS320C6X
+//for now we only have 40bits
+typedef long INT64;
+#else
+typedef long long INT64;
+#endif
+#endif
+
+#endif
+
+/* Floating point */
+typedef  double         FLOAT64;
+typedef  float          FLOAT32;
+
+#endif
diff --git a/vp8/common/vfwsetting.hpp b/vp8/common/vfwsetting.hpp
new file mode 100644 (file)
index 0000000..e352e7a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if !defined(VFWSETTING_HPP)
+#define VFWSETTING_HPP
+//______________________________________________________________________________
+//
+//  VFWSetting.hpp
+//
+
+#include "four_cc.hpp"
+#include <iosfwd>
+
+namespace vpxvp
+{
+
+    //--------------------------------------
+    class VFWSetting
+    {
+        friend std::ostream& operator<<(std::ostream& os, const VFWSetting& vfws);
+
+    public:
+
+        enum Mode
+        {
+            m_setting,
+            m_config
+        };
+
+        enum
+        {
+            header_size = 8,
+            Size = 16
+        };
+
+        VFWSetting(four_cc fcc);
+        ~VFWSetting();
+
+        four_cc fcc() const;
+        Mode mode() const;
+
+        int setting() const;
+        int value() const;
+        void setting_value(int i_setting, int i_value);  //  Sets mode to m_setting
+
+        long size() const;
+        const void* data() const;
+        int data(const void* p_data, unsigned long ul_size);
+
+    private:
+
+        VFWSetting(const VFWSetting& vfws);  //  Not implemented
+        VFWSetting& operator=(const VFWSetting& vfws);  //  Not implemented
+
+        int extract_(const void* p_data, unsigned long ul_size);
+        void update_() const;
+
+        four_cc m_fcc;
+        Mode m_mode;
+        int m_i_setting;
+        int m_i_value;
+
+        mutable unsigned char m_p_data[Size];
+    };
+
+}  //  namespace vpxvp
+
+#endif  //  VFWSETTING_HPP
diff --git a/vp8/common/vpx_ref_build_prefix.h b/vp8/common/vpx_ref_build_prefix.h
new file mode 100644 (file)
index 0000000..40608c6
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _VPX_REF_BUILD_PREFIX_h
+#define _VPX_REF_BUILD_PREFIX_h
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* include guards */
diff --git a/vp8/common/vpxblit.h b/vp8/common/vpxblit.h
new file mode 100644 (file)
index 0000000..d03e0bd
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VPXBLIT_H_INCL
+#define VPXBLIT_H_INCL
+/*==============================================================================
+                              Includes
+==============================================================================*/
+
+/*==============================================================================
+                              Defines
+==============================================================================*/
+
+
+#ifdef VPX_BIG_ENDIAN
+#define BYTE_ZERO(X)    ((X & 0xFF000000) >> (24 - 2)   )
+#define BYTE_ONE(X)     ((X & 0x00FF0000) >> (16 - 2)   )
+#define BYTE_TWO(X)     ((X & 0x0000FF00) >> (8 - 2)    )
+#define BYTE_THREE(X)   ((X & 0x000000FF) << (0 + 2)    )
+
+#define BYTE_ZERO_UV(X) ((X & 0x0000FF00) >> (8 - 2)    )
+#define BYTE_ONE_UV(X)  ((X & 0x000000FF) << (0 + 2)    )
+
+#define REREFERENCE(X) (*((int *) &(X)))
+
+#else
+
+#define BYTE_THREE(X)   ((X & 0xFF000000) >> (24 - 2)   )
+#define BYTE_TWO(X)     ((X & 0x00FF0000) >> (16 - 2)   )
+#define BYTE_ONE(X)     ((X & 0x0000FF00) >> (8 - 2)    )
+#define BYTE_ZERO(X)    ((X & 0x000000FF) << (0 + 2)    )
+
+#define BYTE_ONE_UV(X) ((X & 0x0000FF00) >> (8 - 2) )
+#define BYTE_ZERO_UV(X)     ((X & 0x000000FF) << (0 + 2)    )
+
+#define REREFERENCE(X) (*((int *) &(X)))
+
+#endif
+
+
+/*==============================================================================
+                            Type Definitions
+==============================================================================*/
+typedef struct  // YUV buffer configuration structure
+{
+    int   y_width;
+    int   y_height;
+    int   y_stride;
+
+    int   uv_width;
+    int   uv_height;
+    int   uv_stride;
+
+    char *y_buffer;
+    char *u_buffer;
+    char *v_buffer;
+
+    char *uv_start;
+    int   uv_dst_area;
+    int   uv_used_area;
+
+} VPX_BLIT_CONFIG;
+
+typedef struct tx86_params
+{
+    unsigned int pushed_registers[6];
+    unsigned int return_address;
+    unsigned int dst;
+    unsigned int scrn_pitch;
+    VPX_BLIT_CONFIG *buff_config;
+} x86_params;
+
+/*=============================================================================
+                                Enums
+==============================================================================*/
+
+
+/*==============================================================================
+                              Structures
+==============================================================================*/
+
+/*==============================================================================
+                             Constants
+==============================================================================*/
+
+
+/*==============================================================================
+                               Variables
+==============================================================================*/
+
+
+
+
+/*==============================================================================
+                            Function Protoypes/MICROS
+==============================================================================*/
+int vpx_get_size_of_pixel(unsigned int bd);
+void *vpx_get_blitter(unsigned int bd);
+void vpx_set_blit(void);
+void vpx_destroy_blit(void);
+
+
+
+#endif //VPXBLIT_H_INCL
diff --git a/vp8/common/vpxblit_c64.h b/vp8/common/vpxblit_c64.h
new file mode 100644 (file)
index 0000000..a8e28f5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _VPX_BLIT_C64_h
+#define _VPX_BLIT_C64_h
+
+/****************************************************************************
+*  Typedefs
+****************************************************************************/
+
+typedef struct  // YUV buffer configuration structure
+{
+    int     y_width;
+    int     y_height;
+    int     y_stride;
+
+    int     uv_width;
+    int     uv_height;
+    int     uv_stride;
+
+    unsigned char *y_buffer;
+    unsigned char *u_buffer;
+    unsigned char *v_buffer;
+
+    unsigned char *y_ptr_scrn;
+    unsigned char *u_ptr_scrn;
+    unsigned char *v_ptr_scrn;
+
+} DXV_YUV_BUFFER_CONFIG;
+
+typedef struct
+{
+    unsigned char *rgbptr_scrn;
+    unsigned char *y_ptr_scrn;
+    unsigned char *u_ptr_scrn;
+    unsigned char *v_ptr_scrn;
+    unsigned char *rgbptr_scrn2;
+} DXV_FINAL_VIDEO;
+
+#endif /* include guards */
diff --git a/vp8/common/vpxerrors.h b/vp8/common/vpxerrors.h
new file mode 100644 (file)
index 0000000..e4c9f3e
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+
+#define ALLOC_FAILURE -2
diff --git a/vp8/common/x86/boolcoder.cxx b/vp8/common/x86/boolcoder.cxx
new file mode 100644 (file)
index 0000000..06faca6
--- /dev/null
@@ -0,0 +1,493 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+
+/* Arithmetic bool coder with largish probability range.
+   Timothy S Murphy  6 August 2004 */
+
+#include <assert.h>
+#include <math.h>
+
+#include "bool_coder.h"
+
+#if tim_vp8
+    extern "C" {
+#       include "VP8cx/treewriter.h"
+    }
+#endif
+
+int_types::~int_types() {}
+
+void bool_coder_spec::check_prec() const {
+    assert( w  &&  (r==Up || w > 1)  &&  w < 24  &&  (ebias || w < 17));
+}
+
+bool bool_coder_spec::float_init( uint Ebits, uint Mbits) {
+    uint b = (ebits = Ebits) + (mbits = Mbits);
+    if( b) {
+        assert( ebits < 6  &&  w + mbits < 31);
+        assert( ebits + mbits  <  sizeof(Index) * 8);
+        ebias = (1 << ebits) + 1 + mbits;
+        mmask = (1 << mbits) - 1;
+        max_index = ( ( half_index = 1 << b ) << 1) - 1;
+    } else {
+        ebias = 0;
+        max_index = 255;
+        half_index = 128;
+    }
+    check_prec();
+    return b? 1:0;
+}
+
+void bool_coder_spec::cost_init()
+{
+    static cdouble c = -(1 << 20)/log( 2.);
+
+    FILE *f = fopen( "costs.txt", "w");
+    assert( f);
+
+    assert( sizeof(int) >= 4);  /* for C interface */
+    assert( max_index <= 255);   /* size of Ctbl */
+    uint i = 0;  do {
+        cdouble p = ( *this)( (Index) i);
+        Ctbl[i] = (uint32) ( log( p) * c);
+        fprintf(
+            f, "cost( %d -> %10.7f) = %10d = %12.5f bits\n",
+            i, p, Ctbl[i], (double) Ctbl[i] / (1<<20)
+        );
+    } while( ++i <= max_index);
+    fclose( f);
+}
+
+bool_coder_spec_explicit_table::bool_coder_spec_explicit_table(
+    cuint16 tbl[256], Rounding rr, uint prec
+)
+  : bool_coder_spec( prec, rr)
+{
+    check_prec();
+    uint i = 0;
+    if( tbl)
+        do { Ptbl[i] = tbl[i];}  while( ++i < 256);
+    else
+        do { Ptbl[i] = i << 8;}  while( ++i < 256);
+    cost_init();
+}
+
+
+bool_coder_spec_exponential_table::bool_coder_spec_exponential_table(
+    uint x, Rounding rr, uint prec
+)
+  : bool_coder_spec( prec, rr)
+{
+    assert( x > 1  &&  x <= 16);
+    check_prec();
+    Ptbl[128] = 32768u;
+    Ptbl[0] = (uint16) pow( 2., 16. - x);
+    --x;
+    int i=1;  do {
+        cdouble d = pow( .5, 1. + (1. - i/128.)*x) * 65536.;
+        uint16 v = (uint16) d;
+        if( v < i)
+            v = i;
+        Ptbl[256-i] = (uint16) ( 65536U - (Ptbl[i] = v));
+    } while( ++i < 128);
+    cost_init();
+}
+
+bool_coder_spec::bool_coder_spec( FILE *fp) {
+    fscanf( fp, "%d", &w);
+    int v;
+    fscanf( fp, "%d", &v);
+    assert( 0 <= v  &&  v <= 2);
+    r = (Rounding) v;
+    fscanf( fp, "%d", &ebits);
+    fscanf( fp, "%d", &mbits);
+    if( float_init( ebits, mbits))
+        return;
+    int i=0;  do {
+        uint v;
+        fscanf( fp, "%d", &v);
+        assert( 0 <=v  &&  v <= 65535U);
+        Ptbl[i] = v;
+    } while( ++i < 256);
+    cost_init();
+}
+
+void bool_coder_spec::dump( FILE *fp) const {
+    fprintf( fp, "%d %d %d %d\n", w, (int) r, ebits, mbits);
+    if( ebits  ||  mbits)
+        return;
+    int i=0;  do { fprintf( fp, "%d\n", Ptbl[i]);}  while( ++i < 256);
+}
+
+vp8bc_index_t bool_coder_spec::operator()( double p) const
+{
+    if( p <= 0.)
+        return 0;
+    if( p >= 1.)
+        return max_index;
+    if( ebias) {
+        if( p > .5)
+            return max_index - ( *this)( 1. - p);
+        int e;
+        uint m = (uint) ldexp( frexp( p, &e), mbits + 2);
+        uint x = 1 << (mbits + 1);
+        assert( x <= m  &&  m < x<<1);
+        if( (m = (m >> 1) + (m & 1)) >= x) {
+            m = x >> 1;
+            ++e;
+        }
+        int y = 1 << ebits;
+        if( (e += y) >= y)
+            return half_index - 1;
+        if( e < 0)
+            return 0;
+        return (Index) ( (e << mbits) + (m & mmask));
+    }
+
+    cuint16 v = (uint16) (p * 65536.);
+    int i = 128;
+    int j = 128;
+    uint16 w;
+    while( w = Ptbl[i], j >>= 1) {
+        if( w < v)
+            i += j;
+        else if( w == v)
+            return (uchar) i;
+        else
+            i -= j;
+    }
+    if( w > v) {
+        cuint16 x = Ptbl[i-1];
+        if( v <= x  ||  w - v > v - x)
+            --i;
+    } else if( w < v  &&  i < 255) {
+        cuint16 x = Ptbl[i+1];
+        if( x <= v  ||  x - v < v - w)
+            ++i;
+    }
+    return (Index) i;
+}
+
+double bool_coder_spec::operator()( Index i) const {
+    if( !ebias)
+        return Ptbl[i]/65536.;
+    if( i >= half_index)
+        return 1. - ( *this)( (Index) (max_index - i));
+    return ldexp( (double)mantissa( i), - (int) exponent( i));
+}
+
+
+
+void bool_writer::carry() {
+    uchar *p = B;
+    assert( p > Bstart);
+    while( *--p == 255) { assert( p > Bstart);  *p = 0;}
+    ++*p;
+}
+
+
+bool_writer::bool_writer( c_spec& s, uchar *Dest, size_t Len)
+  : bool_coder( s),
+    Bstart( Dest),
+    Bend( Len? Dest+Len : 0),
+    B( Dest)
+{
+    assert( Dest);
+    reset();
+}
+
+bool_writer::~bool_writer() { flush();}
+
+#if 1
+    extern "C" { int bc_v = 0;}
+#else
+#   define bc_v 0
+#endif
+
+
+void bool_writer::raw( bool value, uint32 s) {
+    uint32 L = Low;
+
+    assert( Range >= min_range  &&  Range <= spec.max_range());
+    assert( !is_toast  &&  s  &&  s < Range);
+
+    if( bc_v) printf(
+        "Writing a %d, B %x  Low %x  Range %x  s %x   blag %d ...\n",
+        value? 1:0, B-Bstart, Low, Range, s, bit_lag
+    );
+    if( value) {
+        L += s;
+        s = Range - s;
+    } else
+        s -= rinc;
+    if( s < min_range) {
+        int ct = bit_lag;  do {
+            if( !--ct) {
+                ct = 8;
+                if( L & (1 << 31))
+                    carry();
+                assert( !Bend  ||  B < Bend);
+                *B++ = (uchar) (L >> 23);
+                L &= (1<<23) - 1;
+            }
+        } while( L += L, (s += s + rinc) < min_range);
+        bit_lag = ct;
+    }
+    Low = L;
+    Range = s;
+    if( bc_v)
+        printf(
+            "...done, B %x  Low %x  Range %x  blag %d \n",
+                B-Bstart, Low, Range, bit_lag
+        );
+}
+
+bool_writer& bool_writer::flush() {
+    if( is_toast)
+        return *this;
+    int b = bit_lag;
+    uint32 L = Low;
+    assert( b);
+    if( L & (1 << (32 - b)))
+        carry();
+    L <<= b & 7;
+    b >>= 3;
+    while( --b >= 0)
+        L <<= 8;
+    b = 4;
+    assert( !Bend  ||  B + 4 <= Bend);
+    do {
+        *B++ = (uchar) (L >> 24);
+        L <<= 8;
+    } while( --b);
+    is_toast = 1;
+    return *this;
+}
+
+
+bool_reader::bool_reader( c_spec& s, cuchar *src, size_t Len)
+  : bool_coder( s),
+    Bstart( src),
+    B( src),
+    Bend( Len? src+Len : 0),
+    shf( 32 - s.w),
+    bct( 8)
+{
+    int i = 4;  do { Low <<= 8;  Low |= *B++;}  while( --i);
+}
+
+
+bool bool_reader::raw( uint32 s) {
+
+    bool val = 0;
+    uint32 L = Low;
+    cuint32 S = s << shf;
+
+    assert( Range >= min_range  &&  Range <= spec.max_range());
+    assert( s  &&  s < Range  &&  (L >> shf) < Range);
+
+    if( bc_v)
+        printf(
+            "Reading, B %x  Low %x  Range %x  s %x  bct %d ...\n",
+            B-Bstart, Low, Range, s, bct
+        );
+
+    if( L >= S) {
+        L -= S;
+        s = Range - s;
+        assert( L < (s << shf));
+        val = 1;
+    } else
+        s -= rinc;
+    if( s < min_range) {
+        int ct = bct;
+        do {
+            assert( ~L & (1 << 31));
+            L += L;
+            if( !--ct) {
+                ct = 8;
+                if( !Bend  ||  B < Bend)
+                    L |= *B++;
+            }
+        } while( (s += s + rinc) < min_range);
+        bct = ct;
+    }
+    Low = L;
+    Range = s;
+    if( bc_v)
+        printf(
+            "...done, val %d  B %x  Low %x  Range %x  bct %d\n",
+            val? 1:0, B-Bstart, Low, Range, bct
+        );
+    return val;
+}
+
+
+/* C interfaces */
+
+// spec interface
+
+struct NS : bool_coder_namespace {
+    static Rounding r( vp8bc_c_prec *p, Rounding rr =down_full) {
+        return p? (Rounding) p->r : rr;
+    }
+};
+
+bool_coder_spec *vp8bc_vp6spec() {
+    return new bool_coder_spec_explicit_table( 0, bool_coder_namespace::Down, 8);
+}
+bool_coder_spec *vp8bc_float_spec(
+    unsigned int Ebits, unsigned int Mbits, vp8bc_c_prec *p
+) {
+    return new bool_coder_spec_float( Ebits, Mbits, NS::r( p), p? p->prec : 12);
+}
+bool_coder_spec *vp8bc_literal_spec(
+    const unsigned short m[256], vp8bc_c_prec *p
+) {
+    return new bool_coder_spec_explicit_table( m, NS::r( p), p? p->prec : 16);
+}
+bool_coder_spec *vp8bc_exponential_spec( unsigned int x, vp8bc_c_prec *p)
+{
+    return new bool_coder_spec_exponential_table( x, NS::r( p), p? p->prec : 16);
+}
+bool_coder_spec *vp8bc_spec_from_file( FILE *fp) {
+    return new bool_coder_spec( fp);
+}
+void vp8bc_destroy_spec( c_bool_coder_spec *p) { delete p;}
+
+void vp8bc_spec_to_file( c_bool_coder_spec *p, FILE *fp) { p->dump( fp);}
+
+vp8bc_index_t vp8bc_index( c_bool_coder_spec *p, double x) {
+    return ( *p)( x);
+}
+
+vp8bc_index_t vp8bc_index_from_counts(
+    c_bool_coder_spec *p, unsigned int L, unsigned int R
+) {
+    return ( *p)( (R += L)? (double) L/R : .5);
+}
+
+double vp8bc_probability( c_bool_coder_spec *p, vp8bc_index_t i) {
+    return ( *p)( i);
+}
+
+vp8bc_index_t vp8bc_complement( c_bool_coder_spec *p, vp8bc_index_t i) {
+    return p->complement( i);
+}
+unsigned int vp8bc_cost_zero( c_bool_coder_spec *p, vp8bc_index_t i) {
+    return p->cost_zero( i);
+}
+unsigned int vp8bc_cost_one( c_bool_coder_spec *p, vp8bc_index_t i) {
+    return p->cost_one( i);
+}
+unsigned int vp8bc_cost_bit( c_bool_coder_spec *p, vp8bc_index_t i, int v) {
+    return p->cost_bit( i, v);
+}
+
+#if tim_vp8
+    extern "C" int tok_verbose;
+
+#   define dbg_l 1000000
+
+    static vp8bc_index_t dbg_i [dbg_l];
+    static char dbg_v [dbg_l];
+    static size_t dbg_w = 0, dbg_r = 0;
+#endif
+
+// writer interface
+
+bool_writer *vp8bc_create_writer(
+    c_bool_coder_spec *p, unsigned char *D, size_t L
+) {
+    return new bool_writer( *p, D, L);
+}
+
+size_t vp8bc_destroy_writer( bool_writer *p) {
+    const size_t s = p->flush().bytes_written();
+    delete p;
+    return s;
+}
+
+void vp8bc_write_bool( bool_writer *p, int v, vp8bc_index_t i)
+{
+#   if tim_vp8
+        // bc_v = dbg_w < 10;
+        if( bc_v = tok_verbose)
+            printf( " writing %d at prob %d\n", v? 1:0, i);
+        accum_entropy_bc( &p->Spec(), i, v);
+
+        ( *p)( i, (bool) v);
+
+        if( dbg_w < dbg_l) {
+            dbg_i [dbg_w] = i;
+            dbg_v [dbg_w++] = v? 1:0;
+        }
+#   else
+        ( *p)( i, (bool) v);
+#   endif
+}
+
+void vp8bc_write_bits( bool_writer *p, unsigned int v, int n)
+{
+#   if tim_vp8
+        {
+            c_bool_coder_spec * const s = & p->Spec();
+            const vp8bc_index_t i = s->half_index();
+            int m = n;
+            while( --m >= 0)
+                accum_entropy_bc( s, i, (v>>m) & 1);
+        }
+#   endif
+
+    p->write_bits( n, v);
+}
+
+c_bool_coder_spec *vp8bc_writer_spec( c_bool_writer *w) { return & w->Spec();}
+
+// reader interface
+
+bool_reader *vp8bc_create_reader(
+    c_bool_coder_spec *p, const unsigned char *S, size_t L
+) {
+    return new bool_reader( *p, S, L);
+}
+
+void vp8bc_destroy_reader( bool_reader * p) { delete p;}
+
+int vp8bc_read_bool( bool_reader *p, vp8bc_index_t i)
+{
+#   if tim_vp8
+        // bc_v = dbg_r < 10;
+        bc_v = tok_verbose;
+        const int v = ( *p)( i)? 1:0;
+        if( tok_verbose)
+            printf( " reading %d at prob %d\n", v, i);
+        if( dbg_r < dbg_l) {
+            assert( dbg_r <= dbg_w);
+            if( i != dbg_i[dbg_r]  ||  v != dbg_v[dbg_r]) {
+                printf(
+        "Position %d: INCORRECTLY READING %d  prob %d, wrote %d  prob %d\n",
+                    dbg_r, v, i, dbg_v[dbg_r], dbg_i[dbg_r]
+                );
+            }
+            ++dbg_r;
+        }
+        return v;
+#   else
+        return ( *p)( i)? 1:0;
+#   endif
+}
+
+unsigned int vp8bc_read_bits( bool_reader *p, int n) { return p->read_bits( n);}
+
+c_bool_coder_spec *vp8bc_reader_spec( c_bool_reader *r) { return & r->Spec();}
+
+#undef bc_v
diff --git a/vp8/common/x86/idct_x86.h b/vp8/common/x86/idct_x86.h
new file mode 100644 (file)
index 0000000..5dfb212
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef IDCT_X86_H
+#define IDCT_X86_H
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+
+#if HAVE_MMX
+extern prototype_idct(vp8_short_idct4x4llm_1_mmx);
+extern prototype_idct(vp8_short_idct4x4llm_mmx);
+extern prototype_idct_scalar(vp8_dc_only_idct_mmx);
+
+extern prototype_second_order(vp8_short_inv_walsh4x4_mmx);
+extern prototype_second_order(vp8_short_inv_walsh4x4_1_mmx);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_idct_idct1
+#define vp8_idct_idct1 vp8_short_idct4x4llm_1_mmx
+
+#undef  vp8_idct_idct16
+#define vp8_idct_idct16 vp8_short_idct4x4llm_mmx
+
+#undef  vp8_idct_idct1_scalar
+#define vp8_idct_idct1_scalar vp8_dc_only_idct_mmx
+
+#undef vp8_idct_iwalsh16
+#define vp8_idct_iwalsh16 vp8_short_inv_walsh4x4_mmx
+
+#undef vp8_idct_iwalsh1
+#define vp8_idct_iwalsh1 vp8_short_inv_walsh4x4_1_mmx
+
+#endif
+#endif
+
+#if HAVE_SSE2
+
+extern prototype_second_order(vp8_short_inv_walsh4x4_sse2);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+
+#undef vp8_idct_iwalsh16
+#define vp8_idct_iwalsh16 vp8_short_inv_walsh4x4_sse2
+
+#endif
+
+#endif
+
+
+
+#endif
diff --git a/vp8/common/x86/idctllm_mmx.asm b/vp8/common/x86/idctllm_mmx.asm
new file mode 100644 (file)
index 0000000..2751c69
--- /dev/null
@@ -0,0 +1,265 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+; /****************************************************************************
+; * Notes:
+; *
+; * This implementation makes use of 16 bit fixed point verio of two multiply
+; * constants:
+; *        1.   sqrt(2) * cos (pi/8)
+; *         2.   sqrt(2) * sin (pi/8)
+; * Becuase the first constant is bigger than 1, to maintain the same 16 bit
+; * fixed point prrcision as the second one, we use a trick of
+; *        x * a = x + x*(a-1)
+; * so
+; *        x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1).
+; *
+; * For     the second constant, becuase of the 16bit version is 35468, which
+; * is bigger than 32768, in signed 16 bit multiply, it become a negative
+; * number.
+; *        (x * (unsigned)35468 >> 16) = x * (signed)35468 >> 16 + x
+; *
+; **************************************************************************/
+
+
+;void short_idct4x4llm_mmx(short *input, short *output, int pitch)
+global sym(vp8_short_idct4x4llm_mmx)
+sym(vp8_short_idct4x4llm_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    GET_GOT     rbx
+    ; end prolog
+
+        mov         rax,            arg(0) ;input
+        mov         rdx,            arg(1) ;output
+
+        movq        mm0,            [rax   ]
+        movq        mm1,            [rax+ 8]
+
+        movq        mm2,            [rax+16]
+        movq        mm3,            [rax+24]
+
+        movsxd      rax,            dword ptr arg(2) ;pitch
+
+        psubw       mm0,            mm2             ; b1= 0-2
+        paddw       mm2,            mm2             ;
+
+        movq        mm5,            mm1
+        paddw       mm2,            mm0             ; a1 =0+2
+
+        pmulhw      mm5,            [x_s1sqr2 GLOBAL]        ;
+        paddw       mm5,            mm1             ; ip1 * sin(pi/8) * sqrt(2)
+
+        movq        mm7,            mm3             ;
+        pmulhw      mm7,            [x_c1sqr2less1 GLOBAL]    ;
+
+        paddw       mm7,            mm3             ; ip3 * cos(pi/8) * sqrt(2)
+        psubw       mm7,            mm5             ; c1
+
+        movq        mm5,            mm1
+        movq        mm4,            mm3
+
+        pmulhw      mm5,            [x_c1sqr2less1 GLOBAL]
+        paddw       mm5,            mm1
+
+        pmulhw      mm3,            [x_s1sqr2 GLOBAL]
+        paddw       mm3,            mm4
+
+        paddw       mm3,            mm5             ; d1
+        movq        mm6,            mm2             ; a1
+
+        movq        mm4,            mm0             ; b1
+        paddw       mm2,            mm3             ;0
+
+        paddw       mm4,            mm7             ;1
+        psubw       mm0,            mm7             ;2
+
+        psubw       mm6,            mm3             ;3
+
+        movq        mm1,            mm2             ; 03 02 01 00
+        movq        mm3,            mm4             ; 23 22 21 20
+
+        punpcklwd   mm1,            mm0             ; 11 01 10 00
+        punpckhwd   mm2,            mm0             ; 13 03 12 02
+
+        punpcklwd   mm3,            mm6             ; 31 21 30 20
+        punpckhwd   mm4,            mm6             ; 33 23 32 22
+
+        movq        mm0,            mm1             ; 11 01 10 00
+        movq        mm5,            mm2             ; 13 03 12 02
+
+        punpckldq   mm0,            mm3             ; 30 20 10 00
+        punpckhdq   mm1,            mm3             ; 31 21 11 01
+
+        punpckldq   mm2,            mm4             ; 32 22 12 02
+        punpckhdq   mm5,            mm4             ; 33 23 13 03
+
+        movq        mm3,            mm5             ; 33 23 13 03
+
+        psubw       mm0,            mm2             ; b1= 0-2
+        paddw       mm2,            mm2             ;
+
+        movq        mm5,            mm1
+        paddw       mm2,            mm0             ; a1 =0+2
+
+        pmulhw      mm5,            [x_s1sqr2 GLOBAL]         ;
+        paddw       mm5,            mm1             ; ip1 * sin(pi/8) * sqrt(2)
+
+        movq        mm7,            mm3             ;
+        pmulhw      mm7,            [x_c1sqr2less1 GLOBAL]    ;
+
+        paddw       mm7,            mm3             ; ip3 * cos(pi/8) * sqrt(2)
+        psubw       mm7,            mm5             ; c1
+
+        movq        mm5,            mm1
+        movq        mm4,            mm3
+
+        pmulhw      mm5,            [x_c1sqr2less1 GLOBAL]
+        paddw       mm5,            mm1
+
+        pmulhw      mm3,            [x_s1sqr2 GLOBAL]
+        paddw       mm3,            mm4
+
+        paddw       mm3,            mm5             ; d1
+        paddw       mm0,            [fours GLOBAL]
+
+        paddw       mm2,            [fours GLOBAL]
+        movq        mm6,            mm2             ; a1
+
+        movq        mm4,            mm0             ; b1
+        paddw       mm2,            mm3             ;0
+
+        paddw       mm4,            mm7             ;1
+        psubw       mm0,            mm7             ;2
+
+        psubw       mm6,            mm3             ;3
+        psraw       mm2,            3
+
+        psraw       mm0,            3
+        psraw       mm4,            3
+
+        psraw       mm6,            3
+
+        movq        mm1,            mm2             ; 03 02 01 00
+        movq        mm3,            mm4             ; 23 22 21 20
+
+        punpcklwd   mm1,            mm0             ; 11 01 10 00
+        punpckhwd   mm2,            mm0             ; 13 03 12 02
+
+        punpcklwd   mm3,            mm6             ; 31 21 30 20
+        punpckhwd   mm4,            mm6             ; 33 23 32 22
+
+        movq        mm0,            mm1             ; 11 01 10 00
+        movq        mm5,            mm2             ; 13 03 12 02
+
+        punpckldq   mm0,            mm3             ; 30 20 10 00
+        punpckhdq   mm1,            mm3             ; 31 21 11 01
+
+        punpckldq   mm2,            mm4             ; 32 22 12 02
+        punpckhdq   mm5,            mm4             ; 33 23 13 03
+
+        movq        [rdx],          mm0
+
+        movq        [rdx+rax],      mm1
+        movq        [rdx+rax*2],    mm2
+
+        add         rdx,            rax
+        movq        [rdx+rax*2],    mm5
+
+    ; begin epilog
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void short_idct4x4llm_1_mmx(short *input, short *output, int pitch)
+global sym(vp8_short_idct4x4llm_1_mmx)
+sym(vp8_short_idct4x4llm_1_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    GET_GOT     rbx
+    ; end prolog
+
+        mov         rax,            arg(0) ;input
+        movd        mm0,            [rax]
+
+        paddw       mm0,            [fours GLOBAL]
+        mov         rdx,            arg(1) ;output
+
+        psraw       mm0,            3
+        movsxd      rax,            dword ptr arg(2) ;pitch
+
+        punpcklwd   mm0,            mm0
+        punpckldq   mm0,            mm0
+
+        movq        [rdx],          mm0
+        movq        [rdx+rax],      mm0
+
+        movq        [rdx+rax*2],    mm0
+        add         rdx,            rax
+
+        movq        [rdx+rax*2],    mm0
+
+
+    ; begin epilog
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void dc_only_idct_mmx(short input_dc, short *output, int pitch)
+global sym(vp8_dc_only_idct_mmx)
+sym(vp8_dc_only_idct_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    GET_GOT     rbx
+    ; end prolog
+
+        movd        mm0,            arg(0) ;input_dc
+
+        paddw       mm0,            [fours GLOBAL]
+        mov         rdx,            arg(1) ;output
+
+        psraw       mm0,            3
+        movsxd      rax,            dword ptr arg(2) ;pitch
+
+        punpcklwd   mm0,            mm0
+        punpckldq   mm0,            mm0
+
+        movq        [rdx],          mm0
+        movq        [rdx+rax],      mm0
+
+        movq        [rdx+rax*2],    mm0
+        add         rdx,            rax
+
+        movq        [rdx+rax*2],    mm0
+
+    ; begin epilog
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+SECTION_RODATA
+align 16
+x_s1sqr2:
+    times 4 dw 0x8A8C
+align 16
+x_c1sqr2less1:
+    times 4 dw 0x4E7B
+align 16
+fours:
+    times 4 dw 0x0004
diff --git a/vp8/common/x86/iwalsh_mmx.asm b/vp8/common/x86/iwalsh_mmx.asm
new file mode 100644 (file)
index 0000000..562e590
--- /dev/null
@@ -0,0 +1,172 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;void vp8_short_inv_walsh4x4_1_mmx(short *input, short *output)
+global sym(vp8_short_inv_walsh4x4_1_mmx)
+sym(vp8_short_inv_walsh4x4_1_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    mov     rsi, arg(0)
+    mov     rax, 3
+
+    mov     rdi, arg(1)
+    add     rax, [rsi]          ;input[0] + 3
+
+    movd    mm0, eax
+
+    punpcklwd mm0, mm0          ;x x val val
+
+    punpckldq mm0, mm0          ;val val val val
+
+    psraw   mm0, 3            ;(input[0] + 3) >> 3
+
+    movq  [rdi + 0], mm0
+    movq  [rdi + 8], mm0
+    movq  [rdi + 16], mm0
+    movq  [rdi + 24], mm0
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void vp8_short_inv_walsh4x4_mmx(short *input, short *output)
+global sym(vp8_short_inv_walsh4x4_mmx)
+sym(vp8_short_inv_walsh4x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    mov     rax, 3
+    mov     rsi, arg(0)
+    mov     rdi, arg(1)
+    shl     rax, 16
+
+    movq    mm0, [rsi + 0]        ;ip[0]
+    movq    mm1, [rsi + 8]        ;ip[4]
+    or      rax, 3            ;00030003h
+
+    movq    mm2, [rsi + 16]       ;ip[8]
+    movq    mm3, [rsi + 24]       ;ip[12]
+
+    movd    mm7, rax
+    movq    mm4, mm0
+
+    punpcklwd mm7, mm7          ;0003000300030003h
+    movq    mm5, mm1
+
+    paddw   mm4, mm3          ;ip[0] + ip[12] aka al
+    paddw   mm5, mm2          ;ip[4] + ip[8] aka bl
+
+    movq    mm6, mm4          ;temp al
+
+    paddw   mm4, mm5          ;al + bl
+    psubw   mm6, mm5          ;al - bl
+
+    psubw   mm0, mm3          ;ip[0] - ip[12] aka d1
+    psubw   mm1, mm2          ;ip[4] - ip[8] aka c1
+
+    movq    mm5, mm0          ;temp dl
+
+    paddw   mm0, mm1          ;dl + cl
+    psubw   mm5, mm1          ;dl - cl
+
+    ; 03 02 01 00
+    ; 13 12 11 10
+    ; 23 22 21 20
+    ; 33 32 31 30
+
+    movq    mm3, mm4          ; 03 02 01 00
+    punpcklwd mm4, mm0          ; 11 01 10 00
+    punpckhwd mm3, mm0          ; 13 03 12 02
+
+    movq    mm1, mm6          ; 23 22 21 20
+    punpcklwd mm6, mm5          ; 31 21 30 20
+    punpckhwd mm1, mm5          ; 33 23 32 22
+
+    movq    mm0, mm4          ; 11 01 10 00
+    movq    mm2, mm3          ; 13 03 12 02
+
+    punpckldq mm0, mm6          ; 30 20 10 00 aka ip[0]
+    punpckhdq mm4, mm6          ; 31 21 11 01 aka ip[4]
+
+    punpckldq mm2, mm1          ; 32 22 12 02 aka ip[8]
+    punpckhdq mm3, mm1          ; 33 23 13 03 aka ip[12]
+;~~~~~~~~~~~~~~~~~~~~~
+    movq    mm1, mm0
+    movq    mm5, mm4
+
+    paddw   mm1, mm3          ;ip[0] + ip[12] aka al
+    paddw   mm5, mm2          ;ip[4] + ip[8] aka bl
+
+    movq    mm6, mm1          ;temp al
+
+    paddw   mm1, mm5          ;al + bl
+    psubw   mm6, mm5          ;al - bl
+
+    psubw   mm0, mm3          ;ip[0] - ip[12] aka d1
+    psubw   mm4, mm2          ;ip[4] - ip[8] aka c1
+
+    movq    mm5, mm0          ;temp dl
+
+    paddw   mm0, mm4          ;dl + cl
+    psubw   mm5, mm4          ;dl - cl
+;~~~~~~~~~~~~~~~~~~~~~
+    movq    mm3, mm1          ; 03 02 01 00
+    punpcklwd mm1, mm0          ; 11 01 10 00
+    punpckhwd mm3, mm0          ; 13 03 12 02
+
+    movq    mm4, mm6          ; 23 22 21 20
+    punpcklwd mm6, mm5          ; 31 21 30 20
+    punpckhwd mm4, mm5          ; 33 23 32 22
+
+    movq    mm0, mm1          ; 11 01 10 00
+    movq    mm2, mm3          ; 13 03 12 02
+
+    punpckldq mm0, mm6          ; 30 20 10 00 aka ip[0]
+    punpckhdq mm1, mm6          ; 31 21 11 01 aka ip[4]
+
+    punpckldq mm2, mm4          ; 32 22 12 02 aka ip[8]
+    punpckhdq mm3, mm4          ; 33 23 13 03 aka ip[12]
+
+    paddw   mm0, mm7
+    paddw   mm1, mm7
+    paddw   mm2, mm7
+    paddw   mm3, mm7
+
+    psraw   mm0, 3
+    psraw   mm1, 3
+    psraw   mm2, 3
+    psraw   mm3, 3
+
+    movq  [rdi + 0], mm0
+    movq  [rdi + 8], mm1
+    movq  [rdi + 16], mm2
+    movq  [rdi + 24], mm3
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
diff --git a/vp8/common/x86/iwalsh_sse2.asm b/vp8/common/x86/iwalsh_sse2.asm
new file mode 100644 (file)
index 0000000..96943df
--- /dev/null
@@ -0,0 +1,116 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;void vp8_short_inv_walsh4x4_sse2(short *input, short *output)
+global sym(vp8_short_inv_walsh4x4_sse2)
+sym(vp8_short_inv_walsh4x4_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    mov     rsi, arg(0)
+    mov     rdi, arg(1)
+    mov     rax, 3
+
+    movdqa    xmm0, [rsi + 0]       ;ip[4] ip[0]
+    movdqa    xmm1, [rsi + 16]      ;ip[12] ip[8]
+
+    shl     rax, 16
+    or      rax, 3            ;00030003h
+
+    pshufd    xmm2, xmm1, 4eh       ;ip[8] ip[12]
+    movdqa    xmm3, xmm0          ;ip[4] ip[0]
+
+    paddw   xmm0, xmm2          ;ip[4]+ip[8] ip[0]+ip[12] aka b1 a1
+    psubw   xmm3, xmm2          ;ip[4]-ip[8] ip[0]-ip[12] aka c1 d1
+
+    movdqa    xmm4, xmm0
+    punpcklqdq  xmm0, xmm3          ;d1 a1
+    punpckhqdq  xmm4, xmm3          ;c1 b1
+    movd    xmm7, eax
+
+    movdqa    xmm1, xmm4          ;c1 b1
+    paddw   xmm4, xmm0          ;dl+cl a1+b1 aka op[4] op[0]
+    psubw   xmm0, xmm1          ;d1-c1 a1-b1 aka op[12] op[8]
+
+;;;temp output
+;;  movdqu  [rdi + 0], xmm4
+;;  movdqu  [rdi + 16], xmm3
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ; 13 12 11 10 03 02 01 00
+    ;
+    ; 33 32 31 30 23 22 21 20
+    ;
+    movdqa    xmm3, xmm4          ; 13 12 11 10 03 02 01 00
+    punpcklwd xmm4, xmm0          ; 23 03 22 02 21 01 20 00
+    punpckhwd xmm3, xmm0          ; 33 13 32 12 31 11 30 10
+    movdqa    xmm1, xmm4          ; 23 03 22 02 21 01 20 00
+    punpcklwd xmm4, xmm3          ; 31 21 11 01 30 20 10 00
+    punpckhwd xmm1, xmm3          ; 33 23 13 03 32 22 12 02
+    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    pshufd    xmm2, xmm1, 4eh       ;ip[8] ip[12]
+    movdqa    xmm3, xmm4          ;ip[4] ip[0]
+
+    pshufd    xmm7, xmm7, 0       ;03 03 03 03 03 03 03 03
+
+    paddw   xmm4, xmm2          ;ip[4]+ip[8] ip[0]+ip[12] aka b1 a1
+    psubw   xmm3, xmm2          ;ip[4]-ip[8] ip[0]-ip[12] aka c1 d1
+
+    movdqa    xmm5, xmm4
+    punpcklqdq  xmm4, xmm3          ;d1 a1
+    punpckhqdq  xmm5, xmm3          ;c1 b1
+
+    movdqa    xmm1, xmm5          ;c1 b1
+    paddw   xmm5, xmm4          ;dl+cl a1+b1 aka op[4] op[0]
+    psubw   xmm4, xmm1          ;d1-c1 a1-b1 aka op[12] op[8]
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ; 13 12 11 10 03 02 01 00
+    ;
+    ; 33 32 31 30 23 22 21 20
+    ;
+    movdqa    xmm0, xmm5          ; 13 12 11 10 03 02 01 00
+    punpcklwd xmm5, xmm4          ; 23 03 22 02 21 01 20 00
+    punpckhwd xmm0, xmm4          ; 33 13 32 12 31 11 30 10
+    movdqa    xmm1, xmm5          ; 23 03 22 02 21 01 20 00
+    punpcklwd xmm5, xmm0          ; 31 21 11 01 30 20 10 00
+    punpckhwd xmm1, xmm0          ; 33 23 13 03 32 22 12 02
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    paddw   xmm5, xmm7
+    paddw   xmm1, xmm7
+
+    psraw   xmm5, 3
+    psraw   xmm1, 3
+
+    movdqa  [rdi + 0], xmm5
+    movdqa  [rdi + 16], xmm1
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+SECTION_RODATA
+align 16
+x_s1sqr2:
+    times 4 dw 0x8A8C
+align 16
+x_c1sqr2less1:
+    times 4 dw 0x4E7B
+align 16
+fours:
+    times 4 dw 0x0004
diff --git a/vp8/common/x86/loopfilter_mmx.asm b/vp8/common/x86/loopfilter_mmx.asm
new file mode 100644 (file)
index 0000000..6e4d2b6
--- /dev/null
@@ -0,0 +1,1776 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+
+;void vp8_loop_filter_horizontal_edge_mmx
+;(
+;    unsigned char *src_ptr,
+;    int src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int  count
+;)
+global sym(vp8_loop_filter_horizontal_edge_mmx)
+sym(vp8_loop_filter_horizontal_edge_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 32                         ; reserve 32 bytes
+    %define t0 [rsp + 0]    ;__declspec(align(16)) char t0[8];
+    %define t1 [rsp + 16]   ;__declspec(align(16)) char t1[8];
+
+        mov         rsi, arg(0) ;src_ptr
+        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        movsxd      rcx, dword ptr arg(5) ;count
+next8_h:
+        mov         rdx, arg(3) ;limit
+        movq        mm7, [rdx]
+        mov         rdi, rsi              ; rdi points to row +1 for indirect addressing
+        add         rdi, rax
+
+        ; calculate breakout conditions
+        movq        mm2, [rdi+2*rax]      ; q3
+        movq        mm1, [rsi+2*rax]      ; q2
+        movq        mm6, mm1              ; q2
+        psubusb     mm1, mm2              ; q2-=q3
+        psubusb     mm2, mm6              ; q3-=q2
+        por         mm1, mm2              ; abs(q3-q2)
+        psubusb     mm1, mm7              ;
+
+
+        movq        mm4, [rsi+rax]        ; q1
+        movq        mm3, mm4              ; q1
+        psubusb     mm4, mm6              ; q1-=q2
+        psubusb     mm6, mm3              ; q2-=q1
+        por         mm4, mm6              ; abs(q2-q1)
+
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+        movq        mm4, [rsi]            ; q0
+        movq        mm0, mm4              ; q0
+        psubusb     mm4, mm3              ; q0-=q1
+        psubusb     mm3, mm0              ; q1-=q0
+        por         mm4, mm3              ; abs(q0-q1)
+        movq        t0, mm4               ; save to t0
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+
+        neg         rax                   ; negate pitch to deal with above border
+
+        movq        mm2, [rsi+4*rax]      ; p3
+        movq        mm4, [rdi+4*rax]      ; p2
+        movq        mm5, mm4              ; p2
+        psubusb     mm4, mm2              ; p2-=p3
+        psubusb     mm2, mm5              ; p3-=p2
+        por         mm4, mm2              ; abs(p3 - p2)
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+
+        movq        mm4, [rsi+2*rax]      ; p1
+        movq        mm3, mm4              ; p1
+        psubusb     mm4, mm5              ; p1-=p2
+        psubusb     mm5, mm3              ; p2-=p1
+        por         mm4, mm5              ; abs(p2 - p1)
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+        movq        mm2, mm3              ; p1
+
+        movq        mm4, [rsi+rax]        ; p0
+        movq        mm5, mm4              ; p0
+        psubusb     mm4, mm3              ; p0-=p1
+        psubusb     mm3, mm5              ; p1-=p0
+        por         mm4, mm3              ; abs(p1 - p0)
+        movq        t1, mm4               ; save to t1
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+        movq        mm3, [rdi]            ; q1
+        movq        mm4, mm3              ; q1
+        psubusb     mm3, mm2              ; q1-=p1
+        psubusb     mm2, mm4              ; p1-=q1
+        por         mm2, mm3              ; abs(p1-q1)
+        pand        mm2, [tfe GLOBAL]     ; set lsb of each byte to zero
+        psrlw       mm2, 1                ; abs(p1-q1)/2
+
+        movq        mm6, mm5              ; p0
+        movq        mm3, [rsi]            ; q0
+        psubusb     mm5, mm3              ; p0-=q0
+        psubusb     mm3, mm6              ; q0-=p0
+        por         mm5, mm3              ; abs(p0 - q0)
+        paddusb     mm5, mm5              ; abs(p0-q0)*2
+        paddusb     mm5, mm2              ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        mov         rdx, arg(2) ;flimit           ; get flimit
+        movq        mm2, [rdx]            ; flimit mm2
+        paddb       mm2, mm2              ; flimit*2 (less than 255)
+        paddb       mm7, mm2              ; flimit * 2 + limit (less than 255)
+
+        psubusb     mm5,    mm7           ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         mm1,    mm5
+        pxor        mm5,    mm5
+        pcmpeqb     mm1,    mm5           ; mask mm1
+
+        ; calculate high edge variance
+        mov         rdx, arg(4) ;thresh           ; get thresh
+        movq        mm7, [rdx]            ;
+        movq        mm4, t0               ; get abs (q1 - q0)
+        psubusb     mm4, mm7
+        movq        mm3, t1               ; get abs (p1 - p0)
+        psubusb     mm3, mm7
+        paddb       mm4, mm3              ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+
+        pcmpeqb     mm4,        mm5
+
+        pcmpeqb     mm5,        mm5
+        pxor        mm4,        mm5
+
+
+        ; start work on filters
+        movq        mm2, [rsi+2*rax]      ; p1
+        movq        mm7, [rdi]            ; q1
+        pxor        mm2, [t80 GLOBAL]     ; p1 offset to convert to signed values
+        pxor        mm7, [t80 GLOBAL]     ; q1 offset to convert to signed values
+        psubsb      mm2, mm7              ; p1 - q1
+        pand        mm2, mm4              ; high var mask (hvm)(p1 - q1)
+        pxor        mm6, [t80 GLOBAL]     ; offset to convert to signed values
+        pxor        mm0, [t80 GLOBAL]     ; offset to convert to signed values
+        movq        mm3, mm0              ; q0
+        psubsb      mm0, mm6              ; q0 - p0
+        paddsb      mm2, mm0              ; 1 * (q0 - p0) + hvm(p1 - q1)
+        paddsb      mm2, mm0              ; 2 * (q0 - p0) + hvm(p1 - q1)
+        paddsb      mm2, mm0              ; 3 * (q0 - p0) + hvm(p1 - q1)
+        pand        mm1, mm2                  ; mask filter values we don't care about
+        movq        mm2, mm1
+        paddsb      mm1, [t4 GLOBAL]      ; 3* (q0 - p0) + hvm(p1 - q1) + 4
+        paddsb      mm2, [t3 GLOBAL]      ; 3* (q0 - p0) + hvm(p1 - q1) + 3
+
+        pxor        mm0, mm0             ;
+        pxor        mm5, mm5
+        punpcklbw   mm0, mm2            ;
+        punpckhbw   mm5, mm2            ;
+        psraw       mm0, 11             ;
+        psraw       mm5, 11
+        packsswb    mm0, mm5
+        movq        mm2, mm0            ;  (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
+
+        pxor        mm0, mm0              ; 0
+        movq        mm5, mm1              ; abcdefgh
+        punpcklbw   mm0, mm1              ; e0f0g0h0
+        psraw       mm0, 11               ; sign extended shift right by 3
+        pxor        mm1, mm1              ; 0
+        punpckhbw   mm1, mm5              ; a0b0c0d0
+        psraw       mm1, 11               ; sign extended shift right by 3
+        movq        mm5, mm0              ; save results
+
+        packsswb    mm0, mm1              ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
+        paddsw      mm5, [ones GLOBAL]
+        paddsw      mm1, [ones GLOBAL]
+        psraw       mm5, 1                ; partial shifted one more time for 2nd tap
+        psraw       mm1, 1                ; partial shifted one more time for 2nd tap
+        packsswb    mm5, mm1              ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
+        pandn       mm4, mm5              ; high edge variance additive
+
+        paddsb      mm6, mm2              ; p0+= p0 add
+        pxor        mm6, [t80 GLOBAL]     ; unoffset
+        movq        [rsi+rax], mm6        ; write back
+
+        movq        mm6, [rsi+2*rax]      ; p1
+        pxor        mm6, [t80 GLOBAL]     ; reoffset
+        paddsb      mm6, mm4              ; p1+= p1 add
+        pxor        mm6, [t80 GLOBAL]     ; unoffset
+        movq        [rsi+2*rax], mm6      ; write back
+
+        psubsb      mm3, mm0              ; q0-= q0 add
+        pxor        mm3, [t80 GLOBAL]     ; unoffset
+        movq        [rsi], mm3            ; write back
+
+        psubsb      mm7, mm4              ; q1-= q1 add
+        pxor        mm7, [t80 GLOBAL]     ; unoffset
+        movq        [rdi], mm7            ; write back
+
+        add         rsi,8
+        neg         rax
+        dec         rcx
+        jnz         next8_h
+
+    add rsp, 32
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_loop_filter_vertical_edge_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_loop_filter_vertical_edge_mmx)
+sym(vp8_loop_filter_vertical_edge_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub          rsp, 64      ; reserve 64 bytes
+    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[8];
+    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[8];
+    %define srct [rsp + 32]   ;__declspec(align(16)) char srct[32];
+
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rax,        dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        lea         rsi,        [rsi + rax*4 - 4]
+
+        movsxd      rcx,        dword ptr arg(5) ;count
+next8_v:
+        mov         rdi,        rsi           ; rdi points to row +1 for indirect addressing
+        add         rdi,        rax
+
+
+        ;transpose
+        movq        mm6,        [rsi+2*rax]                 ; 67 66 65 64 63 62 61 60
+        movq        mm7,        mm6                         ; 77 76 75 74 73 72 71 70
+
+        punpckhbw   mm7,        [rdi+2*rax]                 ; 77 67 76 66 75 65 74 64
+        punpcklbw   mm6,        [rdi+2*rax]                 ; 73 63 72 62 71 61 70 60
+
+        movq        mm4,        [rsi]                       ; 47 46 45 44 43 42 41 40
+        movq        mm5,        mm4                         ; 47 46 45 44 43 42 41 40
+
+        punpckhbw   mm5,        [rsi+rax]                   ; 57 47 56 46 55 45 54 44
+        punpcklbw   mm4,        [rsi+rax]                   ; 53 43 52 42 51 41 50 40
+
+        movq        mm3,        mm5                         ; 57 47 56 46 55 45 54 44
+        punpckhwd   mm5,        mm7                         ; 77 67 57 47 76 66 56 46
+
+        punpcklwd   mm3,        mm7                         ; 75 65 55 45 74 64 54 44
+        movq        mm2,        mm4                         ; 53 43 52 42 51 41 50 40
+
+        punpckhwd   mm4,        mm6                         ; 73 63 53 43 72 62 52 42
+        punpcklwd   mm2,        mm6                         ; 71 61 51 41 70 60 50 40
+
+        neg         rax
+        movq        mm6,        [rsi+rax*2]                 ; 27 26 25 24 23 22 21 20
+
+        movq        mm1,        mm6                         ; 27 26 25 24 23 22 21 20
+        punpckhbw   mm6,        [rsi+rax]                   ; 37 27 36 36 35 25 34 24
+
+        punpcklbw   mm1,        [rsi+rax]                   ; 33 23 32 22 31 21 30 20
+        movq        mm7,        [rsi+rax*4];                ; 07 06 05 04 03 02 01 00
+
+        punpckhbw   mm7,        [rdi+rax*4]                 ; 17 07 16 06 15 05 14 04
+        movq        mm0,        mm7                         ; 17 07 16 06 15 05 14 04
+
+        punpckhwd   mm7,        mm6                         ; 37 27 17 07 36 26 16 06
+        punpcklwd   mm0,        mm6                         ; 35 25 15 05 34 24 14 04
+
+        movq        mm6,        mm7                         ; 37 27 17 07 36 26 16 06
+        punpckhdq   mm7,        mm5                         ; 77 67 57 47 37 27 17 07  = q3
+
+        punpckldq   mm6,        mm5                         ; 76 66 56 46 36 26 16 06  = q2
+
+        movq        mm5,        mm6                         ; 76 66 56 46 36 26 16 06
+        psubusb     mm5,        mm7                         ; q2-q3
+
+        psubusb     mm7,        mm6                         ; q3-q2
+        por         mm7,        mm5;                        ; mm7=abs (q3-q2)
+
+        movq        mm5,        mm0                         ; 35 25 15 05 34 24 14 04
+        punpckhdq   mm5,        mm3                         ; 75 65 55 45 35 25 15 05 = q1
+
+        punpckldq   mm0,        mm3                         ; 74 64 54 44 34 24 15 04 = q0
+        movq        mm3,        mm5                         ; 75 65 55 45 35 25 15 05 = q1
+
+        psubusb     mm3,        mm6                         ; q1-q2
+        psubusb     mm6,        mm5                         ; q2-q1
+
+        por         mm6,        mm3                         ; mm6=abs(q2-q1)
+        lea         rdx,        srct
+
+        movq        [rdx+24],   mm5                         ; save q1
+        movq        [rdx+16],   mm0                         ; save q0
+
+        movq        mm3,        [rsi+rax*4]                 ; 07 06 05 04 03 02 01 00
+        punpcklbw   mm3,        [rdi+rax*4]                 ; 13 03 12 02 11 01 10 00
+
+        movq        mm0,        mm3                         ; 13 03 12 02 11 01 10 00
+        punpcklwd   mm0,        mm1                         ; 31 21 11 01 30 20 10 00
+
+        punpckhwd   mm3,        mm1                         ; 33 23 13 03 32 22 12 02
+        movq        mm1,        mm0                         ; 31 21 11 01 30 20 10 00
+
+        punpckldq   mm0,        mm2                         ; 70 60 50 40 30 20 10 00  =p3
+        punpckhdq   mm1,        mm2                         ; 71 61 51 41 31 21 11 01  =p2
+
+        movq        mm2,        mm1                         ; 71 61 51 41 31 21 11 01  =p2
+        psubusb     mm2,        mm0                         ; p2-p3
+
+        psubusb     mm0,        mm1                         ; p3-p2
+        por         mm0,        mm2                         ; mm0=abs(p3-p2)
+
+        movq        mm2,        mm3                         ; 33 23 13 03 32 22 12 02
+        punpckldq   mm2,        mm4                         ; 72 62 52 42 32 22 12 02 = p1
+
+        punpckhdq   mm3,        mm4                         ; 73 63 53 43 33 23 13 03 = p0
+        movq        [rdx+8],    mm3                         ; save p0
+
+        movq        [rdx],      mm2                         ; save p1
+        movq        mm5,        mm2                         ; mm5 = p1
+
+        psubusb     mm2,        mm1                         ; p1-p2
+        psubusb     mm1,        mm5                         ; p2-p1
+
+        por         mm1,        mm2                         ; mm1=abs(p2-p1)
+        mov         rdx,        arg(3) ;limit
+
+        movq        mm4,        [rdx]                       ; mm4 = limit
+        psubusb     mm7,        mm4
+
+        psubusb     mm0,        mm4
+        psubusb     mm1,        mm4
+
+        psubusb     mm6,        mm4
+        por         mm7,        mm6
+
+        por         mm0,        mm1
+        por         mm0,        mm7                         ;   abs(q3-q2) > limit || abs(p3-p2) > limit ||abs(p2-p1) > limit || abs(q2-q1) > limit
+
+        movq        mm1,        mm5                         ; p1
+
+        movq        mm7,        mm3                         ; mm3=mm7=p0
+        psubusb     mm7,        mm5                         ; p0 - p1
+
+        psubusb     mm5,        mm3                         ; p1 - p0
+        por         mm5,        mm7                         ; abs(p1-p0)
+
+        movq        t0,         mm5                         ; save abs(p1-p0)
+        lea         rdx,        srct
+
+        psubusb     mm5,        mm4
+        por         mm0,        mm5                         ; mm0=mask
+
+        movq        mm5,        [rdx+16]                    ; mm5=q0
+        movq        mm7,        [rdx+24]                    ; mm7=q1
+
+        movq        mm6,        mm5                         ; mm6=q0
+        movq        mm2,        mm7                         ; q1
+        psubusb     mm5,        mm7                         ; q0-q1
+
+        psubusb     mm7,        mm6                         ; q1-q0
+        por         mm7,        mm5                         ; abs(q1-q0)
+
+        movq        t1,         mm7                         ; save abs(q1-q0)
+        psubusb     mm7,        mm4
+
+        por         mm0,        mm7                         ; mask
+
+        movq        mm5,        mm2                         ; q1
+        psubusb     mm5,        mm1                         ; q1-=p1
+        psubusb     mm1,        mm2                         ; p1-=q1
+        por         mm5,        mm1                         ; abs(p1-q1)
+        pand        mm5,        [tfe GLOBAL]                ; set lsb of each byte to zero
+        psrlw       mm5,        1                           ; abs(p1-q1)/2
+
+        mov         rdx,        arg(2) ;flimit                      ;
+
+        movq        mm2,        [rdx]                       ;flimit  mm2
+        movq        mm1,        mm3                         ; mm1=mm3=p0
+
+        movq        mm7,        mm6                         ; mm7=mm6=q0
+        psubusb     mm1,        mm7                         ; p0-q0
+
+        psubusb     mm7,        mm3                         ; q0-p0
+        por         mm1,        mm7                         ; abs(q0-p0)
+        paddusb     mm1,        mm1                         ; abs(q0-p0)*2
+        paddusb     mm1,        mm5                         ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        paddb       mm2,        mm2                         ; flimit*2 (less than 255)
+        paddb       mm4,        mm2                         ; flimit * 2 + limit (less than 255)
+
+        psubusb     mm1,        mm4                         ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         mm1,        mm0;                        ; mask
+
+        pxor        mm0,        mm0
+        pcmpeqb     mm1,        mm0
+
+        ; calculate high edge variance
+        mov         rdx,        arg(4) ;thresh            ; get thresh
+        movq        mm7,        [rdx]
+        ;
+        movq        mm4,        t0              ; get abs (q1 - q0)
+        psubusb     mm4,        mm7
+
+        movq        mm3,        t1              ; get abs (p1 - p0)
+        psubusb     mm3,        mm7
+
+        por         mm4,        mm3             ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+        pcmpeqb     mm4,        mm0
+
+        pcmpeqb     mm0,        mm0
+        pxor        mm4,        mm0
+
+
+
+        ; start work on filters
+        lea         rdx,        srct
+
+        movq        mm2,        [rdx]           ; p1
+        movq        mm7,        [rdx+24]        ; q1
+
+        movq        mm6,        [rdx+8]         ; p0
+        movq        mm0,        [rdx+16]        ; q0
+
+        pxor        mm2,        [t80 GLOBAL]    ; p1 offset to convert to signed values
+        pxor        mm7,        [t80 GLOBAL]    ; q1 offset to convert to signed values
+
+        psubsb      mm2,        mm7             ; p1 - q1
+        pand        mm2,        mm4             ; high var mask (hvm)(p1 - q1)
+
+        pxor        mm6,        [t80 GLOBAL]    ; offset to convert to signed values
+        pxor        mm0,        [t80 GLOBAL]    ; offset to convert to signed values
+
+        movq        mm3,        mm0             ; q0
+        psubsb      mm0,        mm6             ; q0 - p0
+
+        paddsb      mm2,        mm0             ; 1 * (q0 - p0) + hvm(p1 - q1)
+        paddsb      mm2,        mm0             ; 2 * (q0 - p0) + hvm(p1 - q1)
+
+        paddsb      mm2,        mm0             ; 3 * (q0 - p0) + hvm(p1 - q1)
+        pand       mm1,        mm2              ; mask filter values we don't care about
+
+        movq        mm2,        mm1
+        paddsb      mm1,        [t4 GLOBAL]       ; 3* (q0 - p0) + hvm(p1 - q1) + 4
+
+        paddsb      mm2,        [t3 GLOBAL]       ; 3* (q0 - p0) + hvm(p1 - q1) + 3
+        pxor        mm0,        mm0          ;
+
+        pxor        mm5,        mm5
+        punpcklbw   mm0,        mm2         ;
+
+        punpckhbw   mm5,        mm2         ;
+        psraw       mm0,        11              ;
+
+        psraw       mm5,        11
+        packsswb    mm0,        mm5
+
+        movq        mm2,        mm0         ;  (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
+
+        pxor        mm0,        mm0           ; 0
+        movq        mm5,        mm1           ; abcdefgh
+
+        punpcklbw   mm0,        mm1           ; e0f0g0h0
+        psraw       mm0,        11                ; sign extended shift right by 3
+
+        pxor        mm1,        mm1           ; 0
+        punpckhbw   mm1,        mm5           ; a0b0c0d0
+
+        psraw       mm1,        11                ; sign extended shift right by 3
+        movq        mm5,        mm0              ; save results
+
+        packsswb    mm0,        mm1           ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
+        paddsw      mm5,        [ones GLOBAL]
+
+        paddsw      mm1,        [ones GLOBAL]
+        psraw       mm5,        1                 ; partial shifted one more time for 2nd tap
+
+        psraw       mm1,        1                 ; partial shifted one more time for 2nd tap
+        packsswb    mm5,        mm1           ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
+
+        pandn       mm4,        mm5             ; high edge variance additive
+
+        paddsb      mm6,        mm2             ; p0+= p0 add
+        pxor        mm6,        [t80 GLOBAL]    ; unoffset
+
+        ; mm6=p0                               ;
+        movq        mm1,        [rdx]           ; p1
+        pxor        mm1,        [t80 GLOBAL]    ; reoffset
+
+        paddsb      mm1,        mm4                 ; p1+= p1 add
+        pxor        mm1,        [t80 GLOBAL]        ; unoffset
+        ; mm6 = p0 mm1 = p1
+
+        psubsb      mm3,        mm0                 ; q0-= q0 add
+        pxor        mm3,        [t80 GLOBAL]        ; unoffset
+
+        ; mm3 = q0
+        psubsb      mm7,        mm4                 ; q1-= q1 add
+        pxor        mm7,        [t80 GLOBAL]        ; unoffset
+        ; mm7 = q1
+
+        ; tranpose and write back
+        ; mm1 =    72 62 52 42 32 22 12 02
+        ; mm6 =    73 63 53 43 33 23 13 03
+        ; mm3 =    74 64 54 44 34 24 14 04
+        ; mm7 =    75 65 55 45 35 25 15 05
+
+        movq        mm2,        mm1             ; 72 62 52 42 32 22 12 02
+        punpcklbw   mm2,        mm6             ; 33 32 23 22 13 12 03 02
+
+        movq        mm4,        mm3             ; 74 64 54 44 34 24 14 04
+        punpckhbw   mm1,        mm6             ; 73 72 63 62 53 52 43 42
+
+        punpcklbw   mm4,        mm7             ; 35 34 25 24 15 14 05 04
+        punpckhbw   mm3,        mm7             ; 75 74 65 64 55 54 45 44
+
+        movq        mm6,        mm2             ; 33 32 23 22 13 12 03 02
+        punpcklwd   mm2,        mm4             ; 15 14 13 12 05 04 03 02
+
+        punpckhwd   mm6,        mm4             ; 35 34 33 32 25 24 23 22
+        movq        mm5,        mm1             ; 73 72 63 62 53 52 43 42
+
+        punpcklwd   mm1,        mm3             ; 55 54 53 52 45 44 43 42
+        punpckhwd   mm5,        mm3             ; 75 74 73 72 65 64 63 62
+
+
+        ; mm2 = 15 14 13 12 05 04 03 02
+        ; mm6 = 35 34 33 32 25 24 23 22
+        ; mm5 = 55 54 53 52 45 44 43 42
+        ; mm1 = 75 74 73 72 65 64 63 62
+
+
+
+        movd        [rsi+rax*4+2], mm2
+        psrlq       mm2,        32
+
+        movd        [rdi+rax*4+2], mm2
+        movd        [rsi+rax*2+2], mm6
+
+        psrlq       mm6,        32
+        movd        [rsi+rax+2],mm6
+
+        movd        [rsi+2],    mm1
+        psrlq       mm1,        32
+
+        movd        [rdi+2],    mm1
+        neg         rax
+
+        movd        [rdi+rax+2],mm5
+        psrlq       mm5,        32
+
+        movd        [rdi+rax*2+2], mm5
+
+        lea         rsi,        [rsi+rax*8]
+        dec         rcx
+        jnz         next8_v
+
+    add rsp, 64
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_mbloop_filter_horizontal_edge_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_mbloop_filter_horizontal_edge_mmx)
+sym(vp8_mbloop_filter_horizontal_edge_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub          rsp, 32      ; reserve 32 bytes
+    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[8];
+    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[8];
+
+        mov         rsi, arg(0) ;src_ptr
+        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        movsxd      rcx, dword ptr arg(5) ;count
+next8_mbh:
+        mov         rdx, arg(3) ;limit
+        movq        mm7, [rdx]
+        mov         rdi, rsi              ; rdi points to row +1 for indirect addressing
+        add         rdi, rax
+
+        ; calculate breakout conditions
+        movq        mm2, [rdi+2*rax]      ; q3
+
+        movq        mm1, [rsi+2*rax]      ; q2
+        movq        mm6, mm1              ; q2
+        psubusb     mm1, mm2              ; q2-=q3
+        psubusb     mm2, mm6              ; q3-=q2
+        por         mm1, mm2              ; abs(q3-q2)
+        psubusb     mm1, mm7
+
+
+        ; mm1 = abs(q3-q2), mm6 =q2, mm7 = limit
+        movq        mm4, [rsi+rax]        ; q1
+        movq        mm3, mm4              ; q1
+        psubusb     mm4, mm6              ; q1-=q2
+        psubusb     mm6, mm3              ; q2-=q1
+        por         mm4, mm6              ; abs(q2-q1)
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+
+        ; mm1 = mask,      mm3=q1, mm7 = limit
+
+        movq        mm4, [rsi]            ; q0
+        movq        mm0, mm4              ; q0
+        psubusb     mm4, mm3              ; q0-=q1
+        psubusb     mm3, mm0              ; q1-=q0
+        por         mm4, mm3              ; abs(q0-q1)
+        movq        t0, mm4               ; save to t0
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1)
+
+        neg         rax                   ; negate pitch to deal with above border
+
+        movq        mm2, [rsi+4*rax]      ; p3
+        movq        mm4, [rdi+4*rax]      ; p2
+        movq        mm5, mm4              ; p2
+        psubusb     mm4, mm2              ; p2-=p3
+        psubusb     mm2, mm5              ; p3-=p2
+        por         mm4, mm2              ; abs(p3 - p2)
+        psubusb     mm4, mm7
+        por        mm1, mm4
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1)
+
+        movq        mm4, [rsi+2*rax]      ; p1
+        movq        mm3, mm4              ; p1
+        psubusb     mm4, mm5              ; p1-=p2
+        psubusb     mm5, mm3              ; p2-=p1
+        por         mm4, mm5              ; abs(p2 - p1)
+        psubusb     mm4, mm7
+        por        mm1, mm4
+
+        movq        mm2, mm3              ; p1
+
+
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1)
+
+        movq        mm4, [rsi+rax]        ; p0
+        movq        mm5, mm4              ; p0
+        psubusb     mm4, mm3              ; p0-=p1
+        psubusb     mm3, mm5              ; p1-=p0
+        por         mm4, mm3              ; abs(p1 - p0)
+        movq        t1, mm4               ; save to t1
+        psubusb     mm4, mm7
+        por        mm1, mm4
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1) t1 = abs(p1-p0)
+        ; mm5 = p0
+        movq        mm3, [rdi]            ; q1
+        movq        mm4, mm3              ; q1
+        psubusb     mm3, mm2              ; q1-=p1
+        psubusb     mm2, mm4              ; p1-=q1
+        por         mm2, mm3              ; abs(p1-q1)
+        pand        mm2, [tfe GLOBAL]     ; set lsb of each byte to zero
+        psrlw       mm2, 1                ; abs(p1-q1)/2
+
+        movq        mm6, mm5              ; p0
+        movq        mm3, mm0              ; q0
+        psubusb     mm5, mm3              ; p0-=q0
+        psubusb     mm3, mm6              ; q0-=p0
+        por         mm5, mm3              ; abs(p0 - q0)
+        paddusb     mm5, mm5              ; abs(p0-q0)*2
+        paddusb     mm5, mm2              ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        mov         rdx, arg(2) ;flimit           ; get flimit
+        movq        mm2, [rdx]            ; flimit mm2
+        paddb       mm2, mm2              ; flimit*2 (less than 255)
+        paddb       mm7, mm2              ; flimit * 2 + limit (less than 255)
+
+        psubusb     mm5,    mm7           ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         mm1,    mm5
+        pxor        mm5,    mm5
+        pcmpeqb     mm1,    mm5           ; mask mm1
+
+        ; mm1 = mask, mm0=q0,  mm7 = flimit, t0 = abs(q0-q1) t1 = abs(p1-p0)
+        ; mm6 = p0,
+
+        ; calculate high edge variance
+        mov         rdx, arg(4) ;thresh           ; get thresh
+        movq        mm7, [rdx]            ;
+        movq        mm4, t0               ; get abs (q1 - q0)
+        psubusb     mm4, mm7
+        movq        mm3, t1               ; get abs (p1 - p0)
+        psubusb     mm3, mm7
+        paddb       mm4, mm3              ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+
+        pcmpeqb     mm4,        mm5
+
+        pcmpeqb     mm5,        mm5
+        pxor        mm4,        mm5
+
+
+
+        ; mm1 = mask, mm0=q0,  mm7 = thresh, t0 = abs(q0-q1) t1 = abs(p1-p0)
+        ; mm6 = p0, mm4=hev
+        ; start work on filters
+        movq        mm2, [rsi+2*rax]      ; p1
+        movq        mm7, [rdi]            ; q1
+        pxor        mm2, [t80 GLOBAL]     ; p1 offset to convert to signed values
+        pxor        mm7, [t80 GLOBAL]     ; q1 offset to convert to signed values
+        psubsb      mm2, mm7              ; p1 - q1
+
+        pxor        mm6, [t80 GLOBAL]     ; offset to convert to signed values
+        pxor        mm0, [t80 GLOBAL]     ; offset to convert to signed values
+        movq        mm3, mm0              ; q0
+        psubsb      mm0, mm6              ; q0 - p0
+        paddsb      mm2, mm0              ; 1 * (q0 - p0) + (p1 - q1)
+        paddsb      mm2, mm0              ; 2 * (q0 - p0)
+        paddsb      mm2, mm0              ; 3 * (q0 - p0) + (p1 - q1)
+        pand        mm1, mm2              ; mask filter values we don't care about
+
+
+        ; mm1 = vp8_filter, mm4=hev, mm6=ps0, mm3=qs0
+        movq        mm2, mm1              ; vp8_filter
+        pand        mm2, mm4;             ; Filter2 = vp8_filter & hev
+
+        movq        mm5,        mm2       ;
+        paddsb      mm5,        [t3 GLOBAL];
+
+        pxor        mm0, mm0              ; 0
+        pxor        mm7, mm7              ; 0
+
+        punpcklbw   mm0, mm5              ; e0f0g0h0
+        psraw       mm0, 11               ; sign extended shift right by 3
+        punpckhbw   mm7, mm5              ; a0b0c0d0
+        psraw       mm7, 11               ; sign extended shift right by 3
+        packsswb    mm0, mm7              ; Filter2 >>=3;
+
+        movq        mm5, mm0              ; Filter2
+
+        paddsb      mm2, [t4 GLOBAL]      ; vp8_signed_char_clamp(Filter2 + 4)
+        pxor        mm0, mm0              ; 0
+        pxor        mm7, mm7              ; 0
+
+        punpcklbw   mm0, mm2              ; e0f0g0h0
+        psraw       mm0, 11               ; sign extended shift right by 3
+        punpckhbw   mm7, mm2              ; a0b0c0d0
+        psraw       mm7, 11               ; sign extended shift right by 3
+        packsswb    mm0, mm7              ; Filter2 >>=3;
+
+        ; mm0= filter2 mm1 = vp8_filter,  mm3 =qs0 mm5=s mm4 =hev mm6=ps0
+        psubsb      mm3, mm0              ; qs0 =qs0 - filter1
+        paddsb      mm6, mm5              ; ps0 =ps0 + Fitler2
+
+        ; mm1=vp8_filter, mm3=qs0, mm4 =hev mm6=ps0
+        ; vp8_filter &= ~hev;
+        ; Filter2 = vp8_filter;
+        pandn       mm4, mm1              ; vp8_filter&=~hev
+
+
+        ; mm3=qs0, mm4=filter2, mm6=ps0
+
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7);
+        ; s = vp8_signed_char_clamp(qs0 - u);
+        ; *oq0 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps0 + u);
+        ; *op0 = s^0x80;
+        pxor        mm0, mm0
+
+        pxor        mm1, mm1
+        pxor        mm2, mm2
+        punpcklbw   mm1, mm4
+        punpckhbw   mm2, mm4
+        pmulhw      mm1, [s27 GLOBAL]
+        pmulhw      mm2, [s27 GLOBAL]
+        paddw       mm1, [s63 GLOBAL]
+        paddw       mm2, [s63 GLOBAL]
+        psraw       mm1, 7
+        psraw       mm2, 7
+        packsswb    mm1, mm2
+
+        psubsb      mm3, mm1
+        paddsb      mm6, mm1
+
+        pxor        mm3, [t80 GLOBAL]
+        pxor        mm6, [t80 GLOBAL]
+        movq        [rsi+rax], mm6
+        movq        [rsi],     mm3
+
+        ; roughly 2/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7);
+        ; s = vp8_signed_char_clamp(qs1 - u);
+        ; *oq1 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps1 + u);
+        ; *op1 = s^0x80;
+        pxor        mm1, mm1
+        pxor        mm2, mm2
+        punpcklbw   mm1, mm4
+        punpckhbw   mm2, mm4
+        pmulhw      mm1, [s18 GLOBAL]
+        pmulhw      mm2, [s18 GLOBAL]
+        paddw       mm1, [s63 GLOBAL]
+        paddw       mm2, [s63 GLOBAL]
+        psraw       mm1, 7
+        psraw       mm2, 7
+        packsswb    mm1, mm2
+
+        movq        mm3, [rdi]
+        movq        mm6, [rsi+rax*2]       ; p1
+
+        pxor        mm3, [t80 GLOBAL]
+        pxor        mm6, [t80 GLOBAL]
+
+        paddsb      mm6, mm1
+        psubsb      mm3, mm1
+
+        pxor        mm6, [t80 GLOBAL]
+        pxor        mm3, [t80 GLOBAL]
+        movq        [rdi], mm3
+        movq        [rsi+rax*2], mm6
+
+        ; roughly 1/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7);
+        ; s = vp8_signed_char_clamp(qs2 - u);
+        ; *oq2 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps2 + u);
+        ; *op2 = s^0x80;
+        pxor        mm1, mm1
+        pxor        mm2, mm2
+        punpcklbw   mm1, mm4
+        punpckhbw   mm2, mm4
+        pmulhw      mm1, [s9 GLOBAL]
+        pmulhw      mm2, [s9 GLOBAL]
+        paddw       mm1, [s63 GLOBAL]
+        paddw       mm2, [s63 GLOBAL]
+        psraw       mm1, 7
+        psraw       mm2, 7
+        packsswb    mm1, mm2
+
+
+        movq        mm6, [rdi+rax*4]
+        neg         rax
+        movq        mm3, [rdi+rax  ]
+
+        pxor        mm6, [t80 GLOBAL]
+        pxor        mm3, [t80 GLOBAL]
+
+        paddsb      mm6, mm1
+        psubsb      mm3, mm1
+
+        pxor        mm6, [t80 GLOBAL]
+        pxor        mm3, [t80 GLOBAL]
+        movq        [rdi+rax  ], mm3
+        neg         rax
+        movq        [rdi+rax*4], mm6
+
+;EARLY_BREAK_OUT:
+        neg         rax
+        add         rsi,8
+        dec         rcx
+        jnz         next8_mbh
+
+    add rsp, 32
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_mbloop_filter_vertical_edge_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_mbloop_filter_vertical_edge_mmx)
+sym(vp8_mbloop_filter_vertical_edge_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub          rsp, 96      ; reserve 96 bytes
+    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[8];
+    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[8];
+    %define srct [rsp + 32]   ;__declspec(align(16)) char srct[64];
+
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rax,        dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        lea         rsi,        [rsi + rax*4 - 4]
+
+        movsxd      rcx,        dword ptr arg(5) ;count
+next8_mbv:
+        lea         rdi,        [rsi + rax]  ; rdi points to row +1 for indirect addressing
+
+        ;transpose
+        movq        mm0,        [rdi+2*rax]                 ; 77 76 75 74 73 72 71 70
+        movq        mm6,        [rsi+2*rax]                 ; 67 66 65 64 63 62 61 60
+
+        movq        mm7,        mm6                         ; 77 76 75 74 73 72 71 70
+        punpckhbw   mm7,        mm0                         ; 77 67 76 66 75 65 74 64
+
+        punpcklbw   mm6,        mm0                         ; 73 63 72 62 71 61 70 60
+        movq        mm0,        [rsi+rax]                   ; 57 56 55 54 53 52 51 50
+
+        movq        mm4,        [rsi]                       ; 47 46 45 44 43 42 41 40
+        movq        mm5,        mm4                         ; 47 46 45 44 43 42 41 40
+
+        punpckhbw   mm5,        mm0                         ; 57 47 56 46 55 45 54 44
+        punpcklbw   mm4,        mm0                         ; 53 43 52 42 51 41 50 40
+
+        movq        mm3,        mm5                         ; 57 47 56 46 55 45 54 44
+        punpckhwd   mm5,        mm7                         ; 77 67 57 47 76 66 56 46
+
+        punpcklwd   mm3,        mm7                         ; 75 65 55 45 74 64 54 44
+        movq        mm2,        mm4                         ; 53 43 52 42 51 41 50 40
+
+        punpckhwd   mm4,        mm6                         ; 73 63 53 43 72 62 52 42
+        punpcklwd   mm2,        mm6                         ; 71 61 51 41 70 60 50 40
+
+        neg         rax
+
+        movq        mm7,        [rsi+rax]                   ; 37 36 35 34 33 32 31 30
+        movq        mm6,        [rsi+rax*2]                 ; 27 26 25 24 23 22 21 20
+
+        movq        mm1,        mm6                         ; 27 26 25 24 23 22 21 20
+        punpckhbw   mm6,        mm7                         ; 37 27 36 36 35 25 34 24
+
+        punpcklbw   mm1,        mm7                         ; 33 23 32 22 31 21 30 20
+
+        movq        mm7,        [rsi+rax*4];                ; 07 06 05 04 03 02 01 00
+        punpckhbw   mm7,        [rdi+rax*4]                 ; 17 07 16 06 15 05 14 04
+
+        movq        mm0,        mm7                         ; 17 07 16 06 15 05 14 04
+        punpckhwd   mm7,        mm6                         ; 37 27 17 07 36 26 16 06
+
+        punpcklwd   mm0,        mm6                         ; 35 25 15 05 34 24 14 04
+        movq        mm6,        mm7                         ; 37 27 17 07 36 26 16 06
+
+        punpckhdq   mm7,        mm5                         ; 77 67 57 47 37 27 17 07  = q3
+        punpckldq   mm6,        mm5                         ; 76 66 56 46 36 26 16 06  = q2
+
+        lea         rdx,        srct
+        movq        mm5,        mm6                         ; 76 66 56 46 36 26 16 06
+
+        movq        [rdx+56],   mm7
+        psubusb     mm5,        mm7                         ; q2-q3
+
+
+        movq        [rdx+48],   mm6
+        psubusb     mm7,        mm6                         ; q3-q2
+
+        por         mm7,        mm5;                        ; mm7=abs (q3-q2)
+        movq        mm5,        mm0                         ; 35 25 15 05 34 24 14 04
+
+        punpckhdq   mm5,        mm3                         ; 75 65 55 45 35 25 15 05 = q1
+        punpckldq   mm0,        mm3                         ; 74 64 54 44 34 24 15 04 = q0
+
+        movq        mm3,        mm5                         ; 75 65 55 45 35 25 15 05 = q1
+        psubusb     mm3,        mm6                         ; q1-q2
+
+        psubusb     mm6,        mm5                         ; q2-q1
+        por         mm6,        mm3                         ; mm6=abs(q2-q1)
+
+        movq        [rdx+40],   mm5                         ; save q1
+        movq        [rdx+32],   mm0                         ; save q0
+
+        movq        mm3,        [rsi+rax*4]                 ; 07 06 05 04 03 02 01 00
+        punpcklbw   mm3,        [rdi+rax*4]                 ; 13 03 12 02 11 01 10 00
+
+        movq        mm0,        mm3                         ; 13 03 12 02 11 01 10 00
+        punpcklwd   mm0,        mm1                         ; 31 21 11 01 30 20 10 00
+
+        punpckhwd   mm3,        mm1                         ; 33 23 13 03 32 22 12 02
+        movq        mm1,        mm0                         ; 31 21 11 01 30 20 10 00
+
+        punpckldq   mm0,        mm2                         ; 70 60 50 40 30 20 10 00  =p3
+        punpckhdq   mm1,        mm2                         ; 71 61 51 41 31 21 11 01  =p2
+
+        movq        [rdx],      mm0                         ; save p3
+        movq        [rdx+8],    mm1                         ; save p2
+
+        movq        mm2,        mm1                         ; 71 61 51 41 31 21 11 01  =p2
+        psubusb     mm2,        mm0                         ; p2-p3
+
+        psubusb     mm0,        mm1                         ; p3-p2
+        por         mm0,        mm2                         ; mm0=abs(p3-p2)
+
+        movq        mm2,        mm3                         ; 33 23 13 03 32 22 12 02
+        punpckldq   mm2,        mm4                         ; 72 62 52 42 32 22 12 02 = p1
+
+        punpckhdq   mm3,        mm4                         ; 73 63 53 43 33 23 13 03 = p0
+        movq        [rdx+24],   mm3                         ; save p0
+
+        movq        [rdx+16],   mm2                         ; save p1
+        movq        mm5,        mm2                         ; mm5 = p1
+
+        psubusb     mm2,        mm1                         ; p1-p2
+        psubusb     mm1,        mm5                         ; p2-p1
+
+        por         mm1,        mm2                         ; mm1=abs(p2-p1)
+        mov         rdx,        arg(3) ;limit
+
+        movq        mm4,        [rdx]                       ; mm4 = limit
+        psubusb     mm7,        mm4                         ; abs(q3-q2) > limit
+
+        psubusb     mm0,        mm4                         ; abs(p3-p2) > limit
+        psubusb     mm1,        mm4                         ; abs(p2-p1) > limit
+
+        psubusb     mm6,        mm4                         ; abs(q2-q1) > limit
+        por         mm7,        mm6                         ; or
+
+        por         mm0,        mm1                         ;
+        por         mm0,        mm7                         ; abs(q3-q2) > limit || abs(p3-p2) > limit ||abs(p2-p1) > limit || abs(q2-q1) > limit
+
+        movq        mm1,        mm5                         ; p1
+
+        movq        mm7,        mm3                         ; mm3=mm7=p0
+        psubusb     mm7,        mm5                         ; p0 - p1
+
+        psubusb     mm5,        mm3                         ; p1 - p0
+        por         mm5,        mm7                         ; abs(p1-p0)
+
+        movq        t0,         mm5                         ; save abs(p1-p0)
+        lea         rdx,        srct
+
+        psubusb     mm5,        mm4                         ; mm5 = abs(p1-p0) > limit
+        por         mm0,        mm5                         ; mm0=mask
+
+        movq        mm5,        [rdx+32]                    ; mm5=q0
+        movq        mm7,        [rdx+40]                    ; mm7=q1
+
+        movq        mm6,        mm5                         ; mm6=q0
+        movq        mm2,        mm7                         ; q1
+        psubusb     mm5,        mm7                         ; q0-q1
+
+        psubusb     mm7,        mm6                         ; q1-q0
+        por         mm7,        mm5                         ; abs(q1-q0)
+
+        movq        t1,         mm7                         ; save abs(q1-q0)
+        psubusb     mm7,        mm4                         ; mm7=abs(q1-q0)> limit
+
+        por         mm0,        mm7                         ; mask
+
+        movq        mm5,        mm2                         ; q1
+        psubusb     mm5,        mm1                         ; q1-=p1
+        psubusb     mm1,        mm2                         ; p1-=q1
+        por         mm5,        mm1                         ; abs(p1-q1)
+        pand        mm5,        [tfe GLOBAL]                ; set lsb of each byte to zero
+        psrlw       mm5,        1                           ; abs(p1-q1)/2
+
+        mov         rdx,        arg(2) ;flimit                      ;
+
+        movq        mm2,        [rdx]                       ;flimit  mm2
+        movq        mm1,        mm3                         ; mm1=mm3=p0
+
+        movq        mm7,        mm6                         ; mm7=mm6=q0
+        psubusb     mm1,        mm7                         ; p0-q0
+
+        psubusb     mm7,        mm3                         ; q0-p0
+        por         mm1,        mm7                         ; abs(q0-p0)
+        paddusb     mm1,        mm1                         ; abs(q0-p0)*2
+        paddusb     mm1,        mm5                         ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        paddb       mm2,        mm2                         ; flimit*2 (less than 255)
+        paddb       mm4,        mm2                         ; flimit * 2 + limit (less than 255)
+
+        psubusb     mm1,        mm4                         ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         mm1,        mm0;                        ; mask
+
+        pxor        mm0,        mm0
+        pcmpeqb     mm1,        mm0
+
+        ; calculate high edge variance
+        mov         rdx,        arg(4) ;thresh            ; get thresh
+        movq        mm7,        [rdx]
+        ;
+        movq        mm4,        t0              ; get abs (q1 - q0)
+        psubusb     mm4,        mm7             ; abs(q1 - q0) > thresh
+
+        movq        mm3,        t1              ; get abs (p1 - p0)
+        psubusb     mm3,        mm7             ; abs(p1 - p0)> thresh
+
+        por         mm4,        mm3             ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+        pcmpeqb     mm4,        mm0
+
+        pcmpeqb     mm0,        mm0
+        pxor        mm4,        mm0
+
+
+
+
+        ; start work on filters
+        lea         rdx,        srct
+
+        ; start work on filters
+        movq        mm2, [rdx+16]         ; p1
+        movq        mm7, [rdx+40]         ; q1
+        pxor        mm2, [t80 GLOBAL]     ; p1 offset to convert to signed values
+        pxor        mm7, [t80 GLOBAL]     ; q1 offset to convert to signed values
+        psubsb      mm2, mm7              ; p1 - q1
+
+        movq        mm6, [rdx+24]         ; p0
+        movq        mm0, [rdx+32]         ; q0
+        pxor        mm6, [t80 GLOBAL]     ; offset to convert to signed values
+        pxor        mm0, [t80 GLOBAL]     ; offset to convert to signed values
+
+        movq        mm3, mm0              ; q0
+        psubsb      mm0, mm6              ; q0 - p0
+        paddsb      mm2, mm0              ; 1 * (q0 - p0) + (p1 - q1)
+        paddsb      mm2, mm0              ; 2 * (q0 - p0)
+        paddsb      mm2, mm0              ; 3 * (q0 - p0) + (p1 - q1)
+        pand       mm1, mm2           ; mask filter values we don't care about
+
+        ; mm1 = vp8_filter, mm4=hev, mm6=ps0, mm3=qs0
+        movq        mm2, mm1              ; vp8_filter
+        pand        mm2, mm4;             ; Filter2 = vp8_filter & hev
+
+        movq        mm5,        mm2       ;
+        paddsb      mm5,        [t3 GLOBAL];
+
+        pxor        mm0, mm0              ; 0
+        pxor        mm7, mm7              ; 0
+
+        punpcklbw   mm0, mm5              ; e0f0g0h0
+        psraw       mm0, 11               ; sign extended shift right by 3
+        punpckhbw   mm7, mm5              ; a0b0c0d0
+        psraw       mm7, 11               ; sign extended shift right by 3
+        packsswb    mm0, mm7              ; Filter2 >>=3;
+
+        movq        mm5, mm0              ; Filter2
+
+        paddsb      mm2, [t4 GLOBAL]      ; vp8_signed_char_clamp(Filter2 + 4)
+        pxor        mm0, mm0              ; 0
+        pxor        mm7, mm7              ; 0
+
+        punpcklbw   mm0, mm2              ; e0f0g0h0
+        psraw       mm0, 11               ; sign extended shift right by 3
+        punpckhbw   mm7, mm2              ; a0b0c0d0
+        psraw       mm7, 11               ; sign extended shift right by 3
+        packsswb    mm0, mm7              ; Filter2 >>=3;
+
+        ; mm0= filter2 mm1 = vp8_filter,  mm3 =qs0 mm5=s mm4 =hev mm6=ps0
+        psubsb      mm3, mm0              ; qs0 =qs0 - filter1
+        paddsb      mm6, mm5              ; ps0 =ps0 + Fitler2
+
+        ; mm1=vp8_filter, mm3=qs0, mm4 =hev mm6=ps0
+        ; vp8_filter &= ~hev;
+        ; Filter2 = vp8_filter;
+        pandn       mm4, mm1              ; vp8_filter&=~hev
+
+
+        ; mm3=qs0, mm4=filter2, mm6=ps0
+
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7);
+        ; s = vp8_signed_char_clamp(qs0 - u);
+        ; *oq0 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps0 + u);
+        ; *op0 = s^0x80;
+        pxor        mm0, mm0
+
+        pxor        mm1, mm1
+        pxor        mm2, mm2
+        punpcklbw   mm1, mm4
+        punpckhbw   mm2, mm4
+        pmulhw      mm1, [s27 GLOBAL]
+        pmulhw      mm2, [s27 GLOBAL]
+        paddw       mm1, [s63 GLOBAL]
+        paddw       mm2, [s63 GLOBAL]
+        psraw       mm1, 7
+        psraw       mm2, 7
+        packsswb    mm1, mm2
+
+        psubsb      mm3, mm1
+        paddsb      mm6, mm1
+
+        pxor        mm3, [t80 GLOBAL]
+        pxor        mm6, [t80 GLOBAL]
+        movq        [rdx+24], mm6
+        movq        [rdx+32], mm3
+
+        ; roughly 2/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7);
+        ; s = vp8_signed_char_clamp(qs1 - u);
+        ; *oq1 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps1 + u);
+        ; *op1 = s^0x80;
+        pxor        mm1, mm1
+        pxor        mm2, mm2
+        punpcklbw   mm1, mm4
+        punpckhbw   mm2, mm4
+        pmulhw      mm1, [s18 GLOBAL]
+        pmulhw      mm2, [s18 GLOBAL]
+        paddw       mm1, [s63 GLOBAL]
+        paddw       mm2, [s63 GLOBAL]
+        psraw       mm1, 7
+        psraw       mm2, 7
+        packsswb    mm1, mm2
+
+        movq        mm3, [rdx + 40]
+        movq        mm6, [rdx + 16]       ; p1
+        pxor        mm3, [t80 GLOBAL]
+        pxor        mm6, [t80 GLOBAL]
+
+        paddsb      mm6, mm1
+        psubsb      mm3, mm1
+
+        pxor        mm6, [t80 GLOBAL]
+        pxor        mm3, [t80 GLOBAL]
+        movq        [rdx + 40], mm3
+        movq        [rdx + 16], mm6
+
+        ; roughly 1/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7);
+        ; s = vp8_signed_char_clamp(qs2 - u);
+        ; *oq2 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps2 + u);
+        ; *op2 = s^0x80;
+        pxor        mm1, mm1
+        pxor        mm2, mm2
+        punpcklbw   mm1, mm4
+        punpckhbw   mm2, mm4
+        pmulhw      mm1, [s9 GLOBAL]
+        pmulhw      mm2, [s9 GLOBAL]
+        paddw       mm1, [s63 GLOBAL]
+        paddw       mm2, [s63 GLOBAL]
+        psraw       mm1, 7
+        psraw       mm2, 7
+        packsswb    mm1, mm2
+
+        movq        mm6, [rdx+ 8]
+        movq        mm3, [rdx+48]
+
+        pxor        mm6, [t80 GLOBAL]
+        pxor        mm3, [t80 GLOBAL]
+
+        paddsb      mm6, mm1
+        psubsb      mm3, mm1
+
+        pxor        mm6, [t80 GLOBAL]           ; mm6 = 71 61 51 41 31 21 11 01
+        pxor        mm3, [t80 GLOBAL]           ; mm3 = 76 66 56 46 36 26 15 06
+
+        ; tranpose and write back
+        movq        mm0,    [rdx]               ; mm0 = 70 60 50 40 30 20 10 00
+        movq        mm1,    mm0                 ; mm0 = 70 60 50 40 30 20 10 00
+
+        punpcklbw   mm0,    mm6                 ; mm0 = 31 30 21 20 11 10 01 00
+        punpckhbw   mm1,    mm6                 ; mm3 = 71 70 61 60 51 50 41 40
+
+        movq        mm2,    [rdx+16]            ; mm2 = 72 62 52 42 32 22 12 02
+        movq        mm6,    mm2                 ; mm3 = 72 62 52 42 32 22 12 02
+
+        punpcklbw   mm2,    [rdx+24]            ; mm2 = 33 32 23 22 13 12 03 02
+        punpckhbw   mm6,    [rdx+24]            ; mm3 = 73 72 63 62 53 52 43 42
+
+        movq        mm5,    mm0                 ; mm5 = 31 30 21 20 11 10 01 00
+        punpcklwd   mm0,    mm2                 ; mm0 = 13 12 11 10 03 02 01 00
+
+        punpckhwd   mm5,    mm2                 ; mm5 = 33 32 31 30 23 22 21 20
+        movq        mm4,    mm1                 ; mm4 = 71 70 61 60 51 50 41 40
+
+        punpcklwd   mm1,    mm6                 ; mm1 = 53 52 51 50 43 42 41 40
+        punpckhwd   mm4,    mm6                 ; mm4 = 73 72 71 70 63 62 61 60
+
+        movq        mm2,    [rdx+32]            ; mm2 = 74 64 54 44 34 24 14 04
+        punpcklbw   mm2,    [rdx+40]            ; mm2 = 35 34 25 24 15 14 05 04
+
+        movq        mm6,    mm3                 ; mm6 = 76 66 56 46 36 26 15 06
+        punpcklbw   mm6,    [rdx+56]            ; mm6 = 37 36 27 26 17 16 07 06
+
+        movq        mm7,    mm2                 ; mm7 = 35 34 25 24 15 14 05 04
+        punpcklwd   mm2,    mm6                 ; mm2 = 17 16 15 14 07 06 05 04
+
+        punpckhwd   mm7,    mm6                 ; mm7 = 37 36 35 34 27 26 25 24
+        movq        mm6,    mm0                 ; mm6 = 13 12 11 10 03 02 01 00
+
+        punpckldq   mm0,    mm2                 ; mm0 = 07 06 05 04 03 02 01 00
+        punpckhdq   mm6,    mm2                 ; mm6 = 17 16 15 14 13 12 11 10
+
+        movq        [rsi+rax*4], mm0            ; write out
+        movq        [rdi+rax*4], mm6            ; write out
+
+        movq        mm0,    mm5                 ; mm0 = 33 32 31 30 23 22 21 20
+        punpckldq   mm0,    mm7                 ; mm0 = 27 26 25 24 23 22 20 20
+
+        punpckhdq   mm5,    mm7                 ; mm5 = 37 36 35 34 33 32 31 30
+        movq        [rsi+rax*2], mm0            ; write out
+
+        movq        [rdi+rax*2], mm5            ; write out
+        movq        mm2,    [rdx+32]            ; mm2 = 74 64 54 44 34 24 14 04
+
+        punpckhbw   mm2,    [rdx+40]            ; mm2 = 75 74 65 64 54 54 45 44
+        punpckhbw   mm3,    [rdx+56]            ; mm3 = 77 76 67 66 57 56 47 46
+
+        movq        mm5,    mm2                 ; mm5 = 75 74 65 64 54 54 45 44
+        punpcklwd   mm2,    mm3                 ; mm2 = 57 56 55 54 47 46 45 44
+
+        punpckhwd   mm5,    mm3                 ; mm5 = 77 76 75 74 67 66 65 64
+        movq        mm0,    mm1                 ; mm0=  53 52 51 50 43 42 41 40
+
+        movq        mm3,    mm4                 ; mm4 = 73 72 71 70 63 62 61 60
+        punpckldq   mm0,    mm2                 ; mm0 = 47 46 45 44 43 42 41 40
+
+        punpckhdq   mm1,    mm2                 ; mm1 = 57 56 55 54 53 52 51 50
+        movq        [rsi],  mm0                 ; write out
+
+        movq        [rdi],  mm1                 ; write out
+        neg         rax
+
+        punpckldq   mm3,    mm5                 ; mm3 = 67 66 65 64 63 62 61 60
+        punpckhdq   mm4,    mm5                 ; mm4 = 77 76 75 74 73 72 71 60
+
+        movq        [rsi+rax*2], mm3
+        movq        [rdi+rax*2], mm4
+
+        lea         rsi,        [rsi+rax*8]
+        dec         rcx
+
+        jnz         next8_mbv
+
+    add rsp, 96
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_loop_filter_simple_horizontal_edge_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_loop_filter_simple_horizontal_edge_mmx)
+sym(vp8_loop_filter_simple_horizontal_edge_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi, arg(0) ;src_ptr
+        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        movsxd      rcx, dword ptr arg(5) ;count
+nexts8_h:
+        mov         rdx, arg(3) ;limit
+        movq        mm7, [rdx]
+        mov         rdx, arg(2) ;flimit           ; get flimit
+        movq        mm3, [rdx]            ;
+        paddb       mm3, mm3              ; flimit*2 (less than 255)
+        paddb       mm3, mm7              ; flimit * 2 + limit (less than 255)
+
+        mov         rdi, rsi              ; rdi points to row +1 for indirect addressing
+        add         rdi, rax
+        neg         rax
+
+        ; calculate mask
+        movq        mm1, [rsi+2*rax]      ; p1
+        movq        mm0, [rdi]            ; q1
+        movq        mm2, mm1
+        movq        mm7, mm0
+        movq        mm4, mm0
+        psubusb     mm0, mm1              ; q1-=p1
+        psubusb     mm1, mm4              ; p1-=q1
+        por         mm1, mm0              ; abs(p1-q1)
+        pand        mm1, [tfe GLOBAL]     ; set lsb of each byte to zero
+        psrlw       mm1, 1                ; abs(p1-q1)/2
+
+        movq        mm5, [rsi+rax]        ; p0
+        movq        mm4, [rsi]            ; q0
+        movq        mm0, mm4              ; q0
+        movq        mm6, mm5              ; p0
+        psubusb     mm5, mm4              ; p0-=q0
+        psubusb     mm4, mm6              ; q0-=p0
+        por         mm5, mm4              ; abs(p0 - q0)
+        paddusb     mm5, mm5              ; abs(p0-q0)*2
+        paddusb     mm5, mm1              ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        psubusb     mm5, mm3              ; abs(p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        pxor        mm3, mm3
+        pcmpeqb     mm5, mm3
+
+        ; start work on filters
+        pxor        mm2, [t80 GLOBAL]     ; p1 offset to convert to signed values
+        pxor        mm7, [t80 GLOBAL]     ; q1 offset to convert to signed values
+        psubsb      mm2, mm7              ; p1 - q1
+
+        pxor        mm6, [t80 GLOBAL]     ; offset to convert to signed values
+        pxor        mm0, [t80 GLOBAL]     ; offset to convert to signed values
+        movq        mm3, mm0              ; q0
+        psubsb      mm0, mm6              ; q0 - p0
+        paddsb      mm2, mm0              ; p1 - q1 + 1 * (q0 - p0)
+        paddsb      mm2, mm0              ; p1 - q1 + 2 * (q0 - p0)
+        paddsb      mm2, mm0              ; p1 - q1 + 3 * (q0 - p0)
+        pand        mm5, mm2              ; mask filter values we don't care about
+
+        ; do + 4 side
+        paddsb      mm5, [t4 GLOBAL]      ; 3* (q0 - p0) + (p1 - q1) + 4
+
+        movq        mm0, mm5              ; get a copy of filters
+        psllw       mm0, 8                ; shift left 8
+        psraw       mm0, 3                ; arithmetic shift right 11
+        psrlw       mm0, 8
+        movq        mm1, mm5              ; get a copy of filters
+        psraw       mm1, 11               ; arithmetic shift right 11
+        psllw       mm1, 8                ; shift left 8 to put it back
+
+        por         mm0, mm1              ; put the two together to get result
+
+        psubsb      mm3, mm0              ; q0-= q0 add
+        pxor        mm3, [t80 GLOBAL]     ; unoffset
+        movq        [rsi], mm3            ; write back
+
+
+        ; now do +3 side
+        psubsb      mm5, [t1s GLOBAL]      ; +3 instead of +4
+
+        movq        mm0, mm5              ; get a copy of filters
+        psllw       mm0, 8                ; shift left 8
+        psraw       mm0, 3                ; arithmetic shift right 11
+        psrlw       mm0, 8
+        psraw       mm5, 11               ; arithmetic shift right 11
+        psllw       mm5, 8                ; shift left 8 to put it back
+        por         mm0, mm5              ; put the two together to get result
+
+
+        paddsb      mm6, mm0              ; p0+= p0 add
+        pxor        mm6, [t80 GLOBAL]     ; unoffset
+        movq        [rsi+rax], mm6        ; write back
+
+        add         rsi,8
+        neg         rax
+        dec         rcx
+        jnz         nexts8_h
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_loop_filter_simple_vertical_edge_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_loop_filter_simple_vertical_edge_mmx)
+sym(vp8_loop_filter_simple_vertical_edge_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub          rsp, 32      ; reserve 32 bytes
+    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[8];
+    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[8];
+
+        mov         rsi, arg(0) ;src_ptr
+        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        lea         rsi, [rsi + rax*4- 2];  ;
+        movsxd      rcx, dword ptr arg(5) ;count
+nexts8_v:
+
+        lea         rdi,        [rsi + rax];
+        movd        mm0,        [rdi + rax * 2]                 ; xx xx xx xx 73 72 71 70
+
+        movd        mm6,        [rsi + rax * 2]                 ; xx xx xx xx 63 62 61 60
+        punpcklbw   mm6,        mm0                             ; 73 63 72 62 71 61 70 60
+
+        movd        mm0,        [rsi + rax]                     ; xx xx xx xx 53 52 51 50
+        movd        mm4,        [rsi]                           ; xx xx xx xx 43 42 41 40
+
+        punpcklbw   mm4,        mm0                             ; 53 43 52 42 51 41 50 40
+        movq        mm5,        mm4                             ; 53 43 52 42 51 41 50 40
+
+        punpcklwd   mm4,        mm6                             ; 71 61 51 41 70 60 50 40
+        punpckhwd   mm5,        mm6                             ; 73 63 53 43 72 62 52 42
+
+        neg         rax
+
+        movd        mm7,        [rsi + rax]                     ; xx xx xx xx 33 32 31 30
+        movd        mm6,        [rsi + rax * 2]                 ; xx xx xx xx 23 22 21 20
+
+        punpcklbw   mm6,        mm7                             ; 33 23 32 22 31 21 30 20
+        movd        mm1,        [rdi + rax * 4]                 ; xx xx xx xx 13 12 11 10
+
+        movd        mm0,        [rsi + rax * 4]                 ; xx xx xx xx 03 02 01 00
+        punpcklbw   mm0,        mm1                             ; 13 03 12 02 11 01 10 00
+
+        movq        mm2,        mm0                             ; 13 03 12 02 11 01 10 00
+        punpcklwd   mm0,        mm6                             ; 31 21 11 01 30 20 10 00
+
+        punpckhwd   mm2,        mm6                             ; 33 23 13 03 32 22 12 02
+        movq        mm1,        mm0                             ; 13 03 12 02 11 01 10 00
+
+        punpckldq   mm0,        mm4                             ; 70 60 50 40 30 20 10 00       = p1
+        movq        mm3,        mm2                             ; 33 23 13 03 32 22 12 02
+
+        punpckhdq   mm1,        mm4                             ; 71 61 51 41 31 21 11 01       = p0
+        punpckldq   mm2,        mm5                             ; 72 62 52 42 32 22 12 02       = q0
+
+        punpckhdq   mm3,        mm5                             ; 73 63 53 43 33 23 13 03       = q1
+
+
+        ; calculate mask
+        movq        mm6,        mm0                             ; p1
+        movq        mm7,        mm3                             ; q1
+        psubusb     mm7,        mm6                             ; q1-=p1
+        psubusb     mm6,        mm3                             ; p1-=q1
+        por         mm6,        mm7                             ; abs(p1-q1)
+        pand        mm6,        [tfe GLOBAL]                    ; set lsb of each byte to zero
+        psrlw       mm6,        1                               ; abs(p1-q1)/2
+
+        movq        mm5,        mm1                             ; p0
+        movq        mm4,        mm2                             ; q0
+
+        psubusb     mm5,        mm2                             ; p0-=q0
+        psubusb     mm4,        mm1                             ; q0-=p0
+
+        por         mm5,        mm4                             ; abs(p0 - q0)
+        paddusb     mm5,        mm5                             ; abs(p0-q0)*2
+        paddusb     mm5,        mm6                             ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        mov         rdx,        arg(2) ;flimit                          ; get flimit
+        movq        mm7,        [rdx]
+        mov         rdx,        arg(3)                          ; get limit
+        movq        mm6,        [rdx]
+        paddb       mm7,        mm7                             ; flimit*2 (less than 255)
+        paddb       mm7,        mm6                             ; flimit * 2 + limit (less than 255)
+
+        psubusb     mm5,        mm7                             ; abs(p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        pxor        mm7,        mm7
+        pcmpeqb     mm5,        mm7                             ; mm5 = mask
+
+        ; start work on filters
+        movq        t0,         mm0
+        movq        t1,         mm3
+
+        pxor        mm0,        [t80 GLOBAL]                    ; p1 offset to convert to signed values
+        pxor        mm3,        [t80 GLOBAL]                    ; q1 offset to convert to signed values
+
+        psubsb      mm0,        mm3                             ; p1 - q1
+        movq        mm6,        mm1                             ; p0
+
+        movq        mm7,        mm2                             ; q0
+        pxor        mm6,        [t80 GLOBAL]                    ; offset to convert to signed values
+
+        pxor        mm7,        [t80 GLOBAL]                    ; offset to convert to signed values
+        movq        mm3,        mm7                             ; offseted ; q0
+
+        psubsb      mm7,        mm6                             ; q0 - p0
+        paddsb      mm0,        mm7                             ; p1 - q1 + 1 * (q0 - p0)
+
+        paddsb      mm0,        mm7                             ; p1 - q1 + 2 * (q0 - p0)
+        paddsb      mm0,        mm7                             ; p1 - q1 + 3 * (q0 - p0)
+
+        pand        mm5,        mm0                             ; mask filter values we don't care about
+
+        paddsb      mm5,        [t4 GLOBAL]                     ;  3* (q0 - p0) + (p1 - q1) + 4
+
+        movq        mm0,        mm5                             ; get a copy of filters
+        psllw       mm0,        8                               ; shift left 8
+        psraw       mm0,        3                               ; arithmetic shift right 11
+        psrlw       mm0,        8
+
+        movq        mm7,        mm5                             ; get a copy of filters
+        psraw       mm7,        11                              ; arithmetic shift right 11
+        psllw       mm7,        8                               ; shift left 8 to put it back
+
+        por         mm0,        mm7                             ; put the two together to get result
+
+        psubsb      mm3,        mm0                             ; q0-= q0sz add
+        pxor        mm3,        [t80 GLOBAL]                    ; unoffset
+
+        ; now do +3 side
+        psubsb      mm5, [t1s GLOBAL]                           ; +3 instead of +4
+
+        movq        mm0, mm5                                    ; get a copy of filters
+        psllw       mm0, 8                                      ; shift left 8
+        psraw       mm0, 3                                      ; arithmetic shift right 11
+        psrlw       mm0, 8
+
+        psraw       mm5, 11                                     ; arithmetic shift right 11
+        psllw       mm5, 8                                      ; shift left 8 to put it back
+        por         mm0, mm5                                    ; put the two together to get result
+
+        paddsb      mm6, mm0                                    ; p0+= p0 add
+        pxor        mm6, [t80 GLOBAL]                           ; unoffset
+
+
+        movq        mm0,        t0
+        movq        mm4,        t1
+
+        ; mm0 = 70 60 50 40 30 20 10 00
+        ; mm6 = 71 61 51 41 31 21 11 01
+        ; mm3 = 72 62 52 42 32 22 12 02
+        ; mm4 = 73 63 53 43 33 23 13 03
+        ; transpose back to write out
+
+        movq        mm1,        mm0                         ;
+        punpcklbw   mm0,        mm6                         ; 31 30 21 20 11 10 01 00
+
+        punpckhbw   mm1,        mm6                         ; 71 70 61 60 51 50 41 40
+        movq        mm2,        mm3                         ;
+
+        punpcklbw   mm2,        mm4                         ; 33 32 23 22 13 12 03 02
+        movq        mm5,        mm1                         ; 71 70 61 60 51 50 41 40
+
+        punpckhbw   mm3,        mm4                         ; 73 72 63 62 53 52 43 42
+        movq        mm6,        mm0                         ; 31 30 21 20 11 10 01 00
+
+        punpcklwd   mm0,        mm2                         ; 13 12 11 10 03 02 01 00
+        punpckhwd   mm6,        mm2                         ; 33 32 31 30 23 22 21 20
+
+        movd        [rsi+rax*4], mm0                        ; write 03 02 01 00
+        punpcklwd   mm1,        mm3                         ; 53 52 51 50 43 42 41 40
+
+        psrlq       mm0,        32                          ; xx xx xx xx 13 12 11 10
+        punpckhwd   mm5,        mm3                         ; 73 72 71 70 63 62 61 60
+
+        movd        [rdi+rax*4], mm0                        ; write 13 12 11 10
+        movd        [rsi+rax*2], mm6                        ; write 23 22 21 20
+
+        psrlq       mm6,        32                          ; 33 32 31 30
+        movd        [rsi],      mm1                         ; write 43 42 41 40
+
+        movd        [rsi + rax], mm6                        ; write 33 32 31 30
+        neg         rax
+
+        movd        [rsi + rax*2], mm5                      ; write 63 62 61 60
+        psrlq       mm1,        32                          ; 53 52 51 50
+
+        movd        [rdi],      mm1                         ; write out 53 52 51 50
+        psrlq       mm5,        32                          ; 73 72 71 70
+
+        movd        [rdi + rax*2], mm5                      ; write 73 72 71 70
+
+        lea         rsi,        [rsi+rax*8]                 ; next 8
+
+        dec         rcx
+        jnz         nexts8_v
+
+    add rsp, 32
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+;void fast_loop_filter_vertical_edges_mmx(unsigned char *y_ptr,
+;                  int y_stride,
+;                  loop_filter_info *lfi)
+;{
+;
+;
+;    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr+4, y_stride, lfi->flim,lfi->lim,lfi->thr,2);
+;    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr+8, y_stride, lfi->flim,lfi->lim,lfi->thr,2);
+;    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr+12, y_stride, lfi->flim,lfi->lim,lfi->thr,2);
+;}
+
+SECTION_RODATA
+align 16
+tfe:
+    times 8 db 0xfe
+align 16
+t80:
+    times 8 db 0x80
+align 16
+t1s:
+    times 8 db 0x01
+align 16
+t3:
+    times 8 db 0x03
+align 16
+t4:
+    times 8 db 0x04
+align 16
+ones:
+    times 4 dw 0x0001
+align 16
+s27:
+    times 4 dw 0x1b00
+align 16
+s18:
+    times 4 dw 0x1200
+align 16
+s9:
+    times 4 dw 0x0900
+align 16
+s63:
+    times 4 dw 0x003f
diff --git a/vp8/common/x86/loopfilter_sse2.asm b/vp8/common/x86/loopfilter_sse2.asm
new file mode 100644 (file)
index 0000000..5275dfa
--- /dev/null
@@ -0,0 +1,1978 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+
+;void vp8_loop_filter_horizontal_edge_sse2
+;(
+;    unsigned char *src_ptr,
+;    int            src_pixel_step,
+;    const char    *flimit,
+;    const char    *limit,
+;    const char    *thresh,
+;    int            count
+;)
+global sym(vp8_loop_filter_horizontal_edge_sse2)
+sym(vp8_loop_filter_horizontal_edge_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 32                         ; reserve 32 bytes
+    %define t0 [rsp + 0]    ;__declspec(align(16)) char t0[16];
+    %define t1 [rsp + 16]   ;__declspec(align(16)) char t1[16];
+
+        mov         rsi, arg(0) ;src_ptr
+        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        mov         rdx,    arg(3) ;limit
+        movdqa      xmm7,   XMMWORD PTR [rdx]
+        mov         rdi,    rsi           ; rdi points to row +1 for indirect addressing
+        add         rdi,    rax
+
+        ; calculate breakout conditions
+        movdqu      xmm2,   [rdi+2*rax]      ; q3
+        movdqu      xmm1,   [rsi+2*rax]      ; q2
+        movdqa      xmm6,   xmm1              ; q2
+        psubusb     xmm1,   xmm2              ; q2-=q3
+        psubusb     xmm2,   xmm6              ; q3-=q2
+        por         xmm1,   xmm2              ; abs(q3-q2)
+        psubusb     xmm1,   xmm7              ;
+
+
+        movdqu      xmm4,   [rsi+rax]         ; q1
+        movdqa      xmm3,   xmm4              ; q1
+        psubusb     xmm4,   xmm6              ; q1-=q2
+        psubusb     xmm6,   xmm3              ; q2-=q1
+        por         xmm4,   xmm6              ; abs(q2-q1)
+
+        psubusb     xmm4,   xmm7
+        por         xmm1,   xmm4
+
+        movdqu      xmm4,   [rsi]             ; q0
+        movdqa      xmm0,   xmm4              ; q0
+        psubusb     xmm4,   xmm3              ; q0-=q1
+        psubusb     xmm3,   xmm0              ; q1-=q0
+        por         xmm4,   xmm3              ; abs(q0-q1)
+        movdqa        t0,       xmm4                  ; save to t0
+        psubusb     xmm4,   xmm7
+        por         xmm1,   xmm4
+
+        neg         rax                   ; negate pitch to deal with above border
+        movdqu      xmm2,   [rsi+4*rax]      ; p3
+        movdqu      xmm4,   [rdi+4*rax]      ; p2
+        movdqa      xmm5,   xmm4              ; p2
+        psubusb     xmm4,   xmm2              ; p2-=p3
+        psubusb     xmm2,   xmm5              ; p3-=p2
+        por         xmm4,   xmm2              ; abs(p3 - p2)
+        psubusb     xmm4,   xmm7
+        por         xmm1,   xmm4
+
+
+        movdqu      xmm4,   [rsi+2*rax]      ; p1
+        movdqa      xmm3,   xmm4              ; p1
+        psubusb     xmm4,   xmm5              ; p1-=p2
+        psubusb     xmm5,   xmm3              ; p2-=p1
+        por         xmm4,   xmm5              ; abs(p2 - p1)
+        psubusb     xmm4,   xmm7
+        por         xmm1,   xmm4
+
+        movdqa      xmm2,   xmm3              ; p1
+
+        movdqu      xmm4,   [rsi+rax]         ; p0
+        movdqa      xmm5,   xmm4              ; p0
+        psubusb     xmm4,   xmm3              ; p0-=p1
+        psubusb     xmm3,   xmm5              ; p1-=p0
+        por         xmm4,   xmm3              ; abs(p1 - p0)
+        movdqa      t1,     xmm4                  ; save to t1
+        psubusb     xmm4,   xmm7
+        por         xmm1,    xmm4
+
+        movdqu      xmm3,   [rdi]             ; q1
+        movdqa      xmm4,   xmm3              ; q1
+        psubusb     xmm3,   xmm2              ; q1-=p1
+        psubusb     xmm2,   xmm4              ; p1-=q1
+        por         xmm2,   xmm3              ; abs(p1-q1)
+        pand        xmm2,   [tfe GLOBAL]      ; set lsb of each byte to zero
+        psrlw       xmm2,   1                 ; abs(p1-q1)/2
+
+        movdqa      xmm6,   xmm5              ; p0
+        movdqu      xmm3,   [rsi]             ; q0
+        psubusb     xmm5,   xmm3              ; p0-=q0
+        psubusb     xmm3,   xmm6              ; q0-=p0
+        por         xmm5,   xmm3              ; abs(p0 - q0)
+        paddusb     xmm5,   xmm5              ; abs(p0-q0)*2
+        paddusb     xmm5,   xmm2              ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        mov         rdx,    arg(2) ;flimit            ; get flimit
+        movdqa      xmm2,   [rdx]             ;
+
+        paddb       xmm2,   xmm2              ; flimit*2 (less than 255)
+        paddb       xmm7,   xmm2              ; flimit * 2 + limit (less than 255)
+
+        psubusb     xmm5,    xmm7             ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         xmm1,    xmm5
+        pxor        xmm5,    xmm5
+        pcmpeqb     xmm1,    xmm5             ; mask mm1
+
+
+        ; calculate high edge variance
+        mov         rdx,    arg(4) ;thresh            ; get thresh
+        movdqa      xmm7,   [rdx]             ;
+        movdqa      xmm4,   t0                ; get abs (q1 - q0)
+        psubusb     xmm4,   xmm7
+        movdqa      xmm3,   t1                ; get abs (p1 - p0)
+        psubusb     xmm3,   xmm7
+        paddb       xmm4,   xmm3              ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+        pcmpeqb     xmm4,        xmm5
+        pcmpeqb     xmm5,        xmm5
+        pxor        xmm4,        xmm5
+
+
+        ; start work on filters
+        movdqu      xmm2, [rsi+2*rax]     ; p1
+        movdqu      xmm7, [rdi]           ; q1
+        pxor        xmm2, [t80 GLOBAL]    ; p1 offset to convert to signed values
+        pxor        xmm7, [t80 GLOBAL]    ; q1 offset to convert to signed values
+        psubsb      xmm2, xmm7            ; p1 - q1
+        pand        xmm2, xmm4            ; high var mask (hvm)(p1 - q1)
+        pxor        xmm6, [t80 GLOBAL]    ; offset to convert to signed values
+        pxor        xmm0, [t80 GLOBAL]    ; offset to convert to signed values
+        movdqa      xmm3, xmm0            ; q0
+        psubsb      xmm0, xmm6            ; q0 - p0
+        paddsb      xmm2, xmm0            ; 1 * (q0 - p0) + hvm(p1 - q1)
+        paddsb      xmm2, xmm0            ; 2 * (q0 - p0) + hvm(p1 - q1)
+        paddsb      xmm2, xmm0            ; 3 * (q0 - p0) + hvm(p1 - q1)
+        pand        xmm1, xmm2            ; mask filter values we don't care about
+        movdqa      xmm2, xmm1
+        paddsb      xmm1, [t4 GLOBAL]         ; 3* (q0 - p0) + hvm(p1 - q1) + 4
+        paddsb      xmm2, [t3 GLOBAL]         ; 3* (q0 - p0) + hvm(p1 - q1) + 3
+
+        pxor        xmm0, xmm0           ;
+        pxor        xmm5, xmm5
+        punpcklbw   xmm0, xmm2          ;
+        punpckhbw   xmm5, xmm2          ;
+        psraw       xmm0, 11                ;
+        psraw       xmm5, 11
+        packsswb    xmm0, xmm5
+        movdqa      xmm2, xmm0          ;  (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
+
+        pxor        xmm0, xmm0            ; 0
+        movdqa      xmm5, xmm1            ; abcdefgh
+        punpcklbw   xmm0, xmm1            ; e0f0g0h0
+        psraw       xmm0, 11                  ; sign extended shift right by 3
+        pxor        xmm1, xmm1            ; 0
+        punpckhbw   xmm1, xmm5            ; a0b0c0d0
+        psraw       xmm1, 11                  ; sign extended shift right by 3
+        movdqa      xmm5, xmm0              ; save results
+
+        packsswb    xmm0, xmm1            ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
+        paddsw      xmm5, [ones GLOBAL]
+        paddsw      xmm1, [ones GLOBAL]
+        psraw       xmm5, 1               ; partial shifted one more time for 2nd tap
+        psraw       xmm1, 1               ; partial shifted one more time for 2nd tap
+        packsswb    xmm5, xmm1            ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
+        pandn       xmm4, xmm5            ; high edge variance additive
+
+        paddsb      xmm6, xmm2            ; p0+= p0 add
+        pxor        xmm6, [t80 GLOBAL]    ; unoffset
+        movdqu      [rsi+rax], xmm6       ; write back
+
+        movdqu      xmm6, [rsi+2*rax]     ; p1
+        pxor        xmm6, [t80 GLOBAL]    ; reoffset
+        paddsb      xmm6, xmm4            ; p1+= p1 add
+        pxor        xmm6, [t80 GLOBAL]    ; unoffset
+        movdqu      [rsi+2*rax], xmm6     ; write back
+
+        psubsb      xmm3, xmm0            ; q0-= q0 add
+        pxor        xmm3, [t80 GLOBAL]    ; unoffset
+        movdqu      [rsi], xmm3           ; write back
+
+        psubsb      xmm7, xmm4            ; q1-= q1 add
+        pxor        xmm7, [t80 GLOBAL]    ; unoffset
+        movdqu      [rdi], xmm7           ; write back
+
+    add rsp, 32
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_loop_filter_vertical_edge_sse2
+;(
+;    unsigned char *src_ptr,
+;    int            src_pixel_step,
+;    const char    *flimit,
+;    const char    *limit,
+;    const char    *thresh,
+;    int            count
+;)
+global sym(vp8_loop_filter_vertical_edge_sse2)
+sym(vp8_loop_filter_vertical_edge_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub          rsp, 96      ; reserve 96 bytes
+    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[16];
+    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[16];
+    %define srct [rsp + 32]   ;__declspec(align(16)) char srct[64];
+
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rax,        dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        lea         rsi,        [rsi + rax*4 - 4]
+        mov         rdi,        rsi           ; rdi points to row +1 for indirect addressing
+
+        add         rdi,        rax
+        lea         rcx,        [rdi + rax *8]
+
+        ;transpose
+        movq        xmm7,       QWORD PTR [rsi+2*rax]                 ; 67 66 65 64 63 62 61 60
+        movq        xmm6,       QWORD PTR [rdi+2*rax]                 ; 77 76 75 74 73 72 71 70
+
+        punpcklbw   xmm7,       xmm6                        ; 77 67 76 66 75 65 74 64 73 63 72 62 71 61 70 60
+        movq        xmm5,       QWORD PTR [rsi]                       ; 47 46 45 44 43 42 41 40
+
+        movq        xmm4,       QWORD PTR [rsi+rax]                   ; 57 56 55 54 53 52 51 50
+        punpcklbw   xmm5,       xmm4                        ; 57 47 56 46 55 45 54 44 53 43 52 42 51 41 50 40
+
+        movdqa      xmm3,       xmm5                        ; 57 47 56 46 55 45 54 44 53 43 52 42 51 41 50 40
+        punpckhwd   xmm5,       xmm7                        ; 77 67 57 47 76 66 56 46 75 65 55 45 74 64 54 44
+
+        lea         rsi,        [rsi+ rax*8]
+
+        punpcklwd   xmm3,       xmm7                        ; 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40
+        movq        xmm6,       QWORD PTR [rsi + 2*rax]               ; e7 e6 e5 e4 e3 e2 e1 e0
+
+        movq        xmm7,       QWORD PTR [rcx + 2*rax]               ; f7 f6 f5 f4 f3 f2 f1 f0
+        punpcklbw   xmm6,       xmm7                        ; f7 e7 f6 e6 f5 e5 f4 e4 f3 e3 f2 e2 f1 e1 f0 e0
+
+        movq        xmm4,       QWORD PTR [rsi]                       ; c7 c6 c5 c4 c3 c2 c1 c0
+        movq        xmm7,       QWORD PTR [rsi + rax]                 ; d7 d6 d5 d4 d3 d2 d1 d0
+
+        punpcklbw   xmm4,       xmm7                        ; d7 c7 d6 c6 d5 c5 d4 c4 d3 c3 d2 c2 d1 c1 d0 c0
+        movdqa      xmm7,       xmm4                        ; d7 c7 d6 c6 d5 c5 d4 c4 d3 c3 d2 c2 d1 c1 d0 c0
+
+        punpckhwd   xmm7,       xmm6                        ; f7 e7 d7 c7 f6 e6 d6 c6 f5 e5 d5 c5 f4 e4 d4 c4
+        punpcklwd   xmm4,       xmm6                        ; f3 e3 d3 c3 f2 e2 d2 c2 f1 e1 d1 c1 f0 e0 d0 c0
+
+        ; xmm3 xmm4, xmm5 xmm7   in use
+        neg         rax
+
+        lea         rsi,        [rsi+rax*8]
+        movq        xmm6,       QWORD PTR [rsi+rax*2]                 ; 27 26 25 24 23 22 21 20
+
+        movq        xmm1,       QWORD PTR [rsi+rax  ]                 ; 37 36 35 34 33 32 31 30
+        punpcklbw   xmm6,       xmm1                        ; 37 27 36 26 35 25 34 24 33 23 32 22 31 21 30 20
+
+        movq        xmm2,       QWORD PTR [rsi+rax*4]                 ; 07 06 05 04 03 02 01 00
+        movq        xmm1,       QWORD PTR [rdi+rax*4]                 ; 17 16 15 14 13 12 11 10
+
+        punpcklbw   xmm2,       xmm1                        ; 17 07 16 06 15 05 14 04 13 03 12 02 11 01 10 00
+        movdqa      xmm0,       xmm2
+
+        punpckhwd   xmm2,       xmm6                        ; 37 27 17 07 36 26 16 06 35 25 15 05 34 24 14 04
+        punpcklwd   xmm0,       xmm6                        ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+
+        movdqa      xmm6,       xmm2
+        punpckldq   xmm2,       xmm5                        ; 75 65 55 45 35 25 15 05 74 64 54 44 34 24 14 04
+
+        punpckhdq   xmm6,       xmm5                        ; 77 67 57 47 37 27 17 07 76 66 56 46 36 26 16 06
+        ;xmm0 xmm2 xmm3 xmm4, xmm6, xmm7
+
+        movdqa      xmm5,       xmm0                        ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+        punpckhdq   xmm5,       xmm3                        ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+
+        punpckldq   xmm0,       xmm3                        ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+        lea         rsi,        [rcx+rax]
+        ; xmm1, xmm3 free
+        movq        xmm1,       QWORD PTR [rsi+rax*2]                 ; a7 a6 a5 a4 a3 a2 a1 a0
+        movq        xmm3,       QWORD PTR [rsi+rax]                   ; b7 b6 b5 b4 b3 b2 b1 b0
+
+        punpcklbw   xmm1,       xmm3                        ;
+        lea         rdx,        srct                        ;
+
+        movdqa      [rdx+16],   xmm1                        ; b7 a7 b6 a6 b5 a5 b4 a4 b3 a3 b2 a2 b1 a1 b0 a0
+        movq        xmm3,       QWORD PTR [rsi+rax*4]                 ; 87 86 85 84 83 82 81 80
+
+        movq        xmm1,       QWORD PTR [rcx+rax*4]
+        punpcklbw   xmm3,       xmm1                        ; 97 87 96 86 95 85 94 84 93 83 92 82 91 81 90 80
+
+        movdqa      [rdx],      xmm3                        ; 97 87 96 86 95 85 94 84 93 83 92 82 91 81 90 80
+
+        punpckhwd   xmm3,       [rdx+16]                    ; b7 a7 97 87 b6 a6 96 86 b5 a5 95 85 b4 a4 94 84
+        movdqa      xmm1,       xmm3                        ; b7 a7 97 87 b6 a6 96 86 b5 a5 95 85 b4 a4 94 84
+
+        punpckhdq   xmm1,       xmm7                        ; f7 e7 d7 c7 b7 a7 97 87 f6 e6 d6 c6 b6 a6 96 86
+        punpckldq   xmm3,       xmm7                        ; f5 e5 d5 c5 b5 a5 95 85 f4 e4 d4 c4 b4 a4 94 84
+
+        movdqa      xmm7,       xmm2                        ; 75 65 55 45 35 25 15 05 74 64 54 44 34 24 14 04
+        punpcklqdq  xmm7,       xmm3                        ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04
+
+        punpckhqdq  xmm2,       xmm3                        ; f5 e5 d5 c5 b5 a5 95 85 75 65 55 45 35 25 15 05
+        movdqa      [rdx+32],   xmm7                        ; save 4s
+
+        movdqa      [rdx+48],   xmm2                        ; save 5s
+        movdqa      xmm7,       xmm6                        ; 77 67 57 47 37 27 17 07 76 66 56 46 36 26 16 06
+
+        punpckhqdq  xmm7,       xmm1                        ; f7 e7 d7 c7 b7 a7 97 87 77 67 57 47 37 27 17 07 = q3
+        punpcklqdq  xmm6,       xmm1                        ; f6 e6 d6 c6 b6 a6 96 86 76 66 56 46 36 26 16 06 = q2
+
+        ; free 1, 3   xmm7-7s xmm6-6s, xmm2-5s
+        movq        xmm1,       QWORD PTR [rdx]                       ; 93 83 92 82 91 81 90 80
+        movq        xmm3,       QWORD PTR [rdx+16]                    ; b3 a3 b2 a2 b1 a1 b0 a0
+
+        punpcklwd   xmm1,       xmm3                        ; b3 a3 93 83 b2 a2 92 82 b1 a1 91 81 b0 a0 90 80
+        movdqa      xmm3,       xmm1                        ; b3 a3 93 83 b2 a2 92 82 b1 a1 91 81 b0 a0 90 80
+
+        punpckhdq   xmm3,       xmm4                        ; f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
+        punpckldq   xmm1,       xmm4                        ; f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
+
+        movdqa      xmm4,       xmm5                        ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+        punpcklqdq  xmm5,       xmm3                        ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+
+        punpckhqdq  xmm4,       xmm3                        ; f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+        movdqa      [rdx],      xmm5                        ; save 2s
+
+        movdqa      [rdx+16],   xmm4                        ; save 3s
+
+        movdqa      xmm3,       xmm6                        ;
+        psubusb     xmm3,       xmm7                        ; q3 - q2
+
+        psubusb     xmm7,       xmm6                        ; q2 - q3
+        por         xmm7,       xmm3                        ; abs(q3-q2)
+
+        movdqa      xmm3,       xmm2                        ; q1
+        psubusb     xmm3,       xmm6                        ; q1 - q2
+
+        psubusb     xmm6,       xmm2                        ; q2 - q1
+        por         xmm6,       xmm3                        ; abs(q2-q1)
+
+
+        movdqa      xmm3,       xmm0                        ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+        punpcklqdq  xmm0,       xmm1                        ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+
+        punpckhqdq  xmm3,       xmm1                        ; f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+        movdqa      xmm1,       xmm3
+
+        psubusb     xmm3,       xmm0                        ; p2-p3
+        psubusb     xmm0,       xmm1                        ; p3-p2
+
+        por         xmm0,       xmm3                        ; abs(p3-p2)
+        movdqa      xmm3,       xmm5                        ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+
+        psubusb     xmm3,       xmm1                        ; p1-p2
+        psubusb     xmm1,       xmm5                        ; p2-p1
+
+        por         xmm1,       xmm3                        ; abs(p1-p2)
+        mov         rdx,        arg(3) ;limit
+
+        movdqa      xmm3,       [rdx]                       ; limit
+
+        psubusb     xmm7,       xmm3
+        psubusb     xmm0,       xmm3
+
+        psubusb     xmm1,       xmm3
+        psubusb     xmm6,       xmm3
+
+        por         xmm7,       xmm6
+        por         xmm0,       xmm1
+
+        por         xmm0,       xmm7                         ;   abs(q3-q2) > limit || abs(p3-p2) > limit ||abs(p2-p1) > limit || abs(q2-q1) > limit
+
+        movdqa      xmm1,       xmm5                         ; p1
+
+        movdqa      xmm7,       xmm4                        ; xmm4 xmm7 = p0
+
+        psubusb     xmm7,       xmm5                        ; p0 - p1
+        psubusb     xmm5,       xmm4                        ; p1 - p0
+
+        por         xmm5,       xmm7                        ; abs(p1-p0)
+        movdqa        t0,       xmm5                        ; save abs(p1-p0)
+
+        lea         rdx,        srct
+        psubusb     xmm5,       xmm3
+
+        por         xmm0,       xmm5                        ; xmm0=mask
+        movdqa      xmm5,       [rdx+32]                    ; xmm5=q0
+
+        movdqa      xmm7,       [rdx+48]                    ; xmm7=q1
+        movdqa      xmm6,       xmm5                        ; mm6=q0
+
+        movdqa      xmm2,       xmm7                        ; q1
+
+        psubusb     xmm5,       xmm7                        ; q0-q1
+        psubusb     xmm7,       xmm6                        ; q1-q0
+
+        por         xmm7,       xmm5                        ; abs(q1-q0)
+        movdqa        t1,       xmm7                        ; save abs(q1-q0)
+
+        psubusb     xmm7,       xmm3
+        por         xmm0,       xmm7                        ; mask
+
+        movdqa      xmm5,       xmm2                        ; q1
+        psubusb     xmm5,       xmm1                        ; q1-=p1
+        psubusb     xmm1,       xmm2                        ; p1-=q1
+        por         xmm5,       xmm1                        ; abs(p1-q1)
+        pand        xmm5,       [tfe GLOBAL]                ; set lsb of each byte to zero
+        psrlw       xmm5,       1                           ; abs(p1-q1)/2
+
+        mov         rdx,        arg(2) ;flimit                      ;
+        movdqa        xmm2,       [rdx]                       ;flimit  xmm2
+
+        movdqa      xmm1,       xmm4                        ; xmm1=xmm4=p0
+
+        movdqa      xmm7,       xmm6                        ; xmm7=xmm6=q0
+        psubusb     xmm1,       xmm7                        ; p0-q0
+
+        psubusb     xmm7,       xmm4                        ; q0-p0
+        por         xmm1,       xmm7                        ; abs(q0-p0)
+        paddusb     xmm1,       xmm1                        ; abs(q0-p0)*2
+        paddusb     xmm1,       xmm5                        ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        paddb       xmm2,       xmm2                        ; flimit*2 (less than 255)
+        paddb       xmm3,       xmm2                        ; flimit * 2 + limit (less than 255)
+
+        psubusb     xmm1,       xmm3                         ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+
+        por         xmm1,       xmm0;                       ; mask
+
+        pxor        xmm0,       xmm0
+        pcmpeqb     xmm1,       xmm0
+        ; calculate high edge variance
+        mov         rdx,        arg(4) ;thresh            ; get thresh
+        movdqa      xmm7,       [rdx]
+
+        ;
+        movdqa      xmm4,       t0              ; get abs (q1 - q0)
+        psubusb     xmm4,       xmm7
+
+        movdqa      xmm3,       t1              ; get abs (p1 - p0)
+        psubusb     xmm3,       xmm7
+
+        por         xmm4,       xmm3            ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+        pcmpeqb     xmm4,       xmm0
+
+        pcmpeqb     xmm0,       xmm0
+        pxor        xmm4,       xmm0
+
+        ; start work on filters
+        lea         rdx,        srct
+
+        movdqa      xmm2,       [rdx]           ; p1
+        movdqa      xmm7,       [rdx+48]        ; q1
+
+        movdqa      xmm6,       [rdx+16]        ; p0
+        movdqa      xmm0,       [rdx+32]        ; q0
+
+        pxor        xmm2,       [t80 GLOBAL]    ; p1 offset to convert to signed values
+        pxor        xmm7,       [t80 GLOBAL]    ; q1 offset to convert to signed values
+
+        psubsb      xmm2,       xmm7            ; p1 - q1
+        pand        xmm2,       xmm4            ; high var mask (hvm)(p1 - q1)
+
+        pxor        xmm6,       [t80 GLOBAL]    ; offset to convert to signed values
+        pxor        xmm0,       [t80 GLOBAL]    ; offset to convert to signed values
+
+        movdqa      xmm3,       xmm0            ; q0
+        psubsb      xmm0,       xmm6            ; q0 - p0
+
+        paddsb      xmm2,       xmm0            ; 1 * (q0 - p0) + hvm(p1 - q1)
+        paddsb      xmm2,       xmm0            ; 2 * (q0 - p0) + hvm(p1 - q1)
+
+        paddsb      xmm2,       xmm0            ; 3 * (q0 - p0) + hvm(p1 - q1)
+        pand        xmm1,       xmm2            ; mask filter values we don't care about
+
+        movdqa      xmm2,       xmm1
+        paddsb      xmm1,       [t4 GLOBAL]       ; 3* (q0 - p0) + hvm(p1 - q1) + 4
+
+        paddsb      xmm2,       [t3 GLOBAL]       ; 3* (q0 - p0) + hvm(p1 - q1) + 3
+        pxor        xmm0,       xmm0             ;
+
+        pxor        xmm5,       xmm5
+        punpcklbw   xmm0,       xmm2            ;
+
+        punpckhbw   xmm5,       xmm2            ;
+        psraw       xmm0,       11              ;
+
+        psraw       xmm5,       11
+        packsswb    xmm0,       xmm5
+
+        movdqa      xmm2,       xmm0            ;  (3* (q0 - p0) + hvm(p1 - q1) + 3) >> 3;
+
+        pxor        xmm0,       xmm0              ; 0
+        movdqa      xmm5,       xmm1              ; abcdefgh
+
+        punpcklbw   xmm0,       xmm1              ; e0f0g0h0
+        psraw       xmm0,       11                ; sign extended shift right by 3
+
+        pxor        xmm1,       xmm1              ; 0
+        punpckhbw   xmm1,       xmm5              ; a0b0c0d0
+
+        psraw       xmm1,       11                ; sign extended shift right by 3
+        movdqa      xmm5,       xmm0              ; save results
+
+        packsswb    xmm0,       xmm1              ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>3
+        paddsw      xmm5,       [ones GLOBAL]
+
+        paddsw      xmm1,       [ones GLOBAL]
+        psraw       xmm5,       1                 ; partial shifted one more time for 2nd tap
+
+        psraw       xmm1,       1                 ; partial shifted one more time for 2nd tap
+        packsswb    xmm5,       xmm1              ; (3* (q0 - p0) + hvm(p1 - q1) + 4) >>4
+
+        pandn       xmm4,       xmm5            ; high edge variance additive
+
+        paddsb      xmm6,       xmm2            ; p0+= p0 add
+        pxor        xmm6,       [t80 GLOBAL]    ; unoffset
+
+        ; mm6=p0                               ;
+        movdqa      xmm1,       [rdx]           ; p1
+        pxor        xmm1,       [t80 GLOBAL]    ; reoffset
+
+        paddsb      xmm1,       xmm4            ; p1+= p1 add
+        pxor        xmm1,       [t80 GLOBAL]    ; unoffset
+        ; mm6 = p0 mm1 = p1
+
+        psubsb      xmm3,       xmm0            ; q0-= q0 add
+        pxor        xmm3,       [t80 GLOBAL]    ; unoffset
+
+        ; mm3 = q0
+        psubsb      xmm7,       xmm4            ; q1-= q1 add
+        pxor        xmm7,       [t80 GLOBAL]    ; unoffset
+        ; mm7 = q1
+
+        ; tranpose and write back
+        ; xmm1 =    f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+        ; xmm6 =    f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+        ; xmm3 =    f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04
+        ; xmm7 =    f5 e5 d5 c5 b5 a5 95 85 75 65 55 45 35 25 15 05
+        movdqa      xmm2,       xmm1            ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+        punpcklbw   xmm2,       xmm6            ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
+
+        movdqa      xmm4,       xmm3            ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04
+        punpckhbw   xmm1,       xmm6            ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+
+        punpcklbw   xmm4,       xmm7            ; 75 74 65 64 55 54 45 44 35 34 25 24 15 14 05 04
+        punpckhbw   xmm3,       xmm7            ; f5 f4 e5 e4 d5 d4 c5 c4 b5 b4 a5 a4 95 94 85 84
+
+        movdqa      xmm6,       xmm2            ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
+        punpcklwd   xmm2,       xmm4            ; 35 34 33 32 25 24 23 22 15 14 13 12 05 04 03 02
+
+        punpckhwd   xmm6,       xmm4            ; 75 74 73 72 65 64 63 62 55 54 53 52 45 44 43 42
+        movdqa      xmm5,       xmm1            ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+
+        punpcklwd   xmm1,       xmm3            ; f5 f4 f3 f2 e5 e4 e3 e2 d5 d4 d3 d2 c5 c4 c3 c2
+        punpckhwd   xmm5,       xmm3            ; b5 b4 b3 b2 a5 a4 a3 a2 95 94 93 92 85 84 83 82
+
+        ; xmm2 = 35 34 33 32 25 24 23 22 15 14 13 12 05 04 03 02
+        ; xmm6 = 75 74 73 72 65 64 63 62 55 54 53 52 45 44 43 42
+        ; xmm5 = f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+        ; xmm1 = b5 b4 b3 b2 a5 a4 a3 a2 95 94 93 92 85 84 83 82
+        lea         rsi,           [rsi+rax*8]
+
+        movd        [rsi+rax*4+2], xmm2
+        psrldq      xmm2,   4
+
+        movd        [rdi+rax*4+2], xmm2
+        psrldq      xmm2,   4
+
+        movd        [rsi+rax*2+2], xmm2
+        psrldq      xmm2,   4
+
+        movd        [rdi+rax*2+2], xmm2
+        movd        [rsi+2],       xmm6
+
+        psrldq      xmm6,   4
+        movd        [rdi+2],       xmm6
+
+        psrldq      xmm6,   4
+        neg         rax
+
+        movd        [rdi+rax+2],    xmm6
+        psrldq      xmm6,   4
+
+        movd        [rdi+rax*2+2],  xmm6
+        lea         rsi,       [rsi+rax*8]
+
+        neg         rax
+        ;;;;;;;;;;;;;;;;;;;;/
+        movd        [rsi+rax*4+2], xmm1
+        psrldq      xmm1,   4
+
+        movd        [rcx+rax*4+2], xmm1
+        psrldq      xmm1,   4
+
+        movd        [rsi+rax*2+2], xmm1
+        psrldq      xmm1,   4
+
+        movd        [rcx+rax*2+2], xmm1
+        psrldq      xmm1,   4
+
+        movd        [rsi+2],       xmm5
+        psrldq      xmm5,   4
+
+        movd        [rcx+2],        xmm5
+        psrldq      xmm5,   4
+
+        neg         rax
+        movd        [rcx+rax+2],    xmm5
+
+        psrldq      xmm5,   4
+        movd        [rcx+rax*2+2],  xmm5
+
+    add rsp, 96
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_mbloop_filter_horizontal_edge_sse2
+;(
+;    unsigned char *src_ptr,
+;    int            src_pixel_step,
+;    const char    *flimit,
+;    const char    *limit,
+;    const char    *thresh,
+;    int            count
+;)
+global sym(vp8_mbloop_filter_horizontal_edge_sse2)
+sym(vp8_mbloop_filter_horizontal_edge_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 32                         ; reserve 32 bytes
+    %define t0  [rsp + 0]    ;__declspec(align(16)) char t0[8];
+    %define t1  [rsp + 16]   ;__declspec(align(16)) char t1[8];
+
+        mov         rsi,                    arg(0) ;src_ptr
+        movsxd      rax,                    dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        mov         rdx,                    arg(3) ;limit
+        movdqa      xmm7,                   XMMWORD PTR [rdx]
+
+        mov         rdi,                    rsi           ; rdi points to row +1 for indirect addressing
+        add         rdi,                    rax
+
+        ; calculate breakout conditions
+        movdqa      xmm2,                   XMMWORD PTR [rdi+2*rax]      ; q3
+        movdqa      xmm1,                   XMMWORD PTR [rsi+2*rax]      ; q2
+
+        movdqa      xmm6,                   xmm1              ; q2
+        psubusb     xmm1,                   xmm2              ; q2-=q3
+
+
+        psubusb     xmm2,                   xmm6              ; q3-=q2
+        por         xmm1,                   xmm2              ; abs(q3-q2)
+
+        psubusb     xmm1,                   xmm7
+
+        ; mm1 = abs(q3-q2), mm6 =q2, mm7 = limit
+        movdqa      xmm4,                   XMMWORD PTR [rsi+rax]         ; q1
+        movdqa      xmm3,                   xmm4              ; q1
+
+        psubusb     xmm4,                   xmm6              ; q1-=q2
+        psubusb     xmm6,                   xmm3              ; q2-=q1
+
+        por         xmm4,                   xmm6              ; abs(q2-q1)
+        psubusb     xmm4,                   xmm7
+
+        por         xmm1,                   xmm4
+        ; mm1 = mask,      mm3=q1, mm7 = limit
+
+        movdqa      xmm4,                   XMMWORD PTR [rsi]             ; q0
+        movdqa      xmm0,                   xmm4              ; q0
+
+        psubusb     xmm4,                   xmm3              ; q0-=q1
+        psubusb     xmm3,                   xmm0              ; q1-=q0
+
+        por         xmm4,                   xmm3              ; abs(q0-q1)
+        movdqa      t0,                     xmm4                  ; save to t0
+
+        psubusb     xmm4,                   xmm7
+        por         xmm1,                   xmm4
+
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1)
+        neg         rax                   ; negate pitch to deal with above border
+
+        movdqa      xmm2,                   XMMWORD PTR [rsi+4*rax]      ; p3
+        movdqa      xmm4,                   XMMWORD PTR [rdi+4*rax]      ; p2
+
+        movdqa      xmm5,                   xmm4              ; p2
+        psubusb     xmm4,                   xmm2              ; p2-=p3
+
+        psubusb     xmm2,                   xmm5              ; p3-=p2
+        por         xmm4,                   xmm2              ; abs(p3 - p2)
+
+        psubusb     xmm4,                   xmm7
+        por         xmm1,                   xmm4
+
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1)
+        movdqa      xmm4,                   XMMWORD PTR [rsi+2*rax]      ; p1
+        movdqa      xmm3,                   xmm4              ; p1
+
+        psubusb     xmm4,                   xmm5              ; p1-=p2
+        psubusb     xmm5,                   xmm3              ; p2-=p1
+
+        por         xmm4,                   xmm5              ; abs(p2 - p1)
+        psubusb     xmm4,                   xmm7
+
+        por         xmm1,                   xmm4
+
+        movdqa      xmm2,                   xmm3              ; p1
+
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1)
+        movdqa      xmm4,                   XMMWORD PTR [rsi+rax]         ; p0
+        movdqa      xmm5,                   xmm4              ; p0
+
+        psubusb     xmm4,                   xmm3              ; p0-=p1
+        psubusb     xmm3,                   xmm5              ; p1-=p0
+
+        por         xmm4,                   xmm3              ; abs(p1 - p0)
+        movdqa        t1,                   xmm4                  ; save to t1
+
+        psubusb     xmm4,                   xmm7
+        por         xmm1,                   xmm4
+
+        ; mm1 = mask, mm0=q0,  mm7 = limit, t0 = abs(q0-q1) t1 = abs(p1-p0)
+        ; mm5 = p0
+        movdqa      xmm3,                   XMMWORD PTR [rdi] ; q1
+        movdqa      xmm4,                   xmm3              ; q1
+        psubusb     xmm3,                   xmm2              ; q1-=p1
+        psubusb     xmm2,                   xmm4              ; p1-=q1
+        por         xmm2,                   xmm3              ; abs(p1-q1)
+        pand        xmm2,                   [tfe GLOBAL]      ; set lsb of each byte to zero
+        psrlw       xmm2,                   1                 ; abs(p1-q1)/2
+
+        movdqa      xmm6,                   xmm5              ; p0
+        movdqa      xmm3,                   xmm0              ; q0
+
+        psubusb     xmm5,                   xmm3              ; p0-=q0
+        psubusb     xmm3,                   xmm6              ; q0-=p0
+
+        por         xmm5,                   xmm3              ; abs(p0 - q0)
+        paddusb     xmm5,                   xmm5              ; abs(p0-q0)*2
+        paddusb     xmm5,                   xmm2              ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        mov         rdx,                    arg(2) ;flimit            ; get flimit
+        movdqa      xmm2,                   XMMWORD PTR [rdx]             ;
+        paddb       xmm2,                   xmm2              ; flimit*2 (less than 255)
+        paddb       xmm7,                   xmm2              ; flimit * 2 + limit (less than 255)
+
+        psubusb     xmm5,                   xmm7              ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         xmm1,                   xmm5
+        pxor        xmm5,                   xmm5
+        pcmpeqb     xmm1,                   xmm5               ; mask mm1
+        ; mm1 = mask, mm0=q0,  mm7 = flimit, t0 = abs(q0-q1) t1 = abs(p1-p0)
+        ; mm6 = p0,
+
+        ; calculate high edge variance
+        mov         rdx,                    arg(4) ;thresh            ; get thresh
+        movdqa      xmm7,                   XMMWORD PTR [rdx]             ;
+
+        movdqa      xmm4,                   t0                ; get abs (q1 - q0)
+        psubusb     xmm4,                   xmm7
+
+        movdqa      xmm3,                   t1                ; get abs (p1 - p0)
+        psubusb     xmm3,                   xmm7
+
+        paddb       xmm4,                   xmm3              ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+        pcmpeqb     xmm4,                   xmm5
+
+        pcmpeqb     xmm5,                   xmm5
+        pxor        xmm4,                   xmm5
+        ; mm1 = mask, mm0=q0,  mm7 = thresh, t0 = abs(q0-q1) t1 = abs(p1-p0)
+        ; mm6 = p0, mm4=hev
+        ; start work on filters
+        movdqa      xmm2,                   XMMWORD PTR [rsi+2*rax]   ; p1
+        movdqa      xmm7,                   XMMWORD PTR [rdi]             ; q1
+
+        pxor        xmm2,                   [t80 GLOBAL]  ; p1 offset to convert to signed values
+        pxor        xmm7,                   [t80 GLOBAL]  ; q1 offset to convert to signed values
+
+        psubsb      xmm2,                   xmm7              ; p1 - q1
+        pxor        xmm6,                   [t80 GLOBAL]  ; offset to convert to signed values
+
+        pxor        xmm0,                   [t80 GLOBAL]  ; offset to convert to signed values
+        movdqa      xmm3,                   xmm0              ; q0
+
+        psubsb      xmm0,                   xmm6              ; q0 - p0
+        paddsb      xmm2,                   xmm0              ; 1 * (q0 - p0) + (p1 - q1)
+
+        paddsb      xmm2,                   xmm0              ; 2 * (q0 - p0)
+        paddsb      xmm2,                   xmm0              ; 3 * (q0 - p0) + (p1 - q1)
+
+        pand        xmm1,                   xmm2              ; mask filter values we don't care about
+        ; mm1 = vp8_filter, mm4=hev, mm6=ps0, mm3=qs0
+        movdqa      xmm2,                   xmm1              ; vp8_filter
+        pand        xmm2,                   xmm4;             ; Filter2 = vp8_filter & hev
+
+
+        movdqa      xmm5,                   xmm2          ;
+        paddsb      xmm5,                   [t3 GLOBAL];
+
+        pxor        xmm0,                   xmm0              ; 0
+        pxor        xmm7,                   xmm7              ; 0
+
+        punpcklbw   xmm0,                   xmm5              ; e0f0g0h0
+        psraw       xmm0,                   11                ; sign extended shift right by 3
+
+        punpckhbw   xmm7,                   xmm5              ; a0b0c0d0
+        psraw       xmm7,                   11                ; sign extended shift right by 3
+
+        packsswb    xmm0,                   xmm7              ; Filter2 >>=3;
+        movdqa      xmm5,                   xmm0              ; Filter2
+
+        paddsb      xmm2,                   [t4 GLOBAL]      ; vp8_signed_char_clamp(Filter2 + 4)
+        pxor        xmm0,                   xmm0              ; 0
+
+        pxor        xmm7,                   xmm7              ; 0
+        punpcklbw   xmm0,                   xmm2              ; e0f0g0h0
+
+        psraw       xmm0,                   11                ; sign extended shift right by 3
+        punpckhbw   xmm7,                   xmm2              ; a0b0c0d0
+
+        psraw       xmm7,                   11                ; sign extended shift right by 3
+        packsswb    xmm0,                   xmm7              ; Filter2 >>=3;
+
+        ; mm0= filter2 mm1 = vp8_filter,  mm3 =qs0 mm5=s mm4 =hev mm6=ps0
+        psubsb      xmm3,                   xmm0              ; qs0 =qs0 - filter1
+        paddsb      xmm6,                   xmm5              ; ps0 =ps0 + Fitler2
+
+        ; mm1=vp8_filter, mm3=qs0, mm4 =hev mm6=ps0
+        ; vp8_filter &= ~hev;
+        ; Filter2 = vp8_filter;
+        pandn       xmm4,                   xmm1              ; vp8_filter&=~hev
+
+
+        ; mm3=qs0, mm4=filter2, mm6=ps0
+
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7);
+        ; s = vp8_signed_char_clamp(qs0 - u);
+        ; *oq0 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps0 + u);
+        ; *op0 = s^0x80;
+        pxor        xmm0,                   xmm0
+        pxor        xmm1,                   xmm1
+
+        pxor        xmm2,                   xmm2
+        punpcklbw   xmm1,                   xmm4
+
+        punpckhbw   xmm2,                   xmm4
+        pmulhw      xmm1,                   [s27 GLOBAL]
+
+        pmulhw      xmm2,                   [s27 GLOBAL]
+        paddw       xmm1,                   [s63 GLOBAL]
+
+        paddw       xmm2,                   [s63 GLOBAL]
+        psraw       xmm1,                   7
+
+        psraw       xmm2,                   7
+        packsswb    xmm1,                   xmm2
+
+        psubsb      xmm3,                   xmm1
+        paddsb      xmm6,                   xmm1
+
+        pxor        xmm3,                   [t80 GLOBAL]
+        pxor        xmm6,                   [t80 GLOBAL]
+
+        movdqa      XMMWORD PTR [rsi+rax],  xmm6
+        movdqa      XMMWORD PTR [rsi],      xmm3
+
+        ; roughly 2/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7);
+        ; s = vp8_signed_char_clamp(qs1 - u);
+        ; *oq1 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps1 + u);
+        ; *op1 = s^0x80;
+        pxor        xmm1,                   xmm1
+        pxor        xmm2,                   xmm2
+
+        punpcklbw   xmm1,                   xmm4
+        punpckhbw   xmm2,                   xmm4
+
+        pmulhw      xmm1,                   [s18 GLOBAL]
+        pmulhw      xmm2,                   [s18 GLOBAL]
+
+        paddw       xmm1,                   [s63 GLOBAL]
+        paddw       xmm2,                   [s63 GLOBAL]
+
+        psraw       xmm1,                   7
+        psraw       xmm2,                   7
+
+        packsswb    xmm1,                   xmm2
+
+        movdqa      xmm3,                   XMMWORD PTR [rdi]
+        movdqa      xmm6,                   XMMWORD PTR [rsi+rax*2]       ; p1
+
+        pxor        xmm3,                   [t80 GLOBAL]
+        pxor        xmm6,                   [t80 GLOBAL]
+
+        paddsb      xmm6,                   xmm1
+        psubsb      xmm3,                   xmm1
+
+        pxor        xmm6,                   [t80 GLOBAL]
+        pxor        xmm3,                   [t80 GLOBAL]
+
+        movdqa      XMMWORD PTR [rdi],      xmm3
+        movdqa      XMMWORD PTR [rsi+rax*2],xmm6
+
+        ; roughly 1/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7);
+        ; s = vp8_signed_char_clamp(qs2 - u);
+        ; *oq2 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps2 + u);
+        ; *op2 = s^0x80;
+        pxor        xmm1,                   xmm1
+        pxor        xmm2,                   xmm2
+
+        punpcklbw   xmm1,                   xmm4
+        punpckhbw   xmm2,                   xmm4
+
+        pmulhw      xmm1,                   [s9 GLOBAL]
+        pmulhw      xmm2,                   [s9 GLOBAL]
+
+        paddw       xmm1,                   [s63 GLOBAL]
+        paddw       xmm2,                   [s63 GLOBAL]
+
+        psraw       xmm1,                   7
+        psraw       xmm2,                   7
+
+        packsswb    xmm1,                   xmm2
+
+
+        movdqa      xmm6,                   XMMWORD PTR [rdi+rax*4]
+        neg         rax
+
+        movdqa      xmm3,                   XMMWORD PTR [rdi+rax  ]
+
+        pxor        xmm6,                   [t80 GLOBAL]
+        pxor        xmm3,                   [t80 GLOBAL]
+
+        paddsb      xmm6,                   xmm1
+        psubsb      xmm3,                   xmm1
+
+        pxor        xmm6,                   [t80 GLOBAL]
+        pxor        xmm3,                   [t80 GLOBAL]
+
+        movdqa      XMMWORD PTR [rdi+rax  ], xmm3
+        neg         rax
+
+        movdqa      XMMWORD PTR [rdi+rax*4], xmm6
+
+    add rsp, 32
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_mbloop_filter_vertical_edge_sse2
+;(
+;    unsigned char *src_ptr,
+;    int            src_pixel_step,
+;    const char    *flimit,
+;    const char    *limit,
+;    const char    *thresh,
+;    int            count
+;)
+global sym(vp8_mbloop_filter_vertical_edge_sse2)
+sym(vp8_mbloop_filter_vertical_edge_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub          rsp, 160     ; reserve 160 bytes
+    %define t0   [rsp + 0]    ;__declspec(align(16)) char t0[16];
+    %define t1   [rsp + 16]   ;__declspec(align(16)) char t1[16];
+    %define srct [rsp + 32]   ;__declspec(align(16)) char srct[128];
+
+
+        mov         rsi,                arg(0) ;src_ptr
+        movsxd      rax,                dword ptr arg(1) ;src_pixel_step                    ; destination pitch?
+
+        lea         rsi,                [rsi + rax*4 - 4]
+        lea         rdi,                [rsi + rax]                     ; rdi points to row +1 for indirect addressing
+
+        mov         rcx,                rax
+        neg         rcx
+
+        ; Transpose
+        movq        xmm0,               QWORD PTR [rdi+rax*2]           ; xx xx xx xx xx xx xx xx 77 76 75 74 73 72 71 70
+        movq        xmm7,               QWORD PTR [rsi+rax*2]           ; xx xx xx xx xx xx xx xx 67 66 65 64 63 62 61 60
+
+        punpcklbw   xmm7,               xmm0                            ; 77 67 76 66 75 65 74 64 73 63 72 62 71 61 70 60
+        movq        xmm0,               QWORD PTR [rsi+rax]             ;
+
+        movq        xmm5,               QWORD PTR [rsi]                 ;
+        punpcklbw   xmm5,               xmm0                            ; 57 47 56 46 55 45 54 44 53 43 52 42 51 41 50 40
+
+        movdqa      xmm6,               xmm5                            ; 57 47 56 46 55 45 54 44 53 43 52 42 51 41 50 40
+        punpcklwd   xmm5,               xmm7                            ; 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40
+
+        punpckhwd   xmm6,               xmm7                            ; 77 67 57 47 76 66 56 46 75 65 55 45 74 64 54 44
+        movq        xmm7,               QWORD PTR [rsi + rcx]           ; xx xx xx xx xx xx xx xx 37 36 35 34 33 32 31 30
+
+        movq        xmm0,               QWORD PTR [rsi + rcx*2]         ; xx xx xx xx xx xx xx xx 27 26 25 24 23 22 21 20
+        punpcklbw   xmm0,               xmm7                            ; 37 27 36 36 35 25 34 24 33 23 32 22 31 21 30 20
+
+        movq        xmm4,               QWORD PTR [rsi + rcx*4]         ; xx xx xx xx xx xx xx xx 07 06 05 04 03 02 01 00
+        movq        xmm7,               QWORD PTR [rdi + rcx*4]         ; xx xx xx xx xx xx xx xx 17 16 15 14 13 12 11 10
+
+        punpcklbw   xmm4,               xmm7                            ; 17 07 16 06 15 05 14 04 13 03 12 02 11 01 10 00
+        movdqa      xmm3,               xmm4                            ; 17 07 16 06 15 05 14 04 13 03 12 02 11 01 10 00
+
+        punpcklwd   xmm3,               xmm0                            ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+        punpckhwd   xmm4,               xmm0                            ; 37 27 17 07 36 26 16 06 35 25 15 05 34 24 14 04
+
+        movdqa      xmm7,               xmm4                            ; 37 27 17 07 36 26 16 06 35 25 15 05 34 24 14 04
+        movdqa      xmm2,               xmm3                            ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+
+        punpckhdq   xmm7,               xmm6                            ; 77 67 57 47 37 27 17 07 76 66 56 46 36 26 16 06
+        punpckldq   xmm4,               xmm6                            ; 75 65 55 45 35 25 15 05 74 64 54 44 34 24 14 04
+
+        punpckhdq   xmm3,               xmm5                            ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+        punpckldq   xmm2,               xmm5                            ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+
+        movdqa      t0,                 xmm2                            ; save to free XMM2
+        ;movdqa        t1,                 xmm3
+
+        ; XMM3 XMM4 XMM7 in use
+        lea         rsi,                [rsi+rax*8]
+        lea         rdi,                [rdi+rax*8]
+
+        movq        xmm6,               QWORD PTR [rdi+rax*2]           ; xx xx xx xx xx xx xx xx f7 f6 f5 f4 f3 f2 f1 f0
+        movq        xmm5,               QWORD PTR [rsi+rax*2]           ; xx xx xx xx xx xx xx xx e7 e6 e5 e4 e3 e2 e1 e0
+
+        punpcklbw   xmm5,               xmm6                            ; f7 e7 f6 e6 f5 e5 f4 e4 f3 e3 f2 e2 f1 e1 f0 e0
+        movq        xmm6,               QWORD PTR [rsi+rax]             ; xx xx xx xx xx xx xx xx d7 d6 d5 d4 d3 d2 d1 d0
+
+        movq        xmm1,               QWORD PTR [rsi]                 ; xx xx xx xx xx xx xx xx c7 c6 c5 c4 c3 c2 c1 c0
+        punpcklbw   xmm1,               xmm6                            ; d7 c7 d6 c6 d5 c5 d4 c4 d3 c3 d2 c2 d1 e1 d0 c0
+
+        movdqa      xmm6,               xmm1                            ;
+        punpckhwd   xmm6,               xmm5                            ; f7 e7 d7 c7 f6 e6 d6 c6 f5 e5 d5 c5 f4 e4 d4 c4
+
+        punpcklwd   xmm1,               xmm5                            ; f3 e3 d3 c3 f2 e2 d2 c2 f1 e1 d1 c1 f0 e0 d0 c0
+        movq        xmm5,               QWORD PTR [rsi+rcx]             ; xx xx xx xx xx xx xx xx b7 b6 b5 b4 b3 b2 b1 b0
+
+        movq        xmm0,               QWORD PTR [rsi+rcx*2]           ; xx xx xx xx xx xx xx xx a7 a6 a5 a4 a3 a2 a1 a0
+        punpcklbw   xmm0,               xmm5                            ; b7 a7 b6 a6 b5 a5 b4 a4 b3 a3 b2 a2 b1 a1 b0 a0
+
+        movq        xmm2,               QWORD PTR [rsi+rcx*4]           ; xx xx xx xx xx xx xx xx 87 86 85 84 83 82 81 80
+        movq        xmm5,               QWORD PTR [rdi+rcx*4]           ; xx xx xx xx xx xx xx xx 97 96 95 94 93 92 91 90
+
+        punpcklbw   xmm2,               xmm5                            ; 97 87 96 86 95 85 94 84 93 83 92 82 91 81 90 80
+        movdqa      xmm5,               xmm2                            ; 97 87 96 86 95 85 94 84 93 83 92 82 91 81 90 80
+
+        punpcklwd   xmm5,               xmm0                            ; b3 a3 93 83 b2 a2 92 82 b1 a1 91 81 b0 a0 90 80
+        punpckhwd   xmm2,               xmm0                            ; b7 a7 97 87 b6 a6 96 86 b5 a5 95 85 b4 a4 94 84
+
+        movdqa      xmm0,               xmm5
+        punpckldq   xmm0,               xmm1                            ; f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
+
+
+        punpckhdq   xmm5,               xmm1                            ; f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
+        movdqa      xmm1,               xmm2                            ; b7 a7 97 87 b6 a6 96 86 b5 a5 95 85 b4 a4 94 84
+
+        punpckldq   xmm1,               xmm6                            ; f5 e5 d5 c5 b5 a5 95 85 f4 e4 d4 c4 b4 a4 94 84
+        punpckhdq   xmm2,               xmm6                            ; f7 e7 d7 c7 b7 a7 97 87 f6 e6 d6 c6 b6 a6 96 86
+
+        movdqa      xmm6,               xmm7                            ; 77 67 57 47 37 27 17 07 76 66 56 46 36 26 16 06
+        punpcklqdq  xmm6,               xmm2                            ; f6 e6 d6 c6 b6 a6 96 86 76 66 56 46 36 26 16 06
+
+
+        lea         rdx,                srct
+        punpckhqdq  xmm7,               xmm2                            ; f7 e7 d7 c7 b7 a7 97 87 77 67 57 47 37 27 17 07
+
+        movdqa      [rdx+112],          xmm7                            ; save 7
+        movdqa      xmm2,               xmm3                            ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+
+        movdqa      [rdx+96],           xmm6                            ; save 6
+        punpcklqdq  xmm2,               xmm5                            ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+
+        punpckhqdq  xmm3,               xmm5                            ; f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+        movdqa      [rdx+32],           xmm2                            ; save 2
+
+        movdqa      xmm5,               xmm4                            ; 75 65 55 45 35 25 15 05 74 64 54 44 34 24 14 04
+        punpcklqdq  xmm4,               xmm1                            ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04
+
+        movdqa      [rdx+48],           xmm3                            ; save 3
+        punpckhqdq  xmm5,               xmm1                            ; f5 e5 d5 c5 b5 a5 95 85 75 65 55 45 35 25 15 05
+
+        movdqa      [rdx+64],           xmm4                            ; save 4
+        movdqa      [rdx+80],           xmm5                            ; save 5
+
+        movdqa      xmm1,               t0                              ; get
+        movdqa      xmm2,               xmm1                            ;
+
+        punpckhqdq  xmm1,               xmm0                            ; f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+        punpcklqdq  xmm2,               xmm0                            ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+
+        movdqa      [rdx+16],           xmm1
+        movdqa      [rdx],              xmm2
+
+        movdqa      xmm0,               xmm6                            ; q2
+        psubusb     xmm0,               xmm7                            ; q2-q3
+
+        psubusb     xmm7,               xmm6                            ; q3-q2
+        por         xmm7,               xmm0                            ; abs (q3-q2)
+
+        movdqa      xmm1,               xmm5                            ; q1
+        psubusb     xmm1,               xmm6                            ; q1-q2
+
+        psubusb     xmm6,               xmm5                            ; q2-q1
+        por         xmm6,               xmm1                            ; abs (q2-q1)
+
+        ;/*
+        ;movdqa      xmm0,               xmm4                            ; q0
+        ;psubusb     xmm0                xmm5                            ; q0-q1
+        ;
+        ;pusbusb     xmm5,               xmm4                            ; q1-q0
+        ;por         xmm5,               xmm0                            ; abs (q1-q0)
+        ;*/
+
+        movdqa      xmm1,               [rdx+16]                        ; p2
+        movdqa      xmm0,               xmm1
+
+        psubusb     xmm0,               xmm2                            ; p2 - p3;
+        psubusb     xmm2,               xmm1                            ; p3 - p2;
+
+        por         xmm0,               xmm2                            ; abs(p2-p3)
+
+        movdqa      xmm2,               [rdx+32]                        ; p1
+        movdqa      xmm5,               xmm2                            ; p1
+
+        psubusb     xmm5,               xmm1                            ; p1-p2
+        psubusb     xmm1,               xmm2                            ; p2-p1
+
+        por         xmm1,               xmm5                            ; abs(p2-p1)
+        mov         rdx,                arg(3) ;limit
+
+        movdqa      xmm4,               [rdx]                           ; limit
+        psubusb     xmm7,               xmm4                            ;
+
+
+        psubusb     xmm0,               xmm4                            ; abs(p3-p2) > limit
+        psubusb     xmm1,               xmm4                            ; abs(p2-p1) > limit
+
+        psubusb     xmm6,               xmm4                            ; abs(q2-q1) > limit
+        por         xmm7,               xmm6                            ; or
+
+        por         xmm0,               xmm1                            ;
+        por         xmm0,               xmm7                            ; abs(q3-q2) > limit || abs(p3-p2) > limit ||abs(p2-p1) > limit || abs(q2-q1) > limit
+
+        movdqa      xmm1,               xmm2                            ; p1
+
+        movdqa      xmm7,               xmm3                            ; p0
+        psubusb     xmm7,               xmm2                            ; p0-p1
+
+        psubusb     xmm2,               xmm3                            ; p1-p0
+        por         xmm2,               xmm7                            ; abs(p1-p0)
+
+        movdqa      t0,                 xmm2                            ; save abs(p1-p0)
+        lea         rdx,                srct
+
+        psubusb     xmm2,               xmm4                            ; abs(p1-p0)>limit
+        por         xmm0,               xmm2                            ; mask
+
+        movdqa      xmm5,               [rdx+64]                        ; q0
+        movdqa      xmm7,               [rdx+80]                        ; q1
+
+        movdqa      xmm6,               xmm5                            ; q0
+        movdqa      xmm2,               xmm7                            ; q1
+        psubusb     xmm5,               xmm7                            ; q0-q1
+
+        psubusb     xmm7,               xmm6                            ; q1-q0
+        por         xmm7,               xmm5                            ; abs(q1-q0)
+
+        movdqa      t1,                 xmm7                            ; save abs(q1-q0)
+        psubusb     xmm7,               xmm4                            ; abs(q1-q0)> limit
+
+        por         xmm0,               xmm7                            ; mask
+
+        movdqa      xmm5,                xmm2                           ; q1
+        psubusb     xmm5,                xmm1                           ; q1-=p1
+        psubusb     xmm1,                xmm2                           ; p1-=q1
+        por         xmm5,                xmm1                           ; abs(p1-q1)
+        pand        xmm5,                [tfe GLOBAL]                   ; set lsb of each byte to zero
+        psrlw       xmm5,                1                              ; abs(p1-q1)/2
+
+        mov         rdx,                arg(2) ;flimit                          ;
+        movdqa      xmm2,               [rdx]                           ; flimit
+
+        movdqa      xmm1,               xmm3                            ; p0
+        movdqa      xmm7,               xmm6                            ; q0
+        psubusb     xmm1,               xmm7                            ; p0-q0
+        psubusb     xmm7,               xmm3                            ; q0-p0
+        por         xmm1,               xmm7                            ; abs(q0-p0)
+        paddusb     xmm1,               xmm1                            ; abs(q0-p0)*2
+        paddusb     xmm1,               xmm5                            ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        paddb       xmm2,               xmm2                            ; flimit*2 (less than 255)
+        paddb       xmm4,               xmm2                            ; flimit * 2 + limit (less than 255)
+
+        psubusb     xmm1,               xmm4                            ; abs (p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        por         xmm1,               xmm0;                           ; mask
+        pxor        xmm0,               xmm0
+        pcmpeqb     xmm1,               xmm0
+
+        ; calculate high edge variance
+        mov         rdx,                arg(4) ;thresh                          ; get thresh
+        movdqa      xmm7,               [rdx]
+
+        movdqa      xmm4,               t0                              ; get abs (q1 - q0)
+        psubusb     xmm4,               xmm7                            ; abs(q1 - q0) > thresh
+
+        movdqa      xmm3,               t1                              ; get abs (p1 - p0)
+        psubusb     xmm3,               xmm7                            ; abs(p1 - p0)> thresh
+
+        por         xmm4,               xmm3                            ; abs(q1 - q0) > thresh || abs(p1 - p0) > thresh
+        pcmpeqb     xmm4,               xmm0
+
+        pcmpeqb     xmm0,               xmm0
+        pxor        xmm4,               xmm0
+
+
+        ; start work on filters
+        lea         rdx,                srct
+
+        ; start work on filters
+        movdqa      xmm2,               [rdx+32]                        ; p1
+        movdqa      xmm7,               [rdx+80]                        ; q1
+
+        pxor        xmm2,               [t80 GLOBAL]                    ; p1 offset to convert to signed values
+        pxor        xmm7,               [t80 GLOBAL]                    ; q1 offset to convert to signed values
+
+        psubsb      xmm2,               xmm7                            ; p1 - q1
+        movdqa      xmm6,               [rdx+48]                        ; p0
+
+        movdqa      xmm0,               [rdx+64]                        ; q0
+        pxor        xmm6,               [t80 GLOBAL]                    ; offset to convert to signed values
+
+        pxor        xmm0,               [t80 GLOBAL]                    ; offset to convert to signed values
+        movdqa      xmm3,               xmm0                            ; q0
+
+        psubsb      xmm0,               xmm6                            ; q0 - p0
+        paddsb      xmm2,               xmm0                            ; 1 * (q0 - p0) + (p1 - q1)
+
+        paddsb      xmm2,               xmm0                            ; 2 * (q0 - p0)
+        paddsb      xmm2,               xmm0                            ; 3 * (q0 - p0)+ (p1 - q1)
+
+        pand        xmm1,               xmm2                            ; mask filter values we don't care about
+
+        ; xmm1 = vp8_filter, xmm4=hev, xmm6=ps0, xmm3=qs0
+        movdqa      xmm2,               xmm1                            ; vp8_filter
+        pand        xmm2,               xmm4;                           ; Filter2 = vp8_filter & hev
+
+        movdqa      xmm5,               xmm2
+        paddsb      xmm5,               [t3 GLOBAL]
+
+        pxor        xmm0,               xmm0                            ; 0
+        pxor        xmm7,               xmm7                            ; 0
+
+        punpcklbw   xmm0,               xmm5                            ; e0f0g0h0
+        psraw       xmm0,               11                              ; sign extended shift right by 3
+
+        punpckhbw   xmm7,               xmm5                            ; a0b0c0d0
+        psraw       xmm7,               11                              ; sign extended shift right by 3
+
+        packsswb    xmm0,               xmm7                            ; Filter2 >>=3;
+        movdqa      xmm5,               xmm0                            ; Filter2
+
+        paddsb      xmm2,               [t4 GLOBAL]                     ; vp8_signed_char_clamp(Filter2 + 4)
+        pxor        xmm0,               xmm0                            ; 0
+
+        pxor        xmm7,               xmm7                            ; 0
+        punpcklbw   xmm0,               xmm2                            ; e0f0g0h0
+
+        psraw       xmm0,               11                              ; sign extended shift right by 3
+        punpckhbw   xmm7,               xmm2                            ; a0b0c0d0
+
+        psraw       xmm7,               11                              ; sign extended shift right by 3
+        packsswb    xmm0,               xmm7                            ; Filter2 >>=3;
+
+        ; xmm0= filter2 xmm1 = vp8_filter,  xmm3 =qs0 xmm5=s xmm4 =hev xmm6=ps0
+        psubsb      xmm3,               xmm0                            ; qs0 =qs0 - filter1
+        paddsb      xmm6,               xmm5                            ; ps0 =ps0 + Fitler2
+
+
+        ; xmm1=vp8_filter, xmm3=qs0, xmm4 =hev xmm6=ps0
+        ; vp8_filter &= ~hev;
+        ; Filter2 = vp8_filter;
+        pandn       xmm4,                   xmm1                        ; vp8_filter&=~hev
+
+        ; xmm3=qs0, xmm4=filter2, xmm6=ps0
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7);
+        ; s = vp8_signed_char_clamp(qs0 - u);
+        ; *oq0 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps0 + u);
+        ; *op0 = s^0x80;
+        pxor        xmm0,                   xmm0
+        pxor        xmm1,                   xmm1
+
+        pxor        xmm2,                   xmm2
+        punpcklbw   xmm1,                   xmm4
+
+        punpckhbw   xmm2,                   xmm4
+        pmulhw      xmm1,                   [s27 GLOBAL]
+
+        pmulhw      xmm2,                   [s27 GLOBAL]
+        paddw       xmm1,                   [s63 GLOBAL]
+
+        paddw       xmm2,                   [s63 GLOBAL]
+        psraw       xmm1,                   7
+
+        psraw       xmm2,                   7
+        packsswb    xmm1,                   xmm2
+
+        psubsb      xmm3,                   xmm1
+        paddsb      xmm6,                   xmm1
+
+        pxor        xmm3,                   [t80 GLOBAL]
+        pxor        xmm6,                   [t80 GLOBAL]
+
+        movdqa      [rdx+48],               xmm6
+        movdqa      [rdx+64],               xmm3
+
+        ; roughly 2/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7);
+        ; s = vp8_signed_char_clamp(qs1 - u);
+        ; *oq1 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps1 + u);
+        ; *op1 = s^0x80;
+        pxor        xmm1,                       xmm1
+        pxor        xmm2,                       xmm2
+
+        punpcklbw   xmm1,                       xmm4
+        punpckhbw   xmm2,                       xmm4
+
+        pmulhw      xmm1,                       [s18 GLOBAL]
+        pmulhw      xmm2,                       [s18 GLOBAL]
+
+        paddw       xmm1,                       [s63 GLOBAL]
+        paddw       xmm2,                       [s63 GLOBAL]
+
+        psraw       xmm1,                       7
+        psraw       xmm2,                       7
+
+        packsswb    xmm1,                       xmm2
+
+        movdqa      xmm3,                       [rdx + 80]              ;/q1
+        movdqa      xmm6,                       [rdx + 32]              ; p1
+
+        pxor        xmm3,                       [t80 GLOBAL]
+        pxor        xmm6,                       [t80 GLOBAL]
+
+        paddsb      xmm6,                       xmm1
+        psubsb      xmm3,                       xmm1
+
+        pxor        xmm6,                       [t80 GLOBAL]
+        pxor        xmm3,                       [t80 GLOBAL]
+
+        movdqa      [rdx + 80],                 xmm3
+        movdqa      [rdx + 32],                 xmm6
+
+
+        ; roughly 1/7th difference across boundary
+        ; u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7);
+        ; s = vp8_signed_char_clamp(qs2 - u);
+        ; *oq2 = s^0x80;
+        ; s = vp8_signed_char_clamp(ps2 + u);
+        ; *op2 = s^0x80;
+        pxor        xmm1,                       xmm1
+        pxor        xmm2,                       xmm2
+
+        punpcklbw   xmm1,                       xmm4
+        punpckhbw   xmm2,                       xmm4
+
+        pmulhw      xmm1,                       [s9 GLOBAL]
+        pmulhw      xmm2,                       [s9 GLOBAL]
+
+        paddw       xmm1,                       [s63 GLOBAL]
+        paddw       xmm2,                       [s63 GLOBAL]
+
+        psraw       xmm1,                       7
+        psraw       xmm2,                       7
+
+        packsswb    xmm1,                       xmm2
+
+        movdqa      xmm6,                       [rdx+16]
+        movdqa      xmm3,                       [rdx+96]
+
+        pxor        xmm6,                       [t80 GLOBAL]
+        pxor        xmm3,                       [t80 GLOBAL]
+
+        paddsb      xmm6,                       xmm1
+        psubsb      xmm3,                       xmm1
+
+        pxor        xmm6,                       [t80 GLOBAL]        ; xmm6 = f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+        pxor        xmm3,                       [t80 GLOBAL]        ; xmm3 = f6 e6 d6 c6 b6 a6 96 86 76 66 56 46 36 26 15 06
+
+
+        ; transpose and write back
+        movdqa      xmm0,                       [rdx]               ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+        movdqa      xmm1,                       xmm0                ; f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+
+        punpcklbw   xmm0,                       xmm6                ; 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
+        punpckhbw   xmm1,                       xmm6                ; f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80
+
+        movdqa      xmm2,                       [rdx+32]            ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+        movdqa      xmm6,                       xmm2                ; f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+
+        punpcklbw   xmm2,                       [rdx+48]            ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
+        punpckhbw   xmm6,                       [rdx+48]            ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+
+        movdqa      xmm5,                       xmm0                ; 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
+        punpcklwd   xmm0,                       xmm2                ; 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00
+
+        punpckhwd   xmm5,                       xmm2                ; 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40
+        movdqa      xmm4,                       xmm1                ; f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80
+
+        punpcklwd   xmm1,                       xmm6                ; b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80
+        punpckhwd   xmm4,                       xmm6                ; f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0
+
+        movdqa      xmm2,                       [rdx+64]            ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04
+        punpcklbw   xmm2,                       [rdx+80]            ; 75 74 65 64 55 54 45 44 35 34 25 24 15 14 05 04
+
+        movdqa      xmm6,                       xmm3                ; f6 e6 d6 c6 b6 a6 96 86 76 66 56 46 36 26 16 06
+        punpcklbw   xmm6,                       [rdx+112]           ; 77 76 67 66 57 56 47 46 37 36 27 26 17 16 07 06
+
+        movdqa      xmm7,                       xmm2                ; 75 74 65 64 55 54 45 44 35 34 25 24 15 14 05 04
+        punpcklwd   xmm2,                       xmm6                ; 37 36 35 34 27 26 25 24 17 16 15 14 07 06 05 04
+
+        punpckhwd   xmm7,                       xmm6                ; 77 76 75 74 67 66 65 64 57 56 55 54 47 46 45 44
+        movdqa      xmm6,                       xmm0                ; 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00
+
+        punpckldq   xmm0,                       xmm2                ; 17 16 15 14 13 12 11 10 07 06 05 04 03 02 01 00
+        punpckhdq   xmm6,                       xmm2                ; 37 36 35 34 33 32 31 30 27 26 25 24 23 22 21 20
+
+        lea         rsi,                        [rsi+rcx*8]
+        lea         rdi,                        [rdi+rcx*8]
+
+        movq        QWORD PTR [rsi+rcx*4],      xmm0
+        psrldq      xmm0,                       8
+
+        movq        QWORD PTR [rsi+rcx*2],      xmm6
+        psrldq      xmm6,                       8
+
+        movq        QWORD PTR [rdi+rcx*4],      xmm0
+        movq        QWORD PTR [rsi+rcx],        xmm6
+
+        movdqa      xmm0,                       xmm5                ; 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40
+        punpckldq   xmm0,                       xmm7                ; 57 56 55 54 53 52 51 50 47 46 45 44 43 42 41 40
+
+        punpckhdq   xmm5,                       xmm7                ; 77 76 75 74 73 72 71 70 67 66 65 64 63 62 61 60
+
+        movq        QWORD PTR [rsi],            xmm0
+        psrldq      xmm0,                       8
+
+        movq        QWORD PTR [rsi+rax*2],      xmm5
+        psrldq      xmm5,                       8
+
+        movq        QWORD PTR [rsi+rax],        xmm0
+        movq        QWORD PTR [rdi+rax*2],      xmm5
+
+        movdqa      xmm2,                       [rdx+64]            ; f4 e4 d4 c4 b4 a4 94 84 74 64 54 44 34 24 14 04
+        punpckhbw   xmm2,                       [rdx+80]            ; f5 f4 e5 e4 d5 d4 c5 c4 b5 b4 a5 a4 95 94 85 84
+
+        punpckhbw   xmm3,                       [rdx+112]           ; f7 f6 e7 e6 d7 d6 c7 c6 b7 b6 a7 a6 97 96 87 86
+        movdqa      xmm0,                       xmm2
+
+        punpcklwd   xmm0,                       xmm3                ; b7 b6 b4 b4 a7 a6 a5 a4 97 96 95 94 87 86 85 84
+        punpckhwd   xmm2,                       xmm3                ; f7 f6 f5 f4 e7 e6 e5 e4 d7 d6 d5 d4 c7 c6 c5 c4
+
+        movdqa      xmm3,                       xmm1                ; b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80
+        punpckldq   xmm1,                       xmm0                ; 97 96 95 94 93 92 91 90 87 86 85 83 84 82 81 80
+
+        punpckhdq   xmm3,                       xmm0                ; b7 b6 b5 b4 b3 b2 b1 b0 a7 a6 a5 a4 a3 a2 a1 a0
+
+        lea         rsi,                        [rsi+rax*8]
+        lea         rdi,                        [rdi+rax*8]
+
+        movq        QWORD PTR [rsi+rcx*4],      xmm1
+        psrldq      xmm1,                       8
+
+        movq        QWORD PTR [rsi+rcx*2],      xmm3
+        psrldq      xmm3,                       8
+
+        movq        QWORD PTR [rdi+rcx*4],      xmm1
+        movq        QWORD PTR [rsi+rcx],        xmm3
+
+        movdqa      xmm1,                       xmm4                ; f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0
+        punpckldq   xmm1,                       xmm2                ; d7 d6 d5 d4 d3 d2 d1 d0 c7 c6 c5 c4 c3 c2 c1 c0
+
+        punpckhdq   xmm4,                       xmm2                ; f7 f6 f4 f4 f3 f2 f1 f0 e7 e6 e5 e4 e3 e2 e1 e0
+        movq        QWORD PTR [rsi],            xmm1
+
+        psrldq      xmm1,                       8
+
+        movq        QWORD PTR [rsi+rax*2],      xmm4
+        psrldq      xmm4,                       8
+
+        movq        QWORD PTR [rsi+rax],        xmm1
+        movq        QWORD PTR [rdi+rax*2],      xmm4
+
+    add rsp, 160
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_loop_filter_simple_horizontal_edge_sse2
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_loop_filter_simple_horizontal_edge_sse2)
+sym(vp8_loop_filter_simple_horizontal_edge_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi, arg(0)             ;src_ptr
+        movsxd      rax, dword ptr arg(1)   ;src_pixel_step     ; destination pitch?
+        mov         rdx, arg(2) ;flimit     ; get flimit
+        movdqa      xmm3, XMMWORD PTR [rdx]
+        mov         rdx, arg(3) ;limit
+        movdqa      xmm7, XMMWORD PTR [rdx]
+
+        paddb       xmm3, xmm3              ; flimit*2 (less than 255)
+        paddb       xmm3, xmm7              ; flimit * 2 + limit (less than 255)
+
+        mov         rdi, rsi                ; rdi points to row +1 for indirect addressing
+        add         rdi, rax
+        neg         rax
+
+        ; calculate mask
+        movdqu      xmm1, [rsi+2*rax]       ; p1
+        movdqu      xmm0, [rdi]             ; q1
+        movdqa      xmm2, xmm1
+        movdqa      xmm7, xmm0
+        movdqa      xmm4, xmm0
+        psubusb     xmm0, xmm1              ; q1-=p1
+        psubusb     xmm1, xmm4              ; p1-=q1
+        por         xmm1, xmm0              ; abs(p1-q1)
+        pand        xmm1, [tfe GLOBAL]      ; set lsb of each byte to zero
+        psrlw       xmm1, 1                 ; abs(p1-q1)/2
+
+        movdqu      xmm5, [rsi+rax]         ; p0
+        movdqu      xmm4, [rsi]             ; q0
+        movdqa      xmm0, xmm4              ; q0
+        movdqa      xmm6, xmm5              ; p0
+        psubusb     xmm5, xmm4              ; p0-=q0
+        psubusb     xmm4, xmm6              ; q0-=p0
+        por         xmm5, xmm4              ; abs(p0 - q0)
+        paddusb     xmm5, xmm5              ; abs(p0-q0)*2
+        paddusb     xmm5, xmm1              ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        psubusb     xmm5, xmm3              ; abs(p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        pxor        xmm3, xmm3
+        pcmpeqb     xmm5, xmm3
+
+        ; start work on filters
+        pxor        xmm2, [t80 GLOBAL]      ; p1 offset to convert to signed values
+        pxor        xmm7, [t80 GLOBAL]      ; q1 offset to convert to signed values
+        psubsb      xmm2, xmm7              ; p1 - q1
+
+        pxor        xmm6, [t80 GLOBAL]      ; offset to convert to signed values
+        pxor        xmm0, [t80 GLOBAL]      ; offset to convert to signed values
+        movdqa      xmm3, xmm0              ; q0
+        psubsb      xmm0, xmm6              ; q0 - p0
+        paddsb      xmm2, xmm0              ; p1 - q1 + 1 * (q0 - p0)
+        paddsb      xmm2, xmm0              ; p1 - q1 + 2 * (q0 - p0)
+        paddsb      xmm2, xmm0              ; p1 - q1 + 3 * (q0 - p0)
+        pand        xmm5, xmm2              ; mask filter values we don't care about
+
+        ; do + 4 side
+        paddsb      xmm5, [t4 GLOBAL]       ; 3* (q0 - p0) + (p1 - q1) + 4
+
+        movdqa      xmm0, xmm5              ; get a copy of filters
+        psllw       xmm0, 8                 ; shift left 8
+        psraw       xmm0, 3                 ; arithmetic shift right 11
+        psrlw       xmm0, 8
+        movdqa      xmm1, xmm5              ; get a copy of filters
+        psraw       xmm1, 11                ; arithmetic shift right 11
+        psllw       xmm1, 8                 ; shift left 8 to put it back
+
+        por         xmm0, xmm1              ; put the two together to get result
+
+        psubsb      xmm3, xmm0              ; q0-= q0 add
+        pxor        xmm3, [t80 GLOBAL]      ; unoffset
+        movdqu      [rsi], xmm3             ; write back
+
+        ; now do +3 side
+        psubsb      xmm5, [t1s GLOBAL]      ; +3 instead of +4
+
+        movdqa      xmm0, xmm5              ; get a copy of filters
+        psllw       xmm0, 8                 ; shift left 8
+        psraw       xmm0, 3                 ; arithmetic shift right 11
+        psrlw       xmm0, 8
+        psraw       xmm5, 11                ; arithmetic shift right 11
+        psllw       xmm5, 8                 ; shift left 8 to put it back
+        por         xmm0, xmm5              ; put the two together to get result
+
+
+        paddsb      xmm6, xmm0              ; p0+= p0 add
+        pxor        xmm6, [t80 GLOBAL]      ; unoffset
+        movdqu      [rsi+rax], xmm6         ; write back
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_loop_filter_simple_vertical_edge_sse2
+;(
+;    unsigned char *src_ptr,
+;    int  src_pixel_step,
+;    const char *flimit,
+;    const char *limit,
+;    const char *thresh,
+;    int count
+;)
+global sym(vp8_loop_filter_simple_vertical_edge_sse2)
+sym(vp8_loop_filter_simple_vertical_edge_sse2):
+    push        rbp         ; save old base pointer value.
+    mov         rbp, rsp    ; set new base pointer value.
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx         ; save callee-saved reg
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 32                         ; reserve 32 bytes
+    %define t0  [rsp + 0]    ;__declspec(align(16)) char t0[16];
+    %define t1  [rsp + 16]   ;__declspec(align(16)) char t1[16];
+
+        mov         rsi, arg(0) ;src_ptr
+        movsxd      rax, dword ptr arg(1) ;src_pixel_step     ; destination pitch?
+
+        lea         rsi,        [rsi - 2 ]
+        lea         rdi,        [rsi + rax]
+        lea         rdx,        [rsi + rax*4]
+        lea         rcx,        [rdx + rax]
+
+        movdqu      xmm0,       [rsi]                   ; (high 96 bits unused) 03 02 01 00
+        movdqu      xmm1,       [rdx]                   ; (high 96 bits unused) 43 42 41 40
+        movdqu      xmm2,       [rdi]                   ; 13 12 11 10
+        movdqu      xmm3,       [rcx]                   ; 53 52 51 50
+        punpckldq   xmm0,       xmm1                    ; (high 64 bits unused) 43 42 41 40 03 02 01 00
+        punpckldq   xmm2,       xmm3                    ; 53 52 51 50 13 12 11 10
+
+        movdqu      xmm4,       [rsi + rax*2]           ; 23 22 21 20
+        movdqu      xmm5,       [rdx + rax*2]           ; 63 62 61 60
+        movdqu      xmm6,       [rdi + rax*2]           ; 33 32 31 30
+        movdqu      xmm7,       [rcx + rax*2]           ; 73 72 71 70
+        punpckldq   xmm4,       xmm5                    ; 63 62 61 60 23 22 21 20
+        punpckldq   xmm6,       xmm7                    ; 73 72 71 70 33 32 31 30
+
+        punpcklbw   xmm0,       xmm2                    ; 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
+        punpcklbw   xmm4,       xmm6                    ; 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
+
+        movdqa      xmm1,       xmm0
+        punpcklwd   xmm0,       xmm4                    ; 33 23 13 03 32 22 12 02 31 21 11 01 30 20 10 00
+        punpckhwd   xmm1,       xmm4                    ; 73 63 53 43 72 62 52 42 71 61 51 41 70 60 50 40
+
+        movdqa      xmm2,       xmm0
+        punpckldq   xmm0,       xmm1                    ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+        punpckhdq   xmm2,       xmm1                    ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+
+        movdqa      t0,         xmm0                    ; save to t0
+        movdqa      t1,         xmm2                    ; save to t1
+
+        lea         rsi,        [rsi + rax*8]
+        lea         rdi,        [rsi + rax]
+        lea         rdx,        [rsi + rax*4]
+        lea         rcx,        [rdx + rax]
+
+        movdqu      xmm4,       [rsi]                   ; 83 82 81 80
+        movdqu      xmm1,       [rdx]                   ; c3 c2 c1 c0
+        movdqu      xmm6,       [rdi]                   ; 93 92 91 90
+        movdqu      xmm3,       [rcx]                   ; d3 d2 d1 d0
+        punpckldq   xmm4,       xmm1                    ; c3 c2 c1 c0 83 82 81 80
+        punpckldq   xmm6,       xmm3                    ; d3 d2 d1 d0 93 92 91 90
+
+        movdqu      xmm0,       [rsi + rax*2]           ; a3 a2 a1 a0
+        movdqu      xmm5,       [rdx + rax*2]           ; e3 e2 e1 e0
+        movdqu      xmm2,       [rdi + rax*2]           ; b3 b2 b1 b0
+        movdqu      xmm7,       [rcx + rax*2]           ; f3 f2 f1 f0
+        punpckldq   xmm0,       xmm5                    ; e3 e2 e1 e0 a3 a2 a1 a0
+        punpckldq   xmm2,       xmm7                    ; f3 f2 f1 f0 b3 b2 b1 b0
+
+        punpcklbw   xmm4,       xmm6                    ; d3 c3 d2 c2 d1 c1 d0 c0 93 83 92 82 91 81 90 80
+        punpcklbw   xmm0,       xmm2                    ; f3 e3 f2 e2 f1 e1 f0 e0 b3 a3 b2 a2 b1 a1 b0 a0
+
+        movdqa      xmm1,       xmm4
+        punpcklwd   xmm4,       xmm0                    ; b3 a3 93 83 b2 a2 92 82 b1 a1 91 81 b0 a0 90 80
+        punpckhwd   xmm1,       xmm0                    ; f3 e3 d3 c3 f2 e2 d2 c2 f1 e1 d1 c1 f0 e0 d0 c0
+
+        movdqa      xmm6,       xmm4
+        punpckldq   xmm4,       xmm1                    ; f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
+        punpckhdq   xmm6,       xmm1                    ; f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
+
+        movdqa      xmm0,       t0                      ; 71 61 51 41 31 21 11 01 70 60 50 40 30 20 10 00
+        movdqa      xmm2,       t1                      ; 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
+        movdqa      xmm1,       xmm0
+        movdqa      xmm3,       xmm2
+
+        punpcklqdq  xmm0,       xmm4                    ; p1  f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+        punpckhqdq  xmm1,       xmm4                    ; p0  f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+        punpcklqdq  xmm2,       xmm6                    ; q0  f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+        punpckhqdq  xmm3,       xmm6                    ; q1  f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+
+        ; calculate mask
+        movdqa      xmm6,       xmm0                            ; p1
+        movdqa      xmm7,       xmm3                            ; q1
+        psubusb     xmm7,       xmm0                            ; q1-=p1
+        psubusb     xmm6,       xmm3                            ; p1-=q1
+        por         xmm6,       xmm7                            ; abs(p1-q1)
+        pand        xmm6,       [tfe GLOBAL]                    ; set lsb of each byte to zero
+        psrlw       xmm6,       1                               ; abs(p1-q1)/2
+
+        movdqa      xmm5,       xmm1                            ; p0
+        movdqa      xmm4,       xmm2                            ; q0
+        psubusb     xmm5,       xmm2                            ; p0-=q0
+        psubusb     xmm4,       xmm1                            ; q0-=p0
+        por         xmm5,       xmm4                            ; abs(p0 - q0)
+        paddusb     xmm5,       xmm5                            ; abs(p0-q0)*2
+        paddusb     xmm5,       xmm6                            ; abs (p0 - q0) *2 + abs(p1-q1)/2
+
+        mov         rdx,        arg(2)                          ;flimit
+        movdqa      xmm7, XMMWORD PTR [rdx]
+        mov         rdx,        arg(3)                          ; get limit
+        movdqa      xmm6, XMMWORD PTR [rdx]
+        paddb       xmm7,        xmm7                           ; flimit*2 (less than 255)
+        paddb       xmm7,        xmm6                           ; flimit * 2 + limit (less than 255)
+
+        psubusb     xmm5,        xmm7                           ; abs(p0 - q0) *2 + abs(p1-q1)/2  > flimit * 2 + limit
+        pxor        xmm7,        xmm7
+        pcmpeqb     xmm5,        xmm7                           ; mm5 = mask
+
+        ; start work on filters
+        movdqa        t0,        xmm0
+        movdqa        t1,        xmm3
+
+        pxor        xmm0,        [t80 GLOBAL]                   ; p1 offset to convert to signed values
+        pxor        xmm3,        [t80 GLOBAL]                   ; q1 offset to convert to signed values
+
+        psubsb      xmm0,        xmm3                           ; p1 - q1
+        movdqa      xmm6,        xmm1                           ; p0
+
+        movdqa      xmm7,        xmm2                           ; q0
+        pxor        xmm6,        [t80 GLOBAL]                   ; offset to convert to signed values
+
+        pxor        xmm7,        [t80 GLOBAL]                   ; offset to convert to signed values
+        movdqa      xmm3,        xmm7                           ; offseted ; q0
+
+        psubsb      xmm7,        xmm6                           ; q0 - p0
+        paddsb      xmm0,        xmm7                           ; p1 - q1 + 1 * (q0 - p0)
+
+        paddsb      xmm0,        xmm7                           ; p1 - q1 + 2 * (q0 - p0)
+        paddsb      xmm0,        xmm7                           ; p1 - q1 + 3 * (q0 - p0)
+
+        pand        xmm5,        xmm0                           ; mask filter values we don't care about
+
+
+        paddsb      xmm5,        [t4 GLOBAL]                    ;  3* (q0 - p0) + (p1 - q1) + 4
+
+        movdqa      xmm0,        xmm5                           ; get a copy of filters
+        psllw       xmm0,        8                              ; shift left 8
+
+        psraw       xmm0,        3                              ; arithmetic shift right 11
+        psrlw       xmm0,        8
+
+        movdqa      xmm7,        xmm5                           ; get a copy of filters
+        psraw       xmm7,        11                             ; arithmetic shift right 11
+
+        psllw       xmm7,        8                              ; shift left 8 to put it back
+        por         xmm0,        xmm7                           ; put the two together to get result
+
+        psubsb      xmm3,        xmm0                           ; q0-= q0sz add
+        pxor        xmm3,        [t80 GLOBAL]                   ; unoffset   q0
+
+        ; now do +3 side
+        psubsb      xmm5,        [t1s GLOBAL]                   ; +3 instead of +4
+        movdqa      xmm0,        xmm5                           ; get a copy of filters
+
+        psllw       xmm0,        8                              ; shift left 8
+        psraw       xmm0,        3                              ; arithmetic shift right 11
+
+        psrlw       xmm0,        8
+        psraw       xmm5,        11                             ; arithmetic shift right 11
+
+        psllw       xmm5,        8                              ; shift left 8 to put it back
+        por         xmm0,        xmm5                           ; put the two together to get result
+
+        paddsb      xmm6,        xmm0                           ; p0+= p0 add
+        pxor        xmm6,        [t80 GLOBAL]                   ; unoffset   p0
+
+        movdqa      xmm0,        t0                             ; p1
+        movdqa      xmm4,        t1                             ; q1
+
+        ; transpose back to write out
+        ; p1  f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
+        ; p0  f1 e1 d1 c1 b1 a1 91 81 71 61 51 41 31 21 11 01
+        ; q0  f2 e2 d2 c2 b2 a2 92 82 72 62 52 42 32 22 12 02
+        ; q1  f3 e3 d3 c3 b3 a3 93 83 73 63 53 43 33 23 13 03
+        movdqa      xmm1,       xmm0
+        punpcklbw   xmm0,       xmm6                               ; 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
+        punpckhbw   xmm1,       xmm6                               ; f1 f0 e1 e0 d1 d0 c1 c0 b1 b0 a1 a0 91 90 81 80
+
+        movdqa      xmm5,       xmm3
+        punpcklbw   xmm3,       xmm4                               ; 73 72 63 62 53 52 43 42 33 32 23 22 13 12 03 02
+        punpckhbw   xmm5,       xmm4                               ; f3 f2 e3 e2 d3 d2 c3 c2 b3 b2 a3 a2 93 92 83 82
+
+        movdqa      xmm2,       xmm0
+        punpcklwd   xmm0,       xmm3                               ; 33 32 31 30 23 22 21 20 13 12 11 10 03 02 01 00
+        punpckhwd   xmm2,       xmm3                               ; 73 72 71 70 63 62 61 60 53 52 51 50 43 42 41 40
+
+        movdqa      xmm3,       xmm1
+        punpcklwd   xmm1,       xmm5                               ; b3 b2 b1 b0 a3 a2 a1 a0 93 92 91 90 83 82 81 80
+        punpckhwd   xmm3,       xmm5                               ; f3 f2 f1 f0 e3 e2 e1 e0 d3 d2 d1 d0 c3 c2 c1 c0
+
+        ; write out order: xmm0 xmm2 xmm1 xmm3
+        lea         rdx,        [rsi + rax*4]
+
+        movd        [rsi],      xmm1                               ; write the second 8-line result
+        psrldq      xmm1,       4
+        movd        [rdi],      xmm1
+        psrldq      xmm1,       4
+        movd        [rsi + rax*2], xmm1
+        psrldq      xmm1,       4
+        movd        [rdi + rax*2], xmm1
+
+        movd        [rdx],      xmm3
+        psrldq      xmm3,       4
+        movd        [rcx],      xmm3
+        psrldq      xmm3,       4
+        movd        [rdx + rax*2], xmm3
+        psrldq      xmm3,       4
+        movd        [rcx + rax*2], xmm3
+
+        neg         rax
+        lea         rsi,        [rsi + rax*8]
+        neg         rax
+        lea         rdi,        [rsi + rax]
+        lea         rdx,        [rsi + rax*4]
+        lea         rcx,        [rdx + rax]
+
+        movd        [rsi],      xmm0                                ; write the first 8-line result
+        psrldq      xmm0,       4
+        movd        [rdi],      xmm0
+        psrldq      xmm0,       4
+        movd        [rsi + rax*2], xmm0
+        psrldq      xmm0,       4
+        movd        [rdi + rax*2], xmm0
+
+        movd        [rdx],      xmm2
+        psrldq      xmm2,       4
+        movd        [rcx],      xmm2
+        psrldq      xmm2,       4
+        movd        [rdx + rax*2], xmm2
+        psrldq      xmm2,       4
+        movd        [rcx + rax*2], xmm2
+
+    add rsp, 32
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+SECTION_RODATA
+align 16
+tfe:
+    times 16 db 0xfe
+align 16
+t80:
+    times 16 db 0x80
+align 16
+t1s:
+    times 16 db 0x01
+align 16
+t3:
+    times 16 db 0x03
+align 16
+t4:
+    times 16 db 0x04
+align 16
+ones:
+    times 8 dw 0x0001
+align 16
+s27:
+    times 8 dw 0x1b00
+align 16
+s18:
+    times 8 dw 0x1200
+align 16
+s9:
+    times 8 dw 0x0900
+align 16
+s63:
+    times 8 dw 0x003f
diff --git a/vp8/common/x86/loopfilter_x86.c b/vp8/common/x86/loopfilter_x86.c
new file mode 100644 (file)
index 0000000..143ee74
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "loopfilter.h"
+
+prototype_loopfilter(vp8_loop_filter_horizontal_edge_c);
+prototype_loopfilter(vp8_loop_filter_vertical_edge_c);
+prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_c);
+prototype_loopfilter(vp8_mbloop_filter_vertical_edge_c);
+prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_c);
+prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_c);
+
+prototype_loopfilter(vp8_mbloop_filter_vertical_edge_mmx);
+prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_mmx);
+prototype_loopfilter(vp8_loop_filter_vertical_edge_mmx);
+prototype_loopfilter(vp8_loop_filter_horizontal_edge_mmx);
+prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_mmx);
+prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_mmx);
+
+prototype_loopfilter(vp8_loop_filter_vertical_edge_sse2);
+prototype_loopfilter(vp8_loop_filter_horizontal_edge_sse2);
+prototype_loopfilter(vp8_mbloop_filter_vertical_edge_sse2);
+prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_sse2);
+prototype_loopfilter(vp8_loop_filter_simple_vertical_edge_sse2);
+prototype_loopfilter(vp8_loop_filter_simple_horizontal_edge_sse2);
+prototype_loopfilter(vp8_fast_loop_filter_vertical_edges_sse2);
+
+#if HAVE_MMX
+// Horizontal MB filtering
+void vp8_loop_filter_mbh_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_horizontal_edge_mmx(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_horizontal_edge_mmx(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_horizontal_edge_mmx(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+
+void vp8_loop_filter_mbhs_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+
+// Vertical MB Filtering
+void vp8_loop_filter_mbv_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_vertical_edge_mmx(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_vertical_edge_mmx(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_vertical_edge_mmx(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+
+void vp8_loop_filter_mbvs_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+
+// Horizontal B Filtering
+void vp8_loop_filter_bh_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_horizontal_edge_mmx(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_mmx(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_mmx(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_horizontal_edge_mmx(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_horizontal_edge_mmx(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+
+void vp8_loop_filter_bhs_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+
+// Vertical B Filtering
+void vp8_loop_filter_bv_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                            int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_vertical_edge_mmx(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_mmx(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_mmx(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_vertical_edge_mmx(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_vertical_edge_mmx(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+
+void vp8_loop_filter_bvs_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_mmx(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+#endif
+
+
+// Horizontal MB filtering
+#if HAVE_SSE2
+void vp8_loop_filter_mbh_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_horizontal_edge_sse2(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_horizontal_edge_mmx(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_horizontal_edge_mmx(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+
+void vp8_loop_filter_mbhs_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+
+// Vertical MB Filtering
+void vp8_loop_filter_mbv_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_mbloop_filter_vertical_edge_sse2(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+
+    if (u_ptr)
+        vp8_mbloop_filter_vertical_edge_mmx(u_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+
+    if (v_ptr)
+        vp8_mbloop_filter_vertical_edge_mmx(v_ptr, uv_stride, lfi->uvmbflim, lfi->uvlim, lfi->uvmbthr, 1);
+}
+
+
+void vp8_loop_filter_mbvs_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                               int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr, y_stride, lfi->mbflim, lfi->lim, lfi->mbthr, 2);
+}
+
+
+// Horizontal B Filtering
+void vp8_loop_filter_bh_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_horizontal_edge_mmx(u_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_horizontal_edge_mmx(v_ptr + 4 * uv_stride, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+
+void vp8_loop_filter_bhs_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+
+// Vertical B Filtering
+void vp8_loop_filter_bv_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                             int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) simpler_lpf;
+    vp8_loop_filter_vertical_edge_sse2(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_sse2(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_vertical_edge_sse2(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+
+    if (u_ptr)
+        vp8_loop_filter_vertical_edge_mmx(u_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+
+    if (v_ptr)
+        vp8_loop_filter_vertical_edge_mmx(v_ptr + 4, uv_stride, lfi->uvflim, lfi->uvlim, lfi->uvthr, 1);
+}
+
+
+void vp8_loop_filter_bvs_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
+                              int y_stride, int uv_stride, loop_filter_info *lfi, int simpler_lpf)
+{
+    (void) u_ptr;
+    (void) v_ptr;
+    (void) uv_stride;
+    (void) simpler_lpf;
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+
+#endif
+
+#if 0
+void vp8_fast_loop_filter_vertical_edges_sse(unsigned char *y_ptr,
+        int y_stride,
+        loop_filter_info *lfi)
+{
+
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 4, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 8, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+    vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 12, y_stride, lfi->flim, lfi->lim, lfi->thr, 2);
+}
+#endif
diff --git a/vp8/common/x86/loopfilter_x86.h b/vp8/common/x86/loopfilter_x86.h
new file mode 100644 (file)
index 0000000..c87f38a
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef LOOPFILTER_X86_H
+#define LOOPFILTER_X86_H
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+
+#if HAVE_MMX
+extern prototype_loopfilter_block(vp8_loop_filter_mbv_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_bv_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_mbh_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_bh_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_mbvs_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_bvs_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_mbhs_mmx);
+extern prototype_loopfilter_block(vp8_loop_filter_bhs_mmx);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_lf_normal_mb_v
+#define vp8_lf_normal_mb_v vp8_loop_filter_mbv_mmx
+
+#undef  vp8_lf_normal_b_v
+#define vp8_lf_normal_b_v vp8_loop_filter_bv_mmx
+
+#undef  vp8_lf_normal_mb_h
+#define vp8_lf_normal_mb_h vp8_loop_filter_mbh_mmx
+
+#undef  vp8_lf_normal_b_h
+#define vp8_lf_normal_b_h vp8_loop_filter_bh_mmx
+
+#undef  vp8_lf_simple_mb_v
+#define vp8_lf_simple_mb_v vp8_loop_filter_mbvs_mmx
+
+#undef  vp8_lf_simple_b_v
+#define vp8_lf_simple_b_v vp8_loop_filter_bvs_mmx
+
+#undef  vp8_lf_simple_mb_h
+#define vp8_lf_simple_mb_h vp8_loop_filter_mbhs_mmx
+
+#undef  vp8_lf_simple_b_h
+#define vp8_lf_simple_b_h vp8_loop_filter_bhs_mmx
+#endif
+#endif
+
+
+#if HAVE_SSE2
+extern prototype_loopfilter_block(vp8_loop_filter_mbv_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_bv_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_mbh_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_bh_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_mbvs_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_bvs_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_mbhs_sse2);
+extern prototype_loopfilter_block(vp8_loop_filter_bhs_sse2);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_lf_normal_mb_v
+#define vp8_lf_normal_mb_v vp8_loop_filter_mbv_sse2
+
+#undef  vp8_lf_normal_b_v
+#define vp8_lf_normal_b_v vp8_loop_filter_bv_sse2
+
+#undef  vp8_lf_normal_mb_h
+#define vp8_lf_normal_mb_h vp8_loop_filter_mbh_sse2
+
+#undef  vp8_lf_normal_b_h
+#define vp8_lf_normal_b_h vp8_loop_filter_bh_sse2
+
+#undef  vp8_lf_simple_mb_v
+#define vp8_lf_simple_mb_v vp8_loop_filter_mbvs_sse2
+
+#undef  vp8_lf_simple_b_v
+#define vp8_lf_simple_b_v vp8_loop_filter_bvs_sse2
+
+#undef  vp8_lf_simple_mb_h
+#define vp8_lf_simple_mb_h vp8_loop_filter_mbhs_sse2
+
+#undef  vp8_lf_simple_b_h
+#define vp8_lf_simple_b_h vp8_loop_filter_bhs_sse2
+#endif
+#endif
+
+
+#endif
diff --git a/vp8/common/x86/postproc_mmx.asm b/vp8/common/x86/postproc_mmx.asm
new file mode 100644 (file)
index 0000000..721c8d6
--- /dev/null
@@ -0,0 +1,533 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%define VP8_FILTER_WEIGHT 128
+%define VP8_FILTER_SHIFT  7
+
+;void vp8_post_proc_down_and_across_mmx
+;(
+;    unsigned char *src_ptr,
+;    unsigned char *dst_ptr,
+;    int src_pixels_per_line,
+;    int dst_pixels_per_line,
+;    int rows,
+;    int cols,
+;    int flimit
+;)
+global sym(vp8_post_proc_down_and_across_mmx)
+sym(vp8_post_proc_down_and_across_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+%if ABI_IS_32BIT=1 && CONFIG_PIC=1
+    ; move the global rd onto the stack, since we don't have enough registers
+    ; to do PIC addressing
+    movq        mm0, [rd GLOBAL]
+    sub         rsp, 8
+    movq        [rsp], mm0
+%define RD [rsp]
+%else
+%define RD [rd GLOBAL]
+%endif
+
+        push        rbx
+        lea         rbx, [Blur GLOBAL]
+        movd        mm2, dword ptr arg(6) ;flimit
+        punpcklwd   mm2, mm2
+        punpckldq   mm2, mm2
+
+        mov         rsi,        arg(0) ;src_ptr
+        mov         rdi,        arg(1) ;dst_ptr
+
+        movsxd      rcx, DWORD PTR arg(4) ;rows
+        movsxd      rax, DWORD PTR arg(2) ;src_pixels_per_line ; destination pitch?
+        pxor        mm0, mm0              ; mm0 = 00000000
+
+nextrow:
+
+        xor         rdx,        rdx       ; clear out rdx for use as loop counter
+nextcol:
+
+        pxor        mm7, mm7              ; mm7 = 00000000
+        movq        mm6, [rbx + 32 ]      ; mm6 = kernel 2 taps
+        movq        mm3, [rsi]            ; mm4 = r0 p0..p7
+        punpcklbw   mm3, mm0              ; mm3 = p0..p3
+        movq        mm1, mm3              ; mm1 = p0..p3
+        pmullw      mm3, mm6              ; mm3 *= kernel 2 modifiers
+
+        movq        mm6, [rbx + 48]       ; mm6 = kernel 3 taps
+        movq        mm5, [rsi + rax]      ; mm4 = r1 p0..p7
+        punpcklbw   mm5, mm0              ; mm5 = r1 p0..p3
+        pmullw      mm6, mm5              ; mm6 *= p0..p3 * kernel 3 modifiers
+        paddusw     mm3, mm6              ; mm3 += mm6
+
+        ; thresholding
+        movq        mm7, mm1              ; mm7 = r0 p0..p3
+        psubusw     mm7, mm5              ; mm7 = r0 p0..p3 - r1 p0..p3
+        psubusw     mm5, mm1              ; mm5 = r1 p0..p3 - r0 p0..p3
+        paddusw     mm7, mm5              ; mm7 = abs(r0 p0..p3 - r1 p0..p3)
+        pcmpgtw     mm7, mm2
+
+        movq        mm6, [rbx + 64 ]      ; mm6 = kernel 4 modifiers
+        movq        mm5, [rsi + 2*rax]    ; mm4 = r2 p0..p7
+        punpcklbw   mm5, mm0              ; mm5 = r2 p0..p3
+        pmullw      mm6, mm5              ; mm5 *= kernel 4 modifiers
+        paddusw     mm3, mm6              ; mm3 += mm5
+
+        ; thresholding
+        movq        mm6, mm1              ; mm6 = r0 p0..p3
+        psubusw     mm6, mm5              ; mm6 = r0 p0..p3 - r2 p0..p3
+        psubusw     mm5, mm1              ; mm5 = r2 p0..p3 - r2 p0..p3
+        paddusw     mm6, mm5              ; mm6 = abs(r0 p0..p3 - r2 p0..p3)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ; accumulate thresholds
+
+
+        neg         rax
+        movq        mm6, [rbx ]           ; kernel 0 taps
+        movq        mm5, [rsi+2*rax]      ; mm4 = r-2 p0..p7
+        punpcklbw   mm5, mm0              ; mm5 = r-2 p0..p3
+        pmullw      mm6, mm5              ; mm5 *= kernel 0 modifiers
+        paddusw     mm3, mm6              ; mm3 += mm5
+
+        ; thresholding
+        movq        mm6, mm1              ; mm6 = r0 p0..p3
+        psubusw     mm6, mm5              ; mm6 = p0..p3 - r-2 p0..p3
+        psubusw     mm5, mm1              ; mm5 = r-2 p0..p3 - p0..p3
+        paddusw     mm6, mm5              ; mm6 = abs(r0 p0..p3 - r-2 p0..p3)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ; accumulate thresholds
+
+        movq        mm6, [rbx + 16]       ; kernel 1 taps
+        movq        mm4, [rsi+rax]        ; mm4 = r-1 p0..p7
+        punpcklbw   mm4, mm0              ; mm4 = r-1 p0..p3
+        pmullw      mm6, mm4              ; mm4 *= kernel 1 modifiers.
+        paddusw     mm3, mm6              ; mm3 += mm5
+
+        ; thresholding
+        movq        mm6, mm1              ; mm6 = r0 p0..p3
+        psubusw     mm6, mm4              ; mm6 = p0..p3 - r-2 p0..p3
+        psubusw     mm4, mm1              ; mm5 = r-1 p0..p3 - p0..p3
+        paddusw     mm6, mm4              ; mm6 = abs(r0 p0..p3 - r-1 p0..p3)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ; accumulate thresholds
+
+
+        paddusw     mm3, RD               ; mm3 += round value
+        psraw       mm3, VP8_FILTER_SHIFT     ; mm3 /= 128
+
+        pand        mm1, mm7              ; mm1 select vals > thresh from source
+        pandn       mm7, mm3              ; mm7 select vals < thresh from blurred result
+        paddusw     mm1, mm7              ; combination
+
+        packuswb    mm1, mm0              ; pack to bytes
+
+        movd        [rdi], mm1            ;
+        neg         rax                   ; pitch is positive
+
+
+        add         rsi, 4
+        add         rdi, 4
+        add         rdx, 4
+
+        cmp         edx, dword ptr arg(5) ;cols
+        jl          nextcol
+        ; done with the all cols, start the across filtering in place
+        sub         rsi, rdx
+        sub         rdi, rdx
+
+
+        push        rax
+        xor         rdx,    rdx
+        mov         rax,    [rdi-4];
+
+acrossnextcol:
+        pxor        mm7, mm7              ; mm7 = 00000000
+        movq        mm6, [rbx + 32 ]      ;
+        movq        mm4, [rdi+rdx]        ; mm4 = p0..p7
+        movq        mm3, mm4              ; mm3 = p0..p7
+        punpcklbw   mm3, mm0              ; mm3 = p0..p3
+        movq        mm1, mm3              ; mm1 = p0..p3
+        pmullw      mm3, mm6              ; mm3 *= kernel 2 modifiers
+
+        movq        mm6, [rbx + 48]
+        psrlq       mm4, 8                ; mm4 = p1..p7
+        movq        mm5, mm4              ; mm5 = p1..p7
+        punpcklbw   mm5, mm0              ; mm5 = p1..p4
+        pmullw      mm6, mm5              ; mm6 *= p1..p4 * kernel 3 modifiers
+        paddusw     mm3, mm6              ; mm3 += mm6
+
+        ; thresholding
+        movq        mm7, mm1              ; mm7 = p0..p3
+        psubusw     mm7, mm5              ; mm7 = p0..p3 - p1..p4
+        psubusw     mm5, mm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     mm7, mm5              ; mm7 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm7, mm2
+
+        movq        mm6, [rbx + 64 ]
+        psrlq       mm4, 8                ; mm4 = p2..p7
+        movq        mm5, mm4              ; mm5 = p2..p7
+        punpcklbw   mm5, mm0              ; mm5 = p2..p5
+        pmullw      mm6, mm5              ; mm5 *= kernel 4 modifiers
+        paddusw     mm3, mm6              ; mm3 += mm5
+
+        ; thresholding
+        movq        mm6, mm1              ; mm6 = p0..p3
+        psubusw     mm6, mm5              ; mm6 = p0..p3 - p1..p4
+        psubusw     mm5, mm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     mm6, mm5              ; mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ; accumulate thresholds
+
+
+        movq        mm6, [rbx ]
+        movq        mm4, [rdi+rdx-2]      ; mm4 = p-2..p5
+        movq        mm5, mm4              ; mm5 = p-2..p5
+        punpcklbw   mm5, mm0              ; mm5 = p-2..p1
+        pmullw      mm6, mm5              ; mm5 *= kernel 0 modifiers
+        paddusw     mm3, mm6              ; mm3 += mm5
+
+        ; thresholding
+        movq        mm6, mm1              ; mm6 = p0..p3
+        psubusw     mm6, mm5              ; mm6 = p0..p3 - p1..p4
+        psubusw     mm5, mm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     mm6, mm5              ; mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ; accumulate thresholds
+
+        movq        mm6, [rbx + 16]
+        psrlq       mm4, 8                ; mm4 = p-1..p5
+        punpcklbw   mm4, mm0              ; mm4 = p-1..p2
+        pmullw      mm6, mm4              ; mm4 *= kernel 1 modifiers.
+        paddusw     mm3, mm6              ; mm3 += mm5
+
+        ; thresholding
+        movq        mm6, mm1              ; mm6 = p0..p3
+        psubusw     mm6, mm4              ; mm6 = p0..p3 - p1..p4
+        psubusw     mm4, mm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     mm6, mm4              ; mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ; accumulate thresholds
+
+        paddusw     mm3, RD               ; mm3 += round value
+        psraw       mm3, VP8_FILTER_SHIFT     ; mm3 /= 128
+
+        pand        mm1, mm7              ; mm1 select vals > thresh from source
+        pandn       mm7, mm3              ; mm7 select vals < thresh from blurred result
+        paddusw     mm1, mm7              ; combination
+
+        packuswb    mm1, mm0              ; pack to bytes
+        mov         DWORD PTR [rdi+rdx-4],  eax   ; store previous four bytes
+        movd        eax,    mm1
+
+        add         rdx, 4
+        cmp         edx, dword ptr arg(5) ;cols
+        jl          acrossnextcol;
+
+        mov         DWORD PTR [rdi+rdx-4],  eax
+        pop         rax
+
+        ; done with this rwo
+        add         rsi,rax               ; next line
+        movsxd      rax, dword ptr arg(3) ;dst_pixels_per_line ; destination pitch?
+        add         rdi,rax               ; next destination
+        movsxd      rax, dword ptr arg(2) ;src_pixels_per_line ; destination pitch?
+
+        dec         rcx                   ; decrement count
+        jnz         nextrow               ; next row
+        pop         rbx
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+%undef RD
+
+
+;void vp8_mbpost_proc_down_mmx(unsigned char *dst,
+;                             int pitch, int rows, int cols,int flimit)
+extern sym(vp8_rv)
+global sym(vp8_mbpost_proc_down_mmx)
+sym(vp8_mbpost_proc_down_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 136
+
+    ; unsigned char d[16][8] at [rsp]
+    ; create flimit2 at [rsp+128]
+    mov         eax, dword ptr arg(4) ;flimit
+    mov         [rsp+128], eax
+    mov         [rsp+128+4], eax
+%define flimit2 [rsp+128]
+
+%if ABI_IS_32BIT=0
+    lea         r8,       [sym(vp8_rv) GLOBAL]
+%endif
+
+    ;rows +=8;
+    add         dword ptr arg(2), 8
+
+    ;for(c=0; c<cols; c+=4)
+loop_col:
+            mov         rsi,        arg(0)  ;s
+            pxor        mm0,        mm0     ;
+
+            movsxd      rax,        dword ptr arg(1) ;pitch       ;
+            neg         rax                                     ; rax = -pitch
+
+            lea         rsi,        [rsi + rax*8];              ; rdi = s[-pitch*8]
+            neg         rax
+
+
+            pxor        mm5,        mm5
+            pxor        mm6,        mm6     ;
+
+            pxor        mm7,        mm7     ;
+            mov         rdi,        rsi
+
+            mov         rcx,        15          ;
+
+loop_initvar:
+            movd        mm1,        DWORD PTR [rdi];
+            punpcklbw   mm1,        mm0     ;
+
+            paddw       mm5,        mm1     ;
+            pmullw      mm1,        mm1     ;
+
+            movq        mm2,        mm1     ;
+            punpcklwd   mm1,        mm0     ;
+
+            punpckhwd   mm2,        mm0     ;
+            paddd       mm6,        mm1     ;
+
+            paddd       mm7,        mm2     ;
+            lea         rdi,        [rdi+rax]   ;
+
+            dec         rcx
+            jne         loop_initvar
+            ;save the var and sum
+            xor         rdx,        rdx
+loop_row:
+            movd        mm1,        DWORD PTR [rsi]     ; [s-pitch*8]
+            movd        mm2,        DWORD PTR [rdi]     ; [s+pitch*7]
+
+            punpcklbw   mm1,        mm0
+            punpcklbw   mm2,        mm0
+
+            paddw       mm5,        mm2
+            psubw       mm5,        mm1
+
+            pmullw      mm2,        mm2
+            movq        mm4,        mm2
+
+            punpcklwd   mm2,        mm0
+            punpckhwd   mm4,        mm0
+
+            paddd       mm6,        mm2
+            paddd       mm7,        mm4
+
+            pmullw      mm1,        mm1
+            movq        mm2,        mm1
+
+            punpcklwd   mm1,        mm0
+            psubd       mm6,        mm1
+
+            punpckhwd   mm2,        mm0
+            psubd       mm7,        mm2
+
+
+            movq        mm3,        mm6
+            pslld       mm3,        4
+
+            psubd       mm3,        mm6
+            movq        mm1,        mm5
+
+            movq        mm4,        mm5
+            pmullw      mm1,        mm1
+
+            pmulhw      mm4,        mm4
+            movq        mm2,        mm1
+
+            punpcklwd   mm1,        mm4
+            punpckhwd   mm2,        mm4
+
+            movq        mm4,        mm7
+            pslld       mm4,        4
+
+            psubd       mm4,        mm7
+
+            psubd       mm3,        mm1
+            psubd       mm4,        mm2
+
+            psubd       mm3,        flimit2
+            psubd       mm4,        flimit2
+
+            psrad       mm3,        31
+            psrad       mm4,        31
+
+            packssdw    mm3,        mm4
+            packsswb    mm3,        mm0
+
+            movd        mm1,        DWORD PTR [rsi+rax*8]
+
+            movq        mm2,        mm1
+            punpcklbw   mm1,        mm0
+
+            paddw       mm1,        mm5
+            mov         rcx,        rdx
+
+            and         rcx,        127
+%if ABI_IS_32BIT=1 && CONFIG_PIC=1
+            push        rax
+            lea         rax,        [sym(vp8_rv) GLOBAL]
+            movq        mm4,        [rax + rcx*2] ;vp8_rv[rcx*2]
+            pop         rax
+%elif ABI_IS_32BIT=0
+            movq        mm4,        [r8 + rcx*2] ;vp8_rv[rcx*2]
+%else
+            movq        mm4,        [sym(vp8_rv) + rcx*2]
+%endif
+            paddw       mm1,        mm4
+            ;paddw     xmm1,       eight8s
+            psraw       mm1,        4
+
+            packuswb    mm1,        mm0
+            pand        mm1,        mm3
+
+            pandn       mm3,        mm2
+            por         mm1,        mm3
+
+            and         rcx,        15
+            movd        DWORD PTR   [rsp+rcx*4], mm1 ;d[rcx*4]
+
+            mov         rcx,        rdx
+            sub         rcx,        8
+
+            and         rcx,        15
+            movd        mm1,        DWORD PTR [rsp+rcx*4] ;d[rcx*4]
+
+            movd        [rsi],      mm1
+            lea         rsi,        [rsi+rax]
+
+            lea         rdi,        [rdi+rax]
+            add         rdx,        1
+
+            cmp         edx,        dword arg(2) ;rows
+            jl          loop_row
+
+
+        add         dword arg(0), 4 ; s += 4
+        sub         dword arg(3), 4 ; cols -= 4
+        cmp         dword arg(3), 0
+        jg          loop_col
+
+    add         rsp, 136
+    pop         rsp
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+%undef flimit2
+
+
+;void vp8_plane_add_noise_mmx (unsigned char *Start, unsigned char *noise,
+;                            unsigned char blackclamp[16],
+;                            unsigned char whiteclamp[16],
+;                            unsigned char bothclamp[16],
+;                            unsigned int Width, unsigned int Height, int Pitch)
+extern sym(rand)
+global sym(vp8_plane_add_noise_mmx)
+sym(vp8_plane_add_noise_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+addnoise_loop:
+    call sym(rand) WRT_PLT
+    mov     rcx, arg(1) ;noise
+    and     rax, 0xff
+    add     rcx, rax
+
+    ; we rely on the fact that the clamping vectors are stored contiguously
+    ; in black/white/both order. Note that we have to reload this here because
+    ; rdx could be trashed by rand()
+    mov     rdx, arg(2) ; blackclamp
+
+
+            mov     rdi, rcx
+            movsxd  rcx, dword arg(5) ;[Width]
+            mov     rsi, arg(0) ;Pos
+            xor         rax,rax
+
+addnoise_nextset:
+            movq        mm1,[rsi+rax]         ; get the source
+
+            psubusb     mm1, [rdx]    ;blackclamp        ; clamp both sides so we don't outrange adding noise
+            paddusb     mm1, [rdx+32] ;bothclamp
+            psubusb     mm1, [rdx+16] ;whiteclamp
+
+            movq        mm2,[rdi+rax]         ; get the noise for this line
+            paddb       mm1,mm2              ; add it in
+            movq        [rsi+rax],mm1         ; store the result
+
+            add         rax,8                 ; move to the next line
+
+            cmp         rax, rcx
+            jl          addnoise_nextset
+
+    movsxd  rax, dword arg(7) ; Pitch
+    add     arg(0), rax ; Start += Pitch
+    sub     dword arg(6), 1   ; Height -= 1
+    jg      addnoise_loop
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+align 16
+Blur:
+    times 16 dw 16
+    times  8 dw 64
+    times 16 dw 16
+    times  8 dw  0
+
+rd:
+    times 4 dw 0x40
diff --git a/vp8/common/x86/postproc_mmx.c b/vp8/common/x86/postproc_mmx.c
new file mode 100644 (file)
index 0000000..095797b
--- /dev/null
@@ -0,0 +1,1507 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include "vpx_scale/yv12config.h"
+#include "pragmas.h"
+
+#define VP8_FILTER_WEIGHT 128
+#define VP8_FILTER_SHIFT  7
+
+
+
+/* static constants */
+__declspec(align(16))
+const static short  Blur[48] =
+{
+
+    16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16,
+    64, 64, 64, 64, 64, 64, 64, 64,
+    16, 16, 16, 16, 16, 16, 16, 16,
+    16, 16, 16, 16, 16, 16, 16, 16,
+    0,  0,  0,  0,  0,  0,  0,  0,
+
+};
+#define RD  __declspec(align(16)) __int64 rd  = 0x0040004000400040;
+#define R4D2 __declspec(align(16)) __int64 rd42[2] = {0x0004000400040004,0x0004000400040004};
+
+#ifndef RELOCATEABLE
+const static RD;
+const static R4D2;
+#endif
+
+
+/* external references */
+extern double vp8_gaussian(double sigma, double mu, double x);
+extern short vp8_rv[];
+extern int vp8_q2mbl(int x) ;
+
+
+
+void vp8_post_proc_down_and_across_mmx
+(
+    unsigned char *src_ptr,
+    unsigned char *dst_ptr,
+    int src_pixels_per_line,
+    int dst_pixels_per_line,
+    int rows,
+    int cols,
+    int flimit
+)
+{
+#ifdef RELOCATEABLE
+    RD
+    R4D2
+#endif
+
+    __asm
+    {
+        push        ebx
+        lea         ebx, Blur
+        movd        mm2, flimit
+        punpcklwd   mm2, mm2
+        punpckldq   mm2, mm2
+
+        mov         esi,        src_ptr
+        mov         edi,        dst_ptr
+
+        mov         ecx, DWORD PTR rows
+        mov         eax, src_pixels_per_line ;
+        destination pitch?
+        pxor        mm0, mm0              ;
+        mm0 = 00000000
+
+        nextrow:
+
+        xor         edx,        edx       ;
+
+        clear out edx for use as loop counter
+        nextcol:
+
+        pxor        mm7, mm7              ;
+
+    mm7 = 00000000
+    movq        mm6, [ebx + 32 ]      ;
+        mm6 = kernel 2 taps
+        movq        mm3, [esi]            ;
+        mm4 = r0 p0..p7
+        punpcklbw   mm3, mm0              ;
+        mm3 = p0..p3
+        movq        mm1, mm3              ;
+        mm1 = p0..p3
+        pmullw      mm3, mm6              ;
+        mm3 *= kernel 2 modifiers
+
+        movq        mm6, [ebx + 48]       ;
+        mm6 = kernel 3 taps
+        movq        mm5, [esi + eax]      ;
+        mm4 = r1 p0..p7
+        punpcklbw   mm5, mm0              ;
+        mm5 = r1 p0..p3
+        pmullw      mm6, mm5              ;
+        mm6 *= p0..p3 * kernel 3 modifiers
+        paddusw     mm3, mm6              ;
+        mm3 += mm6
+
+        ;
+        thresholding
+        movq        mm7, mm1              ;
+        mm7 = r0 p0..p3
+        psubusw     mm7, mm5              ;
+        mm7 = r0 p0..p3 - r1 p0..p3
+        psubusw     mm5, mm1              ;
+        mm5 = r1 p0..p3 - r0 p0..p3
+        paddusw     mm7, mm5              ;
+        mm7 = abs(r0 p0..p3 - r1 p0..p3)
+        pcmpgtw     mm7, mm2
+
+        movq        mm6, [ebx + 64 ]      ;
+        mm6 = kernel 4 modifiers
+        movq        mm5, [esi + 2*eax]    ;
+        mm4 = r2 p0..p7
+        punpcklbw   mm5, mm0              ;
+        mm5 = r2 p0..p3
+        pmullw      mm6, mm5              ;
+        mm5 *= kernel 4 modifiers
+        paddusw     mm3, mm6              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movq        mm6, mm1              ;
+        mm6 = r0 p0..p3
+        psubusw     mm6, mm5              ;
+        mm6 = r0 p0..p3 - r2 p0..p3
+        psubusw     mm5, mm1              ;
+        mm5 = r2 p0..p3 - r2 p0..p3
+        paddusw     mm6, mm5              ;
+        mm6 = abs(r0 p0..p3 - r2 p0..p3)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ;
+        accumulate thresholds
+
+
+        neg         eax
+        movq        mm6, [ebx ]           ;
+        kernel 0 taps
+        movq        mm5, [esi+2*eax]      ;
+        mm4 = r-2 p0..p7
+        punpcklbw   mm5, mm0              ;
+        mm5 = r-2 p0..p3
+        pmullw      mm6, mm5              ;
+        mm5 *= kernel 0 modifiers
+        paddusw     mm3, mm6              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movq        mm6, mm1              ;
+        mm6 = r0 p0..p3
+        psubusw     mm6, mm5              ;
+        mm6 = p0..p3 - r-2 p0..p3
+        psubusw     mm5, mm1              ;
+        mm5 = r-2 p0..p3 - p0..p3
+        paddusw     mm6, mm5              ;
+        mm6 = abs(r0 p0..p3 - r-2 p0..p3)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ;
+        accumulate thresholds
+
+        movq        mm6, [ebx + 16]       ;
+        kernel 1 taps
+        movq        mm4, [esi+eax]        ;
+        mm4 = r-1 p0..p7
+        punpcklbw   mm4, mm0              ;
+        mm4 = r-1 p0..p3
+        pmullw      mm6, mm4              ;
+        mm4 *= kernel 1 modifiers.
+        paddusw     mm3, mm6              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movq        mm6, mm1              ;
+        mm6 = r0 p0..p3
+        psubusw     mm6, mm4              ;
+        mm6 = p0..p3 - r-2 p0..p3
+        psubusw     mm4, mm1              ;
+        mm5 = r-1 p0..p3 - p0..p3
+        paddusw     mm6, mm4              ;
+        mm6 = abs(r0 p0..p3 - r-1 p0..p3)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ;
+        accumulate thresholds
+
+
+        paddusw     mm3, rd               ;
+        mm3 += round value
+        psraw       mm3, VP8_FILTER_SHIFT     ;
+        mm3 /= 128
+
+        pand        mm1, mm7              ;
+        mm1 select vals > thresh from source
+        pandn       mm7, mm3              ;
+        mm7 select vals < thresh from blurred result
+        paddusw     mm1, mm7              ;
+        combination
+
+        packuswb    mm1, mm0              ;
+        pack to bytes
+
+        movd        [edi], mm1            ;
+        neg         eax                   ;
+        pitch is positive
+
+
+        add         esi, 4
+        add         edi, 4
+        add         edx, 4
+
+        cmp         edx, cols
+        jl          nextcol
+        // done with the all cols, start the across filtering in place
+        sub         esi, edx
+        sub         edi, edx
+
+
+        push        eax
+        xor         edx,    edx
+        mov         eax,    [edi-4];
+
+        acrossnextcol:
+        pxor        mm7, mm7              ;
+        mm7 = 00000000
+        movq        mm6, [ebx + 32 ]      ;
+        movq        mm4, [edi+edx]        ;
+        mm4 = p0..p7
+        movq        mm3, mm4              ;
+        mm3 = p0..p7
+        punpcklbw   mm3, mm0              ;
+        mm3 = p0..p3
+        movq        mm1, mm3              ;
+        mm1 = p0..p3
+        pmullw      mm3, mm6              ;
+        mm3 *= kernel 2 modifiers
+
+        movq        mm6, [ebx + 48]
+        psrlq       mm4, 8                ;
+        mm4 = p1..p7
+        movq        mm5, mm4              ;
+        mm5 = p1..p7
+        punpcklbw   mm5, mm0              ;
+        mm5 = p1..p4
+        pmullw      mm6, mm5              ;
+        mm6 *= p1..p4 * kernel 3 modifiers
+        paddusw     mm3, mm6              ;
+        mm3 += mm6
+
+        ;
+        thresholding
+        movq        mm7, mm1              ;
+        mm7 = p0..p3
+        psubusw     mm7, mm5              ;
+        mm7 = p0..p3 - p1..p4
+        psubusw     mm5, mm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     mm7, mm5              ;
+        mm7 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm7, mm2
+
+        movq        mm6, [ebx + 64 ]
+        psrlq       mm4, 8                ;
+        mm4 = p2..p7
+        movq        mm5, mm4              ;
+        mm5 = p2..p7
+        punpcklbw   mm5, mm0              ;
+        mm5 = p2..p5
+        pmullw      mm6, mm5              ;
+        mm5 *= kernel 4 modifiers
+        paddusw     mm3, mm6              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movq        mm6, mm1              ;
+        mm6 = p0..p3
+        psubusw     mm6, mm5              ;
+        mm6 = p0..p3 - p1..p4
+        psubusw     mm5, mm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     mm6, mm5              ;
+        mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ;
+        accumulate thresholds
+
+
+        movq        mm6, [ebx ]
+        movq        mm4, [edi+edx-2]      ;
+        mm4 = p-2..p5
+        movq        mm5, mm4              ;
+        mm5 = p-2..p5
+        punpcklbw   mm5, mm0              ;
+        mm5 = p-2..p1
+        pmullw      mm6, mm5              ;
+        mm5 *= kernel 0 modifiers
+        paddusw     mm3, mm6              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movq        mm6, mm1              ;
+        mm6 = p0..p3
+        psubusw     mm6, mm5              ;
+        mm6 = p0..p3 - p1..p4
+        psubusw     mm5, mm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     mm6, mm5              ;
+        mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ;
+        accumulate thresholds
+
+        movq        mm6, [ebx + 16]
+        psrlq       mm4, 8                ;
+        mm4 = p-1..p5
+        punpcklbw   mm4, mm0              ;
+        mm4 = p-1..p2
+        pmullw      mm6, mm4              ;
+        mm4 *= kernel 1 modifiers.
+        paddusw     mm3, mm6              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movq        mm6, mm1              ;
+        mm6 = p0..p3
+        psubusw     mm6, mm4              ;
+        mm6 = p0..p3 - p1..p4
+        psubusw     mm4, mm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     mm6, mm4              ;
+        mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     mm6, mm2
+        por         mm7, mm6              ;
+        accumulate thresholds
+
+        paddusw     mm3, rd               ;
+        mm3 += round value
+        psraw       mm3, VP8_FILTER_SHIFT     ;
+        mm3 /= 128
+
+        pand        mm1, mm7              ;
+        mm1 select vals > thresh from source
+        pandn       mm7, mm3              ;
+        mm7 select vals < thresh from blurred result
+        paddusw     mm1, mm7              ;
+        combination
+
+        packuswb    mm1, mm0              ;
+        pack to bytes
+        mov         DWORD PTR [edi+edx-4],  eax   ;
+        store previous four bytes
+        movd        eax,    mm1
+
+        add         edx, 4
+        cmp         edx, cols
+        jl          acrossnextcol;
+
+        mov         DWORD PTR [edi+edx-4],  eax
+        pop         eax
+
+        // done with this rwo
+        add         esi, eax               ;
+        next line
+        mov         eax, dst_pixels_per_line ;
+        destination pitch?
+        add         edi, eax               ;
+        next destination
+        mov         eax, src_pixels_per_line ;
+        destination pitch?
+
+        dec         ecx                   ;
+        decrement count
+        jnz         nextrow               ;
+        next row
+        pop         ebx
+
+    }
+}
+
+
+
+void vp8_post_proc_down_and_across_xmm
+(
+    unsigned char *src_ptr,
+    unsigned char *dst_ptr,
+    int src_pixels_per_line,
+    int dst_pixels_per_line,
+    int rows,
+    int cols,
+    int flimit
+)
+{
+#ifdef RELOCATEABLE
+    R4D2
+#endif
+
+    __asm
+    {
+        movd        xmm2,       flimit
+        punpcklwd   xmm2,       xmm2
+        punpckldq   xmm2,       xmm2
+        punpcklqdq  xmm2,       xmm2
+
+        mov         esi,        src_ptr
+        mov         edi,        dst_ptr
+
+        mov         ecx,        DWORD PTR rows
+        mov         eax,        src_pixels_per_line ;
+        destination pitch?
+        pxor        xmm0,       xmm0              ;
+        mm0 = 00000000
+
+        nextrow:
+
+        xor         edx,        edx       ;
+
+        clear out edx for use as loop counter
+        nextcol:
+        movq        xmm3,       QWORD PTR [esi]         ;
+
+        mm4 = r0 p0..p7
+        punpcklbw   xmm3,       xmm0                    ;
+        mm3 = p0..p3
+        movdqa      xmm1,       xmm3                    ;
+        mm1 = p0..p3
+        psllw       xmm3,       2                       ;
+
+        movq        xmm5,       QWORD PTR [esi + eax]   ;
+        mm4 = r1 p0..p7
+        punpcklbw   xmm5,       xmm0                    ;
+        mm5 = r1 p0..p3
+        paddusw     xmm3,       xmm5                    ;
+        mm3 += mm6
+
+        ;
+        thresholding
+        movdqa      xmm7,       xmm1                    ;
+        mm7 = r0 p0..p3
+        psubusw     xmm7,       xmm5                    ;
+        mm7 = r0 p0..p3 - r1 p0..p3
+        psubusw     xmm5,       xmm1                    ;
+        mm5 = r1 p0..p3 - r0 p0..p3
+        paddusw     xmm7,       xmm5                    ;
+        mm7 = abs(r0 p0..p3 - r1 p0..p3)
+        pcmpgtw     xmm7,       xmm2
+
+        movq        xmm5,       QWORD PTR [esi + 2*eax] ;
+        mm4 = r2 p0..p7
+        punpcklbw   xmm5,       xmm0                    ;
+        mm5 = r2 p0..p3
+        paddusw     xmm3,       xmm5                    ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movdqa      xmm6,       xmm1                    ;
+        mm6 = r0 p0..p3
+        psubusw     xmm6,       xmm5                    ;
+        mm6 = r0 p0..p3 - r2 p0..p3
+        psubusw     xmm5,       xmm1                    ;
+        mm5 = r2 p0..p3 - r2 p0..p3
+        paddusw     xmm6,       xmm5                    ;
+        mm6 = abs(r0 p0..p3 - r2 p0..p3)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6                    ;
+        accumulate thresholds
+
+
+        neg         eax
+        movq        xmm5,       QWORD PTR [esi+2*eax]   ;
+        mm4 = r-2 p0..p7
+        punpcklbw   xmm5,       xmm0                    ;
+        mm5 = r-2 p0..p3
+        paddusw     xmm3,       xmm5                    ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movdqa      xmm6,       xmm1                    ;
+        mm6 = r0 p0..p3
+        psubusw     xmm6,       xmm5                    ;
+        mm6 = p0..p3 - r-2 p0..p3
+        psubusw     xmm5,       xmm1                    ;
+        mm5 = r-2 p0..p3 - p0..p3
+        paddusw     xmm6,       xmm5                    ;
+        mm6 = abs(r0 p0..p3 - r-2 p0..p3)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6                    ;
+        accumulate thresholds
+
+        movq        xmm4,       QWORD PTR [esi+eax]     ;
+        mm4 = r-1 p0..p7
+        punpcklbw   xmm4,       xmm0                    ;
+        mm4 = r-1 p0..p3
+        paddusw     xmm3,       xmm4                    ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movdqa      xmm6,       xmm1                    ;
+        mm6 = r0 p0..p3
+        psubusw     xmm6,       xmm4                    ;
+        mm6 = p0..p3 - r-2 p0..p3
+        psubusw     xmm4,       xmm1                    ;
+        mm5 = r-1 p0..p3 - p0..p3
+        paddusw     xmm6,       xmm4                    ;
+        mm6 = abs(r0 p0..p3 - r-1 p0..p3)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6                    ;
+        accumulate thresholds
+
+
+        paddusw     xmm3,       rd42                    ;
+        mm3 += round value
+        psraw       xmm3,       3                       ;
+        mm3 /= 8
+
+        pand        xmm1,       xmm7                    ;
+        mm1 select vals > thresh from source
+        pandn       xmm7,       xmm3                    ;
+        mm7 select vals < thresh from blurred result
+        paddusw     xmm1,       xmm7                    ;
+        combination
+
+        packuswb    xmm1,       xmm0                    ;
+        pack to bytes
+        movq        QWORD PTR [edi], xmm1             ;
+
+        neg         eax                   ;
+        pitch is positive
+        add         esi,        8
+        add         edi,        8
+
+        add         edx,        8
+        cmp         edx,        cols
+
+        jl          nextcol
+
+        // done with the all cols, start the across filtering in place
+        sub         esi,        edx
+        sub         edi,        edx
+
+        xor         edx,        edx
+        movq        mm0,        QWORD PTR [edi-8];
+
+        acrossnextcol:
+        movq        xmm7,       QWORD PTR [edi +edx -2]
+        movd        xmm4,       DWORD PTR [edi +edx +6]
+
+        pslldq      xmm4,       8
+        por         xmm4,       xmm7
+
+        movdqa      xmm3,       xmm4
+        psrldq      xmm3,       2
+        punpcklbw   xmm3,       xmm0              ;
+        mm3 = p0..p3
+        movdqa      xmm1,       xmm3              ;
+        mm1 = p0..p3
+        psllw       xmm3,       2
+
+
+        movdqa      xmm5,       xmm4
+        psrldq      xmm5,       3
+        punpcklbw   xmm5,       xmm0              ;
+        mm5 = p1..p4
+        paddusw     xmm3,       xmm5              ;
+        mm3 += mm6
+
+        ;
+        thresholding
+        movdqa      xmm7,       xmm1              ;
+        mm7 = p0..p3
+        psubusw     xmm7,       xmm5              ;
+        mm7 = p0..p3 - p1..p4
+        psubusw     xmm5,       xmm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     xmm7,       xmm5              ;
+        mm7 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm7,       xmm2
+
+        movdqa      xmm5,       xmm4
+        psrldq      xmm5,       4
+        punpcklbw   xmm5,       xmm0              ;
+        mm5 = p2..p5
+        paddusw     xmm3,       xmm5              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movdqa      xmm6,       xmm1              ;
+        mm6 = p0..p3
+        psubusw     xmm6,       xmm5              ;
+        mm6 = p0..p3 - p1..p4
+        psubusw     xmm5,       xmm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     xmm6,       xmm5              ;
+        mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6              ;
+        accumulate thresholds
+
+
+        movdqa      xmm5,       xmm4              ;
+        mm5 = p-2..p5
+        punpcklbw   xmm5,       xmm0              ;
+        mm5 = p-2..p1
+        paddusw     xmm3,       xmm5              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movdqa      xmm6,       xmm1              ;
+        mm6 = p0..p3
+        psubusw     xmm6,       xmm5              ;
+        mm6 = p0..p3 - p1..p4
+        psubusw     xmm5,       xmm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     xmm6,       xmm5              ;
+        mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6              ;
+        accumulate thresholds
+
+        psrldq      xmm4,       1                   ;
+        mm4 = p-1..p5
+        punpcklbw   xmm4,       xmm0              ;
+        mm4 = p-1..p2
+        paddusw     xmm3,       xmm4              ;
+        mm3 += mm5
+
+        ;
+        thresholding
+        movdqa      xmm6,       xmm1              ;
+        mm6 = p0..p3
+        psubusw     xmm6,       xmm4              ;
+        mm6 = p0..p3 - p1..p4
+        psubusw     xmm4,       xmm1              ;
+        mm5 = p1..p4 - p0..p3
+        paddusw     xmm6,       xmm4              ;
+        mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6              ;
+        accumulate thresholds
+
+        paddusw     xmm3,       rd42              ;
+        mm3 += round value
+        psraw       xmm3,       3                 ;
+        mm3 /= 8
+
+        pand        xmm1,       xmm7              ;
+        mm1 select vals > thresh from source
+        pandn       xmm7,       xmm3              ;
+        mm7 select vals < thresh from blurred result
+        paddusw     xmm1,       xmm7              ;
+        combination
+
+        packuswb    xmm1,       xmm0              ;
+        pack to bytes
+        movq        QWORD PTR [edi+edx-8],  mm0   ;
+        store previous four bytes
+        movdq2q     mm0,        xmm1
+
+        add         edx,        8
+        cmp         edx,        cols
+        jl          acrossnextcol;
+
+        // last 8 pixels
+        movq        QWORD PTR [edi+edx-8],  mm0
+
+        // done with this rwo
+        add         esi, eax               ;
+        next line
+        mov         eax, dst_pixels_per_line ;
+        destination pitch?
+        add         edi, eax               ;
+        next destination
+        mov         eax, src_pixels_per_line ;
+        destination pitch?
+
+        dec         ecx                   ;
+        decrement count
+        jnz         nextrow               ;
+        next row
+    }
+}
+
+
+void vp8_mbpost_proc_down_mmx(unsigned char *dst, int pitch, int rows, int cols, int flimit)
+{
+    int c, i;
+    __declspec(align(16))
+    int flimit2[2];
+    __declspec(align(16))
+    unsigned char d[16][8];
+
+    flimit = vp8_q2mbl(flimit);
+
+    for (i = 0; i < 2; i++)
+        flimit2[i] = flimit;
+
+    rows += 8;
+
+    for (c = 0; c < cols; c += 4)
+    {
+        unsigned char *s = &dst[c];
+
+        __asm
+        {
+            mov         esi,        s           ;
+            pxor        mm0,        mm0     ;
+
+            mov         eax,        pitch       ;
+            neg         eax                                     // eax = -pitch
+
+            lea         esi,        [esi + eax*8];              // edi = s[-pitch*8]
+            neg         eax
+
+
+            pxor        mm5,        mm5
+            pxor        mm6,        mm6     ;
+
+            pxor        mm7,        mm7     ;
+            mov         edi,        esi
+
+            mov         ecx,        15          ;
+
+            loop_initvar:
+            movd        mm1,        DWORD PTR [edi];
+            punpcklbw   mm1,        mm0     ;
+
+            paddw       mm5,        mm1     ;
+            pmullw      mm1,        mm1     ;
+
+            movq        mm2,        mm1     ;
+            punpcklwd   mm1,        mm0     ;
+
+            punpckhwd   mm2,        mm0     ;
+            paddd       mm6,        mm1     ;
+
+            paddd       mm7,        mm2     ;
+            lea         edi,        [edi+eax]   ;
+
+            dec         ecx
+            jne         loop_initvar
+            //save the var and sum
+            xor         edx,        edx
+            loop_row:
+            movd        mm1,        DWORD PTR [esi]     // [s-pitch*8]
+            movd        mm2,        DWORD PTR [edi]     // [s+pitch*7]
+
+            punpcklbw   mm1,        mm0
+            punpcklbw   mm2,        mm0
+
+            paddw       mm5,        mm2
+            psubw       mm5,        mm1
+
+            pmullw      mm2,        mm2
+            movq        mm4,        mm2
+
+            punpcklwd   mm2,        mm0
+            punpckhwd   mm4,        mm0
+
+            paddd       mm6,        mm2
+            paddd       mm7,        mm4
+
+            pmullw      mm1,        mm1
+            movq        mm2,        mm1
+
+            punpcklwd   mm1,        mm0
+            psubd       mm6,        mm1
+
+            punpckhwd   mm2,        mm0
+            psubd       mm7,        mm2
+
+
+            movq        mm3,        mm6
+            pslld       mm3,        4
+
+            psubd       mm3,        mm6
+            movq        mm1,        mm5
+
+            movq        mm4,        mm5
+            pmullw      mm1,        mm1
+
+            pmulhw      mm4,        mm4
+            movq        mm2,        mm1
+
+            punpcklwd   mm1,        mm4
+            punpckhwd   mm2,        mm4
+
+            movq        mm4,        mm7
+            pslld       mm4,        4
+
+            psubd       mm4,        mm7
+
+            psubd       mm3,        mm1
+            psubd       mm4,        mm2
+
+            psubd       mm3,        flimit2
+            psubd       mm4,        flimit2
+
+            psrad       mm3,        31
+            psrad       mm4,        31
+
+            packssdw    mm3,        mm4
+            packsswb    mm3,        mm0
+
+            movd        mm1,        DWORD PTR [esi+eax*8]
+
+            movq        mm2,        mm1
+            punpcklbw   mm1,        mm0
+
+            paddw       mm1,        mm5
+            mov         ecx,        edx
+
+            and         ecx,        127
+            movq        mm4,        vp8_rv[ecx*2]
+
+            paddw       mm1,        mm4
+            //paddw     xmm1,       eight8s
+            psraw       mm1,        4
+
+            packuswb    mm1,        mm0
+            pand        mm1,        mm3
+
+            pandn       mm3,        mm2
+            por         mm1,        mm3
+
+            and         ecx,        15
+            movd        DWORD PTR  d[ecx*4], mm1
+
+            mov         ecx,        edx
+            sub         ecx,        8
+
+            and         ecx,        15
+            movd        mm1,        DWORD PTR d[ecx*4]
+
+            movd        [esi],      mm1
+            lea         esi,        [esi+eax]
+
+            lea         edi,        [edi+eax]
+            add         edx,        1
+
+            cmp         edx,        rows
+            jl          loop_row
+
+        }
+
+    }
+}
+
+void vp8_mbpost_proc_down_xmm(unsigned char *dst, int pitch, int rows, int cols, int flimit)
+{
+    int c, i;
+    __declspec(align(16))
+    int flimit4[4];
+    __declspec(align(16))
+    unsigned char d[16][8];
+
+    flimit = vp8_q2mbl(flimit);
+
+    for (i = 0; i < 4; i++)
+        flimit4[i] = flimit;
+
+    rows += 8;
+
+    for (c = 0; c < cols; c += 8)
+    {
+        unsigned char *s = &dst[c];
+
+        __asm
+        {
+            mov         esi,        s           ;
+            pxor        xmm0,       xmm0        ;
+
+            mov         eax,        pitch       ;
+            neg         eax                                     // eax = -pitch
+
+            lea         esi,        [esi + eax*8];              // edi = s[-pitch*8]
+            neg         eax
+
+
+            pxor        xmm5,       xmm5
+            pxor        xmm6,       xmm6        ;
+
+            pxor        xmm7,       xmm7        ;
+            mov         edi,        esi
+
+            mov         ecx,        15          ;
+
+            loop_initvar:
+            movq        xmm1,       QWORD PTR [edi];
+            punpcklbw   xmm1,       xmm0        ;
+
+            paddw       xmm5,       xmm1        ;
+            pmullw      xmm1,       xmm1        ;
+
+            movdqa      xmm2,       xmm1        ;
+            punpcklwd   xmm1,       xmm0        ;
+
+            punpckhwd   xmm2,       xmm0        ;
+            paddd       xmm6,       xmm1        ;
+
+            paddd       xmm7,       xmm2        ;
+            lea         edi,        [edi+eax]   ;
+
+            dec         ecx
+            jne         loop_initvar
+            //save the var and sum
+            xor         edx,        edx
+            loop_row:
+            movq        xmm1,       QWORD PTR [esi]     // [s-pitch*8]
+            movq        xmm2,       QWORD PTR [edi]     // [s+pitch*7]
+
+            punpcklbw   xmm1,       xmm0
+            punpcklbw   xmm2,       xmm0
+
+            paddw       xmm5,       xmm2
+            psubw       xmm5,       xmm1
+
+            pmullw      xmm2,       xmm2
+            movdqa      xmm4,       xmm2
+
+            punpcklwd   xmm2,       xmm0
+            punpckhwd   xmm4,       xmm0
+
+            paddd       xmm6,       xmm2
+            paddd       xmm7,       xmm4
+
+            pmullw      xmm1,       xmm1
+            movdqa      xmm2,       xmm1
+
+            punpcklwd   xmm1,       xmm0
+            psubd       xmm6,       xmm1
+
+            punpckhwd   xmm2,       xmm0
+            psubd       xmm7,       xmm2
+
+
+            movdqa      xmm3,       xmm6
+            pslld       xmm3,       4
+
+            psubd       xmm3,       xmm6
+            movdqa      xmm1,       xmm5
+
+            movdqa      xmm4,       xmm5
+            pmullw      xmm1,       xmm1
+
+            pmulhw      xmm4,       xmm4
+            movdqa      xmm2,       xmm1
+
+            punpcklwd   xmm1,       xmm4
+            punpckhwd   xmm2,       xmm4
+
+            movdqa      xmm4,       xmm7
+            pslld       xmm4,       4
+
+            psubd       xmm4,       xmm7
+
+            psubd       xmm3,       xmm1
+            psubd       xmm4,       xmm2
+
+            psubd       xmm3,       flimit4
+            psubd       xmm4,       flimit4
+
+            psrad       xmm3,       31
+            psrad       xmm4,       31
+
+            packssdw    xmm3,       xmm4
+            packsswb    xmm3,       xmm0
+
+            movq        xmm1,       QWORD PTR [esi+eax*8]
+
+            movq        xmm2,       xmm1
+            punpcklbw   xmm1,       xmm0
+
+            paddw       xmm1,       xmm5
+            mov         ecx,        edx
+
+            and         ecx,        127
+            movdqu      xmm4,       vp8_rv[ecx*2]
+
+            paddw       xmm1,       xmm4
+            //paddw     xmm1,       eight8s
+            psraw       xmm1,       4
+
+            packuswb    xmm1,       xmm0
+            pand        xmm1,       xmm3
+
+            pandn       xmm3,       xmm2
+            por         xmm1,       xmm3
+
+            and         ecx,        15
+            movq        QWORD PTR  d[ecx*8], xmm1
+
+            mov         ecx,        edx
+            sub         ecx,        8
+
+            and         ecx,        15
+            movq        mm0,        d[ecx*8]
+
+            movq        [esi],      mm0
+            lea         esi,        [esi+eax]
+
+            lea         edi,        [edi+eax]
+            add         edx,        1
+
+            cmp         edx,        rows
+            jl          loop_row
+
+        }
+
+    }
+}
+#if 0
+/****************************************************************************
+ *
+ *  ROUTINE       : plane_add_noise_wmt
+ *
+ *  INPUTS        : unsigned char *Start    starting address of buffer to add gaussian
+ *                                  noise to
+ *                  unsigned int Width    width of plane
+ *                  unsigned int Height   height of plane
+ *                  int  Pitch    distance between subsequent lines of frame
+ *                  int  q        quantizer used to determine amount of noise
+ *                                  to add
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void.
+ *
+ *  FUNCTION      : adds gaussian noise to a plane of pixels
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_plane_add_noise_wmt(unsigned char *Start, unsigned int Width, unsigned int Height, int Pitch, int q, int a)
+{
+    unsigned int i;
+
+    __declspec(align(16)) unsigned char blackclamp[16];
+    __declspec(align(16)) unsigned char whiteclamp[16];
+    __declspec(align(16)) unsigned char bothclamp[16];
+    char char_dist[300];
+    char Rand[2048];
+    double sigma;
+//    return;
+    __asm emms
+    sigma = a + .5 + .6 * (63 - q) / 63.0;
+
+    // set up a lookup table of 256 entries that matches
+    // a gaussian distribution with sigma determined by q.
+    //
+    {
+        double i;
+        int next, j;
+
+        next = 0;
+
+        for (i = -32; i < 32; i++)
+        {
+            double g = 256 * vp8_gaussian(sigma, 0, 1.0 * i);
+            int a = (int)(g + .5);
+
+            if (a)
+            {
+                for (j = 0; j < a; j++)
+                {
+                    char_dist[next+j] = (char) i;
+                }
+
+                next = next + j;
+            }
+
+        }
+
+        for (next = next; next < 256; next++)
+            char_dist[next] = 0;
+
+    }
+
+    for (i = 0; i < 2048; i++)
+    {
+        Rand[i] = char_dist[rand() & 0xff];
+    }
+
+    for (i = 0; i < 16; i++)
+    {
+        blackclamp[i] = -char_dist[0];
+        whiteclamp[i] = -char_dist[0];
+        bothclamp[i] = -2 * char_dist[0];
+    }
+
+    for (i = 0; i < Height; i++)
+    {
+        unsigned char *Pos = Start + i * Pitch;
+        char  *Ref = Rand + (rand() & 0xff);
+
+        __asm
+        {
+            mov ecx, [Width]
+            mov esi, Pos
+            mov edi, Ref
+            xor         eax, eax
+
+            nextset:
+            movdqu      xmm1, [esi+eax]        // get the source
+
+            psubusb     xmm1, blackclamp       // clamp both sides so we don't outrange adding noise
+            paddusb     xmm1, bothclamp
+            psubusb     xmm1, whiteclamp
+
+            movdqu      xmm2, [edi+eax]        // get the noise for this line
+            paddb       xmm1, xmm2             // add it in
+            movdqu      [esi+eax], xmm1        // store the result
+
+            add         eax, 16                // move to the next line
+
+            cmp         eax, ecx
+            jl          nextset
+
+
+        }
+
+    }
+}
+#endif
+__declspec(align(16))
+static const int four8s[4] = { 8, 8, 8, 8};
+void vp8_mbpost_proc_across_ip_xmm(unsigned char *src, int pitch, int rows, int cols, int flimit)
+{
+    int r, i;
+    __declspec(align(16))
+    int flimit4[4];
+    unsigned char *s = src;
+    int sumsq;
+    int sum;
+
+
+    flimit = vp8_q2mbl(flimit);
+    flimit4[0] =
+        flimit4[1] =
+            flimit4[2] =
+                flimit4[3] = flimit;
+
+    for (r = 0; r < rows; r++)
+    {
+
+
+        sumsq = 0;
+        sum = 0;
+
+        for (i = -8; i <= 6; i++)
+        {
+            sumsq += s[i] * s[i];
+            sum   += s[i];
+        }
+
+        __asm
+        {
+            mov         eax,    sumsq
+            movd        xmm7,   eax
+
+            mov         eax,    sum
+            movd        xmm6,   eax
+
+            mov         esi,    s
+            xor         ecx,    ecx
+
+            mov         edx,    cols
+            add         edx,    8
+            pxor        mm0,    mm0
+            pxor        mm1,    mm1
+
+            pxor        xmm0,   xmm0
+            nextcol4:
+
+            movd        xmm1,   DWORD PTR [esi+ecx-8]   // -8 -7 -6 -5
+            movd        xmm2,   DWORD PTR [esi+ecx+7]   // +7 +8 +9 +10
+
+            punpcklbw   xmm1,   xmm0                    // expanding
+            punpcklbw   xmm2,   xmm0                    // expanding
+
+            punpcklwd   xmm1,   xmm0                    // expanding to dwords
+            punpcklwd   xmm2,   xmm0                    // expanding to dwords
+
+            psubd       xmm2,   xmm1                    // 7--8   8--7   9--6 10--5
+            paddd       xmm1,   xmm1                    // -8*2   -7*2   -6*2 -5*2
+
+            paddd       xmm1,   xmm2                    // 7+-8   8+-7   9+-6 10+-5
+            pmaddwd     xmm1,   xmm2                    // squared of 7+-8   8+-7   9+-6 10+-5
+
+            paddd       xmm6,   xmm2
+            paddd       xmm7,   xmm1
+
+            pshufd      xmm6,   xmm6,   0               // duplicate the last ones
+            pshufd      xmm7,   xmm7,   0               // duplicate the last ones
+
+            psrldq      xmm1,       4                   // 8--7   9--6 10--5  0000
+            psrldq      xmm2,       4                   // 8--7   9--6 10--5  0000
+
+            pshufd      xmm3,   xmm1,   3               // 0000  8--7   8--7   8--7 squared
+            pshufd      xmm4,   xmm2,   3               // 0000  8--7   8--7   8--7 squared
+
+            paddd       xmm6,   xmm4
+            paddd       xmm7,   xmm3
+
+            pshufd      xmm3,   xmm1,   01011111b       // 0000  0000   9--6   9--6 squared
+            pshufd      xmm4,   xmm2,   01011111b       // 0000  0000   9--6   9--6 squared
+
+            paddd       xmm7,   xmm3
+            paddd       xmm6,   xmm4
+
+            pshufd      xmm3,   xmm1,   10111111b       // 0000  0000   8--7   8--7 squared
+            pshufd      xmm4,   xmm2,   10111111b       // 0000  0000   8--7   8--7 squared
+
+            paddd       xmm7,   xmm3
+            paddd       xmm6,   xmm4
+
+            movdqa      xmm3,   xmm6
+            pmaddwd     xmm3,   xmm3
+
+            movdqa      xmm5,   xmm7
+            pslld       xmm5,   4
+
+            psubd       xmm5,   xmm7
+            psubd       xmm5,   xmm3
+
+            psubd       xmm5,   flimit4
+            psrad       xmm5,   31
+
+            packssdw    xmm5,   xmm0
+            packsswb    xmm5,   xmm0
+
+            movd        xmm1,   DWORD PTR [esi+ecx]
+            movq        xmm2,   xmm1
+
+            punpcklbw   xmm1,   xmm0
+            punpcklwd   xmm1,   xmm0
+
+            paddd       xmm1,   xmm6
+            paddd       xmm1,   four8s
+
+            psrad       xmm1,   4
+            packssdw    xmm1,   xmm0
+
+            packuswb    xmm1,   xmm0
+            pand        xmm1,   xmm5
+
+            pandn       xmm5,   xmm2
+            por         xmm5,   xmm1
+
+            movd        [esi+ecx-8],  mm0
+            movq        mm0,    mm1
+
+            movdq2q     mm1,    xmm5
+            psrldq      xmm7,   12
+
+            psrldq      xmm6,   12
+            add         ecx,    4
+
+            cmp         ecx,    edx
+            jl          nextcol4
+
+        }
+        s += pitch;
+    }
+}
+
+#if 0
+
+/****************************************************************************
+ *
+ *  ROUTINE       : plane_add_noise_mmx
+ *
+ *  INPUTS        : unsigned char *Start    starting address of buffer to add gaussian
+ *                                  noise to
+ *                  unsigned int Width    width of plane
+ *                  unsigned int Height   height of plane
+ *                  int  Pitch    distance between subsequent lines of frame
+ *                  int  q        quantizer used to determine amount of noise
+ *                                  to add
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void.
+ *
+ *  FUNCTION      : adds gaussian noise to a plane of pixels
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_plane_add_noise_mmx(unsigned char *Start, unsigned int Width, unsigned int Height, int Pitch, int q, int a)
+{
+    unsigned int i;
+    int Pitch4 = Pitch * 4;
+    const int noise_amount = 2;
+    const int noise_adder = 2 * noise_amount + 1;
+
+    __declspec(align(16)) unsigned char blackclamp[16];
+    __declspec(align(16)) unsigned char whiteclamp[16];
+    __declspec(align(16)) unsigned char bothclamp[16];
+
+    char char_dist[300];
+    char Rand[2048];
+
+    double sigma;
+    __asm emms
+    sigma = a + .5 + .6 * (63 - q) / 63.0;
+
+    // set up a lookup table of 256 entries that matches
+    // a gaussian distribution with sigma determined by q.
+    //
+    {
+        double i, sum = 0;
+        int next, j;
+
+        next = 0;
+
+        for (i = -32; i < 32; i++)
+        {
+            int a = (int)(.5 + 256 * vp8_gaussian(sigma, 0, i));
+
+            if (a)
+            {
+                for (j = 0; j < a; j++)
+                {
+                    char_dist[next+j] = (char) i;
+                }
+
+                next = next + j;
+            }
+
+        }
+
+        for (next = next; next < 256; next++)
+            char_dist[next] = 0;
+
+    }
+
+    for (i = 0; i < 2048; i++)
+    {
+        Rand[i] = char_dist[rand() & 0xff];
+    }
+
+    for (i = 0; i < 16; i++)
+    {
+        blackclamp[i] = -char_dist[0];
+        whiteclamp[i] = -char_dist[0];
+        bothclamp[i] = -2 * char_dist[0];
+    }
+
+    for (i = 0; i < Height; i++)
+    {
+        unsigned char *Pos = Start + i * Pitch;
+        char  *Ref = Rand + (rand() & 0xff);
+
+        __asm
+        {
+            mov ecx, [Width]
+            mov esi, Pos
+            mov edi, Ref
+            xor         eax, eax
+
+            nextset:
+            movq        mm1, [esi+eax]        // get the source
+
+            psubusb     mm1, blackclamp       // clamp both sides so we don't outrange adding noise
+            paddusb     mm1, bothclamp
+            psubusb     mm1, whiteclamp
+
+            movq        mm2, [edi+eax]        // get the noise for this line
+            paddb       mm1, mm2             // add it in
+            movq        [esi+eax], mm1        // store the result
+
+            add         eax, 8                // move to the next line
+
+            cmp         eax, ecx
+            jl          nextset
+
+
+        }
+
+    }
+}
+#else
+extern char an[8][64][3072];
+extern int cd[8][64];
+
+void vp8_plane_add_noise_mmx(unsigned char *Start, unsigned int Width, unsigned int Height, int Pitch, int q, int a)
+{
+    unsigned int i;
+    __declspec(align(16)) unsigned char blackclamp[16];
+    __declspec(align(16)) unsigned char whiteclamp[16];
+    __declspec(align(16)) unsigned char bothclamp[16];
+
+
+    __asm emms
+
+    for (i = 0; i < 16; i++)
+    {
+        blackclamp[i] = -cd[a][q];
+        whiteclamp[i] = -cd[a][q];
+        bothclamp[i] = -2 * cd[a][q];
+    }
+
+    for (i = 0; i < Height; i++)
+    {
+        unsigned char *Pos = Start + i * Pitch;
+        char  *Ref = an[a][q] + (rand() & 0xff);
+
+        __asm
+        {
+            mov ecx, [Width]
+            mov esi, Pos
+            mov edi, Ref
+            xor         eax, eax
+
+            nextset:
+            movq        mm1, [esi+eax]        // get the source
+
+            psubusb     mm1, blackclamp       // clamp both sides so we don't outrange adding noise
+            paddusb     mm1, bothclamp
+            psubusb     mm1, whiteclamp
+
+            movq        mm2, [edi+eax]        // get the noise for this line
+            paddb       mm1, mm2             // add it in
+            movq        [esi+eax], mm1        // store the result
+
+            add         eax, 8                // move to the next line
+
+            cmp         eax, ecx
+            jl          nextset
+        }
+    }
+}
+
+
+void vp8_plane_add_noise_wmt(unsigned char *Start, unsigned int Width, unsigned int Height, int Pitch, int q, int a)
+{
+    unsigned int i;
+
+    __declspec(align(16)) unsigned char blackclamp[16];
+    __declspec(align(16)) unsigned char whiteclamp[16];
+    __declspec(align(16)) unsigned char bothclamp[16];
+
+    __asm emms
+
+    for (i = 0; i < 16; i++)
+    {
+        blackclamp[i] = -cd[a][q];
+        whiteclamp[i] = -cd[a][q];
+        bothclamp[i] = -2 * cd[a][q];
+    }
+
+    for (i = 0; i < Height; i++)
+    {
+        unsigned char *Pos = Start + i * Pitch;
+        char *Ref = an[a][q] + (rand() & 0xff);
+
+        __asm
+        {
+            mov ecx,    [Width]
+            mov esi,    Pos
+            mov edi,    Ref
+            xor         eax, eax
+
+            nextset:
+            movdqu      xmm1, [esi+eax]        // get the source
+
+            psubusb     xmm1, blackclamp       // clamp both sides so we don't outrange adding noise
+            paddusb     xmm1, bothclamp
+            psubusb     xmm1, whiteclamp
+
+            movdqu      xmm2, [edi+eax]        // get the noise for this line
+            paddb       xmm1, xmm2             // add it in
+            movdqu      [esi+eax], xmm1        // store the result
+
+            add         eax, 16                // move to the next line
+
+            cmp         eax, ecx
+            jl          nextset
+        }
+    }
+}
+
+#endif
diff --git a/vp8/common/x86/postproc_sse2.asm b/vp8/common/x86/postproc_sse2.asm
new file mode 100644 (file)
index 0000000..bfa36fa
--- /dev/null
@@ -0,0 +1,688 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;void vp8_post_proc_down_and_across_xmm
+;(
+;    unsigned char *src_ptr,
+;    unsigned char *dst_ptr,
+;    int src_pixels_per_line,
+;    int dst_pixels_per_line,
+;    int rows,
+;    int cols,
+;    int flimit
+;)
+global sym(vp8_post_proc_down_and_across_xmm)
+sym(vp8_post_proc_down_and_across_xmm):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+%if ABI_IS_32BIT=1 && CONFIG_PIC=1
+    ALIGN_STACK 16, rax
+    ; move the global rd onto the stack, since we don't have enough registers
+    ; to do PIC addressing
+    movdqa      xmm0, [rd42 GLOBAL]
+    sub         rsp, 16
+    movdqa      [rsp], xmm0
+%define RD42 [rsp]
+%else
+%define RD42 [rd42 GLOBAL]
+%endif
+
+
+        movd        xmm2,       dword ptr arg(6) ;flimit
+        punpcklwd   xmm2,       xmm2
+        punpckldq   xmm2,       xmm2
+        punpcklqdq  xmm2,       xmm2
+
+        mov         rsi,        arg(0) ;src_ptr
+        mov         rdi,        arg(1) ;dst_ptr
+
+        movsxd      rcx,        DWORD PTR arg(4) ;rows
+        movsxd      rax,        DWORD PTR arg(2) ;src_pixels_per_line ; destination pitch?
+        pxor        xmm0,       xmm0              ; mm0 = 00000000
+
+nextrow:
+
+        xor         rdx,        rdx       ; clear out rdx for use as loop counter
+nextcol:
+        movq        xmm3,       QWORD PTR [rsi]         ; mm4 = r0 p0..p7
+        punpcklbw   xmm3,       xmm0                    ; mm3 = p0..p3
+        movdqa      xmm1,       xmm3                    ; mm1 = p0..p3
+        psllw       xmm3,       2                       ;
+
+        movq        xmm5,       QWORD PTR [rsi + rax]   ; mm4 = r1 p0..p7
+        punpcklbw   xmm5,       xmm0                    ; mm5 = r1 p0..p3
+        paddusw     xmm3,       xmm5                    ; mm3 += mm6
+
+        ; thresholding
+        movdqa      xmm7,       xmm1                    ; mm7 = r0 p0..p3
+        psubusw     xmm7,       xmm5                    ; mm7 = r0 p0..p3 - r1 p0..p3
+        psubusw     xmm5,       xmm1                    ; mm5 = r1 p0..p3 - r0 p0..p3
+        paddusw     xmm7,       xmm5                    ; mm7 = abs(r0 p0..p3 - r1 p0..p3)
+        pcmpgtw     xmm7,       xmm2
+
+        movq        xmm5,       QWORD PTR [rsi + 2*rax] ; mm4 = r2 p0..p7
+        punpcklbw   xmm5,       xmm0                    ; mm5 = r2 p0..p3
+        paddusw     xmm3,       xmm5                    ; mm3 += mm5
+
+        ; thresholding
+        movdqa      xmm6,       xmm1                    ; mm6 = r0 p0..p3
+        psubusw     xmm6,       xmm5                    ; mm6 = r0 p0..p3 - r2 p0..p3
+        psubusw     xmm5,       xmm1                    ; mm5 = r2 p0..p3 - r2 p0..p3
+        paddusw     xmm6,       xmm5                    ; mm6 = abs(r0 p0..p3 - r2 p0..p3)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6                    ; accumulate thresholds
+
+
+        neg         rax
+        movq        xmm5,       QWORD PTR [rsi+2*rax]   ; mm4 = r-2 p0..p7
+        punpcklbw   xmm5,       xmm0                    ; mm5 = r-2 p0..p3
+        paddusw     xmm3,       xmm5                    ; mm3 += mm5
+
+        ; thresholding
+        movdqa      xmm6,       xmm1                    ; mm6 = r0 p0..p3
+        psubusw     xmm6,       xmm5                    ; mm6 = p0..p3 - r-2 p0..p3
+        psubusw     xmm5,       xmm1                    ; mm5 = r-2 p0..p3 - p0..p3
+        paddusw     xmm6,       xmm5                    ; mm6 = abs(r0 p0..p3 - r-2 p0..p3)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6                    ; accumulate thresholds
+
+        movq        xmm4,       QWORD PTR [rsi+rax]     ; mm4 = r-1 p0..p7
+        punpcklbw   xmm4,       xmm0                    ; mm4 = r-1 p0..p3
+        paddusw     xmm3,       xmm4                    ; mm3 += mm5
+
+        ; thresholding
+        movdqa      xmm6,       xmm1                    ; mm6 = r0 p0..p3
+        psubusw     xmm6,       xmm4                    ; mm6 = p0..p3 - r-2 p0..p3
+        psubusw     xmm4,       xmm1                    ; mm5 = r-1 p0..p3 - p0..p3
+        paddusw     xmm6,       xmm4                    ; mm6 = abs(r0 p0..p3 - r-1 p0..p3)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6                    ; accumulate thresholds
+
+
+        paddusw     xmm3,       RD42                    ; mm3 += round value
+        psraw       xmm3,       3                       ; mm3 /= 8
+
+        pand        xmm1,       xmm7                    ; mm1 select vals > thresh from source
+        pandn       xmm7,       xmm3                    ; mm7 select vals < thresh from blurred result
+        paddusw     xmm1,       xmm7                    ; combination
+
+        packuswb    xmm1,       xmm0                    ; pack to bytes
+        movq        QWORD PTR [rdi], xmm1             ;
+
+        neg         rax                   ; pitch is positive
+        add         rsi,        8
+        add         rdi,        8
+
+        add         rdx,        8
+        cmp         edx,        dword arg(5) ;cols
+
+        jl          nextcol
+
+        ; done with the all cols, start the across filtering in place
+        sub         rsi,        rdx
+        sub         rdi,        rdx
+
+        xor         rdx,        rdx
+        movq        mm0,        QWORD PTR [rdi-8];
+
+acrossnextcol:
+        movq        xmm7,       QWORD PTR [rdi +rdx -2]
+        movd        xmm4,       DWORD PTR [rdi +rdx +6]
+
+        pslldq      xmm4,       8
+        por         xmm4,       xmm7
+
+        movdqa      xmm3,       xmm4
+        psrldq      xmm3,       2
+        punpcklbw   xmm3,       xmm0              ; mm3 = p0..p3
+        movdqa      xmm1,       xmm3              ; mm1 = p0..p3
+        psllw       xmm3,       2
+
+
+        movdqa      xmm5,       xmm4
+        psrldq      xmm5,       3
+        punpcklbw   xmm5,       xmm0              ; mm5 = p1..p4
+        paddusw     xmm3,       xmm5              ; mm3 += mm6
+
+        ; thresholding
+        movdqa      xmm7,       xmm1              ; mm7 = p0..p3
+        psubusw     xmm7,       xmm5              ; mm7 = p0..p3 - p1..p4
+        psubusw     xmm5,       xmm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     xmm7,       xmm5              ; mm7 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm7,       xmm2
+
+        movdqa      xmm5,       xmm4
+        psrldq      xmm5,       4
+        punpcklbw   xmm5,       xmm0              ; mm5 = p2..p5
+        paddusw     xmm3,       xmm5              ; mm3 += mm5
+
+        ; thresholding
+        movdqa      xmm6,       xmm1              ; mm6 = p0..p3
+        psubusw     xmm6,       xmm5              ; mm6 = p0..p3 - p1..p4
+        psubusw     xmm5,       xmm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     xmm6,       xmm5              ; mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6              ; accumulate thresholds
+
+
+        movdqa      xmm5,       xmm4              ; mm5 = p-2..p5
+        punpcklbw   xmm5,       xmm0              ; mm5 = p-2..p1
+        paddusw     xmm3,       xmm5              ; mm3 += mm5
+
+        ; thresholding
+        movdqa      xmm6,       xmm1              ; mm6 = p0..p3
+        psubusw     xmm6,       xmm5              ; mm6 = p0..p3 - p1..p4
+        psubusw     xmm5,       xmm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     xmm6,       xmm5              ; mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6              ; accumulate thresholds
+
+        psrldq      xmm4,       1                   ; mm4 = p-1..p5
+        punpcklbw   xmm4,       xmm0              ; mm4 = p-1..p2
+        paddusw     xmm3,       xmm4              ; mm3 += mm5
+
+        ; thresholding
+        movdqa      xmm6,       xmm1              ; mm6 = p0..p3
+        psubusw     xmm6,       xmm4              ; mm6 = p0..p3 - p1..p4
+        psubusw     xmm4,       xmm1              ; mm5 = p1..p4 - p0..p3
+        paddusw     xmm6,       xmm4              ; mm6 = abs(p0..p3 - p1..p4)
+        pcmpgtw     xmm6,       xmm2
+        por         xmm7,       xmm6              ; accumulate thresholds
+
+        paddusw     xmm3,       RD42              ; mm3 += round value
+        psraw       xmm3,       3                 ; mm3 /= 8
+
+        pand        xmm1,       xmm7              ; mm1 select vals > thresh from source
+        pandn       xmm7,       xmm3              ; mm7 select vals < thresh from blurred result
+        paddusw     xmm1,       xmm7              ; combination
+
+        packuswb    xmm1,       xmm0              ; pack to bytes
+        movq        QWORD PTR [rdi+rdx-8],  mm0   ; store previous four bytes
+        movdq2q     mm0,        xmm1
+
+        add         rdx,        8
+        cmp         edx,        dword arg(5) ;cols
+        jl          acrossnextcol;
+
+        ; last 8 pixels
+        movq        QWORD PTR [rdi+rdx-8],  mm0
+
+        ; done with this rwo
+        add         rsi,rax               ; next line
+        mov         eax, dword arg(3) ;dst_pixels_per_line ; destination pitch?
+        add         rdi,rax               ; next destination
+        mov         eax, dword arg(2) ;src_pixels_per_line ; destination pitch?
+
+        dec         rcx                   ; decrement count
+        jnz         nextrow               ; next row
+
+%if ABI_IS_32BIT=1 && CONFIG_PIC=1
+    add rsp,16
+    pop rsp
+%endif
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+%undef RD42
+
+
+;void vp8_mbpost_proc_down_xmm(unsigned char *dst,
+;                            int pitch, int rows, int cols,int flimit)
+extern sym(vp8_rv)
+global sym(vp8_mbpost_proc_down_xmm)
+sym(vp8_mbpost_proc_down_xmm):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 128+16
+
+    ; unsigned char d[16][8] at [rsp]
+    ; create flimit2 at [rsp+128]
+    mov         eax, dword ptr arg(4) ;flimit
+    mov         [rsp+128], eax
+    mov         [rsp+128+4], eax
+    mov         [rsp+128+8], eax
+    mov         [rsp+128+12], eax
+%define flimit4 [rsp+128]
+
+%if ABI_IS_32BIT=0
+    lea         r8,       [sym(vp8_rv) GLOBAL]
+%endif
+
+    ;rows +=8;
+    add         dword arg(2), 8
+
+    ;for(c=0; c<cols; c+=8)
+loop_col:
+            mov         rsi,        arg(0) ; s
+            pxor        xmm0,       xmm0        ;
+
+            movsxd      rax,        dword ptr arg(1) ;pitch       ;
+            neg         rax                                     ; rax = -pitch
+
+            lea         rsi,        [rsi + rax*8];              ; rdi = s[-pitch*8]
+            neg         rax
+
+
+            pxor        xmm5,       xmm5
+            pxor        xmm6,       xmm6        ;
+
+            pxor        xmm7,       xmm7        ;
+            mov         rdi,        rsi
+
+            mov         rcx,        15          ;
+
+loop_initvar:
+            movq        xmm1,       QWORD PTR [rdi];
+            punpcklbw   xmm1,       xmm0        ;
+
+            paddw       xmm5,       xmm1        ;
+            pmullw      xmm1,       xmm1        ;
+
+            movdqa      xmm2,       xmm1        ;
+            punpcklwd   xmm1,       xmm0        ;
+
+            punpckhwd   xmm2,       xmm0        ;
+            paddd       xmm6,       xmm1        ;
+
+            paddd       xmm7,       xmm2        ;
+            lea         rdi,        [rdi+rax]   ;
+
+            dec         rcx
+            jne         loop_initvar
+            ;save the var and sum
+            xor         rdx,        rdx
+loop_row:
+            movq        xmm1,       QWORD PTR [rsi]     ; [s-pitch*8]
+            movq        xmm2,       QWORD PTR [rdi]     ; [s+pitch*7]
+
+            punpcklbw   xmm1,       xmm0
+            punpcklbw   xmm2,       xmm0
+
+            paddw       xmm5,       xmm2
+            psubw       xmm5,       xmm1
+
+            pmullw      xmm2,       xmm2
+            movdqa      xmm4,       xmm2
+
+            punpcklwd   xmm2,       xmm0
+            punpckhwd   xmm4,       xmm0
+
+            paddd       xmm6,       xmm2
+            paddd       xmm7,       xmm4
+
+            pmullw      xmm1,       xmm1
+            movdqa      xmm2,       xmm1
+
+            punpcklwd   xmm1,       xmm0
+            psubd       xmm6,       xmm1
+
+            punpckhwd   xmm2,       xmm0
+            psubd       xmm7,       xmm2
+
+
+            movdqa      xmm3,       xmm6
+            pslld       xmm3,       4
+
+            psubd       xmm3,       xmm6
+            movdqa      xmm1,       xmm5
+
+            movdqa      xmm4,       xmm5
+            pmullw      xmm1,       xmm1
+
+            pmulhw      xmm4,       xmm4
+            movdqa      xmm2,       xmm1
+
+            punpcklwd   xmm1,       xmm4
+            punpckhwd   xmm2,       xmm4
+
+            movdqa      xmm4,       xmm7
+            pslld       xmm4,       4
+
+            psubd       xmm4,       xmm7
+
+            psubd       xmm3,       xmm1
+            psubd       xmm4,       xmm2
+
+            psubd       xmm3,       flimit4
+            psubd       xmm4,       flimit4
+
+            psrad       xmm3,       31
+            psrad       xmm4,       31
+
+            packssdw    xmm3,       xmm4
+            packsswb    xmm3,       xmm0
+
+            movq        xmm1,       QWORD PTR [rsi+rax*8]
+
+            movq        xmm2,       xmm1
+            punpcklbw   xmm1,       xmm0
+
+            paddw       xmm1,       xmm5
+            mov         rcx,        rdx
+
+            and         rcx,        127
+%if ABI_IS_32BIT=1 && CONFIG_PIC=1
+            push        rax
+            lea         rax,        [sym(vp8_rv) GLOBAL]
+            movdqu      xmm4,       [rax + rcx*2] ;vp8_rv[rcx*2]
+            pop         rax
+%elif ABI_IS_32BIT=0
+            movdqu      xmm4,       [r8 + rcx*2] ;vp8_rv[rcx*2]
+%else
+            movdqu      xmm4,       [sym(vp8_rv) + rcx*2]
+%endif
+
+            paddw       xmm1,       xmm4
+            ;paddw     xmm1,       eight8s
+            psraw       xmm1,       4
+
+            packuswb    xmm1,       xmm0
+            pand        xmm1,       xmm3
+
+            pandn       xmm3,       xmm2
+            por         xmm1,       xmm3
+
+            and         rcx,        15
+            movq        QWORD PTR   [rsp + rcx*8], xmm1 ;d[rcx*8]
+
+            mov         rcx,        rdx
+            sub         rcx,        8
+
+            and         rcx,        15
+            movq        mm0,        [rsp + rcx*8] ;d[rcx*8]
+
+            movq        [rsi],      mm0
+            lea         rsi,        [rsi+rax]
+
+            lea         rdi,        [rdi+rax]
+            add         rdx,        1
+
+            cmp         edx,        dword arg(2) ;rows
+            jl          loop_row
+
+        add         dword arg(0), 8 ; s += 8
+        sub         dword arg(3), 8 ; cols -= 8
+        cmp         dword arg(3), 0
+        jg          loop_col
+
+    add         rsp, 128+16
+    pop         rsp
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+%undef flimit4
+
+
+;void vp8_mbpost_proc_across_ip_xmm(unsigned char *src,
+;                                int pitch, int rows, int cols,int flimit)
+global sym(vp8_mbpost_proc_across_ip_xmm)
+sym(vp8_mbpost_proc_across_ip_xmm):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 16
+
+    ; create flimit4 at [rsp]
+    mov         eax, dword ptr arg(4) ;flimit
+    mov         [rsp], eax
+    mov         [rsp+4], eax
+    mov         [rsp+8], eax
+    mov         [rsp+12], eax
+%define flimit4 [rsp]
+
+
+    ;for(r=0;r<rows;r++)
+ip_row_loop:
+
+        xor         rdx,    rdx ;sumsq=0;
+        xor         rcx,    rcx ;sum=0;
+        mov         rsi,    arg(0); s
+        mov         rdi,    -8
+ip_var_loop:
+        ;for(i=-8;i<=6;i++)
+        ;{
+        ;    sumsq += s[i]*s[i];
+        ;    sum   += s[i];
+        ;}
+        movzx       eax, byte [rsi+rdi]
+        add         ecx, eax
+        mul         al
+        add         edx, eax
+        add         rdi, 1
+        cmp         rdi, 6
+        jle         ip_var_loop
+
+
+            ;mov         rax,    sumsq
+            ;movd        xmm7,   rax
+            movd        xmm7,   edx
+
+            ;mov         rax,    sum
+            ;movd        xmm6,   rax
+            movd        xmm6,   ecx
+
+            mov         rsi,    arg(0) ;s
+            xor         rcx,    rcx
+
+            movsxd      rdx,    dword arg(3) ;cols
+            add         rdx,    8
+            pxor        mm0,    mm0
+            pxor        mm1,    mm1
+
+            pxor        xmm0,   xmm0
+nextcol4:
+
+            movd        xmm1,   DWORD PTR [rsi+rcx-8]   ; -8 -7 -6 -5
+            movd        xmm2,   DWORD PTR [rsi+rcx+7]   ; +7 +8 +9 +10
+
+            punpcklbw   xmm1,   xmm0                    ; expanding
+            punpcklbw   xmm2,   xmm0                    ; expanding
+
+            punpcklwd   xmm1,   xmm0                    ; expanding to dwords
+            punpcklwd   xmm2,   xmm0                    ; expanding to dwords
+
+            psubd       xmm2,   xmm1                    ; 7--8   8--7   9--6 10--5
+            paddd       xmm1,   xmm1                    ; -8*2   -7*2   -6*2 -5*2
+
+            paddd       xmm1,   xmm2                    ; 7+-8   8+-7   9+-6 10+-5
+            pmaddwd     xmm1,   xmm2                    ; squared of 7+-8   8+-7   9+-6 10+-5
+
+            paddd       xmm6,   xmm2
+            paddd       xmm7,   xmm1
+
+            pshufd      xmm6,   xmm6,   0               ; duplicate the last ones
+            pshufd      xmm7,   xmm7,   0               ; duplicate the last ones
+
+            psrldq      xmm1,       4                   ; 8--7   9--6 10--5  0000
+            psrldq      xmm2,       4                   ; 8--7   9--6 10--5  0000
+
+            pshufd      xmm3,   xmm1,   3               ; 0000  8--7   8--7   8--7 squared
+            pshufd      xmm4,   xmm2,   3               ; 0000  8--7   8--7   8--7 squared
+
+            paddd       xmm6,   xmm4
+            paddd       xmm7,   xmm3
+
+            pshufd      xmm3,   xmm1,   01011111b       ; 0000  0000   9--6   9--6 squared
+            pshufd      xmm4,   xmm2,   01011111b       ; 0000  0000   9--6   9--6 squared
+
+            paddd       xmm7,   xmm3
+            paddd       xmm6,   xmm4
+
+            pshufd      xmm3,   xmm1,   10111111b       ; 0000  0000   8--7   8--7 squared
+            pshufd      xmm4,   xmm2,   10111111b       ; 0000  0000   8--7   8--7 squared
+
+            paddd       xmm7,   xmm3
+            paddd       xmm6,   xmm4
+
+            movdqa      xmm3,   xmm6
+            pmaddwd     xmm3,   xmm3
+
+            movdqa      xmm5,   xmm7
+            pslld       xmm5,   4
+
+            psubd       xmm5,   xmm7
+            psubd       xmm5,   xmm3
+
+            psubd       xmm5,   flimit4
+            psrad       xmm5,   31
+
+            packssdw    xmm5,   xmm0
+            packsswb    xmm5,   xmm0
+
+            movd        xmm1,   DWORD PTR [rsi+rcx]
+            movq        xmm2,   xmm1
+
+            punpcklbw   xmm1,   xmm0
+            punpcklwd   xmm1,   xmm0
+
+            paddd       xmm1,   xmm6
+            paddd       xmm1,   [four8s GLOBAL]
+
+            psrad       xmm1,   4
+            packssdw    xmm1,   xmm0
+
+            packuswb    xmm1,   xmm0
+            pand        xmm1,   xmm5
+
+            pandn       xmm5,   xmm2
+            por         xmm5,   xmm1
+
+            movd        [rsi+rcx-8],  mm0
+            movq        mm0,    mm1
+
+            movdq2q     mm1,    xmm5
+            psrldq      xmm7,   12
+
+            psrldq      xmm6,   12
+            add         rcx,    4
+
+            cmp         rcx,    rdx
+            jl          nextcol4
+
+        ;s+=pitch;
+        movsxd rax, dword arg(1)
+        add    arg(0), rax
+
+        sub dword arg(2), 1 ;rows-=1
+        cmp dword arg(2), 0
+        jg ip_row_loop
+
+    add         rsp, 16
+    pop         rsp
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+%undef flimit4
+
+
+;void vp8_plane_add_noise_wmt (unsigned char *Start, unsigned char *noise,
+;                            unsigned char blackclamp[16],
+;                            unsigned char whiteclamp[16],
+;                            unsigned char bothclamp[16],
+;                            unsigned int Width, unsigned int Height, int Pitch)
+extern sym(rand)
+global sym(vp8_plane_add_noise_wmt)
+sym(vp8_plane_add_noise_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+addnoise_loop:
+    call sym(rand) WRT_PLT
+    mov     rcx, arg(1) ;noise
+    and     rax, 0xff
+    add     rcx, rax
+
+    ; we rely on the fact that the clamping vectors are stored contiguously
+    ; in black/white/both order. Note that we have to reload this here because
+    ; rdx could be trashed by rand()
+    mov     rdx, arg(2) ; blackclamp
+
+
+            mov     rdi, rcx
+            movsxd  rcx, dword arg(5) ;[Width]
+            mov     rsi, arg(0) ;Pos
+            xor         rax,rax
+
+addnoise_nextset:
+            movdqu      xmm1,[rsi+rax]         ; get the source
+
+            psubusb     xmm1, [rdx]    ;blackclamp        ; clamp both sides so we don't outrange adding noise
+            paddusb     xmm1, [rdx+32] ;bothclamp
+            psubusb     xmm1, [rdx+16] ;whiteclamp
+
+            movdqu      xmm2,[rdi+rax]         ; get the noise for this line
+            paddb       xmm1,xmm2              ; add it in
+            movdqu      [rsi+rax],xmm1         ; store the result
+
+            add         rax,16                 ; move to the next line
+
+            cmp         rax, rcx
+            jl          addnoise_nextset
+
+    movsxd  rax, dword arg(7) ; Pitch
+    add     arg(0), rax ; Start += Pitch
+    sub     dword arg(6), 1   ; Height -= 1
+    jg      addnoise_loop
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+align 16
+rd42:
+    times 8 dw 0x04
+four8s:
+    times 4 dd 8
diff --git a/vp8/common/x86/postproc_x86.h b/vp8/common/x86/postproc_x86.h
new file mode 100644 (file)
index 0000000..49a1907
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef POSTPROC_X86_H
+#define POSTPROC_X86_H
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+
+#if HAVE_MMX
+extern prototype_postproc_inplace(vp8_mbpost_proc_down_mmx);
+extern prototype_postproc(vp8_post_proc_down_and_across_mmx);
+extern prototype_postproc_addnoise(vp8_plane_add_noise_mmx);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_postproc_down
+#define vp8_postproc_down vp8_mbpost_proc_down_mmx
+
+#undef  vp8_postproc_downacross
+#define vp8_postproc_downacross vp8_post_proc_down_and_across_mmx
+
+#undef  vp8_postproc_addnoise
+#define vp8_postproc_addnoise vp8_plane_add_noise_mmx
+
+#endif
+#endif
+
+
+#if HAVE_SSE2
+extern prototype_postproc_inplace(vp8_mbpost_proc_down_xmm);
+extern prototype_postproc_inplace(vp8_mbpost_proc_across_ip_xmm);
+extern prototype_postproc(vp8_post_proc_down_and_across_xmm);
+extern prototype_postproc_addnoise(vp8_plane_add_noise_wmt);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_postproc_down
+#define vp8_postproc_down vp8_mbpost_proc_down_xmm
+
+#undef  vp8_postproc_across
+#define vp8_postproc_across vp8_mbpost_proc_across_ip_xmm
+
+#undef  vp8_postproc_downacross
+#define vp8_postproc_downacross vp8_post_proc_down_and_across_xmm
+
+#undef  vp8_postproc_addnoise
+#define vp8_postproc_addnoise vp8_plane_add_noise_wmt
+
+
+#endif
+#endif
+
+#endif
diff --git a/vp8/common/x86/recon_mmx.asm b/vp8/common/x86/recon_mmx.asm
new file mode 100644 (file)
index 0000000..ba60c5d
--- /dev/null
@@ -0,0 +1,320 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+;void vp8_recon_b_mmx(unsigned char *s, short *q, unsigned char *d, int stride)
+global sym(vp8_recon_b_mmx)
+sym(vp8_recon_b_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov       rsi, arg(0) ;s
+        mov       rdi, arg(2) ;d
+        mov       rdx, arg(1) ;q
+        movsxd    rax, dword ptr arg(3) ;stride
+        pxor      mm0, mm0
+
+        movd      mm1, [rsi]
+        punpcklbw mm1, mm0
+        paddsw    mm1, [rdx]
+        packuswb  mm1,  mm0              ; pack and unpack to saturate
+        movd      [rdi], mm1
+
+        movd      mm2, [rsi+16]
+        punpcklbw mm2, mm0
+        paddsw    mm2, [rdx+32]
+        packuswb  mm2, mm0              ; pack and unpack to saturate
+        movd      [rdi+rax], mm2
+
+        movd      mm3, [rsi+32]
+        punpcklbw mm3, mm0
+        paddsw    mm3, [rdx+64]
+        packuswb  mm3,  mm0              ; pack and unpack to saturate
+        movd      [rdi+2*rax], mm3
+
+        add       rdi, rax
+        movd      mm4, [rsi+48]
+        punpcklbw mm4, mm0
+        paddsw    mm4, [rdx+96]
+        packuswb  mm4, mm0              ; pack and unpack to saturate
+        movd      [rdi+2*rax], mm4
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void copy_mem8x8_mmx(
+;    unsigned char *src,
+;    int src_stride,
+;    unsigned char *dst,
+;    int dst_stride
+;    )
+global sym(vp8_copy_mem8x8_mmx)
+sym(vp8_copy_mem8x8_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;src;
+        movq        mm0,        [rsi]
+
+        movsxd      rax,        dword ptr arg(1) ;src_stride;
+        mov         rdi,        arg(2) ;dst;
+
+        movq        mm1,        [rsi+rax]
+        movq        mm2,        [rsi+rax*2]
+
+        movsxd      rcx,        dword ptr arg(3) ;dst_stride
+        lea         rsi,        [rsi+rax*2]
+
+        movq        [rdi],      mm0
+        add         rsi,        rax
+
+        movq        [rdi+rcx],      mm1
+        movq        [rdi+rcx*2],    mm2
+
+
+        lea         rdi,        [rdi+rcx*2]
+        movq        mm3,        [rsi]
+
+        add         rdi,        rcx
+        movq        mm4,        [rsi+rax]
+
+        movq        mm5,        [rsi+rax*2]
+        movq        [rdi],      mm3
+
+        lea         rsi,        [rsi+rax*2]
+        movq        [rdi+rcx],  mm4
+
+        movq        [rdi+rcx*2],    mm5
+        lea         rdi,        [rdi+rcx*2]
+
+        movq        mm0,        [rsi+rax]
+        movq        mm1,        [rsi+rax*2]
+
+        movq        [rdi+rcx],  mm0
+        movq        [rdi+rcx*2],mm1
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void copy_mem8x4_mmx(
+;    unsigned char *src,
+;    int src_stride,
+;    unsigned char *dst,
+;    int dst_stride
+;    )
+global sym(vp8_copy_mem8x4_mmx)
+sym(vp8_copy_mem8x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;src;
+        movq        mm0,        [rsi]
+
+        movsxd      rax,        dword ptr arg(1) ;src_stride;
+        mov         rdi,        arg(2) ;dst;
+
+        movq        mm1,        [rsi+rax]
+        movq        mm2,        [rsi+rax*2]
+
+        movsxd      rcx,        dword ptr arg(3) ;dst_stride
+        lea         rsi,        [rsi+rax*2]
+
+        movq        [rdi],      mm0
+        movq        [rdi+rcx],      mm1
+
+        movq        [rdi+rcx*2],    mm2
+        lea         rdi,        [rdi+rcx*2]
+
+        movq        mm3,        [rsi+rax]
+        movq        [rdi+rcx],      mm3
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void copy_mem16x16_mmx(
+;    unsigned char *src,
+;    int src_stride,
+;    unsigned char *dst,
+;    int dst_stride
+;    )
+global sym(vp8_copy_mem16x16_mmx)
+sym(vp8_copy_mem16x16_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;src;
+        movsxd      rax,        dword ptr arg(1) ;src_stride;
+
+        mov         rdi,        arg(2) ;dst;
+        movsxd      rcx,        dword ptr arg(3) ;dst_stride
+
+        movq        mm0,            [rsi]
+        movq        mm3,            [rsi+8];
+
+        movq        mm1,            [rsi+rax]
+        movq        mm4,            [rsi+rax+8]
+
+        movq        mm2,            [rsi+rax*2]
+        movq        mm5,            [rsi+rax*2+8]
+
+        lea         rsi,            [rsi+rax*2]
+        add         rsi,            rax
+
+        movq        [rdi],          mm0
+        movq        [rdi+8],        mm3
+
+        movq        [rdi+rcx],      mm1
+        movq        [rdi+rcx+8],    mm4
+
+        movq        [rdi+rcx*2],    mm2
+        movq        [rdi+rcx*2+8],  mm5
+
+        lea         rdi,            [rdi+rcx*2]
+        add         rdi,            rcx
+
+        movq        mm0,            [rsi]
+        movq        mm3,            [rsi+8];
+
+        movq        mm1,            [rsi+rax]
+        movq        mm4,            [rsi+rax+8]
+
+        movq        mm2,            [rsi+rax*2]
+        movq        mm5,            [rsi+rax*2+8]
+
+        lea         rsi,            [rsi+rax*2]
+        add         rsi,            rax
+
+        movq        [rdi],          mm0
+        movq        [rdi+8],        mm3
+
+        movq        [rdi+rcx],      mm1
+        movq        [rdi+rcx+8],    mm4
+
+        movq        [rdi+rcx*2],    mm2
+        movq        [rdi+rcx*2+8],  mm5
+
+        lea         rdi,            [rdi+rcx*2]
+        add         rdi,            rcx
+
+        movq        mm0,            [rsi]
+        movq        mm3,            [rsi+8];
+
+        movq        mm1,            [rsi+rax]
+        movq        mm4,            [rsi+rax+8]
+
+        movq        mm2,            [rsi+rax*2]
+        movq        mm5,            [rsi+rax*2+8]
+
+        lea         rsi,            [rsi+rax*2]
+        add         rsi,            rax
+
+        movq        [rdi],          mm0
+        movq        [rdi+8],        mm3
+
+        movq        [rdi+rcx],      mm1
+        movq        [rdi+rcx+8],    mm4
+
+        movq        [rdi+rcx*2],    mm2
+        movq        [rdi+rcx*2+8],  mm5
+
+        lea         rdi,            [rdi+rcx*2]
+        add         rdi,            rcx
+
+        movq        mm0,            [rsi]
+        movq        mm3,            [rsi+8];
+
+        movq        mm1,            [rsi+rax]
+        movq        mm4,            [rsi+rax+8]
+
+        movq        mm2,            [rsi+rax*2]
+        movq        mm5,            [rsi+rax*2+8]
+
+        lea         rsi,            [rsi+rax*2]
+        add         rsi,            rax
+
+        movq        [rdi],          mm0
+        movq        [rdi+8],        mm3
+
+        movq        [rdi+rcx],      mm1
+        movq        [rdi+rcx+8],    mm4
+
+        movq        [rdi+rcx*2],    mm2
+        movq        [rdi+rcx*2+8],  mm5
+
+        lea         rdi,            [rdi+rcx*2]
+        add         rdi,            rcx
+
+        movq        mm0,            [rsi]
+        movq        mm3,            [rsi+8];
+
+        movq        mm1,            [rsi+rax]
+        movq        mm4,            [rsi+rax+8]
+
+        movq        mm2,            [rsi+rax*2]
+        movq        mm5,            [rsi+rax*2+8]
+
+        lea         rsi,            [rsi+rax*2]
+        add         rsi,            rax
+
+        movq        [rdi],          mm0
+        movq        [rdi+8],        mm3
+
+        movq        [rdi+rcx],      mm1
+        movq        [rdi+rcx+8],    mm4
+
+        movq        [rdi+rcx*2],    mm2
+        movq        [rdi+rcx*2+8],  mm5
+
+        lea         rdi,            [rdi+rcx*2]
+        add         rdi,            rcx
+
+        movq        mm0,            [rsi]
+        movq        mm3,            [rsi+8];
+
+        movq        [rdi],          mm0
+        movq        [rdi+8],        mm3
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/common/x86/recon_sse2.asm b/vp8/common/x86/recon_sse2.asm
new file mode 100644 (file)
index 0000000..f2685a7
--- /dev/null
@@ -0,0 +1,228 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+;void vp8_recon2b_sse2(unsigned char *s, short *q, unsigned char *d, int stride)
+global sym(vp8_recon2b_sse2)
+sym(vp8_recon2b_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;s
+        mov         rdi,        arg(2) ;d
+        mov         rdx,        arg(1) ;q
+        movsxd      rax,        dword ptr arg(3) ;stride
+        pxor        xmm0,       xmm0
+
+        movq        xmm1,       MMWORD PTR [rsi]
+        punpcklbw   xmm1,       xmm0
+        paddsw      xmm1,       XMMWORD PTR [rdx]
+        packuswb    xmm1,       xmm0              ; pack and unpack to saturate
+        movq        MMWORD PTR [rdi],   xmm1
+
+
+        movq        xmm2,       MMWORD PTR [rsi+8]
+        punpcklbw   xmm2,       xmm0
+        paddsw      xmm2,       XMMWORD PTR [rdx+16]
+        packuswb    xmm2,       xmm0              ; pack and unpack to saturate
+        movq        MMWORD PTR [rdi+rax],   xmm2
+
+
+        movq        xmm3,       MMWORD PTR [rsi+16]
+        punpcklbw   xmm3,       xmm0
+        paddsw      xmm3,       XMMWORD PTR [rdx+32]
+        packuswb    xmm3,       xmm0              ; pack and unpack to saturate
+        movq        MMWORD PTR [rdi+rax*2], xmm3
+
+        add         rdi, rax
+        movq        xmm4,       MMWORD PTR [rsi+24]
+        punpcklbw   xmm4,       xmm0
+        paddsw      xmm4,       XMMWORD PTR [rdx+48]
+        packuswb    xmm4,       xmm0              ; pack and unpack to saturate
+        movq        MMWORD PTR [rdi+rax*2], xmm4
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_recon4b_sse2(unsigned char *s, short *q, unsigned char *d, int stride)
+global sym(vp8_recon4b_sse2)
+sym(vp8_recon4b_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;s
+        mov         rdi,        arg(2) ;d
+        mov         rdx,        arg(1) ;q
+        movsxd      rax,        dword ptr arg(3) ;stride
+        pxor        xmm0,       xmm0
+
+        movdqa      xmm1,       XMMWORD PTR [rsi]
+        movdqa      xmm5,       xmm1
+        punpcklbw   xmm1,       xmm0
+        punpckhbw   xmm5,       xmm0
+        paddsw      xmm1,       XMMWORD PTR [rdx]
+        paddsw      xmm5,       XMMWORD PTR [rdx+16]
+        packuswb    xmm1,       xmm5              ; pack and unpack to saturate
+        movdqa      XMMWORD PTR [rdi],  xmm1
+
+
+        movdqa      xmm2,       XMMWORD PTR [rsi+16]
+        movdqa      xmm6,       xmm2
+        punpcklbw   xmm2,       xmm0
+        punpckhbw   xmm6,       xmm0
+        paddsw      xmm2,       XMMWORD PTR [rdx+32]
+        paddsw      xmm6,       XMMWORD PTR [rdx+48]
+        packuswb    xmm2,       xmm6              ; pack and unpack to saturate
+        movdqa      XMMWORD PTR [rdi+rax],  xmm2
+
+
+        movdqa      xmm3,       XMMWORD PTR [rsi+32]
+        movdqa      xmm7,       xmm3
+        punpcklbw   xmm3,       xmm0
+        punpckhbw   xmm7,       xmm0
+        paddsw      xmm3,       XMMWORD PTR [rdx+64]
+        paddsw      xmm7,       XMMWORD PTR [rdx+80]
+        packuswb    xmm3,       xmm7              ; pack and unpack to saturate
+        movdqa      XMMWORD PTR [rdi+rax*2],    xmm3
+
+        add       rdi, rax
+        movdqa      xmm4,       XMMWORD PTR [rsi+48]
+        movdqa      xmm5,       xmm4
+        punpcklbw   xmm4,       xmm0
+        punpckhbw   xmm5,       xmm0
+        paddsw      xmm4,       XMMWORD PTR [rdx+96]
+        paddsw      xmm5,       XMMWORD PTR [rdx+112]
+        packuswb    xmm4,       xmm5              ; pack and unpack to saturate
+        movdqa      XMMWORD PTR [rdi+rax*2],    xmm4
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void copy_mem16x16_sse2(
+;    unsigned char *src,
+;    int src_stride,
+;    unsigned char *dst,
+;    int dst_stride
+;    )
+global sym(vp8_copy_mem16x16_sse2)
+sym(vp8_copy_mem16x16_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;src;
+        movdqu      xmm0,       [rsi]
+
+        movsxd      rax,        dword ptr arg(1) ;src_stride;
+        mov         rdi,        arg(2) ;dst;
+
+        movdqu      xmm1,       [rsi+rax]
+        movdqu      xmm2,       [rsi+rax*2]
+
+        movsxd      rcx,        dword ptr arg(3) ;dst_stride
+        lea         rsi,        [rsi+rax*2]
+
+        movdqa      [rdi],      xmm0
+        add         rsi,        rax
+
+        movdqa      [rdi+rcx],  xmm1
+        movdqa      [rdi+rcx*2],xmm2
+
+        lea         rdi,        [rdi+rcx*2]
+        movdqu      xmm3,       [rsi]
+
+        add         rdi,        rcx
+        movdqu      xmm4,       [rsi+rax]
+
+        movdqu      xmm5,       [rsi+rax*2]
+        lea         rsi,        [rsi+rax*2]
+
+        movdqa      [rdi],  xmm3
+        add         rsi,        rax
+
+        movdqa      [rdi+rcx],  xmm4
+        movdqa      [rdi+rcx*2],xmm5
+
+        lea         rdi,        [rdi+rcx*2]
+        movdqu      xmm0,       [rsi]
+
+        add         rdi,        rcx
+        movdqu      xmm1,       [rsi+rax]
+
+        movdqu      xmm2,       [rsi+rax*2]
+        lea         rsi,        [rsi+rax*2]
+
+        movdqa      [rdi],      xmm0
+        add         rsi,        rax
+
+        movdqa      [rdi+rcx],  xmm1
+
+        movdqa      [rdi+rcx*2],    xmm2
+        movdqu      xmm3,       [rsi]
+
+        movdqu      xmm4,       [rsi+rax]
+        lea         rdi,        [rdi+rcx*2]
+
+        add         rdi,        rcx
+        movdqu      xmm5,       [rsi+rax*2]
+
+        lea         rsi,        [rsi+rax*2]
+        movdqa      [rdi],  xmm3
+
+        add         rsi,        rax
+        movdqa      [rdi+rcx],  xmm4
+
+        movdqa      [rdi+rcx*2],xmm5
+        movdqu      xmm0,       [rsi]
+
+        lea         rdi,        [rdi+rcx*2]
+        movdqu      xmm1,       [rsi+rax]
+
+        add         rdi,        rcx
+        movdqu      xmm2,       [rsi+rax*2]
+
+        lea         rsi,        [rsi+rax*2]
+        movdqa      [rdi],      xmm0
+
+        movdqa      [rdi+rcx],  xmm1
+        movdqa      [rdi+rcx*2],xmm2
+
+        movdqu      xmm3,       [rsi+rax]
+        lea         rdi,        [rdi+rcx*2]
+
+        movdqa      [rdi+rcx],  xmm3
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/common/x86/recon_x86.h b/vp8/common/x86/recon_x86.h
new file mode 100644 (file)
index 0000000..c469778
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef RECON_X86_H
+#define RECON_X86_H
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+
+#if HAVE_MMX
+extern prototype_recon_block(vp8_recon_b_mmx);
+extern prototype_copy_block(vp8_copy_mem8x8_mmx);
+extern prototype_copy_block(vp8_copy_mem8x4_mmx);
+extern prototype_copy_block(vp8_copy_mem16x16_mmx);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_recon_recon
+#define vp8_recon_recon vp8_recon_b_mmx
+
+#undef  vp8_recon_copy8x8
+#define vp8_recon_copy8x8 vp8_copy_mem8x8_mmx
+
+#undef  vp8_recon_copy8x4
+#define vp8_recon_copy8x4 vp8_copy_mem8x4_mmx
+
+#undef  vp8_recon_copy16x16
+#define vp8_recon_copy16x16 vp8_copy_mem16x16_mmx
+
+#endif
+#endif
+
+#if HAVE_SSE2
+extern prototype_recon_block(vp8_recon2b_sse2);
+extern prototype_recon_block(vp8_recon4b_sse2);
+extern prototype_copy_block(vp8_copy_mem16x16_sse2);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_recon_recon2
+#define vp8_recon_recon2 vp8_recon2b_sse2
+
+#undef  vp8_recon_recon4
+#define vp8_recon_recon4 vp8_recon4b_sse2
+
+#undef  vp8_recon_copy16x16
+#define vp8_recon_copy16x16 vp8_copy_mem16x16_sse2
+
+#endif
+#endif
+#endif
diff --git a/vp8/common/x86/subpixel_mmx.asm b/vp8/common/x86/subpixel_mmx.asm
new file mode 100644 (file)
index 0000000..c502118
--- /dev/null
@@ -0,0 +1,817 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+
+%define BLOCK_HEIGHT_WIDTH 4
+%define vp8_filter_weight 128
+%define VP8_FILTER_SHIFT  7
+
+
+;void vp8_filter_block1d_h6_mmx
+;(
+;    unsigned char   *src_ptr,
+;    unsigned short  *output_ptr,
+;    unsigned int    src_pixels_per_line,
+;    unsigned int    pixel_step,
+;    unsigned int    output_height,
+;    unsigned int    output_width,
+;    short           * vp8_filter
+;)
+global sym(vp8_filter_block1d_h6_mmx)
+sym(vp8_filter_block1d_h6_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rdx,    arg(6) ;vp8_filter
+
+        movq        mm1,    [rdx + 16]             ; do both the negative taps first!!!
+        movq        mm2,    [rdx + 32]         ;
+        movq        mm6,    [rdx + 48]        ;
+        movq        mm7,    [rdx + 64]        ;
+
+        mov         rdi,    arg(1) ;output_ptr
+        mov         rsi,    arg(0) ;src_ptr
+        movsxd      rcx,    dword ptr arg(4) ;output_height
+        movsxd      rax,    dword ptr arg(5) ;output_width      ; destination pitch?
+        pxor        mm0,    mm0              ; mm0 = 00000000
+
+nextrow:
+        movq        mm3,    [rsi-2]          ; mm3 = p-2..p5
+        movq        mm4,    mm3              ; mm4 = p-2..p5
+        psrlq       mm3,    8                ; mm3 = p-1..p5
+        punpcklbw   mm3,    mm0              ; mm3 = p-1..p2
+        pmullw      mm3,    mm1              ; mm3 *= kernel 1 modifiers.
+
+        movq        mm5,    mm4              ; mm5 = p-2..p5
+        punpckhbw   mm4,    mm0              ; mm5 = p2..p5
+        pmullw      mm4,    mm7              ; mm5 *= kernel 4 modifiers
+        paddsw      mm3,    mm4              ; mm3 += mm5
+
+        movq        mm4,    mm5              ; mm4 = p-2..p5;
+        psrlq       mm5,    16               ; mm5 = p0..p5;
+        punpcklbw   mm5,    mm0              ; mm5 = p0..p3
+        pmullw      mm5,    mm2              ; mm5 *= kernel 2 modifiers
+        paddsw      mm3,    mm5              ; mm3 += mm5
+
+        movq        mm5,    mm4              ; mm5 = p-2..p5
+        psrlq       mm4,    24               ; mm4 = p1..p5
+        punpcklbw   mm4,    mm0              ; mm4 = p1..p4
+        pmullw      mm4,    mm6              ; mm5 *= kernel 3 modifiers
+        paddsw      mm3,    mm4              ; mm3 += mm5
+
+        ; do outer positive taps
+        movd        mm4,    [rsi+3]
+        punpcklbw   mm4,    mm0              ; mm5 = p3..p6
+        pmullw      mm4,    [rdx+80]         ; mm5 *= kernel 0 modifiers
+        paddsw      mm3,    mm4              ; mm3 += mm5
+
+        punpcklbw   mm5,    mm0              ; mm5 = p-2..p1
+        pmullw      mm5,    [rdx]            ; mm5 *= kernel 5 modifiers
+        paddsw      mm3,    mm5              ; mm3 += mm5
+
+        paddsw      mm3,    [rd GLOBAL]               ; mm3 += round value
+        psraw       mm3,    VP8_FILTER_SHIFT     ; mm3 /= 128
+        packuswb    mm3,    mm0              ; pack and unpack to saturate
+        punpcklbw   mm3,    mm0              ;
+
+        movq        [rdi],  mm3              ; store the results in the destination
+
+%if ABI_IS_32BIT
+        add         rsi,    dword ptr arg(2) ;src_pixels_per_line ; next line
+        add         rdi,    rax;
+%else
+        movsxd      r8,     dword ptr arg(2) ;src_pixels_per_line
+        add         rdi,    rax;
+
+        add         rsi,    r8               ; next line
+%endif
+
+        dec         rcx                      ; decrement count
+        jnz         nextrow                  ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;
+; THIS FUNCTION APPEARS TO BE UNUSED
+;
+;void vp8_filter_block1d_v6_mmx
+;(
+;   short *src_ptr,
+;   unsigned char *output_ptr,
+;   unsigned int pixels_per_line,
+;   unsigned int pixel_step,
+;   unsigned int output_height,
+;   unsigned int output_width,
+;   short * vp8_filter
+;)
+global sym(vp8_filter_block1d_v6_mmx)
+sym(vp8_filter_block1d_v6_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        movq      mm5, [rd GLOBAL]
+        push        rbx
+        mov         rbx, arg(6) ;vp8_filter
+        movq      mm1, [rbx + 16]             ; do both the negative taps first!!!
+        movq      mm2, [rbx + 32]         ;
+        movq      mm6, [rbx + 48]        ;
+        movq      mm7, [rbx + 64]        ;
+
+        movsxd      rdx, dword ptr arg(2) ;pixels_per_line
+        mov         rdi, arg(1) ;output_ptr
+        mov         rsi, arg(0) ;src_ptr
+        sub         rsi, rdx
+        sub         rsi, rdx
+        movsxd      rcx, DWORD PTR arg(4) ;output_height
+        movsxd      rax, DWORD PTR arg(5) ;output_width      ; destination pitch?
+        pxor        mm0, mm0              ; mm0 = 00000000
+
+
+nextrow_v:
+        movq        mm3, [rsi+rdx]        ; mm3 = p0..p8  = row -1
+        pmullw      mm3, mm1              ; mm3 *= kernel 1 modifiers.
+
+
+        movq        mm4, [rsi + 4*rdx]      ; mm4 = p0..p3  = row 2
+        pmullw      mm4, mm7              ; mm4 *= kernel 4 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+        movq        mm4, [rsi + 2*rdx]           ; mm4 = p0..p3  = row 0
+        pmullw      mm4, mm2              ; mm4 *= kernel 2 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+        movq        mm4, [rsi]            ; mm4 = p0..p3  = row -2
+        pmullw      mm4, [rbx]            ; mm4 *= kernel 0 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+
+        add         rsi, rdx              ; move source forward 1 line to avoid 3 * pitch
+        movq        mm4, [rsi + 2*rdx]     ; mm4 = p0..p3  = row 1
+        pmullw      mm4, mm6              ; mm4 *= kernel 3 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+        movq        mm4, [rsi + 4*rdx]    ; mm4 = p0..p3  = row 3
+        pmullw      mm4, [rbx +80]        ; mm4 *= kernel 3 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+
+        paddsw      mm3, mm5               ; mm3 += round value
+        psraw       mm3, VP8_FILTER_SHIFT     ; mm3 /= 128
+        packuswb    mm3, mm0              ; pack and saturate
+
+        movd        [rdi],mm3             ; store the results in the destination
+
+        add         rdi,rax;
+
+        dec         rcx                   ; decrement count
+        jnz         nextrow_v             ; next row
+
+        pop         rbx
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_filter_block1dc_v6_mmx
+;(
+;   short *src_ptr,
+;   unsigned char *output_ptr,
+;    int output_pitch,
+;   unsigned int pixels_per_line,
+;   unsigned int pixel_step,
+;   unsigned int output_height,
+;   unsigned int output_width,
+;   short * vp8_filter
+;)
+global sym(vp8_filter_block1dc_v6_mmx)
+sym(vp8_filter_block1dc_v6_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        movq      mm5, [rd GLOBAL]
+        push        rbx
+        mov         rbx, arg(7) ;vp8_filter
+        movq      mm1, [rbx + 16]             ; do both the negative taps first!!!
+        movq      mm2, [rbx + 32]         ;
+        movq      mm6, [rbx + 48]        ;
+        movq      mm7, [rbx + 64]        ;
+
+        movsxd      rdx, dword ptr arg(3) ;pixels_per_line
+        mov         rdi, arg(1) ;output_ptr
+        mov         rsi, arg(0) ;src_ptr
+        sub         rsi, rdx
+        sub         rsi, rdx
+        movsxd      rcx, DWORD PTR arg(5) ;output_height
+        movsxd      rax, DWORD PTR arg(2) ;output_pitch      ; destination pitch?
+        pxor        mm0, mm0              ; mm0 = 00000000
+
+
+nextrow_cv:
+        movq        mm3, [rsi+rdx]        ; mm3 = p0..p8  = row -1
+        pmullw      mm3, mm1              ; mm3 *= kernel 1 modifiers.
+
+
+        movq        mm4, [rsi + 4*rdx]      ; mm4 = p0..p3  = row 2
+        pmullw      mm4, mm7              ; mm4 *= kernel 4 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+        movq        mm4, [rsi + 2*rdx]           ; mm4 = p0..p3  = row 0
+        pmullw      mm4, mm2              ; mm4 *= kernel 2 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+        movq        mm4, [rsi]            ; mm4 = p0..p3  = row -2
+        pmullw      mm4, [rbx]            ; mm4 *= kernel 0 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+
+        add         rsi, rdx              ; move source forward 1 line to avoid 3 * pitch
+        movq        mm4, [rsi + 2*rdx]     ; mm4 = p0..p3  = row 1
+        pmullw      mm4, mm6              ; mm4 *= kernel 3 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+        movq        mm4, [rsi + 4*rdx]    ; mm4 = p0..p3  = row 3
+        pmullw      mm4, [rbx +80]        ; mm4 *= kernel 3 modifiers.
+        paddsw      mm3, mm4              ; mm3 += mm4
+
+
+        paddsw      mm3, mm5               ; mm3 += round value
+        psraw       mm3, VP8_FILTER_SHIFT     ; mm3 /= 128
+        packuswb    mm3, mm0              ; pack and saturate
+
+        movd        [rdi],mm3             ; store the results in the destination
+        ; the subsequent iterations repeat 3 out of 4 of these reads.  Since the
+        ; recon block should be in cache this shouldn't cost much.  Its obviously
+        ; avoidable!!!.
+        lea         rdi,  [rdi+rax] ;
+        dec         rcx                   ; decrement count
+        jnz         nextrow_cv             ; next row
+
+        pop         rbx
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void bilinear_predict8x8_mmx
+;(
+;    unsigned char  *src_ptr,
+;    int   src_pixels_per_line,
+;    int  xoffset,
+;    int  yoffset,
+;   unsigned char *dst_ptr,
+;    int dst_pitch
+;)
+global sym(vp8_bilinear_predict8x8_mmx)
+sym(vp8_bilinear_predict8x8_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ;const short *HFilter = bilinear_filters_mmx[xoffset];
+    ;const short *VFilter = bilinear_filters_mmx[yoffset];
+
+        movsxd      rax,        dword ptr arg(2) ;xoffset
+        mov         rdi,        arg(4) ;dst_ptr           ;
+
+        shl         rax,        5 ; offset * 32
+        lea         rcx,        [sym(vp8_bilinear_filters_mmx) GLOBAL]
+
+        add         rax,        rcx ; HFilter
+        mov         rsi,        arg(0) ;src_ptr              ;
+
+        movsxd      rdx,        dword ptr arg(5) ;dst_pitch
+        movq        mm1,        [rax]               ;
+
+        movq        mm2,        [rax+16]            ;
+        movsxd      rax,        dword ptr arg(3) ;yoffset
+
+        pxor        mm0,        mm0                 ;
+
+        shl         rax,        5 ; offset*32
+        add         rax,        rcx ; VFilter
+
+        lea         rcx,        [rdi+rdx*8]          ;
+        movsxd      rdx,        dword ptr arg(1) ;src_pixels_per_line    ;
+
+
+
+        ; get the first horizontal line done       ;
+        movq        mm3,        [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movq        mm4,        mm3                 ; make a copy of current line
+
+        punpcklbw   mm3,        mm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   mm4,        mm0                 ;
+
+        pmullw      mm3,        mm1                 ;
+        pmullw      mm4,        mm1                 ;
+
+        movq        mm5,        [rsi+1]             ;
+        movq        mm6,        mm5                 ;
+
+        punpcklbw   mm5,        mm0                 ;
+        punpckhbw   mm6,        mm0                 ;
+
+        pmullw      mm5,        mm2                 ;
+        pmullw      mm6,        mm2                 ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm4,        mm6                 ;
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       mm4,        [rd GLOBAL]                  ;
+        psraw       mm4,        VP8_FILTER_SHIFT        ;
+
+        movq        mm7,        mm3                 ;
+        packuswb    mm7,        mm4                 ;
+
+        add         rsi,        rdx                 ; next line
+next_row_8x8:
+        movq        mm3,        [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movq        mm4,        mm3                 ; make a copy of current line
+
+        punpcklbw   mm3,        mm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   mm4,        mm0                 ;
+
+        pmullw      mm3,        mm1                 ;
+        pmullw      mm4,        mm1                 ;
+
+        movq        mm5,        [rsi+1]             ;
+        movq        mm6,        mm5                 ;
+
+        punpcklbw   mm5,        mm0                 ;
+        punpckhbw   mm6,        mm0                 ;
+
+        pmullw      mm5,        mm2                 ;
+        pmullw      mm6,        mm2                 ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm4,        mm6                 ;
+
+        movq        mm5,        mm7                 ;
+        movq        mm6,        mm7                 ;
+
+        punpcklbw   mm5,        mm0                 ;
+        punpckhbw   mm6,        mm0
+
+        pmullw      mm5,        [rax]               ;
+        pmullw      mm6,        [rax]               ;
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       mm4,        [rd GLOBAL]                  ;
+        psraw       mm4,        VP8_FILTER_SHIFT        ;
+
+        movq        mm7,        mm3                 ;
+        packuswb    mm7,        mm4                 ;
+
+
+        pmullw      mm3,        [rax+16]            ;
+        pmullw      mm4,        [rax+16]            ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm4,        mm6                 ;
+
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       mm4,        [rd GLOBAL]                  ;
+        psraw       mm4,        VP8_FILTER_SHIFT        ;
+
+        packuswb    mm3,        mm4
+
+        movq        [rdi],      mm3                 ; store the results in the destination
+
+%if ABI_IS_32BIT
+        add         rsi,        rdx                 ; next line
+        add         rdi,        dword ptr arg(5) ;dst_pitch                   ;
+%else
+        movsxd      r8,         dword ptr arg(5) ;dst_pitch
+        add         rsi,        rdx                 ; next line
+        add         rdi,        r8                  ;dst_pitch
+%endif
+        cmp         rdi,        rcx                 ;
+        jne         next_row_8x8
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void bilinear_predict8x4_mmx
+;(
+;    unsigned char  *src_ptr,
+;    int   src_pixels_per_line,
+;    int  xoffset,
+;    int  yoffset,
+;    unsigned char *dst_ptr,
+;    int dst_pitch
+;)
+global sym(vp8_bilinear_predict8x4_mmx)
+sym(vp8_bilinear_predict8x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ;const short *HFilter = bilinear_filters_mmx[xoffset];
+    ;const short *VFilter = bilinear_filters_mmx[yoffset];
+
+        movsxd      rax,        dword ptr arg(2) ;xoffset
+        mov         rdi,        arg(4) ;dst_ptr           ;
+
+        lea         rcx,        [sym(vp8_bilinear_filters_mmx) GLOBAL]
+        shl         rax,        5
+
+        mov         rsi,        arg(0) ;src_ptr              ;
+        add         rax,        rcx
+
+        movsxd      rdx,        dword ptr arg(5) ;dst_pitch
+        movq        mm1,        [rax]               ;
+
+        movq        mm2,        [rax+16]            ;
+        movsxd      rax,        dword ptr arg(3) ;yoffset
+
+        pxor        mm0,        mm0                 ;
+        shl         rax,        5
+
+        add         rax,        rcx
+        lea         rcx,        [rdi+rdx*4]          ;
+
+        movsxd      rdx,        dword ptr arg(1) ;src_pixels_per_line    ;
+
+        ; get the first horizontal line done       ;
+        movq        mm3,        [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movq        mm4,        mm3                 ; make a copy of current line
+
+        punpcklbw   mm3,        mm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   mm4,        mm0                 ;
+
+        pmullw      mm3,        mm1                 ;
+        pmullw      mm4,        mm1                 ;
+
+        movq        mm5,        [rsi+1]             ;
+        movq        mm6,        mm5                 ;
+
+        punpcklbw   mm5,        mm0                 ;
+        punpckhbw   mm6,        mm0                 ;
+
+        pmullw      mm5,        mm2                 ;
+        pmullw      mm6,        mm2                 ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm4,        mm6                 ;
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       mm4,        [rd GLOBAL]                  ;
+        psraw       mm4,        VP8_FILTER_SHIFT        ;
+
+        movq        mm7,        mm3                 ;
+        packuswb    mm7,        mm4                 ;
+
+        add         rsi,        rdx                 ; next line
+next_row_8x4:
+        movq        mm3,        [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movq        mm4,        mm3                 ; make a copy of current line
+
+        punpcklbw   mm3,        mm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   mm4,        mm0                 ;
+
+        pmullw      mm3,        mm1                 ;
+        pmullw      mm4,        mm1                 ;
+
+        movq        mm5,        [rsi+1]             ;
+        movq        mm6,        mm5                 ;
+
+        punpcklbw   mm5,        mm0                 ;
+        punpckhbw   mm6,        mm0                 ;
+
+        pmullw      mm5,        mm2                 ;
+        pmullw      mm6,        mm2                 ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm4,        mm6                 ;
+
+        movq        mm5,        mm7                 ;
+        movq        mm6,        mm7                 ;
+
+        punpcklbw   mm5,        mm0                 ;
+        punpckhbw   mm6,        mm0
+
+        pmullw      mm5,        [rax]               ;
+        pmullw      mm6,        [rax]               ;
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       mm4,        [rd GLOBAL]                  ;
+        psraw       mm4,        VP8_FILTER_SHIFT        ;
+
+        movq        mm7,        mm3                 ;
+        packuswb    mm7,        mm4                 ;
+
+
+        pmullw      mm3,        [rax+16]            ;
+        pmullw      mm4,        [rax+16]            ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm4,        mm6                 ;
+
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       mm4,        [rd GLOBAL]                  ;
+        psraw       mm4,        VP8_FILTER_SHIFT        ;
+
+        packuswb    mm3,        mm4
+
+        movq        [rdi],      mm3                 ; store the results in the destination
+
+%if ABI_IS_32BIT
+        add         rsi,        rdx                 ; next line
+        add         rdi,        dword ptr arg(5) ;dst_pitch                   ;
+%else
+        movsxd      r8,         dword ptr arg(5) ;dst_pitch
+        add         rsi,        rdx                 ; next line
+        add         rdi,        r8
+%endif
+        cmp         rdi,        rcx                 ;
+        jne         next_row_8x4
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void bilinear_predict4x4_mmx
+;(
+;    unsigned char  *src_ptr,
+;    int   src_pixels_per_line,
+;    int  xoffset,
+;    int  yoffset,
+;    unsigned char *dst_ptr,
+;    int dst_pitch
+;)
+global sym(vp8_bilinear_predict4x4_mmx)
+sym(vp8_bilinear_predict4x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ;const short *HFilter = bilinear_filters_mmx[xoffset];
+    ;const short *VFilter = bilinear_filters_mmx[yoffset];
+
+        movsxd      rax,        dword ptr arg(2) ;xoffset
+        mov         rdi,        arg(4) ;dst_ptr           ;
+
+        lea         rcx,        [sym(vp8_bilinear_filters_mmx) GLOBAL]
+        shl         rax,        5
+
+        add         rax,        rcx ; HFilter
+        mov         rsi,        arg(0) ;src_ptr              ;
+
+        movsxd      rdx,        dword ptr arg(5) ;ldst_pitch
+        movq        mm1,        [rax]               ;
+
+        movq        mm2,        [rax+16]            ;
+        movsxd      rax,        dword ptr arg(3) ;yoffset
+
+        pxor        mm0,        mm0                 ;
+        shl         rax,        5
+
+        add         rax,        rcx
+        lea         rcx,        [rdi+rdx*4]          ;
+
+        movsxd      rdx,        dword ptr arg(1) ;src_pixels_per_line    ;
+
+        ; get the first horizontal line done       ;
+        movd        mm3,        [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        punpcklbw   mm3,        mm0                 ; xx 00 01 02 03 04 05 06
+
+        pmullw      mm3,        mm1                 ;
+        movd        mm5,        [rsi+1]             ;
+
+        punpcklbw   mm5,        mm0                 ;
+        pmullw      mm5,        mm2                 ;
+
+        paddw       mm3,        mm5                 ;
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        movq        mm7,        mm3                 ;
+        packuswb    mm7,        mm0                 ;
+
+        add         rsi,        rdx                 ; next line
+next_row_4x4:
+        movd        mm3,        [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        punpcklbw   mm3,        mm0                 ; xx 00 01 02 03 04 05 06
+
+        pmullw      mm3,        mm1                 ;
+        movd        mm5,        [rsi+1]             ;
+
+        punpcklbw   mm5,        mm0                 ;
+        pmullw      mm5,        mm2                 ;
+
+        paddw       mm3,        mm5                 ;
+
+        movq        mm5,        mm7                 ;
+        punpcklbw   mm5,        mm0                 ;
+
+        pmullw      mm5,        [rax]               ;
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+        movq        mm7,        mm3                 ;
+
+        packuswb    mm7,        mm0                 ;
+
+        pmullw      mm3,        [rax+16]            ;
+        paddw       mm3,        mm5                 ;
+
+
+        paddw       mm3,        [rd GLOBAL]                  ; xmm3 += round value
+        psraw       mm3,        VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        packuswb    mm3,        mm0
+        movd        [rdi],      mm3                 ; store the results in the destination
+
+%if ABI_IS_32BIT
+        add         rsi,        rdx                 ; next line
+        add         rdi,        dword ptr arg(5) ;dst_pitch                   ;
+%else
+        movsxd      r8,         dword ptr arg(5) ;dst_pitch                   ;
+        add         rsi,        rdx                 ; next line
+        add         rdi,        r8
+%endif
+
+        cmp         rdi,        rcx                 ;
+        jne         next_row_4x4
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+SECTION_RODATA
+align 16
+rd:
+    times 4 dw 0x40
+
+align 16
+global sym(vp8_six_tap_mmx)
+sym(vp8_six_tap_mmx):
+    times 8 dw 0
+    times 8 dw 0
+    times 8 dw 128
+    times 8 dw 0
+    times 8 dw 0
+    times 8 dw 0
+
+    times 8 dw 0
+    times 8 dw -6
+    times 8 dw 123
+    times 8 dw 12
+    times 8 dw -1
+    times 8 dw 0
+
+    times 8 dw 2
+    times 8 dw -11
+    times 8 dw 108
+    times 8 dw 36
+    times 8 dw -8
+    times 8 dw 1
+
+    times 8 dw 0
+    times 8 dw -9
+    times 8 dw 93
+    times 8 dw 50
+    times 8 dw -6
+    times 8 dw 0
+
+    times 8 dw 3
+    times 8 dw -16
+    times 8 dw 77
+    times 8 dw 77
+    times 8 dw -16
+    times 8 dw 3
+
+    times 8 dw 0
+    times 8 dw -6
+    times 8 dw 50
+    times 8 dw 93
+    times 8 dw -9
+    times 8 dw 0
+
+    times 8 dw 1
+    times 8 dw -8
+    times 8 dw 36
+    times 8 dw 108
+    times 8 dw -11
+    times 8 dw 2
+
+    times 8 dw 0
+    times 8 dw -1
+    times 8 dw 12
+    times 8 dw 123
+    times 8 dw -6
+    times 8 dw 0
+
+
+align 16
+global sym(vp8_bilinear_filters_mmx)
+sym(vp8_bilinear_filters_mmx):
+    times 8 dw 128
+    times 8 dw 0
+
+    times 8 dw 112
+    times 8 dw 16
+
+    times 8 dw 96
+    times 8 dw 32
+
+    times 8 dw 80
+    times 8 dw 48
+
+    times 8 dw 64
+    times 8 dw 64
+
+    times 8 dw 48
+    times 8 dw 80
+
+    times 8 dw 32
+    times 8 dw 96
+
+    times 8 dw 16
+    times 8 dw 112
diff --git a/vp8/common/x86/subpixel_sse2.asm b/vp8/common/x86/subpixel_sse2.asm
new file mode 100644 (file)
index 0000000..dee04f2
--- /dev/null
@@ -0,0 +1,1032 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%define BLOCK_HEIGHT_WIDTH 4
+%define VP8_FILTER_WEIGHT 128
+%define VP8_FILTER_SHIFT  7
+
+
+;/************************************************************************************
+; Notes: filter_block1d_h6 applies a 6 tap filter horizontally to the input pixels. The
+; input pixel array has output_height rows. This routine assumes that output_height is an
+; even number. This function handles 8 pixels in horizontal direction, calculating ONE
+; rows each iteration to take advantage of the 128 bits operations.
+;*************************************************************************************/
+;void vp8_filter_block1d8_h6_sse2
+;(
+;    unsigned char  *src_ptr,
+;    unsigned short *output_ptr,
+;    unsigned int    src_pixels_per_line,
+;    unsigned int    pixel_step,
+;    unsigned int    output_height,
+;    unsigned int    output_width,
+;    short           *vp8_filter
+;)
+global sym(vp8_filter_block1d8_h6_sse2)
+sym(vp8_filter_block1d8_h6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rdx,        arg(6) ;vp8_filter
+        mov         rsi,        arg(0) ;src_ptr
+
+        mov         rdi,        arg(1) ;output_ptr
+
+        movsxd      rcx,        dword ptr arg(4) ;output_height
+        movsxd      rax,        dword ptr arg(2) ;src_pixels_per_line            ; Pitch for Source
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(5) ;output_width
+%endif
+        pxor        xmm0,       xmm0                        ; clear xmm0 for unpack
+
+filter_block1d8_h6_rowloop:
+        movq        xmm3,       MMWORD PTR [rsi - 2]
+        movq        xmm1,       MMWORD PTR [rsi + 6]
+
+        prefetcht2  [rsi+rax-2]
+
+        pslldq      xmm1,       8
+        por         xmm1,       xmm3
+
+        movdqa      xmm4,       xmm1
+        movdqa      xmm5,       xmm1
+
+        movdqa      xmm6,       xmm1
+        movdqa      xmm7,       xmm1
+
+        punpcklbw   xmm3,       xmm0                        ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2
+        psrldq      xmm4,       1                           ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1
+
+        pmullw      xmm3,       XMMWORD PTR [rdx]           ; x[-2] * H[-2]; Tap 1
+        punpcklbw   xmm4,       xmm0                        ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1
+
+        psrldq      xmm5,       2                           ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
+        pmullw      xmm4,       XMMWORD PTR [rdx+16]        ; x[-1] * H[-1]; Tap 2
+
+
+        punpcklbw   xmm5,       xmm0                        ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00
+        psrldq      xmm6,       3                           ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01
+
+        pmullw      xmm5,       [rdx+32]                    ; x[ 0] * H[ 0]; Tap 3
+
+        punpcklbw   xmm6,       xmm0                        ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01
+        psrldq      xmm7,       4                           ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02
+
+        pmullw      xmm6,       [rdx+48]                    ; x[ 1] * h[ 1] ; Tap 4
+
+        punpcklbw   xmm7,       xmm0                        ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02
+        psrldq      xmm1,       5                           ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03
+
+
+        pmullw      xmm7,       [rdx+64]                    ; x[ 2] * h[ 2] ; Tap 5
+
+        punpcklbw   xmm1,       xmm0                        ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03
+        pmullw      xmm1,       [rdx+80]                    ; x[ 3] * h[ 3] ; Tap 6
+
+
+        paddsw      xmm4,       xmm7
+        paddsw      xmm4,       xmm5
+
+        paddsw      xmm4,       xmm3
+        paddsw      xmm4,       xmm6
+
+        paddsw      xmm4,       xmm1
+        paddsw      xmm4,       [rd GLOBAL]
+
+        psraw       xmm4,       7
+
+        packuswb    xmm4,       xmm0
+        punpcklbw   xmm4,       xmm0
+
+        movdqa      XMMWORD Ptr [rdi],         xmm4
+        lea         rsi,        [rsi + rax]
+
+%if ABI_IS_32BIT
+        add         rdi,        DWORD Ptr arg(5) ;[output_width]
+%else
+        add         rdi,        r8
+%endif
+        dec         rcx
+
+        jnz         filter_block1d8_h6_rowloop                ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_filter_block1d16_h6_sse2
+;(
+;    unsigned char  *src_ptr,
+;    unsigned short *output_ptr,
+;    unsigned int    src_pixels_per_line,
+;    unsigned int    pixel_step,
+;    unsigned int    output_height,
+;    unsigned int    output_width,
+;    short           *vp8_filter
+;)
+;/************************************************************************************
+; Notes: filter_block1d_h6 applies a 6 tap filter horizontally to the input pixels. The
+; input pixel array has output_height rows. This routine assumes that output_height is an
+; even number. This function handles 8 pixels in horizontal direction, calculating ONE
+; rows each iteration to take advantage of the 128 bits operations.
+;*************************************************************************************/
+global sym(vp8_filter_block1d16_h6_sse2)
+sym(vp8_filter_block1d16_h6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rdx,        arg(6) ;vp8_filter
+        mov         rsi,        arg(0) ;src_ptr
+
+        mov         rdi,        arg(1) ;output_ptr
+
+        movsxd      rcx,        dword ptr arg(4) ;output_height
+        movsxd      rax,        dword ptr arg(2) ;src_pixels_per_line            ; Pitch for Source
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(5) ;output_width
+%endif
+
+        pxor        xmm0,       xmm0                        ; clear xmm0 for unpack
+
+filter_block1d16_h6_sse2_rowloop:
+        movq        xmm3,       MMWORD PTR [rsi - 2]
+        movq        xmm1,       MMWORD PTR [rsi + 6]
+
+        movq        xmm2,       MMWORD PTR [rsi +14]
+        pslldq      xmm2,       8
+
+        por         xmm2,       xmm1
+        prefetcht2  [rsi+rax-2]
+
+        pslldq      xmm1,       8
+        por         xmm1,       xmm3
+
+        movdqa      xmm4,       xmm1
+        movdqa      xmm5,       xmm1
+
+        movdqa      xmm6,       xmm1
+        movdqa      xmm7,       xmm1
+
+        punpcklbw   xmm3,       xmm0                        ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2
+        psrldq      xmm4,       1                           ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1
+
+        pmullw      xmm3,       XMMWORD PTR [rdx]           ; x[-2] * H[-2]; Tap 1
+        punpcklbw   xmm4,       xmm0                        ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1
+
+        psrldq      xmm5,       2                           ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
+        pmullw      xmm4,       XMMWORD PTR [rdx+16]        ; x[-1] * H[-1]; Tap 2
+
+
+        punpcklbw   xmm5,       xmm0                        ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00
+        psrldq      xmm6,       3                           ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01
+
+        pmullw      xmm5,       [rdx+32]                    ; x[ 0] * H[ 0]; Tap 3
+
+        punpcklbw   xmm6,       xmm0                        ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01
+        psrldq      xmm7,       4                           ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02
+
+        pmullw      xmm6,       [rdx+48]                    ; x[ 1] * h[ 1] ; Tap 4
+
+        punpcklbw   xmm7,       xmm0                        ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02
+        psrldq      xmm1,       5                           ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03
+
+
+        pmullw      xmm7,       [rdx+64]                    ; x[ 2] * h[ 2] ; Tap 5
+
+        punpcklbw   xmm1,       xmm0                        ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03
+        pmullw      xmm1,       [rdx+80]                    ; x[ 3] * h[ 3] ; Tap 6
+
+        paddsw      xmm4,       xmm7
+        paddsw      xmm4,       xmm5
+
+        paddsw      xmm4,       xmm3
+        paddsw      xmm4,       xmm6
+
+        paddsw      xmm4,       xmm1
+        paddsw      xmm4,       [rd GLOBAL]
+
+        psraw       xmm4,       7
+
+        packuswb    xmm4,       xmm0
+        punpcklbw   xmm4,       xmm0
+
+        movdqa      XMMWORD Ptr [rdi],         xmm4
+
+        movdqa      xmm3,       xmm2
+        movdqa      xmm4,       xmm2
+
+        movdqa      xmm5,       xmm2
+        movdqa      xmm6,       xmm2
+
+        movdqa      xmm7,       xmm2
+
+        punpcklbw   xmm3,       xmm0                        ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2
+        psrldq      xmm4,       1                           ; xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1
+
+        pmullw      xmm3,       XMMWORD PTR [rdx]           ; x[-2] * H[-2]; Tap 1
+        punpcklbw   xmm4,       xmm0                        ; xx06 xx05 xx04 xx03 xx02 xx01 xx00 xx-1
+
+        psrldq      xmm5,       2                           ; xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
+        pmullw      xmm4,       XMMWORD PTR [rdx+16]        ; x[-1] * H[-1]; Tap 2
+
+
+        punpcklbw   xmm5,       xmm0                        ; xx07 xx06 xx05 xx04 xx03 xx02 xx01 xx00
+        psrldq      xmm6,       3                           ; xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01
+
+        pmullw      xmm5,       [rdx+32]                    ; x[ 0] * H[ 0]; Tap 3
+
+        punpcklbw   xmm6,       xmm0                        ; xx08 xx07 xx06 xx05 xx04 xx03 xx02 xx01
+        psrldq      xmm7,       4                           ; xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03 02
+
+        pmullw      xmm6,       [rdx+48]                    ; x[ 1] * h[ 1] ; Tap 4
+
+        punpcklbw   xmm7,       xmm0                        ; xx09 xx08 xx07 xx06 xx05 xx04 xx03 xx02
+        psrldq      xmm2,       5                           ; xx xx xx xx xx 0d 0c 0b 0a 09 08 07 06 05 04 03
+
+        pmullw      xmm7,       [rdx+64]                    ; x[ 2] * h[ 2] ; Tap 5
+
+        punpcklbw   xmm2,       xmm0                        ; xx0a xx09 xx08 xx07 xx06 xx05 xx04 xx03
+        pmullw      xmm2,       [rdx+80]                    ; x[ 3] * h[ 3] ; Tap 6
+
+
+        paddsw      xmm4,       xmm7
+        paddsw      xmm4,       xmm5
+
+        paddsw      xmm4,       xmm3
+        paddsw      xmm4,       xmm6
+
+        paddsw      xmm4,       xmm2
+        paddsw      xmm4,       [rd GLOBAL]
+
+        psraw       xmm4,       7
+
+        packuswb    xmm4,       xmm0
+        punpcklbw   xmm4,       xmm0
+
+        movdqa      XMMWORD Ptr [rdi+16],      xmm4
+
+        lea         rsi,        [rsi + rax]
+%if ABI_IS_32BIT
+        add         rdi,        DWORD Ptr arg(5) ;[output_width]
+%else
+        add         rdi,        r8
+%endif
+
+        dec         rcx
+        jnz         filter_block1d16_h6_sse2_rowloop                ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_filter_block1d8_v6_sse2
+;(
+;    short *src_ptr,
+;    unsigned char *output_ptr,
+;    int dst_ptich,
+;    unsigned int pixels_per_line,
+;    unsigned int pixel_step,
+;    unsigned int output_height,
+;    unsigned int output_width,
+;    short * vp8_filter
+;)
+;/************************************************************************************
+; Notes: filter_block1d8_v6 applies a 6 tap filter vertically to the input pixels. The
+; input pixel array has output_height rows.
+;*************************************************************************************/
+global sym(vp8_filter_block1d8_v6_sse2)
+sym(vp8_filter_block1d8_v6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rax,        arg(7) ;vp8_filter
+        movsxd      rdx,        dword ptr arg(3) ;pixels_per_line
+
+        mov         rdi,        arg(1) ;output_ptr
+        mov         rsi,        arg(0) ;src_ptr
+
+        sub         rsi,        rdx
+        sub         rsi,        rdx
+
+        movsxd      rcx,        DWORD PTR arg(5) ;[output_height]
+        pxor        xmm0,       xmm0                        ; clear xmm0
+
+        movdqa      xmm7,       XMMWORD PTR [rd GLOBAL]
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(2) ; dst_ptich
+%endif
+
+vp8_filter_block1d8_v6_sse2_loop:
+        movdqa      xmm1,       XMMWORD PTR [rsi]
+        pmullw      xmm1,       [rax]
+
+        movdqa      xmm2,       XMMWORD PTR [rsi + rdx]
+        pmullw      xmm2,       [rax + 16]
+
+        movdqa      xmm3,       XMMWORD PTR [rsi + rdx * 2]
+        pmullw      xmm3,       [rax + 32]
+
+        movdqa      xmm5,       XMMWORD PTR [rsi + rdx * 4]
+        pmullw      xmm5,       [rax + 64]
+
+        add         rsi,        rdx
+        movdqa      xmm4,       XMMWORD PTR [rsi + rdx * 2]
+
+        pmullw      xmm4,       [rax + 48]
+        movdqa      xmm6,       XMMWORD PTR [rsi + rdx * 4]
+
+        pmullw      xmm6,       [rax + 80]
+
+        paddsw      xmm2,       xmm5
+        paddsw      xmm2,       xmm3
+
+        paddsw      xmm2,       xmm1
+        paddsw      xmm2,       xmm4
+
+        paddsw      xmm2,       xmm6
+        paddsw      xmm2,       xmm7
+
+        psraw       xmm2,       7
+        packuswb    xmm2,       xmm0              ; pack and saturate
+
+        movq        QWORD PTR [rdi], xmm2         ; store the results in the destination
+%if ABI_IS_32BIT
+        add         rdi,        DWORD PTR arg(2) ;[dst_ptich]
+%else
+        add         rdi,        r8
+%endif
+        dec         rcx         ; decrement count
+        jnz         vp8_filter_block1d8_v6_sse2_loop               ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_unpack_block1d16_h6_sse2
+;(
+;    unsigned char  *src_ptr,
+;    unsigned short *output_ptr,
+;    unsigned int    src_pixels_per_line,
+;    unsigned int    output_height,
+;    unsigned int    output_width
+;)
+global sym(vp8_unpack_block1d16_h6_sse2)
+sym(vp8_unpack_block1d16_h6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;src_ptr
+        mov         rdi,        arg(1) ;output_ptr
+
+        movsxd      rcx,        dword ptr arg(3) ;output_height
+        movsxd      rax,        dword ptr arg(2) ;src_pixels_per_line            ; Pitch for Source
+
+        pxor        xmm0,       xmm0                        ; clear xmm0 for unpack
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(4) ;output_width            ; Pitch for Source
+%endif
+
+unpack_block1d16_h6_sse2_rowloop:
+        movq        xmm1,       MMWORD PTR [rsi]            ; 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 -2
+        movq        xmm3,       MMWORD PTR [rsi+8]          ; make copy of xmm1
+
+        punpcklbw   xmm3,       xmm0                        ; xx05 xx04 xx03 xx02 xx01 xx01 xx-1 xx-2
+        punpcklbw   xmm1,       xmm0
+
+        movdqa      XMMWORD Ptr [rdi],         xmm1
+        movdqa      XMMWORD Ptr [rdi + 16],    xmm3
+
+        lea         rsi,        [rsi + rax]
+%if ABI_IS_32BIT
+        add         rdi,        DWORD Ptr arg(4) ;[output_width]
+%else
+        add         rdi,        r8
+%endif
+        dec         rcx
+        jnz         unpack_block1d16_h6_sse2_rowloop                ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_unpack_block1d8_h6_sse2
+;(
+;    unsigned char  *src_ptr,
+;    unsigned short *output_ptr,
+;    unsigned int    src_pixels_per_line,
+;    unsigned int    output_height,
+;    unsigned int    output_width
+;)
+global sym(vp8_unpack_block1d8_h6_sse2)
+sym(vp8_unpack_block1d8_h6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rsi,        arg(0) ;src_ptr
+        mov         rdi,        arg(1) ;output_ptr
+
+        movsxd      rcx,        dword ptr arg(3) ;output_height
+        movsxd      rax,        dword ptr arg(2) ;src_pixels_per_line            ; Pitch for Source
+
+        pxor        xmm0,       xmm0                        ; clear xmm0 for unpack
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(4) ;output_width            ; Pitch for Source
+%endif
+
+unpack_block1d8_h6_sse2_rowloop:
+        movq        xmm1,       MMWORD PTR [rsi]            ; 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 -1 -2
+        lea         rsi,        [rsi + rax]
+
+        punpcklbw   xmm1,       xmm0
+        movdqa      XMMWORD Ptr [rdi],         xmm1
+
+%if ABI_IS_32BIT
+        add         rdi,        DWORD Ptr arg(4) ;[output_width]
+%else
+        add         rdi,        r8
+%endif
+        dec         rcx
+        jnz         unpack_block1d8_h6_sse2_rowloop                ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_pack_block1d8_v6_sse2
+;(
+;    short *src_ptr,
+;    unsigned char *output_ptr,
+;    int dst_ptich,
+;    unsigned int pixels_per_line,
+;    unsigned int output_height,
+;    unsigned int output_width
+;)
+global sym(vp8_pack_block1d8_v6_sse2)
+sym(vp8_pack_block1d8_v6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        movsxd      rdx,        dword ptr arg(3) ;pixels_per_line
+        mov         rdi,        arg(1) ;output_ptr
+
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rcx,        DWORD PTR arg(4) ;[output_height]
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(5) ;output_width            ; Pitch for Source
+%endif
+
+pack_block1d8_v6_sse2_loop:
+        movdqa      xmm0,       XMMWORD PTR [rsi]
+        packuswb    xmm0,       xmm0
+
+        movq        QWORD PTR [rdi], xmm0         ; store the results in the destination
+        lea         rsi,        [rsi+rdx]
+
+%if ABI_IS_32BIT
+        add         rdi,        DWORD Ptr arg(5) ;[output_width]
+%else
+        add         rdi,        r8
+%endif
+        dec         rcx         ; decrement count
+        jnz         pack_block1d8_v6_sse2_loop               ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_pack_block1d16_v6_sse2
+;(
+;    short *src_ptr,
+;    unsigned char *output_ptr,
+;    int dst_ptich,
+;    unsigned int pixels_per_line,
+;    unsigned int output_height,
+;    unsigned int output_width
+;)
+global sym(vp8_pack_block1d16_v6_sse2)
+sym(vp8_pack_block1d16_v6_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        movsxd      rdx,        dword ptr arg(3) ;pixels_per_line
+        mov         rdi,        arg(1) ;output_ptr
+
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rcx,        DWORD PTR arg(4) ;[output_height]
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(2) ;dst_pitch
+%endif
+
+pack_block1d16_v6_sse2_loop:
+        movdqa      xmm0,       XMMWORD PTR [rsi]
+        movdqa      xmm1,       XMMWORD PTR [rsi+16]
+
+        packuswb    xmm0,       xmm1
+        movdqa      XMMWORD PTR [rdi], xmm0         ; store the results in the destination
+
+        add         rsi,        rdx
+%if ABI_IS_32BIT
+        add         rdi,        DWORD Ptr arg(2) ;dst_pitch
+%else
+        add         rdi,        r8
+%endif
+        dec         rcx         ; decrement count
+        jnz         pack_block1d16_v6_sse2_loop               ; next row
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_bilinear_predict16x16_sse2
+;(
+;    unsigned char  *src_ptr,
+;    int   src_pixels_per_line,
+;    int  xoffset,
+;    int  yoffset,
+;    unsigned char *dst_ptr,
+;    int dst_pitch
+;)
+extern sym(vp8_bilinear_filters_mmx)
+global sym(vp8_bilinear_predict16x16_sse2)
+sym(vp8_bilinear_predict16x16_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ;const short *HFilter = bilinear_filters_mmx[xoffset]
+    ;const short *VFilter = bilinear_filters_mmx[yoffset]
+
+        lea         rcx,        [sym(vp8_bilinear_filters_mmx) GLOBAL]
+        movsxd      rax,        dword ptr arg(2) ;xoffset
+
+        cmp         rax,        0      ;skip first_pass filter if xoffset=0
+        je          b16x16_sp_only
+
+        shl         rax,        5
+        add         rax,        rcx    ;HFilter
+
+        mov         rdi,        arg(4) ;dst_ptr
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rdx,        dword ptr arg(5) ;dst_pitch
+
+        movdqa      xmm1,       [rax]
+        movdqa      xmm2,       [rax+16]
+
+        movsxd      rax,        dword ptr arg(3) ;yoffset
+
+        cmp         rax,        0      ;skip second_pass filter if yoffset=0
+        je          b16x16_fp_only
+
+        shl         rax,        5
+        add         rax,        rcx    ;VFilter
+
+        lea         rcx,        [rdi+rdx*8]
+        lea         rcx,        [rcx+rdx*8]
+        movsxd      rdx,        dword ptr arg(1) ;src_pixels_per_line
+
+        pxor        xmm0,       xmm0
+
+%if ABI_IS_32BIT=0
+        movsxd      r8,         dword ptr arg(5) ;dst_pitch
+%endif
+        ; get the first horizontal line done
+        movdqu      xmm3,       [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movdqa      xmm4,       xmm3                 ; make a copy of current line
+
+        punpcklbw   xmm3,       xmm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   xmm4,       xmm0
+
+        pmullw      xmm3,       xmm1
+        pmullw      xmm4,       xmm1
+
+        movdqu      xmm5,       [rsi+1]
+        movdqa      xmm6,       xmm5
+
+        punpcklbw   xmm5,       xmm0
+        punpckhbw   xmm6,       xmm0
+
+        pmullw      xmm5,       xmm2
+        pmullw      xmm6,       xmm2
+
+        paddw       xmm3,       xmm5
+        paddw       xmm4,       xmm6
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       xmm4,       [rd GLOBAL]
+        psraw       xmm4,       VP8_FILTER_SHIFT
+
+        movdqa      xmm7,       xmm3
+        packuswb    xmm7,       xmm4
+
+        add         rsi,        rdx                 ; next line
+next_row:
+        movdqu      xmm3,       [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movdqa      xmm4,       xmm3                 ; make a copy of current line
+
+        punpcklbw   xmm3,       xmm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   xmm4,       xmm0
+
+        pmullw      xmm3,       xmm1
+        pmullw      xmm4,       xmm1
+
+        movdqu      xmm5,       [rsi+1]
+        movdqa      xmm6,       xmm5
+
+        punpcklbw   xmm5,       xmm0
+        punpckhbw   xmm6,       xmm0
+
+        pmullw      xmm5,       xmm2
+        pmullw      xmm6,       xmm2
+
+        paddw       xmm3,       xmm5
+        paddw       xmm4,       xmm6
+
+        movdqa      xmm5,       xmm7
+        movdqa      xmm6,       xmm7
+
+        punpcklbw   xmm5,       xmm0
+        punpckhbw   xmm6,       xmm0
+
+        pmullw      xmm5,       [rax]
+        pmullw      xmm6,       [rax]
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       xmm4,       [rd GLOBAL]
+        psraw       xmm4,       VP8_FILTER_SHIFT
+
+        movdqa      xmm7,       xmm3
+        packuswb    xmm7,       xmm4
+
+        pmullw      xmm3,       [rax+16]
+        pmullw      xmm4,       [rax+16]
+
+        paddw       xmm3,       xmm5
+        paddw       xmm4,       xmm6
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       xmm4,       [rd GLOBAL]
+        psraw       xmm4,       VP8_FILTER_SHIFT
+
+        packuswb    xmm3,       xmm4
+        movdqa      [rdi],      xmm3                 ; store the results in the destination
+
+        add         rsi,        rdx                 ; next line
+%if ABI_IS_32BIT
+        add         rdi,        DWORD PTR arg(5) ;dst_pitch
+%else
+        add         rdi,        r8
+%endif
+
+        cmp         rdi,        rcx
+        jne         next_row
+
+        jmp         done
+
+b16x16_sp_only:
+        movsxd      rax,        dword ptr arg(3) ;yoffset
+        shl         rax,        5
+        add         rax,        rcx    ;VFilter
+
+        mov         rdi,        arg(4) ;dst_ptr
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rdx,        dword ptr arg(5) ;dst_pitch
+
+        movdqa      xmm1,       [rax]
+        movdqa      xmm2,       [rax+16]
+
+        lea         rcx,        [rdi+rdx*8]
+        lea         rcx,        [rcx+rdx*8]
+        movsxd      rax,        dword ptr arg(1) ;src_pixels_per_line
+
+        pxor        xmm0,       xmm0
+
+        ; get the first horizontal line done
+        movdqu      xmm7,       [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+
+        add         rsi,        rax                 ; next line
+next_row_spo:
+        movdqu      xmm3,       [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+
+        movdqa      xmm5,       xmm7
+        movdqa      xmm6,       xmm7
+
+        movdqa      xmm4,       xmm3                 ; make a copy of current line
+        movdqa      xmm7,       xmm3
+
+        punpcklbw   xmm5,       xmm0
+        punpckhbw   xmm6,       xmm0
+        punpcklbw   xmm3,       xmm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   xmm4,       xmm0
+
+        pmullw      xmm5,       xmm1
+        pmullw      xmm6,       xmm1
+        pmullw      xmm3,       xmm2
+        pmullw      xmm4,       xmm2
+
+        paddw       xmm3,       xmm5
+        paddw       xmm4,       xmm6
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       xmm4,       [rd GLOBAL]
+        psraw       xmm4,       VP8_FILTER_SHIFT
+
+        packuswb    xmm3,       xmm4
+        movdqa      [rdi],      xmm3                 ; store the results in the destination
+
+        add         rsi,        rax                 ; next line
+        add         rdi,        rdx                 ;dst_pitch
+        cmp         rdi,        rcx
+        jne         next_row_spo
+
+        jmp         done
+
+b16x16_fp_only:
+        lea         rcx,        [rdi+rdx*8]
+        lea         rcx,        [rcx+rdx*8]
+        movsxd      rax,        dword ptr arg(1) ;src_pixels_per_line
+        pxor        xmm0,       xmm0
+
+next_row_fpo:
+        movdqu      xmm3,       [rsi]               ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
+        movdqa      xmm4,       xmm3                 ; make a copy of current line
+
+        punpcklbw   xmm3,       xmm0                 ; xx 00 01 02 03 04 05 06
+        punpckhbw   xmm4,       xmm0
+
+        pmullw      xmm3,       xmm1
+        pmullw      xmm4,       xmm1
+
+        movdqu      xmm5,       [rsi+1]
+        movdqa      xmm6,       xmm5
+
+        punpcklbw   xmm5,       xmm0
+        punpckhbw   xmm6,       xmm0
+
+        pmullw      xmm5,       xmm2
+        pmullw      xmm6,       xmm2
+
+        paddw       xmm3,       xmm5
+        paddw       xmm4,       xmm6
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        paddw       xmm4,       [rd GLOBAL]
+        psraw       xmm4,       VP8_FILTER_SHIFT
+
+        packuswb    xmm3,       xmm4
+        movdqa      [rdi],      xmm3                 ; store the results in the destination
+
+        add         rsi,        rax                 ; next line
+        add         rdi,        rdx                 ; dst_pitch
+        cmp         rdi,        rcx
+        jne         next_row_fpo
+
+done:
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_bilinear_predict8x8_sse2
+;(
+;    unsigned char  *src_ptr,
+;    int   src_pixels_per_line,
+;    int  xoffset,
+;    int  yoffset,
+;    unsigned char *dst_ptr,
+;    int dst_pitch
+;)
+extern sym(vp8_bilinear_filters_mmx)
+global sym(vp8_bilinear_predict8x8_sse2)
+sym(vp8_bilinear_predict8x8_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    ALIGN_STACK 16, rax
+    sub         rsp, 144                         ; reserve 144 bytes
+
+    ;const short *HFilter = bilinear_filters_mmx[xoffset]
+    ;const short *VFilter = bilinear_filters_mmx[yoffset]
+        lea         rcx,        [sym(vp8_bilinear_filters_mmx) GLOBAL]
+
+        mov         rsi,        arg(0) ;src_ptr
+        movsxd      rdx,        dword ptr arg(1) ;src_pixels_per_line
+
+    ;Read 9-line unaligned data in and put them on stack. This gives a big
+    ;performance boost.
+        movdqu      xmm0,       [rsi]
+        lea         rax,        [rdx + rdx*2]
+        movdqu      xmm1,       [rsi+rdx]
+        movdqu      xmm2,       [rsi+rdx*2]
+        add         rsi,        rax
+        movdqu      xmm3,       [rsi]
+        movdqu      xmm4,       [rsi+rdx]
+        movdqu      xmm5,       [rsi+rdx*2]
+        add         rsi,        rax
+        movdqu      xmm6,       [rsi]
+        movdqu      xmm7,       [rsi+rdx]
+
+        movdqa      XMMWORD PTR [rsp],            xmm0
+
+        movdqu      xmm0,       [rsi+rdx*2]
+
+        movdqa      XMMWORD PTR [rsp+16],         xmm1
+        movdqa      XMMWORD PTR [rsp+32],         xmm2
+        movdqa      XMMWORD PTR [rsp+48],         xmm3
+        movdqa      XMMWORD PTR [rsp+64],         xmm4
+        movdqa      XMMWORD PTR [rsp+80],         xmm5
+        movdqa      XMMWORD PTR [rsp+96],         xmm6
+        movdqa      XMMWORD PTR [rsp+112],        xmm7
+        movdqa      XMMWORD PTR [rsp+128],        xmm0
+
+        movsxd      rax,        dword ptr arg(2) ;xoffset
+        shl         rax,        5
+        add         rax,        rcx    ;HFilter
+
+        mov         rdi,        arg(4) ;dst_ptr
+        movsxd      rdx,        dword ptr arg(5) ;dst_pitch
+
+        movdqa      xmm1,       [rax]
+        movdqa      xmm2,       [rax+16]
+
+        movsxd      rax,        dword ptr arg(3) ;yoffset
+        shl         rax,        5
+        add         rax,        rcx    ;VFilter
+
+        lea         rcx,        [rdi+rdx*8]
+
+        movdqa      xmm5,       [rax]
+        movdqa      xmm6,       [rax+16]
+
+        pxor        xmm0,       xmm0
+
+        ; get the first horizontal line done
+        movdqa      xmm3,       XMMWORD PTR [rsp]
+        movdqa      xmm4,       xmm3                 ; make a copy of current line
+        psrldq      xmm4,       1
+
+        punpcklbw   xmm3,       xmm0                 ; 00 01 02 03 04 05 06 07
+        punpcklbw   xmm4,       xmm0                 ; 01 02 03 04 05 06 07 08
+
+        pmullw      xmm3,       xmm1
+        pmullw      xmm4,       xmm2
+
+        paddw       xmm3,       xmm4
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        movdqa      xmm7,       xmm3
+        add         rsp,        16                 ; next line
+next_row8x8:
+        movdqa      xmm3,       XMMWORD PTR [rsp]               ; 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
+        movdqa      xmm4,       xmm3                 ; make a copy of current line
+        psrldq      xmm4,       1
+
+        punpcklbw   xmm3,       xmm0                 ; 00 01 02 03 04 05 06 07
+        punpcklbw   xmm4,       xmm0                 ; 01 02 03 04 05 06 07 08
+
+        pmullw      xmm3,       xmm1
+        pmullw      xmm4,       xmm2
+
+        paddw       xmm3,       xmm4
+        pmullw      xmm7,       xmm5
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        movdqa      xmm4,       xmm3
+
+        pmullw      xmm3,       xmm6
+        paddw       xmm3,       xmm7
+
+        movdqa      xmm7,       xmm4
+
+        paddw       xmm3,       [rd GLOBAL]         ; xmm3 += round value
+        psraw       xmm3,       VP8_FILTER_SHIFT        ; xmm3 /= 128
+
+        packuswb    xmm3,       xmm0
+        movq        [rdi],      xmm3                 ; store the results in the destination
+
+        add         rsp,        16                 ; next line
+        add         rdi,        rdx
+
+        cmp         rdi,        rcx
+        jne         next_row8x8
+
+    ;add rsp, 144
+    pop rsp
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+align 16
+rd:
+    times 8 dw 0x40
diff --git a/vp8/common/x86/subpixel_x86.h b/vp8/common/x86/subpixel_x86.h
new file mode 100644 (file)
index 0000000..efa7b2e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef SUBPIXEL_X86_H
+#define SUBPIXEL_X86_H
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+
+#if HAVE_MMX
+extern prototype_subpixel_predict(vp8_sixtap_predict16x16_mmx);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x8_mmx);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x4_mmx);
+extern prototype_subpixel_predict(vp8_sixtap_predict4x4_mmx);
+extern prototype_subpixel_predict(vp8_bilinear_predict16x16_mmx);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x8_mmx);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x4_mmx);
+extern prototype_subpixel_predict(vp8_bilinear_predict4x4_mmx);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_subpix_sixtap16x16
+#define vp8_subpix_sixtap16x16 vp8_sixtap_predict16x16_mmx
+
+#undef  vp8_subpix_sixtap8x8
+#define vp8_subpix_sixtap8x8 vp8_sixtap_predict8x8_mmx
+
+#undef  vp8_subpix_sixtap8x4
+#define vp8_subpix_sixtap8x4 vp8_sixtap_predict8x4_mmx
+
+#undef  vp8_subpix_sixtap4x4
+#define vp8_subpix_sixtap4x4 vp8_sixtap_predict4x4_mmx
+
+#undef  vp8_subpix_bilinear16x16
+#define vp8_subpix_bilinear16x16 vp8_bilinear_predict16x16_mmx
+
+#undef  vp8_subpix_bilinear8x8
+#define vp8_subpix_bilinear8x8 vp8_bilinear_predict8x8_mmx
+
+#undef  vp8_subpix_bilinear8x4
+#define vp8_subpix_bilinear8x4 vp8_bilinear_predict8x4_mmx
+
+#undef  vp8_subpix_bilinear4x4
+#define vp8_subpix_bilinear4x4 vp8_bilinear_predict4x4_mmx
+
+#endif
+#endif
+
+
+#if HAVE_SSE2
+extern prototype_subpixel_predict(vp8_sixtap_predict16x16_sse2);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x8_sse2);
+extern prototype_subpixel_predict(vp8_sixtap_predict8x4_sse2);
+extern prototype_subpixel_predict(vp8_bilinear_predict16x16_sse2);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x8_sse2);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_subpix_sixtap16x16
+#define vp8_subpix_sixtap16x16 vp8_sixtap_predict16x16_sse2
+
+#undef  vp8_subpix_sixtap8x8
+#define vp8_subpix_sixtap8x8 vp8_sixtap_predict8x8_sse2
+
+#undef  vp8_subpix_sixtap8x4
+#define vp8_subpix_sixtap8x4 vp8_sixtap_predict8x4_sse2
+
+#undef  vp8_subpix_bilinear16x16
+#define vp8_subpix_bilinear16x16 vp8_bilinear_predict16x16_sse2
+
+#undef  vp8_subpix_bilinear8x8
+#define vp8_subpix_bilinear8x8 vp8_bilinear_predict8x8_sse2
+
+#endif
+#endif
+
+#endif
diff --git a/vp8/common/x86/vp8_asm_stubs.c b/vp8/common/x86/vp8_asm_stubs.c
new file mode 100644 (file)
index 0000000..68454f7
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "vpx_ports/mem.h"
+#include "subpixel.h"
+
+extern const short vp8_six_tap_mmx[8][6*8];
+extern const short vp8_bilinear_filters_mmx[8][2*8];
+
+extern void vp8_filter_block1d_h6_mmx
+(
+    unsigned char   *src_ptr,
+    unsigned short  *output_ptr,
+    unsigned int    src_pixels_per_line,
+    unsigned int    pixel_step,
+    unsigned int    output_height,
+    unsigned int    output_width,
+    const short      *vp8_filter
+);
+extern void vp8_filter_block1dc_v6_mmx
+(
+    unsigned short *src_ptr,
+    unsigned char  *output_ptr,
+    int             output_pitch,
+    unsigned int    pixels_per_line,
+    unsigned int    pixel_step,
+    unsigned int    output_height,
+    unsigned int    output_width,
+    const short    *vp8_filter
+);
+extern void vp8_filter_block1d8_h6_sse2
+(
+    unsigned char  *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int    src_pixels_per_line,
+    unsigned int    pixel_step,
+    unsigned int    output_height,
+    unsigned int    output_width,
+    const short    *vp8_filter
+);
+extern void vp8_filter_block1d16_h6_sse2
+(
+    unsigned char  *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int    src_pixels_per_line,
+    unsigned int    pixel_step,
+    unsigned int    output_height,
+    unsigned int    output_width,
+    const short    *vp8_filter
+);
+extern void vp8_filter_block1d8_v6_sse2
+(
+    unsigned short *src_ptr,
+    unsigned char *output_ptr,
+    int dst_ptich,
+    unsigned int pixels_per_line,
+    unsigned int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    const short    *vp8_filter
+);
+extern void vp8_unpack_block1d16_h6_sse2
+(
+    unsigned char  *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int    src_pixels_per_line,
+    unsigned int    output_height,
+    unsigned int    output_width
+);
+extern void vp8_unpack_block1d8_h6_sse2
+(
+    unsigned char  *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int    src_pixels_per_line,
+    unsigned int    output_height,
+    unsigned int    output_width
+);
+extern void vp8_pack_block1d8_v6_sse2
+(
+    unsigned short *src_ptr,
+    unsigned char *output_ptr,
+    int dst_ptich,
+    unsigned int pixels_per_line,
+    unsigned int output_height,
+    unsigned int output_width
+);
+extern void vp8_pack_block1d16_v6_sse2
+(
+    unsigned short *src_ptr,
+    unsigned char *output_ptr,
+    int dst_ptich,
+    unsigned int pixels_per_line,
+    unsigned int output_height,
+    unsigned int output_width
+);
+extern prototype_subpixel_predict(vp8_bilinear_predict8x8_mmx);
+
+
+#if HAVE_MMX
+void vp8_sixtap_predict4x4_mmx
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 16*16);  // Temp data bufffer used in filtering
+    const short *HFilter, *VFilter;
+    HFilter = vp8_six_tap_mmx[xoffset];
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line), FData2, src_pixels_per_line, 1, 9, 8, HFilter);
+    VFilter = vp8_six_tap_mmx[yoffset];
+    vp8_filter_block1dc_v6_mmx(FData2 + 8, dst_ptr, dst_pitch, 8, 4 , 4, 4, VFilter);
+
+}
+
+
+void vp8_sixtap_predict16x16_mmx
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 24*24);  // Temp data bufffer used in filtering
+
+    const short *HFilter, *VFilter;
+
+
+    HFilter = vp8_six_tap_mmx[xoffset];
+
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line),    FData2,   src_pixels_per_line, 1, 21, 32, HFilter);
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line) + 4,  FData2 + 4, src_pixels_per_line, 1, 21, 32, HFilter);
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line) + 8,  FData2 + 8, src_pixels_per_line, 1, 21, 32, HFilter);
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line) + 12, FData2 + 12, src_pixels_per_line, 1, 21, 32, HFilter);
+
+    VFilter = vp8_six_tap_mmx[yoffset];
+    vp8_filter_block1dc_v6_mmx(FData2 + 32, dst_ptr,   dst_pitch, 32, 16 , 16, 16, VFilter);
+    vp8_filter_block1dc_v6_mmx(FData2 + 36, dst_ptr + 4, dst_pitch, 32, 16 , 16, 16, VFilter);
+    vp8_filter_block1dc_v6_mmx(FData2 + 40, dst_ptr + 8, dst_pitch, 32, 16 , 16, 16, VFilter);
+    vp8_filter_block1dc_v6_mmx(FData2 + 44, dst_ptr + 12, dst_pitch, 32, 16 , 16, 16, VFilter);
+
+}
+
+
+void vp8_sixtap_predict8x8_mmx
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);    // Temp data bufffer used in filtering
+
+    const short *HFilter, *VFilter;
+
+    HFilter = vp8_six_tap_mmx[xoffset];
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line),    FData2,   src_pixels_per_line, 1, 13, 16, HFilter);
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line) + 4,  FData2 + 4, src_pixels_per_line, 1, 13, 16, HFilter);
+
+    VFilter = vp8_six_tap_mmx[yoffset];
+    vp8_filter_block1dc_v6_mmx(FData2 + 16, dst_ptr,   dst_pitch, 16, 8 , 8, 8, VFilter);
+    vp8_filter_block1dc_v6_mmx(FData2 + 20, dst_ptr + 4, dst_pitch, 16, 8 , 8, 8, VFilter);
+
+}
+
+
+void vp8_sixtap_predict8x4_mmx
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);    // Temp data bufffer used in filtering
+
+    const short *HFilter, *VFilter;
+
+    HFilter = vp8_six_tap_mmx[xoffset];
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line),    FData2,   src_pixels_per_line, 1, 9, 16, HFilter);
+    vp8_filter_block1d_h6_mmx(src_ptr - (2 * src_pixels_per_line) + 4,  FData2 + 4, src_pixels_per_line, 1, 9, 16, HFilter);
+
+    VFilter = vp8_six_tap_mmx[yoffset];
+    vp8_filter_block1dc_v6_mmx(FData2 + 16, dst_ptr,   dst_pitch, 16, 8 , 4, 8, VFilter);
+    vp8_filter_block1dc_v6_mmx(FData2 + 20, dst_ptr + 4, dst_pitch, 16, 8 , 4, 8, VFilter);
+
+}
+
+
+
+void vp8_bilinear_predict16x16_mmx
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    vp8_bilinear_predict8x8_mmx(src_ptr,   src_pixels_per_line, xoffset, yoffset, dst_ptr,   dst_pitch);
+    vp8_bilinear_predict8x8_mmx(src_ptr + 8, src_pixels_per_line, xoffset, yoffset, dst_ptr + 8, dst_pitch);
+    vp8_bilinear_predict8x8_mmx(src_ptr + 8 * src_pixels_per_line,   src_pixels_per_line, xoffset, yoffset, dst_ptr + dst_pitch * 8,   dst_pitch);
+    vp8_bilinear_predict8x8_mmx(src_ptr + 8 * src_pixels_per_line + 8, src_pixels_per_line, xoffset, yoffset, dst_ptr + dst_pitch * 8 + 8, dst_pitch);
+}
+#endif
+
+
+#if HAVE_SSE2
+void vp8_sixtap_predict16x16_sse2
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+
+)
+{
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 24*24);    // Temp data bufffer used in filtering
+
+    const short *HFilter, *VFilter;
+
+    if (xoffset)
+    {
+        HFilter = vp8_six_tap_mmx[xoffset];
+        vp8_filter_block1d16_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2,   src_pixels_per_line, 1, 21, 32, HFilter);
+    }
+    else
+    {
+        vp8_unpack_block1d16_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2,   src_pixels_per_line, 21, 32);
+    }
+
+    if (yoffset)
+    {
+        VFilter = vp8_six_tap_mmx[yoffset];
+        vp8_filter_block1d8_v6_sse2(FData2 + 32, dst_ptr,   dst_pitch, 32, 16 , 16, 16, VFilter);
+        vp8_filter_block1d8_v6_sse2(FData2 + 40, dst_ptr + 8, dst_pitch, 32, 16 , 16, 16, VFilter);
+    }
+    else
+    {
+        vp8_pack_block1d16_v6_sse2(FData2 + 32, dst_ptr,   dst_pitch, 32,  16, 16);
+    }
+}
+
+
+void vp8_sixtap_predict8x8_sse2
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);  // Temp data bufffer used in filtering
+    const short *HFilter, *VFilter;
+
+    if (xoffset)
+    {
+        HFilter = vp8_six_tap_mmx[xoffset];
+        vp8_filter_block1d8_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2,   src_pixels_per_line, 1, 13, 16, HFilter);
+    }
+    else
+    {
+        vp8_unpack_block1d8_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2,   src_pixels_per_line, 13, 16);
+    }
+
+    if (yoffset)
+    {
+        VFilter = vp8_six_tap_mmx[yoffset];
+        vp8_filter_block1d8_v6_sse2(FData2 + 16, dst_ptr,   dst_pitch, 16, 8 , 8, dst_pitch, VFilter);
+    }
+    else
+    {
+        vp8_pack_block1d8_v6_sse2(FData2 + 16, dst_ptr,   dst_pitch, 16,  8, dst_pitch);
+    }
+
+
+}
+
+
+void vp8_sixtap_predict8x4_sse2
+(
+    unsigned char  *src_ptr,
+    int   src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pitch
+)
+{
+    DECLARE_ALIGNED_ARRAY(16, unsigned short, FData2, 256);  // Temp data bufffer used in filtering
+    const short *HFilter, *VFilter;
+
+    if (xoffset)
+    {
+        HFilter = vp8_six_tap_mmx[xoffset];
+        vp8_filter_block1d8_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2,   src_pixels_per_line, 1, 9, 16, HFilter);
+    }
+    else
+    {
+        vp8_unpack_block1d8_h6_sse2(src_ptr - (2 * src_pixels_per_line), FData2,   src_pixels_per_line, 9, 16);
+    }
+
+    if (yoffset)
+    {
+        VFilter = vp8_six_tap_mmx[yoffset];
+        vp8_filter_block1d8_v6_sse2(FData2 + 16, dst_ptr,   dst_pitch, 16, 8 , 4, dst_pitch, VFilter);
+    }
+    else
+    {
+        vp8_pack_block1d8_v6_sse2(FData2 + 16, dst_ptr,   dst_pitch, 16,  4, dst_pitch);
+    }
+
+
+}
+#endif
diff --git a/vp8/common/x86/x86_systemdependent.c b/vp8/common/x86/x86_systemdependent.c
new file mode 100644 (file)
index 0000000..5312e06
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "vpx_ports/x86.h"
+#include "g_common.h"
+#include "subpixel.h"
+#include "loopfilter.h"
+#include "recon.h"
+#include "idct.h"
+#include "pragmas.h"
+#include "onyxc_int.h"
+
+void vp8_arch_x86_common_init(VP8_COMMON *ctx)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    VP8_COMMON_RTCD *rtcd = &ctx->rtcd;
+    int flags = x86_simd_caps();
+    int mmx_enabled = flags & HAS_MMX;
+    int xmm_enabled = flags & HAS_SSE;
+    int wmt_enabled = flags & HAS_SSE2;
+
+    /* Note:
+     *
+     * This platform can be built without runtime CPU detection as well. If
+     * you modify any of the function mappings present in this file, be sure
+     * to also update them in static mapings (<arch>/filename_<arch>.h)
+     */
+
+    /* Override default functions with fastest ones for this CPU. */
+#if HAVE_MMX
+
+    if (mmx_enabled)
+    {
+        rtcd->idct.idct1        = vp8_short_idct4x4llm_1_mmx;
+        rtcd->idct.idct16       = vp8_short_idct4x4llm_mmx;
+        rtcd->idct.idct1_scalar = vp8_dc_only_idct_mmx;
+        rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_mmx;
+        rtcd->idct.iwalsh1     = vp8_short_inv_walsh4x4_1_mmx;
+
+
+
+        rtcd->recon.recon       = vp8_recon_b_mmx;
+        rtcd->recon.copy8x8     = vp8_copy_mem8x8_mmx;
+        rtcd->recon.copy8x4     = vp8_copy_mem8x4_mmx;
+        rtcd->recon.copy16x16   = vp8_copy_mem16x16_mmx;
+
+        rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_mmx;
+        rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_mmx;
+        rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_mmx;
+        rtcd->subpix.sixtap4x4     = vp8_sixtap_predict4x4_mmx;
+        rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_mmx;
+        rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_mmx;
+        rtcd->subpix.bilinear8x4   = vp8_bilinear_predict8x4_mmx;
+        rtcd->subpix.bilinear4x4   = vp8_bilinear_predict4x4_mmx;
+
+        rtcd->loopfilter.normal_mb_v = vp8_loop_filter_mbv_mmx;
+        rtcd->loopfilter.normal_b_v  = vp8_loop_filter_bv_mmx;
+        rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_mmx;
+        rtcd->loopfilter.normal_b_h  = vp8_loop_filter_bh_mmx;
+        rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_mmx;
+        rtcd->loopfilter.simple_b_v  = vp8_loop_filter_bvs_mmx;
+        rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_mmx;
+        rtcd->loopfilter.simple_b_h  = vp8_loop_filter_bhs_mmx;
+
+#if CONFIG_POSTPROC
+        rtcd->postproc.down        = vp8_mbpost_proc_down_mmx;
+        //rtcd->postproc.across      = vp8_mbpost_proc_across_ip_c;
+        rtcd->postproc.downacross  = vp8_post_proc_down_and_across_mmx;
+        rtcd->postproc.addnoise    = vp8_plane_add_noise_mmx;
+#endif
+    }
+
+#endif
+#if HAVE_SSE2
+
+    if (wmt_enabled)
+    {
+        rtcd->recon.recon2      = vp8_recon2b_sse2;
+        rtcd->recon.recon4      = vp8_recon4b_sse2;
+        rtcd->recon.copy16x16   = vp8_copy_mem16x16_sse2;
+
+        rtcd->idct.iwalsh16     = vp8_short_inv_walsh4x4_sse2;
+
+        rtcd->subpix.sixtap16x16   = vp8_sixtap_predict16x16_sse2;
+        rtcd->subpix.sixtap8x8     = vp8_sixtap_predict8x8_sse2;
+        rtcd->subpix.sixtap8x4     = vp8_sixtap_predict8x4_sse2;
+        rtcd->subpix.bilinear16x16 = vp8_bilinear_predict16x16_sse2;
+        rtcd->subpix.bilinear8x8   = vp8_bilinear_predict8x8_sse2;
+
+        rtcd->loopfilter.normal_mb_v = vp8_loop_filter_mbv_sse2;
+        rtcd->loopfilter.normal_b_v  = vp8_loop_filter_bv_sse2;
+        rtcd->loopfilter.normal_mb_h = vp8_loop_filter_mbh_sse2;
+        rtcd->loopfilter.normal_b_h  = vp8_loop_filter_bh_sse2;
+        rtcd->loopfilter.simple_mb_v = vp8_loop_filter_mbvs_sse2;
+        rtcd->loopfilter.simple_b_v  = vp8_loop_filter_bvs_sse2;
+        rtcd->loopfilter.simple_mb_h = vp8_loop_filter_mbhs_sse2;
+        rtcd->loopfilter.simple_b_h  = vp8_loop_filter_bhs_sse2;
+
+#if CONFIG_POSTPROC
+        rtcd->postproc.down        = vp8_mbpost_proc_down_xmm;
+        rtcd->postproc.across      = vp8_mbpost_proc_across_ip_xmm;
+        rtcd->postproc.downacross  = vp8_post_proc_down_and_across_xmm;
+        rtcd->postproc.addnoise    = vp8_plane_add_noise_wmt;
+#endif
+    }
+
+#endif
+#endif
+}
diff --git a/vp8/decoder/arm/armv5/dequantize_v5.asm b/vp8/decoder/arm/armv5/dequantize_v5.asm
new file mode 100644 (file)
index 0000000..eb3f030
--- /dev/null
@@ -0,0 +1,51 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequantize_b_armv5|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+q       RN  r0
+dqc     RN  r1
+cnt     RN  r2
+
+;void dequantize_b_armv5(short *Q, short *DQC)
+|vp8_dequantize_b_armv5| PROC
+    stmdb   sp!, {r4, lr}
+    ldr     r3, [q]
+    ldr     r4, [dqc], #8
+
+    mov     cnt, #4
+dequant_loop
+    smulbb  lr, r3, r4
+    smultt  r12, r3, r4
+
+    ldr     r3, [q, #4]
+    ldr     r4, [dqc, #-4]
+
+    strh    lr, [q], #2
+    strh    r12, [q], #2
+
+    smulbb  lr, r3, r4
+    smultt  r12, r3, r4
+
+    subs    cnt, cnt, #1
+    ldrne   r3, [q, #4]
+    ldrne   r4, [dqc], #8
+
+    strh    lr, [q], #2
+    strh    r12, [q], #2
+
+    bne     dequant_loop
+
+    ldmia   sp!, {r4, pc}
+    ENDP    ;|vp8_dequantize_b_arm|
+
+    END
diff --git a/vp8/decoder/arm/armv6/dboolhuff_v6.asm b/vp8/decoder/arm/armv6/dboolhuff_v6.asm
new file mode 100644 (file)
index 0000000..143e33e
--- /dev/null
@@ -0,0 +1,162 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_decode_value_v6|
+    EXPORT  |vp8dx_start_decode_v6|
+    EXPORT  |vp8dx_stop_decode_v6|
+    EXPORT  |vp8dx_decode_bool_v6|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    INCLUDE vpx_asm_offsets.asm
+
+br      RN  r0
+prob    RN  r1
+bits    RN  r1
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+;   int z = 0;
+;   int bit;
+;   for ( bit=bits-1; bit>=0; bit-- )
+;   {
+;       z |= (vp8dx_decode_bool(br, 0x80)<<bit);
+;   }
+;   return z;
+
+;int vp8_decode_value_v6 ( BOOL_DECODER *br, int bits )
+|vp8_decode_value_v6| PROC
+    stmdb   sp!, {r4 - r6, lr}
+    mov     r4, br
+    mov     r5, bits
+    mov     r6, #0
+
+    subs    r5, r5, #1
+    bmi     decode_value_exit
+
+decode_value_loop
+    mov     prob, #0x80
+    mov     br, r4
+    bl      vp8dx_decode_bool_v6_internal     ; needed for conversion to s file
+    orr     r6, r6, r0, lsl r5
+    subs    r5, r5, #1
+    bpl     decode_value_loop
+
+decode_value_exit
+    mov     r0, r6
+    ldmia   sp!, {r4 - r6, pc}
+    ENDP    ; |vp8_decode_value_v6|
+
+
+;void vp8dx_start_decode_v6 ( BOOL_DECODER *br, unsigned char *source )
+|vp8dx_start_decode_v6| PROC
+    stmdb   sp!, {r4 - r5, lr}
+    mov     r2, #0
+    mov     r3, #255
+
+    str     r2, [br, #bool_decoder_lowvalue]
+    str     r3, [br, #bool_decoder_range]
+    str     r1, [br, #bool_decoder_buffer]
+
+    mov     r3, #8
+    mov     r2, #4
+    str     r3, [br, #bool_decoder_count]
+    str     r2, [br, #bool_decoder_pos]
+
+    ldrb    r2, [r1, #3]
+    ldrb    r3, [r1, #2]
+    ldrb    r4, [r1, #1]
+    ldrb    r5, [r1]
+
+    orr     r1, r2, r3, lsl #8
+    orr     r1, r1, r4, lsl #16
+    orr     r1, r1, r5, lsl #24
+
+    str     r1, [br, #bool_decoder_value]
+
+    ldmia   sp!, {r4 - r5, pc}
+    ENDP    ; |vp8dx_start_decode_v6|
+
+
+;void vp8dx_stop_decode_v6 ( BOOL_DECODER *bc );
+|vp8dx_stop_decode_v6| PROC
+    mov     pc, lr
+    ENDP    ; |vp8dx_stop_decode_v6|
+
+
+; bigsplit  RN  r1
+; buffer_v  RN  r1
+; count_v       RN  r4
+; range_v       RN  r2
+; value_v       RN  r3
+; pos_v     RN  r5
+; split     RN  r6
+; bit           RN  lr
+;int vp8dx_decode_bool_v6 ( BOOL_DECODER *br, int probability )
+|vp8dx_decode_bool_v6| PROC
+vp8dx_decode_bool_v6_internal
+    stmdb   sp!, {r4 - r6, lr}
+
+    ldr     r2, [br, #bool_decoder_range]
+    ldr     r3, [br, #bool_decoder_value]
+
+    mov     r6, r2, lsl #8
+    sub     r6, r6, #256                ;   split = 1 +  (((range-1) * probability) >> 8)
+    mov     r12, #1
+    smlawb  r6, r6, prob, r12
+
+    mov     lr, #0
+    subs    r5, r3, r6, lsl #24
+
+    ;cmp        r3, r1
+    movhs   lr, #1
+    movhs   r3, r5
+    subhs   r2, r2, r6
+    movlo   r2, r6
+
+    cmp     r2, #0x80
+    blt     range_less_0x80
+    ;strd   r2, r3, [br, #bool_decoder_range]
+    str     r2, [br, #bool_decoder_range]
+    str     r3, [br, #bool_decoder_value]
+    mov     r0, lr
+    ldmia   sp!, {r4 - r6, pc}
+
+range_less_0x80
+    ldr     r5, [br, #bool_decoder_pos]
+    ldr     r1, [br, #bool_decoder_buffer]
+    ldr     r4, [br, #bool_decoder_count]
+    add     r1, r1, r5
+
+    clz       r12, r2
+    sub       r12, r12, #24
+    subs      r4, r4, r12
+    ldrleb    r6, [r1], #1
+    mov       r2, r2, lsl r12
+    mov       r3, r3, lsl r12
+    addle     r4, r4, #8
+    rsble     r12, r4, #8
+    addle     r5, r5, #1
+    orrle     r3, r3, r6, lsl r12
+
+    ;strd       r2, r3, [br, #bool_decoder_range]
+    ;strd       r4, r5, [br, #bool_decoder_count]
+    str         r2, [br, #bool_decoder_range]
+    str         r3, [br, #bool_decoder_value]
+    str         r4, [br, #bool_decoder_count]
+    str         r5, [br, #bool_decoder_pos]
+
+    mov     r0, lr
+
+    ldmia   sp!, {r4 - r6, pc}
+    ENDP    ; |vp8dx_decode_bool_v6|
+
+    END
diff --git a/vp8/decoder/arm/armv6/dequantdcidct_v6.asm b/vp8/decoder/arm/armv6/dequantdcidct_v6.asm
new file mode 100644 (file)
index 0000000..3daa9b3
--- /dev/null
@@ -0,0 +1,202 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequant_dc_idct_v6|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+;void vp8_dequant_dc_idct_v6(short *input, short *dq, short *output, int pitch,int Dc)
+|vp8_dequant_dc_idct_v6| PROC
+    stmdb   sp!, {r4-r11, lr}
+
+    ldr     r6, [sp, #36]           ;load Dc
+
+    ldr     r4, [r0]                ;input
+    ldr     r5, [r1], #4            ;dq
+
+    sub     sp, sp, #4
+    str     r0, [sp]
+
+    smultt  r7, r4, r5
+
+    ldr     r4, [r0, #4]            ;input
+    ldr     r5, [r1], #4            ;dq
+
+    strh    r6, [r0], #2
+    strh    r7, [r0], #2
+
+    smulbb  r6, r4, r5
+    smultt  r7, r4, r5
+
+    ldr     r4, [r0, #4]            ;input
+    ldr     r5, [r1], #4            ;dq
+
+    strh    r6, [r0], #2
+    strh    r7, [r0], #2
+
+    mov     r12, #3
+
+dequant_dc_idct_loop
+    smulbb  r6, r4, r5
+    smultt  r7, r4, r5
+
+    ldr     r4, [r0, #4]            ;input
+    ldr     r5, [r1], #4            ;dq
+
+    strh    r6, [r0], #2
+    strh    r7, [r0], #2
+
+    smulbb  r6, r4, r5
+    smultt  r7, r4, r5
+
+    subs    r12, r12, #1
+
+    ldrne   r4, [r0, #4]
+    ldrne   r5, [r1], #4
+
+    strh    r6, [r0], #2
+    strh    r7, [r0], #2
+
+    bne     dequant_dc_idct_loop
+
+    sub     r0, r0, #32
+    mov     r1, r2
+    mov     r2, r3
+
+; short_idct4x4llm_v6_dual
+
+    mov r3, #0x00004E00 ;                   cos
+    orr r3, r3, #0x0000007B ; cospi8sqrt2minus1
+    mov r4, #0x00008A00 ;                       sin
+    orr r4, r4, #0x0000008C ; sinpi8sqrt2
+    mov r5, #0x2    ; i=2                           i
+loop1_dual_11
+    ldr r6, [r0, #(4*2)]    ; i5 | i4                               5|4
+    ldr r12, [r0, #(12*2)]  ; i13 | i12                                                     13|12
+    ldr r14, [r0, #(8*2)]   ; i9 | i8                                                               9|8
+
+    smulwt  r9, r3, r6  ; (ip[5] * cospi8sqrt2minus1) >> 16                                         5c
+    smulwb  r7, r3, r6  ; (ip[4] * cospi8sqrt2minus1) >> 16                                 4c
+    smulwt  r10, r4, r6 ; (ip[5] * sinpi8sqrt2) >> 16                                               5s
+    smulwb  r8, r4, r6  ; (ip[4] * sinpi8sqrt2) >> 16                                       4s
+    pkhbt   r7, r7, r9, lsl #16 ; 5c | 4c
+    smulwt  r11, r3, r12    ; (ip[13] * cospi8sqrt2minus1) >> 16                                                    13c
+    pkhbt   r8, r8, r10, lsl #16    ; 5s | 4s
+    uadd16  r6, r6, r7  ; 5c+5 | 4c+4
+    smulwt  r7, r4, r12 ; (ip[13] * sinpi8sqrt2) >> 16                                  13s
+    smulwb  r9, r3, r12 ; (ip[12] * cospi8sqrt2minus1) >> 16                                            12c
+    smulwb  r10, r4, r12    ; (ip[12] * sinpi8sqrt2) >> 16                                              12s
+    subs    r5, r5, #0x1    ; i--                           --
+    pkhbt   r9, r9, r11, lsl #16    ; 13c | 12c
+    ldr r11, [r0], #0x4 ; i1 | i0       ++                                          1|0
+    pkhbt   r10, r10, r7, lsl #16   ; 13s | 12s
+    uadd16  r7, r12, r9 ; 13c+13 | 12c+12
+    usub16  r7, r8, r7  ; c                                 c
+    uadd16  r6, r6, r10 ; d                             d
+    uadd16  r10, r11, r14   ; a                                             a
+    usub16  r8, r11, r14    ; b                                     b
+    uadd16  r9, r10, r6 ; a+d                                           a+d
+    usub16  r10, r10, r6    ; a-d                                               a-d
+    uadd16  r6, r8, r7  ; b+c                               b+c
+    usub16  r7, r8, r7  ; b-c                                   b-c
+    str r6, [r1, r2]    ; o5 | o4
+    add r6, r2, r2  ; pitch * 2                             p2
+    str r7, [r1, r6]    ; o9 | o8
+    add r6,  r6, r2 ; pitch * 3                             p3
+    str r10, [r1, r6]   ; o13 | o12
+    str r9, [r1], #0x4  ; o1 | o0           ++
+    bne loop1_dual_11   ;
+    mov r5, #0x2    ; i=2                           i
+    sub r0, r1, #8  ; reset input/output        i/o
+loop2_dual_22
+    ldr r6, [r0, r2]    ; i5 | i4                               5|4
+    ldr r1, [r0]    ; i1 | i0           1|0
+    ldr r12, [r0, #0x4] ; i3 | i2                                                       3|2
+    add r14, r2, #0x4   ; pitch + 2                                                             p+2
+    ldr r14, [r0, r14]  ; i7 | i6                                                               7|6
+    smulwt  r9, r3, r6  ; (ip[5] * cospi8sqrt2minus1) >> 16                                         5c
+    smulwt  r7, r3, r1  ; (ip[1] * cospi8sqrt2minus1) >> 16                                 1c
+    smulwt  r10, r4, r6 ; (ip[5] * sinpi8sqrt2) >> 16                                               5s
+    smulwt  r8, r4, r1  ; (ip[1] * sinpi8sqrt2) >> 16                                       1s
+    pkhbt   r11, r6, r1, lsl #16    ; i0 | i4                                                   0|4
+    pkhbt   r7, r9, r7, lsl #16 ; 1c | 5c
+    pkhbt   r8, r10, r8, lsl #16    ; 1s | 5s = temp1 ©                                     tc1
+    pkhtb   r1, r1, r6, asr #16 ; i1 | i5           1|5
+    uadd16  r1, r7, r1  ; 1c+1 | 5c+5 = temp2 (d)           td2
+    pkhbt   r9, r14, r12, lsl #16   ; i2 | i6                                           2|6
+    uadd16  r10, r11, r9    ; a                                             a
+    usub16  r9, r11, r9 ; b                                         b
+    pkhtb   r6, r12, r14, asr #16   ; i3 | i7                               3|7
+    subs    r5, r5, #0x1    ; i--                           --
+    smulwt  r7, r3, r6  ; (ip[3] * cospi8sqrt2minus1) >> 16                                 3c
+    smulwt  r11, r4, r6 ; (ip[3] * sinpi8sqrt2) >> 16                                                   3s
+    smulwb  r12, r3, r6 ; (ip[7] * cospi8sqrt2minus1) >> 16                                                     7c
+    smulwb  r14, r4, r6 ; (ip[7] * sinpi8sqrt2) >> 16                                                               7s
+
+    pkhbt   r7, r12, r7, lsl #16    ; 3c | 7c
+    pkhbt   r11, r14, r11, lsl #16  ; 3s | 7s = temp1 (d)                                                   td1
+    uadd16  r6, r7, r6  ; 3c+3 | 7c+7 = temp2  (c)                              tc2
+    usub16  r12, r8, r6 ; c (o1 | o5)                                                       c
+    uadd16  r6, r11, r1 ; d (o3 | o7)                               d
+    uadd16  r7, r10, r6 ; a+d                                   a+d
+    mov r8, #0x4    ; set up 4's                                        4
+    orr r8, r8, #0x40000    ;                                       4|4
+    usub16  r6, r10, r6 ; a-d                               a-d
+    uadd16  r6, r6, r8  ; a-d+4                             3|7
+    uadd16  r7, r7, r8  ; a+d+4                                 0|4
+    uadd16  r10, r9, r12    ; b+c                                               b+c
+    usub16  r1, r9, r12 ; b-c           b-c
+    uadd16  r10, r10, r8    ; b+c+4                                             1|5
+    uadd16  r1, r1, r8  ; b-c+4         2|6
+    mov r8, r10, asr #19    ; o1 >> 3
+    strh    r8, [r0, #2]    ; o1
+    mov r8, r1, asr #19 ; o2 >> 3
+    strh    r8, [r0, #4]    ; o2
+    mov r8, r6, asr #19 ; o3 >> 3
+    strh    r8, [r0, #6]    ; o3
+    mov r8, r7, asr #19 ; o0 >> 3
+    strh    r8, [r0], r2    ; o0        +p
+    sxth    r10, r10    ;
+    mov r8, r10, asr #3 ; o5 >> 3
+    strh    r8, [r0, #2]    ; o5
+    sxth    r1, r1  ;
+    mov r8, r1, asr #3  ; o6 >> 3
+    strh    r8, [r0, #4]    ; o6
+    sxth    r6, r6  ;
+    mov r8, r6, asr #3  ; o7 >> 3
+    strh    r8, [r0, #6]    ; o7
+    sxth    r7, r7  ;
+    mov r8, r7, asr #3  ; o4 >> 3
+    strh    r8, [r0], r2    ; o4        +p
+;;;;;   subs    r5, r5, #0x1    ; i--                           --
+    bne loop2_dual_22   ;
+
+
+;vpx_memset
+    ldr     r0, [sp]
+    add     sp, sp, #4
+
+    mov     r12, #0
+    str     r12, [r0]
+    str     r12, [r0, #4]
+    str     r12, [r0, #8]
+    str     r12, [r0, #12]
+    str     r12, [r0, #16]
+    str     r12, [r0, #20]
+    str     r12, [r0, #24]
+    str     r12, [r0, #28]
+
+    ldmia   sp!, {r4 - r11, pc} ; replace vars, return                      restore
+
+    ENDP    ;|vp8_dequant_dc_idct_v68|
+
+    END
diff --git a/vp8/decoder/arm/armv6/dequantidct_v6.asm b/vp8/decoder/arm/armv6/dequantidct_v6.asm
new file mode 100644 (file)
index 0000000..61bb48d
--- /dev/null
@@ -0,0 +1,183 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequant_idct_v6|
+    ; ARM
+    ; REQUIRE8
+    ; PRESERVE8
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+;void vp8_dequant_idct_v6(short *input, short *dq, short *output, int pitch)
+|vp8_dequant_idct_v6| PROC
+    stmdb   sp!, {r4-r11, lr}
+
+    ldr     r4, [r0]            ;input
+    ldr     r5, [r1], #4            ;dq
+
+    sub     sp, sp, #4
+    str     r0, [sp]
+
+    mov     r12, #4
+
+dequant_idct_loop
+    smulbb  r6, r4, r5
+    smultt  r7, r4, r5
+
+    ldr     r4, [r0, #4]            ;input
+    ldr     r5, [r1], #4        ;dq
+
+    strh    r6, [r0], #2
+    strh    r7, [r0], #2
+
+    smulbb  r6, r4, r5
+    smultt  r7, r4, r5
+
+    subs    r12, r12, #1
+
+    ldrne   r4, [r0, #4]
+    ldrne   r5, [r1], #4
+
+    strh    r6, [r0], #2
+    strh    r7, [r0], #2
+
+    bne     dequant_idct_loop
+
+    sub     r0, r0, #32
+    mov     r1, r2
+    mov     r2, r3
+
+; short_idct4x4llm_v6_dual
+
+    mov r3, #0x00004E00 ;                   cos
+    orr r3, r3, #0x0000007B ; cospi8sqrt2minus1
+    mov r4, #0x00008A00 ;                       sin
+    orr r4, r4, #0x0000008C ; sinpi8sqrt2
+    mov r5, #0x2    ; i=2                           i
+loop1_dual_1
+    ldr r6, [r0, #(4*2)]    ; i5 | i4                               5|4
+    ldr r12, [r0, #(12*2)]  ; i13 | i12                                                     13|12
+    ldr r14, [r0, #(8*2)]   ; i9 | i8                                                               9|8
+
+    smulwt  r9, r3, r6  ; (ip[5] * cospi8sqrt2minus1) >> 16                                         5c
+    smulwb  r7, r3, r6  ; (ip[4] * cospi8sqrt2minus1) >> 16                                 4c
+    smulwt  r10, r4, r6 ; (ip[5] * sinpi8sqrt2) >> 16                                               5s
+    smulwb  r8, r4, r6  ; (ip[4] * sinpi8sqrt2) >> 16                                       4s
+    pkhbt   r7, r7, r9, lsl #16 ; 5c | 4c
+    smulwt  r11, r3, r12    ; (ip[13] * cospi8sqrt2minus1) >> 16                                                    13c
+    pkhbt   r8, r8, r10, lsl #16    ; 5s | 4s
+    uadd16  r6, r6, r7  ; 5c+5 | 4c+4
+    smulwt  r7, r4, r12 ; (ip[13] * sinpi8sqrt2) >> 16                                  13s
+    smulwb  r9, r3, r12 ; (ip[12] * cospi8sqrt2minus1) >> 16                                            12c
+    smulwb  r10, r4, r12    ; (ip[12] * sinpi8sqrt2) >> 16                                              12s
+    subs    r5, r5, #0x1    ; i--                           --
+    pkhbt   r9, r9, r11, lsl #16    ; 13c | 12c
+    ldr r11, [r0], #0x4 ; i1 | i0       ++                                          1|0
+    pkhbt   r10, r10, r7, lsl #16   ; 13s | 12s
+    uadd16  r7, r12, r9 ; 13c+13 | 12c+12
+    usub16  r7, r8, r7  ; c                                 c
+    uadd16  r6, r6, r10 ; d                             d
+    uadd16  r10, r11, r14   ; a                                             a
+    usub16  r8, r11, r14    ; b                                     b
+    uadd16  r9, r10, r6 ; a+d                                           a+d
+    usub16  r10, r10, r6    ; a-d                                               a-d
+    uadd16  r6, r8, r7  ; b+c                               b+c
+    usub16  r7, r8, r7  ; b-c                                   b-c
+    str r6, [r1, r2]    ; o5 | o4
+    add r6, r2, r2  ; pitch * 2                             p2
+    str r7, [r1, r6]    ; o9 | o8
+    add r6,  r6, r2 ; pitch * 3                             p3
+    str r10, [r1, r6]   ; o13 | o12
+    str r9, [r1], #0x4  ; o1 | o0           ++
+    bne loop1_dual_1    ;
+    mov r5, #0x2    ; i=2                           i
+    sub r0, r1, #8  ; reset input/output        i/o
+loop2_dual_2
+    ldr r6, [r0, r2]    ; i5 | i4                               5|4
+    ldr r1, [r0]    ; i1 | i0           1|0
+    ldr r12, [r0, #0x4] ; i3 | i2                                                       3|2
+    add r14, r2, #0x4   ; pitch + 2                                                             p+2
+    ldr r14, [r0, r14]  ; i7 | i6                                                               7|6
+    smulwt  r9, r3, r6  ; (ip[5] * cospi8sqrt2minus1) >> 16                                         5c
+    smulwt  r7, r3, r1  ; (ip[1] * cospi8sqrt2minus1) >> 16                                 1c
+    smulwt  r10, r4, r6 ; (ip[5] * sinpi8sqrt2) >> 16                                               5s
+    smulwt  r8, r4, r1  ; (ip[1] * sinpi8sqrt2) >> 16                                       1s
+    pkhbt   r11, r6, r1, lsl #16    ; i0 | i4                                                   0|4
+    pkhbt   r7, r9, r7, lsl #16 ; 1c | 5c
+    pkhbt   r8, r10, r8, lsl #16    ; 1s | 5s = temp1 ©                                     tc1
+    pkhtb   r1, r1, r6, asr #16 ; i1 | i5           1|5
+    uadd16  r1, r7, r1  ; 1c+1 | 5c+5 = temp2 (d)           td2
+    pkhbt   r9, r14, r12, lsl #16   ; i2 | i6                                           2|6
+    uadd16  r10, r11, r9    ; a                                             a
+    usub16  r9, r11, r9 ; b                                         b
+    pkhtb   r6, r12, r14, asr #16   ; i3 | i7                               3|7
+    subs    r5, r5, #0x1    ; i--                           --
+    smulwt  r7, r3, r6  ; (ip[3] * cospi8sqrt2minus1) >> 16                                 3c
+    smulwt  r11, r4, r6 ; (ip[3] * sinpi8sqrt2) >> 16                                                   3s
+    smulwb  r12, r3, r6 ; (ip[7] * cospi8sqrt2minus1) >> 16                                                     7c
+    smulwb  r14, r4, r6 ; (ip[7] * sinpi8sqrt2) >> 16                                                               7s
+
+    pkhbt   r7, r12, r7, lsl #16    ; 3c | 7c
+    pkhbt   r11, r14, r11, lsl #16  ; 3s | 7s = temp1 (d)                                                   td1
+    uadd16  r6, r7, r6  ; 3c+3 | 7c+7 = temp2  (c)                              tc2
+    usub16  r12, r8, r6 ; c (o1 | o5)                                                       c
+    uadd16  r6, r11, r1 ; d (o3 | o7)                               d
+    uadd16  r7, r10, r6 ; a+d                                   a+d
+    mov r8, #0x4    ; set up 4's                                        4
+    orr r8, r8, #0x40000    ;                                       4|4
+    usub16  r6, r10, r6 ; a-d                               a-d
+    uadd16  r6, r6, r8  ; a-d+4                             3|7
+    uadd16  r7, r7, r8  ; a+d+4                                 0|4
+    uadd16  r10, r9, r12    ; b+c                                               b+c
+    usub16  r1, r9, r12 ; b-c           b-c
+    uadd16  r10, r10, r8    ; b+c+4                                             1|5
+    uadd16  r1, r1, r8  ; b-c+4         2|6
+    mov r8, r10, asr #19    ; o1 >> 3
+    strh    r8, [r0, #2]    ; o1
+    mov r8, r1, asr #19 ; o2 >> 3
+    strh    r8, [r0, #4]    ; o2
+    mov r8, r6, asr #19 ; o3 >> 3
+    strh    r8, [r0, #6]    ; o3
+    mov r8, r7, asr #19 ; o0 >> 3
+    strh    r8, [r0], r2    ; o0        +p
+    sxth    r10, r10    ;
+    mov r8, r10, asr #3 ; o5 >> 3
+    strh    r8, [r0, #2]    ; o5
+    sxth    r1, r1  ;
+    mov r8, r1, asr #3  ; o6 >> 3
+    strh    r8, [r0, #4]    ; o6
+    sxth    r6, r6  ;
+    mov r8, r6, asr #3  ; o7 >> 3
+    strh    r8, [r0, #6]    ; o7
+    sxth    r7, r7  ;
+    mov r8, r7, asr #3  ; o4 >> 3
+    strh    r8, [r0], r2    ; o4        +p
+;;;;;   subs    r5, r5, #0x1    ; i--                           --
+    bne loop2_dual_2    ;
+            ;
+
+;vpx_memset
+    ldr     r0, [sp]
+    add     sp, sp, #4
+
+    mov     r12, #0
+    str     r12, [r0]
+    str     r12, [r0, #4]
+    str     r12, [r0, #8]
+    str     r12, [r0, #12]
+    str     r12, [r0, #16]
+    str     r12, [r0, #20]
+    str     r12, [r0, #24]
+    str     r12, [r0, #28]
+
+    ldmia   sp!, {r4 - r11, pc} ; replace vars, return                      restore
+
+    ENDP    ;|vp8_dequant_idct_v6|
+
+    END
diff --git a/vp8/decoder/arm/armv6/dequantize_v6.asm b/vp8/decoder/arm/armv6/dequantize_v6.asm
new file mode 100644 (file)
index 0000000..95e3859
--- /dev/null
@@ -0,0 +1,68 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequantize_b_loop_v6|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+;-------------------------------
+;void   vp8_dequantize_b_loop_v6(short *Q, short *DQC, short *DQ);
+; r0    short *Q,
+; r1    short *DQC
+; r2    short *DQ
+|vp8_dequantize_b_loop_v6| PROC
+    stmdb   sp!, {r4-r9, lr}
+
+    ldr     r3, [r0]                ;load Q
+    ldr     r4, [r1]                ;load DQC
+    ldr     r5, [r0, #4]
+    ldr     r6, [r1, #4]
+
+    mov     r12, #2                 ;loop counter
+
+dequant_loop
+    smulbb  r7, r3, r4              ;multiply
+    smultt  r8, r3, r4
+    smulbb  r9, r5, r6
+    smultt  lr, r5, r6
+
+    ldr     r3, [r0, #8]
+    ldr     r4, [r1, #8]
+    ldr     r5, [r0, #12]
+    ldr     r6, [r1, #12]
+
+    strh    r7, [r2], #2            ;store result
+    smulbb  r7, r3, r4              ;multiply
+    strh    r8, [r2], #2
+    smultt  r8, r3, r4
+    strh    r9, [r2], #2
+    smulbb  r9, r5, r6
+    strh    lr, [r2], #2
+    smultt  lr, r5, r6
+
+    subs    r12, r12, #1
+
+    add     r0, r0, #16
+    add     r1, r1, #16
+
+    ldrne       r3, [r0]
+    strh    r7, [r2], #2            ;store result
+    ldrne       r4, [r1]
+    strh    r8, [r2], #2
+    ldrne       r5, [r0, #4]
+    strh    r9, [r2], #2
+    ldrne       r6, [r1, #4]
+    strh    lr, [r2], #2
+
+    bne     dequant_loop
+
+    ldmia   sp!, {r4-r9, pc}
+    ENDP    ;|vp8_dequantize_b_loop_v6|
+
+    END
diff --git a/vp8/decoder/arm/dboolhuff_arm.h b/vp8/decoder/arm/dboolhuff_arm.h
new file mode 100644 (file)
index 0000000..495004f
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef DBOOLHUFF_ARM_H
+#define DBOOLHUFF_ARM_H
+
+/* JLK
+ * There are currently no arm-optimized versions of
+ * these functions. As they are implemented, they
+ * can be uncommented below and added to
+ * arm/dsystemdependent.c
+ *
+ * The existing asm code is likely so different as
+ * to be useless. However, its been left (for now)
+ * for reference.
+ */
+/*
+#if HAVE_ARMV6
+#undef vp8_dbool_start
+#define vp8_dbool_start vp8dx_start_decode_v6
+
+#undef vp8_dbool_stop
+#define vp8_dbool_stop vp8dx_stop_decode_v6
+
+#undef vp8_dbool_fill
+#define vp8_dbool_fill vp8_bool_decoder_fill_v6
+
+#undef vp8_dbool_debool
+#define vp8_dbool_debool vp8_decode_bool_v6
+
+#undef vp8_dbool_devalue
+#define vp8_dbool_devalue vp8_decode_value_v6
+#endif // HAVE_ARMV6
+
+#if HAVE_ARMV7
+#undef vp8_dbool_start
+#define vp8_dbool_start vp8dx_start_decode_neon
+
+#undef vp8_dbool_stop
+#define vp8_dbool_stop vp8dx_stop_decode_neon
+
+#undef vp8_dbool_fill
+#define vp8_dbool_fill vp8_bool_decoder_fill_neon
+
+#undef vp8_dbool_debool
+#define vp8_dbool_debool vp8_decode_bool_neon
+
+#undef vp8_dbool_devalue
+#define vp8_dbool_devalue vp8_decode_value_neon
+#endif // HAVE_ARMV7
+*/
+#endif // DBOOLHUFF_ARM_H
diff --git a/vp8/decoder/arm/dequantize_arm.c b/vp8/decoder/arm/dequantize_arm.c
new file mode 100644 (file)
index 0000000..54006a9
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "dequantize.h"
+#include "predictdc.h"
+#include "idct.h"
+#include "vpx_mem/vpx_mem.h"
+
+#if HAVE_ARMV7
+extern void vp8_dequantize_b_loop_neon(short *Q, short *DQC, short *DQ);
+#endif
+
+#if HAVE_ARMV6
+extern void vp8_dequantize_b_loop_v6(short *Q, short *DQC, short *DQ);
+#endif
+
+#if HAVE_ARMV7
+
+void vp8_dequantize_b_neon(BLOCKD *d)
+{
+    int i;
+    short *DQ  = d->dqcoeff;
+    short *Q   = d->qcoeff;
+    short *DQC = &d->dequant[0][0];
+
+    vp8_dequantize_b_loop_neon(Q, DQC, DQ);
+}
+#endif
+
+#if HAVE_ARMV6
+void vp8_dequantize_b_v6(BLOCKD *d)
+{
+    int i;
+    short *DQ  = d->dqcoeff;
+    short *Q   = d->qcoeff;
+    short *DQC = &d->dequant[0][0];
+
+    vp8_dequantize_b_loop_v6(Q, DQC, DQ);
+}
+#endif
diff --git a/vp8/decoder/arm/dequantize_arm.h b/vp8/decoder/arm/dequantize_arm.h
new file mode 100644 (file)
index 0000000..c8a61a4
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef DEQUANTIZE_ARM_H
+#define DEQUANTIZE_ARM_H
+
+#if HAVE_ARMV6
+extern prototype_dequant_block(vp8_dequantize_b_v6);
+extern prototype_dequant_idct(vp8_dequant_idct_v6);
+extern prototype_dequant_idct_dc(vp8_dequant_dc_idct_v6);
+
+#undef  vp8_dequant_block
+#define vp8_dequant_block vp8_dequantize_b_v6
+
+#undef  vp8_dequant_idct
+#define vp8_dequant_idct vp8_dequant_idct_v6
+
+#undef  vp8_dequant_idct_dc
+#define vp8_dequant_idct_dc vp8_dequant_dc_idct_v6
+#endif
+
+#if HAVE_ARMV7
+extern prototype_dequant_block(vp8_dequantize_b_neon);
+extern prototype_dequant_idct(vp8_dequant_idct_neon);
+extern prototype_dequant_idct_dc(vp8_dequant_dc_idct_neon);
+
+#undef  vp8_dequant_block
+#define vp8_dequant_block vp8_dequantize_b_neon
+
+#undef  vp8_dequant_idct
+#define vp8_dequant_idct vp8_dequant_idct_neon
+
+#undef  vp8_dequant_idct_dc
+#define vp8_dequant_idct_dc vp8_dequant_dc_idct_neon
+#endif
+
+#endif
diff --git a/vp8/decoder/arm/detokenizearm_sjl.c b/vp8/decoder/arm/detokenizearm_sjl.c
new file mode 100644 (file)
index 0000000..c714452
--- /dev/null
@@ -0,0 +1,730 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "type_aliases.h"
+#include "blockd.h"
+#include "onyxd_int.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_ports/mem.h"
+
+#define BR_COUNT 8
+#define BOOL_DATA UINT8
+
+#define OCB_X PREV_COEF_CONTEXTS * ENTROPY_NODES
+//ALIGN16 UINT16 onyx_coef_bands_x[16] = { 0, 1*OCB_X, 2*OCB_X, 3*OCB_X, 6*OCB_X, 4*OCB_X, 5*OCB_X, 6*OCB_X, 6*OCB_X, 6*OCB_X, 6*OCB_X, 6*OCB_X, 6*OCB_X, 6*OCB_X, 6*OCB_X, 7*OCB_X};
+DECLARE_ALIGNED(16, UINT8, vp8_coef_bands_x[16]) = { 0, 1 * OCB_X, 2 * OCB_X, 3 * OCB_X, 6 * OCB_X, 4 * OCB_X, 5 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 7 * OCB_X};
+
+#define EOB_CONTEXT_NODE            0
+#define ZERO_CONTEXT_NODE           1
+#define ONE_CONTEXT_NODE            2
+#define LOW_VAL_CONTEXT_NODE        3
+#define TWO_CONTEXT_NODE            4
+#define THREE_CONTEXT_NODE          5
+#define HIGH_LOW_CONTEXT_NODE       6
+#define CAT_ONE_CONTEXT_NODE        7
+#define CAT_THREEFOUR_CONTEXT_NODE  8
+#define CAT_THREE_CONTEXT_NODE      9
+#define CAT_FIVE_CONTEXT_NODE       10
+
+
+
+
+DECLARE_ALIGNED(16, static const TOKENEXTRABITS, vp8d_token_extra_bits2[MAX_ENTROPY_TOKENS]) =
+{
+    {  0, -1, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },  //ZERO_TOKEN
+    {  1, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //ONE_TOKEN
+    {  2, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //TWO_TOKEN
+    {  3, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //THREE_TOKEN
+    {  4, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //FOUR_TOKEN
+    {  5, 0, { 159, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },  //DCT_VAL_CATEGORY1
+    {  7, 1, { 145, 165, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY2
+    { 11, 2, { 140, 148, 173, 0,  0,  0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY3
+    { 19, 3, { 135, 140, 155, 176, 0,  0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY4
+    { 35, 4, { 130, 134, 141, 157, 180, 0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY5
+    { 67, 10, { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254, 0   } }, //DCT_VAL_CATEGORY6
+    {  0, -1, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },  // EOB TOKEN
+};
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+DECLARE_ALIGNED(16, const UINT8, vp8_block2context_leftabove[25*3]) =
+{
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, //end of vp8_block2context
+    0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 1, 1, 0, //end of vp8_block2left
+    0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 0, 1, 0, 1, 0, 1, 0 //end of vp8_block2above
+};
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+void vp8_reset_mb_tokens_context(MACROBLOCKD *x)
+{
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+
+    ENTROPY_CONTEXT *a;
+    ENTROPY_CONTEXT *l;
+    int i;
+
+    for (i = 0; i < 24; i++)
+    {
+
+        a = A[ vp8_block2context[i] ] + vp8_block2above[i];
+        l = L[ vp8_block2context[i] ] + vp8_block2left[i];
+
+        *a = *l = 0;
+    }
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        a = A[Y2CONTEXT] + vp8_block2above[24];
+        l = L[Y2CONTEXT] + vp8_block2left[24];
+        *a = *l = 0;
+    }
+
+
+}
+
+#define ONYXBLOCK2CONTEXT_OFFSET    0
+#define ONYXBLOCK2LEFT_OFFSET       25
+#define ONYXBLOCK2ABOVE_OFFSET 50
+
+DECLARE_ALIGNED(16, const static unsigned char, norm[128]) =
+{
+    0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+void init_detokenizer(VP8D_COMP *dx)
+{
+    const VP8_COMMON *const oc = & dx->common;
+    MACROBLOCKD *x = & dx->mb;
+
+    dx->detoken.norm_ptr = (unsigned char *)norm;
+    dx->detoken.vp8_coef_tree_ptr = (vp8_tree_index *)vp8_coef_tree;
+    dx->detoken.ptr_onyxblock2context_leftabove = (UINT8 *)vp8_block2context_leftabove;
+    dx->detoken.ptr_onyx_coef_bands_x = vp8_coef_bands_x;
+    dx->detoken.scan = (int *)vp8_default_zig_zag1d;
+    dx->detoken.teb_base_ptr = (TOKENEXTRABITS *)vp8d_token_extra_bits2;
+
+    dx->detoken.qcoeff_start_ptr = &x->qcoeff[0];
+
+
+    dx->detoken.coef_probs[0] = (unsigned char *)(oc->fc.coef_probs [0] [ 0 ] [0]);
+    dx->detoken.coef_probs[1] = (unsigned char *)(oc->fc.coef_probs [1] [ 0 ] [0]);
+    dx->detoken.coef_probs[2] = (unsigned char *)(oc->fc.coef_probs [2] [ 0 ] [0]);
+    dx->detoken.coef_probs[3] = (unsigned char *)(oc->fc.coef_probs [3] [ 0 ] [0]);
+
+}
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+
+//shift = norm[range]; \
+//      shift = norm_ptr[range]; \
+
+#define NORMALIZE \
+    /*if(range < 0x80)*/                            \
+    { \
+        shift = detoken->norm_ptr[range]; \
+        range <<= shift; \
+        value <<= shift; \
+        count -= shift; \
+        if(count <= 0) \
+        { \
+            count += BR_COUNT ; \
+            value |= (*bufptr) << (BR_COUNT-count); \
+            bufptr++; \
+        } \
+    }
+#if 1
+#define DECODE_AND_APPLYSIGN(value_to_sign) \
+    split = (range + 1) >> 1; \
+    if ( (value >> 24) < split ) \
+    { \
+        range = split; \
+        v= value_to_sign; \
+    } \
+    else \
+    { \
+        range = range-split; \
+        value = value-(split<<24); \
+        v = -value_to_sign; \
+    } \
+    range +=range;                   \
+    value +=value;                   \
+    if (!--count) \
+    { \
+        count = BR_COUNT; \
+        value |= *bufptr; \
+        bufptr++; \
+    }
+
+#define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \
+    { \
+        split = 1 +  ((( probability*(range-1) ) )>> 8); \
+        if ( (value >> 24) < split ) \
+        { \
+            range = split; \
+            NORMALIZE \
+            goto branch; \
+        } \
+        value -= (split<<24); \
+        range = range - split; \
+        NORMALIZE \
+    }
+
+#define DECODE_AND_LOOP_IF_ZERO(probability,branch) \
+    { \
+        split = 1 + ((( probability*(range-1) ) ) >> 8); \
+        if ( (value >> 24) < split ) \
+        { \
+            range = split; \
+            NORMALIZE \
+            Prob = coef_probs; \
+            ++c; \
+            Prob += vp8_coef_bands_x[c]; \
+            goto branch; \
+        } \
+        value -= (split<<24); \
+        range = range - split; \
+        NORMALIZE \
+    }
+
+#define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \
+    DECODE_AND_APPLYSIGN(val) \
+    Prob = coef_probs + (ENTROPY_NODES*2); \
+    if(c < 15){\
+        qcoeff_ptr [ scan[c] ] = (INT16) v; \
+        ++c; \
+        goto DO_WHILE; }\
+    qcoeff_ptr [ scan[15] ] = (INT16) v; \
+    goto BLOCK_FINISHED;
+
+
+#define DECODE_EXTRABIT_AND_ADJUST_VAL(t,bits_count)\
+    split = 1 +  (((range-1) * vp8d_token_extra_bits2[t].Probs[bits_count]) >> 8); \
+    if(value >= (split<<24))\
+    {\
+        range = range-split;\
+        value = value-(split<<24);\
+        val += ((UINT16)1<<bits_count);\
+    }\
+    else\
+    {\
+        range = split;\
+    }\
+    NORMALIZE
+#endif
+
+#if 0
+int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x)
+{
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+    const VP8_COMMON *const oc = & dx->common;
+
+    BOOL_DECODER *bc = x->current_bc;
+
+    ENTROPY_CONTEXT *a;
+    ENTROPY_CONTEXT *l;
+    int i;
+
+    int eobtotal = 0;
+
+    register int count;
+
+    BOOL_DATA *bufptr;
+    register unsigned int range;
+    register unsigned int value;
+    const int *scan;
+    register unsigned int shift;
+    UINT32 split;
+    INT16 *qcoeff_ptr;
+
+    UINT8 *coef_probs;
+    int type;
+    int stop;
+    INT16 val, bits_count;
+    INT16 c;
+    INT16 t;
+    INT16 v;
+    vp8_prob *Prob;
+
+    //int *scan;
+    type = 3;
+    i = 0;
+    stop = 16;
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        i = 24;
+        stop = 24;
+        type = 1;
+        qcoeff_ptr = &x->qcoeff[24*16];
+        scan = vp8_default_zig_zag1d;
+        eobtotal -= 16;
+    }
+    else
+    {
+        scan = vp8_default_zig_zag1d;
+        qcoeff_ptr = &x->qcoeff[0];
+    }
+
+    count   = bc->count;
+    range   = bc->range;
+    value   = bc->value;
+    bufptr  = &bc->buffer[bc->pos];
+
+
+    coef_probs = (unsigned char *)(oc->fc.coef_probs [type] [ 0 ] [0]);
+
+BLOCK_LOOP:
+    a = A[ vp8_block2context[i] ] + vp8_block2above[i];
+    l = L[ vp8_block2context[i] ] + vp8_block2left[i];
+    c = (INT16)(!type);
+
+    VP8_COMBINEENTROPYCONTEXTS(t, *a, *l);
+    Prob = coef_probs;
+    Prob += t * ENTROPY_NODES;
+
+DO_WHILE:
+    Prob += vp8_coef_bands_x[c];
+    DECODE_AND_BRANCH_IF_ZERO(Prob[EOB_CONTEXT_NODE], BLOCK_FINISHED);
+
+CHECK_0_:
+    DECODE_AND_LOOP_IF_ZERO(Prob[ZERO_CONTEXT_NODE], CHECK_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[ONE_CONTEXT_NODE], ONE_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[LOW_VAL_CONTEXT_NODE], LOW_VAL_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[HIGH_LOW_CONTEXT_NODE], HIGH_LOW_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREEFOUR_CONTEXT_NODE], CAT_THREEFOUR_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_FIVE_CONTEXT_NODE], CAT_FIVE_CONTEXT_NODE_0_);
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY6].min_val;
+    bits_count = vp8d_token_extra_bits2[DCT_VAL_CATEGORY6].Length;
+
+    do
+    {
+        DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY6, bits_count);
+        bits_count -- ;
+    }
+    while (bits_count >= 0);
+
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_FIVE_CONTEXT_NODE_0_:
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY5].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 4);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 3);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 2);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_THREEFOUR_CONTEXT_NODE_0_:
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREE_CONTEXT_NODE], CAT_THREE_CONTEXT_NODE_0_);
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY4].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 3);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 2);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_THREE_CONTEXT_NODE_0_:
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY3].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 2);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+HIGH_LOW_CONTEXT_NODE_0_:
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_ONE_CONTEXT_NODE], CAT_ONE_CONTEXT_NODE_0_);
+
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY2].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_ONE_CONTEXT_NODE_0_:
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY1].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY1, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+LOW_VAL_CONTEXT_NODE_0_:
+    DECODE_AND_BRANCH_IF_ZERO(Prob[TWO_CONTEXT_NODE], TWO_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[THREE_CONTEXT_NODE], THREE_CONTEXT_NODE_0_);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(4);
+
+THREE_CONTEXT_NODE_0_:
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3);
+
+TWO_CONTEXT_NODE_0_:
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2);
+
+ONE_CONTEXT_NODE_0_:
+    DECODE_AND_APPLYSIGN(1);
+    Prob = coef_probs + ENTROPY_NODES;
+
+    if (c < 15)
+    {
+        qcoeff_ptr [ scan[c] ] = (INT16) v;
+        ++c;
+        goto DO_WHILE;
+    }
+
+    qcoeff_ptr [ scan[15] ] = (INT16) v;
+BLOCK_FINISHED:
+    t = ((x->Block[i].eob = c) != !type);   // any nonzero data?
+    eobtotal += x->Block[i].eob;
+    *a = *l = t;
+    qcoeff_ptr += 16;
+
+    i++;
+
+    if (i < stop)
+        goto BLOCK_LOOP;
+
+    if (i == 25)
+    {
+        scan = vp8_default_zig_zag1d;//x->scan_order1d;
+        type = 0;
+        i = 0;
+        stop = 16;
+        coef_probs = (unsigned char *)(oc->fc.coef_probs [type] [ 0 ] [0]);
+        qcoeff_ptr = &x->qcoeff[0];
+        goto BLOCK_LOOP;
+    }
+
+    if (i == 16)
+    {
+        type = 2;
+        coef_probs = (unsigned char *)(oc->fc.coef_probs [type] [ 0 ] [0]);
+        stop = 24;
+        goto BLOCK_LOOP;
+    }
+
+    bc->count = count;
+    bc->value = value;
+    bc->range = range;
+    bc->pos  = bufptr - bc->buffer;
+    return eobtotal;
+
+}
+//#endif
+#else
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+#if 0
+//uses relative offsets
+
+const vp8_tree_index vp8_coef_tree_x[ 22] =   /* corresponding _CONTEXT_NODEs */
+{
+    -DCT_EOB_TOKEN, 1,                             /* 0 = EOB */
+    -ZERO_TOKEN, 1,                               /* 1 = ZERO */
+    -ONE_TOKEN, 1,                               /* 2 = ONE */
+    2, 5,                                       /* 3 = LOW_VAL */
+    -TWO_TOKEN, 1,                         /* 4 = TWO */
+    -THREE_TOKEN, -FOUR_TOKEN,                /* 5 = THREE */
+    2, 3,                                  /* 6 = HIGH_LOW */
+    -DCT_VAL_CATEGORY1, -DCT_VAL_CATEGORY2,   /* 7 = CAT_ONE */
+    2, 3,                                 /* 8 = CAT_THREEFOUR */
+    -DCT_VAL_CATEGORY3, -DCT_VAL_CATEGORY4,  /* 9 = CAT_THREE */
+    -DCT_VAL_CATEGORY5, -DCT_VAL_CATEGORY6   /* 10 = CAT_FIVE */
+};
+#endif
+
+#define _SCALEDOWN 8 //16 //8
+
+int vp8_decode_mb_tokens_v5(DETOK *detoken, int type);
+
+int vp8_decode_mb_tokens_v5_c(DETOK *detoken, int type)
+{
+    BOOL_DECODER *bc = detoken->current_bc;
+
+    ENTROPY_CONTEXT *a;
+    ENTROPY_CONTEXT *l;
+    int i;
+
+    register int count;
+
+    BOOL_DATA *bufptr;
+    register unsigned int range;
+    register unsigned int value;
+    register unsigned int shift;
+    UINT32 split;
+    INT16 *qcoeff_ptr;
+
+    UINT8 *coef_probs;
+//  int type;
+    int stop;
+    INT16 c;
+    INT16 t;
+    INT16 v;
+    vp8_prob *Prob;
+
+
+
+//  type = 3;
+    i = 0;
+    stop = 16;
+    qcoeff_ptr = detoken->qcoeff_start_ptr;
+
+//  if( detoken->mode != B_PRED && detoken->mode != SPLITMV)
+    if (type == 1)
+    {
+        i += 24;
+        stop += 8; //24;
+//      type = 1;
+        qcoeff_ptr += 24 * 16;
+//      eobtotal-=16;
+    }
+
+    count   = bc->count;
+    range   = bc->range;
+    value   = bc->value;
+    bufptr  = &bc->buffer[bc->pos];
+
+
+    coef_probs = detoken->coef_probs[type]; //(unsigned char *)( oc->fc.coef_probs [type] [ 0 ] [0]);
+
+BLOCK_LOOP:
+    a = detoken->A[ detoken->ptr_onyxblock2context_leftabove[i] ];
+    l = detoken->L[ detoken->ptr_onyxblock2context_leftabove[i] ];
+    c = !type;
+    a += detoken->ptr_onyxblock2context_leftabove[i + ONYXBLOCK2ABOVE_OFFSET];
+    l += detoken->ptr_onyxblock2context_leftabove[i + ONYXBLOCK2LEFT_OFFSET];
+
+    //#define ONYX_COMBINEENTROPYCONTEXTS( Dest, A, B) \
+    //Dest = ((A)!=0) + ((B)!=0);
+
+    VP8_COMBINEENTROPYCONTEXTS(t, *a, *l);
+
+    Prob = coef_probs;
+    Prob += t * ENTROPY_NODES;
+    t = 0;
+
+    do
+    {
+
+        {
+//                  onyx_tree_index * onyx_coef_tree_ptr = onyx_coef_tree_x;
+
+            Prob += detoken->ptr_onyx_coef_bands_x[c];
+
+        GET_TOKEN_START:
+
+            do
+            {
+                split = 1 + (((range - 1) * (Prob[t>>1])) >> 8);
+
+                if (value >> 24 >= split)
+                {
+                    range = range - split;
+                    value = value - (split << 24);
+                    t += 1;
+
+                    //used to eliminate else branch
+                    split = range;
+                }
+
+                range = split;
+
+                t = detoken->vp8_coef_tree_ptr[ t ];
+
+                NORMALIZE
+
+            }
+            while (t  > 0) ;
+        }
+    GET_TOKEN_STOP:
+
+        if (t == -DCT_EOB_TOKEN)
+        {
+            break;
+        }
+
+        v = -t;
+
+        if (v > FOUR_TOKEN)
+        {
+            INT16 bits_count;
+            TOKENEXTRABITS *teb_ptr;
+
+//                      teb_ptr = &onyxd_token_extra_bits2[t];
+//                  teb_ptr = &onyxd_token_extra_bits2[v];
+            teb_ptr = &detoken->teb_base_ptr[v];
+
+
+            v = teb_ptr->min_val;
+            bits_count = teb_ptr->Length;
+
+            do
+            {
+                split = 1 + (((range - 1) * teb_ptr->Probs[bits_count]) >> _SCALEDOWN);
+
+                if ((value >> 24) >= split)
+                {
+                    range = range - split;
+                    value = value - (split << 24);
+                    v += ((UINT16)1 << bits_count);
+
+                    //used to eliminate else branch
+                    split = range;
+                }
+
+                range = split;
+
+                NORMALIZE
+
+                bits_count -- ;
+            }
+            while (bits_count >= 0);
+        }
+
+        Prob = coef_probs;
+
+        if (t)
+        {
+            split = 1 + (((range - 1) * vp8_prob_half) >> 8);
+
+            if ((value >> 24) >= split)
+            {
+                range = range - split;
+                value = value - (split << 24);
+                v = (v ^ -1) + 1;           /* negate w/out conditionals */
+
+                //used to eliminate else branch
+                split = range;
+            }
+
+            range = split;
+
+            NORMALIZE
+            Prob += ENTROPY_NODES;
+
+            if (t < -ONE_TOKEN)
+                Prob += ENTROPY_NODES;
+
+            t = -2;
+        }
+
+        //if t is zero, we will skip the eob table check
+        t += 2;
+        qcoeff_ptr [detoken->scan [c] ] = (INT16) v;
+
+    }
+    while (++c < 16);
+
+    if (t != -DCT_EOB_TOKEN)
+    {
+        --c;
+    }
+
+    t = ((detoken->eob[i] = c) != !type);   // any nonzero data?
+//  eobtotal += detoken->eob[i];
+    *a = *l = t;
+    qcoeff_ptr += 16;
+
+    i++;
+
+    if (i < stop)
+        goto BLOCK_LOOP;
+
+    if (i == 25)
+    {
+        type = 0;
+        i = 0;
+        stop = 16;
+//      coef_probs = (unsigned char *)(oc->fc.coef_probs [type] [ 0 ] [0]);
+        coef_probs = detoken->coef_probs[type]; //(unsigned char *)( oc->fc.coef_probs [type] [ 0 ] [0]);
+        qcoeff_ptr = detoken->qcoeff_start_ptr;
+        goto BLOCK_LOOP;
+    }
+
+    if (i == 16)
+    {
+        type = 2;
+//      coef_probs =(unsigned char *)( oc->fc.coef_probs [type] [ 0 ] [0]);
+        coef_probs = detoken->coef_probs[type]; //(unsigned char *)( oc->fc.coef_probs [type] [ 0 ] [0]);
+        stop = 24;
+        goto BLOCK_LOOP;
+    }
+
+    bc->count = count;
+    bc->value = value;
+    bc->range = range;
+    bc->pos  = bufptr - bc->buffer;
+    return 0;
+}
+//#if 0
+int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x)
+{
+//  const ONYX_COMMON * const oc = & dx->common;
+    int eobtotal = 0;
+    int i, type;
+    /*
+        dx->detoken.norm_ptr = norm;
+        dx->detoken.onyx_coef_tree_ptr = onyx_coef_tree;
+        dx->detoken.ptr_onyxblock2context_leftabove = ONYXBLOCK2CONTEXT_LEFTABOVE;
+        dx->detoken.ptr_onyx_coef_bands_x = onyx_coef_bands_x;
+        dx->detoken.scan = default_zig_zag1d;
+        dx->detoken.teb_base_ptr = onyxd_token_extra_bits2;
+
+        dx->detoken.qcoeff_start_ptr = &x->qcoeff[0];
+
+        dx->detoken.A = x->above_context;
+        dx->detoken.L = x->left_context;
+
+        dx->detoken.coef_probs[0] = (unsigned char *)( oc->fc.coef_probs [0] [ 0 ] [0]);
+        dx->detoken.coef_probs[1] = (unsigned char *)( oc->fc.coef_probs [1] [ 0 ] [0]);
+        dx->detoken.coef_probs[2] = (unsigned char *)( oc->fc.coef_probs [2] [ 0 ] [0]);
+        dx->detoken.coef_probs[3] = (unsigned char *)( oc->fc.coef_probs [3] [ 0 ] [0]);
+    */
+
+    dx->detoken.current_bc = x->current_bc;
+    dx->detoken.A = x->above_context;
+    dx->detoken.L = x->left_context;
+
+    type = 3;
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        type = 1;
+        eobtotal -= 16;
+    }
+
+    vp8_decode_mb_tokens_v5(&dx->detoken, type);
+
+    for (i = 0; i < 25; i++)
+    {
+        x->Block[i].eob = dx->detoken.eob[i];
+        eobtotal += dx->detoken.eob[i];
+    }
+
+    return eobtotal;
+}
+#endif
diff --git a/vp8/decoder/arm/detokenizearm_v6.asm b/vp8/decoder/arm/detokenizearm_v6.asm
new file mode 100644 (file)
index 0000000..4d87ee5
--- /dev/null
@@ -0,0 +1,364 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_decode_mb_tokens_v5|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+    INCLUDE vpx_asm_offsets.asm
+
+l_qcoeff    EQU     0
+l_i         EQU     4
+l_type      EQU     8
+l_stop      EQU     12
+l_c         EQU     16
+l_l_ptr      EQU     20
+l_a_ptr      EQU     24
+l_bc        EQU     28
+l_coef_ptr   EQU     32
+l_stacksize EQU     64
+
+
+;; constant offsets -- these should be created at build time
+c_onyxblock2left_offset      EQU 25
+c_onyxblock2above_offset     EQU 50
+c_entropy_nodes              EQU 11
+c_dct_eob_token              EQU 11
+
+|vp8_decode_mb_tokens_v5| PROC
+    stmdb       sp!, {r4 - r11, lr}
+    sub         sp, sp, #l_stacksize
+    mov         r7, r1
+    mov         r9, r0                      ;DETOK *detoken
+
+    ldr         r1, [r9, #detok_current_bc]
+    ldr         r0, [r9, #detok_qcoeff_start_ptr]
+    mov         r11, #0
+    mov         r3, #0x10
+
+    cmp         r7, #1
+    addeq       r11, r11, #24
+    addeq       r3, r3, #8
+    addeq       r0, r0, #3, 24
+
+    str         r0, [sp, #l_qcoeff]
+    str         r11, [sp, #l_i]
+    str         r7, [sp, #l_type]
+    str         r3, [sp, #l_stop]
+    str         r1, [sp, #l_bc]
+
+    add         lr, r9, r7, lsl #2
+
+    ldr         r2, [r1, #bool_decoder_buffer]
+    ldr         r3, [r1, #bool_decoder_pos]
+
+    ldr         r10, [lr, #detok_coef_probs]
+    ldr         r5, [r1, #bool_decoder_count]
+    ldr         r6, [r1, #bool_decoder_range]
+    ldr         r4, [r1, #bool_decoder_value]
+    add         r8, r2, r3
+
+    str         r10, [sp, #l_coef_ptr]
+
+
+    ;align 4
+BLOCK_LOOP
+    ldr         r3, [r9, #detok_ptr_onyxblock2context_leftabove]
+    ldr         r2, [r9, #DETOK_A]
+    ldr         r1, [r9, #DETOK_L]
+    ldrb        r12, [r3, +r11]                                 ; detoken->ptr_onyxblock2context_leftabove[i]
+
+    cmp         r7, #0                                          ; check type
+    moveq       r7, #1
+    movne       r7, #0
+
+    ldr         r0, [r2, +r12, lsl #2]                          ; a
+    add         r1, r1, r12, lsl #4
+    add         r3, r3, r11
+
+    ldrb        r2, [r3, #c_onyxblock2above_offset]
+    ldrb        r3, [r3, #c_onyxblock2left_offset]
+    mov         lr, #c_entropy_nodes
+;;  ;++
+
+    ldr         r2, [r0, +r2, lsl #2]!
+    add         r3, r1, r3, lsl #2
+    str         r3, [sp, #l_l_ptr]
+    ldr         r3, [r3]
+
+    cmp         r2, #0
+    movne       r2, #1
+    cmp         r3, #0
+    addne       r2, r2, #1
+
+    str         r0, [sp, #l_a_ptr]
+    smlabb      r0, r2, lr, r10
+    mov         r1, #0                                          ; t = 0
+    str         r7, [sp, #l_c]
+
+    ;align 4
+COEFF_LOOP
+    ldr         r3, [r9, #detok_ptr_onyx_coef_bands_x]
+    ldr         lr, [r9, #detok_onyx_coef_tree_ptr]
+
+;;the following two lines are used if onyx_coef_bands_x is UINT16
+;;  add         r3, r3, r7, lsl #1
+;;  ldrh        r3, [r3]
+
+;;the following line is used if onyx_coef_bands_x is UINT8
+    ldrb        r3, [r7, +r3]
+
+
+;;  ;++
+;;  pld         [r8]
+    ;++
+    add         r0, r0, r3
+
+    ;align 4
+get_token_loop
+    ldrb        r2, [r0, +r1, asr #1]
+    mov         r3, r6, lsl #8
+    sub         r3, r3, #256                    ;split = 1 +  (((range-1) * probability) >> 8)
+    mov         r10, #1
+
+    smlawb      r2, r3, r2, r10
+    ldrb        r12, [r8]                       ;load cx data byte in stall slot
+    ;++
+
+    subs        r3, r4, r2, lsl #24             ;x = value-(split<<24)
+    addhs       r1, r1, #1                      ;t += 1
+    movhs       r4, r3                          ;update value
+    subhs       r2, r6, r2                      ;range = range - split
+    movlo       r6, r2
+
+;;; ldrsbhs     r1, [r1, +lr]
+    ldrsb     r1, [r1, +lr]
+
+
+;; use branch for short pipelines ???
+;;  cmp         r2, #0x80
+;;  bcs         |$LN22@decode_mb_to|
+
+    clz         r3, r2
+    sub         r3, r3, #24
+    subs        r5, r5, r3
+    mov         r6, r2, lsl r3
+    mov         r4, r4, lsl r3
+
+;; use branch for short pipelines ???
+;;  bgt         |$LN22@decode_mb_to|
+
+    addle         r5, r5, #8
+    rsble         r3, r5, #8
+    addle         r8, r8, #1
+    orrle         r4, r4, r12, lsl r3
+
+;;|$LN22@decode_mb_to|
+
+    cmp         r1, #0
+    bgt         get_token_loop
+
+    cmn         r1, #c_dct_eob_token             ;if(t == -DCT_EOB_TOKEN)
+    beq         END_OF_BLOCK
+
+    rsb         lr, r1, #0                      ;v = -t;
+
+    cmp         lr, #4                          ;if(v > FOUR_TOKEN)
+    ble         SKIP_EXTRABITS
+
+    ldr         r3, [r9, #detok_teb_base_ptr]
+    mov         r11, #1
+    add         r7, r3, lr, lsl #4
+
+    ldrsh       lr, [r7, #tokenextrabits_min_val];v = teb_ptr->min_val
+    ldrsh       r0, [r7, #tokenextrabits_length];bits_count = teb_ptr->Length
+
+extrabits_loop
+    add         r3, r0, r7
+
+    ldrb        r2, [r3, #4]
+    mov         r3, r6, lsl #8
+    sub         r3, r3, #256                    ;split = 1 +  (((range-1) * probability) >> 8)
+    mov         r10, #1
+
+    smlawb      r2, r3, r2, r10
+    ldrb        r12, [r8]
+    ;++
+
+    subs        r10, r4, r2, lsl #24            ;x = value-(split<<24)
+    movhs       r4, r10                         ;update value
+    subhs       r2, r6, r2                      ;range = range - split
+    addhs       lr, lr, r11, lsl r0             ;v += ((UINT16)1<<bits_count)
+    movlo       r6, r2                          ;range = split
+
+
+;; use branch for short pipelines ???
+;;  cmp         r2, #0x80
+;;  bcs         |$LN10@decode_mb_to|
+
+    clz         r3, r2
+    sub         r3, r3, #24
+    subs        r5, r5, r3
+    mov         r6, r2, lsl r3                  ;range
+    mov         r4, r4, lsl r3                  ;value
+
+    addle       r5, r5, #8
+    addle       r8, r8, #1
+    rsble       r3, r5, #8
+    orrle       r4, r4, r12, lsl r3
+
+;;|$LN10@decode_mb_to|
+    subs         r0, r0, #1
+    bpl         extrabits_loop
+
+
+SKIP_EXTRABITS
+    ldr         r11, [sp, #l_qcoeff]
+    ldr         r0, [sp, #l_coef_ptr]
+
+    cmp         r1, #0                          ;check for nonzero token
+    beq         SKIP_EOB_CHECK              ;if t is zero, we will skip the eob table chec
+
+    sub         r3, r6, #1                      ;range - 1
+    ;++
+    mov         r3, r3, lsl #7                  ; *= onyx_prob_half  (128)
+    ;++
+    mov         r3, r3, lsr #8
+    add         r2, r3, #1                      ;split
+
+    subs        r3, r4, r2, lsl #24             ;x = value-(split<<24)
+    movhs       r4, r3                          ;update value
+    subhs       r2, r6, r2                      ;range = range - split
+    mvnhs       r3, lr
+    addhs       lr, r3, #1                      ;v = (v ^ -1) + 1
+    movlo       r6, r2                          ;range = split
+
+;; use branch for short pipelines ???
+;;  cmp         r2, #0x80
+;;  bcs         |$LN6@decode_mb_to|
+
+    clz         r3, r2
+    sub         r3, r3, #24
+    subs        r5, r5, r3
+    mov         r6, r2, lsl r3
+    mov         r4, r4, lsl r3
+    ldrleb      r2, [r8], #1
+    addle       r5, r5, #8
+    rsble       r3, r5, #8
+    orrle       r4, r4, r2, lsl r3
+
+;;|$LN6@decode_mb_to|
+    add         r0, r0, #0xB
+
+    cmn         r1, #1
+
+    addlt       r0, r0, #0xB
+
+    mvn         r1, #1
+
+SKIP_EOB_CHECK
+    ldr         r7, [sp, #l_c]
+    ldr         r3, [r9, #detok_scan]
+    add         r1, r1, #2
+    cmp         r7, #(0x10 - 1)                     ;assume one less for now.... increment below
+
+    ldr         r3, [r3, +r7, lsl #2]
+    add         r7, r7, #1
+    add         r3, r11, r3, lsl #1
+
+    str         r7, [sp, #l_c]
+    strh        lr, [r3]
+
+    blt         COEFF_LOOP
+
+    sub         r7, r7, #1                          ;if(t != -DCT_EOB_TOKEN) --c
+
+END_OF_BLOCK
+    ldr         r3, [sp, #l_type]
+    ldr         r10, [sp, #l_coef_ptr]
+    ldr         r0, [sp, #l_qcoeff]
+    ldr         r11, [sp, #l_i]
+    ldr         r12, [sp, #l_stop]
+
+    cmp         r3, #0
+    moveq       r1, #1
+    movne       r1, #0
+    add         r3, r11, r9
+
+    cmp         r7, r1
+    strb        r7, [r3, #detok_eob]
+
+    ldr         r7, [sp, #l_l_ptr]
+    ldr         r2, [sp, #l_a_ptr]
+    movne       r3, #1
+    moveq       r3, #0
+
+    add         r0, r0, #0x20
+    add         r11, r11, #1
+    str         r3, [r7]
+    str         r3, [r2]
+    str         r0, [sp, #l_qcoeff]
+    str         r11, [sp, #l_i]
+
+    cmp         r11, r12                            ;i >= stop ?
+    ldr         r7, [sp, #l_type]
+    mov         lr, #0xB
+
+    blt         BLOCK_LOOP
+
+    cmp         r11, #0x19
+    bne         ln2_decode_mb_to
+
+    ldr         r12, [r9, #detok_qcoeff_start_ptr]
+    ldr         r10, [r9, #detok_coef_probs]
+    mov         r7, #0
+    mov         r3, #0x10
+    str         r12, [sp, #l_qcoeff]
+    str         r7, [sp, #l_i]
+    str         r7, [sp, #l_type]
+    str         r3, [sp, #l_stop]
+
+    str         r10, [sp, #l_coef_ptr]
+
+    b           BLOCK_LOOP
+
+ln2_decode_mb_to
+    cmp         r11, #0x10
+    bne         ln1_decode_mb_to
+
+    ldr         r10, [r9, #0x30]
+
+    mov         r7, #2
+    mov         r3, #0x18
+
+    str         r7, [sp, #l_type]
+    str         r3, [sp, #l_stop]
+
+    str         r10, [sp, #l_coef_ptr]
+    b           BLOCK_LOOP
+
+ln1_decode_mb_to
+    ldr         r2, [sp, #l_bc]
+    mov         r0, #0
+    nop
+
+    ldr         r3, [r2, #bool_decoder_buffer]
+    str         r5, [r2, #bool_decoder_count]
+    str         r4, [r2, #bool_decoder_value]
+    sub         r3, r8, r3
+    str         r3, [r2, #bool_decoder_pos]
+    str         r6, [r2, #bool_decoder_range]
+
+    add         sp, sp, #l_stacksize
+    ldmia       sp!, {r4 - r11, pc}
+
+    ENDP  ; |vp8_decode_mb_tokens_v5|
+
+    END
diff --git a/vp8/decoder/arm/dsystemdependent.c b/vp8/decoder/arm/dsystemdependent.c
new file mode 100644 (file)
index 0000000..455c83a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "blockd.h"
+#include "pragmas.h"
+#include "postproc.h"
+#include "dboolhuff.h"
+#include "dequantize.h"
+#include "onyxd_int.h"
+
+void vp8_dmachine_specific_config(VP8D_COMP *pbi)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    pbi->mb.rtcd         = &pbi->common.rtcd;
+#if HAVE_ARMV7
+    pbi->dequant.block   = vp8_dequantize_b_neon;
+    pbi->dequant.idct    = vp8_dequant_idct_neon;
+    pbi->dequant.idct_dc = vp8_dequant_dc_idct_neon;
+    pbi->dboolhuff.start = vp8dx_start_decode_c;
+    pbi->dboolhuff.stop  = vp8dx_stop_decode_c;
+    pbi->dboolhuff.fill  = vp8dx_bool_decoder_fill_c;
+    pbi->dboolhuff.debool = vp8dx_decode_bool_c;
+    pbi->dboolhuff.devalue = vp8dx_decode_value_c;
+
+#elif HAVE_ARMV6
+    pbi->dequant.block   = vp8_dequantize_b_v6;
+    pbi->dequant.idct    = vp8_dequant_idct_v6;
+    pbi->dequant.idct_dc = vp8_dequant_dc_idct_v6;
+    pbi->dboolhuff.start = vp8dx_start_decode_c;
+    pbi->dboolhuff.stop  = vp8dx_stop_decode_c;
+    pbi->dboolhuff.fill  = vp8dx_bool_decoder_fill_c;
+    pbi->dboolhuff.debool = vp8dx_decode_bool_c;
+    pbi->dboolhuff.devalue = vp8dx_decode_value_c;
+#endif
+#endif
+}
diff --git a/vp8/decoder/arm/neon/dboolhuff_neon.asm b/vp8/decoder/arm/neon/dboolhuff_neon.asm
new file mode 100644 (file)
index 0000000..7ec62a3
--- /dev/null
@@ -0,0 +1,159 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_decode_value_neon|
+    EXPORT  |vp8dx_start_decode_neon|
+    EXPORT  |vp8dx_stop_decode_neon|
+    EXPORT  |vp8dx_decode_bool_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    INCLUDE vpx_asm_offsets.asm
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+;   int z = 0;
+;   int bit;
+;   for ( bit=bits-1; bit>=0; bit-- )
+;   {
+;       z |= (vp8dx_decode_bool(br, 0x80)<<bit);
+;   }
+;   return z;
+
+;int vp8_decode_value_neon ( BOOL_DECODER *br, int bits )
+|vp8_decode_value_neon| PROC
+    stmdb   sp!, {r4 - r6, lr}
+    mov     r4, r0
+    mov     r5, r1
+    mov     r6, #0
+
+    subs    r5, r5, #1
+    bmi     decode_value_exit
+
+decode_value_loop
+    mov     r1, #0x80
+    mov     r0, r4
+    bl      vp8dx_decode_bool_neon_internal       ; needed for conversion to s file
+    orr     r6, r6, r0, lsl r5
+    subs    r5, r5, #1
+    bpl     decode_value_loop
+
+decode_value_exit
+    mov     r0, r6
+    ldmia   sp!, {r4 - r6, pc}
+    ENDP    ; |vp8_decode_value_neon|
+
+
+;void vp8dx_start_decode_neon ( BOOL_DECODER *br, unsigned char *source )
+|vp8dx_start_decode_neon| PROC
+    stmdb   sp!, {r4 - r5, lr}
+    mov     r2, #0
+    mov     r3, #255
+
+    str     r2, [r0, #bool_decoder_lowvalue]
+    str     r3, [r0, #bool_decoder_range]
+    str     r1, [r0, #bool_decoder_buffer]
+
+    mov     r3, #8
+    mov     r2, #4
+    str     r3, [r0, #bool_decoder_count]
+    str     r2, [r0, #bool_decoder_pos]
+
+    ldrb    r2, [r1, #3]
+    ldrb    r3, [r1, #2]
+    ldrb    r4, [r1, #1]
+    ldrb    r5, [r1]
+
+    orr     r1, r2, r3, lsl #8
+    orr     r1, r1, r4, lsl #16
+    orr     r1, r1, r5, lsl #24
+
+    str     r1, [r0, #bool_decoder_value]
+
+    ldmia   sp!, {r4 - r5, pc}
+    ENDP    ; |vp8dx_start_decode_neon|
+
+
+;void vp8dx_stop_decode_neon ( BOOL_DECODER *bc );
+|vp8dx_stop_decode_neon| PROC
+    mov     pc, lr
+    ENDP    ; |vp8dx_stop_decode_neon|
+
+
+; bigsplit  RN  r1
+; buffer_v  RN  r1
+; count_v       RN  r4
+; range_v       RN  r2
+; value_v       RN  r3
+; pos_v     RN  r5
+; split     RN  r6
+; bit           RN  lr
+;int vp8dx_decode_bool_neon ( BOOL_DECODER *br, int probability )
+|vp8dx_decode_bool_neon| PROC
+vp8dx_decode_bool_neon_internal
+;LDRD and STRD doubleword data transfers must be eight-byte aligned. Use ALIGN 8
+;before memory allocation
+    stmdb   sp!, {r4 - r5, lr}
+
+    ldr     r2, [r0, #bool_decoder_range]       ;load range (r2), value(r3)
+    ldr     r3, [r0, #bool_decoder_value]
+    ;ldrd   r2, r3, [r0, #bool_decoder_range]   ;ldrd costs 2 cycles
+    ;
+
+    mov     r4, r2, lsl #8
+    sub     r4, r4, #256
+    mov     r12, #1
+
+    smlawb  r4, r4, r1, r12         ;split = 1 +  (((range-1) * probability) >> 8)
+
+    mov     lr, r0
+    mov     r0, #0                  ;bit = 0
+    ;
+    subs    r5, r3, r4, lsl #24
+
+    subhs   r2, r2, r4              ;range = br->range-split
+    movlo   r2, r4                  ;range = split
+    movhs   r0, #1                  ;bit = 1
+    movhs   r3, r5                  ;value = value-bigsplit
+
+    cmp     r2, #0x80
+    blt     range_less_0x80
+    strd    r2, r3, [lr, #bool_decoder_range]   ;store result
+
+    ldmia   sp!, {r4 - r5, pc}
+
+range_less_0x80
+
+    ldrd    r4, r5, [lr, #bool_decoder_count]   ;load count, pos, buffer
+    ldr     r1, [lr, #bool_decoder_buffer]
+
+    clz     r12, r2
+    add     r1, r1, r5
+
+    sub     r12, r12, #24
+    subs    r4, r4, r12             ;count -= shift
+    mov     r2, r2, lsl r12         ;range <<= shift
+    mov     r3, r3, lsl r12         ;value <<= shift
+    addle   r4, r4, #8              ;count += 8
+    ldrleb  r12, [r1], #1           ;br->buffer[br->pos]
+
+    rsble   r1, r4, #8              ;-count
+    addle   r5, r5, #1              ;br->pos++
+    orrle   r3, r3, r12, lsl r1     ;value |= (br->buffer[br->pos]) << (-count)
+
+    strd    r2, r3, [lr, #bool_decoder_range]   ;store result
+    strd    r4, r5, [lr, #bool_decoder_count]
+
+    ldmia   sp!, {r4 - r5, pc}
+    ENDP    ; |vp8dx_decode_bool_neon|
+
+    END
diff --git a/vp8/decoder/arm/neon/dequantdcidct_neon.asm b/vp8/decoder/arm/neon/dequantdcidct_neon.asm
new file mode 100644 (file)
index 0000000..3392f2c
--- /dev/null
@@ -0,0 +1,133 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequant_dc_idct_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vp8_dequant_dc_idct_c(short *input, short *dq, short *output, int pitch, int Dc);
+; r0    short *input,
+; r1    short *dq,
+; r2    short *output,
+; r3    int pitch,
+; (stack)   int Dc
+|vp8_dequant_dc_idct_neon| PROC
+    vld1.16         {q3, q4}, [r0]
+    vld1.16         {q5, q6}, [r1]
+
+    ldr             r1, [sp]                ;load Dc from stack
+
+    ldr             r12, _dcidct_coeff_
+
+    vmul.i16        q1, q3, q5              ;input for short_idct4x4llm_neon
+    vmul.i16        q2, q4, q6
+
+    vmov.16         d2[0], r1
+
+;|short_idct4x4llm_neon| PROC
+    vld1.16         {d0}, [r12]
+    vswp            d3, d4                  ;q2(vp[4] vp[12])
+
+    vqdmulh.s16     q3, q2, d0[2]
+    vqdmulh.s16     q4, q2, d0[0]
+
+    vqadd.s16       d12, d2, d3             ;a1
+    vqsub.s16       d13, d2, d3             ;b1
+
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vqadd.s16       q3, q3, q2              ;modify since sinpi8sqrt2 > 65536/2 (negtive number)
+    vqadd.s16       q4, q4, q2
+
+    ;d6 - c1:temp1
+    ;d7 - d1:temp2
+    ;d8 - d1:temp1
+    ;d9 - c1:temp2
+
+    vqsub.s16       d10, d6, d9             ;c1
+    vqadd.s16       d11, d7, d8             ;d1
+
+    vqadd.s16       d2, d12, d11
+    vqadd.s16       d3, d13, d10
+    vqsub.s16       d4, d13, d10
+    vqsub.s16       d5, d12, d11
+
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+; memset(input, 0, 32) -- 32bytes
+    vmov.i16        q14, #0
+
+    vswp            d3, d4
+    vqdmulh.s16     q3, q2, d0[2]
+    vqdmulh.s16     q4, q2, d0[0]
+
+    vqadd.s16       d12, d2, d3             ;a1
+    vqsub.s16       d13, d2, d3             ;b1
+
+    vmov            q15, q14
+
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vqadd.s16       q3, q3, q2              ;modify since sinpi8sqrt2 > 65536/2 (negtive number)
+    vqadd.s16       q4, q4, q2
+
+    vqsub.s16       d10, d6, d9             ;c1
+    vqadd.s16       d11, d7, d8             ;d1
+
+    vqadd.s16       d2, d12, d11
+    vqadd.s16       d3, d13, d10
+    vqsub.s16       d4, d13, d10
+    vqsub.s16       d5, d12, d11
+
+    vst1.16         {q14, q15}, [r0]
+
+    vrshr.s16       d2, d2, #3
+    vrshr.s16       d3, d3, #3
+    vrshr.s16       d4, d4, #3
+    vrshr.s16       d5, d5, #3
+
+    add             r1, r2, r3
+    add             r12, r1, r3
+    add             r0, r12, r3
+
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vst1.16         {d2}, [r2]
+    vst1.16         {d3}, [r1]
+    vst1.16         {d4}, [r12]
+    vst1.16         {d5}, [r0]
+
+    bx             lr
+
+    ENDP
+
+;-----------------
+    AREA    dcidct4x4_dat, DATA, READWRITE          ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_dcidct_coeff_
+    DCD     dcidct_coeff
+dcidct_coeff
+    DCD     0x4e7b4e7b, 0x8a8c8a8c
+
+;20091, 20091, 35468, 35468
+
+    END
diff --git a/vp8/decoder/arm/neon/dequantidct_neon.asm b/vp8/decoder/arm/neon/dequantidct_neon.asm
new file mode 100644 (file)
index 0000000..bba4d5d
--- /dev/null
@@ -0,0 +1,128 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequant_idct_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vp8_dequant_idct_c(short *input, short *dq, short *output, int pitch);
+; r0    short *input,
+; r1    short *dq,
+; r2    short *output,
+; r3    int pitch,
+|vp8_dequant_idct_neon| PROC
+    vld1.16         {q3, q4}, [r0]
+    vld1.16         {q5, q6}, [r1]
+
+    ldr             r12, _didct_coeff_
+
+    vmul.i16        q1, q3, q5              ;input for short_idct4x4llm_neon
+    vmul.i16        q2, q4, q6
+
+;|short_idct4x4llm_neon| PROC
+    vld1.16         {d0}, [r12]
+    vswp            d3, d4                  ;q2(vp[4] vp[12])
+
+    vqdmulh.s16     q3, q2, d0[2]
+    vqdmulh.s16     q4, q2, d0[0]
+
+    vqadd.s16       d12, d2, d3             ;a1
+    vqsub.s16       d13, d2, d3             ;b1
+
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vqadd.s16       q3, q3, q2              ;modify since sinpi8sqrt2 > 65536/2 (negtive number)
+    vqadd.s16       q4, q4, q2
+
+    ;d6 - c1:temp1
+    ;d7 - d1:temp2
+    ;d8 - d1:temp1
+    ;d9 - c1:temp2
+
+    vqsub.s16       d10, d6, d9             ;c1
+    vqadd.s16       d11, d7, d8             ;d1
+
+    vqadd.s16       d2, d12, d11
+    vqadd.s16       d3, d13, d10
+    vqsub.s16       d4, d13, d10
+    vqsub.s16       d5, d12, d11
+
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+; memset(input, 0, 32) -- 32bytes
+    vmov.i16        q14, #0
+
+    vswp            d3, d4
+    vqdmulh.s16     q3, q2, d0[2]
+    vqdmulh.s16     q4, q2, d0[0]
+
+    vqadd.s16       d12, d2, d3             ;a1
+    vqsub.s16       d13, d2, d3             ;b1
+
+    vmov            q15, q14
+
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vqadd.s16       q3, q3, q2              ;modify since sinpi8sqrt2 > 65536/2 (negtive number)
+    vqadd.s16       q4, q4, q2
+
+    vqsub.s16       d10, d6, d9             ;c1
+    vqadd.s16       d11, d7, d8             ;d1
+
+    vqadd.s16       d2, d12, d11
+    vqadd.s16       d3, d13, d10
+    vqsub.s16       d4, d13, d10
+    vqsub.s16       d5, d12, d11
+
+    vst1.16         {q14, q15}, [r0]
+
+    vrshr.s16       d2, d2, #3
+    vrshr.s16       d3, d3, #3
+    vrshr.s16       d4, d4, #3
+    vrshr.s16       d5, d5, #3
+
+    add             r1, r2, r3
+    add             r12, r1, r3
+    add             r0, r12, r3
+
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vst1.16         {d2}, [r2]
+    vst1.16         {d3}, [r1]
+    vst1.16         {d4}, [r12]
+    vst1.16         {d5}, [r0]
+
+    bx             lr
+
+    ENDP
+
+;-----------------
+    AREA    didct4x4_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_didct_coeff_
+    DCD     didct_coeff
+didct_coeff
+    DCD     0x4e7b4e7b, 0x8a8c8a8c
+
+;20091, 20091, 35468, 35468
+
+    END
diff --git a/vp8/decoder/arm/neon/dequantizeb_neon.asm b/vp8/decoder/arm/neon/dequantizeb_neon.asm
new file mode 100644 (file)
index 0000000..1bde946
--- /dev/null
@@ -0,0 +1,33 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_dequantize_b_loop_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    short *Q,
+; r1    short *DQC
+; r2    short *DQ
+|vp8_dequantize_b_loop_neon| PROC
+    vld1.16         {q0, q1}, [r0]
+    vld1.16         {q2, q3}, [r1]
+
+    vmul.i16        q4, q0, q2
+    vmul.i16        q5, q1, q3
+
+    vst1.16         {q4, q5}, [r2]
+
+    bx             lr
+
+    ENDP
+
+    END
diff --git a/vp8/decoder/dboolhuff.c b/vp8/decoder/dboolhuff.c
new file mode 100644 (file)
index 0000000..442054e
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "dboolhuff.h"
+#include "vpx_ports/mem.h"
+#include "vpx_mem/vpx_mem.h"
+
+DECLARE_ALIGNED(16, const unsigned int, vp8dx_bitreader_norm[256]) =
+{
+    0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+static void copy_in(BOOL_DECODER *br, unsigned int to_write)
+{
+    if (to_write > br->user_buffer_sz)
+        to_write = br->user_buffer_sz;
+
+    memcpy(br->write_ptr, br->user_buffer, to_write);
+    br->user_buffer += to_write;
+    br->user_buffer_sz -= to_write;
+    br->write_ptr = br_ptr_advance(br->write_ptr, to_write);
+}
+
+int vp8dx_start_decode_c(BOOL_DECODER *br, const unsigned char *source,
+                        unsigned int source_sz)
+{
+    br->lowvalue = 0;
+    br->range    = 255;
+    br->count    = 0;
+    br->user_buffer    = source;
+    br->user_buffer_sz = source_sz;
+
+    if (source_sz && !source)
+        return 1;
+
+    /* Allocate the ring buffer backing store with alignment equal to the
+     * buffer size*2 so that a single pointer can be used for wrapping rather
+     * than a pointer+offset.
+     */
+    br->decode_buffer  = vpx_memalign(VP8_BOOL_DECODER_SZ * 2,
+                                      VP8_BOOL_DECODER_SZ);
+
+    if (!br->decode_buffer)
+        return 1;
+
+    /* Populate the buffer */
+    br->read_ptr = br->decode_buffer;
+    br->write_ptr = br->decode_buffer;
+    copy_in(br, VP8_BOOL_DECODER_SZ);
+
+    /* Read the first byte */
+    br->value = (*br->read_ptr++) << 8;
+    return 0;
+}
+
+
+void vp8dx_bool_decoder_fill_c(BOOL_DECODER *br)
+{
+    int          left, right;
+
+    /* Find available room in the buffer */
+    left = 0;
+    right = br->read_ptr - br->write_ptr;
+
+    if (right < 0)
+    {
+        /* Read pointer is behind the write pointer. We can write from the
+         * write pointer to the end of the buffer.
+         */
+        right = VP8_BOOL_DECODER_SZ - (br->write_ptr - br->decode_buffer);
+        left = br->read_ptr - br->decode_buffer;
+    }
+
+    if (right + left < 128)
+        return;
+
+    if (right)
+        copy_in(br, right);
+
+    if (left)
+    {
+        br->write_ptr = br->decode_buffer;
+        copy_in(br, left);
+    }
+
+}
+
+
+void vp8dx_stop_decode_c(BOOL_DECODER *bc)
+{
+    vpx_free(bc->decode_buffer);
+    bc->decode_buffer = 0;
+}
+
+#if 0
+/*
+ * Until optimized versions of these functions are available, we
+ * keep the implementation in the header to allow inlining.
+ *
+ * The RTCD-style invocations are still in place so this can
+ * be switched by just uncommenting these functions here and
+ * the DBOOLHUFF_INVOKE calls in the header.
+ */
+int vp8dx_decode_bool_c(BOOL_DECODER *br, int probability)
+{
+    unsigned int bit=0;
+    unsigned int split;
+    unsigned int bigsplit;
+    register unsigned int range = br->range;
+    register unsigned int value = br->value;
+
+    split = 1 + (((range-1) * probability) >> 8);
+    bigsplit = (split<<8);
+
+    range = split;
+    if(value >= bigsplit)
+    {
+        range = br->range-split;
+        value = value-bigsplit;
+        bit = 1;
+    }
+
+    /*if(range>=0x80)
+    {
+        br->value = value;
+        br->range = range;
+        return bit;
+    }*/
+
+    {
+        int count = br->count;
+        register unsigned int shift = vp8dx_bitreader_norm[range];
+        range <<= shift;
+        value <<= shift;
+        count -= shift;
+        if(count <= 0)
+        {
+            value |= (*br->read_ptr) << (-count);
+            br->read_ptr = br_ptr_advance(br->read_ptr, 1);
+            count += 8 ;
+        }
+        br->count = count;
+    }
+    br->value = value;
+    br->range = range;
+    return bit;
+}
+
+int vp8dx_decode_value_c(BOOL_DECODER *br, int bits)
+{
+    int z = 0;
+    int bit;
+    for ( bit=bits-1; bit>=0; bit-- )
+    {
+        z |= (vp8dx_decode_bool(br, 0x80)<<bit);
+    }
+    return z;
+}
+#endif
diff --git a/vp8/decoder/dboolhuff.h b/vp8/decoder/dboolhuff.h
new file mode 100644 (file)
index 0000000..f5c9822
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef DBOOLHUFF_H
+#define DBOOLHUFF_H
+#include "vpx_ports/config.h"
+#include "vpx_ports/mem.h"
+#include "vpx_ports/vpx_integer.h"
+
+/* Size of the bool decoder backing storage
+ *
+ * This size was chosen to be greater than the worst case encoding of a
+ * single macroblock. This was calcluated as follows (python):
+ *
+ *     def max_cost(prob):
+ *         return max(prob_costs[prob], prob_costs[255-prob]) / 256;
+ *
+ *     tree_nodes_cost = 7 * max_cost(255)
+ *     extra_bits_cost = sum([max_cost(bit) for bit in extra_bits])
+ *     sign_bit_cost = max_cost(128)
+ *     total_cost = tree_nodes_cost + extra_bits_cost + sign_bit_cost
+ *
+ * where the prob_costs table was taken from the C vp8_prob_cost table in
+ * boolhuff.c and the extra_bits table was taken from the 11 extrabits for
+ * a category 6 token as defined in vp8d_token_extra_bits2/detokenize.c
+ *
+ * This equation produced a maximum of 79 bits per coefficient. Scaling up
+ * to the macroblock level:
+ *
+ *     79 bits/coeff * 16 coeff/block * 25 blocks/macroblock = 31600 b/mb
+ *
+ *     4096 bytes = 32768 bits > 31600
+ */
+#define VP8_BOOL_DECODER_SZ       4096
+#define VP8_BOOL_DECODER_MASK     (VP8_BOOL_DECODER_SZ-1)
+#define VP8_BOOL_DECODER_PTR_MASK (~(uintptr_t)(VP8_BOOL_DECODER_SZ))
+
+struct vp8_dboolhuff_rtcd_vtable;
+
+typedef struct
+{
+    unsigned int         lowvalue;
+    unsigned int         range;
+    unsigned int         value;
+    int                  count;
+    const unsigned char *user_buffer;
+    unsigned int         user_buffer_sz;
+    unsigned char       *decode_buffer;
+    const unsigned char *read_ptr;
+    unsigned char       *write_ptr;
+#if CONFIG_RUNTIME_CPU_DETECT
+    struct vp8_dboolhuff_rtcd_vtable *rtcd;
+#endif
+} BOOL_DECODER;
+
+#define prototype_dbool_start(sym) int sym(BOOL_DECODER *br, \
+    const unsigned char *source, unsigned int source_sz)
+#define prototype_dbool_stop(sym) void sym(BOOL_DECODER *bc)
+#define prototype_dbool_fill(sym) void sym(BOOL_DECODER *br)
+#define prototype_dbool_debool(sym) int sym(BOOL_DECODER *br, int probability)
+#define prototype_dbool_devalue(sym) int sym(BOOL_DECODER *br, int bits);
+
+#if ARCH_ARM
+#include "arm/dboolhuff_arm.h"
+#endif
+
+#ifndef vp8_dbool_start
+#define vp8_dbool_start vp8dx_start_decode_c
+#endif
+
+#ifndef vp8_dbool_stop
+#define vp8_dbool_stop vp8dx_stop_decode_c
+#endif
+
+#ifndef vp8_dbool_fill
+#define vp8_dbool_fill vp8dx_bool_decoder_fill_c
+#endif
+
+#ifndef vp8_dbool_debool
+#define vp8_dbool_debool vp8dx_decode_bool_c
+#endif
+
+#ifndef vp8_dbool_devalue
+#define vp8_dbool_devalue vp8dx_decode_value_c
+#endif
+
+extern prototype_dbool_start(vp8_dbool_start);
+extern prototype_dbool_stop(vp8_dbool_stop);
+extern prototype_dbool_fill(vp8_dbool_fill);
+extern prototype_dbool_debool(vp8_dbool_debool);
+extern prototype_dbool_devalue(vp8_dbool_devalue);
+
+typedef prototype_dbool_start((*vp8_dbool_start_fn_t));
+typedef prototype_dbool_stop((*vp8_dbool_stop_fn_t));
+typedef prototype_dbool_fill((*vp8_dbool_fill_fn_t));
+typedef prototype_dbool_debool((*vp8_dbool_debool_fn_t));
+typedef prototype_dbool_devalue((*vp8_dbool_devalue_fn_t));
+
+typedef struct vp8_dboolhuff_rtcd_vtable {
+    vp8_dbool_start_fn_t   start;
+    vp8_dbool_stop_fn_t    stop;
+    vp8_dbool_fill_fn_t    fill;
+    vp8_dbool_debool_fn_t  debool;
+    vp8_dbool_devalue_fn_t devalue;
+} vp8_dboolhuff_rtcd_vtable_t;
+
+// There are no processor-specific versions of these
+// functions right now. Disable RTCD to avoid using
+// function pointers which gives a speed boost
+//#ifdef ENABLE_RUNTIME_CPU_DETECT
+//#define DBOOLHUFF_INVOKE(ctx,fn) (ctx)->fn
+//#define IF_RTCD(x) (x)
+//#else
+#define DBOOLHUFF_INVOKE(ctx,fn) vp8_dbool_##fn
+#define IF_RTCD(x) NULL
+//#endif
+
+static unsigned char *br_ptr_advance(const unsigned char *_ptr,
+                                     unsigned int n)
+{
+    uintptr_t  ptr = (uintptr_t)_ptr;
+
+    ptr += n;
+    ptr &= VP8_BOOL_DECODER_PTR_MASK;
+
+    return (void *)ptr;
+}
+
+DECLARE_ALIGNED(16, extern const unsigned int, vp8dx_bitreader_norm[256]);
+
+/* wrapper functions to hide RTCD. static means inline means hopefully no
+ * penalty
+ */
+static int vp8dx_start_decode(BOOL_DECODER *br,
+        struct vp8_dboolhuff_rtcd_vtable *rtcd,
+        const unsigned char *source, unsigned int source_sz) {
+#if CONFIG_RUNTIME_CPU_DETECT
+    br->rtcd = rtcd;
+#endif
+    return DBOOLHUFF_INVOKE(rtcd, start)(br, source, source_sz);
+}
+static void vp8dx_stop_decode(BOOL_DECODER *br) {
+    DBOOLHUFF_INVOKE(br->rtcd, stop)(br);
+}
+static void vp8dx_bool_decoder_fill(BOOL_DECODER *br) {
+    DBOOLHUFF_INVOKE(br->rtcd, fill)(br);
+}
+static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
+  /*
+   * Until optimized versions of this function are available, we
+   * keep the implementation in the header to allow inlining.
+   *
+   *return DBOOLHUFF_INVOKE(br->rtcd, debool)(br, probability);
+   */
+    unsigned int bit = 0;
+    unsigned int split;
+    unsigned int bigsplit;
+    register unsigned int range = br->range;
+    register unsigned int value = br->value;
+
+    split = 1 + (((range - 1) * probability) >> 8);
+    bigsplit = (split << 8);
+
+    range = split;
+
+    if (value >= bigsplit)
+    {
+        range = br->range - split;
+        value = value - bigsplit;
+        bit = 1;
+    }
+
+    /*if(range>=0x80)
+    {
+        br->value = value;
+        br->range = range;
+        return bit
+    }*/
+
+    {
+        int count = br->count;
+        register unsigned int shift = vp8dx_bitreader_norm[range];
+        range <<= shift;
+        value <<= shift;
+        count -= shift;
+
+        if (count <= 0)
+        {
+            value |= (*br->read_ptr) << (-count);
+            br->read_ptr = br_ptr_advance(br->read_ptr, 1);
+            count += 8 ;
+        }
+
+        br->count = count;
+    }
+    br->value = value;
+    br->range = range;
+    return bit;
+}
+
+static int vp8_decode_value(BOOL_DECODER *br, int bits)
+{
+  /*
+   * Until optimized versions of this function are available, we
+   * keep the implementation in the header to allow inlining.
+   *
+   *return DBOOLHUFF_INVOKE(br->rtcd, devalue)(br, bits);
+   */
+    int z = 0;
+    int bit;
+
+    for (bit = bits - 1; bit >= 0; bit--)
+    {
+        z |= (vp8dx_decode_bool(br, 0x80) << bit);
+    }
+
+    return z;
+}
+#endif
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
new file mode 100644 (file)
index 0000000..6035f3e
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "treereader.h"
+#include "entropymv.h"
+#include "entropymode.h"
+#include "onyxd_int.h"
+#include "findnearmv.h"
+#include "demode.h"
+#if CONFIG_DEBUG
+#include <assert.h>
+#endif
+
+static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc)
+{
+    const vp8_prob *const p = (const vp8_prob *) mvc;
+    int x = 0;
+
+    if (vp8_read(r, p [mvpis_short]))  /* Large */
+    {
+        int i = 0;
+
+        do
+        {
+            x += vp8_read(r, p [MVPbits + i]) << i;
+        }
+        while (++i < 3);
+
+        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
+
+        do
+        {
+            x += vp8_read(r, p [MVPbits + i]) << i;
+        }
+        while (--i > 3);
+
+        if (!(x & 0xFFF0)  ||  vp8_read(r, p [MVPbits + 3]))
+            x += 8;
+    }
+    else   /* small */
+        x = vp8_treed_read(r, vp8_small_mvtree, p + MVPshort);
+
+    if (x  &&  vp8_read(r, p [MVPsign]))
+        x = -x;
+
+    return x;
+}
+
+static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc)
+{
+    mv->row = (short)(read_mvcomponent(r,   mvc) << 1);
+    mv->col = (short)(read_mvcomponent(r, ++mvc) << 1);
+}
+
+
+static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc)
+{
+    int i = 0;
+
+    do
+    {
+        const vp8_prob *up = vp8_mv_update_probs[i].prob;
+        vp8_prob *p = (vp8_prob *)(mvc + i);
+        vp8_prob *const pstop = p + MVPcount;
+
+        do
+        {
+            if (vp8_read(bc, *up++))
+            {
+                const vp8_prob x = (vp8_prob)vp8_read_literal(bc, 7);
+
+                *p = x ? x << 1 : 1;
+            }
+        }
+        while (++p < pstop);
+    }
+    while (++i < 2);
+}
+
+
+static MB_PREDICTION_MODE read_mv_ref(vp8_reader *bc, const vp8_prob *p)
+{
+    const int i = vp8_treed_read(bc, vp8_mv_ref_tree, p);
+
+    return (MB_PREDICTION_MODE)i;
+}
+
+static MB_PREDICTION_MODE sub_mv_ref(vp8_reader *bc, const vp8_prob *p)
+{
+    const int i = vp8_treed_read(bc, vp8_sub_mv_ref_tree, p);
+
+    return (MB_PREDICTION_MODE)i;
+}
+unsigned int vp8_mv_cont_count[5][4] =
+{
+    { 0, 0, 0, 0 },
+    { 0, 0, 0, 0 },
+    { 0, 0, 0, 0 },
+    { 0, 0, 0, 0 },
+    { 0, 0, 0, 0 }
+};
+
+void vp8_decode_mode_mvs(VP8D_COMP *pbi)
+{
+    const MV Zero = { 0, 0};
+
+    VP8_COMMON *const pc = & pbi->common;
+    vp8_reader *const bc = & pbi->bc;
+
+    MODE_INFO *mi = pc->mi, *ms;
+    const int mis = pc->mode_info_stride;
+
+    MV_CONTEXT *const mvc = pc->fc.mvc;
+
+    int mb_row = -1;
+
+    vp8_prob prob_intra;
+    vp8_prob prob_last;
+    vp8_prob prob_gf;
+    vp8_prob prob_skip_false = 0;
+
+    if (pc->mb_no_coeff_skip)
+        prob_skip_false = (vp8_prob)vp8_read_literal(bc, 8);
+
+    prob_intra = (vp8_prob)vp8_read_literal(bc, 8);
+    prob_last  = (vp8_prob)vp8_read_literal(bc, 8);
+    prob_gf    = (vp8_prob)vp8_read_literal(bc, 8);
+
+    ms = pc->mi - 1;
+
+    if (vp8_read_bit(bc))
+    {
+        int i = 0;
+
+        do
+        {
+            pc->fc.ymode_prob[i] = (vp8_prob) vp8_read_literal(bc, 8);
+        }
+        while (++i < 4);
+    }
+
+    if (vp8_read_bit(bc))
+    {
+        int i = 0;
+
+        do
+        {
+            pc->fc.uv_mode_prob[i] = (vp8_prob) vp8_read_literal(bc, 8);
+        }
+        while (++i < 3);
+    }
+
+    read_mvcontexts(bc, mvc);
+
+    while (++mb_row < pc->mb_rows)
+    {
+        int mb_col = -1;
+
+        while (++mb_col < pc->mb_cols)
+        {
+            MB_MODE_INFO *const mbmi = & mi->mbmi;
+            MV *const mv = & mbmi->mv.as_mv;
+            VP8_COMMON *const pc = &pbi->common;
+            MACROBLOCKD *xd = &pbi->mb;
+
+            vp8dx_bool_decoder_fill(bc);
+
+            // Distance of Mb to the various image edges.
+            // These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
+            xd->mb_to_left_edge = -((mb_col * 16) << 3);
+            xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+            xd->mb_to_top_edge = -((mb_row * 16)) << 3;
+            xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+
+            // If required read in new segmentation data for this MB
+            if (pbi->mb.update_mb_segmentation_map)
+                vp8_read_mb_features(bc, mbmi, &pbi->mb);
+
+            // Read the macroblock coeff skip flag if this feature is in use, else default to 0
+            if (pc->mb_no_coeff_skip)
+                mbmi->mb_skip_coeff = vp8_read(bc, prob_skip_false);
+            else
+                mbmi->mb_skip_coeff = 0;
+
+            mbmi->uv_mode = DC_PRED;
+
+            if ((mbmi->ref_frame = (MV_REFERENCE_FRAME) vp8_read(bc, prob_intra)))    /* inter MB */
+            {
+                int rct[4];
+                vp8_prob mv_ref_p [VP8_MVREFS-1];
+                MV nearest, nearby, best_mv;
+
+                if (vp8_read(bc, prob_last))
+                {
+                    mbmi->ref_frame = (MV_REFERENCE_FRAME)((int)mbmi->ref_frame + (int)(1 + vp8_read(bc, prob_gf)));
+                }
+
+                vp8_find_near_mvs(xd, mi, &nearest, &nearby, &best_mv, rct, mbmi->ref_frame, pbi->common.ref_frame_sign_bias);
+
+                vp8_mv_ref_probs(mv_ref_p, rct);
+
+                switch (mbmi->mode = read_mv_ref(bc, mv_ref_p))
+                {
+                case SPLITMV:
+                {
+                    const int s = mbmi->partitioning = vp8_treed_read(
+                                                           bc, vp8_mbsplit_tree, vp8_mbsplit_probs
+                                                       );
+                    const int num_p = vp8_mbsplit_count [s];
+                    const int *const  L = vp8_mbsplits [s];
+                    int j = 0;
+
+                    do  /* for each subset j */
+                    {
+                        B_MODE_INFO *const bmi = mbmi->partition_bmi + j;
+                        MV *const mv = & bmi->mv.as_mv;
+
+                        int k = -1;  /* first block in subset j */
+                        int mv_contz;
+
+                        while (j != L[++k])
+                            if (k >= 16)
+#if CONFIG_DEBUG
+                                assert(0);
+
+#else
+                                ;
+#endif
+
+                        mv_contz = vp8_mv_cont(&(vp8_left_bmi(mi, k)->mv.as_mv), &(vp8_above_bmi(mi, k, mis)->mv.as_mv));
+
+                        switch (bmi->mode = (B_PREDICTION_MODE) sub_mv_ref(bc, vp8_sub_mv_ref_prob2 [mv_contz])) //pc->fc.sub_mv_ref_prob))
+                        {
+                        case NEW4X4:
+                            read_mv(bc, mv, (const MV_CONTEXT *) mvc);
+                            mv->row += best_mv.row;
+                            mv->col += best_mv.col;
+#ifdef VPX_MODE_COUNT
+                            vp8_mv_cont_count[mv_contz][3]++;
+#endif
+                            break;
+                        case LEFT4X4:
+                            *mv = vp8_left_bmi(mi, k)->mv.as_mv;
+#ifdef VPX_MODE_COUNT
+                            vp8_mv_cont_count[mv_contz][0]++;
+#endif
+                            break;
+                        case ABOVE4X4:
+                            *mv = vp8_above_bmi(mi, k, mis)->mv.as_mv;
+#ifdef VPX_MODE_COUNT
+                            vp8_mv_cont_count[mv_contz][1]++;
+#endif
+                            break;
+                        case ZERO4X4:
+                            *mv = Zero;
+#ifdef VPX_MODE_COUNT
+                            vp8_mv_cont_count[mv_contz][2]++;
+#endif
+                            break;
+                        default:
+                            break;
+                        }
+
+                        /* Fill (uniform) modes, mvs of jth subset.
+                           Must do it here because ensuing subsets can
+                           refer back to us via "left" or "above". */
+                        do
+                            if (j == L[k])
+                                mi->bmi[k] = *bmi;
+
+                        while (++k < 16);
+                    }
+                    while (++j < num_p);
+                }
+
+                *mv = mi->bmi[15].mv.as_mv;
+
+                break;  /* done with SPLITMV */
+
+                case NEARMV:
+                    *mv = nearby;
+
+                    // Clip "next_nearest" so that it does not extend to far out of image
+                    if (mv->col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
+                        mv->col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
+                    else if (mv->col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
+                        mv->col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
+
+                    if (mv->row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
+                        mv->row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
+                    else if (mv->row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
+                        mv->row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
+
+                    goto propagate_mv;
+
+                case NEARESTMV:
+                    *mv = nearest;
+
+                    // Clip "next_nearest" so that it does not extend to far out of image
+                    if (mv->col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
+                        mv->col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
+                    else if (mv->col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
+                        mv->col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
+
+                    if (mv->row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
+                        mv->row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
+                    else if (mv->row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
+                        mv->row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
+
+                    goto propagate_mv;
+
+                case ZEROMV:
+                    *mv = Zero;
+                    goto propagate_mv;
+
+                case NEWMV:
+                    read_mv(bc, mv, (const MV_CONTEXT *) mvc);
+                    mv->row += best_mv.row;
+                    mv->col += best_mv.col;
+                    /* Encoder should not produce invalid motion vectors, but since
+                     * arbitrary length MVs can be parsed from the bitstream, we
+                     * need to clamp them here in case we're reading bad data to
+                     * avoid a crash.
+                     */
+#if CONFIG_DEBUG
+                    assert(mv->col >= (xd->mb_to_left_edge - LEFT_TOP_MARGIN));
+                    assert(mv->col <= (xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN));
+                    assert(mv->row >= (xd->mb_to_top_edge - LEFT_TOP_MARGIN));
+                    assert(mv->row <= (xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN));
+#endif
+
+                    if (mv->col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
+                        mv->col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
+                    else if (mv->col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
+                        mv->col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
+
+                    if (mv->row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
+                        mv->row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
+                    else if (mv->row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
+                        mv->row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
+
+                propagate_mv:  /* same MV throughout */
+                    {
+                        //int i=0;
+                        //do
+                        //{
+                        //  mi->bmi[i].mv.as_mv = *mv;
+                        //}
+                        //while( ++i < 16);
+
+                        mi->bmi[0].mv.as_mv = *mv;
+                        mi->bmi[1].mv.as_mv = *mv;
+                        mi->bmi[2].mv.as_mv = *mv;
+                        mi->bmi[3].mv.as_mv = *mv;
+                        mi->bmi[4].mv.as_mv = *mv;
+                        mi->bmi[5].mv.as_mv = *mv;
+                        mi->bmi[6].mv.as_mv = *mv;
+                        mi->bmi[7].mv.as_mv = *mv;
+                        mi->bmi[8].mv.as_mv = *mv;
+                        mi->bmi[9].mv.as_mv = *mv;
+                        mi->bmi[10].mv.as_mv = *mv;
+                        mi->bmi[11].mv.as_mv = *mv;
+                        mi->bmi[12].mv.as_mv = *mv;
+                        mi->bmi[13].mv.as_mv = *mv;
+                        mi->bmi[14].mv.as_mv = *mv;
+                        mi->bmi[15].mv.as_mv = *mv;
+                    }
+
+                    break;
+
+                default:;
+#if CONFIG_DEBUG
+                    assert(0);
+#endif
+                }
+
+            }
+            else
+            {
+                /* MB is intra coded */
+
+                int j = 0;
+
+                do
+                {
+                    mi->bmi[j].mv.as_mv = Zero;
+                }
+                while (++j < 16);
+
+                *mv = Zero;
+
+                if ((mbmi->mode = (MB_PREDICTION_MODE) vp8_read_ymode(bc, pc->fc.ymode_prob)) == B_PRED)
+                {
+                    int j = 0;
+
+                    do
+                    {
+                        mi->bmi[j].mode = (B_PREDICTION_MODE)vp8_read_bmode(bc, pc->fc.bmode_prob);
+                    }
+                    while (++j < 16);
+                }
+
+                mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pc->fc.uv_mode_prob);
+            }
+
+            mi++;       // next macroblock
+        }
+
+        mi++;           // skip left predictor each row
+    }
+}
diff --git a/vp8/decoder/decodemv.h b/vp8/decoder/decodemv.h
new file mode 100644 (file)
index 0000000..4030071
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxd_int.h"
+
+void vp8_decode_mode_mvs(VP8D_COMP *);
diff --git a/vp8/decoder/decoderthreading.h b/vp8/decoder/decoderthreading.h
new file mode 100644 (file)
index 0000000..ebc5c27
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+
+
+
+#ifndef _DECODER_THREADING_H
+#define _DECODER_THREADING_H
+
+
+extern void vp8_mtdecode_mb_rows(VP8D_COMP *pbi,
+                                 MACROBLOCKD *xd);
+extern void vp8_stop_lfthread(VP8D_COMP *pbi);
+extern void vp8_start_lfthread(VP8D_COMP *pbi);
+extern void vp8_decoder_remove_threads(VP8D_COMP *pbi);
+extern void vp8_decoder_create_threads(VP8D_COMP *pbi);
+#endif
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
new file mode 100644 (file)
index 0000000..4edf4f6
--- /dev/null
@@ -0,0 +1,907 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxd_int.h"
+#include "header.h"
+#include "reconintra.h"
+#include "reconintra4x4.h"
+#include "recon.h"
+#include "reconinter.h"
+#include "dequantize.h"
+#include "detokenize.h"
+#include "invtrans.h"
+#include "alloccommon.h"
+#include "entropymode.h"
+#include "quant_common.h"
+#include "segmentation_common.h"
+#include "setupintrarecon.h"
+#include "demode.h"
+#include "decodemv.h"
+#include "extend.h"
+#include "vpx_mem/vpx_mem.h"
+#include "idct.h"
+#include "dequantize.h"
+#include "predictdc.h"
+#include "threading.h"
+#include "decoderthreading.h"
+#include "dboolhuff.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+void vp8cx_init_de_quantizer(VP8D_COMP *pbi)
+{
+    int r, c;
+    int i;
+    int Q;
+    VP8_COMMON *const pc = & pbi->common;
+
+    for (Q = 0; Q < QINDEX_RANGE; Q++)
+    {
+        pc->Y1dequant[Q][0][0] = (short)vp8_dc_quant(Q, pc->y1dc_delta_q);
+        pc->Y2dequant[Q][0][0] = (short)vp8_dc2quant(Q, pc->y2dc_delta_q);
+        pc->UVdequant[Q][0][0] = (short)vp8_dc_uv_quant(Q, pc->uvdc_delta_q);
+
+        // all the ac values = ;
+        for (i = 1; i < 16; i++)
+        {
+            int rc = vp8_default_zig_zag1d[i];
+            r = (rc >> 2);
+            c = (rc & 3);
+
+            pc->Y1dequant[Q][r][c] = (short)vp8_ac_yquant(Q);
+            pc->Y2dequant[Q][r][c] = (short)vp8_ac2quant(Q, pc->y2ac_delta_q);
+            pc->UVdequant[Q][r][c] = (short)vp8_ac_uv_quant(Q, pc->uvac_delta_q);
+        }
+    }
+}
+
+static void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd)
+{
+    int i;
+    int QIndex;
+    MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
+    VP8_COMMON *const pc = & pbi->common;
+
+    // Decide whether to use the default or alternate baseline Q value.
+    if (xd->segmentation_enabled)
+    {
+        // Abs Value
+        if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+            QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id];
+
+        // Delta Value
+        else
+        {
+            QIndex = pc->base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id];
+            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;    // Clamp to valid range
+        }
+    }
+    else
+        QIndex = pc->base_qindex;
+
+    // Set up the block level dequant pointers
+    for (i = 0; i < 16; i++)
+    {
+        xd->block[i].dequant = pc->Y1dequant[QIndex];
+    }
+
+    for (i = 16; i < 24; i++)
+    {
+        xd->block[i].dequant = pc->UVdequant[QIndex];
+    }
+
+    xd->block[24].dequant = pc->Y2dequant[QIndex];
+
+}
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define RTCD_VTABLE(x) (&(pbi)->common.rtcd.x)
+#else
+#define RTCD_VTABLE(x) NULL
+#endif
+
+//skip_recon_mb() is Modified: Instead of writing the result to predictor buffer and then copying it
+// to dst buffer, we can write the result directly to dst buffer. This eliminates unnecessary copy.
+static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd)
+{
+    if (xd->frame_type == KEY_FRAME  ||  xd->mbmi.ref_frame == INTRA_FRAME)
+    {
+
+        vp8_build_intra_predictors_mbuv_s(xd);
+        vp8_build_intra_predictors_mby_s_ptr(xd);
+
+    }
+    else
+    {
+        vp8_build_inter_predictors_mb_s(xd);
+    }
+}
+
+static void reconstruct_mb(VP8D_COMP *pbi, MACROBLOCKD *xd)
+{
+    if (xd->frame_type == KEY_FRAME  ||  xd->mbmi.ref_frame == INTRA_FRAME)
+    {
+        vp8_build_intra_predictors_mbuv(xd);
+
+        if (xd->mbmi.mode != B_PRED)
+        {
+            vp8_build_intra_predictors_mby_ptr(xd);
+            vp8_recon16x16mb(RTCD_VTABLE(recon), xd);
+        }
+        else
+        {
+            vp8_recon_intra4x4mb(RTCD_VTABLE(recon), xd);
+        }
+    }
+    else
+    {
+        vp8_build_inter_predictors_mb(xd);
+        vp8_recon16x16mb(RTCD_VTABLE(recon), xd);
+    }
+}
+
+
+static void de_quantand_idct(VP8D_COMP *pbi, MACROBLOCKD *xd)
+{
+    int i;
+    BLOCKD *b = &xd->block[24];
+
+
+    if (xd->mbmi.mode != B_PRED && xd->mbmi.mode != SPLITMV)
+    {
+        DEQUANT_INVOKE(&pbi->dequant, block)(b);
+
+        // do 2nd order transform on the dc block
+        if (b->eob > 1)
+        {
+            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
+            ((int *)b->qcoeff)[0] = 0;
+            ((int *)b->qcoeff)[1] = 0;
+            ((int *)b->qcoeff)[2] = 0;
+            ((int *)b->qcoeff)[3] = 0;
+            ((int *)b->qcoeff)[4] = 0;
+            ((int *)b->qcoeff)[5] = 0;
+            ((int *)b->qcoeff)[6] = 0;
+            ((int *)b->qcoeff)[7] = 0;
+        }
+        else
+        {
+            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
+            ((int *)b->qcoeff)[0] = 0;
+        }
+
+
+        for (i = 0; i < 16; i++)
+        {
+
+            b = &xd->block[i];
+
+            if (b->eob > 1)
+            {
+                DEQUANT_INVOKE(&pbi->dequant, idct_dc)(b->qcoeff, &b->dequant[0][0], b->diff, 32, xd->block[24].diff[i]);
+            }
+            else
+            {
+                IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar)(xd->block[24].diff[i], b->diff, 32);
+            }
+        }
+
+        for (i = 16; i < 24; i++)
+        {
+            b = &xd->block[i];
+
+            if (b->eob > 1)
+            {
+                DEQUANT_INVOKE(&pbi->dequant, idct)(b->qcoeff, &b->dequant[0][0], b->diff, 16);
+            }
+            else
+            {
+                IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar)(b->qcoeff[0] * b->dequant[0][0], b->diff, 16);
+                ((int *)b->qcoeff)[0] = 0;
+            }
+        }
+    }
+    else
+    {
+        for (i = 0; i < 24; i++)
+        {
+
+            b = &xd->block[i];
+
+            if (b->eob > 1)
+            {
+                DEQUANT_INVOKE(&pbi->dequant, idct)(b->qcoeff, &b->dequant[0][0], b->diff, (32 - (i & 16)));
+            }
+            else
+            {
+                IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar)(b->qcoeff[0] * b->dequant[0][0], b->diff, (32 - (i & 16)));
+                ((int *)b->qcoeff)[0] = 0;
+            }
+        }
+    }
+}
+
+void vp8_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd)
+{
+    int eobtotal = 0;
+
+    if (xd->mbmi.mb_skip_coeff)
+    {
+        vp8_reset_mb_tokens_context(xd);
+    }
+    else
+    {
+        eobtotal = vp8_decode_mb_tokens(pbi, xd);
+    }
+
+    xd->mode_info_context->mbmi.dc_diff = 1;
+
+    if (xd->mbmi.mode != B_PRED && xd->mbmi.mode != SPLITMV && eobtotal == 0)
+    {
+        xd->mode_info_context->mbmi.dc_diff = 0;
+        skip_recon_mb(pbi, xd);
+        return;
+    }
+
+    if (xd->segmentation_enabled)
+        mb_init_dequantizer(pbi, xd);
+
+    de_quantand_idct(pbi, xd);
+    reconstruct_mb(pbi, xd);
+}
+
+static int get_delta_q(vp8_reader *bc, int prev, int *q_update)
+{
+    int ret_val = 0;
+
+    if (vp8_read_bit(bc))
+    {
+        ret_val = vp8_read_literal(bc, 4);
+
+        if (vp8_read_bit(bc))
+            ret_val = -ret_val;
+    }
+
+    /* Trigger a quantizer update if the delta-q value has changed */
+    if (ret_val != prev)
+        *q_update = 1;
+
+    return ret_val;
+}
+
+#ifdef PACKET_TESTING
+#include <stdio.h>
+FILE *vpxlog = 0;
+#endif
+
+
+
+void vp8_decode_mb_row(VP8D_COMP *pbi,
+                       VP8_COMMON *pc,
+                       int mb_row,
+                       MACROBLOCKD *xd)
+{
+
+    int i;
+    int recon_yoffset, recon_uvoffset;
+    int mb_col;
+    int recon_y_stride = pc->last_frame.y_stride;
+    int recon_uv_stride = pc->last_frame.uv_stride;
+
+    vpx_memset(pc->left_context, 0, sizeof(pc->left_context));
+    recon_yoffset = mb_row * recon_y_stride * 16;
+    recon_uvoffset = mb_row * recon_uv_stride * 8;
+    // reset above block coeffs
+
+    xd->above_context[Y1CONTEXT] = pc->above_context[Y1CONTEXT];
+    xd->above_context[UCONTEXT ] = pc->above_context[UCONTEXT];
+    xd->above_context[VCONTEXT ] = pc->above_context[VCONTEXT];
+    xd->above_context[Y2CONTEXT] = pc->above_context[Y2CONTEXT];
+    xd->up_available = (mb_row != 0);
+
+    xd->mb_to_top_edge = -((mb_row * 16)) << 3;
+    xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+
+    for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
+    {
+        // Take a copy of the mode and Mv information for this macroblock into the xd->mbmi
+        vpx_memcpy(&xd->mbmi, &xd->mode_info_context->mbmi, 32); //sizeof(MB_MODE_INFO) );
+
+        if (xd->mbmi.mode == SPLITMV || xd->mbmi.mode == B_PRED)
+        {
+            for (i = 0; i < 16; i++)
+            {
+                BLOCKD *d = &xd->block[i];
+                vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
+            }
+        }
+
+        // Distance of Mb to the various image edges.
+        // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
+        xd->mb_to_left_edge = -((mb_col * 16) << 3);
+        xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+
+        xd->dst.y_buffer = pc->new_frame.y_buffer + recon_yoffset;
+        xd->dst.u_buffer = pc->new_frame.u_buffer + recon_uvoffset;
+        xd->dst.v_buffer = pc->new_frame.v_buffer + recon_uvoffset;
+
+        xd->left_available = (mb_col != 0);
+
+        // Select the appropriate reference frame for this MB
+        if (xd->mbmi.ref_frame == LAST_FRAME)
+        {
+            xd->pre.y_buffer = pc->last_frame.y_buffer + recon_yoffset;
+            xd->pre.u_buffer = pc->last_frame.u_buffer + recon_uvoffset;
+            xd->pre.v_buffer = pc->last_frame.v_buffer + recon_uvoffset;
+        }
+        else if (xd->mbmi.ref_frame == GOLDEN_FRAME)
+        {
+            // Golden frame reconstruction buffer
+            xd->pre.y_buffer = pc->golden_frame.y_buffer + recon_yoffset;
+            xd->pre.u_buffer = pc->golden_frame.u_buffer + recon_uvoffset;
+            xd->pre.v_buffer = pc->golden_frame.v_buffer + recon_uvoffset;
+        }
+        else
+        {
+            // Alternate reference frame reconstruction buffer
+            xd->pre.y_buffer = pc->alt_ref_frame.y_buffer + recon_yoffset;
+            xd->pre.u_buffer = pc->alt_ref_frame.u_buffer + recon_uvoffset;
+            xd->pre.v_buffer = pc->alt_ref_frame.v_buffer + recon_uvoffset;
+        }
+
+        vp8_build_uvmvs(xd, pc->full_pixel);
+
+        /*
+        if(pbi->common.current_video_frame==0 &&mb_col==1 && mb_row==0)
+        pbi->debugoutput =1;
+        else
+        pbi->debugoutput =0;
+        */
+        vp8dx_bool_decoder_fill(xd->current_bc);
+        vp8_decode_macroblock(pbi, xd);
+
+
+        recon_yoffset += 16;
+        recon_uvoffset += 8;
+
+        ++xd->mode_info_context;  /* next mb */
+
+        xd->gf_active_ptr++;      // GF useage flag for next MB
+
+        xd->above_context[Y1CONTEXT] += 4;
+        xd->above_context[UCONTEXT ] += 2;
+        xd->above_context[VCONTEXT ] += 2;
+        xd->above_context[Y2CONTEXT] ++;
+
+        pbi->current_mb_col_main = mb_col;
+    }
+
+    // adjust to the next row of mbs
+    vp8_extend_mb_row(
+        &pc->new_frame,
+        xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8
+    );
+
+    ++xd->mode_info_context;      /* skip prediction column */
+
+    pbi->last_mb_row_decoded = mb_row;
+}
+
+
+static unsigned int read_partition_size(const unsigned char *cx_size)
+{
+    const unsigned int size =
+        cx_size[0] + (cx_size[1] << 8) + (cx_size[2] << 16);
+    return size;
+}
+
+
+static void setup_token_decoder(VP8D_COMP *pbi,
+                                const unsigned char *cx_data)
+{
+    int num_part;
+    int i;
+    VP8_COMMON          *pc = &pbi->common;
+    const unsigned char *user_data_end = pbi->Source + pbi->source_sz;
+    vp8_reader          *bool_decoder;
+    const unsigned char *partition;
+
+    /* Parse number of token partitions to use */
+    pc->multi_token_partition = (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
+    num_part = 1 << pc->multi_token_partition;
+
+    /* Set up pointers to the first partition */
+    partition = cx_data;
+    bool_decoder = &pbi->bc2;
+
+    if (num_part > 1)
+    {
+        CHECK_MEM_ERROR(pbi->mbc, vpx_malloc(num_part * sizeof(vp8_reader)));
+        bool_decoder = pbi->mbc;
+        partition += 3 * (num_part - 1);
+    }
+
+    for (i = 0; i < num_part; i++)
+    {
+        const unsigned char *partition_size_ptr = cx_data + i * 3;
+        unsigned int         partition_size;
+
+        /* Calculate the length of this partition. The last partition
+         * size is implicit.
+         */
+        if (i < num_part - 1)
+        {
+            partition_size = read_partition_size(partition_size_ptr);
+        }
+        else
+        {
+            partition_size = user_data_end - partition;
+        }
+
+        if (partition + partition_size > user_data_end)
+            vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                               "Truncated packet or corrupt partition "
+                               "%d length", i + 1);
+
+        if (vp8dx_start_decode(bool_decoder, IF_RTCD(&pbi->dboolhuff),
+                               partition, partition_size))
+            vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
+                               "Failed to allocate bool decoder %d", i + 1);
+
+        /* Advance to the next partition */
+        partition += partition_size;
+        bool_decoder++;
+    }
+
+    /* Clamp number of decoder threads */
+    if (pbi->decoding_thread_count > num_part - 1)
+        pbi->decoding_thread_count = num_part - 1;
+}
+
+
+static void stop_token_decoder(VP8D_COMP *pbi)
+{
+    int i;
+    VP8_COMMON *pc = &pbi->common;
+
+    if (pc->multi_token_partition != ONE_PARTITION)
+    {
+        int num_part = (1 << pc->multi_token_partition);
+
+        for (i = 0; i < num_part; i++)
+        {
+            vp8dx_stop_decode(&pbi->mbc[i]);
+        }
+
+        vpx_free(pbi->mbc);
+    }
+    else
+        vp8dx_stop_decode(& pbi->bc2);
+}
+
+static void init_frame(VP8D_COMP *pbi)
+{
+    VP8_COMMON *const pc = & pbi->common;
+    MACROBLOCKD *const xd  = & pbi->mb;
+
+    if (pc->frame_type == KEY_FRAME)
+    {
+        // Various keyframe initializations
+        vpx_memcpy(pc->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
+
+        vp8_init_mbmode_probs(pc);
+
+        vp8_default_coef_probs(pc);
+        vp8_kf_default_bmode_probs(pc->kf_bmode_prob);
+
+        // reset the segment feature data to 0 with delta coding (Default state).
+        vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
+        xd->mb_segement_abs_delta = SEGMENT_DELTADATA;
+
+       // reset the mode ref deltasa for loop filter
+        vpx_memset(xd->ref_lf_deltas, 0, sizeof(xd->ref_lf_deltas));
+        vpx_memset(xd->mode_lf_deltas, 0, sizeof(xd->mode_lf_deltas));
+
+        // All buffers are implicitly updated on key frames.
+        pc->refresh_golden_frame = 1;
+        pc->refresh_alt_ref_frame = 1;
+        pc->copy_buffer_to_gf = 0;
+        pc->copy_buffer_to_arf = 0;
+
+        // Note that Golden and Altref modes cannot be used on a key frame so
+        // ref_frame_sign_bias[] is undefined and meaningless
+        pc->ref_frame_sign_bias[GOLDEN_FRAME] = 0;
+        pc->ref_frame_sign_bias[ALTREF_FRAME] = 0;
+    }
+    else
+    {
+        if (!pc->use_bilinear_mc_filter)
+            pc->mcomp_filter_type = SIXTAP;
+        else
+            pc->mcomp_filter_type = BILINEAR;
+
+        // To enable choice of different interploation filters
+        if (pc->mcomp_filter_type == SIXTAP)
+        {
+            xd->subpixel_predict      = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap4x4);
+            xd->subpixel_predict8x4   = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x4);
+            xd->subpixel_predict8x8   = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x8);
+            xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap16x16);
+        }
+        else
+        {
+            xd->subpixel_predict      = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear4x4);
+            xd->subpixel_predict8x4   = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x4);
+            xd->subpixel_predict8x8   = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x8);
+            xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear16x16);
+        }
+    }
+
+    xd->left_context = pc->left_context;
+    xd->mode_info_context = pc->mi;
+    xd->frame_type = pc->frame_type;
+    xd->mbmi.mode = DC_PRED;
+    xd->mode_info_stride = pc->mode_info_stride;
+}
+
+int vp8_decode_frame(VP8D_COMP *pbi)
+{
+    vp8_reader *const bc = & pbi->bc;
+    VP8_COMMON *const pc = & pbi->common;
+    MACROBLOCKD *const xd  = & pbi->mb;
+    const unsigned char *data = (const unsigned char *)pbi->Source;
+    const unsigned char *const data_end = data + pbi->source_sz;
+    int first_partition_length_in_bytes;
+
+    int mb_row;
+    int i, j, k, l;
+    const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
+
+    pc->frame_type = (FRAME_TYPE)(data[0] & 1);
+    pc->version = (data[0] >> 1) & 7;
+    pc->show_frame = (data[0] >> 4) & 1;
+    first_partition_length_in_bytes =
+        (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
+    data += 3;
+
+    if (data + first_partition_length_in_bytes > data_end)
+        vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                           "Truncated packet or corrupt partition 0 length");
+    vp8_setup_version(pc);
+
+    if (pc->frame_type == KEY_FRAME)
+    {
+        const int Width = pc->Width;
+        const int Height = pc->Height;
+
+        // vet via sync code
+        if (data[0] != 0x9d || data[1] != 0x01 || data[2] != 0x2a)
+            vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM,
+                               "Invalid frame sync code");
+
+        pc->Width = (data[3] | (data[4] << 8)) & 0x3fff;
+        pc->horiz_scale = data[4] >> 6;
+        pc->Height = (data[5] | (data[6] << 8)) & 0x3fff;
+        pc->vert_scale = data[6] >> 6;
+        data += 7;
+
+        if (Width != pc->Width  ||  Height != pc->Height)
+        {
+            if (pc->Width <= 0)
+            {
+                pc->Width = Width;
+                vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                                   "Invalid frame width");
+            }
+
+            if (pc->Height <= 0)
+            {
+                pc->Height = Height;
+                vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                                   "Invalid frame height");
+            }
+
+            if (vp8_alloc_frame_buffers(&pbi->common, pc->Width, pc->Height))
+                vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
+                                   "Failed to allocate frame buffers");
+        }
+    }
+
+    if (pc->Width == 0 || pc->Height == 0)
+    {
+        return -1;
+    }
+
+    init_frame(pbi);
+
+    if (vp8dx_start_decode(bc, IF_RTCD(&pbi->dboolhuff),
+                           data, data_end - data))
+        vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
+                           "Failed to allocate bool decoder 0");
+    if (pc->frame_type == KEY_FRAME) {
+        pc->clr_type    = (YUV_TYPE)vp8_read_bit(bc);
+        pc->clamp_type  = (CLAMP_TYPE)vp8_read_bit(bc);
+    }
+
+    // Is segmentation enabled
+    xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc);
+
+    if (xd->segmentation_enabled)
+    {
+        // Signal whether or not the segmentation map is being explicitly updated this frame.
+        xd->update_mb_segmentation_map = (unsigned char)vp8_read_bit(bc);
+        xd->update_mb_segmentation_data = (unsigned char)vp8_read_bit(bc);
+
+        if (xd->update_mb_segmentation_data)
+        {
+            xd->mb_segement_abs_delta = (unsigned char)vp8_read_bit(bc);
+
+            vpx_memset(xd->segment_feature_data, 0, sizeof(xd->segment_feature_data));
+
+            // For each segmentation feature (Quant and loop filter level)
+            for (i = 0; i < MB_LVL_MAX; i++)
+            {
+                for (j = 0; j < MAX_MB_SEGMENTS; j++)
+                {
+                    // Frame level data
+                    if (vp8_read_bit(bc))
+                    {
+                        xd->segment_feature_data[i][j] = (signed char)vp8_read_literal(bc, mb_feature_data_bits[i]);
+
+                        if (vp8_read_bit(bc))
+                            xd->segment_feature_data[i][j] = -xd->segment_feature_data[i][j];
+                    }
+                    else
+                        xd->segment_feature_data[i][j] = 0;
+                }
+            }
+        }
+
+        if (xd->update_mb_segmentation_map)
+        {
+            // Which macro block level features are enabled
+            vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
+
+            // Read the probs used to decode the segment id for each macro block.
+            for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+            {
+                // If not explicitly set value is defaulted to 255 by memset above
+                if (vp8_read_bit(bc))
+                    xd->mb_segment_tree_probs[i] = (vp8_prob)vp8_read_literal(bc, 8);
+            }
+        }
+    }
+
+    // Read the loop filter level and type
+    pc->filter_type = (LOOPFILTERTYPE) vp8_read_bit(bc);
+    pc->filter_level = vp8_read_literal(bc, 6);
+    pc->sharpness_level = vp8_read_literal(bc, 3);
+
+    // Read in loop filter deltas applied at the MB level based on mode or ref frame.
+    xd->mode_ref_lf_delta_update = 0;
+    xd->mode_ref_lf_delta_enabled = (unsigned char)vp8_read_bit(bc);
+
+    if (xd->mode_ref_lf_delta_enabled)
+    {
+        // Do the deltas need to be updated
+        xd->mode_ref_lf_delta_update = (unsigned char)vp8_read_bit(bc);
+
+        if (xd->mode_ref_lf_delta_update)
+        {
+            // Send update
+            for (i = 0; i < MAX_REF_LF_DELTAS; i++)
+            {
+                if (vp8_read_bit(bc))
+                {
+                    //sign = vp8_read_bit( bc );
+                    xd->ref_lf_deltas[i] = (signed char)vp8_read_literal(bc, 6);
+
+                    if (vp8_read_bit(bc))        // Apply sign
+                        xd->ref_lf_deltas[i] = xd->ref_lf_deltas[i] * -1;
+                }
+            }
+
+            // Send update
+            for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
+            {
+                if (vp8_read_bit(bc))
+                {
+                    //sign = vp8_read_bit( bc );
+                    xd->mode_lf_deltas[i] = (signed char)vp8_read_literal(bc, 6);
+
+                    if (vp8_read_bit(bc))        // Apply sign
+                        xd->mode_lf_deltas[i] = xd->mode_lf_deltas[i] * -1;
+                }
+            }
+        }
+    }
+
+    setup_token_decoder(pbi, data + first_partition_length_in_bytes);
+    xd->current_bc = &pbi->bc2;
+
+    // Read the default quantizers.
+    {
+        int Q, q_update;
+
+        Q = vp8_read_literal(bc, 7);  // AC 1st order Q = default
+        pc->base_qindex = Q;
+        q_update = 0;
+        pc->y1dc_delta_q = get_delta_q(bc, pc->y1dc_delta_q, &q_update);
+        pc->y2dc_delta_q = get_delta_q(bc, pc->y2dc_delta_q, &q_update);
+        pc->y2ac_delta_q = get_delta_q(bc, pc->y2ac_delta_q, &q_update);
+        pc->uvdc_delta_q = get_delta_q(bc, pc->uvdc_delta_q, &q_update);
+        pc->uvac_delta_q = get_delta_q(bc, pc->uvac_delta_q, &q_update);
+
+        if (q_update)
+            vp8cx_init_de_quantizer(pbi);
+
+        // MB level dequantizer setup
+        mb_init_dequantizer(pbi, &pbi->mb);
+    }
+
+    // Determine if the golden frame or ARF buffer should be updated and how.
+    // For all non key frames the GF and ARF refresh flags and sign bias
+    // flags must be set explicitly.
+    if (pc->frame_type != KEY_FRAME)
+    {
+        // Should the GF or ARF be updated from the current frame
+        pc->refresh_golden_frame = vp8_read_bit(bc);
+        pc->refresh_alt_ref_frame = vp8_read_bit(bc);
+
+        // Buffer to buffer copy flags.
+        pc->copy_buffer_to_gf = 0;
+
+        if (!pc->refresh_golden_frame)
+            pc->copy_buffer_to_gf = vp8_read_literal(bc, 2);
+
+        pc->copy_buffer_to_arf = 0;
+
+        if (!pc->refresh_alt_ref_frame)
+            pc->copy_buffer_to_arf = vp8_read_literal(bc, 2);
+
+        pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp8_read_bit(bc);
+        pc->ref_frame_sign_bias[ALTREF_FRAME] = vp8_read_bit(bc);
+    }
+
+    pc->refresh_entropy_probs = vp8_read_bit(bc);
+    if (pc->refresh_entropy_probs == 0)
+    {
+        vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
+    }
+
+    pc->refresh_last_frame = pc->frame_type == KEY_FRAME  ||  vp8_read_bit(bc);
+
+    if (0)
+    {
+        FILE *z = fopen("decodestats.stt", "a");
+        fprintf(z, "%6d F:%d,G:%d,A:%d,L:%d,Q:%d\n",
+                pc->current_video_frame,
+                pc->frame_type,
+                pc->refresh_golden_frame,
+                pc->refresh_alt_ref_frame,
+                pc->refresh_last_frame,
+                pc->base_qindex);
+        fclose(z);
+    }
+
+
+    vp8dx_bool_decoder_fill(bc);
+    {
+        // read coef probability tree
+
+        for (i = 0; i < BLOCK_TYPES; i++)
+            for (j = 0; j < COEF_BANDS; j++)
+                for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+                    for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++)
+                    {
+
+                        vp8_prob *const p = pc->fc.coef_probs [i][j][k] + l;
+
+                        if (vp8_read(bc, vp8_coef_update_probs [i][j][k][l]))
+                        {
+                            *p = (vp8_prob)vp8_read_literal(bc, 8);
+
+                        }
+                    }
+    }
+
+    vpx_memcpy(&xd->pre, &pc->last_frame, sizeof(YV12_BUFFER_CONFIG));
+    vpx_memcpy(&xd->dst, &pc->new_frame, sizeof(YV12_BUFFER_CONFIG));
+
+    // set up frame new frame for intra coded blocks
+    vp8_setup_intra_recon(&pc->new_frame);
+
+    vp8_setup_block_dptrs(xd);
+
+    vp8_build_block_doffsets(xd);
+
+    // clear out the coeff buffer
+    vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
+
+    // Read the mb_no_coeff_skip flag
+    pc->mb_no_coeff_skip = (int)vp8_read_bit(bc);
+
+    if (pc->frame_type == KEY_FRAME)
+        vp8_kfread_modes(pbi);
+    else
+        vp8_decode_mode_mvs(pbi);
+
+    // reset since these guys are used as iterators
+    vpx_memset(pc->above_context[Y1CONTEXT], 0, sizeof(ENTROPY_CONTEXT) * pc->mb_cols * 4);
+    vpx_memset(pc->above_context[UCONTEXT ], 0, sizeof(ENTROPY_CONTEXT) * pc->mb_cols * 2);
+    vpx_memset(pc->above_context[VCONTEXT ], 0, sizeof(ENTROPY_CONTEXT) * pc->mb_cols * 2);
+    vpx_memset(pc->above_context[Y2CONTEXT], 0, sizeof(ENTROPY_CONTEXT) * pc->mb_cols);
+
+    xd->gf_active_ptr = (signed char *)pc->gf_active_flags;     // Point to base of GF active flags data structure
+
+
+    vpx_memcpy(&xd->block[0].bmi, &xd->mode_info_context->bmi[0], sizeof(B_MODE_INFO));
+
+
+    if (pbi->b_multithreaded_lf && pbi->common.filter_level != 0)
+        vp8_start_lfthread(pbi);
+
+    if (pbi->b_multithreaded_rd && pbi->common.multi_token_partition != ONE_PARTITION)
+    {
+        vp8_mtdecode_mb_rows(pbi, xd);
+    }
+    else
+    {
+        int ibc = 0;
+        int num_part = 1 << pbi->common.multi_token_partition;
+
+        // Decode the individual macro block
+        for (mb_row = 0; mb_row < pc->mb_rows; mb_row++)
+        {
+
+            if (num_part > 1)
+            {
+                xd->current_bc = & pbi->mbc[ibc];
+                ibc++;
+
+                if (ibc == num_part)
+                    ibc = 0;
+            }
+
+            vp8_decode_mb_row(pbi, pc, mb_row, xd);
+        }
+
+        pbi->last_mb_row_decoded = mb_row;
+    }
+
+
+    stop_token_decoder(pbi);
+
+    vp8dx_stop_decode(bc);
+
+    // vpx_log("Decoder: Frame Decoded, Size Roughly:%d bytes  \n",bc->pos+pbi->bc2.pos);
+
+    // If this was a kf or Gf note the Q used
+    if ((pc->frame_type == KEY_FRAME) || (pc->refresh_golden_frame) || pbi->common.refresh_alt_ref_frame)
+        pc->last_kf_gf_q = pc->base_qindex;
+
+    if (pc->refresh_entropy_probs == 0)
+    {
+        vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
+    }
+
+#ifdef PACKET_TESTING
+    {
+        FILE *f = fopen("decompressor.VP8", "ab");
+        unsigned int size = pbi->bc2.pos + pbi->bc.pos + 8;
+        fwrite((void *) &size, 4, 1, f);
+        fwrite((void *) pbi->Source, size, 1, f);
+        fclose(f);
+    }
+#endif
+
+    return 0;
+}
diff --git a/vp8/decoder/demode.c b/vp8/decoder/demode.c
new file mode 100644 (file)
index 0000000..fd05e6d
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxd_int.h"
+#include "entropymode.h"
+#include "findnearmv.h"
+
+
+int vp8_read_bmode(vp8_reader *bc, const vp8_prob *p)
+{
+    const int i = vp8_treed_read(bc, vp8_bmode_tree, p);
+
+    return i;
+}
+
+
+int vp8_read_ymode(vp8_reader *bc, const vp8_prob *p)
+{
+    const int i = vp8_treed_read(bc, vp8_ymode_tree, p);
+
+    return i;
+}
+
+int vp8_kfread_ymode(vp8_reader *bc, const vp8_prob *p)
+{
+    const int i = vp8_treed_read(bc, vp8_kf_ymode_tree, p);
+
+    return i;
+}
+
+
+
+int vp8_read_uv_mode(vp8_reader *bc, const vp8_prob *p)
+{
+    const int i = vp8_treed_read(bc, vp8_uv_mode_tree, p);
+
+    return i;
+}
+
+void vp8_read_mb_features(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x)
+{
+    // Is segmentation enabled
+    if (x->segmentation_enabled && x->update_mb_segmentation_map)
+    {
+        // If so then read the segment id.
+        if (vp8_read(r, x->mb_segment_tree_probs[0]))
+            mi->segment_id = (unsigned char)(2 + vp8_read(r, x->mb_segment_tree_probs[2]));
+        else
+            mi->segment_id = (unsigned char)(vp8_read(r, x->mb_segment_tree_probs[1]));
+    }
+}
+
+void vp8_kfread_modes(VP8D_COMP *pbi)
+{
+    VP8_COMMON *const cp = & pbi->common;
+    vp8_reader *const bc = & pbi->bc;
+
+    MODE_INFO *m = cp->mi;
+    const int ms = cp->mode_info_stride;
+
+    int mb_row = -1;
+    vp8_prob prob_skip_false = 0;
+
+    if (cp->mb_no_coeff_skip)
+        prob_skip_false = (vp8_prob)(vp8_read_literal(bc, 8));
+
+    while (++mb_row < cp->mb_rows)
+    {
+        int mb_col = -1;
+
+        while (++mb_col < cp->mb_cols)
+        {
+            MB_PREDICTION_MODE y_mode;
+
+            vp8dx_bool_decoder_fill(bc);
+            // Read the Macroblock segmentation map if it is being updated explicitly this frame (reset to 0 above by default)
+            // By default on a key frame reset all MBs to segment 0
+            m->mbmi.segment_id = 0;
+
+            if (pbi->mb.update_mb_segmentation_map)
+                vp8_read_mb_features(bc, &m->mbmi, &pbi->mb);
+
+            // Read the macroblock coeff skip flag if this feature is in use, else default to 0
+            if (cp->mb_no_coeff_skip)
+                m->mbmi.mb_skip_coeff = vp8_read(bc, prob_skip_false);
+            else
+                m->mbmi.mb_skip_coeff = 0;
+
+            y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc, cp->kf_ymode_prob);
+
+            m->mbmi.ref_frame = INTRA_FRAME;
+
+            if ((m->mbmi.mode = y_mode) == B_PRED)
+            {
+                int i = 0;
+
+                do
+                {
+                    const B_PREDICTION_MODE A = vp8_above_bmi(m, i, ms)->mode;
+                    const B_PREDICTION_MODE L = vp8_left_bmi(m, i)->mode;
+
+                    m->bmi[i].mode = (B_PREDICTION_MODE) vp8_read_bmode(bc, cp->kf_bmode_prob [A] [L]);
+                }
+                while (++i < 16);
+            }
+            else
+            {
+                int BMode;
+                int i = 0;
+
+                switch (y_mode)
+                {
+                case DC_PRED:
+                    BMode = B_DC_PRED;
+                    break;
+                case V_PRED:
+                    BMode = B_VE_PRED;
+                    break;
+                case H_PRED:
+                    BMode = B_HE_PRED;
+                    break;
+                case TM_PRED:
+                    BMode = B_TM_PRED;
+                    break;
+                default:
+                    BMode = B_DC_PRED;
+                    break;
+                }
+
+                do
+                {
+                    m->bmi[i].mode = (B_PREDICTION_MODE)BMode;
+                }
+                while (++i < 16);
+            }
+
+            (m++)->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, cp->kf_uv_mode_prob);
+        }
+
+        m++; // skip the border
+    }
+}
diff --git a/vp8/decoder/demode.h b/vp8/decoder/demode.h
new file mode 100644 (file)
index 0000000..51bbc5e
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxd_int.h"
+
+/* Read (intra) modes for all blocks in a keyframe */
+
+void vp8_kfread_modes(VP8D_COMP *pbi);
+
+/* Intra mode for a Y subblock */
+
+int vp8_read_bmode(vp8_reader *, const vp8_prob *);
+
+/* MB intra Y mode trees differ for key and inter frames. */
+
+int   vp8_read_ymode(vp8_reader *, const vp8_prob *);
+int vp8_kfread_ymode(vp8_reader *, const vp8_prob *);
+
+/* MB intra UV mode trees are the same for key and inter frames. */
+
+int vp8_read_uv_mode(vp8_reader *, const vp8_prob *);
+
+/* Read any macroblock-level features that may be present. */
+
+void vp8_read_mb_features(vp8_reader *, MB_MODE_INFO *, MACROBLOCKD *);
diff --git a/vp8/decoder/dequantize.c b/vp8/decoder/dequantize.c
new file mode 100644 (file)
index 0000000..14798d9
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "dequantize.h"
+#include "predictdc.h"
+#include "idct.h"
+#include "vpx_mem/vpx_mem.h"
+
+extern void vp8_short_idct4x4llm_c(short *input, short *output, int pitch) ;
+extern void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch);
+
+
+void vp8_dequantize_b_c(BLOCKD *d)
+{
+    int i;
+    short *DQ  = d->dqcoeff;
+    short *Q   = d->qcoeff;
+    short *DQC = &d->dequant[0][0];
+
+    for (i = 0; i < 16; i++)
+    {
+        DQ[i] = Q[i] * DQC[i];
+    }
+}
+
+void vp8_dequant_idct_c(short *input, short *dq, short *output, int pitch)
+{
+    int i;
+
+    for (i = 0; i < 16; i++)
+    {
+        input[i] = dq[i] * input[i];
+    }
+
+    vp8_short_idct4x4llm_c(input, output, pitch);
+    vpx_memset(input, 0, 32);
+}
+
+void vp8_dequant_dc_idct_c(short *input, short *dq, short *output, int pitch, int Dc)
+{
+    int i;
+
+    input[0] = (short)Dc;
+
+    for (i = 1; i < 16; i++)
+    {
+        input[i] = dq[i] * input[i];
+    }
+
+    vp8_short_idct4x4llm_c(input, output, pitch);
+    vpx_memset(input, 0, 32);
+}
diff --git a/vp8/decoder/dequantize.h b/vp8/decoder/dequantize.h
new file mode 100644 (file)
index 0000000..d16b02e
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef DEQUANTIZE_H
+#define DEQUANTIZE_H
+#include "blockd.h"
+
+#define prototype_dequant_block(sym) \
+    void sym(BLOCKD *x)
+
+#define prototype_dequant_idct(sym) \
+    void sym(short *input, short *dq, short *output, int pitch)
+
+#define prototype_dequant_idct_dc(sym) \
+    void sym(short *input, short *dq, short *output, int pitch, int dc)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/dequantize_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/dequantize_arm.h"
+#endif
+
+#ifndef vp8_dequant_block
+#define vp8_dequant_block vp8_dequantize_b_c
+#endif
+extern prototype_dequant_block(vp8_dequant_block);
+
+#ifndef vp8_dequant_idct
+#define vp8_dequant_idct vp8_dequant_idct_c
+#endif
+extern prototype_dequant_idct(vp8_dequant_idct);
+
+#ifndef vp8_dequant_idct_dc
+#define vp8_dequant_idct_dc vp8_dequant_dc_idct_c
+#endif
+extern prototype_dequant_idct_dc(vp8_dequant_idct_dc);
+
+
+typedef prototype_dequant_block((*vp8_dequant_block_fn_t));
+typedef prototype_dequant_idct((*vp8_dequant_idct_fn_t));
+typedef prototype_dequant_idct_dc((*vp8_dequant_idct_dc_fn_t));
+typedef struct
+{
+    vp8_dequant_block_fn_t    block;
+    vp8_dequant_idct_fn_t     idct;
+    vp8_dequant_idct_dc_fn_t  idct_dc;
+} vp8_dequant_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define DEQUANT_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define DEQUANT_INVOKE(ctx,fn) vp8_dequant_##fn
+#endif
+
+#endif
diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c
new file mode 100644 (file)
index 0000000..a42f18d
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "type_aliases.h"
+#include "blockd.h"
+#include "onyxd_int.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_ports/mem.h"
+
+#define BR_COUNT 8
+#define BOOL_DATA UINT8
+
+#define OCB_X PREV_COEF_CONTEXTS * ENTROPY_NODES
+DECLARE_ALIGNED(16, UINT16, vp8_coef_bands_x[16]) = { 0, 1 * OCB_X, 2 * OCB_X, 3 * OCB_X, 6 * OCB_X, 4 * OCB_X, 5 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 6 * OCB_X, 7 * OCB_X};
+#define EOB_CONTEXT_NODE            0
+#define ZERO_CONTEXT_NODE           1
+#define ONE_CONTEXT_NODE            2
+#define LOW_VAL_CONTEXT_NODE        3
+#define TWO_CONTEXT_NODE            4
+#define THREE_CONTEXT_NODE          5
+#define HIGH_LOW_CONTEXT_NODE       6
+#define CAT_ONE_CONTEXT_NODE        7
+#define CAT_THREEFOUR_CONTEXT_NODE  8
+#define CAT_THREE_CONTEXT_NODE      9
+#define CAT_FIVE_CONTEXT_NODE       10
+
+/*
+//the definition is put in "onyxd_int.h"
+typedef struct
+{
+    INT16         min_val;
+    INT16         Length;
+    UINT8 Probs[12];
+} TOKENEXTRABITS;
+*/
+
+DECLARE_ALIGNED(16, static const TOKENEXTRABITS, vp8d_token_extra_bits2[MAX_ENTROPY_TOKENS]) =
+{
+    {  0, -1, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },  //ZERO_TOKEN
+    {  1, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //ONE_TOKEN
+    {  2, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //TWO_TOKEN
+    {  3, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //THREE_TOKEN
+    {  4, 0, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },   //FOUR_TOKEN
+    {  5, 0, { 159, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },  //DCT_VAL_CATEGORY1
+    {  7, 1, { 145, 165, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY2
+    { 11, 2, { 140, 148, 173, 0,  0,  0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY3
+    { 19, 3, { 135, 140, 155, 176, 0,  0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY4
+    { 35, 4, { 130, 134, 141, 157, 180, 0,  0,  0,  0,  0,  0,  0   } }, //DCT_VAL_CATEGORY5
+    { 67, 10, { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254, 0   } }, //DCT_VAL_CATEGORY6
+    {  0, -1, { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   } },  // EOB TOKEN
+};
+
+
+void vp8_reset_mb_tokens_context(MACROBLOCKD *x)
+{
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+
+    ENTROPY_CONTEXT *a;
+    ENTROPY_CONTEXT *l;
+    int i;
+
+    for (i = 0; i < 24; i++)
+    {
+
+        a = A[ vp8_block2context[i] ] + vp8_block2above[i];
+        l = L[ vp8_block2context[i] ] + vp8_block2left[i];
+
+        *a = *l = 0;
+    }
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        a = A[Y2CONTEXT] + vp8_block2above[24];
+        l = L[Y2CONTEXT] + vp8_block2left[24];
+        *a = *l = 0;
+    }
+
+
+}
+DECLARE_ALIGNED(16, extern const unsigned int, vp8dx_bitreader_norm[256]);
+#define NORMALIZE \
+    /*if(range < 0x80)*/                            \
+    { \
+        shift = vp8dx_bitreader_norm[range]; \
+        range <<= shift; \
+        value <<= shift; \
+        count -= shift; \
+        if(count <= 0) \
+        { \
+            count += BR_COUNT ; \
+            value |= (*bufptr) << (BR_COUNT-count); \
+            bufptr = br_ptr_advance(bufptr, 1); \
+        } \
+    }
+
+#define DECODE_AND_APPLYSIGN(value_to_sign) \
+    split = (range + 1) >> 1; \
+    if ( (value >> 8) < split ) \
+    { \
+        range = split; \
+        v= value_to_sign; \
+    } \
+    else \
+    { \
+        range = range-split; \
+        value = value-(split<<8); \
+        v = -value_to_sign; \
+    } \
+    range +=range;                   \
+    value +=value;                   \
+    if (!--count) \
+    { \
+        count = BR_COUNT; \
+        value |= *bufptr; \
+        bufptr = br_ptr_advance(bufptr, 1); \
+    }
+
+#define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \
+    { \
+        split = 1 +  ((( probability*(range-1) ) )>> 8); \
+        if ( (value >> 8) < split ) \
+        { \
+            range = split; \
+            NORMALIZE \
+            goto branch; \
+        } \
+        value -= (split<<8); \
+        range = range - split; \
+        NORMALIZE \
+    }
+
+#define DECODE_AND_LOOP_IF_ZERO(probability,branch) \
+    { \
+        split = 1 + ((( probability*(range-1) ) ) >> 8); \
+        if ( (value >> 8) < split ) \
+        { \
+            range = split; \
+            NORMALIZE \
+            Prob = coef_probs; \
+            if(c<15) {\
+            ++c; \
+            Prob += vp8_coef_bands_x[c]; \
+            goto branch; \
+            } goto BLOCK_FINISHED; /*for malformed input */\
+        } \
+        value -= (split<<8); \
+        range = range - split; \
+        NORMALIZE \
+    }
+
+#define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \
+    DECODE_AND_APPLYSIGN(val) \
+    Prob = coef_probs + (ENTROPY_NODES*2); \
+    if(c < 15){\
+        qcoeff_ptr [ scan[c] ] = (INT16) v; \
+        ++c; \
+        goto DO_WHILE; }\
+    qcoeff_ptr [ scan[15] ] = (INT16) v; \
+    goto BLOCK_FINISHED;
+
+
+#define DECODE_EXTRABIT_AND_ADJUST_VAL(t,bits_count)\
+    split = 1 +  (((range-1) * vp8d_token_extra_bits2[t].Probs[bits_count]) >> 8); \
+    if(value >= (split<<8))\
+    {\
+        range = range-split;\
+        value = value-(split<<8);\
+        val += ((UINT16)1<<bits_count);\
+    }\
+    else\
+    {\
+        range = split;\
+    }\
+    NORMALIZE
+
+int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x)
+{
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+    const VP8_COMMON *const oc = & dx->common;
+
+    BOOL_DECODER *bc = x->current_bc;
+
+    ENTROPY_CONTEXT *a;
+    ENTROPY_CONTEXT *l;
+    int i;
+
+    int eobtotal = 0;
+
+    register int count;
+
+    const BOOL_DATA *bufptr;
+    register unsigned int range;
+    register unsigned int value;
+    const int *scan;
+    register unsigned int shift;
+    UINT32 split;
+    INT16 *qcoeff_ptr;
+
+    const vp8_prob *coef_probs;
+    int type;
+    int stop;
+    INT16 val, bits_count;
+    INT16 c;
+    INT16 t;
+    INT16 v;
+    const vp8_prob *Prob;
+
+    //int *scan;
+    type = 3;
+    i = 0;
+    stop = 16;
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        i = 24;
+        stop = 24;
+        type = 1;
+        qcoeff_ptr = &x->qcoeff[24*16];
+        scan = vp8_default_zig_zag1d;
+        eobtotal -= 16;
+    }
+    else
+    {
+        scan = vp8_default_zig_zag1d;
+        qcoeff_ptr = &x->qcoeff[0];
+    }
+
+    count   = bc->count;
+    range   = bc->range;
+    value   = bc->value;
+    bufptr  = bc->read_ptr;
+
+
+    coef_probs = oc->fc.coef_probs [type] [ 0 ] [0];
+
+BLOCK_LOOP:
+    a = A[ vp8_block2context[i] ] + vp8_block2above[i];
+    l = L[ vp8_block2context[i] ] + vp8_block2left[i];
+    c = (INT16)(!type);
+
+    VP8_COMBINEENTROPYCONTEXTS(t, *a, *l);
+    Prob = coef_probs;
+    Prob += t * ENTROPY_NODES;
+
+DO_WHILE:
+    Prob += vp8_coef_bands_x[c];
+    DECODE_AND_BRANCH_IF_ZERO(Prob[EOB_CONTEXT_NODE], BLOCK_FINISHED);
+
+CHECK_0_:
+    DECODE_AND_LOOP_IF_ZERO(Prob[ZERO_CONTEXT_NODE], CHECK_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[ONE_CONTEXT_NODE], ONE_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[LOW_VAL_CONTEXT_NODE], LOW_VAL_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[HIGH_LOW_CONTEXT_NODE], HIGH_LOW_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREEFOUR_CONTEXT_NODE], CAT_THREEFOUR_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_FIVE_CONTEXT_NODE], CAT_FIVE_CONTEXT_NODE_0_);
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY6].min_val;
+    bits_count = vp8d_token_extra_bits2[DCT_VAL_CATEGORY6].Length;
+
+    do
+    {
+        DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY6, bits_count);
+        bits_count -- ;
+    }
+    while (bits_count >= 0);
+
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_FIVE_CONTEXT_NODE_0_:
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY5].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 4);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 3);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 2);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_THREEFOUR_CONTEXT_NODE_0_:
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_THREE_CONTEXT_NODE], CAT_THREE_CONTEXT_NODE_0_);
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY4].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 3);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 2);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_THREE_CONTEXT_NODE_0_:
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY3].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 2);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+HIGH_LOW_CONTEXT_NODE_0_:
+    DECODE_AND_BRANCH_IF_ZERO(Prob[CAT_ONE_CONTEXT_NODE], CAT_ONE_CONTEXT_NODE_0_);
+
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY2].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 1);
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+CAT_ONE_CONTEXT_NODE_0_:
+    val = vp8d_token_extra_bits2[DCT_VAL_CATEGORY1].min_val;
+    DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY1, 0);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val);
+
+LOW_VAL_CONTEXT_NODE_0_:
+    DECODE_AND_BRANCH_IF_ZERO(Prob[TWO_CONTEXT_NODE], TWO_CONTEXT_NODE_0_);
+    DECODE_AND_BRANCH_IF_ZERO(Prob[THREE_CONTEXT_NODE], THREE_CONTEXT_NODE_0_);
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(4);
+
+THREE_CONTEXT_NODE_0_:
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3);
+
+TWO_CONTEXT_NODE_0_:
+    DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2);
+
+ONE_CONTEXT_NODE_0_:
+    DECODE_AND_APPLYSIGN(1);
+    Prob = coef_probs + ENTROPY_NODES;
+
+    if (c < 15)
+    {
+        qcoeff_ptr [ scan[c] ] = (INT16) v;
+        ++c;
+        goto DO_WHILE;
+    }
+
+    qcoeff_ptr [ scan[15] ] = (INT16) v;
+BLOCK_FINISHED:
+    t = ((x->block[i].eob = c) != !type);   // any nonzero data?
+    eobtotal += x->block[i].eob;
+    *a = *l = t;
+    qcoeff_ptr += 16;
+
+    i++;
+
+    if (i < stop)
+        goto BLOCK_LOOP;
+
+    if (i == 25)
+    {
+        scan = vp8_default_zig_zag1d;//x->scan_order1d;
+        type = 0;
+        i = 0;
+        stop = 16;
+        coef_probs = oc->fc.coef_probs [type] [ 0 ] [0];
+        qcoeff_ptr = &x->qcoeff[0];
+        goto BLOCK_LOOP;
+    }
+
+    if (i == 16)
+    {
+        type = 2;
+        coef_probs = oc->fc.coef_probs [type] [ 0 ] [0];
+        stop = 24;
+        goto BLOCK_LOOP;
+    }
+
+    bc->count = count;
+    bc->value = value;
+    bc->range = range;
+    bc->read_ptr = bufptr;
+    return eobtotal;
+
+}
diff --git a/vp8/decoder/detokenize.h b/vp8/decoder/detokenize.h
new file mode 100644 (file)
index 0000000..6a9a476
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef detokenize_h
+#define detokenize_h 1
+
+#include "onyxd_int.h"
+
+void vp8_reset_mb_tokens_context(MACROBLOCKD *x);
+int vp8_decode_mb_tokens(VP8D_COMP *, MACROBLOCKD *);
+
+#endif /* detokenize_h */
diff --git a/vp8/decoder/generic/dsystemdependent.c b/vp8/decoder/generic/dsystemdependent.c
new file mode 100644 (file)
index 0000000..302b64b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "dequantize.h"
+#include "onyxd_int.h"
+
+extern void vp8_arch_x86_decode_init(VP8D_COMP *pbi);
+
+void vp8_dmachine_specific_config(VP8D_COMP *pbi)
+{
+    // Pure C:
+#if CONFIG_RUNTIME_CPU_DETECT
+    pbi->mb.rtcd         = &pbi->common.rtcd;
+    pbi->dequant.block   = vp8_dequantize_b_c;
+    pbi->dequant.idct    = vp8_dequant_idct_c;
+    pbi->dequant.idct_dc = vp8_dequant_dc_idct_c;
+    pbi->dboolhuff.start = vp8dx_start_decode_c;
+    pbi->dboolhuff.stop  = vp8dx_stop_decode_c;
+    pbi->dboolhuff.fill  = vp8dx_bool_decoder_fill_c;
+#if 0 //For use with RTCD, when implemented
+    pbi->dboolhuff.debool = vp8dx_decode_bool_c;
+    pbi->dboolhuff.devalue = vp8dx_decode_value_c;
+#endif
+#endif
+
+#if ARCH_X86 || ARCH_X86_64
+    vp8_arch_x86_decode_init(pbi);
+#endif
+}
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
new file mode 100644 (file)
index 0000000..6875585
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxc_int.h"
+#if CONFIG_POSTPROC
+#include "postproc.h"
+#endif
+#include "onyxd.h"
+#include "onyxd_int.h"
+#include "vpx_mem/vpx_mem.h"
+#include "alloccommon.h"
+#include "vpx_scale/yv12extend.h"
+#include "loopfilter.h"
+#include "swapyv12buffer.h"
+#include "g_common.h"
+#include "threading.h"
+#include "decoderthreading.h"
+#include <stdio.h>
+#include "segmentation_common.h"
+#include "quant_common.h"
+#include "vpx_scale/vpxscale.h"
+#include "systemdependent.h"
+#include "vpx_ports/vpx_timer.h"
+
+
+extern void vp8_init_loop_filter(VP8_COMMON *cm);
+
+extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
+
+// DEBUG code
+#if CONFIG_DEBUG
+void vp8_recon_write_yuv_frame(unsigned char *name, YV12_BUFFER_CONFIG *s)
+{
+    FILE *yuv_file = fopen((char *)name, "ab");
+    unsigned char *src = s->y_buffer;
+    int h = s->y_height;
+
+    do
+    {
+        fwrite(src, s->y_width, 1,  yuv_file);
+        src += s->y_stride;
+    }
+    while (--h);
+
+    src = s->u_buffer;
+    h = s->uv_height;
+
+    do
+    {
+        fwrite(src, s->uv_width, 1,  yuv_file);
+        src += s->uv_stride;
+    }
+    while (--h);
+
+    src = s->v_buffer;
+    h = s->uv_height;
+
+    do
+    {
+        fwrite(src, s->uv_width, 1, yuv_file);
+        src += s->uv_stride;
+    }
+    while (--h);
+
+    fclose(yuv_file);
+}
+#endif
+
+void vp8dx_initialize()
+{
+    static int init_done = 0;
+
+    if (!init_done)
+    {
+        vp8_initialize_common();
+        vp8_scale_machine_specific_config();
+        init_done = 1;
+    }
+}
+
+
+VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
+{
+    VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
+
+    if (!pbi)
+        return NULL;
+
+    vpx_memset(pbi, 0, sizeof(VP8D_COMP));
+
+    if (setjmp(pbi->common.error.jmp))
+    {
+        pbi->common.error.setjmp = 0;
+        vp8dx_remove_decompressor(pbi);
+        return 0;
+    }
+
+    pbi->common.error.setjmp = 1;
+    vp8dx_initialize();
+
+    vp8_create_common(&pbi->common);
+    vp8_dmachine_specific_config(pbi);
+
+    pbi->common.current_video_frame = 0;
+    pbi->ready_for_new_data = 1;
+
+    pbi->CPUFreq = 0; //vp8_get_processor_freq();
+    pbi->max_threads = oxcf->max_threads;
+    vp8_decoder_create_threads(pbi);
+
+    //vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
+    // unnecessary calling of vp8cx_init_de_quantizer() for every frame.
+    vp8cx_init_de_quantizer(pbi);
+
+    {
+        VP8_COMMON *cm = &pbi->common;
+
+        vp8_init_loop_filter(cm);
+        cm->last_frame_type = KEY_FRAME;
+        cm->last_filter_type = cm->filter_type;
+        cm->last_sharpness_level = cm->sharpness_level;
+    }
+
+    pbi->common.error.setjmp = 0;
+    return (VP8D_PTR) pbi;
+}
+
+
+void vp8dx_remove_decompressor(VP8D_PTR ptr)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+
+    if (!pbi)
+        return;
+
+    vp8_decoder_remove_threads(pbi);
+    vp8_remove_common(&pbi->common);
+    vpx_free(pbi);
+}
+
+
+void vp8dx_set_setting(VP8D_PTR comp, VP8D_SETTING oxst, int x)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) comp;
+
+    (void) pbi;
+    (void) x;
+
+    switch (oxst)
+    {
+    case VP8D_OK:
+        break;
+    }
+}
+
+int vp8dx_get_setting(VP8D_PTR comp, VP8D_SETTING oxst)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) comp;
+
+    (void) pbi;
+
+    switch (oxst)
+    {
+    case VP8D_OK:
+        break;
+    }
+
+    return -1;
+}
+
+int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+    VP8_COMMON *cm = &pbi->common;
+
+    if (ref_frame_flag == VP8_LAST_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->last_frame, sd);
+
+    else if (ref_frame_flag == VP8_GOLD_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->golden_frame, sd);
+
+    else if (ref_frame_flag == VP8_ALT_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, sd);
+
+    else
+        return -1;
+
+    return 0;
+}
+int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+    VP8_COMMON *cm = &pbi->common;
+
+    if (ref_frame_flag == VP8_LAST_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->last_frame);
+
+    else if (ref_frame_flag == VP8_GOLD_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->golden_frame);
+
+    else if (ref_frame_flag == VP8_ALT_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->alt_ref_frame);
+
+    else
+        return -1;
+
+    return 0;
+}
+
+//For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.
+#if HAVE_ARMV7
+extern void vp8_push_neon(INT64 *store);
+extern void vp8_pop_neon(INT64 *store);
+static INT64 dx_store_reg[8];
+#endif
+int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+    VP8_COMMON *cm = &pbi->common;
+    int retcode = 0;
+
+    struct vpx_usec_timer timer;
+
+//  if(pbi->ready_for_new_data == 0)
+//      return -1;
+
+    if (ptr == 0)
+    {
+        return -1;
+    }
+
+    pbi->common.error.error_code = VPX_CODEC_OK;
+
+    if (setjmp(pbi->common.error.jmp))
+    {
+        pbi->common.error.setjmp = 0;
+        return -1;
+    }
+
+    pbi->common.error.setjmp = 1;
+
+#if HAVE_ARMV7
+    vp8_push_neon(dx_store_reg);
+#endif
+
+    vpx_usec_timer_start(&timer);
+
+    //cm->current_video_frame++;
+    pbi->Source = source;
+    pbi->source_sz = size;
+
+    retcode = vp8_decode_frame(pbi);
+
+    if (retcode < 0)
+    {
+#if HAVE_ARMV7
+        vp8_pop_neon(dx_store_reg);
+#endif
+        pbi->common.error.error_code = VPX_CODEC_ERROR;
+        pbi->common.error.setjmp = 0;
+        return retcode;
+    }
+
+    // Update the GF useage maps.
+    vp8_update_gf_useage_maps(cm, &pbi->mb);
+
+    if (pbi->b_multithreaded_lf && pbi->common.filter_level != 0)
+        vp8_stop_lfthread(pbi);
+
+    if (cm->refresh_last_frame)
+    {
+        vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);
+
+        cm->frame_to_show = &cm->last_frame;
+    }
+    else
+    {
+        cm->frame_to_show = &cm->new_frame;
+    }
+
+    if (!pbi->b_multithreaded_lf)
+    {
+        struct vpx_usec_timer lpftimer;
+        vpx_usec_timer_start(&lpftimer);
+        // Apply the loop filter if appropriate.
+
+        if (cm->filter_level > 0)
+        {
+            vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
+            cm->last_frame_type = cm->frame_type;
+            cm->last_filter_type = cm->filter_type;
+            cm->last_sharpness_level = cm->sharpness_level;
+
+        }
+
+        vpx_usec_timer_mark(&lpftimer);
+        pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
+    }
+
+    vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
+
+#if 0
+    // DEBUG code
+    //vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
+    if (cm->current_video_frame <= 5)
+        write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
+#endif
+
+    // If any buffer copy / swaping is signalled it should be done here.
+    if (cm->copy_buffer_to_arf)
+    {
+        if (cm->copy_buffer_to_arf == 1)
+        {
+            if (cm->refresh_last_frame)
+                vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame);
+            else
+                vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame);
+        }
+        else if (cm->copy_buffer_to_arf == 2)
+            vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame);
+    }
+
+    if (cm->copy_buffer_to_gf)
+    {
+        if (cm->copy_buffer_to_gf == 1)
+        {
+            if (cm->refresh_last_frame)
+                vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->golden_frame);
+            else
+                vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
+        }
+        else if (cm->copy_buffer_to_gf == 2)
+            vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, &cm->golden_frame);
+    }
+
+    // Should the golden or alternate reference frame be refreshed?
+    if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
+    {
+        if (cm->refresh_golden_frame)
+            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);
+
+        if (cm->refresh_alt_ref_frame)
+            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);
+
+        //vpx_log("Decoder: recovery frame received \n");
+
+        // Update data structures that monitors GF useage
+        vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
+        cm->gf_active_count = cm->mb_rows * cm->mb_cols;
+    }
+
+    vp8_clear_system_state();
+
+    vpx_usec_timer_mark(&timer);
+    pbi->decode_microseconds = vpx_usec_timer_elapsed(&timer);
+
+    pbi->time_decoding += pbi->decode_microseconds;
+
+//  vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);
+
+    if (cm->show_frame)
+        cm->current_video_frame++;
+
+    pbi->ready_for_new_data = 0;
+    pbi->last_time_stamp = time_stamp;
+
+#if 0
+    {
+        int i;
+        INT64 earliest_time = pbi->dr[0].time_stamp;
+        INT64 latest_time = pbi->dr[0].time_stamp;
+        INT64 time_diff = 0;
+        int bytes = 0;
+
+        pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
+        pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;
+
+        for (i = 0; i < 16; i++)
+        {
+
+            bytes += pbi->dr[i].size;
+
+            if (pbi->dr[i].time_stamp < earliest_time)
+                earliest_time = pbi->dr[i].time_stamp;
+
+            if (pbi->dr[i].time_stamp > latest_time)
+                latest_time = pbi->dr[i].time_stamp;
+        }
+
+        time_diff = latest_time - earliest_time;
+
+        if (time_diff > 0)
+        {
+            pbi->common.bitrate = 80000.00 * bytes / time_diff  ;
+            pbi->common.framerate = 160000000.00 / time_diff ;
+        }
+
+    }
+#endif
+
+#if HAVE_ARMV7
+    vp8_pop_neon(dx_store_reg);
+#endif
+    pbi->common.error.setjmp = 0;
+    return retcode;
+}
+int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level,  int noise_level, int flags)
+{
+    int ret = -1;
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+
+    if (pbi->ready_for_new_data == 1)
+        return ret;
+
+    // ie no raw frame to show!!!
+    if (pbi->common.show_frame == 0)
+        return ret;
+
+    pbi->ready_for_new_data = 1;
+    *time_stamp = pbi->last_time_stamp;
+    *time_end_stamp = 0;
+
+    sd->clrtype = pbi->common.clr_type;
+#if CONFIG_POSTPROC
+    ret = vp8_post_proc_frame(&pbi->common, sd, deblock_level, noise_level, flags);
+#else
+
+    if (pbi->common.frame_to_show)
+    {
+        *sd = *pbi->common.frame_to_show;
+        sd->y_width = pbi->common.Width;
+        sd->y_height = pbi->common.Height;
+        sd->uv_height = pbi->common.Height / 2;
+        ret = 0;
+    }
+    else
+    {
+        ret = -1;
+    }
+
+#endif //!CONFIG_POSTPROC
+    vp8_clear_system_state();
+    return ret;
+}
diff --git a/vp8/decoder/onyxd_if_sjl.c b/vp8/decoder/onyxd_if_sjl.c
new file mode 100644 (file)
index 0000000..363ad5d
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxc_int.h"
+#include "postproc.h"
+#include "onyxd.h"
+#include "onyxd_int.h"
+#include "vpx_mem/vpx_mem.h"
+#include "alloccommon.h"
+#include "vpx_scale/yv12extend.h"
+#include "loopfilter.h"
+#include "swapyv12buffer.h"
+#include "g_common.h"
+#include "threading.h"
+#include "decoderthreading.h"
+#include <stdio.h>
+#include "segmentation_common.h"
+#include "quant_common.h"
+#include "vpx_scale/vpxscale.h"
+#include "systemdependent.h"
+#include "vpx_ports/vpx_timer.h"
+
+
+#ifndef VPX_NO_GLOBALS
+static int init_ct = 0;
+#else
+# include "vpx_global_handling.h"
+# define init_ct ((int)vpxglobalm(onyxd,init_ct))
+#endif
+
+extern void vp8_init_loop_filter(VP8_COMMON *cm);
+
+extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
+extern void init_detokenizer(VP8D_COMP *dx);
+
+// DEBUG code
+void vp8_recon_write_yuv_frame(unsigned char *name, YV12_BUFFER_CONFIG *s)
+{
+    FILE *yuv_file = fopen((char *)name, "ab");
+    unsigned char *src = s->y_buffer;
+    int h = s->y_height;
+
+    do
+    {
+        fwrite(src, s->y_width, 1,  yuv_file);
+        src += s->y_stride;
+    }
+    while (--h);
+
+    src = s->u_buffer;
+    h = s->uv_height;
+
+    do
+    {
+        fwrite(src, s->uv_width, 1,  yuv_file);
+        src += s->uv_stride;
+    }
+    while (--h);
+
+    src = s->v_buffer;
+    h = s->uv_height;
+
+    do
+    {
+        fwrite(src, s->uv_width, 1, yuv_file);
+        src += s->uv_stride;
+    }
+    while (--h);
+
+    fclose(yuv_file);
+}
+
+void vp8dx_initialize()
+{
+    if (!init_ct++)
+    {
+        vp8_initialize_common();
+        vp8_scale_machine_specific_config();
+    }
+}
+
+void vp8dx_shutdown()
+{
+    if (!--init_ct)
+    {
+        vp8_shutdown_common();
+    }
+}
+
+
+VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
+{
+    VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
+
+    if (!pbi)
+        return NULL;
+
+    vpx_memset(pbi, 0, sizeof(VP8D_COMP));
+
+    vp8dx_initialize();
+
+    vp8_create_common(&pbi->common);
+    vp8_dmachine_specific_config(pbi);
+
+    pbi->common.current_video_frame = 0;
+    pbi->ready_for_new_data = 1;
+
+    pbi->CPUFreq = 0; //vp8_get_processor_freq();
+    pbi->max_threads = oxcf->max_threads;
+    vp8_decoder_create_threads(pbi);
+
+    //vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
+    // unnecessary calling of vp8cx_init_de_quantizer() for every frame.
+    vp8cx_init_de_quantizer(pbi);
+
+    {
+        VP8_COMMON *cm = &pbi->common;
+
+        vp8_init_loop_filter(cm);
+        cm->last_frame_type = KEY_FRAME;
+        cm->last_filter_type = cm->filter_type;
+        cm->last_sharpness_level = cm->sharpness_level;
+    }
+
+    init_detokenizer(pbi);
+
+    return (VP8D_PTR) pbi;
+}
+void vp8dx_remove_decompressor(VP8D_PTR ptr)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+
+    if (!pbi)
+        return;
+
+    vp8_decoder_remove_threads(pbi);
+    vp8_remove_common(&pbi->common);
+    vpx_free(pbi);
+    vp8dx_shutdown();
+
+}
+
+void vp8dx_set_setting(VP8D_PTR comp, VP8D_SETTING oxst, int x)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) comp;
+
+    (void) pbi;
+    (void) x;
+
+    switch (oxst)
+    {
+    case VP8D_OK:
+        break;
+    }
+}
+
+int vp8dx_get_setting(VP8D_PTR comp, VP8D_SETTING oxst)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) comp;
+
+    (void) pbi;
+
+    switch (oxst)
+    {
+    case VP8D_OK:
+        break;
+    }
+
+    return -1;
+}
+
+int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+    VP8_COMMON *cm = &pbi->common;
+
+    if (ref_frame_flag == VP8_LAST_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->last_frame, sd);
+
+    else if (ref_frame_flag == VP8_GOLD_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->golden_frame, sd);
+
+    else if (ref_frame_flag == VP8_ALT_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, sd);
+
+    else
+        return -1;
+
+    return 0;
+}
+int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+    VP8_COMMON *cm = &pbi->common;
+
+    if (ref_frame_flag == VP8_LAST_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->last_frame);
+
+    else if (ref_frame_flag == VP8_GOLD_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->golden_frame);
+
+    else if (ref_frame_flag == VP8_ALT_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->alt_ref_frame);
+
+    else
+        return -1;
+
+    return 0;
+}
+int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, char *source, INT64 time_stamp)
+{
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+    VP8_COMMON *cm = &pbi->common;
+    int retcode = 0;
+
+    struct vpx_usec_timer timer;
+    (void) size;
+
+//  if(pbi->ready_for_new_data == 0)
+//      return -1;
+
+    vpx_usec_timer_start(&timer);
+
+    if (ptr == 0)
+    {
+        return -1;
+    }
+
+    //cm->current_video_frame++;
+    pbi->Source = source;
+
+    retcode = vp8_decode_frame(pbi);
+
+    if (retcode < 0)
+        return retcode;
+
+    // Update the GF useage maps.
+    vp8_update_gf_useage_maps(cm, &pbi->mb);
+
+    if (pbi->b_multithreaded)
+        vp8_stop_lfthread(pbi);
+
+    if (cm->refresh_last_frame)
+    {
+        vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);
+
+        cm->frame_to_show = &cm->last_frame;
+    }
+    else
+    {
+        cm->frame_to_show = &cm->new_frame;
+    }
+
+    if (!pbi->b_multithreaded)
+    {
+        struct vpx_usec_timer lpftimer;
+        vpx_usec_timer_start(&lpftimer);
+        // Apply the loop filter if appropriate.
+
+        if (cm->filter_level > 0)
+        {
+            vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
+            cm->last_frame_type = cm->frame_type;
+            cm->last_filter_type = cm->filter_type;
+            cm->last_sharpness_level = cm->sharpness_level;
+
+        }
+
+        vpx_usec_timer_mark(&lpftimer);
+        pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
+    }
+
+    vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
+
+#if 0
+    // DEBUG code
+    //vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
+    if (cm->current_video_frame <= 5)
+        write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
+#endif
+
+    // If any buffer copy / swaping is signalled it should be done here.
+    if (cm->copy_buffer_to_arf)
+    {
+        if (cm->copy_buffer_to_arf == 1)
+        {
+            if (cm->refresh_last_frame)
+                vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame);
+            else
+                vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame);
+        }
+        else if (cm->copy_buffer_to_arf == 2)
+            vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame);
+    }
+
+    if (cm->copy_buffer_to_gf)
+    {
+        if (cm->copy_buffer_to_gf == 1)
+        {
+            if (cm->refresh_last_frame)
+                vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->golden_frame);
+            else
+                vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
+        }
+        else if (cm->copy_buffer_to_gf == 2)
+            vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, &cm->golden_frame);
+    }
+
+    // Should the golden or alternate reference frame be refreshed?
+    if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
+    {
+        if (cm->refresh_golden_frame)
+            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);
+
+        if (cm->refresh_alt_ref_frame)
+            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);
+
+        //vpx_log("Decoder: recovery frame received \n");
+
+        // Update data structures that monitors GF useage
+        vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
+        cm->gf_active_count = cm->mb_rows * cm->mb_cols;
+    }
+
+    vp8_clear_system_state();
+
+    vpx_usec_timer_mark(&timer);
+    pbi->decode_microseconds = vpx_usec_timer_elapsed(&timer);
+
+    pbi->time_decoding += pbi->decode_microseconds;
+
+//  vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);
+
+    cm->current_video_frame++;
+    pbi->ready_for_new_data = 0;
+    pbi->last_time_stamp = time_stamp;
+
+    {
+        int i;
+        INT64 earliest_time = pbi->dr[0].time_stamp;
+        INT64 latest_time = pbi->dr[0].time_stamp;
+        INT64 time_diff = 0;
+        int bytes = 0;
+
+        pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
+        pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;
+
+        for (i = 0; i < 16; i++)
+        {
+
+            bytes += pbi->dr[i].size;
+
+            if (pbi->dr[i].time_stamp < earliest_time)
+                earliest_time = pbi->dr[i].time_stamp;
+
+            if (pbi->dr[i].time_stamp > latest_time)
+                latest_time = pbi->dr[i].time_stamp;
+        }
+
+        time_diff = latest_time - earliest_time;
+
+        if (time_diff > 0)
+        {
+            pbi->common.bitrate = 80000.00 * bytes / time_diff  ;
+            pbi->common.framerate = 160000000.00 / time_diff ;
+        }
+
+    }
+    return retcode;
+}
+int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level,  int noise_level, int flags)
+{
+    int ret = -1;
+    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
+
+    if (pbi->ready_for_new_data == 1)
+        return ret;
+
+    // ie no raw frame to show!!!
+    if (pbi->common.show_frame == 0)
+        return ret;
+
+    pbi->ready_for_new_data = 1;
+    *time_stamp = pbi->last_time_stamp;
+    *time_end_stamp = 0;
+
+    sd->clrtype = pbi->common.clr_type;
+    ret = vp8_post_proc_frame(&pbi->common, sd, deblock_level, noise_level, flags);
+    vp8_clear_system_state();
+    return ret;
+}
diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h
new file mode 100644 (file)
index 0000000..fa4fa48
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_VP8D_INT_H
+#define __INC_VP8D_INT_H
+#include "vpx_ports/config.h"
+#include "onyxd.h"
+#include "treereader.h"
+#include "onyxc_int.h"
+#include "threading.h"
+#include "dequantize.h"
+
+typedef struct
+{
+    int ithread;
+    void *ptr1;
+    void *ptr2;
+} DECODETHREAD_DATA;
+
+typedef struct
+{
+    MACROBLOCKD  mbd;
+    int mb_row;
+    int current_mb_col;
+    short *coef_ptr;
+} MB_ROW_DEC;
+
+typedef struct
+{
+    INT64 time_stamp;
+    int size;
+} DATARATE;
+
+typedef struct
+{
+    INT16         min_val;
+    INT16         Length;
+    UINT8 Probs[12];
+} TOKENEXTRABITS;
+
+typedef struct
+{
+    int *scan;
+    UINT8 *ptr_onyxblock2context_leftabove;
+    vp8_tree_index *vp8_coef_tree_ptr;  //onyx_coef_tree_ptr; ???
+    TOKENEXTRABITS *teb_base_ptr;
+    unsigned char *norm_ptr;
+//  UINT16 *ptr_onyx_coef_bands_x;
+    UINT8 *ptr_onyx_coef_bands_x;
+
+    ENTROPY_CONTEXT   **A;
+    ENTROPY_CONTEXT(*L)[4];
+
+    INT16 *qcoeff_start_ptr;
+    BOOL_DECODER *current_bc;
+
+    UINT8 *coef_probs[4];
+
+    UINT8 eob[25];
+
+} DETOK;
+
+typedef struct VP8Decompressor
+{
+    DECLARE_ALIGNED(16, MACROBLOCKD, mb);
+
+    DECLARE_ALIGNED(16, VP8_COMMON, common);
+
+    vp8_reader bc, bc2;
+
+    VP8D_CONFIG oxcf;
+
+
+    const unsigned char *Source;
+    unsigned int   source_sz;
+
+
+    unsigned int CPUFreq;
+    unsigned int decode_microseconds;
+    unsigned int time_decoding;
+    unsigned int time_loop_filtering;
+
+    volatile int b_multithreaded_rd;
+    volatile int b_multithreaded_lf;
+    int max_threads;
+    int last_mb_row_decoded;
+    int current_mb_col_main;
+    int decoding_thread_count;
+    int allocated_decoding_thread_count;
+
+    // variable for threading
+    DECLARE_ALIGNED(16, MACROBLOCKD, lpfmb);
+#if CONFIG_MULTITHREAD
+    pthread_t           h_thread_lpf;         // thread for postprocessing
+    sem_t               h_event_lpf;          // Event for post_proc completed
+    sem_t               h_event_start_lpf;
+#endif
+    MB_ROW_DEC           *mb_row_di;
+    DECODETHREAD_DATA   *de_thread_data;
+#if CONFIG_MULTITHREAD
+    pthread_t           *h_decoding_thread;
+    sem_t               *h_event_mbrdecoding;
+    sem_t               h_event_main;
+    // end of threading data
+#endif
+    vp8_reader *mbc;
+    INT64 last_time_stamp;
+    int   ready_for_new_data;
+
+    DATARATE dr[16];
+
+    DETOK detoken;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+    vp8_dequant_rtcd_vtable_t        dequant;
+    struct vp8_dboolhuff_rtcd_vtable dboolhuff;
+#endif
+
+} VP8D_COMP;
+
+int vp8_decode_frame(VP8D_COMP *cpi);
+void vp8_dmachine_specific_config(VP8D_COMP *pbi);
+
+
+#if CONFIG_DEBUG
+#define CHECK_MEM_ERROR(lval,expr) do {\
+        lval = (expr); \
+        if(!lval) \
+            vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,\
+                               "Failed to allocate "#lval" at %s:%d", \
+                               __FILE__,__LINE__);\
+    } while(0)
+#else
+#define CHECK_MEM_ERROR(lval,expr) do {\
+        lval = (expr); \
+        if(!lval) \
+            vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,\
+                               "Failed to allocate "#lval);\
+    } while(0)
+#endif
+
+#endif
diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c
new file mode 100644 (file)
index 0000000..e35d175
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef WIN32
+# include <unistd.h>
+#endif
+#include "onyxd_int.h"
+#include "vpx_mem/vpx_mem.h"
+#include "threading.h"
+
+#include "loopfilter.h"
+#include "extend.h"
+#include "vpx_ports/vpx_timer.h"
+
+extern void vp8_decode_mb_row(VP8D_COMP *pbi,
+                              VP8_COMMON *pc,
+                              int mb_row,
+                              MACROBLOCKD *xd);
+
+extern void vp8_build_uvmvs(MACROBLOCKD *x, int fullpixel);
+extern void vp8_decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd);
+
+void vp8_setup_decoding_thread_data(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_ROW_DEC *mbrd, int count)
+{
+
+
+
+#if CONFIG_MULTITHREAD
+    VP8_COMMON *const pc = & pbi->common;
+    int i, j;
+
+    for (i = 0; i < count; i++)
+    {
+        MACROBLOCKD *mbd = &mbrd[i].mbd;
+#if CONFIG_RUNTIME_CPU_DETECT
+        mbd->rtcd = xd->rtcd;
+#endif
+
+
+        mbd->subpixel_predict        = xd->subpixel_predict;
+        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
+        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
+        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
+        mbd->gf_active_ptr            = xd->gf_active_ptr;
+
+        mbd->mode_info        = pc->mi - 1;
+        mbd->mode_info_context = pc->mi   + pc->mode_info_stride * (i + 1);
+        mbd->mode_info_stride  = pc->mode_info_stride;
+
+        mbd->frame_type = pc->frame_type;
+        mbd->frames_since_golden      = pc->frames_since_golden;
+        mbd->frames_till_alt_ref_frame  = pc->frames_till_alt_ref_frame;
+
+        mbd->pre = pc->last_frame;
+        mbd->dst = pc->new_frame;
+
+
+
+
+        vp8_setup_block_dptrs(mbd);
+        vp8_build_block_doffsets(mbd);
+        mbd->segmentation_enabled    = xd->segmentation_enabled;
+        mbd->mb_segement_abs_delta     = xd->mb_segement_abs_delta;
+        vpx_memcpy(mbd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
+
+        mbd->mbmi.mode = DC_PRED;
+        mbd->mbmi.uv_mode = DC_PRED;
+
+        mbd->current_bc = &pbi->bc2;
+
+        for (j = 0; j < 25; j++)
+        {
+            mbd->block[j].dequant = xd->block[j].dequant;
+        }
+    }
+
+#else
+    (void) pbi;
+    (void) xd;
+    (void) mbrd;
+    (void) count;
+#endif
+}
+
+
+THREAD_FUNCTION vp8_thread_decoding_proc(void *p_data)
+{
+#if CONFIG_MULTITHREAD
+    int ithread = ((DECODETHREAD_DATA *)p_data)->ithread;
+    VP8D_COMP *pbi = (VP8D_COMP *)(((DECODETHREAD_DATA *)p_data)->ptr1);
+    MB_ROW_DEC *mbrd = (MB_ROW_DEC *)(((DECODETHREAD_DATA *)p_data)->ptr2);
+    ENTROPY_CONTEXT mb_row_left_context[4][4];
+
+    while (1)
+    {
+        if (pbi->b_multithreaded_rd == 0)
+            break;
+
+        //if(WaitForSingleObject(pbi->h_event_mbrdecoding[ithread], INFINITE) == WAIT_OBJECT_0)
+        if (sem_wait(&pbi->h_event_mbrdecoding[ithread]) == 0)
+        {
+            if (pbi->b_multithreaded_rd == 0)
+                break;
+            else
+            {
+                VP8_COMMON *pc = &pbi->common;
+                int mb_row       = mbrd->mb_row;
+                MACROBLOCKD *xd = &mbrd->mbd;
+
+                //printf("ithread:%d mb_row %d\n", ithread, mb_row);
+                int i;
+                int recon_yoffset, recon_uvoffset;
+                int mb_col;
+                int recon_y_stride = pc->last_frame.y_stride;
+                int recon_uv_stride = pc->last_frame.uv_stride;
+
+                volatile int *last_row_current_mb_col;
+
+                if (ithread > 0)
+                    last_row_current_mb_col = &pbi->mb_row_di[ithread-1].current_mb_col;
+                else
+                    last_row_current_mb_col = &pbi->current_mb_col_main;
+
+                recon_yoffset = mb_row * recon_y_stride * 16;
+                recon_uvoffset = mb_row * recon_uv_stride * 8;
+                // reset above block coeffs
+
+                xd->above_context[Y1CONTEXT] = pc->above_context[Y1CONTEXT];
+                xd->above_context[UCONTEXT ] = pc->above_context[UCONTEXT];
+                xd->above_context[VCONTEXT ] = pc->above_context[VCONTEXT];
+                xd->above_context[Y2CONTEXT] = pc->above_context[Y2CONTEXT];
+                xd->left_context = mb_row_left_context;
+                vpx_memset(mb_row_left_context, 0, sizeof(mb_row_left_context));
+                xd->up_available = (mb_row != 0);
+
+                xd->mb_to_top_edge = -((mb_row * 16)) << 3;
+                xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+
+                for (mb_col = 0; mb_col < pc->mb_cols; mb_col++)
+                {
+
+                    while (mb_col > (*last_row_current_mb_col - 1) && *last_row_current_mb_col != pc->mb_cols - 1)
+                    {
+                        x86_pause_hint();
+                        thread_sleep(0);
+                    }
+
+                    // Take a copy of the mode and Mv information for this macroblock into the xd->mbmi
+                    vpx_memcpy(&xd->mbmi, &xd->mode_info_context->mbmi, 32); //sizeof(MB_MODE_INFO) );
+
+                    if (xd->mbmi.mode == SPLITMV || xd->mbmi.mode == B_PRED)
+                    {
+                        for (i = 0; i < 16; i++)
+                        {
+                            BLOCKD *d = &xd->block[i];
+                            vpx_memcpy(&d->bmi, &xd->mode_info_context->bmi[i], sizeof(B_MODE_INFO));
+                        }
+                    }
+
+                    // Distance of Mb to the various image edges.
+                    // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
+                    xd->mb_to_left_edge = -((mb_col * 16) << 3);
+                    xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+
+                    xd->dst.y_buffer = pc->new_frame.y_buffer + recon_yoffset;
+                    xd->dst.u_buffer = pc->new_frame.u_buffer + recon_uvoffset;
+                    xd->dst.v_buffer = pc->new_frame.v_buffer + recon_uvoffset;
+
+                    xd->left_available = (mb_col != 0);
+
+                    // Select the appropriate reference frame for this MB
+                    if (xd->mbmi.ref_frame == LAST_FRAME)
+                    {
+                        xd->pre.y_buffer = pc->last_frame.y_buffer + recon_yoffset;
+                        xd->pre.u_buffer = pc->last_frame.u_buffer + recon_uvoffset;
+                        xd->pre.v_buffer = pc->last_frame.v_buffer + recon_uvoffset;
+                    }
+                    else if (xd->mbmi.ref_frame == GOLDEN_FRAME)
+                    {
+                        // Golden frame reconstruction buffer
+                        xd->pre.y_buffer = pc->golden_frame.y_buffer + recon_yoffset;
+                        xd->pre.u_buffer = pc->golden_frame.u_buffer + recon_uvoffset;
+                        xd->pre.v_buffer = pc->golden_frame.v_buffer + recon_uvoffset;
+                    }
+                    else
+                    {
+                        // Alternate reference frame reconstruction buffer
+                        xd->pre.y_buffer = pc->alt_ref_frame.y_buffer + recon_yoffset;
+                        xd->pre.u_buffer = pc->alt_ref_frame.u_buffer + recon_uvoffset;
+                        xd->pre.v_buffer = pc->alt_ref_frame.v_buffer + recon_uvoffset;
+                    }
+
+                    vp8_build_uvmvs(xd, pc->full_pixel);
+
+                    vp8dx_bool_decoder_fill(xd->current_bc);
+                    vp8_decode_macroblock(pbi, xd);
+
+
+                    recon_yoffset += 16;
+                    recon_uvoffset += 8;
+
+                    ++xd->mode_info_context;  /* next mb */
+
+                    xd->gf_active_ptr++;      // GF useage flag for next MB
+
+                    xd->above_context[Y1CONTEXT] += 4;
+                    xd->above_context[UCONTEXT ] += 2;
+                    xd->above_context[VCONTEXT ] += 2;
+                    xd->above_context[Y2CONTEXT] ++;
+                    pbi->mb_row_di[ithread].current_mb_col = mb_col;
+
+                }
+
+                // adjust to the next row of mbs
+                vp8_extend_mb_row(
+                    &pc->new_frame,
+                    xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8
+                );
+
+                ++xd->mode_info_context;      /* skip prediction column */
+
+                // since we have multithread
+                xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
+
+                //memcpy(&pbi->lpfmb, &pbi->mb, sizeof(pbi->mb));
+                if ((mb_row & 1) == 1)
+                {
+                    pbi->last_mb_row_decoded = mb_row;
+                    //printf("S%d", pbi->last_mb_row_decoded);
+                }
+
+                if (ithread == (pbi->decoding_thread_count - 1) || mb_row == pc->mb_rows - 1)
+                {
+                    //SetEvent(pbi->h_event_main);
+                    sem_post(&pbi->h_event_main);
+
+                }
+            }
+        }
+    }
+
+#else
+    (void) p_data;
+#endif
+
+    return 0 ;
+}
+
+THREAD_FUNCTION vp8_thread_loop_filter(void *p_data)
+{
+#if CONFIG_MULTITHREAD
+    VP8D_COMP *pbi = (VP8D_COMP *)p_data;
+
+    while (1)
+    {
+        if (pbi->b_multithreaded_lf == 0)
+            break;
+
+        //printf("before waiting for start_lpf\n");
+
+        //if(WaitForSingleObject(pbi->h_event_start_lpf, INFINITE) == WAIT_OBJECT_0)
+        if (sem_wait(&pbi->h_event_start_lpf) == 0)
+        {
+            if (pbi->b_multithreaded_lf == 0) // we're shutting down
+                break;
+            else
+            {
+
+                VP8_COMMON *cm  = &pbi->common;
+                MACROBLOCKD *mbd = &pbi->lpfmb;
+                int default_filt_lvl = pbi->common.filter_level;
+
+                YV12_BUFFER_CONFIG *post = &cm->new_frame;
+                loop_filter_info *lfi = cm->lf_info;
+
+                int mb_row;
+                int mb_col;
+
+
+                int baseline_filter_level[MAX_MB_SEGMENTS];
+                int filter_level;
+                int alt_flt_enabled = mbd->segmentation_enabled;
+
+                int i;
+                unsigned char *y_ptr, *u_ptr, *v_ptr;
+
+                volatile int *last_mb_row_decoded = &pbi->last_mb_row_decoded;
+
+                //MODE_INFO * this_mb_mode_info = cm->mi;
+                mbd->mode_info_context = cm->mi;          // Point at base of Mb MODE_INFO list
+
+                // Note the baseline filter values for each segment
+                if (alt_flt_enabled)
+                {
+                    for (i = 0; i < MAX_MB_SEGMENTS; i++)
+                    {
+                        if (mbd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+                            baseline_filter_level[i] = mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+                        else
+                        {
+                            baseline_filter_level[i] = default_filt_lvl + mbd->segment_feature_data[MB_LVL_ALT_LF][i];
+                            baseline_filter_level[i] = (baseline_filter_level[i] >= 0) ? ((baseline_filter_level[i] <= MAX_LOOP_FILTER) ? baseline_filter_level[i] : MAX_LOOP_FILTER) : 0;  // Clamp to valid range
+                        }
+                    }
+                }
+                else
+                {
+                    for (i = 0; i < MAX_MB_SEGMENTS; i++)
+                        baseline_filter_level[i] = default_filt_lvl;
+                }
+
+                // Initialize the loop filter for this frame.
+                vp8_init_loop_filter(cm);
+
+                // Set up the buffer pointers
+                y_ptr = post->y_buffer;
+                u_ptr = post->u_buffer;
+                v_ptr = post->v_buffer;
+
+                // vp8_filter each macro block
+                for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+                {
+
+                    while (mb_row >= *last_mb_row_decoded)
+                    {
+                        x86_pause_hint();
+                        thread_sleep(0);
+                    }
+
+                    //printf("R%d", mb_row);
+                    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+                    {
+                        int Segment = (alt_flt_enabled) ? mbd->mode_info_context->mbmi.segment_id : 0;
+
+                        filter_level = baseline_filter_level[Segment];
+
+                        // Apply any context driven MB level adjustment
+                        vp8_adjust_mb_lf_value(mbd, &filter_level);
+
+                        if (filter_level)
+                        {
+                            if (mb_col > 0)
+                                cm->lf_mbv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+
+                            if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                                cm->lf_bv(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+
+                            // don't apply across umv border
+                            if (mb_row > 0)
+                                cm->lf_mbh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+
+                            if (mbd->mode_info_context->mbmi.dc_diff > 0)
+                                cm->lf_bh(y_ptr, u_ptr, v_ptr, post->y_stride, post->uv_stride, &lfi[filter_level], cm->simpler_lpf);
+                        }
+
+                        y_ptr += 16;
+                        u_ptr += 8;
+                        v_ptr += 8;
+
+                        mbd->mode_info_context++;     // step to next MB
+
+                    }
+
+                    y_ptr += post->y_stride  * 16 - post->y_width;
+                    u_ptr += post->uv_stride *  8 - post->uv_width;
+                    v_ptr += post->uv_stride *  8 - post->uv_width;
+
+                    mbd->mode_info_context++;         // Skip border mb
+                }
+
+                //printf("R%d\n", mb_row);
+                // When done, signal main thread that ME is finished
+                //SetEvent(pbi->h_event_lpf);
+                sem_post(&pbi->h_event_lpf);
+            }
+
+        }
+    }
+
+#else
+    (void) p_data;
+#endif
+    return 0;
+}
+
+void vp8_decoder_create_threads(VP8D_COMP *pbi)
+{
+#if CONFIG_MULTITHREAD
+    int core_count = 0;
+    int ithread;
+
+    pbi->b_multithreaded_rd = 0;
+    pbi->b_multithreaded_lf = 0;
+    pbi->allocated_decoding_thread_count = 0;
+    core_count = (pbi->max_threads > 16) ? 16 : pbi->max_threads; //vp8_get_proc_core_count();
+    if (core_count > 1)
+    {
+        sem_init(&pbi->h_event_lpf, 0, 0);
+        sem_init(&pbi->h_event_start_lpf, 0, 0);
+        pbi->b_multithreaded_lf = 1;
+        pthread_create(&pbi->h_thread_lpf, 0, vp8_thread_loop_filter, (pbi));
+    }
+
+    if (core_count > 1)
+    {
+        pbi->b_multithreaded_rd = 1;
+        pbi->decoding_thread_count = core_count - 1;
+
+        CHECK_MEM_ERROR(pbi->h_decoding_thread, vpx_malloc(sizeof(pthread_t) * pbi->decoding_thread_count));
+        CHECK_MEM_ERROR(pbi->h_event_mbrdecoding, vpx_malloc(sizeof(sem_t) * pbi->decoding_thread_count));
+        CHECK_MEM_ERROR(pbi->mb_row_di, vpx_memalign(32, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count));
+        vpx_memset(pbi->mb_row_di, 0, sizeof(MB_ROW_DEC) * pbi->decoding_thread_count);
+        CHECK_MEM_ERROR(pbi->de_thread_data, vpx_malloc(sizeof(DECODETHREAD_DATA) * pbi->decoding_thread_count));
+
+        for (ithread = 0; ithread < pbi->decoding_thread_count; ithread++)
+        {
+            sem_init(&pbi->h_event_mbrdecoding[ithread], 0, 0);
+
+            pbi->de_thread_data[ithread].ithread  = ithread;
+            pbi->de_thread_data[ithread].ptr1     = (void *)pbi;
+            pbi->de_thread_data[ithread].ptr2     = (void *) &pbi->mb_row_di[ithread];
+
+            pthread_create(&pbi->h_decoding_thread[ithread], 0, vp8_thread_decoding_proc, (&pbi->de_thread_data[ithread]));
+
+        }
+
+        sem_init(&pbi->h_event_main, 0, 0);
+        pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
+    }
+
+#else
+    (void) pbi;
+#endif
+}
+
+void vp8_decoder_remove_threads(VP8D_COMP *pbi)
+{
+#if CONFIG_MULTITHREAD
+
+    if (pbi->b_multithreaded_lf)
+    {
+        pbi->b_multithreaded_lf = 0;
+        sem_post(&pbi->h_event_start_lpf);
+        pthread_join(pbi->h_thread_lpf, 0);
+        sem_destroy(&pbi->h_event_start_lpf);
+    }
+
+    //shutdown MB Decoding thread;
+    if (pbi->b_multithreaded_rd)
+    {
+        pbi->b_multithreaded_rd = 0;
+        // allow all threads to exit
+        {
+            int i;
+
+            for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
+            {
+
+                sem_post(&pbi->h_event_mbrdecoding[i]);
+                pthread_join(pbi->h_decoding_thread[i], NULL);
+            }
+        }
+        {
+
+            int i;
+            for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
+            {
+                sem_destroy(&pbi->h_event_mbrdecoding[i]);
+            }
+
+
+        }
+
+        sem_destroy(&pbi->h_event_main);
+
+        if (pbi->h_decoding_thread)
+        {
+            vpx_free(pbi->h_decoding_thread);
+            pbi->h_decoding_thread = NULL;
+        }
+
+        if (pbi->h_event_mbrdecoding)
+        {
+            vpx_free(pbi->h_event_mbrdecoding);
+            pbi->h_event_mbrdecoding = NULL;
+        }
+
+        if (pbi->mb_row_di)
+        {
+            vpx_free(pbi->mb_row_di);
+            pbi->mb_row_di = NULL ;
+        }
+
+        if (pbi->de_thread_data)
+        {
+            vpx_free(pbi->de_thread_data);
+            pbi->de_thread_data = NULL;
+        }
+    }
+
+#else
+    (void) pbi;
+#endif
+}
+
+
+void vp8_start_lfthread(VP8D_COMP *pbi)
+{
+#if CONFIG_MULTITHREAD
+    memcpy(&pbi->lpfmb, &pbi->mb, sizeof(pbi->mb));
+    pbi->last_mb_row_decoded = 0;
+    sem_post(&pbi->h_event_start_lpf);
+#else
+    (void) pbi;
+#endif
+}
+
+void vp8_stop_lfthread(VP8D_COMP *pbi)
+{
+#if CONFIG_MULTITHREAD
+    struct vpx_usec_timer timer;
+
+    vpx_usec_timer_start(&timer);
+
+    sem_wait(&pbi->h_event_lpf);
+
+    vpx_usec_timer_mark(&timer);
+    pbi->time_loop_filtering += vpx_usec_timer_elapsed(&timer);
+#else
+    (void) pbi;
+#endif
+}
+
+
+void vp8_mtdecode_mb_rows(VP8D_COMP *pbi,
+                          MACROBLOCKD *xd)
+{
+#if CONFIG_MULTITHREAD
+    int mb_row;
+    VP8_COMMON *pc = &pbi->common;
+
+    int ibc = 0;
+    int num_part = 1 << pbi->common.multi_token_partition;
+
+    vp8_setup_decoding_thread_data(pbi, xd, pbi->mb_row_di, pbi->decoding_thread_count);
+
+    for (mb_row = 0; mb_row < pc->mb_rows; mb_row += (pbi->decoding_thread_count + 1))
+    {
+        int i;
+        pbi->current_mb_col_main = -1;
+
+        xd->current_bc = &pbi->mbc[ibc];
+        ibc++ ;
+
+        if (ibc == num_part)
+            ibc = 0;
+
+        for (i = 0; i < pbi->decoding_thread_count; i++)
+        {
+            if ((mb_row + i + 1) >= pc->mb_rows)
+                break;
+
+            pbi->mb_row_di[i].mb_row = mb_row + i + 1;
+            pbi->mb_row_di[i].mbd.current_bc =  &pbi->mbc[ibc];
+            ibc++;
+
+            if (ibc == num_part)
+                ibc = 0;
+
+            pbi->mb_row_di[i].current_mb_col = -1;
+            sem_post(&pbi->h_event_mbrdecoding[i]);
+        }
+
+        vp8_decode_mb_row(pbi, pc, mb_row, xd);
+
+        xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count;
+
+        if (mb_row < pc->mb_rows - 1)
+        {
+            sem_wait(&pbi->h_event_main);
+        }
+    }
+
+    pbi->last_mb_row_decoded = mb_row;
+#else
+    (void) pbi;
+    (void) xd;
+#endif
+}
diff --git a/vp8/decoder/treereader.h b/vp8/decoder/treereader.h
new file mode 100644 (file)
index 0000000..eb10e24
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef tree_reader_h
+#define tree_reader_h 1
+
+#include "treecoder.h"
+
+#include "dboolhuff.h"
+
+typedef BOOL_DECODER vp8_reader;
+
+#define vp8_read vp8dx_decode_bool
+#define vp8_read_literal vp8_decode_value
+#define vp8_read_bit( R) vp8_read( R, vp8_prob_half)
+
+
+/* Intent of tree data structure is to make decoding trivial. */
+
+static int vp8_treed_read(
+    vp8_reader *const r,        /* !!! must return a 0 or 1 !!! */
+    vp8_tree t,
+    const vp8_prob *const p
+)
+{
+    register vp8_tree_index i = 0;
+
+    while ((i = t[ i + vp8_read(r, p[i>>1])]) > 0) ;
+
+    return -i;
+}
+
+
+/* Variant reads a binary number given distributions on each bit.
+   Note that tree is arbitrary; probability of decoding a zero
+   may or may not depend on previously decoded bits. */
+
+static int vp8_treed_read_num(
+    vp8_reader *const r,        /* !!! must return a 0 or 1 !!! */
+    vp8_tree t,
+    const vp8_prob *const p
+)
+{
+    vp8_tree_index i = 0;
+    int v = 0, b;
+
+    do
+    {
+        b = vp8_read(r, p[i>>1]);
+        v = (v << 1) + b;
+    }
+    while ((i = t[i+b]) > 0);
+
+    return v;
+}
+#endif /* tree_reader_h */
diff --git a/vp8/decoder/x86/dequantize_mmx.asm b/vp8/decoder/x86/dequantize_mmx.asm
new file mode 100644 (file)
index 0000000..02be487
--- /dev/null
@@ -0,0 +1,410 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+
+;void vp8_dequantize_b_impl_mmx(short *sq, short *dq, short *q)
+global sym(vp8_dequantize_b_impl_mmx)
+sym(vp8_dequantize_b_impl_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov       rsi, arg(0) ;sq
+        mov       rdi, arg(1) ;dq
+        mov       rax, arg(2) ;q
+
+        movq      mm1, [rsi]
+        pmullw    mm1, [rax+0]            ; mm4 *= kernel 0 modifiers.
+        movq      [rdi], mm1
+
+        movq      mm1, [rsi+8]
+        pmullw    mm1, [rax+8]            ; mm4 *= kernel 0 modifiers.
+        movq      [rdi+8], mm1
+
+        movq      mm1, [rsi+16]
+        pmullw    mm1, [rax+16]            ; mm4 *= kernel 0 modifiers.
+        movq      [rdi+16], mm1
+
+        movq      mm1, [rsi+24]
+        pmullw    mm1, [rax+24]            ; mm4 *= kernel 0 modifiers.
+        movq      [rdi+24], mm1
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void dequant_idct_mmx(short *input, short *dq, short *output, int pitch)
+global sym(vp8_dequant_idct_mmx)
+sym(vp8_dequant_idct_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rax,    arg(0) ;input
+        mov         rdx,    arg(1) ;dq
+
+
+        movq        mm0,    [rax   ]
+        pmullw      mm0,    [rdx]
+
+        movq        mm1,    [rax +8]
+        pmullw      mm1,    [rdx +8]
+
+        movq        mm2,    [rax+16]
+        pmullw      mm2,    [rdx+16]
+
+        movq        mm3,    [rax+24]
+        pmullw      mm3,    [rdx+24]
+
+        mov         rdx,    arg(2) ;output
+        pxor        mm7,    mm7
+
+
+        movq        [rax],   mm7
+        movq        [rax+8], mm7
+
+        movq        [rax+16],mm7
+        movq        [rax+24],mm7
+
+
+        movsxd      rax,            dword ptr arg(3) ;pitch
+
+        psubw       mm0,            mm2             ; b1= 0-2
+        paddw       mm2,            mm2             ;
+
+        movq        mm5,            mm1
+        paddw       mm2,            mm0             ; a1 =0+2
+
+        pmulhw      mm5,            [x_s1sqr2 GLOBAL];
+        paddw       mm5,            mm1             ; ip1 * sin(pi/8) * sqrt(2)
+
+        movq        mm7,            mm3             ;
+        pmulhw      mm7,            [x_c1sqr2less1 GLOBAL];
+
+        paddw       mm7,            mm3             ; ip3 * cos(pi/8) * sqrt(2)
+        psubw       mm7,            mm5             ; c1
+
+        movq        mm5,            mm1
+        movq        mm4,            mm3
+
+        pmulhw      mm5,            [x_c1sqr2less1 GLOBAL]
+        paddw       mm5,            mm1
+
+        pmulhw      mm3,            [x_s1sqr2 GLOBAL]
+        paddw       mm3,            mm4
+
+        paddw       mm3,            mm5             ; d1
+        movq        mm6,            mm2             ; a1
+
+        movq        mm4,            mm0             ; b1
+        paddw       mm2,            mm3             ;0
+
+        paddw       mm4,            mm7             ;1
+        psubw       mm0,            mm7             ;2
+
+        psubw       mm6,            mm3             ;3
+
+        movq        mm1,            mm2             ; 03 02 01 00
+        movq        mm3,            mm4             ; 23 22 21 20
+
+        punpcklwd   mm1,            mm0             ; 11 01 10 00
+        punpckhwd   mm2,            mm0             ; 13 03 12 02
+
+        punpcklwd   mm3,            mm6             ; 31 21 30 20
+        punpckhwd   mm4,            mm6             ; 33 23 32 22
+
+        movq        mm0,            mm1             ; 11 01 10 00
+        movq        mm5,            mm2             ; 13 03 12 02
+
+        punpckldq   mm0,            mm3             ; 30 20 10 00
+        punpckhdq   mm1,            mm3             ; 31 21 11 01
+
+        punpckldq   mm2,            mm4             ; 32 22 12 02
+        punpckhdq   mm5,            mm4             ; 33 23 13 03
+
+        movq        mm3,            mm5             ; 33 23 13 03
+
+        psubw       mm0,            mm2             ; b1= 0-2
+        paddw       mm2,            mm2             ;
+
+        movq        mm5,            mm1
+        paddw       mm2,            mm0             ; a1 =0+2
+
+        pmulhw      mm5,            [x_s1sqr2 GLOBAL];
+        paddw       mm5,            mm1             ; ip1 * sin(pi/8) * sqrt(2)
+
+        movq        mm7,            mm3             ;
+        pmulhw      mm7,            [x_c1sqr2less1 GLOBAL];
+
+        paddw       mm7,            mm3             ; ip3 * cos(pi/8) * sqrt(2)
+        psubw       mm7,            mm5             ; c1
+
+        movq        mm5,            mm1
+        movq        mm4,            mm3
+
+        pmulhw      mm5,            [x_c1sqr2less1 GLOBAL]
+        paddw       mm5,            mm1
+
+        pmulhw      mm3,            [x_s1sqr2 GLOBAL]
+        paddw       mm3,            mm4
+
+        paddw       mm3,            mm5             ; d1
+        paddw       mm0,            [fours GLOBAL]
+
+        paddw       mm2,            [fours GLOBAL]
+        movq        mm6,            mm2             ; a1
+
+        movq        mm4,            mm0             ; b1
+        paddw       mm2,            mm3             ;0
+
+        paddw       mm4,            mm7             ;1
+        psubw       mm0,            mm7             ;2
+
+        psubw       mm6,            mm3             ;3
+        psraw       mm2,            3
+
+        psraw       mm0,            3
+        psraw       mm4,            3
+
+        psraw       mm6,            3
+
+        movq        mm1,            mm2             ; 03 02 01 00
+        movq        mm3,            mm4             ; 23 22 21 20
+
+        punpcklwd   mm1,            mm0             ; 11 01 10 00
+        punpckhwd   mm2,            mm0             ; 13 03 12 02
+
+        punpcklwd   mm3,            mm6             ; 31 21 30 20
+        punpckhwd   mm4,            mm6             ; 33 23 32 22
+
+        movq        mm0,            mm1             ; 11 01 10 00
+        movq        mm5,            mm2             ; 13 03 12 02
+
+        punpckldq   mm0,            mm3             ; 30 20 10 00
+        punpckhdq   mm1,            mm3             ; 31 21 11 01
+
+        punpckldq   mm2,            mm4             ; 32 22 12 02
+        punpckhdq   mm5,            mm4             ; 33 23 13 03
+
+        movq        [rdx],          mm0
+
+        movq        [rdx+rax],      mm1
+        movq        [rdx+rax*2],    mm2
+
+        add         rdx,            rax
+        movq        [rdx+rax*2],    mm5
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void dequant_dc_idct_mmx(short *input, short *dq, short *output, int pitch, int Dc)
+global sym(vp8_dequant_dc_idct_mmx)
+sym(vp8_dequant_dc_idct_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    GET_GOT     rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov         rax,    arg(0) ;input
+        mov         rdx,    arg(1) ;dq
+
+        movsxd      rcx,    dword ptr arg(4) ;Dc
+
+        movq        mm0,    [rax   ]
+        pmullw      mm0,    [rdx]
+
+        movq        mm1,    [rax +8]
+        pmullw      mm1,    [rdx +8]
+
+        movq        mm2,    [rax+16]
+        pmullw      mm2,    [rdx+16]
+
+        movq        mm3,    [rax+24]
+        pmullw      mm3,    [rdx+24]
+
+        mov         rdx,    arg(2) ;output
+        pxor        mm7,    mm7
+
+
+        movq        [rax],   mm7
+        movq        [rax+8], mm7
+
+        movq        [rax+16],mm7
+        movq        [rax+24],mm7
+
+        pinsrw      mm0,    rcx,  0
+        movsxd      rax,            dword ptr arg(3) ;pitch
+
+        psubw       mm0,            mm2             ; b1= 0-2
+        paddw       mm2,            mm2             ;
+
+        movq        mm5,            mm1
+        paddw       mm2,            mm0             ; a1 =0+2
+
+        pmulhw      mm5,            [x_s1sqr2 GLOBAL];
+        paddw       mm5,            mm1             ; ip1 * sin(pi/8) * sqrt(2)
+
+        movq        mm7,            mm3             ;
+        pmulhw      mm7,            [x_c1sqr2less1 GLOBAL];
+
+        paddw       mm7,            mm3             ; ip3 * cos(pi/8) * sqrt(2)
+        psubw       mm7,            mm5             ; c1
+
+        movq        mm5,            mm1
+        movq        mm4,            mm3
+
+        pmulhw      mm5,            [x_c1sqr2less1 GLOBAL]
+        paddw       mm5,            mm1
+
+        pmulhw      mm3,            [x_s1sqr2 GLOBAL]
+        paddw       mm3,            mm4
+
+        paddw       mm3,            mm5             ; d1
+        movq        mm6,            mm2             ; a1
+
+        movq        mm4,            mm0             ; b1
+        paddw       mm2,            mm3             ;0
+
+        paddw       mm4,            mm7             ;1
+        psubw       mm0,            mm7             ;2
+
+        psubw       mm6,            mm3             ;3
+
+        movq        mm1,            mm2             ; 03 02 01 00
+        movq        mm3,            mm4             ; 23 22 21 20
+
+        punpcklwd   mm1,            mm0             ; 11 01 10 00
+        punpckhwd   mm2,            mm0             ; 13 03 12 02
+
+        punpcklwd   mm3,            mm6             ; 31 21 30 20
+        punpckhwd   mm4,            mm6             ; 33 23 32 22
+
+        movq        mm0,            mm1             ; 11 01 10 00
+        movq        mm5,            mm2             ; 13 03 12 02
+
+        punpckldq   mm0,            mm3             ; 30 20 10 00
+        punpckhdq   mm1,            mm3             ; 31 21 11 01
+
+        punpckldq   mm2,            mm4             ; 32 22 12 02
+        punpckhdq   mm5,            mm4             ; 33 23 13 03
+
+        movq        mm3,            mm5             ; 33 23 13 03
+
+        psubw       mm0,            mm2             ; b1= 0-2
+        paddw       mm2,            mm2             ;
+
+        movq        mm5,            mm1
+        paddw       mm2,            mm0             ; a1 =0+2
+
+        pmulhw      mm5,            [x_s1sqr2 GLOBAL];
+        paddw       mm5,            mm1             ; ip1 * sin(pi/8) * sqrt(2)
+
+        movq        mm7,            mm3             ;
+        pmulhw      mm7,            [x_c1sqr2less1 GLOBAL];
+
+        paddw       mm7,            mm3             ; ip3 * cos(pi/8) * sqrt(2)
+        psubw       mm7,            mm5             ; c1
+
+        movq        mm5,            mm1
+        movq        mm4,            mm3
+
+        pmulhw      mm5,            [x_c1sqr2less1 GLOBAL]
+        paddw       mm5,            mm1
+
+        pmulhw      mm3,            [x_s1sqr2 GLOBAL]
+        paddw       mm3,            mm4
+
+        paddw       mm3,            mm5             ; d1
+        paddw       mm0,            [fours GLOBAL]
+
+        paddw       mm2,            [fours GLOBAL]
+        movq        mm6,            mm2             ; a1
+
+        movq        mm4,            mm0             ; b1
+        paddw       mm2,            mm3             ;0
+
+        paddw       mm4,            mm7             ;1
+        psubw       mm0,            mm7             ;2
+
+        psubw       mm6,            mm3             ;3
+        psraw       mm2,            3
+
+        psraw       mm0,            3
+        psraw       mm4,            3
+
+        psraw       mm6,            3
+
+        movq        mm1,            mm2             ; 03 02 01 00
+        movq        mm3,            mm4             ; 23 22 21 20
+
+        punpcklwd   mm1,            mm0             ; 11 01 10 00
+        punpckhwd   mm2,            mm0             ; 13 03 12 02
+
+        punpcklwd   mm3,            mm6             ; 31 21 30 20
+        punpckhwd   mm4,            mm6             ; 33 23 32 22
+
+        movq        mm0,            mm1             ; 11 01 10 00
+        movq        mm5,            mm2             ; 13 03 12 02
+
+        punpckldq   mm0,            mm3             ; 30 20 10 00
+        punpckhdq   mm1,            mm3             ; 31 21 11 01
+
+        punpckldq   mm2,            mm4             ; 32 22 12 02
+        punpckhdq   mm5,            mm4             ; 33 23 13 03
+
+        movq        [rdx],          mm0
+
+        movq        [rdx+rax],      mm1
+        movq        [rdx+rax*2],    mm2
+
+        add         rdx,            rax
+        movq        [rdx+rax*2],    mm5
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+align 16
+x_s1sqr2:
+    times 4 dw 0x8A8C
+align 16
+x_c1sqr2less1:
+    times 4 dw 0x4E7B
+align 16
+fours:
+    times 4 dw 0x0004
diff --git a/vp8/decoder/x86/dequantize_x86.h b/vp8/decoder/x86/dequantize_x86.h
new file mode 100644 (file)
index 0000000..5def406
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef DEQUANTIZE_X86_H
+#define DEQUANTIZE_X86_H
+
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+#if HAVE_MMX
+extern prototype_dequant_block(vp8_dequantize_b_mmx);
+extern prototype_dequant_idct(vp8_dequant_idct_mmx);
+extern prototype_dequant_idct_dc(vp8_dequant_dc_idct_mmx);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_dequant_block
+#define vp8_dequant_block vp8_dequantize_b_mmx
+
+#undef  vp8_dequant_idct
+#define vp8_dequant_idct vp8_dequant_idct_mmx
+
+#undef  vp8_dequant_idct_dc
+#define vp8_dequant_idct_dc vp8_dequant_dc_idct_mmx
+
+#endif
+#endif
+
+#endif
diff --git a/vp8/decoder/x86/onyxdxv.c b/vp8/decoder/x86/onyxdxv.c
new file mode 100644 (file)
index 0000000..75a676a
--- /dev/null
@@ -0,0 +1,1079 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     onyxdxv.c
+*
+*   Description  :     VP80 interface to DXV.
+*
+*****************************************************************************
+*/
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include <math.h>   // For Abs()
+#include "pragmas.h"
+
+#include "vpxdxv.h"
+#include "vpxdxv_plugin.h"
+
+#include "onyxd_int.h"
+#include "onyx.h"
+#include "codec_common_interface.h"
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+#include "postproc.h"
+#include "vpxblit.h"
+#include "g_common.h"
+#include "vpx_scale/yv12extend.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include "scale_mode.h"
+#include "onyx_pb_interface.h"
+
+/****************************************************************************
+*  Macros
+****************************************************************************/
+
+#define VP8_FOURCC DXL_MKFOURCC( 'V', 'P', '8', '0')
+
+extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch);
+
+
+/****************************************************************************
+*  Typedefs
+****************************************************************************/
+
+typedef struct  // YUV buffer configuration structure
+{
+    int   y_width;
+    int   y_height;
+    int   y_stride;
+
+    int   uv_width;
+    int   uv_height;
+    int   uv_stride;
+
+    char *y_buffer;
+    char *u_buffer;
+    char *v_buffer;
+
+    char *uv_start;
+    int   uv_dst_area;
+    int   uv_used_area;
+
+    unsigned char *y_ptr_scrn;
+    unsigned char *u_ptr_scrn;
+    unsigned char *v_ptr_scrn;
+
+
+} DXV_YUV_BUFFER_CONFIG;
+
+
+typedef void ((*vp8blit_func)(unsigned char *, int, YUV_BUFFER_CONFIG *));
+
+/* define an x_image structure based on the core x_image struct */
+typedef struct t_ximage_codec
+{
+    DXV_YUV_BUFFER_CONFIG frame_buffer;
+    VP8D_COMP *my_pbi;
+    VP8_COMMON *common;
+    int owned;
+    int decompressed_once;
+
+    int sizeof_pixel;
+    vp8blit_func blitter;
+
+    unsigned int ppl_tag;
+    unsigned int bd_tag;
+    unsigned int *supported_output_format_list;
+
+    int cpu_free;
+    int postproc;
+    int add_noise;
+    int deinterlace;
+
+    int post_proc2time;
+    int post_proc4time;
+
+    int hs;
+    int hr;
+    int vs;
+    int vr;
+    YV12_BUFFER_CONFIG this_buffer;
+    YV12_BUFFER_CONFIG scaled_buffer;
+    YV12_BUFFER_CONFIG *passed_in_buffer;
+
+    int avgq;
+    int ppcount;
+
+
+} VP8_XIMAGE, *VP8_XIMAGE_HANDLE;
+
+
+/****************************************************************************
+*  Modul Statics
+****************************************************************************/
+static unsigned int g_vp8_preferred_output_format_list[] =
+{
+    VPXDXV_YUY2,
+    VPXDXV_UYVY,
+    VPXDXV_RGB8888,
+    VPXDXV_RGB888,
+    VPXDXV_RGB555,
+    VPXDXV_RGB565,
+    VPXDXV_YV12,
+    VPXDXV_I420,
+
+//    VPXDXV_YV12,
+//    VPXDXV_YUY2,
+//    VPXDXV_RGB565,
+//    VPXDXV_UYVY,
+    0
+};
+
+/****************************************************************************
+*  Forward declarationss
+****************************************************************************/
+void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter);
+
+static int onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *bd_tag);
+static int onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag);
+
+static int vpx_get_size_of_pixel(unsigned int bd);
+
+/****************************************************************************
+*  Imports
+****************************************************************************/
+
+#define __Clamp255(x)   (unsigned char) ( (x) < 0 ? 0 : ( (x) <= 255 ? (x) : 255 ) )
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+void
+convert_yv12_buffer_types(YV12_BUFFER_CONFIG *source, DXV_YUV_BUFFER_CONFIG *dest)
+{
+    dest->y_buffer = (char *)source->y_buffer;
+    dest->u_buffer = (char *)source->u_buffer;
+    dest->v_buffer = (char *)source->v_buffer;
+    dest->y_width  = source->y_width;
+    dest->y_height = source->y_height;
+    dest->y_stride = source->y_stride;
+    dest->uv_width  = source->uv_width;
+    dest->uv_height = source->uv_height;
+    dest->uv_stride = source->uv_stride;
+}
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+
+int onyx_blit
+(
+    XIMAGE_HANDLE src,
+    VSCREEN_HANDLE v_screen,
+    DXV_YUV_BUFFER_CONFIG *frame_buffer,
+    int x,
+    int y
+)
+{
+    VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+    VP8D_COMP *pbi;
+    VP8_COMMON *common = tab->common;
+    pbi = tab->my_pbi;
+
+    if (v_screen) /* if there is a v_screen, blit to it */
+    {
+        unsigned char *ptr_scrn;
+        int this_pitch, vs_height, vs_width;
+        unsigned int start_tick, stop_tick;
+
+        vpxdxv_get_vscreen_attributes(v_screen, (void **)&ptr_scrn,  &vs_width, &vs_height, &this_pitch);
+
+        if (ptr_scrn)
+        {
+            int w, h;
+
+            int p_size;
+            int view_x, view_y, view_w;
+            int hs, hr, vs, vr;
+            int neww, newh;
+            int cw, ch;
+            int microseconds_available = (int)(1000000 / 30);
+
+            microseconds_available = microseconds_available * tab->cpu_free / 100;
+
+            if (pbi)
+            {
+                microseconds_available -= pbi->decode_microseconds;
+
+                if (tab->cpu_free == 0)
+                    microseconds_available = INT_MAX;
+
+                if (tab->post_proc2time == 0)
+                    tab->post_proc2time = pbi->decode_microseconds * 1 / 2;
+
+                if (tab->post_proc4time == 0)
+                    tab->post_proc4time = pbi->decode_microseconds;
+            }
+
+
+            if (tab->ppcount == 0)
+            {
+                tab->post_proc2time = 0;
+                tab->post_proc4time = 0;
+                tab->ppcount = 64;
+            }
+            else
+            {
+                tab->ppcount --;
+            }
+
+            vpxdxv_get_vscreen_view(v_screen, &view_x, &view_y, &view_w, NULL);
+
+            Scale2Ratio(common->horiz_scale, &hr, &hs);
+            Scale2Ratio(common->vert_scale, &vr, &vs);
+
+            if (tab->postproc && tab->passed_in_buffer == 0)
+            {
+                int show_text = 0;
+
+                unsigned char message[512];
+
+                int pp = tab->postproc;
+                int q = (tab->avgq + 4) / 8;
+                int noise = 0;
+
+                vp8_clear_system_state();
+
+                if (pp >= 1000)
+                {
+                    pp -= 1000;
+                    noise = pp / 100;
+                    pp = pp - noise * 100;
+                }
+
+                if (pp >= 300)
+                {
+                    pp -= 300;
+                    show_text = 3;
+                }
+                else if (pp >= 200)
+                {
+                    pp -= 200;
+                    show_text = 2;
+                }
+                else if (pp >= 100)
+                {
+                    pp -= 100;
+                    show_text = 1;
+                }
+
+                if (pbi && (pbi->mb.segmentation_enabled & SEGMENT_PF) && tab->deinterlace)
+                {
+                    de_interlace(common->frame_to_show->y_buffer, common->post_proc_buffer.y_buffer,
+                                 common->post_proc_buffer.y_width, common->post_proc_buffer.y_height,
+                                 common->post_proc_buffer.y_stride);
+
+                    de_interlace(common->frame_to_show->u_buffer, common->post_proc_buffer.u_buffer,
+                                 common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height,
+                                 common->post_proc_buffer.uv_stride);
+                    de_interlace(common->frame_to_show->v_buffer, common->post_proc_buffer.v_buffer,
+                                 common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height,
+                                 common->post_proc_buffer.uv_stride);
+                }
+                else
+                {
+                    if (pp >= 10 && pp <= 20)
+                    {
+                        q = q + (pp - 15) * 10;
+
+                        if (q < 0)
+                            q = 0;
+                    }
+
+                    start_tick = vp8_get_high_res_timer_tick();
+
+                    if (pp > 3 && tab->post_proc4time < microseconds_available)
+                    {
+                        vp8_deblock_and_de_macro_block(common->frame_to_show, &common->post_proc_buffer, q, 1, 0);
+
+                        stop_tick = vp8_get_high_res_timer_tick();
+
+                        if (pbi)
+                            tab->post_proc4time = vp8_get_time_in_micro_sec(start_tick, stop_tick);
+                    }
+
+                    else if (pp > 0 && tab->post_proc2time < microseconds_available)
+                    {
+                        vp8_deblock(common->frame_to_show, &common->post_proc_buffer, q , 1,  0);
+                        stop_tick = vp8_get_high_res_timer_tick();
+
+                        if (pbi)
+                            tab->post_proc2time = vp8_get_time_in_micro_sec(start_tick, stop_tick);
+                    }
+                    else
+                    {
+                        vp8_yv12_copy_frame(common->frame_to_show, &common->post_proc_buffer);
+                    }
+
+                }
+
+                vp8_clear_system_state();
+
+                if (tab->add_noise == 1)
+                {
+
+                    vp8_plane_add_noise(common->post_proc_buffer.y_buffer,
+                                        common->post_proc_buffer.y_width, common->post_proc_buffer.y_height,
+                                        common->post_proc_buffer.y_stride, 63 - q, noise);
+                }
+
+
+                if (show_text == 1)
+                {
+#ifdef PACKET_TESTING
+                    {
+                        VP8_HEADER *oh2 = (VP8_HEADER *) pbi->Source;
+                        sprintf(message, "%8d %d%d%d%d%d size:%d\n",
+                        oh2->frame_number ,
+                        oh2->update_gold  ,
+                        oh2->update_last  ,
+                        oh2->uses_gold    ,
+                        oh2->uses_last    ,
+                        oh2->type,
+                        vpxdxv_get_ximage_csize(src));
+                    }
+#else
+                    sprintf(message, "F:%1ldG:%1ldQ:%3ldF:%3ld,%3ldP:%d_s:%6ld,N:%d,",
+                            (common->frame_type == KEY_FRAME),
+                            common->refresh_golden_frame,
+                            common->base_qindex,
+                            common->filter_level,
+                            q,
+                            tab->postproc,
+                            vpxdxv_get_ximage_csize(src), noise);
+#endif
+
+                    vp8_blit_text(message, common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_stride);
+
+                }
+                else if (show_text == 2)
+                {
+                    int i, j;
+                    unsigned char *y_ptr;
+                    YV12_BUFFER_CONFIG *post = &common->post_proc_buffer;
+                    int mb_rows = post->y_height >> 4;
+                    int mb_cols = post->y_width  >> 4;
+                    int mb_index = 0;
+                    MODE_INFO *mi = common->mi;
+
+                    y_ptr = post->y_buffer + 4 * post->y_stride + 4;
+
+                    // vp8_filter each macro block
+                    for (i = 0; i < mb_rows; i++)
+                    {
+                        for (j = 0; j < mb_cols; j++)
+                        {
+                            char zz[4];
+
+                            if (pp == 4)
+                                sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
+                            else
+                                sprintf(zz, "%c", mi[mb_index].mbmi.ref_frame + 'a');
+
+                            vp8_blit_text(zz, y_ptr, post->y_stride);
+                            mb_index ++;
+                            y_ptr += 16;
+                        }
+
+                        mb_index ++; //border
+                        y_ptr += post->y_stride  * 16 - post->y_width;
+
+                    }
+                }
+                else if (show_text == 3)
+                {
+                    int i, j;
+                    unsigned char *y_ptr;
+                    YV12_BUFFER_CONFIG *post = &common->post_proc_buffer;
+                    int mb_rows = post->y_height >> 4;
+                    int mb_cols = post->y_width  >> 4;
+                    int mb_index = 0;
+                    MODE_INFO *mi = common->mi;
+
+                    y_ptr = post->y_buffer + 4 * post->y_stride + 4;
+
+                    // vp8_filter each macro block
+                    for (i = 0; i < mb_rows; i++)
+                    {
+                        for (j = 0; j < mb_cols; j++)
+                        {
+                            char zz[4];
+
+                            if (j == 0)
+                                sprintf(zz, "%c", '0' + i % 10);
+                            else
+                                sprintf(zz, "%c", '0' + j % 10);
+
+                            vp8_blit_text(zz, y_ptr, post->y_stride);
+                            mb_index ++;
+                            y_ptr += 16;
+                        }
+
+                        y_ptr += post->y_stride  * 16 - post->y_width;
+
+                    }
+                }
+
+                vpx_memcpy(&tab->this_buffer, &common->post_proc_buffer, sizeof(YV12_BUFFER_CONFIG));
+            }
+            else
+            {
+                vpx_memcpy(&tab->this_buffer, common->frame_to_show, sizeof(YV12_BUFFER_CONFIG));
+            }
+
+
+            /* get a frame pointer to the scaled and postprocessed reconstructed buffer */
+            if (tab->passed_in_buffer == 0)
+            {
+                if (common->horiz_scale != NORMAL || common->vert_scale != NORMAL)
+                {
+                    neww = hs * tab->this_buffer.y_width / hr;
+                    newh = vs * tab->this_buffer.y_height / vr;
+
+                    neww += neww & 1;
+
+                    if (tab->hs != hs || tab->hr != hr || tab->vs != vs || tab->vr != vr)
+                    {
+                        vp8_yv12_alloc_frame_buffer(&tab->scaled_buffer, neww, newh , 8);
+                    }
+
+                    vp8_yv12_scale_or_center(&tab->this_buffer,
+                                             &tab->scaled_buffer,
+                                             neww, newh, SCALE_TO_FIT, hs, hr, vs, vr);
+
+                    convert_yv12_buffer_types(&tab->scaled_buffer, frame_buffer);
+
+                    cw = hs * common->Width / hr;
+                    ch = vs * common->Height / vr;
+
+                }
+                else
+                {
+                    convert_yv12_buffer_types(&tab->this_buffer, frame_buffer);
+
+                    cw = common->Width;
+                    ch = common->Height;
+                }
+            }
+            else
+            {
+                convert_yv12_buffer_types(tab->passed_in_buffer, frame_buffer);
+                cw = common->Width;
+                ch = common->Height;
+                tab->passed_in_buffer = 0;
+            }
+
+            frame_buffer->y_width = cw;
+            frame_buffer->y_height = ch;
+            frame_buffer->uv_width = cw / 2;
+            frame_buffer->uv_height = ch / 2;
+
+            p_size = vpx_get_size_of_pixel(tab->bd_tag);
+
+            /* remember to offset if requested */
+            y += view_y;
+            x += view_x ;
+
+            /* for planar destinations */
+            w = view_w;
+            h = vs_height;
+
+            if (w < frame_buffer->y_width)
+            {
+                frame_buffer->y_width = w;
+                frame_buffer->uv_width = (w + 1) / 2;
+            }
+
+            if (h < frame_buffer->y_height)
+            {
+                frame_buffer->y_height = h;
+                frame_buffer->uv_height = (h + 1) / 2;
+            }
+
+            if (frame_buffer->y_width < view_w)
+                x += (view_w - frame_buffer->y_width) / 2;
+
+            if (x & 1)
+                x -= 1;
+
+            if (frame_buffer->y_height < vs_height)
+                y += (vs_height - frame_buffer->y_height) / 2;
+
+
+            ptr_scrn += (x * p_size) + (y * this_pitch);
+
+            frame_buffer->y_stride *= -1;
+            frame_buffer->uv_stride *= -1;
+
+            if (tab->bd_tag == VPXDXV_YV12 || tab->bd_tag == VPXDXV_I420)
+            {
+                if (this_pitch < 0)
+                {
+                    frame_buffer->uv_start = (char *)(ptr_scrn + abs(this_pitch) + abs(this_pitch) * h / 4 + this_pitch / 2);
+                    frame_buffer->uv_dst_area = abs((this_pitch * h) / 4);
+                    frame_buffer->uv_used_area = 0;
+                }
+                else
+                {
+                    frame_buffer->uv_start = (char *)(ptr_scrn + (this_pitch * h));
+                    frame_buffer->uv_dst_area = (((this_pitch + 1) / 2) * ((h + 1) / 2));
+                    frame_buffer->uv_used_area = (((this_pitch + 1) / 2) * frame_buffer->uv_height);
+                }
+            }
+
+            if ((pbi->mb.segmentation_enabled & SEGMENT_PF) && (tab->bd_tag != VPXDXV_YV12 && tab->bd_tag != VPXDXV_I420))
+            {
+                int ypitch = frame_buffer->y_stride;
+                int uvpitch = frame_buffer->uv_stride;
+
+                frame_buffer->y_stride <<= 1;
+                frame_buffer->y_height >>= 1;
+                frame_buffer->uv_stride <<= 1;
+                frame_buffer->uv_height >>= 1;
+
+                ptr_scrn += this_pitch;
+                frame_buffer->y_buffer -= ypitch;
+                frame_buffer->u_buffer -= uvpitch;
+                frame_buffer->v_buffer -= uvpitch;
+                tab->blitter(ptr_scrn, 2 * this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer));
+
+                ptr_scrn -= this_pitch;
+                frame_buffer->y_buffer += ypitch;
+                frame_buffer->u_buffer += uvpitch;
+                frame_buffer->v_buffer += uvpitch;
+                tab->blitter(ptr_scrn, 2 * this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer));
+
+            }
+            else
+            {
+                /* blit the screen */
+                tab->blitter(ptr_scrn, this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer));
+                vpx_log("Decoder: Frame shown \n");
+            }
+
+        }
+        else
+            vpx_log("Decoder: Frame not shown scrn pointer 0\n");
+    }
+    else
+        vpx_log("Decoder: Frame not shown vscreen 0\n");
+
+    return DXV_OK;
+}
+/****************************************************************************
+ *
+ *  ROUTINE       :     onyx_decompress
+ *
+ *  INPUTS        :     None
+ *
+ *  OUTPUTS       :     None
+ *
+ *  RETURNS       :     None.
+ *
+ *  FUNCTION      :
+ *
+ *  SPECIAL NOTES :
+ *
+ ****************************************************************************/
+static
+int onyx_decompress(XIMAGE_HANDLE src, VSCREEN_HANDLE v_screen)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+    unsigned char *c_addr;
+    unsigned int c_size;
+    int w, h, x, y;
+    int vp8_rv;
+
+    c_addr = vpxdxv_get_ximage_cdata_addr(src);
+    c_size = vpxdxv_get_ximage_csize(src);
+    vpxdxv_get_ximage_xywh(src, &x, &y, &w, &h);
+
+    // if we have a compressed frame decompress it ( otherwise we'll just redo
+    // the scaling and postprocessing from the last frame )
+    if (c_addr)
+    {
+        if (c_size != 0)
+        {
+            int flags;
+            int ret_val;
+
+            int f;
+
+            // decode the frame
+            ret_val = vp8d_decompress_frame((VP8D_PTR) this_algorithm_base->my_pbi,
+                                            c_size,
+                                            (char *) c_addr,
+                                            &this_algorithm_base->this_buffer,
+                                            &flags);
+
+
+            f = this_algorithm_base->my_pbi->common.filter_level * 10 / 6;
+
+            if (this_algorithm_base->my_pbi->common.frame_type == KEY_FRAME)
+                this_algorithm_base->avgq = 8 * f;
+            else
+                this_algorithm_base->avgq = this_algorithm_base->avgq * 7 / 8 + f;
+
+
+
+            if (ret_val != 0)
+            {
+                if (ret_val == -1)
+                    return DXV_VERSION_CONFLICT;
+                else
+                    return DXV_BAD_DATA;
+            }
+
+        }
+    }
+
+
+    vp8_rv = onyx_blit(src, v_screen, &this_algorithm_base->frame_buffer, x, y);
+
+
+    return vp8_rv;
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static
+int vp8_ximagedestroy(XIMAGE_HANDLE src)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+
+    if (this_algorithm_base)
+    {
+
+        vp8_yv12_de_alloc_frame_buffer(&this_algorithm_base->scaled_buffer);
+
+        /* safety check in case stopdecode was not called */
+        if (this_algorithm_base->owned)
+            vp8dx_remove_decompressor((VP8D_PTR)(this_algorithm_base->my_pbi));
+
+        duck_free(this_algorithm_base);
+    }
+
+    return DXV_OK;
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static int
+onyx_get_post_proc(XIMAGE_HANDLE src, unsigned int *ppl)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+
+    if (this_algorithm_base)
+    {
+        *ppl = this_algorithm_base->ppl_tag;
+
+        return DXV_OK;
+    }
+
+    return DXV_NULL_BASE;
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static int
+onyx_set_post_proc(XIMAGE_HANDLE src, unsigned int ppl)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+
+    if (this_algorithm_base)
+    {
+        this_algorithm_base->ppl_tag = ppl;
+
+        return DXV_OK;
+    }
+
+    return DXV_NULL_BASE;
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static
+int vp8_ximagestop_decode(XIMAGE_HANDLE src)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+
+    if (this_algorithm_base)
+    {
+
+        vp8_yv12_de_alloc_frame_buffer(&this_algorithm_base->scaled_buffer);
+
+        if (this_algorithm_base->owned)
+            vp8dx_remove_decompressor((VP8D_PTR)(this_algorithm_base->my_pbi));
+
+        this_algorithm_base->owned = 0;
+    }
+
+    return DXV_OK;
+}
+
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static
+int vp8_ximagestart_decode
+(
+    XIMAGE_HANDLE src
+)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+    XIMAGE_INFO_PTR xinfo = vpxdxv_get_ximage_info(src);
+    VP8D_CONFIG ocf;
+
+    if (xinfo)
+    {
+        ocf.Width = xinfo->width;
+        ocf.Height = xinfo->height;
+    }
+
+    if (this_algorithm_base->common == 0)
+    {
+        this_algorithm_base->my_pbi = (VP8D_COMP *) vp8dx_create_decompressor(&ocf);
+        this_algorithm_base->owned = 1;
+        this_algorithm_base->common = &this_algorithm_base->my_pbi->common;
+        this_algorithm_base->avgq = 0;
+
+    }
+
+    this_algorithm_base->passed_in_buffer = 0;
+    this_algorithm_base->post_proc2time = 0;
+    this_algorithm_base->post_proc4time = 0;
+    this_algorithm_base->ppcount = 64;
+
+    return DXV_OK;
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static
+DXV_HANDLE vp8_ximagecreate(XIMAGE_HANDLE src)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base;
+
+    /* create a new algorithm base container */
+    this_algorithm_base = (VP8_XIMAGE_HANDLE)duck_calloc(1, sizeof(VP8_XIMAGE), DMEM_GENERAL);
+
+    if (this_algorithm_base == NULL)
+        return NULL;
+
+    vp8_scale_machine_specific_config();
+
+    vpxdxv_register_ximage_start_decode(src, vp8_ximagestart_decode);
+
+    vpxdxv_register_ximage_stop_decode(src, vp8_ximagestop_decode);
+
+    vpxdxv_register_ximage_destroy(src, vp8_ximagedestroy);
+
+    vpxdxv_register_ximage_dx(src, onyx_decompress);
+
+    vpxdxv_register_ximage_set_parameter(src, onyx_set_parameter);
+
+    vpxdxv_register_ximage_output_format_func(src,
+            onyx_get_output_format,
+            onyx_set_output_format);
+
+    vpxdxv_register_ximage_post_proc_level_func(src,
+            onyx_get_post_proc,
+            onyx_set_post_proc);
+
+    return (DXV_HANDLE)this_algorithm_base;
+}
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+static int store_output_list(unsigned int supported, int count,
+                             unsigned int *outlist)
+{
+    int i = 0, j = 0,
+        ret = DXV_OK;
+
+    while (i < count)
+    {
+        while (supported && !(supported & 0x01))
+        {
+            supported >>= 1;
+            ++j;
+        }
+
+        *(outlist + i) = g_vp8_preferred_output_format_list[j];
+        ++i;
+        ++j;
+        supported >>= 1;
+    }
+
+
+    return ret;
+}
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static int onyx_get_output_list(XIMAGE_INFO_PTR xinfo, unsigned int *outlist,
+                                unsigned int *size)
+{
+    int i,
+        ret = DXV_INVALID_REQUEST;
+    unsigned int supported = 0,
+                 count = 0;
+    (void)xinfo;
+
+    if (size)
+    {
+        for (i = 0; i < sizeof(g_vp8_preferred_output_format_list) / sizeof(unsigned int) && i < 32; ++i)
+        {
+            if (vpx_get_blitter(g_vp8_preferred_output_format_list[i]) != (void *)0xffffffff)
+            {
+                supported |= (1 << i);
+                ++count;
+            }
+        }
+
+        if (outlist)
+        {
+            if (count && ((count + 1) == (*size / sizeof(int))))
+                ret = store_output_list(supported, count, outlist);
+            else
+                *outlist = 0;
+        }
+        else
+        {
+            *size = (count + 1) * sizeof(int);
+            ret = DXV_OK;
+        }
+    }
+
+    return ret;
+}
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+int onyx_init(void)
+{
+    int vp8_rv;
+
+    /* register VPX blitters based on cpu */
+    vpx_set_blit();
+
+    vp8_rv = vpxdxv_register_ximage(vp8_ximagecreate, onyx_get_output_list, VP8_FOURCC);
+    return vp8_rv;
+
+    return DXV_OK;
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+int onyx_exit(void)
+{
+
+    vpxdxv_un_register_ximage(VP8_FOURCC);
+
+    return DXV_OK;
+}
+/****************************************************************************
+ *
+ *  ROUTINE       :  onyx_set_parameter
+ *
+ *  INPUTS        :  XIMAGE_HANDLE src   :
+ *                   int Command             :
+ *                   unsigned long Parameter :
+ *
+ *  OUTPUTS       :  None.
+ *
+ *  RETURNS       :  void
+ *
+ *  FUNCTION      :
+ *
+ *
+ *  SPECIAL NOTES :  None.
+ *
+ ****************************************************************************/
+void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+
+    switch (Command)
+    {
+    case PBC_SET_CPUFREE:
+        this_algorithm_base->cpu_free  = Parameter;
+        break;
+    case PBC_SET_POSTPROC:
+        this_algorithm_base->postproc = Parameter;
+        break;
+
+    case PBC_SET_BLITBUFF:
+        this_algorithm_base->passed_in_buffer = (YV12_BUFFER_CONFIG *) Parameter;
+        break;
+
+    case PBC_SET_REFERENCEFRAME:
+    {
+        VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+        VP8D_COMP *pbi;
+        pbi = tab->my_pbi;
+        vp8_yv12_copy_frame((YV12_BUFFER_CONFIG *) Parameter, &pbi->common.last_frame);
+    }
+    break;
+
+    case PBC_SET_COMMON:
+
+        if (Parameter)
+        {
+            this_algorithm_base->common = (VP8_COMMON *)Parameter;
+        }
+
+        break;
+    case PBC_SET_ADDNOISE:
+        this_algorithm_base->add_noise = Parameter;
+        break;
+    case PBC_SET_DEINTERLACEMODE:
+        this_algorithm_base->deinterlace = Parameter;
+        break;
+
+    }
+}
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static int
+onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *format_tag)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+
+    if (this_algorithm_base)
+    {
+        *format_tag = this_algorithm_base->bd_tag;
+        return DXV_OK;
+    }
+
+    return DXV_NULL_BASE;
+}
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+static int
+onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag)
+{
+    VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
+    int i;
+    unsigned int bd_tag_found;
+
+    if (this_algorithm_base)
+    {
+        i = 0;
+        bd_tag_found = 0;
+
+        while (g_vp8_preferred_output_format_list[i] != 0)
+        {
+            if (g_vp8_preferred_output_format_list[i] == bd_tag)
+            {
+                bd_tag_found = 1;
+                break;
+            }
+
+            i++;
+        }
+
+        if (bd_tag_found)
+        {
+            this_algorithm_base->blitter = (vp8blit_func)vpx_get_blitter(bd_tag);
+            this_algorithm_base->bd_tag = bd_tag;
+            return DXV_OK;
+        }
+
+        return DXV_INVALID_BLIT;
+    }
+
+    return DXV_NULL_BASE;
+}
+
+/*
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+int
+vpx_get_size_of_pixel(unsigned int bd)
+{
+    int vp8_rv;
+
+    switch (bd)
+    {
+    case VPXDXV_YV12:
+    case VPXDXV_I420:
+        vp8_rv = 1;
+        break;
+
+#ifdef _ENABLE_SPLIT_PIXEL_
+    case VPXDXV_SPLIT565:
+#endif
+    case VPXDXV_RGB555:
+    case VPXDXV_RGB565:
+    case VPXDXV_YUY2:
+    case VPXDXV_UYVY:
+    case VPXDXV_YVYU:
+        vp8_rv = 2;
+        break;
+
+    case VPXDXV_RGB888:
+        vp8_rv = 3;
+        break;
+
+    case VPXDXV_RGB8888:
+        vp8_rv = 4;
+        break;
+
+    default:
+        vp8_rv = -1;
+        break;
+    }
+
+    return vp8_rv;
+}
diff --git a/vp8/decoder/x86/x86_dsystemdependent.c b/vp8/decoder/x86/x86_dsystemdependent.c
new file mode 100644 (file)
index 0000000..6d7cc36
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "vpx_ports/x86.h"
+#include "onyxd_int.h"
+
+
+#if HAVE_MMX
+void vp8_dequantize_b_impl_mmx(short *sq, short *dq, short *q);
+
+void vp8_dequantize_b_mmx(BLOCKD *d)
+{
+    short *sq = (short *) d->qcoeff;
+    short *dq = (short *) d->dqcoeff;
+    short *q = (short *) d->dequant;
+    vp8_dequantize_b_impl_mmx(sq, dq, q);
+}
+#endif
+
+void vp8_arch_x86_decode_init(VP8D_COMP *pbi)
+{
+    int flags = x86_simd_caps();
+
+    /* Note:
+     *
+     * This platform can be built without runtime CPU detection as well. If
+     * you modify any of the function mappings present in this file, be sure
+     * to also update them in static mapings (<arch>/filename_<arch>.h)
+     */
+#if CONFIG_RUNTIME_CPU_DETECT
+    /* Override default functions with fastest ones for this CPU. */
+#if HAVE_MMX
+
+    if (flags & HAS_MMX)
+    {
+        pbi->dequant.block   = vp8_dequantize_b_mmx;
+        pbi->dequant.idct    = vp8_dequant_idct_mmx;
+        pbi->dequant.idct_dc = vp8_dequant_dc_idct_mmx;
+    }
+
+#endif
+#endif
+}
diff --git a/vp8/decoder/xprintf.c b/vp8/decoder/xprintf.c
new file mode 100644 (file)
index 0000000..cb2221c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     xprintf.cpp
+*
+*   Description  :     Display a printf style message on the current video frame.
+*
+****************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdarg.h>
+#ifdef _WIN32_WCE
+#include <windows.h>
+#endif
+#include "xprintf.h"
+
+/****************************************************************************
+ *
+ *  ROUTINE       : xprintf
+ *
+ *  INPUTS        : const PB_INSTANCE *ppbi : Pointer to decoder instance.
+ *                  long n_pixel             : Offset into buffer to write text.
+ *                  const char *format      : Format string for print.
+ *                  ...                     : Variable length argument list.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int: Size (in bytes) of the formatted text.
+ *
+ *  FUNCTION      : Display a printf style message on the current video frame.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+int onyx_xprintf(unsigned char *ppbuffer, long n_pixel, long n_size, long n_stride, const char *format, ...)
+{
+    BOOL b_rc;
+    va_list arglist;
+    HFONT hfont, hfonto;
+
+    int rc = 0;
+    char sz_formatted[256] = "";
+    unsigned char *p_dest = &ppbuffer[n_pixel];
+
+#ifdef _WIN32_WCE
+    //  Set up temporary bitmap
+    HDC hdc_memory   = NULL;
+    HBITMAP hbm_temp = NULL;
+    HBITMAP hbm_orig = NULL;
+
+    RECT rect;
+
+    //  Copy bitmap to video frame
+    long x;
+    long y;
+
+    //  Format text
+    va_start(arglist, format);
+    _vsnprintf(sz_formatted, sizeof(sz_formatted), format, arglist);
+    va_end(arglist);
+
+    rect.left   = 0;
+    rect.top    = 0;
+    rect.right  = 8 * strlen(sz_formatted);
+    rect.bottom = 8;
+
+    hdc_memory = create_compatible_dc(NULL);
+
+    if (hdc_memory == NULL)
+        goto Exit;
+
+    hbm_temp = create_bitmap(rect.right, rect.bottom, 1, 1, NULL);
+
+    if (hbm_temp == NULL)
+        goto Exit;
+
+    hbm_orig = (HBITMAP)(select_object(hdc_memory, hbm_temp));
+
+    if (!hbm_orig)
+        goto Exit;
+
+    //  Write text into bitmap
+    //  font?
+    hfont = create_font(8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, "");
+
+    if (hfont == NULL)
+        goto Exit;
+
+    hfonto = (HFONT)(select_object(hdc_memory, hbm_temp));
+
+    if (!hfonto)
+        goto Exit;
+
+    select_object(hdc_memory, hfont);
+    set_text_color(hdc_memory, 1);
+    set_bk_color(hdc_memory, 0);
+    set_bk_mode(hdc_memory, TRANSPARENT);
+
+    b_rc = bit_blt(hdc_memory, rect.left, rect.top, rect.right, rect.bottom, hdc_memory, rect.left, rect.top, BLACKNESS);
+
+    if (!b_rc)
+        goto Exit;
+
+    b_rc = ext_text_out(hdc_memory, 0, 0, ETO_CLIPPED, &rect, sz_formatted, strlen(sz_formatted), NULL);
+
+    if (!b_rc)
+        goto Exit;
+
+    for (y = rect.top; y < rect.bottom; ++y)
+    {
+        for (x = rect.left; x < rect.right; ++x)
+        {
+            if (get_pixel(hdc_memory, x, rect.bottom - 1 - y))
+                p_dest[x] = 255;
+        }
+
+        p_dest += n_stride;
+    }
+
+    rc = strlen(sz_formatted);
+
+Exit:
+
+    if (hbm_temp != NULL)
+    {
+        if (hbm_orig != NULL)
+        {
+            select_object(hdc_memory, hbm_orig);
+        }
+
+        delete_object(hbm_temp);
+    }
+
+    if (hfont != NULL)
+    {
+        if (hfonto != NULL)
+            select_object(hdc_memory, hfonto);
+
+        delete_object(hfont);
+    }
+
+    if (hdc_memory != NULL)
+        delete_dc(hdc_memory);
+
+    hdc_memory = 0;
+
+#endif
+
+    return rc;
+}
diff --git a/vp8/decoder/xprintf.h b/vp8/decoder/xprintf.h
new file mode 100644 (file)
index 0000000..2f175e9
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     xprintf.h
+*
+*   Description  :     Debug print interface header file.
+*
+****************************************************************************/
+#ifndef __INC_XPRINTF_H
+#define __INC_XPRINTF_H
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+
+/****************************************************************************
+*  Functions
+****************************************************************************/
+
+// Display a printf style message on the current video frame
+extern int onyx_xprintf(unsigned char *ppbuffer, long n_pixel, long n_size, long n_stride, const char *format, ...);
+
+#endif
diff --git a/vp8/encoder/arm/armv6/walsh_v6.asm b/vp8/encoder/arm/armv6/walsh_v6.asm
new file mode 100644 (file)
index 0000000..608c9ae
--- /dev/null
@@ -0,0 +1,144 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+    EXPORT |vp8_short_walsh4x4_armv6|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+;short vp8_short_walsh4x4_armv6(short *input, short *output, int pitch)
+|vp8_short_walsh4x4_armv6| PROC
+
+    stmdb       sp!, {r4 - r11, lr}
+
+    mov         r12, r2              ; ugh. not clean
+    ldr         r2, [r0]             ; [1  |  0]
+    ldr         r3, [r0, #4]         ; [3  |  2]
+    ldr         r4, [r0, r12]!       ; [5  |  4]
+    ldr         r5, [r0, #4]         ; [7  |  6]
+    ldr         r6, [r0, r12]!       ; [9  |  8]
+    ldr         r7, [r0, #4]         ; [11 | 10]
+    ldr         r8, [r0, r12]!       ; [13 | 12]
+    ldr         r9, [r0, #4]         ; [15 | 14]
+
+    qsubaddx    r10, r2, r3          ; [c1|a1] [1-2   |   0+3]
+    qaddsubx    r11, r2, r3          ; [b1|d1] [1+2   |   0-3]
+    qsubaddx    r12, r4, r5          ; [c1|a1] [5-6   |   4+7]
+    qaddsubx    lr, r4, r5           ; [b1|d1] [5+6   |   4-7]
+
+    qaddsubx    r2, r10, r11         ; [1 | 2] [c1+d1 | a1-b1]
+    qaddsubx    r3, r11, r10         ; [0 | 3] [b1+a1 | d1-c1]
+    qaddsubx    r4, r12, lr          ; [5 | 6] [c1+d1 | a1-b1]
+    qaddsubx    r5, lr, r12          ; [4 | 7] [b1+a1 | d1-c1]
+
+    qsubaddx    r10, r6, r7          ; [c1|a1] [9-10  |  8+11]
+    qaddsubx    r11, r6, r7          ; [b1|d1] [9+10  |  8-11]
+    qsubaddx    r12, r8, r9          ; [c1|a1] [13-14 | 12+15]
+    qaddsubx    lr, r8, r9           ; [b1|d1] [13+14 | 12-15]
+
+    qaddsubx    r6, r10, r11         ; [9 |10] [c1+d1 | a1-b1]
+    qaddsubx    r7, r11, r10         ; [8 |11] [b1+a1 | d1-c1]
+    qaddsubx    r8, r12, lr          ; [13|14] [c1+d1 | a1-b1]
+    qaddsubx    r9, lr, r12          ; [12|15] [b1+a1 | d1-c1]
+
+    ; first transform complete
+
+    qadd16      r10, r3, r9          ; a1 [0+12  |  3+15]
+    qadd16      r11, r5, r7          ; b1 [4+8   |  7+11]
+    qsub16      r12, r5, r7          ; c1 [4-8   |  7-11]
+    qsub16      lr, r3, r9           ; d1 [0-12  |  3-15]
+
+    qadd16      r3, r10, r11         ; a2 [a1+b1] [0 | 3]
+    qadd16      r5, r12, lr          ; b2 [c1+d1] [4 | 7]
+    qsub16      r7, r10, r11         ; c2 [a1-b1] [8 |11]
+    qsub16      r9, lr, r12          ; d2 [d1-c1] [12|15]
+
+    qadd16      r10, r2, r8          ; a1 [1+13  |  2+14]
+    qadd16      r11, r4, r6          ; b1 [5+9   |  6+10]
+    qsub16      r12, r4, r6          ; c1 [5-9   |  6-10]
+    qsub16      lr, r2, r8           ; d1 [1-13  |  2-14]
+
+    qadd16      r2, r10, r11         ; a2 [a1+b1] [1 | 2]
+    qadd16      r4, r12, lr          ; b2 [c1+d1] [5 | 6]
+    qsub16      r6, r10, r11         ; c2 [a1-b1] [9 |10]
+    qsub16      r8, lr, r12          ; d2 [d1-c1] [13|14]
+
+    ; [a-d]2 += ([a-d]2 > 0)
+
+    asrs        r10, r3, #16
+    addpl       r10, r10, #1         ; [~0]
+    asrs        r11, r2, #16
+    addpl       r11, r11, #1         ; [~1]
+    lsl         r11, r11, #15        ; [1  |  x]
+    pkhtb       r10, r11, r10, asr #1; [1  |  0]
+    str         r10, [r1], #4
+
+    lsls        r11, r2, #16
+    addpl       r11, r11, #0x10000   ; [~2]
+    lsls        r12, r3, #16
+    addpl       r12, r12, #0x10000   ; [~3]
+    asr         r12, r12, #1         ; [3  |  x]
+    pkhtb       r11, r12, r11, asr #17; [3  |  2]
+    str         r11, [r1], #4
+
+    asrs        r2, r5, #16
+    addpl       r2, r2, #1           ; [~4]
+    asrs        r3, r4, #16
+    addpl       r3, r3, #1           ; [~5]
+    lsl         r3, r3, #15          ; [5  |  x]
+    pkhtb       r2, r3, r2, asr #1   ; [5  |  4]
+    str         r2, [r1], #4
+
+    lsls        r2, r4, #16
+    addpl       r2, r2, #0x10000     ; [~6]
+    lsls        r3, r5, #16
+    addpl       r3, r3, #0x10000     ; [~7]
+    asr         r3, r3, #1           ; [7  |  x]
+    pkhtb       r2, r3, r2, asr #17  ; [7  |  6]
+    str         r2, [r1], #4
+
+    asrs        r2, r7, #16
+    addpl       r2, r2, #1           ; [~8]
+    asrs        r3, r6, #16
+    addpl       r3, r3, #1           ; [~9]
+    lsl         r3, r3, #15          ; [9  |  x]
+    pkhtb       r2, r3, r2, asr #1   ; [9  |  8]
+    str         r2, [r1], #4
+
+    lsls        r2, r6, #16
+    addpl       r2, r2, #0x10000     ; [~10]
+    lsls        r3, r7, #16
+    addpl       r3, r3, #0x10000     ; [~11]
+    asr         r3, r3, #1           ; [11 |  x]
+    pkhtb       r2, r3, r2, asr #17  ; [11 | 10]
+    str         r2, [r1], #4
+
+    asrs        r2, r9, #16
+    addpl       r2, r2, #1           ; [~12]
+    asrs        r3, r8, #16
+    addpl       r3, r3, #1           ; [~13]
+    lsl         r3, r3, #15          ; [13 |  x]
+    pkhtb       r2, r3, r2, asr #1   ; [13 | 12]
+    str         r2, [r1], #4
+
+    lsls        r2, r8, #16
+    addpl       r2, r2, #0x10000     ; [~14]
+    lsls        r3, r9, #16
+    addpl       r3, r3, #0x10000     ; [~15]
+    asr         r3, r3, #1           ; [15 |  x]
+    pkhtb       r2, r3, r2, asr #17  ; [15 | 14]
+    str         r2, [r1]
+
+    ldmia       sp!, {r4 - r11, pc}
+    ENDP        ; |vp8_short_walsh4x4_armv6|
+
+    END
diff --git a/vp8/encoder/arm/boolhuff_arm.c b/vp8/encoder/arm/boolhuff_arm.c
new file mode 100644 (file)
index 0000000..e70b3ad
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "boolhuff.h"
+#include "blockd.h"
+
+const unsigned int vp8_prob_cost[256] =
+{
+    2047, 2047, 1791, 1641, 1535, 1452, 1385, 1328, 1279, 1235, 1196, 1161, 1129, 1099, 1072, 1046,
+    1023, 1000,  979,  959,  940,  922,  905,  889,  873,  858,  843,  829,  816,  803,  790,  778,
+    767,  755,  744,  733,  723,  713,  703,  693,  684,  675,  666,  657,  649,  641,  633,  625,
+    617,  609,  602,  594,  587,  580,  573,  567,  560,  553,  547,  541,  534,  528,  522,  516,
+    511,  505,  499,  494,  488,  483,  477,  472,  467,  462,  457,  452,  447,  442,  437,  433,
+    428,  424,  419,  415,  410,  406,  401,  397,  393,  389,  385,  381,  377,  373,  369,  365,
+    361,  357,  353,  349,  346,  342,  338,  335,  331,  328,  324,  321,  317,  314,  311,  307,
+    304,  301,  297,  294,  291,  288,  285,  281,  278,  275,  272,  269,  266,  263,  260,  257,
+    255,  252,  249,  246,  243,  240,  238,  235,  232,  229,  227,  224,  221,  219,  216,  214,
+    211,  208,  206,  203,  201,  198,  196,  194,  191,  189,  186,  184,  181,  179,  177,  174,
+    172,  170,  168,  165,  163,  161,  159,  156,  154,  152,  150,  148,  145,  143,  141,  139,
+    137,  135,  133,  131,  129,  127,  125,  123,  121,  119,  117,  115,  113,  111,  109,  107,
+    105,  103,  101,   99,   97,   95,   93,   92,   90,   88,   86,   84,   82,   81,   79,   77,
+    75,   73,   72,   70,   68,   66,   65,   63,   61,   60,   58,   56,   55,   53,   51,   50,
+    48,   46,   45,   43,   41,   40,   38,   37,   35,   33,   32,   30,   29,   27,   25,   24,
+    22,   21,   19,   18,   16,   15,   13,   12,   10,    9,    7,    6,    4,    3,    1,   1
+};
+
diff --git a/vp8/encoder/arm/csystemdependent.c b/vp8/encoder/arm/csystemdependent.c
new file mode 100644 (file)
index 0000000..0039796
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "variance.h"
+#include "onyx_int.h"
+
+void (*vp8_yv12_copy_partial_frame_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction);
+extern void vp8_yv12_copy_partial_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction);
+extern void vpxyv12_copy_partial_frame_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction);
+
+void vp8_cmachine_specific_config(VP8_COMP *cpi)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    cpi->rtcd.common                         = &cpi->common.rtcd;
+
+#if HAVE_ARMV7
+    cpi->rtcd.variance.sad16x16              = vp8_sad16x16_neon;
+    cpi->rtcd.variance.sad16x8               = vp8_sad16x8_neon;
+    cpi->rtcd.variance.sad8x16               = vp8_sad8x16_neon;
+    cpi->rtcd.variance.sad8x8                = vp8_sad8x8_neon;
+    cpi->rtcd.variance.sad4x4                = vp8_sad4x4_neon;
+
+    cpi->rtcd.variance.var4x4                = vp8_variance4x4_c;
+    cpi->rtcd.variance.var8x8                = vp8_variance8x8_neon;
+    cpi->rtcd.variance.var8x16               = vp8_variance8x16_neon;
+    cpi->rtcd.variance.var16x8               = vp8_variance16x8_neon;
+    cpi->rtcd.variance.var16x16              = vp8_variance16x16_neon;
+
+    cpi->rtcd.variance.subpixvar4x4          = vp8_sub_pixel_variance4x4_c;
+    cpi->rtcd.variance.subpixvar8x8          = vp8_sub_pixel_variance8x8_neon;
+    cpi->rtcd.variance.subpixvar8x16         = vp8_sub_pixel_variance8x16_c;
+    cpi->rtcd.variance.subpixvar16x8         = vp8_sub_pixel_variance16x8_c;
+    cpi->rtcd.variance.subpixvar16x16        = vp8_sub_pixel_variance16x16_neon;
+
+    cpi->rtcd.variance.mse16x16              = vp8_mse16x16_neon;
+    cpi->rtcd.variance.getmbss               = vp8_get_mb_ss_c;
+
+    cpi->rtcd.variance.get16x16prederror     = vp8_get16x16pred_error_neon;
+    cpi->rtcd.variance.get8x8var             = vp8_get8x8var_c;
+    cpi->rtcd.variance.get16x16var           = vp8_get16x16var_c;;
+    cpi->rtcd.variance.get4x4sse_cs          = vp8_get4x4sse_cs_neon;
+
+    cpi->rtcd.fdct.short4x4                  = vp8_short_fdct4x4_neon;
+    cpi->rtcd.fdct.short8x4                  = vp8_short_fdct8x4_neon;
+    cpi->rtcd.fdct.fast4x4                   = vp8_fast_fdct4x4_neon;
+    cpi->rtcd.fdct.fast8x4                   = vp8_fast_fdct8x4_neon;
+    cpi->rtcd.fdct.walsh_short4x4            = vp8_short_walsh4x4_neon;
+
+    cpi->rtcd.encodemb.berr                  = vp8_block_error_c;
+    cpi->rtcd.encodemb.mberr                 = vp8_mbblock_error_c;
+    cpi->rtcd.encodemb.mbuverr               = vp8_mbuverror_c;
+    cpi->rtcd.encodemb.subb                  = vp8_subtract_b_neon;
+    cpi->rtcd.encodemb.submby                = vp8_subtract_mby_neon;
+    cpi->rtcd.encodemb.submbuv               = vp8_subtract_mbuv_neon;
+
+    cpi->rtcd.quantize.quantb                = vp8_regular_quantize_b;
+    cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_neon;
+#elif HAVE_ARMV6
+    cpi->rtcd.variance.sad16x16              = vp8_sad16x16_c;
+    cpi->rtcd.variance.sad16x8               = vp8_sad16x8_c;
+    cpi->rtcd.variance.sad8x16               = vp8_sad8x16_c;
+    cpi->rtcd.variance.sad8x8                = vp8_sad8x8_c;
+    cpi->rtcd.variance.sad4x4                = vp8_sad4x4_c;
+
+    cpi->rtcd.variance.var4x4                = vp8_variance4x4_c;
+    cpi->rtcd.variance.var8x8                = vp8_variance8x8_c;
+    cpi->rtcd.variance.var8x16               = vp8_variance8x16_c;
+    cpi->rtcd.variance.var16x8               = vp8_variance16x8_c;
+    cpi->rtcd.variance.var16x16              = vp8_variance16x16_c;
+
+    cpi->rtcd.variance.subpixvar4x4          = vp8_sub_pixel_variance4x4_c;
+    cpi->rtcd.variance.subpixvar8x8          = vp8_sub_pixel_variance8x8_c;
+    cpi->rtcd.variance.subpixvar8x16         = vp8_sub_pixel_variance8x16_c;
+    cpi->rtcd.variance.subpixvar16x8         = vp8_sub_pixel_variance16x8_c;
+    cpi->rtcd.variance.subpixvar16x16        = vp8_sub_pixel_variance16x16_c;
+
+    cpi->rtcd.variance.mse16x16              = vp8_mse16x16_c;
+    cpi->rtcd.variance.getmbss               = vp8_get_mb_ss_c;
+
+    cpi->rtcd.variance.get16x16prederror     = vp8_get16x16pred_error_c;
+    cpi->rtcd.variance.get8x8var             = vp8_get8x8var_c;
+    cpi->rtcd.variance.get16x16var           = vp8_get16x16var_c;;
+    cpi->rtcd.variance.get4x4sse_cs          = vp8_get4x4sse_cs_c;
+
+    cpi->rtcd.fdct.short4x4                  = vp8_short_fdct4x4_c;
+    cpi->rtcd.fdct.short8x4                  = vp8_short_fdct8x4_c;
+    cpi->rtcd.fdct.fast4x4                   = vp8_fast_fdct4x4_c;
+    cpi->rtcd.fdct.fast8x4                   = vp8_fast_fdct8x4_c;
+    cpi->rtcd.fdct.walsh_short4x4            = vp8_short_walsh4x4_armv6;
+
+    cpi->rtcd.encodemb.berr                  = vp8_block_error_c;
+    cpi->rtcd.encodemb.mberr                 = vp8_mbblock_error_c;
+    cpi->rtcd.encodemb.mbuverr               = vp8_mbuverror_c;
+    cpi->rtcd.encodemb.subb                  = vp8_subtract_b_c;
+    cpi->rtcd.encodemb.submby                = vp8_subtract_mby_c;
+    cpi->rtcd.encodemb.submbuv               = vp8_subtract_mbuv_c;
+
+    cpi->rtcd.quantize.quantb                = vp8_regular_quantize_b;
+    cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_c;
+#else
+    //pure c
+    cpi->rtcd.variance.sad16x16              = vp8_sad16x16_c;
+    cpi->rtcd.variance.sad16x8               = vp8_sad16x8_c;
+    cpi->rtcd.variance.sad8x16               = vp8_sad8x16_c;
+    cpi->rtcd.variance.sad8x8                = vp8_sad8x8_c;
+    cpi->rtcd.variance.sad4x4                = vp8_sad4x4_c;
+
+    cpi->rtcd.variance.var4x4                = vp8_variance4x4_c;
+    cpi->rtcd.variance.var8x8                = vp8_variance8x8_c;
+    cpi->rtcd.variance.var8x16               = vp8_variance8x16_c;
+    cpi->rtcd.variance.var16x8               = vp8_variance16x8_c;
+    cpi->rtcd.variance.var16x16              = vp8_variance16x16_c;
+
+    cpi->rtcd.variance.subpixvar4x4          = vp8_sub_pixel_variance4x4_c;
+    cpi->rtcd.variance.subpixvar8x8          = vp8_sub_pixel_variance8x8_c;
+    cpi->rtcd.variance.subpixvar8x16         = vp8_sub_pixel_variance8x16_c;
+    cpi->rtcd.variance.subpixvar16x8         = vp8_sub_pixel_variance16x8_c;
+    cpi->rtcd.variance.subpixvar16x16        = vp8_sub_pixel_variance16x16_c;
+
+    cpi->rtcd.variance.mse16x16              = vp8_mse16x16_c;
+    cpi->rtcd.variance.getmbss               = vp8_get_mb_ss_c;
+
+    cpi->rtcd.variance.get16x16prederror     = vp8_get16x16pred_error_c;
+    cpi->rtcd.variance.get8x8var             = vp8_get8x8var_c;
+    cpi->rtcd.variance.get16x16var           = vp8_get16x16var_c;;
+    cpi->rtcd.variance.get4x4sse_cs          = vp8_get4x4sse_cs_c;
+
+    cpi->rtcd.fdct.short4x4                  = vp8_short_fdct4x4_c;
+    cpi->rtcd.fdct.short8x4                  = vp8_short_fdct8x4_c;
+    cpi->rtcd.fdct.fast4x4                   = vp8_fast_fdct4x4_c;
+    cpi->rtcd.fdct.fast8x4                   = vp8_fast_fdct8x4_c;
+    cpi->rtcd.fdct.walsh_short4x4            = vp8_short_walsh4x4_c;
+
+    cpi->rtcd.encodemb.berr                  = vp8_block_error_c;
+    cpi->rtcd.encodemb.mberr                 = vp8_mbblock_error_c;
+    cpi->rtcd.encodemb.mbuverr               = vp8_mbuverror_c;
+    cpi->rtcd.encodemb.subb                  = vp8_subtract_b_c;
+    cpi->rtcd.encodemb.submby                = vp8_subtract_mby_c;
+    cpi->rtcd.encodemb.submbuv               = vp8_subtract_mbuv_c;
+
+    cpi->rtcd.quantize.quantb                = vp8_regular_quantize_b;
+    cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_c;
+#endif
+#endif
+
+#if HAVE_ARMV7
+    vp8_yv12_copy_partial_frame_ptr = vpxyv12_copy_partial_frame_neon;
+#else
+    vp8_yv12_copy_partial_frame_ptr = vp8_yv12_copy_partial_frame;
+#endif
+}
diff --git a/vp8/encoder/arm/dct_arm.h b/vp8/encoder/arm/dct_arm.h
new file mode 100644 (file)
index 0000000..a671862
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef DCT_ARM_H
+#define DCT_ARM_H
+
+#if HAVE_ARMV6
+extern prototype_fdct(vp8_short_walsh4x4_armv6);
+
+#undef  vp8_fdct_walsh_short4x4
+#define vp8_fdct_walsh_short4x4 vp8_short_walsh4x4_armv6
+#endif
+
+#if HAVE_ARMV7
+extern prototype_fdct(vp8_short_fdct4x4_neon);
+extern prototype_fdct(vp8_short_fdct8x4_neon);
+extern prototype_fdct(vp8_fast_fdct4x4_neon);
+extern prototype_fdct(vp8_fast_fdct8x4_neon);
+extern prototype_fdct(vp8_short_walsh4x4_neon);
+
+#undef  vp8_fdct_short4x4
+#define vp8_fdct_short4x4 vp8_short_fdct4x4_neon
+
+#undef  vp8_fdct_short8x4
+#define vp8_fdct_short8x4 vp8_short_fdct8x4_neon
+
+#undef  vp8_fdct_fast4x4
+#define vp8_fdct_fast4x4 vp8_fast_fdct4x4_neon
+
+#undef  vp8_fdct_fast8x4
+#define vp8_fdct_fast8x4 vp8_fast_fdct8x4_neon
+
+#undef  vp8_fdct_walsh_short4x4
+#define vp8_fdct_walsh_short4x4 vp8_short_walsh4x4_neon
+
+#endif
+
+#endif
diff --git a/vp8/encoder/arm/encodemb_arm.c b/vp8/encoder/arm/encodemb_arm.c
new file mode 100644 (file)
index 0000000..3f1d053
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "encodemb.h"
+#include "reconinter.h"
+#include "quantize.h"
+#include "invtrans.h"
+#include "recon.h"
+#include "reconintra.h"
+#include "dct.h"
+#include "vpx_mem/vpx_mem.h"
+
+extern void vp8_subtract_b_neon_func(short *diff, unsigned char *src, unsigned char *pred, int stride, int pitch);
+
+void vp8_subtract_b_neon(BLOCK *be, BLOCKD *bd, int pitch)
+{
+    unsigned char *src_ptr = (*(be->base_src) + be->src);
+    short *diff_ptr = be->src_diff;
+    unsigned char *pred_ptr = bd->predictor;
+    int src_stride = be->src_stride;
+
+    vp8_subtract_b_neon_func(diff_ptr, src_ptr, pred_ptr, src_stride, pitch);
+}
diff --git a/vp8/encoder/arm/encodemb_arm.h b/vp8/encoder/arm/encodemb_arm.h
new file mode 100644 (file)
index 0000000..28f9e5c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef ENCODEMB_ARM_H
+#define ENCODEMB_ARM_H
+
+#if HAVE_ARMV7
+//extern prototype_berr(vp8_block_error_c);
+//extern prototype_mberr(vp8_mbblock_error_c);
+//extern prototype_mbuverr(vp8_mbuverror_c);
+
+extern prototype_subb(vp8_subtract_b_neon);
+extern prototype_submby(vp8_subtract_mby_neon);
+extern prototype_submbuv(vp8_subtract_mbuv_neon);
+
+//#undef  vp8_encodemb_berr
+//#define vp8_encodemb_berr vp8_block_error_c
+
+//#undef  vp8_encodemb_mberr
+//#define vp8_encodemb_mberr vp8_mbblock_error_c
+
+//#undef  vp8_encodemb_mbuverr
+//#define vp8_encodemb_mbuverr vp8_mbuverror_c
+
+#undef  vp8_encodemb_subb
+#define vp8_encodemb_subb vp8_subtract_b_neon
+
+#undef  vp8_encodemb_submby
+#define vp8_encodemb_submby vp8_subtract_mby_neon
+
+#undef  vp8_encodemb_submbuv
+#define vp8_encodemb_submbuv vp8_subtract_mbuv_neon
+
+#endif
+
+#endif
diff --git a/vp8/encoder/arm/mcomp_arm.c b/vp8/encoder/arm/mcomp_arm.c
new file mode 100644 (file)
index 0000000..07f2186
--- /dev/null
@@ -0,0 +1,1662 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "mcomp.h"
+#include "vpx_mem/vpx_mem.h"
+
+#include <stdio.h>
+#include <limits.h>
+#include <math.h>
+
+#ifdef ENTROPY_STATS
+static int mv_ref_ct [31] [4] [2];
+static int mv_mode_cts [4] [2];
+#endif
+
+static int mv_bits_sadcost[256];
+
+extern unsigned int vp8_sub_pixel_variance16x16s_neon
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+);
+extern unsigned int vp8_sub_pixel_variance16x16s_4_0_neon
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+);
+extern unsigned int vp8_sub_pixel_variance16x16s_0_4_neon
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+);
+extern unsigned int vp8_sub_pixel_variance16x16s_4_4_neon
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+);
+
+void vp8cx_init_mv_bits_sadcost()
+{
+    int i;
+
+    for (i = 0; i < 256; i++)
+    {
+        mv_bits_sadcost[i] = (int)sqrt(i * 16);
+    }
+}
+
+
+int vp8_mv_bit_cost(MV *mv, MV *ref, int *mvcost[2], int Weight)
+{
+    // MV costing is based on the distribution of vectors in the previous frame and as such will tend to
+    // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
+    // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
+    // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
+    return ((mvcost[0][(mv->row - ref->row) >> 1] + mvcost[1][(mv->col - ref->col) >> 1]) * Weight) >> 7;
+}
+
+int vp8_mv_err_cost(MV *mv, MV *ref, int *mvcost[2], int error_per_bit)
+{
+    //int i;
+    //return ((mvcost[0][(mv->row - ref->row)>>1] + mvcost[1][(mv->col - ref->col)>>1] + 128) * error_per_bit) >> 8;
+    //return ( (vp8_mv_bit_cost(mv,  ref, mvcost, 100) + 128) * error_per_bit) >> 8;
+
+    //i = (vp8_mv_bit_cost(mv,  ref, mvcost, 100) * error_per_bit + 128) >> 8;
+    return ((mvcost[0][(mv->row - ref->row) >> 1] + mvcost[1][(mv->col - ref->col) >> 1]) * error_per_bit + 128) >> 8;
+    //return (vp8_mv_bit_cost(mv,  ref, mvcost, 128) * error_per_bit + 128) >> 8;
+}
+
+
+static int mv_bits(MV *mv, MV *ref, int *mvcost[2])
+{
+    // get the estimated number of bits for a motion vector, to be used for costing in SAD based
+    // motion estimation
+    return ((mvcost[0][(mv->row - ref->row) >> 1]  +  mvcost[1][(mv->col - ref->col)>> 1]) + 128) >> 8;
+}
+
+void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride)
+{
+    int Len;
+    int search_site_count = 0;
+
+
+    // Generate offsets for 4 search sites per step.
+    Len = MAX_FIRST_STEP;
+    x->ss[search_site_count].mv.col = 0;
+    x->ss[search_site_count].mv.row = 0;
+    x->ss[search_site_count].offset = 0;
+    search_site_count++;
+
+    while (Len > 0)
+    {
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = -Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = Len;
+        search_site_count++;
+
+        // Contract.
+        Len /= 2;
+    }
+
+    x->ss_count = search_site_count;
+    x->searches_per_step = 4;
+}
+
+void vp8_init3smotion_compensation(MACROBLOCK *x, int stride)
+{
+    int Len;
+    int search_site_count = 0;
+
+    // Generate offsets for 8 search sites per step.
+    Len = MAX_FIRST_STEP;
+    x->ss[search_site_count].mv.col = 0;
+    x->ss[search_site_count].mv.row = 0;
+    x->ss[search_site_count].offset = 0;
+    search_site_count++;
+
+    while (Len > 0)
+    {
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = -Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride - Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride + Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride - Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride + Len;
+        search_site_count++;
+
+
+        // Contract.
+        Len /= 2;
+    }
+
+    x->ss_count = search_site_count;
+    x->searches_per_step = 8;
+}
+
+
+#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+#define PRE(r,c) (*(d->base_pre) + d->pre + ((r)>>2) * d->pre_stride + ((c)>>2)) // pointer to predictor base of a motionvector
+#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
+#define DIST(r,c) svf( PRE(r,c), d->pre_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
+#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
+#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
+#define CHECK_BETTER(v,r,c) IFMVCV(r,c,{if((v = ERR(r,c)) < besterr) { besterr = v; br=r; bc=c; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MAX(x,y) (((x)>(y))?(x):(y))
+
+//#define CHECK_BETTER(v,r,c) if((v = ERR(r,c)) < besterr) { besterr = v; br=r; bc=c; }
+
+int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->row) * d->pre_stride + bestmv->col;
+    unsigned char *z = (*(b->base_src) + b->src);
+
+    int rr = ref_mv->row >> 1, rc = ref_mv->col >> 1;
+    int br = bestmv->row << 2, bc = bestmv->col << 2;
+    int tr = br, tc = bc;
+    unsigned int besterr = INT_MAX;
+    unsigned int left, right, up, down, diag;
+    unsigned int sse;
+    unsigned int whichdir;
+    unsigned int halfiters = 4;
+    unsigned int quarteriters = 4;
+
+    int minc = MAX(x->mv_col_min << 2, (ref_mv->col >> 1) - ((1 << mvlong_width) - 1));
+    int maxc = MIN(x->mv_col_max << 2, (ref_mv->col >> 1) + ((1 << mvlong_width) - 1));
+    int minr = MAX(x->mv_row_min << 2, (ref_mv->row >> 1) - ((1 << mvlong_width) - 1));
+    int maxr = MIN(x->mv_row_max << 2, (ref_mv->row >> 1) + ((1 << mvlong_width) - 1));
+
+    // central mv
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+
+    // calculate central point error
+    besterr = vf(y, d->pre_stride, z, b->src_stride, &sse);
+    besterr += vp8_mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+
+    // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
+    while (--halfiters)
+    {
+        // 1/2 pel
+        CHECK_BETTER(left, tr, tc - 2);
+        CHECK_BETTER(right, tr, tc + 2);
+        CHECK_BETTER(up, tr - 2, tc);
+        CHECK_BETTER(down, tr + 2, tc);
+
+        whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+        switch (whichdir)
+        {
+        case 0:
+            CHECK_BETTER(diag, tr - 2, tc - 2);
+            break;
+        case 1:
+            CHECK_BETTER(diag, tr - 2, tc + 2);
+            break;
+        case 2:
+            CHECK_BETTER(diag, tr + 2, tc - 2);
+            break;
+        case 3:
+            CHECK_BETTER(diag, tr + 2, tc + 2);
+            break;
+        }
+
+        // no reason to check the same one again.
+        if (tr == br && tc == bc)
+            break;
+
+        tr = br;
+        tc = bc;
+    }
+
+    // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
+    // 1/4 pel
+    while (--quarteriters)
+    {
+        CHECK_BETTER(left, tr, tc - 1);
+        CHECK_BETTER(right, tr, tc + 1);
+        CHECK_BETTER(up, tr - 1, tc);
+        CHECK_BETTER(down, tr + 1, tc);
+
+        whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+        switch (whichdir)
+        {
+        case 0:
+            CHECK_BETTER(diag, tr - 1, tc - 1);
+            break;
+        case 1:
+            CHECK_BETTER(diag, tr - 1, tc + 1);
+            break;
+        case 2:
+            CHECK_BETTER(diag, tr + 1, tc - 1);
+            break;
+        case 3:
+            CHECK_BETTER(diag, tr + 1, tc + 1);
+            break;
+        }
+
+        // no reason to check the same one again.
+        if (tr == br && tc == bc)
+            break;
+
+        tr = br;
+        tc = bc;
+    }
+
+    bestmv->row = br << 1;
+    bestmv->col = bc << 1;
+
+    if ((abs(bestmv->col - ref_mv->col) > MAX_FULL_PEL_VAL) || (abs(bestmv->row - ref_mv->row) > MAX_FULL_PEL_VAL))
+        return INT_MAX;
+
+    return besterr;
+}
+#undef MVC
+#undef PRE
+#undef SP
+#undef DIST
+#undef ERR
+#undef CHECK_BETTER
+#undef MIN
+#undef MAX
+int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    int bestmse = INT_MAX;
+    MV startmv;
+    //MV this_mv;
+    MV this_mv;
+    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->row) * d->pre_stride + bestmv->col;
+    unsigned char *z = (*(b->base_src) + b->src);
+    int left, right, up, down, diag;
+    unsigned int sse;
+    int whichdir ;
+
+
+    // Trap uncodable vectors
+    if ((abs((bestmv->col << 3) - ref_mv->col) > MAX_FULL_PEL_VAL) || (abs((bestmv->row << 3) - ref_mv->row) > MAX_FULL_PEL_VAL))
+    {
+        bestmv->row <<= 3;
+        bestmv->col <<= 3;
+        return INT_MAX;
+    }
+
+    // central mv
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+    startmv = *bestmv;
+
+    // calculate central point error
+    bestmse = vf(y, d->pre_stride, z, b->src_stride, &sse);
+    bestmse += vp8_mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+
+    // go left then right and check error
+    this_mv.row = startmv.row;
+    this_mv.col = ((startmv.col - 8) | 4);
+    left = vp8_sub_pixel_variance16x16s_4_0_neon(y - 1, d->pre_stride, z, b->src_stride, &sse);
+    left += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+    }
+
+    this_mv.col += 8;
+    right = vp8_sub_pixel_variance16x16s_4_0_neon(y, d->pre_stride, z, b->src_stride, &sse);
+    right += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+    }
+
+    // go up then down and check error
+    this_mv.col = startmv.col;
+    this_mv.row = ((startmv.row - 8) | 4);
+    up = vp8_sub_pixel_variance16x16s_0_4_neon(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
+    up += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+    }
+
+    this_mv.row += 8;
+    down = vp8_sub_pixel_variance16x16s_0_4_neon(y, d->pre_stride, z, b->src_stride, &sse);
+    down += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+    }
+
+
+    // now check 1 more diagonal
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+    //for(whichdir =0;whichdir<4;whichdir++)
+    //{
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = vp8_sub_pixel_variance16x16s_4_4_neon(y - 1 - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
+        break;
+    case 1:
+        this_mv.col += 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = vp8_sub_pixel_variance16x16s_4_4_neon(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
+        break;
+    case 2:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row += 4;
+        diag = vp8_sub_pixel_variance16x16s_4_4_neon(y - 1, d->pre_stride, z, b->src_stride, &sse);
+        break;
+    case 3:
+        this_mv.col += 4;
+        this_mv.row += 4;
+        diag = vp8_sub_pixel_variance16x16s_4_4_neon(y, d->pre_stride, z, b->src_stride, &sse);
+        break;
+    }
+
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+//  }
+
+
+    // time to check quarter pels.
+    if (bestmv->row < startmv.row)
+        y -= d->pre_stride;
+
+    if (bestmv->col < startmv.col)
+        y--;
+
+    startmv = *bestmv;
+
+
+
+    // go left then right and check error
+    this_mv.row = startmv.row;
+
+    if (startmv.col & 7)
+    {
+        this_mv.col = startmv.col - 2;
+        left = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    }
+    else
+    {
+        this_mv.col = (startmv.col - 8) | 6;
+        left = svf(y - 1, d->pre_stride, 6, this_mv.row & 7, z, b->src_stride, &sse);
+    }
+
+    left += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+    }
+
+    this_mv.col += 4;
+    right = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    right += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+    }
+
+    // go up then down and check error
+    this_mv.col = startmv.col;
+
+    if (startmv.row & 7)
+    {
+        this_mv.row = startmv.row - 2;
+        up = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    }
+    else
+    {
+        this_mv.row = (startmv.row - 8) | 6;
+        up = svf(y - d->pre_stride, d->pre_stride, this_mv.col & 7, 6, z, b->src_stride, &sse);
+    }
+
+    up += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+    }
+
+    this_mv.row += 4;
+    down = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    down += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+    }
+
+
+    // now check 1 more diagonal
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+//  for(whichdir=0;whichdir<4;whichdir++)
+//  {
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+
+        if (startmv.row & 7)
+        {
+            this_mv.row -= 2;
+
+            if (startmv.col & 7)
+            {
+                this_mv.col -= 2;
+                diag = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+            }
+            else
+            {
+                this_mv.col = (startmv.col - 8) | 6;
+                diag = svf(y - 1, d->pre_stride, 6, this_mv.row & 7, z, b->src_stride, &sse);;
+            }
+        }
+        else
+        {
+            this_mv.row = (startmv.row - 8) | 6;
+
+            if (startmv.col & 7)
+            {
+                this_mv.col -= 2;
+                diag = svf(y - d->pre_stride, d->pre_stride, this_mv.col & 7, 6, z, b->src_stride, &sse);
+            }
+            else
+            {
+                this_mv.col = (startmv.col - 8) | 6;
+                diag = svf(y - d->pre_stride - 1, d->pre_stride, 6, 6, z, b->src_stride, &sse);
+            }
+        }
+
+        break;
+    case 1:
+        this_mv.col += 2;
+
+        if (startmv.row & 7)
+        {
+            this_mv.row -= 2;
+            diag = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+        }
+        else
+        {
+            this_mv.row = (startmv.row - 8) | 6;
+            diag = svf(y - d->pre_stride, d->pre_stride, this_mv.col & 7, 6, z, b->src_stride, &sse);
+        }
+
+        break;
+    case 2:
+        this_mv.row += 2;
+
+        if (startmv.col & 7)
+        {
+            this_mv.col -= 2;
+            diag = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+        }
+        else
+        {
+            this_mv.col = (startmv.col - 8) | 6;
+            diag = svf(y - 1, d->pre_stride, 6, this_mv.row & 7, z, b->src_stride, &sse);;
+        }
+
+        break;
+    case 3:
+        this_mv.col += 2;
+        this_mv.row += 2;
+        diag = svf(y, d->pre_stride,  this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+        break;
+    }
+
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+//  }
+
+    return bestmse;
+}
+
+int vp8_find_best_half_pixel_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    int bestmse = INT_MAX;
+    MV startmv;
+    //MV this_mv;
+    MV this_mv;
+    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->row) * d->pre_stride + bestmv->col;
+    unsigned char *z = (*(b->base_src) + b->src);
+    int left, right, up, down, diag;
+    unsigned int sse;
+
+    // Trap uncodable vectors
+    if ((abs((bestmv->col << 3) - ref_mv->col) > MAX_FULL_PEL_VAL) || (abs((bestmv->row << 3) - ref_mv->row) > MAX_FULL_PEL_VAL))
+    {
+        bestmv->row <<= 3;
+        bestmv->col <<= 3;
+        return INT_MAX;
+    }
+
+    // central mv
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+    startmv = *bestmv;
+
+    // calculate central point error
+    bestmse = vf(y, d->pre_stride, z, b->src_stride, &sse);
+    bestmse += vp8_mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+
+    // go left then right and check error
+    this_mv.row = startmv.row;
+    this_mv.col = ((startmv.col - 8) | 4);
+    left = vp8_sub_pixel_variance16x16s_4_0_neon(y - 1, d->pre_stride, z, b->src_stride, &sse);
+    left += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+    }
+
+    this_mv.col += 8;
+    right = vp8_sub_pixel_variance16x16s_4_0_neon(y, d->pre_stride, z, b->src_stride, &sse);
+    right += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+    }
+
+    // go up then down and check error
+    this_mv.col = startmv.col;
+    this_mv.row = ((startmv.row - 8) | 4);
+    up = vp8_sub_pixel_variance16x16s_0_4_neon(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
+    up += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+    }
+
+    this_mv.row += 8;
+    down = vp8_sub_pixel_variance16x16s_0_4_neon(y, d->pre_stride, z, b->src_stride, &sse);
+    down += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+    }
+
+    // somewhat strangely not doing all the diagonals for half pel is slower than doing them.
+#if 0
+    // now check 1 more diagonal -
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = svf(y - 1 - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 1:
+        this_mv.col += 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = svf(y - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 2:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row += 4;
+        diag = svf(y - 1, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 3:
+        this_mv.col += 4;
+        this_mv.row += 4;
+        diag = svf(y, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    }
+
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+#else
+    this_mv.col = (this_mv.col - 8) | 4;
+    this_mv.row = (this_mv.row - 8) | 4;
+    diag = vp8_sub_pixel_variance16x16s_4_4_neon(y - 1 - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+    this_mv.col += 8;
+    diag = vp8_sub_pixel_variance16x16s_4_4_neon(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+    this_mv.col = (this_mv.col - 8) | 4;
+    this_mv.row = startmv.row + 4;
+    diag = vp8_sub_pixel_variance16x16s_4_4_neon(y - 1, d->pre_stride, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+    this_mv.col += 8;
+    diag = vp8_sub_pixel_variance16x16s_4_4_neon(y, d->pre_stride, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+#endif
+    return bestmse;
+}
+
+#if 1
+
+#define MVC(r,c) (((mvsadcost[0][((r)<<2)-rr] + mvsadcost[1][((c)<<2) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+#define PRE(r,c) (*(d->base_pre) + d->pre + (r) * d->pre_stride + (c)) // pointer to predictor base of a motionvector
+#define DIST(r,c,v) sf( src,src_stride,PRE(r,c),d->pre_stride, v) // returns sad error score.
+#define ERR(r,c,v) (MVC(r,c)+DIST(r,c,v)) // returns distortion + motion vector cost
+#define CHECK_BETTER(v,r,c) if ((v = ERR(r,c,besterr)) < besterr) { besterr = v; br=r; bc=c; } // checks if (r,c) has better score than previous best
+const MV next_chkpts[6][3] =
+{
+    {{ -2, 0}, { -1, -2}, {1, -2}},
+    {{ -1, -2}, {1, -2}, {2, 0}},
+    {{1, -2}, {2, 0}, {1, 2}},
+    {{2, 0}, {1, 2}, { -1, 2}},
+    {{1, 2}, { -1, 2}, { -2, 0}},
+    {{ -1, 2}, { -2, 0}, { -1, -2}}
+};
+int vp8_hex_search
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_t vf,
+    vp8_sad_fn_t      sf,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    MV hex[6] = { { -1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0} } ;
+    MV neighbors[8] = { { -1, -1}, { -1, 0}, { -1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} } ;
+    int i, j;
+    unsigned char *src = (*(b->base_src) + b->src);
+    int src_stride = b->src_stride;
+    int rr = ref_mv->row, rc = ref_mv->col, br = rr >> 3, bc = rc >> 3, tr, tc;
+    unsigned int besterr, thiserr = 0x7fffffff;
+    int k = -1, tk;
+
+    if (bc < x->mv_col_min) bc = x->mv_col_min;
+
+    if (bc > x->mv_col_max) bc = x->mv_col_max;
+
+    if (br < x->mv_row_min) br = x->mv_row_min;
+
+    if (br > x->mv_row_max) br = x->mv_row_max;
+
+    rr >>= 1;
+    rc >>= 1;
+
+    besterr = ERR(br, bc, thiserr);
+
+    // hex search
+    //j=0
+    tr = br;
+    tc = bc;
+
+    for (i = 0; i < 6; i++)
+    {
+        int nr = tr + hex[i].row, nc = tc + hex[i].col;
+
+        if (nc < x->mv_col_min) continue;
+
+        if (nc > x->mv_col_max) continue;
+
+        if (nr < x->mv_row_min) continue;
+
+        if (nr > x->mv_row_max) continue;
+
+        //CHECK_BETTER(thiserr,nr,nc);
+        if ((thiserr = ERR(nr, nc, besterr)) < besterr)
+        {
+            besterr = thiserr;
+            br = nr;
+            bc = nc;
+            k = i;
+        }
+    }
+
+    if (tr == br && tc == bc)
+        goto cal_neighbors;
+
+    for (j = 1; j < 127; j++)
+    {
+        tr = br;
+        tc = bc;
+        tk = k;
+
+        for (i = 0; i < 3; i++)
+        {
+            int nr = tr + next_chkpts[tk][i].row, nc = tc + next_chkpts[tk][i].col;
+
+            if (nc < x->mv_col_min) continue;
+
+            if (nc > x->mv_col_max) continue;
+
+            if (nr < x->mv_row_min) continue;
+
+            if (nr > x->mv_row_max) continue;
+
+            //CHECK_BETTER(thiserr,nr,nc);
+            if ((thiserr = ERR(nr, nc, besterr)) < besterr)
+            {
+                besterr = thiserr;
+                br = nr;
+                bc = nc; //k=(tk+5+i)%6;}
+                k = tk + 5 + i;
+
+                if (k >= 12) k -= 12;
+                else if (k >= 6) k -= 6;
+            }
+        }
+
+        if (tr == br && tc == bc)
+            break;
+    }
+
+    // check 8 1 away neighbors
+cal_neighbors:
+    tr = br;
+    tc = bc;
+
+    for (i = 0; i < 8; i++)
+    {
+        int nr = tr + neighbors[i].row, nc = tc + neighbors[i].col;
+
+        if (nc < x->mv_col_min) continue;
+
+        if (nc > x->mv_col_max) continue;
+
+        if (nr < x->mv_row_min) continue;
+
+        if (nr > x->mv_row_max) continue;
+
+        CHECK_BETTER(thiserr, nr, nc);
+    }
+
+    best_mv->row = br;
+    best_mv->col = bc;
+
+    return vf(src, src_stride, PRE(br, bc), d->pre_stride, &thiserr) + MVC(br, bc) ;
+}
+#undef MVC
+#undef PRE
+#undef SP
+#undef DIST
+#undef ERR
+#undef CHECK_BETTER
+
+#else
+
+#define MVC(r,c) (((mvsadcost[0][((r)<<2)-rr] + mvsadcost[1][((c)<<2) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+#define PRE(r,c) (*(d->base_pre) + d->pre + (r) * d->pre_stride + (c)) // pointer to predictor base of a motionvector
+#define DIST(r,c,v) sf( src,src_stride,PRE(r,c),d->pre_stride, v) // returns sad error score.
+#define ERR(r,c,v) (MVC(r,c)+DIST(r,c,v)) // returns distortion + motion vector cost
+#define CHECK_BETTER(v,r,c) if ((v = ERR(r,c,besterr)) < besterr) { besterr = v; br=r; bc=c; } // checks if (r,c) has better score than previous best
+
+int vp8_hex_search
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_t vf,
+    vp8_sad_fn_t      sf,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    MV hex[6] = { { -2, 0}, { -1, -2}, { -1, 2}, {2, 0}, {1, 2}, {1, -2} } ;
+    MV neighbors[8] = { { -1, -1}, { -1, 0}, { -1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} } ;
+    int i, j;
+    unsigned char *src = (*(b->base_src) + b->src);
+    int src_stride = b->src_stride;
+    //int rr= ref_mv->row,rc= ref_mv->col,br=rr,bc=rc,tr,tc;
+    int rr = ref_mv->row, rc = ref_mv->col, br = rr >> 3, bc = rc >> 3, tr, tc;
+    unsigned int besterr, thiserr = 0x7fffffff;
+
+    /*
+        if ( rc < x->mv_col_min) bc = x->mv_col_min;
+        if ( rc > x->mv_col_max) bc = x->mv_col_max;
+        if ( rr < x->mv_row_min) br = x->mv_row_min;
+        if ( rr > x->mv_row_max) br = x->mv_row_max;
+        rr>>=1;
+        rc>>=1;
+        br>>=3;
+        bc>>=3;
+    */
+    if (bc < x->mv_col_min) bc = x->mv_col_min;
+
+    if (bc > x->mv_col_max) bc = x->mv_col_max;
+
+    if (br < x->mv_row_min) br = x->mv_row_min;
+
+    if (br > x->mv_row_max) br = x->mv_row_max;
+
+    rr >>= 1;
+    rc >>= 1;
+
+    besterr = ERR(br, bc, thiserr);
+
+    // hex search  jbb changed to 127 to avoid max 256 problem steping by 2.
+    for (j = 0; j < 127; j++)
+    {
+        tr = br;
+        tc = bc;
+
+        for (i = 0; i < 6; i++)
+        {
+            int nr = tr + hex[i].row, nc = tc + hex[i].col;
+
+            if (nc < x->mv_col_min) continue;
+
+            if (nc > x->mv_col_max) continue;
+
+            if (nr < x->mv_row_min) continue;
+
+            if (nr > x->mv_row_max) continue;
+
+            CHECK_BETTER(thiserr, nr, nc);
+        }
+
+        if (tr == br && tc == bc)
+            break;
+    }
+
+    // check 8 1 away neighbors
+    tr = br;
+    tc = bc;
+
+    for (i = 0; i < 8; i++)
+    {
+        int nr = tr + neighbors[i].row, nc = tc + neighbors[i].col;
+
+        if (nc < x->mv_col_min) continue;
+
+        if (nc > x->mv_col_max) continue;
+
+        if (nr < x->mv_row_min) continue;
+
+        if (nr > x->mv_row_max) continue;
+
+        CHECK_BETTER(thiserr, nr, nc);
+    }
+
+    best_mv->row = br;
+    best_mv->col = bc;
+
+    return vf(src, src_stride, PRE(br, bc), d->pre_stride, &thiserr) + MVC(br, bc) ;
+}
+#undef MVC
+#undef PRE
+#undef SP
+#undef DIST
+#undef ERR
+#undef CHECK_BETTER
+
+#endif
+
+int vp8_diamond_search_sad
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_ptr_t *fn_ptr,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    int i, j, step;
+
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    unsigned char *best_address;
+
+    int tot_steps;
+    MV this_mv;
+
+    int bestsad = INT_MAX;
+    int best_site = 0;
+    int last_site = 0;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+    int this_row_offset;
+    int this_col_offset;
+    search_site *ss;
+
+    unsigned char *check_here;
+    int thissad;
+
+    // Work out the start point for the search
+    in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col);
+    best_address = in_what;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Check the starting position
+        bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // search_param determines the length of the initial step and hence the number of iterations
+    // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
+    ss = &x->ss[search_param * x->searches_per_step];
+    tot_steps = (x->ss_count / x->searches_per_step) - search_param;
+
+    i = 1;
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    *num00 = 0;
+
+    for (step = 0; step < tot_steps ; step++)
+    {
+        for (j = 0 ; j < x->searches_per_step ; j++)
+        {
+            // Trap illegal vectors
+            this_row_offset = best_mv->row + ss[i].mv.row;
+            this_col_offset = best_mv->col + ss[i].mv.col;
+
+            if ((this_col_offset > x->mv_col_min) && (this_col_offset < x->mv_col_max) &&
+            (this_row_offset > x->mv_row_min) && (this_row_offset < x->mv_row_max))
+
+            {
+                check_here = ss[i].offset + best_address;
+                thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+                if (thissad < bestsad)
+                {
+                    this_mv.row = this_row_offset << 3;
+                    this_mv.col = this_col_offset << 3;
+                    thissad += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                    if (thissad < bestsad)
+                    {
+                        bestsad = thissad;
+                        best_site = i;
+                    }
+                }
+            }
+
+            i++;
+        }
+
+        if (best_site != last_site)
+        {
+            best_mv->row += ss[best_site].mv.row;
+            best_mv->col += ss[best_site].mv.col;
+            best_address += ss[best_site].offset;
+            last_site = best_site;
+        }
+        else if (best_address == in_what)
+            (*num00)++;
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad == INT_MAX)
+        return INT_MAX;
+
+    return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+    + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+}
+
+int vp8_diamond_search_sadx4
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_ptr_t *fn_ptr,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    int i, j, step;
+
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    unsigned char *best_address;
+
+    int tot_steps;
+    MV this_mv;
+
+    int bestsad = INT_MAX;
+    int best_site = 0;
+    int last_site = 0;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+    int this_row_offset;
+    int this_col_offset;
+    search_site *ss;
+
+    unsigned char *check_here;
+    int thissad;
+
+    // Work out the start point for the search
+    in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col);
+    best_address = in_what;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Check the starting position
+        bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // search_param determines the length of the initial step and hence the number of iterations
+    // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
+    ss = &x->ss[search_param * x->searches_per_step];
+    tot_steps = (x->ss_count / x->searches_per_step) - search_param;
+
+    i = 1;
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    *num00 = 0;
+
+    for (step = 0; step < tot_steps ; step++)
+    {
+        int check_row_min, check_col_min, check_row_max, check_col_max;
+
+        check_row_min = x->mv_row_min - best_mv->row;
+        check_row_max = x->mv_row_max - best_mv->row;
+        check_col_min = x->mv_col_min - best_mv->col;
+        check_col_max = x->mv_col_max - best_mv->col;
+
+        for (j = 0 ; j < x->searches_per_step ; j += 4)
+        {
+            char *block_offset[4];
+            unsigned int valid_block[4];
+            int all_in = 1, t;
+
+            for (t = 0; t < 4; t++)
+            {
+                valid_block [t]  = (ss[t+i].mv.col > check_col_min);
+                valid_block [t] &= (ss[t+i].mv.col < check_col_max);
+                valid_block [t] &= (ss[t+i].mv.row > check_row_min);
+                valid_block [t] &= (ss[t+i].mv.row < check_row_max);
+
+                all_in &= valid_block[t];
+                block_offset[t] = ss[i+t].offset + best_address;
+            }
+
+            if (all_in)
+            {
+                int sad_array[4];
+
+                fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, sad_array);
+
+                for (t = 0; t < 4; t++, i++)
+                {
+                    thissad = sad_array[t];
+
+                    if (thissad < bestsad)
+                    {
+                        this_mv.row = (best_mv->row + ss[i].mv.row) << 3;
+                        this_mv.col = (best_mv->col + ss[i].mv.col) << 3;
+                        thissad += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                        if (thissad < bestsad)
+                        {
+                            bestsad = thissad;
+                            best_site = i;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                int t;
+
+                for (t = 0; t < 4; i++, t++)
+                {
+                    // Trap illegal vectors
+                    if (valid_block[t])
+
+                    {
+                        check_here = block_offset[t];
+                        thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+                        if (thissad < bestsad)
+                        {
+                            this_row_offset = best_mv->row + ss[i].mv.row;
+                            this_col_offset = best_mv->col + ss[i].mv.col;
+
+                            this_mv.row = this_row_offset << 3;
+                            this_mv.col = this_col_offset << 3;
+                            thissad += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                            if (thissad < bestsad)
+                            {
+                                bestsad = thissad;
+                                best_site = i;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (best_site != last_site)
+        {
+            best_mv->row += ss[best_site].mv.row;
+            best_mv->col += ss[best_site].mv.col;
+            best_address += ss[best_site].offset;
+            last_site = best_site;
+        }
+        else if (best_address == in_what)
+            (*num00)++;
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad == INT_MAX)
+        return INT_MAX;
+
+    return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+    + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+}
+
+
+#if !(CONFIG_REALTIME_ONLY)
+int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int error_per_bit, int distance, vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], int *mvsadcost[2])
+{
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    int mv_stride = d->pre_stride;
+    unsigned char *bestaddress;
+    MV *best_mv = &d->bmi.mv.as_mv;
+    MV this_mv;
+    int bestsad = INT_MAX;
+    int r, c;
+
+    unsigned char *check_here;
+    int thissad;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
+
+    // Work out the mid point for the search
+    in_what = *(d->base_pre) + d->pre;
+    bestaddress = in_what + (ref_row * d->pre_stride) + ref_col;
+
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Baseline value at the centre
+
+        //bestsad = fn_ptr->sf( what,what_stride,bestaddress,in_what_stride) + (int)sqrt(vp8_mv_err_cost(ref_mv,ref_mv, mvcost,error_per_bit*14));
+        bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border
+    if (col_min < x->mv_col_min)
+        col_min = x->mv_col_min;
+
+    if (col_max > x->mv_col_max)
+        col_max = x->mv_col_max;
+
+    if (row_min < x->mv_row_min)
+        row_min = x->mv_row_min;
+
+    if (row_max > x->mv_row_max)
+        row_max = x->mv_row_max;
+
+    for (r = row_min; r < row_max ; r++)
+    {
+        this_mv.row = r << 3;
+        check_here = r * mv_stride + in_what + col_min;
+
+        for (c = col_min; c < col_max; c++)
+        {
+            thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+            this_mv.col = c << 3;
+            //thissad += (int)sqrt(vp8_mv_err_cost(&this_mv,ref_mv, mvcost,error_per_bit*14));
+            //thissad  += error_per_bit * mv_bits_sadcost[mv_bits(&this_mv, ref_mv, mvcost)];
+            thissad  += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit); //mv_bits(error_per_bit, &this_mv, ref_mv, mvsadcost);
+
+            if (thissad < bestsad)
+            {
+                bestsad = thissad;
+                best_mv->row = r;
+                best_mv->col = c;
+                bestaddress = check_here;
+            }
+
+            check_here++;
+        }
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad < INT_MAX)
+        return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+        + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    else
+        return INT_MAX;
+}
+
+int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int error_per_bit, int distance, vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], int *mvsadcost[2])
+{
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    int mv_stride = d->pre_stride;
+    unsigned char *bestaddress;
+    MV *best_mv = &d->bmi.mv.as_mv;
+    MV this_mv;
+    int bestsad = INT_MAX;
+    int r, c;
+
+    unsigned char *check_here;
+    int thissad;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
+
+    int sad_array[3];
+
+    // Work out the mid point for the search
+    in_what = *(d->base_pre) + d->pre;
+    bestaddress = in_what + (ref_row * d->pre_stride) + ref_col;
+
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Baseline value at the centre
+        bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border
+    if (col_min < x->mv_col_min)
+        col_min = x->mv_col_min;
+
+    if (col_max > x->mv_col_max)
+        col_max = x->mv_col_max;
+
+    if (row_min < x->mv_row_min)
+        row_min = x->mv_row_min;
+
+    if (row_max > x->mv_row_max)
+        row_max = x->mv_row_max;
+
+    for (r = row_min; r < row_max ; r++)
+    {
+        this_mv.row = r << 3;
+        check_here = r * mv_stride + in_what + col_min;
+        c = col_min;
+
+        while ((c + 3) < col_max)
+        {
+            int i;
+
+            fn_ptr->sdx3f(what, what_stride, check_here , in_what_stride, sad_array);
+
+            for (i = 0; i < 3; i++)
+            {
+                thissad = sad_array[i];
+
+                if (thissad < bestsad)
+                {
+                    this_mv.col = c << 3;
+                    thissad  += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                    if (thissad < bestsad)
+                    {
+                        bestsad = thissad;
+                        best_mv->row = r;
+                        best_mv->col = c;
+                        bestaddress = check_here;
+                    }
+                }
+
+                check_here++;
+                c++;
+            }
+        }
+
+        while (c < col_max)
+        {
+            thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+            if (thissad < bestsad)
+            {
+                this_mv.col = c << 3;
+                thissad  += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                if (thissad < bestsad)
+                {
+                    bestsad = thissad;
+                    best_mv->row = r;
+                    best_mv->col = c;
+                    bestaddress = check_here;
+                }
+            }
+
+            check_here ++;
+            c ++;
+        }
+
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad < INT_MAX)
+        return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+        + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    else
+        return INT_MAX;
+}
+#endif
+
+#ifdef ENTROPY_STATS
+void print_mode_context(void)
+{
+    FILE *f = fopen("modecont.c", "w");
+    int i, j;
+
+    fprintf(f, "#include \"entropy.h\"\n");
+    fprintf(f, "const int vp8_mode_contexts[6][4] =\n");
+    fprintf(f, "{\n");
+
+    for (j = 0; j < 6; j++)
+    {
+        fprintf(f, "  { // %d \n", j);
+        fprintf(f, "    ");
+
+        for (i = 0; i < 4; i++)
+        {
+            int overal_prob;
+            int this_prob;
+            int count; // = mv_ref_ct[j][i][0]+mv_ref_ct[j][i][1];
+
+            // Overall probs
+            count = mv_mode_cts[i][0] + mv_mode_cts[i][1];
+
+            if (count)
+                overal_prob = 256 * mv_mode_cts[i][0] / count;
+            else
+                overal_prob = 128;
+
+            if (overal_prob == 0)
+                overal_prob = 1;
+
+            // context probs
+            count = mv_ref_ct[j][i][0] + mv_ref_ct[j][i][1];
+
+            if (count)
+                this_prob = 256 * mv_ref_ct[j][i][0] / count;
+            else
+                this_prob = 128;
+
+            if (this_prob == 0)
+                this_prob = 1;
+
+            fprintf(f, "%5d, ", this_prob);
+            //fprintf(f,"%5d, %5d, %8d,", this_prob, overal_prob, (this_prob << 10)/overal_prob);
+            //fprintf(f,"%8d, ", (this_prob << 10)/overal_prob);
+        }
+
+        fprintf(f, "  },\n");
+    }
+
+    fprintf(f, "};\n");
+    fclose(f);
+}
+
+/* MV ref count ENTROPY_STATS stats code */
+#ifdef ENTROPY_STATS
+void init_mv_ref_counts()
+{
+    vpx_memset(mv_ref_ct, 0, sizeof(mv_ref_ct));
+    vpx_memset(mv_mode_cts, 0, sizeof(mv_mode_cts));
+}
+
+void accum_mv_refs(MB_PREDICTION_MODE m, const int ct[4])
+{
+    if (m == ZEROMV)
+    {
+        ++mv_ref_ct [ct[0]] [0] [0];
+        ++mv_mode_cts[0][0];
+    }
+    else
+    {
+        ++mv_ref_ct [ct[0]] [0] [1];
+        ++mv_mode_cts[0][1];
+
+        if (m == NEARESTMV)
+        {
+            ++mv_ref_ct [ct[1]] [1] [0];
+            ++mv_mode_cts[1][0];
+        }
+        else
+        {
+            ++mv_ref_ct [ct[1]] [1] [1];
+            ++mv_mode_cts[1][1];
+
+            if (m == NEARMV)
+            {
+                ++mv_ref_ct [ct[2]] [2] [0];
+                ++mv_mode_cts[2][0];
+            }
+            else
+            {
+                ++mv_ref_ct [ct[2]] [2] [1];
+                ++mv_mode_cts[2][1];
+
+                if (m == NEWMV)
+                {
+                    ++mv_ref_ct [ct[3]] [3] [0];
+                    ++mv_mode_cts[3][0];
+                }
+                else
+                {
+                    ++mv_ref_ct [ct[3]] [3] [1];
+                    ++mv_mode_cts[3][1];
+                }
+            }
+        }
+    }
+}
+
+#endif/* END MV ref count ENTROPY_STATS stats code */
+
+#endif
diff --git a/vp8/encoder/arm/neon/boolhuff_armv7.asm b/vp8/encoder/arm/neon/boolhuff_armv7.asm
new file mode 100644 (file)
index 0000000..9a5f366
--- /dev/null
@@ -0,0 +1,292 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8_start_encode|
+    EXPORT |vp8_encode_bool|
+    EXPORT |vp8_stop_encode|
+    EXPORT |vp8_encode_value|
+
+    INCLUDE vpx_vp8_enc_asm_offsets.asm
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY
+
+; r0 BOOL_CODER *br
+; r1 unsigned char *source
+
+|vp8_start_encode| PROC
+    mov     r12, #0
+    mov     r3,  #255
+    mvn     r2,  #23
+    str     r12, [r0, #vp8_writer_lowvalue]
+    str     r3,  [r0, #vp8_writer_range]
+    str     r12, [r0, #vp8_writer_value]
+    str     r2,  [r0, #vp8_writer_count]
+    str     r12, [r0, #vp8_writer_pos]
+    str     r1,  [r0, #vp8_writer_buffer]
+    bx      lr
+    ENDP
+
+; r0 BOOL_CODER *br
+; r1 int bit
+; r2 int probability
+|vp8_encode_bool| PROC
+    push    {r4-r9, lr}
+
+    mov     r4, r2
+
+    ldr     r2, [r0, #vp8_writer_lowvalue]
+    ldr     r5, [r0, #vp8_writer_range]
+    ldr     r3, [r0, #vp8_writer_count]
+
+    sub     r7, r5, #1                  ; range-1
+
+    cmp     r1, #0
+    mul     r4, r4, r7                  ; ((range-1) * probability)
+
+    mov     r7, #1
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * probability) >> 8)
+
+    addne   r2, r2, r4                  ; if  (bit) lowvalue += split
+    subne   r4, r5, r4                  ; if  (bit) range = range-split
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start
+token_zero_while_loop
+    mov     r9, #0
+    strb    r9, [r7, r4]                ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r1, [r7, r4]
+    cmpge   r1, #0xff
+    beq     token_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r9, [r7, r4]                ; w->buffer[x]
+    add     r9, r9, #1
+    strb    r9, [r7, r4]                ; w->buffer[x] + 1
+token_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r9, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r1, r4, #1                  ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r1, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r9, r4]                ; w->buffer[w->pos++]
+
+token_count_lt_zero
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    str     r2, [r0, #vp8_writer_lowvalue]
+    str     r5, [r0, #vp8_writer_range]
+    str     r3, [r0, #vp8_writer_count]
+    pop     {r4-r9, pc}
+    ENDP
+
+; r0 BOOL_CODER *br
+|vp8_stop_encode| PROC
+    push    {r4-r10, lr}
+
+    ldr     r2, [r0, #vp8_writer_lowvalue]
+    ldr     r5, [r0, #vp8_writer_range]
+    ldr     r3, [r0, #vp8_writer_count]
+
+    mov     r10, #32
+
+stop_encode_loop
+    sub     r7, r5, #1                  ; range-1
+
+    mov     r4, r7, lsl #7              ; ((range-1) * 128)
+
+    mov     r7, #1
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * 128) >> 8)
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero_se      ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set_se
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start_se
+token_zero_while_loop_se
+    mov     r9, #0
+    strb    r9, [r7, r4]                ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start_se
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r1, [r7, r4]
+    cmpge   r1, #0xff
+    beq     token_zero_while_loop_se
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r9, [r7, r4]                ; w->buffer[x]
+    add     r9, r9, #1
+    strb    r9, [r7, r4]                ; w->buffer[x] + 1
+token_high_bit_not_set_se
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r9, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r1, r4, #1                  ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r1, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r9, r4]                ; w->buffer[w->pos++]
+
+token_count_lt_zero_se
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    subs    r10, r10, #1
+    bne     stop_encode_loop
+
+    str     r2, [r0, #vp8_writer_lowvalue]
+    str     r5, [r0, #vp8_writer_range]
+    str     r3, [r0, #vp8_writer_count]
+    pop     {r4-r10, pc}
+
+    ENDP
+
+; r0 BOOL_CODER *br
+; r1 int data
+; r2 int bits
+|vp8_encode_value| PROC
+    push    {r4-r11, lr}
+
+    mov     r10, r2
+
+    ldr     r2, [r0, #vp8_writer_lowvalue]
+    ldr     r5, [r0, #vp8_writer_range]
+    ldr     r3, [r0, #vp8_writer_count]
+
+    ; reverse the stream of bits to be packed.  Normally
+    ; the most significant bit is peeled off and compared
+    ; in the form of (v >> --n) & 1.  ARM architecture has
+    ; the ability to set a flag based on the value of the
+    ; bit shifted off the bottom of the register.  To make
+    ; that happen the bitstream is reversed.
+    rbit    r11, r1
+    rsb     r4, r10, #32                 ; 32-n
+
+    ; v is kept in r1 during the token pack loop
+    lsr     r1, r11, r4                 ; v >>= 32 - n
+
+encode_value_loop
+    sub     r7, r5, #1                  ; range-1
+
+    ; Decisions are made based on the bit value shifted
+    ; off of v, so set a flag here based on this.
+    ; This value is refered to as "bb"
+    lsrs    r1, r1, #1                  ; bit = v >> n
+    mov     r4, r7, lsl #7              ; ((range-1) * 128)
+
+    mov     r7, #1
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * 128) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bit) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bit) range = range-split
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero_ev      ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set_ev
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start_ev
+token_zero_while_loop_ev
+    mov     r9, #0
+    strb    r9, [r7, r4]                ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start_ev
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     token_zero_while_loop_ev
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r9, [r7, r4]                ; w->buffer[x]
+    add     r9, r9, #1
+    strb    r9, [r7, r4]                ; w->buffer[x] + 1
+token_high_bit_not_set_ev
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r9, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r9, r4]                ; w->buffer[w->pos++]
+
+token_count_lt_zero_ev
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    subs    r10, r10, #1
+    bne     encode_value_loop
+
+    str     r2, [r0, #vp8_writer_lowvalue]
+    str     r5, [r0, #vp8_writer_range]
+    str     r3, [r0, #vp8_writer_count]
+    pop     {r4-r11, pc}
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/fastfdct4x4_neon.asm b/vp8/encoder/arm/neon/fastfdct4x4_neon.asm
new file mode 100644 (file)
index 0000000..d5dec44
--- /dev/null
@@ -0,0 +1,126 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_fast_fdct4x4_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vp8_fast_fdct4x4_c(short *input, short *output, int pitch);
+;NOTE:
+;The input *src_diff. src_diff is calculated as:
+;diff_ptr[c] = src_ptr[c] - pred_ptr[c]; (in Subtract* function)
+;In which *src_ptr and *pred_ptr both are unsigned char.
+;Therefore, *src_diff should be in the range of [-255, 255].
+;CAUTION:
+;The input values of 25th block are set in vp8_build_dcblock function, which are out of [-255, 255].
+;But, VP8 encoder only uses vp8_short_fdct4x4_c for 25th block, not vp8_fast_fdct4x4_c. That makes
+;it ok for assuming *input in [-255, 255] in vp8_fast_fdct4x4_c, but not ok in vp8_short_fdct4x4_c.
+
+|vp8_fast_fdct4x4_neon| PROC
+    vld1.16         {d2}, [r0], r2              ;load input
+    ldr             r12, _ffdct_coeff_
+    vld1.16         {d3}, [r0], r2
+    vld1.16         {d4}, [r0], r2
+    vld1.16         {d0}, [r12]
+    vld1.16         {d5}, [r0], r2
+
+    ;First for-loop
+    ;transpose d2, d3, d4, d5. Then, d2=ip[0], d3=ip[1], d4=ip[2], d5=ip[3]
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vadd.s16        d6, d2, d5              ;ip[0]+ip[3]
+    vadd.s16        d7, d3, d4              ;ip[1]+ip[2]
+    vsub.s16        d8, d3, d4              ;ip[1]-ip[2]
+    vsub.s16        d9, d2, d5              ;ip[0]-ip[3]
+    vshl.i16        q3, q3, #1              ; a1, b1
+    vshl.i16        q4, q4, #1              ; c1, d1
+
+    vadd.s16        d10, d6, d7             ;temp1 = a1 + b1
+    vsub.s16        d11, d6, d7             ;temp2 = a1 - b1
+
+    vqdmulh.s16     q6, q5, d0[1]
+    vqdmulh.s16     q8, q4, d0[0]
+    vqdmulh.s16     q7, q4, d0[2]
+
+    vshr.s16        q6, q6, #1
+    vshr.s16        q8, q8, #1
+    vshr.s16        q7, q7, #1              ;d14:temp1 = ( c1 * x_c3)>>16;  d15:temp1 =  (d1 * x_c3)>>16
+    vadd.s16        q8, q4, q8              ;d16:temp2 = ((c1 * x_c1)>>16) + c1;  d17:temp2 = ((d1 * x_c1)>>16) + d1
+
+    vadd.s16        d2, d10, d12            ;op[0] = ((temp1 * x_c2 )>>16) + temp1
+    vadd.s16        d4, d11, d13            ;op[2] = ((temp2 * x_c2 )>>16) + temp2
+    vadd.s16        d3, d14, d17            ;op[1] = temp1 + temp2  -- q is not necessary, just for protection
+    vsub.s16        d5, d15, d16            ;op[3] = temp1 - temp2
+
+    ;Second for-loop
+    ;transpose d2, d3, d4, d5. Then, d2=ip[0], d3=ip[4], d4=ip[8], d5=ip[12]
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vadd.s16        d6, d2, d5              ;a1 = ip[0]+ip[12]
+    vadd.s16        d7, d3, d4              ;b1 = ip[4]+ip[8]
+    vsub.s16        d8, d3, d4              ;c1 = ip[4]-ip[8]
+    vsub.s16        d9, d2, d5              ;d1 = ip[0]-ip[12]
+
+    vadd.s16        d10, d6, d7             ;temp1 = a1 + b1
+    vsub.s16        d11, d6, d7             ;temp2 = a1 - b1
+
+
+    vqdmulh.s16     q6, q5, d0[1]
+    vqdmulh.s16     q8, q4, d0[0]
+    vqdmulh.s16     q7, q4, d0[2]
+
+    vshr.s16        q6, q6, #1
+    vshr.s16        q8, q8, #1
+    vshr.s16        q7, q7, #1              ;d14:temp1 = ( c1 * x_c3)>>16;  d15:temp1 =  (d1 * x_c3)>>16
+    vadd.s16        q8, q4, q8              ;d16:temp2 = ((c1 * x_c1)>>16) + c1;  d17:temp2 = ((d1 * x_c1)>>16) + d1
+
+    vadd.s16        d2, d10, d12            ;a2 = ((temp1 * x_c2 )>>16) + temp1
+    vadd.s16        d4, d11, d13            ;c2 = ((temp2 * x_c2 )>>16) + temp2
+    vadd.s16        d3, d14, d17            ;b2 = temp1 + temp2  -- q is not necessary, just for protection
+    vsub.s16        d5, d15, d16            ;d2 = temp1 - temp2
+
+    vclt.s16        q3, q1, #0
+    vclt.s16        q4, q2, #0
+
+    vsub.s16        q1, q1, q3
+    vsub.s16        q2, q2, q4
+
+    vshr.s16        q1, q1, #1
+    vshr.s16        q2, q2, #1
+
+    vst1.16         {q1, q2}, [r1]
+
+    bx              lr
+
+    ENDP
+
+;-----------------
+    AREA    fastfdct_dat, DATA, READONLY
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_ffdct_coeff_
+    DCD     ffdct_coeff
+ffdct_coeff
+; 60547 =  0xEC83
+; 46341 =  0xB505
+; 25080 =  0x61F8
+    DCD     0xB505EC83, 0x000061F8
+
+    END
diff --git a/vp8/encoder/arm/neon/fastfdct8x4_neon.asm b/vp8/encoder/arm/neon/fastfdct8x4_neon.asm
new file mode 100644 (file)
index 0000000..de1c254
--- /dev/null
@@ -0,0 +1,179 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_fast_fdct8x4_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vp8_fast_fdct4x4_c(short *input, short *output, int pitch);
+;NOTE:
+;The input *src_diff. src_diff is calculated as:
+;diff_ptr[c] = src_ptr[c] - pred_ptr[c]; (in Subtract* function)
+;In which *src_ptr and *pred_ptr both are unsigned char.
+;Therefore, *src_diff should be in the range of [-255, 255].
+;CAUTION:
+;The input values of 25th block are set in vp8_build_dcblock function, which are out of [-255, 255].
+;But, VP8 encoder only uses vp8_short_fdct4x4_c for 25th block, not vp8_fast_fdct4x4_c. That makes
+;it ok for assuming *input in [-255, 255] in vp8_fast_fdct4x4_c, but not ok in vp8_short_fdct4x4_c.
+
+|vp8_fast_fdct8x4_neon| PROC
+    vld1.16         {q1}, [r0], r2              ;load input
+    ldr             r12, _ffdct8_coeff_
+    vld1.16         {q2}, [r0], r2
+    vld1.16         {q3}, [r0], r2
+    vld1.16         {d0}, [r12]
+    vld1.16         {q4}, [r0], r2
+
+    ;First for-loop
+    ;transpose d2, d4, d6, d8. Then, d2=ip[0], d4=ip[1], d6=ip[2], d8=ip[3]
+    ;transpose d3, d5, d7, d9. Then, d3=ip[0], d5=ip[1], d7=ip[2], d9=ip[3]
+    vtrn.32         d2, d6
+    vtrn.32         d3, d7
+    vtrn.32         d4, d8
+    vtrn.32         d5, d9
+    vtrn.16         d2, d4
+    vtrn.16         d3, d5
+    vtrn.16         d6, d8
+    vtrn.16         d7, d9
+
+    vadd.s16        d10, d2, d8             ;ip[0]+ip[3]
+    vadd.s16        d11, d4, d6             ;ip[1]+ip[2]
+    vsub.s16        d12, d4, d6             ;ip[1]-ip[2]
+    vsub.s16        d13, d2, d8             ;ip[0]-ip[3]
+    vadd.s16        d22, d3, d9
+    vadd.s16        d23, d5, d7
+    vsub.s16        d24, d5, d7
+    vsub.s16        d25, d3, d9
+
+    vshl.i16        q5, q5, #1              ; a1, b1
+    vshl.i16        q6, q6, #1              ; c1, d1
+    vshl.i16        q1, q11, #1
+    vshl.i16        q2, q12, #1
+
+    vadd.s16        d14, d10, d11           ;temp1 = a1 + b1
+    vsub.s16        d15, d10, d11           ;temp2 = a1 - b1
+    vadd.s16        d24, d2, d3
+    vsub.s16        d25, d2, d3
+
+    vqdmulh.s16     q8, q7, d0[1]
+    vqdmulh.s16     q13, q12, d0[1]
+    vqdmulh.s16     q10, q6, d0[0]
+    vqdmulh.s16     q15, q2, d0[0]
+    vqdmulh.s16     q9, q6, d0[2]
+    vqdmulh.s16     q14, q2, d0[2]
+
+    vshr.s16        q8, q8, #1
+    vshr.s16        q13, q13, #1
+    vshr.s16        q10, q10, #1
+    vshr.s16        q15, q15, #1
+    vshr.s16        q9, q9, #1              ;d18:temp1 = ( c1 * x_c3)>>16;  d19:temp1 =  (d1 * x_c3)>>16
+    vshr.s16        q14, q14, #1            ;d28:temp1 = ( c1 * x_c3)>>16;  d29:temp1 =  (d1 * x_c3)>>16
+    vadd.s16        q10, q6, q10            ;d20:temp2 = ((c1 * x_c1)>>16) + c1;  d21:temp2 = ((d1 * x_c1)>>16) + d1
+    vadd.s16        q15, q2, q15            ;d30:temp2 = ((c1 * x_c1)>>16) + c1;  d31:temp2 = ((d1 * x_c1)>>16) + d1
+
+    vadd.s16        d2, d14, d16            ;op[0] = ((temp1 * x_c2 )>>16) + temp1
+    vadd.s16        d3, d24, d26            ;op[0] = ((temp1 * x_c2 )>>16) + temp1
+    vadd.s16        d6, d15, d17            ;op[2] = ((temp2 * x_c2 )>>16) + temp2
+    vadd.s16        d7, d25, d27            ;op[2] = ((temp2 * x_c2 )>>16) + temp2
+    vadd.s16        d4, d18, d21            ;op[1] = temp1 + temp2  -- q is not necessary, just for protection
+    vadd.s16        d5, d28, d31            ;op[1] = temp1 + temp2  -- q is not necessary, just for protection
+    vsub.s16        d8, d19, d20            ;op[3] = temp1 - temp2
+    vsub.s16        d9, d29, d30            ;op[3] = temp1 - temp2
+
+    ;Second for-loop
+    ;transpose d2, d4, d6, d8. Then, d2=ip[0], d4=ip[4], d6=ip[8], d8=ip[12]
+    ;transpose d3, d5, d7, d9. Then, d3=ip[0], d5=ip[4], d7=ip[8], d9=ip[12]
+    vtrn.32         d2, d6
+    vtrn.32         d3, d7
+    vtrn.32         d4, d8
+    vtrn.32         d5, d9
+    vtrn.16         d2, d4
+    vtrn.16         d3, d5
+    vtrn.16         d6, d8
+    vtrn.16         d7, d9
+
+    vadd.s16        d10, d2, d8             ;a1 = ip[0]+ip[12]
+    vadd.s16        d11, d4, d6             ;b1 = ip[4]+ip[8]
+    vsub.s16        d12, d4, d6             ;c1 = ip[4]-ip[8]
+    vsub.s16        d13, d2, d8             ;d1 = ip[0]-ip[12]
+    vadd.s16        d2, d3, d9
+    vadd.s16        d4, d5, d7
+    vsub.s16        d24, d5, d7
+    vsub.s16        d25, d3, d9
+
+    vadd.s16        d14, d10, d11           ;temp1 = a1 + b1
+    vsub.s16        d15, d10, d11           ;temp2 = a1 - b1
+    vadd.s16        d22, d2, d4
+    vsub.s16        d23, d2, d4
+
+    vqdmulh.s16     q8, q7, d0[1]
+    vqdmulh.s16     q13, q11, d0[1]
+    vqdmulh.s16     q10, q6, d0[0]
+    vqdmulh.s16     q15, q12, d0[0]
+    vqdmulh.s16     q9, q6, d0[2]
+    vqdmulh.s16     q14, q12, d0[2]
+
+    vshr.s16        q8, q8, #1
+    vshr.s16        q13, q13, #1
+    vshr.s16        q10, q10, #1
+    vshr.s16        q15, q15, #1
+    vshr.s16        q9, q9, #1              ;d18:temp1 = ( c1 * x_c3)>>16;  d19:temp1 =  (d1 * x_c3)>>16
+    vshr.s16        q14, q14, #1            ;d28:temp1 = ( c1 * x_c3)>>16;  d29:temp1 =  (d1 * x_c3)>>16
+    vadd.s16        q10, q6, q10            ;d20:temp2 = ((c1 * x_c1)>>16) + c1;  d21:temp2 = ((d1 * x_c1)>>16) + d1
+    vadd.s16        q15, q12, q15           ;d30:temp2 = ((c1 * x_c1)>>16) + c1;  d31:temp2 = ((d1 * x_c1)>>16) + d1
+
+    vadd.s16        d2, d14, d16            ;a2 = ((temp1 * x_c2 )>>16) + temp1
+    vadd.s16        d6, d22, d26            ;a2 = ((temp1 * x_c2 )>>16) + temp1
+    vadd.s16        d4, d15, d17            ;c2 = ((temp2 * x_c2 )>>16) + temp2
+    vadd.s16        d8, d23, d27            ;c2 = ((temp2 * x_c2 )>>16) + temp2
+    vadd.s16        d3, d18, d21            ;b2 = temp1 + temp2  -- q is not necessary, just for protection
+    vadd.s16        d7, d28, d31            ;b2 = temp1 + temp2  -- q is not necessary, just for protection
+    vsub.s16        d5, d19, d20            ;d2 = temp1 - temp2
+    vsub.s16        d9, d29, d30            ;d2 = temp1 - temp2
+
+    vclt.s16        q5, q1, #0
+    vclt.s16        q6, q2, #0
+    vclt.s16        q7, q3, #0
+    vclt.s16        q8, q4, #0
+
+    vsub.s16        q1, q1, q5
+    vsub.s16        q2, q2, q6
+    vsub.s16        q3, q3, q7
+    vsub.s16        q4, q4, q8
+
+    vshr.s16        q1, q1, #1
+    vshr.s16        q2, q2, #1
+    vshr.s16        q3, q3, #1
+    vshr.s16        q4, q4, #1
+
+    vst1.16         {q1, q2}, [r1]!
+    vst1.16         {q3, q4}, [r1]
+
+    bx              lr
+
+    ENDP
+
+;-----------------
+    AREA    fastfdct8x4_dat, DATA, READONLY
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_ffdct8_coeff_
+    DCD     ffdct8_coeff
+ffdct8_coeff
+; 60547 =  0xEC83
+; 46341 =  0xB505
+; 25080 =  0x61F8
+    DCD     0xB505EC83, 0x000061F8
+
+    END
diff --git a/vp8/encoder/arm/neon/fastquantizeb_neon.asm b/vp8/encoder/arm/neon/fastquantizeb_neon.asm
new file mode 100644 (file)
index 0000000..1107037
--- /dev/null
@@ -0,0 +1,117 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_fast_quantize_b_neon_func|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0        short *coeff_ptr
+; r1        short *zbin_ptr
+; r2        short *qcoeff_ptr
+; r3        short *dqcoeff_ptr
+; stack     short *dequant_ptr
+; stack     short *scan_mask
+; stack     short *round_ptr
+; stack     short *quant_ptr
+
+; return    int * eob
+|vp8_fast_quantize_b_neon_func| PROC
+    vld1.16         {q0, q1}, [r0]              ;load z
+    vld1.16         {q10, q11}, [r1]            ;load zbin
+
+    vabs.s16        q4, q0                      ;calculate x = abs(z)
+    vabs.s16        q5, q1
+
+    vcge.s16        q10, q4, q10                ;x>=zbin
+    vcge.s16        q11, q5, q11
+
+    ;if x<zbin (q10 & q11 are all 0), go to zero_output
+    vorr.s16        q6, q10, q11
+    vorr.s16        d12, d12, d13
+    vmov            r0, r1, d12
+    orr             r0, r0, r1
+    cmp             r0, #0
+    beq             zero_output
+
+    ldr             r0, [sp, #8]                ;load round_ptr
+    ldr             r12, [sp, #12]              ;load quant_ptr
+
+    ;right shift 15 to get sign, all 0 if it is positive, all 1 if it is negative
+    vshr.s16        q2, q0, #15                 ; sz
+    vshr.s16        q3, q1, #15
+
+    vld1.s16        {q6, q7}, [r0]              ;load round_ptr [0-15]
+    vld1.s16        {q8, q9}, [r12]             ;load quant_ptr [0-15]
+
+    vadd.s16        q4, q6                      ;x + Round
+    vadd.s16        q5, q7
+
+    ldr             r0, [sp, #4]                ;load rvsplus1_scan_order ptr
+
+    vqdmulh.s16     q4, q8                      ;y = ((Round + abs(z)) * Quant) >> 16
+    vqdmulh.s16     q5, q9
+
+    vld1.16         {q0, q1}, [r0]              ;load rvsplus1_scan_order
+    vceq.s16        q8, q8                      ;set q8 to all 1
+
+    vshr.s16        q4, #1                      ;right shift 1 after vqdmulh
+    vshr.s16        q5, #1
+
+    ;modify data to have its original sign
+    veor.s16        q4, q2                      ; y^sz
+    veor.s16        q5, q3
+
+    ldr             r12, [sp]                   ;load dequant_ptr
+
+    vsub.s16        q4, q2                      ; x1 = (y^sz) - sz = (y^sz) - (-1) (two's complement)
+    vsub.s16        q5, q3
+
+    vand.s16        q4, q10                     ;mask off x1 elements
+    vand.s16        q5, q11
+
+    vld1.s16        {q6, q7}, [r12]             ;load dequant_ptr[i]
+
+    vtst.16         q14, q4, q8                 ;now find eob
+    vtst.16         q15, q5, q8                 ;non-zero element is set to all 1 in q4, q5
+
+    vst1.s16        {q4, q5}, [r2]              ;store: qcoeff = x1
+
+    vand            q0, q0, q14                 ;get all valid number from rvsplus1_scan_order array
+    vand            q1, q1, q15
+
+    vmax.u16        q0, q0, q1                  ;find maximum value in q0, q1
+    vmax.u16        d0, d0, d1
+    vmovl.u16       q0, d0
+
+    vmul.s16        q6, q4                      ;x * Dequant
+    vmul.s16        q7, q5
+
+    vmax.u32        d0, d0, d1
+    vpmax.u32       d0, d0, d0
+
+    vst1.s16        {q6, q7}, [r3]              ;store dqcoeff = x * Dequant
+
+    vmov.32         r0, d0[0]
+    bx              lr
+
+zero_output
+    vst1.s16        {q10, q11}, [r2]        ; qcoeff = 0
+    vst1.s16        {q10, q11}, [r3]        ; dqcoeff = 0
+    mov             r0, #0
+
+    bx              lr
+
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/sad16_neon.asm b/vp8/encoder/arm/neon/sad16_neon.asm
new file mode 100644 (file)
index 0000000..6169f10
--- /dev/null
@@ -0,0 +1,206 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sad16x16_neon|
+    EXPORT  |vp8_sad16x8_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    unsigned char *src_ptr
+; r1    int  src_stride
+; r2    unsigned char *ref_ptr
+; r3    int  ref_stride
+|vp8_sad16x16_neon| PROC
+;;
+    vld1.8          {q0}, [r0], r1
+    vld1.8          {q4}, [r2], r3
+
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+
+    vabdl.u8        q12, d0, d8
+    vabdl.u8        q13, d1, d9
+
+    vld1.8          {q2}, [r0], r1
+    vld1.8          {q6}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+    vabal.u8        q13, d3, d11
+
+    vld1.8          {q3}, [r0], r1
+    vld1.8          {q7}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q13, d5, d13
+
+;;
+    vld1.8          {q0}, [r0], r1
+    vld1.8          {q4}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+    vabal.u8        q13, d7, d15
+
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+    vabal.u8        q13, d1, d9
+
+    vld1.8          {q2}, [r0], r1
+    vld1.8          {q6}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+    vabal.u8        q13, d3, d11
+
+    vld1.8          {q3}, [r0], r1
+    vld1.8          {q7}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q13, d5, d13
+
+;;
+    vld1.8          {q0}, [r0], r1
+    vld1.8          {q4}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+    vabal.u8        q13, d7, d15
+
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+    vabal.u8        q13, d1, d9
+
+    vld1.8          {q2}, [r0], r1
+    vld1.8          {q6}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+    vabal.u8        q13, d3, d11
+
+    vld1.8          {q3}, [r0], r1
+    vld1.8          {q7}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q13, d5, d13
+
+;;
+    vld1.8          {q0}, [r0], r1
+    vld1.8          {q4}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+    vabal.u8        q13, d7, d15
+
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+    vabal.u8        q13, d1, d9
+
+    vld1.8          {q2}, [r0], r1
+    vld1.8          {q6}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+    vabal.u8        q13, d3, d11
+
+    vld1.8          {q3}, [r0]
+    vld1.8          {q7}, [r2]
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q13, d5, d13
+
+    vabal.u8        q12, d6, d14
+    vabal.u8        q13, d7, d15
+
+    vadd.u16        q0, q12, q13
+
+    vpaddl.u16      q1, q0
+    vpaddl.u32      q0, q1
+
+    vadd.u32        d0, d0, d1
+
+    vmov.32         r0, d0[0]
+
+    bx              lr
+
+    ENDP
+
+;==============================
+;unsigned int vp8_sad16x8_c(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+|vp8_sad16x8_neon| PROC
+    vld1.8          {q0}, [r0], r1
+    vld1.8          {q4}, [r2], r3
+
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+
+    vabdl.u8        q12, d0, d8
+    vabdl.u8        q13, d1, d9
+
+    vld1.8          {q2}, [r0], r1
+    vld1.8          {q6}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+    vabal.u8        q13, d3, d11
+
+    vld1.8          {q3}, [r0], r1
+    vld1.8          {q7}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q13, d5, d13
+
+    vld1.8          {q0}, [r0], r1
+    vld1.8          {q4}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+    vabal.u8        q13, d7, d15
+
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+    vabal.u8        q13, d1, d9
+
+    vld1.8          {q2}, [r0], r1
+    vld1.8          {q6}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+    vabal.u8        q13, d3, d11
+
+    vld1.8          {q3}, [r0], r1
+    vld1.8          {q7}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q13, d5, d13
+
+    vabal.u8        q12, d6, d14
+    vabal.u8        q13, d7, d15
+
+    vadd.u16        q0, q12, q13
+
+    vpaddl.u16      q1, q0
+    vpaddl.u32      q0, q1
+
+    vadd.u32        d0, d0, d1
+
+    vmov.32         r0, d0[0]
+
+    bx              lr
+
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/sad8_neon.asm b/vp8/encoder/arm/neon/sad8_neon.asm
new file mode 100644 (file)
index 0000000..28604dd
--- /dev/null
@@ -0,0 +1,208 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sad8x8_neon|
+    EXPORT  |vp8_sad8x16_neon|
+    EXPORT  |vp8_sad4x4_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; unsigned int vp8_sad8x8_c(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+
+|vp8_sad8x8_neon| PROC
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabdl.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q12, d6, d14
+
+    vpaddl.u16      q1, q12
+    vpaddl.u32      q0, q1
+    vadd.u32        d0, d0, d1
+
+    vmov.32         r0, d0[0]
+
+    bx              lr
+
+    ENDP
+
+;============================
+;unsigned int vp8_sad8x16_c(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+
+|vp8_sad8x16_neon| PROC
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabdl.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vabal.u8        q12, d6, d14
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabal.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q12, d6, d14
+
+    vpaddl.u16      q1, q12
+    vpaddl.u32      q0, q1
+    vadd.u32        d0, d0, d1
+
+    vmov.32         r0, d0[0]
+
+    bx              lr
+
+    ENDP
+
+;===========================
+;unsigned int vp8_sad4x4_c(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+
+|vp8_sad4x4_neon| PROC
+    vld1.8          {d0}, [r0], r1
+    vld1.8          {d8}, [r2], r3
+
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d10}, [r2], r3
+
+    vabdl.u8        q12, d0, d8
+
+    vld1.8          {d4}, [r0], r1
+    vld1.8          {d12}, [r2], r3
+
+    vabal.u8        q12, d2, d10
+
+    vld1.8          {d6}, [r0], r1
+    vld1.8          {d14}, [r2], r3
+
+    vabal.u8        q12, d4, d12
+    vabal.u8        q12, d6, d14
+
+    vpaddl.u16      d1, d24
+    vpaddl.u32      d0, d1
+    vmov.32         r0, d0[0]
+
+    bx              lr
+
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/shortfdct_neon.asm b/vp8/encoder/arm/neon/shortfdct_neon.asm
new file mode 100644 (file)
index 0000000..26bc0d0
--- /dev/null
@@ -0,0 +1,146 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_short_fdct4x4_neon|
+    EXPORT  |vp8_short_fdct8x4_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    short *input
+; r1    short *output
+; r2    int pitch
+; Input has a pitch, output is contiguous
+|vp8_short_fdct4x4_neon| PROC
+    ldr             r12, _dct_matrix_
+    vld1.16         d0, [r0], r2
+    vld1.16         d1, [r0], r2
+    vld1.16         d2, [r0], r2
+    vld1.16         d3, [r0]
+    vld1.16         {q2, q3}, [r12]
+
+;first stage
+    vmull.s16       q11, d4, d0[0]              ;i=0
+    vmull.s16       q12, d4, d1[0]              ;i=1
+    vmull.s16       q13, d4, d2[0]              ;i=2
+    vmull.s16       q14, d4, d3[0]              ;i=3
+
+    vmlal.s16       q11, d5, d0[1]
+    vmlal.s16       q12, d5, d1[1]
+    vmlal.s16       q13, d5, d2[1]
+    vmlal.s16       q14, d5, d3[1]
+
+    vmlal.s16       q11, d6, d0[2]
+    vmlal.s16       q12, d6, d1[2]
+    vmlal.s16       q13, d6, d2[2]
+    vmlal.s16       q14, d6, d3[2]
+
+    vmlal.s16       q11, d7, d0[3]              ;sumtemp for i=0
+    vmlal.s16       q12, d7, d1[3]              ;sumtemp for i=1
+    vmlal.s16       q13, d7, d2[3]              ;sumtemp for i=2
+    vmlal.s16       q14, d7, d3[3]              ;sumtemp for i=3
+
+    ; rounding
+    vrshrn.i32      d22, q11, #14
+    vrshrn.i32      d24, q12, #14
+    vrshrn.i32      d26, q13, #14
+    vrshrn.i32      d28, q14, #14
+
+;second stage
+    vmull.s16       q4, d22, d4[0]              ;i=0
+    vmull.s16       q5, d22, d4[1]              ;i=1
+    vmull.s16       q6, d22, d4[2]              ;i=2
+    vmull.s16       q7, d22, d4[3]              ;i=3
+
+    vmlal.s16       q4, d24, d5[0]
+    vmlal.s16       q5, d24, d5[1]
+    vmlal.s16       q6, d24, d5[2]
+    vmlal.s16       q7, d24, d5[3]
+
+    vmlal.s16       q4, d26, d6[0]
+    vmlal.s16       q5, d26, d6[1]
+    vmlal.s16       q6, d26, d6[2]
+    vmlal.s16       q7, d26, d6[3]
+
+    vmlal.s16       q4, d28, d7[0]              ;sumtemp for i=0
+    vmlal.s16       q5, d28, d7[1]              ;sumtemp for i=1
+    vmlal.s16       q6, d28, d7[2]              ;sumtemp for i=2
+    vmlal.s16       q7, d28, d7[3]              ;sumtemp for i=3
+
+    vrshr.s32       q0, q4, #16
+    vrshr.s32       q1, q5, #16
+    vrshr.s32       q2, q6, #16
+    vrshr.s32       q3, q7, #16
+
+    vmovn.i32       d0, q0
+    vmovn.i32       d1, q1
+    vmovn.i32       d2, q2
+    vmovn.i32       d3, q3
+
+    vst1.16         {q0, q1}, [r1]
+
+    bx              lr
+
+    ENDP
+
+; r0    short *input
+; r1    short *output
+; r2    int pitch
+|vp8_short_fdct8x4_neon| PROC
+    ; Store link register and input before calling
+    ;  first 4x4 fdct.  Do not need to worry about
+    ;  output or pitch because those pointers are not
+    ;  touched in the 4x4 fdct function
+    stmdb           sp!, {r0, lr}
+
+    bl              vp8_short_fdct4x4_neon
+
+    ldmia           sp!, {r0, lr}
+
+    ; Move to the next block of data.
+    add             r0, r0, #8
+    add             r1, r1, #32
+
+    ; Second time through do not store off the
+    ;  link register, just return from the 4x4 fdtc
+    b               vp8_short_fdct4x4_neon
+
+    ; Should never get to this.
+    bx              lr
+
+    ENDP
+
+;-----------------
+    AREA    dct4x4_dat, DATA, READONLY
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_dct_matrix_
+    DCD     dct_matrix
+dct_matrix
+;   DCW     23170,  30274,  23170, 12540
+;   DCW     23170,  12540, -23170,-30274
+;   DCW     23170, -12540, -23170, 30274
+;   DCW     23170, -30274,  23170,-12540
+; 23170 =  0x5a82
+; -23170 =  0xa57e
+; 30274 =  0x7642
+; -30274 =  0x89be
+; 12540 =  0x30fc
+; -12540 = 0xcf04
+    DCD     0x76425a82, 0x30fc5a82
+    DCD     0x30fc5a82, 0x89bea57e
+    DCD     0xcf045a82, 0x7642a57e
+    DCD     0x89be5a82, 0xcf045a82
+
+    END
diff --git a/vp8/encoder/arm/neon/subtract_neon.asm b/vp8/encoder/arm/neon/subtract_neon.asm
new file mode 100644 (file)
index 0000000..8781ca0
--- /dev/null
@@ -0,0 +1,171 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8_subtract_b_neon_func|
+    EXPORT |vp8_subtract_mby_neon|
+    EXPORT |vp8_subtract_mbuv_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;=========================================
+;void vp8_subtract_b_neon_func(short *diff, unsigned char *src, unsigned char *pred, int stride, int pitch);
+|vp8_subtract_b_neon_func| PROC
+    ldr             r12, [sp]               ;load pitch
+
+    vld1.8          {d0}, [r1], r3          ;load src
+    vld1.8          {d1}, [r2], r12         ;load pred
+    vld1.8          {d2}, [r1], r3
+    vld1.8          {d3}, [r2], r12
+    vld1.8          {d4}, [r1], r3
+    vld1.8          {d5}, [r2], r12
+    vld1.8          {d6}, [r1], r3
+    vld1.8          {d7}, [r2], r12
+
+    vsubl.u8        q10, d0, d1
+    vsubl.u8        q11, d2, d3
+    vsubl.u8        q12, d4, d5
+    vsubl.u8        q13, d6, d7
+
+    mov             r12, r12, lsl #1
+
+    vst1.16         {d20}, [r0], r12        ;store diff
+    vst1.16         {d22}, [r0], r12
+    vst1.16         {d24}, [r0], r12
+    vst1.16         {d26}, [r0], r12
+
+    bx              lr
+    ENDP
+
+;==========================================
+;void vp8_subtract_mby_neon(short *diff, unsigned char *src, unsigned char *pred, int stride)
+|vp8_subtract_mby_neon| PROC
+    mov             r12, #4
+
+subtract_mby_loop
+    vld1.8          {q0}, [r1], r3          ;load src
+    vld1.8          {q1}, [r2]!             ;load pred
+    vld1.8          {q2}, [r1], r3
+    vld1.8          {q3}, [r2]!
+    vld1.8          {q4}, [r1], r3
+    vld1.8          {q5}, [r2]!
+    vld1.8          {q6}, [r1], r3
+    vld1.8          {q7}, [r2]!
+
+    vsubl.u8        q8, d0, d2
+    vsubl.u8        q9, d1, d3
+    vsubl.u8        q10, d4, d6
+    vsubl.u8        q11, d5, d7
+    vsubl.u8        q12, d8, d10
+    vsubl.u8        q13, d9, d11
+    vsubl.u8        q14, d12, d14
+    vsubl.u8        q15, d13, d15
+
+    vst1.16         {q8}, [r0]!             ;store diff
+    vst1.16         {q9}, [r0]!
+    vst1.16         {q10}, [r0]!
+    vst1.16         {q11}, [r0]!
+    vst1.16         {q12}, [r0]!
+    vst1.16         {q13}, [r0]!
+    vst1.16         {q14}, [r0]!
+    vst1.16         {q15}, [r0]!
+
+    subs            r12, r12, #1
+    bne             subtract_mby_loop
+
+    bx              lr
+    ENDP
+
+;=================================
+;void vp8_subtract_mbuv_neon(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride)
+|vp8_subtract_mbuv_neon| PROC
+    ldr             r12, [sp]
+
+;u
+    add             r0, r0, #512        ;   short *udiff = diff + 256;
+    add             r3, r3, #256        ;   unsigned char *upred = pred + 256;
+
+    vld1.8          {d0}, [r1], r12         ;load src
+    vld1.8          {d1}, [r3]!             ;load pred
+    vld1.8          {d2}, [r1], r12
+    vld1.8          {d3}, [r3]!
+    vld1.8          {d4}, [r1], r12
+    vld1.8          {d5}, [r3]!
+    vld1.8          {d6}, [r1], r12
+    vld1.8          {d7}, [r3]!
+    vld1.8          {d8}, [r1], r12
+    vld1.8          {d9}, [r3]!
+    vld1.8          {d10}, [r1], r12
+    vld1.8          {d11}, [r3]!
+    vld1.8          {d12}, [r1], r12
+    vld1.8          {d13}, [r3]!
+    vld1.8          {d14}, [r1], r12
+    vld1.8          {d15}, [r3]!
+
+    vsubl.u8        q8, d0, d1
+    vsubl.u8        q9, d2, d3
+    vsubl.u8        q10, d4, d5
+    vsubl.u8        q11, d6, d7
+    vsubl.u8        q12, d8, d9
+    vsubl.u8        q13, d10, d11
+    vsubl.u8        q14, d12, d13
+    vsubl.u8        q15, d14, d15
+
+    vst1.16         {q8}, [r0]!             ;store diff
+    vst1.16         {q9}, [r0]!
+    vst1.16         {q10}, [r0]!
+    vst1.16         {q11}, [r0]!
+    vst1.16         {q12}, [r0]!
+    vst1.16         {q13}, [r0]!
+    vst1.16         {q14}, [r0]!
+    vst1.16         {q15}, [r0]!
+
+;v
+    vld1.8          {d0}, [r2], r12         ;load src
+    vld1.8          {d1}, [r3]!             ;load pred
+    vld1.8          {d2}, [r2], r12
+    vld1.8          {d3}, [r3]!
+    vld1.8          {d4}, [r2], r12
+    vld1.8          {d5}, [r3]!
+    vld1.8          {d6}, [r2], r12
+    vld1.8          {d7}, [r3]!
+    vld1.8          {d8}, [r2], r12
+    vld1.8          {d9}, [r3]!
+    vld1.8          {d10}, [r2], r12
+    vld1.8          {d11}, [r3]!
+    vld1.8          {d12}, [r2], r12
+    vld1.8          {d13}, [r3]!
+    vld1.8          {d14}, [r2], r12
+    vld1.8          {d15}, [r3]!
+
+    vsubl.u8        q8, d0, d1
+    vsubl.u8        q9, d2, d3
+    vsubl.u8        q10, d4, d5
+    vsubl.u8        q11, d6, d7
+    vsubl.u8        q12, d8, d9
+    vsubl.u8        q13, d10, d11
+    vsubl.u8        q14, d12, d13
+    vsubl.u8        q15, d14, d15
+
+    vst1.16         {q8}, [r0]!             ;store diff
+    vst1.16         {q9}, [r0]!
+    vst1.16         {q10}, [r0]!
+    vst1.16         {q11}, [r0]!
+    vst1.16         {q12}, [r0]!
+    vst1.16         {q13}, [r0]!
+    vst1.16         {q14}, [r0]!
+    vst1.16         {q15}, [r0]!
+
+    bx              lr
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/variance_neon.asm b/vp8/encoder/arm/neon/variance_neon.asm
new file mode 100644 (file)
index 0000000..64b83ca
--- /dev/null
@@ -0,0 +1,275 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_variance16x16_neon|
+    EXPORT  |vp8_variance16x8_neon|
+    EXPORT  |vp8_variance8x16_neon|
+    EXPORT  |vp8_variance8x8_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+; r0    unsigned char *src_ptr
+; r1    int source_stride
+; r2    unsigned char *ref_ptr
+; r3    int  recon_stride
+; stack unsigned int *sse
+|vp8_variance16x16_neon| PROC
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    mov             r12, #8
+
+variance16x16_neon_loop
+    vld1.8          {q0}, [r0], r1              ;Load up source and reference
+    vld1.8          {q2}, [r2], r3
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q3}, [r2], r3
+
+    vsubl.u8        q11, d0, d4                 ;calculate diff
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    ;VPADAL adds adjacent pairs of elements of a vector, and accumulates
+    ;the results into the elements of the destination vector. The explanation
+    ;in ARM guide is wrong.
+    vpadal.s16      q8, q11                     ;calculate sum
+    vmlal.s16       q9, d22, d22                ;calculate sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    bne             variance16x16_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    ldr             r12, [sp]                   ;load *sse from stack
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    ;vmov.32        r0, d0[0]                   ;this instruction costs a lot
+    ;vmov.32        r1, d1[0]
+    ;mul            r0, r0, r0
+    ;str            r1, [r12]
+    ;sub            r0, r1, r0, asr #8
+
+    ;sum is in [-255x256, 255x256]. sumxsum is 32-bit. Shift to right should
+    ;have sign-bit exension, which is vshr.s. Have to use s32 to make it right.
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [r12]              ;store sse
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    bx              lr
+
+    ENDP
+
+;================================
+;unsigned int vp8_variance16x8_c(
+;    unsigned char *src_ptr,
+;    int  source_stride,
+;    unsigned char *ref_ptr,
+;    int  recon_stride,
+;   unsigned int *sse)
+|vp8_variance16x8_neon| PROC
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    mov             r12, #4
+
+variance16x8_neon_loop
+    vld1.8          {q0}, [r0], r1              ;Load up source and reference
+    vld1.8          {q2}, [r2], r3
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q3}, [r2], r3
+
+    vsubl.u8        q11, d0, d4                 ;calculate diff
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    vpadal.s16      q8, q11                     ;calculate sum
+    vmlal.s16       q9, d22, d22                ;calculate sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    bne             variance16x8_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    ldr             r12, [sp]                   ;load *sse from stack
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [r12]              ;store sse
+    vshr.s32        d10, d10, #7
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    bx              lr
+
+    ENDP
+
+;=================================
+;unsigned int vp8_variance8x16_c(
+;    unsigned char *src_ptr,
+;    int  source_stride,
+;    unsigned char *ref_ptr,
+;    int  recon_stride,
+;   unsigned int *sse)
+
+|vp8_variance8x16_neon| PROC
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    mov             r12, #8
+
+variance8x16_neon_loop
+    vld1.8          {d0}, [r0], r1              ;Load up source and reference
+    vld1.8          {d4}, [r2], r3
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d6}, [r2], r3
+
+    vsubl.u8        q11, d0, d4                 ;calculate diff
+    vsubl.u8        q12, d2, d6
+
+    vpadal.s16      q8, q11                     ;calculate sum
+    vmlal.s16       q9, d22, d22                ;calculate sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+
+    bne             variance8x16_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    ldr             r12, [sp]                   ;load *sse from stack
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [r12]              ;store sse
+    vshr.s32        d10, d10, #7
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    bx              lr
+
+    ENDP
+
+;==================================
+; r0    unsigned char *src_ptr
+; r1    int source_stride
+; r2    unsigned char *ref_ptr
+; r3    int  recon_stride
+; stack unsigned int *sse
+|vp8_variance8x8_neon| PROC
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    mov             r12, #2
+
+variance8x8_neon_loop
+    vld1.8          {d0}, [r0], r1              ;Load up source and reference
+    vld1.8          {d4}, [r2], r3
+    vld1.8          {d1}, [r0], r1
+    vld1.8          {d5}, [r2], r3
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d6}, [r2], r3
+    vld1.8          {d3}, [r0], r1
+    vld1.8          {d7}, [r2], r3
+
+    vsubl.u8        q11, d0, d4                 ;calculate diff
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    vpadal.s16      q8, q11                     ;calculate sum
+    vmlal.s16       q9, d22, d22                ;calculate sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    bne             variance8x8_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    ldr             r12, [sp]                   ;load *sse from stack
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [r12]              ;store sse
+    vshr.s32        d10, d10, #6
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    bx              lr
+
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_memcpy_neon.asm b/vp8/encoder/arm/neon/vp8_memcpy_neon.asm
new file mode 100644 (file)
index 0000000..f26b4d7
--- /dev/null
@@ -0,0 +1,67 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8_memcpy_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;=========================================
+;void vp8_memcpy_neon(unsigned char *dst_ptr, unsigned char *src_ptr, int sz);
+|vp8_memcpy_neon| PROC
+    ;pld                [r1]                        ;preload pred data
+    ;pld                [r1, #128]
+    ;pld                [r1, #256]
+    ;pld                [r1, #384]
+
+    mov             r12, r2, lsr #8                 ;copy 256 bytes data at one time
+
+memcpy_neon_loop
+    vld1.8          {q0, q1}, [r1]!                 ;load src data
+    subs            r12, r12, #1
+    vld1.8          {q2, q3}, [r1]!
+    vst1.8          {q0, q1}, [r0]!                 ;copy to dst_ptr
+    vld1.8          {q4, q5}, [r1]!
+    vst1.8          {q2, q3}, [r0]!
+    vld1.8          {q6, q7}, [r1]!
+    vst1.8          {q4, q5}, [r0]!
+    vld1.8          {q8, q9}, [r1]!
+    vst1.8          {q6, q7}, [r0]!
+    vld1.8          {q10, q11}, [r1]!
+    vst1.8          {q8, q9}, [r0]!
+    vld1.8          {q12, q13}, [r1]!
+    vst1.8          {q10, q11}, [r0]!
+    vld1.8          {q14, q15}, [r1]!
+    vst1.8          {q12, q13}, [r0]!
+    vst1.8          {q14, q15}, [r0]!
+
+    ;pld                [r1]                        ;preload pred data -- need to adjust for real device
+    ;pld                [r1, #128]
+    ;pld                [r1, #256]
+    ;pld                [r1, #384]
+
+    bne             memcpy_neon_loop
+
+    ands            r3, r2, #0xff                   ;extra copy
+    beq             done_copy_neon_loop
+
+extra_copy_neon_loop
+    vld1.8          {q0}, [r1]!                 ;load src data
+    subs            r3, r3, #16
+    vst1.8          {q0}, [r0]!
+    bne             extra_copy_neon_loop
+
+done_copy_neon_loop
+    bx              lr
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_mse16x16_neon.asm b/vp8/encoder/arm/neon/vp8_mse16x16_neon.asm
new file mode 100644 (file)
index 0000000..f535967
--- /dev/null
@@ -0,0 +1,172 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_mse16x16_neon|
+    EXPORT  |vp8_get16x16pred_error_neon|
+    EXPORT  |vp8_get4x4sse_cs_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;============================
+; r0    unsigned char *src_ptr
+; r1    int source_stride
+; r2    unsigned char *ref_ptr
+; r3    int  recon_stride
+; stack unsigned int *sse
+;note: in this function, sum is never used. So, we can remove this part of calculation
+;from vp8_variance().
+
+|vp8_mse16x16_neon| PROC
+    vmov.i8         q7, #0                      ;q7, q8, q9, q10 - sse
+    vmov.i8         q8, #0
+    vmov.i8         q9, #0
+    vmov.i8         q10, #0
+
+    mov             r12, #8
+
+mse16x16_neon_loop
+    vld1.8          {q0}, [r0], r1              ;Load up source and reference
+    vld1.8          {q2}, [r2], r3
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q3}, [r2], r3
+
+    vsubl.u8        q11, d0, d4
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    vmlal.s16       q7, d22, d22
+    vmlal.s16       q8, d23, d23
+
+    subs            r12, r12, #1
+
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vmlal.s16       q7, d26, d26
+    vmlal.s16       q8, d27, d27
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    bne             mse16x16_neon_loop
+
+    vadd.u32        q7, q7, q8
+    vadd.u32        q9, q9, q10
+
+    ldr             r12, [sp]               ;load *sse from stack
+
+    vadd.u32        q10, q7, q9
+    vpaddl.u32      q1, q10
+    vadd.u64        d0, d2, d3
+
+    vst1.32         {d0[0]}, [r12]
+    vmov.32         r0, d0[0]
+
+    bx              lr
+
+    ENDP
+
+;============================
+; r0    unsigned char *src_ptr
+; r1    int src_stride
+; r2    unsigned char *ref_ptr
+; r3    int ref_stride
+|vp8_get16x16pred_error_neon| PROC
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - pred_error
+    vmov.i8         q10, #0
+
+    mov             r12, #8
+
+get16x16pred_error_neon_loop
+    vld1.8          {q0}, [r0], r1              ;Load up source and reference
+    vld1.8          {q2}, [r2], r3
+    vld1.8          {q1}, [r0], r1
+    vld1.8          {q3}, [r2], r3
+
+    vsubl.u8        q11, d0, d4
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    vpadal.s16      q8, q11
+    vmlal.s16       q9, d22, d22
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    bne             get16x16pred_error_neon_loop
+
+    vadd.u32        q10, q9, q10
+    vpaddl.s32      q0, q8
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]
+    bx              lr
+
+    ENDP
+
+;=============================
+; r0    unsigned char *src_ptr,
+; r1    int  source_stride,
+; r2    unsigned char *ref_ptr,
+; r3    int  recon_stride
+|vp8_get4x4sse_cs_neon| PROC
+    vld1.8          {d0}, [r0], r1              ;Load up source and reference
+    vld1.8          {d4}, [r2], r3
+    vld1.8          {d1}, [r0], r1
+    vld1.8          {d5}, [r2], r3
+    vld1.8          {d2}, [r0], r1
+    vld1.8          {d6}, [r2], r3
+    vld1.8          {d3}, [r0], r1
+    vld1.8          {d7}, [r2], r3
+
+    vsubl.u8        q11, d0, d4
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    vmull.s16       q7, d22, d22
+    vmull.s16       q8, d24, d24
+    vmull.s16       q9, d26, d26
+    vmull.s16       q10, d28, d28
+
+    vadd.u32        q7, q7, q8
+    vadd.u32        q9, q9, q10
+    vadd.u32        q9, q7, q9
+
+    vpaddl.u32      q1, q9
+    vadd.u64        d0, d2, d3
+
+    vmov.32         r0, d0[0]
+    bx              lr
+
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_packtokens_armv7.asm b/vp8/encoder/arm/neon/vp8_packtokens_armv7.asm
new file mode 100644 (file)
index 0000000..9c52c52
--- /dev/null
@@ -0,0 +1,300 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8cx_pack_tokens_armv7|
+
+    INCLUDE vpx_vp8_enc_asm_offsets.asm
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY
+
+; r0 vp8_writer *w
+; r1 const TOKENEXTRA *p
+; r2 int xcount
+; r3 vp8_coef_encodings
+; s0 vp8_extra_bits
+; s1 vp8_coef_tree
+|vp8cx_pack_tokens_armv7| PROC
+    push    {r4-r11, lr}
+
+    ; Add size of xcount * sizeof (TOKENEXTRA) to get stop
+    ;  sizeof (TOKENEXTRA) is 20
+    add     r2, r2, r2, lsl #2          ; xcount
+    sub     sp, sp, #12
+    add     r2, r1, r2, lsl #2          ; stop = p + xcount
+    str     r2, [sp, #0]
+    str     r3, [sp, #8]                ; save vp8_coef_encodings
+    ldr     r2, [r0, #vp8_writer_lowvalue]
+    ldr     r5, [r0, #vp8_writer_range]
+    ldr     r3, [r0, #vp8_writer_count]
+    b       check_p_lt_stop
+
+while_p_lt_stop
+    ldr     r6, [r1, #tokenextra_token] ; t
+    ldr     r4, [sp, #8]                ; vp8_coef_encodings
+    mov     lr, #0
+    add     r4, r4, r6, lsl #3          ; a = vp8_coef_encodings + t
+    ldr     r9, [r1, #tokenextra_context_tree]   ; pp
+
+    ldr     r7, [r1, #tokenextra_skip_eob_node]
+
+    ldr     r6, [r4, #vp8_token_value]  ; v
+    ldr     r8, [r4, #vp8_token_len]    ; n
+
+    ; vp8 specific skip_eob_node
+    cmp     r7, #0
+    movne   lr, #2                      ; i = 2
+    subne   r8, r8, #1                  ; --n
+
+    ; reverse the stream of bits to be packed.  Normally
+    ; the most significant bit is peeled off and compared
+    ; in the form of (v >> --n) & 1.  ARM architecture has
+    ; the ability to set a flag based on the value of the
+    ; bit shifted off the bottom of the register.  To make
+    ; that happen the bitstream is reversed.
+    rbit    r12, r6
+    rsb     r4, r8, #32                 ; 32-n
+    ldr     r10, [sp, #52]              ; vp8_coef_tree
+
+    ; v is kept in r12 during the token pack loop
+    lsr     r12, r12, r4                ; v >>= 32 - n
+
+; loop start
+token_loop
+    ldrb    r4, [r9, lr, asr #1]        ; pp [i>>1]
+    sub     r7, r5, #1                  ; range-1
+
+    ; Decisions are made based on the bit value shifted
+    ; off of v, so set a flag here based on this.
+    ; This value is refered to as "bb"
+    lsrs    r12, r12, #1                ; bb = v >> n
+    mul     r4, r4, r7                  ; ((range-1) * pp[i>>1]))
+
+    ; bb can only be 0 or 1.  So only execute this statement
+    ; if bb == 1, otherwise it will act like i + 0
+    addcs   lr, lr, #1                  ; i + bb
+
+    mov     r7, #1
+    ldrsb   lr, [r10, lr]               ; i = vp8_coef_tree[i+bb]
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * pp[i>>1]) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bb) range = range-split
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start
+token_zero_while_loop
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     token_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]               ; w->buffer[x]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]               ; w->buffer[x] + 1
+token_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]
+
+    ; r10 is used earlier in the loop, but r10 is used as
+    ; temp variable here.  So after r10 is used, reload
+    ; vp8_coef_tree_dcd into r10
+    ldr     r10, [sp, #52]              ; vp8_coef_tree
+
+token_count_lt_zero
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    subs    r8, r8, #1                  ; --n
+    bne     token_loop
+
+    ldr     r6, [r1, #tokenextra_token] ; t
+    ldr     r7, [sp, #48]               ; vp8_extra_bits
+    ; Add t * sizeof (vp8_extra_bit_struct) to get the desired
+    ;  element.  Here vp8_extra_bit_struct == 20
+    add     r6, r6, r6, lsl #2          ; b = vp8_extra_bits + t
+    add     r12, r7, r6, lsl #2         ; b = vp8_extra_bits + t
+
+    ldr     r4, [r12, #vp8_extra_bit_struct_base_val]
+    cmp     r4, #0
+    beq     skip_extra_bits
+
+;   if( b->base_val)
+    ldr     r8, [r12, #vp8_extra_bit_struct_len] ; L
+    ldr     lr, [r1, #tokenextra_extra] ; e = p->Extra
+    cmp     r8, #0                      ; if( L)
+    beq     no_extra_bits
+
+    ldr     r9, [r12, #vp8_extra_bit_struct_prob]
+    asr     r7, lr, #1                  ; v=e>>1
+
+    ldr     r10, [r12, #vp8_extra_bit_struct_tree]
+    str     r10, [sp, #4]               ; b->tree
+
+    rbit    r12, r7                     ; reverse v
+    rsb     r4, r8, #32
+    lsr     r12, r12, r4
+
+    mov     lr, #0                      ; i = 0
+
+extra_bits_loop
+    ldrb    r4, [r9, lr, asr #1]            ; pp[i>>1]
+    sub     r7, r5, #1                  ; range-1
+    lsrs    r12, r12, #1                ; v >> n
+    mul     r4, r4, r7                  ; (range-1) * pp[i>>1]
+    addcs   lr, lr, #1                  ; i + bb
+
+    mov     r7, #1
+    ldrsb   lr, [r10, lr]               ; i = b->tree[i+bb]
+    add     r4, r7, r4, lsr #8          ; split = 1 +  (((range-1) * pp[i>>1]) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bb) range = range-split
+
+    clz     r6, r4
+    sub     r6, r6, #24
+
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     extra_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset= shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     extra_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos - 1
+    b       extra_zero_while_start
+extra_zero_while_loop
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+extra_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     extra_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]
+extra_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]=(lowvalue >> (24-offset))
+    ldr     r10, [sp, #4]               ; b->tree
+extra_count_lt_zero
+    lsl     r2, r2, r6
+
+    subs    r8, r8, #1                  ; --n
+    bne     extra_bits_loop             ; while (n)
+
+no_extra_bits
+    ldr     lr, [r1, #4]                ; e = p->Extra
+    add     r4, r5, #1                  ; range + 1
+    tst     lr, #1
+    lsr     r4, r4, #1                  ; split = (range + 1) >> 1
+    addne   r2, r2, r4                  ; lowvalue += split
+    subne   r4, r5, r4                  ; range = range-split
+    tst     r2, #0x80000000             ; lowvalue & 0x80000000
+    lsl     r5, r4, #1                  ; range <<= 1
+    beq     end_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]
+    mov     r7, #0
+    sub     r4, r4, #1
+    b       end_zero_while_start
+end_zero_while_loop
+    strb    r7, [r6, r4]
+    sub     r4, r4, #1                  ; x--
+end_zero_while_start
+    cmp     r4, #0
+    ldrge   r6, [r0, #vp8_writer_buffer]
+    ldrb    r12, [r6, r4]
+    cmpge   r12, #0xff
+    beq     end_zero_while_loop
+
+    ldr     r6, [r0, #vp8_writer_buffer]
+    ldrb    r7, [r6, r4]
+    add     r7, r7, #1
+    strb    r7, [r6, r4]
+end_high_bit_not_set
+    adds    r3, r3, #1                  ; ++count
+    lsl     r2, r2, #1                  ; lowvalue  <<= 1
+    bne     end_count_zero
+
+    ldr     r4, [r0, #vp8_writer_pos]
+    mvn     r3, #7
+    ldr     r7, [r0, #vp8_writer_buffer]
+    lsr     r6, r2, #24                 ; lowvalue >> 24
+    add     r12, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r12, [r0, #0x10]
+    strb    r6, [r7, r4]
+end_count_zero
+skip_extra_bits
+    add     r1, r1, #TOKENEXTRA_SZ      ; ++p
+check_p_lt_stop
+    ldr     r4, [sp, #0]                ; stop
+    cmp     r1, r4                      ; while( p < stop)
+    bcc     while_p_lt_stop
+
+    str     r2, [r0, #vp8_writer_lowvalue]
+    str     r5, [r0, #vp8_writer_range]
+    str     r3, [r0, #vp8_writer_count]
+    add     sp, sp, #12
+    pop     {r4-r11, pc}
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_packtokens_mbrow_armv7.asm b/vp8/encoder/arm/neon/vp8_packtokens_mbrow_armv7.asm
new file mode 100644 (file)
index 0000000..92b0989
--- /dev/null
@@ -0,0 +1,335 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8cx_pack_mb_row_tokens_armv7|
+
+    INCLUDE vpx_vp8_enc_asm_offsets.asm
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY
+
+; r0 VP8_COMP *cpi
+; r1 vp8_writer *w
+; r2 vp8_coef_encodings
+; r3 vp8_extra_bits
+; s0 vp8_coef_tree
+
+|vp8cx_pack_mb_row_tokens_armv7| PROC
+    push    {r4-r11, lr}
+    sub     sp, sp, #24
+
+    ; Compute address of cpi->common.mb_rows
+    ldr     r4, _VP8_COMP_common_
+    ldr     r6, _VP8_COMMON_MBrows_
+    add     r4, r0, r4
+
+    ldr     r5, [r4, r6]                ; load up mb_rows
+
+    str     r2, [sp, #20]               ; save vp8_coef_encodings
+    str     r5, [sp, #12]               ; save mb_rows
+    str     r3, [sp, #8]                ; save vp8_extra_bits
+
+    ldr     r4, _VP8_COMP_tplist_
+    add     r4, r0, r4
+    ldr     r7, [r4, #0]                ; dereference cpi->tp_list
+
+    mov     r0, r1                      ; keep same as other loops
+
+    ldr     r2, [r0, #vp8_writer_lowvalue]
+    ldr     r5, [r0, #vp8_writer_range]
+    ldr     r3, [r0, #vp8_writer_count]
+
+mb_row_loop
+
+    ldr     r1, [r7, #tokenlist_start]
+    ldr     r9, [r7, #tokenlist_stop]
+    str     r9, [sp, #0]                ; save stop for later comparison
+    str     r7, [sp, #16]               ; tokenlist address for next time
+
+    b       check_p_lt_stop
+
+    ; actuall work gets done here!
+
+while_p_lt_stop
+    ldr     r6, [r1, #tokenextra_token] ; t
+    ldr     r4, [sp, #20]               ; vp8_coef_encodings
+    mov     lr, #0
+    add     r4, r4, r6, lsl #3          ; a = vp8_coef_encodings + t
+    ldr     r9, [r1, #tokenextra_context_tree]   ; pp
+
+    ldr     r7, [r1, #tokenextra_skip_eob_node]
+
+    ldr     r6, [r4, #vp8_token_value]  ; v
+    ldr     r8, [r4, #vp8_token_len]    ; n
+
+    ; vp8 specific skip_eob_node
+    cmp     r7, #0
+    movne   lr, #2                      ; i = 2
+    subne   r8, r8, #1                  ; --n
+
+    ; reverse the stream of bits to be packed.  Normally
+    ; the most significant bit is peeled off and compared
+    ; in the form of (v >> --n) & 1.  ARM architecture has
+    ; the ability to set a flag based on the value of the
+    ; bit shifted off the bottom of the register.  To make
+    ; that happen the bitstream is reversed.
+    rbit    r12, r6
+    rsb     r4, r8, #32                 ; 32-n
+    ldr     r10, [sp, #60]              ; vp8_coef_tree
+
+    ; v is kept in r12 during the token pack loop
+    lsr     r12, r12, r4                ; v >>= 32 - n
+
+; loop start
+token_loop
+    ldrb    r4, [r9, lr, asr #1]        ; pp [i>>1]
+    sub     r7, r5, #1                  ; range-1
+
+    ; Decisions are made based on the bit value shifted
+    ; off of v, so set a flag here based on this.
+    ; This value is refered to as "bb"
+    lsrs    r12, r12, #1                ; bb = v >> n
+    mul     r4, r4, r7                  ; ((range-1) * pp[i>>1]))
+
+    ; bb can only be 0 or 1.  So only execute this statement
+    ; if bb == 1, otherwise it will act like i + 0
+    addcs   lr, lr, #1                  ; i + bb
+
+    mov     r7, #1
+    ldrsb   lr, [r10, lr]               ; i = vp8_coef_tree[i+bb]
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * pp[i>>1]) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bb) range = range-split
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start
+token_zero_while_loop
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     token_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]               ; w->buffer[x]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]               ; w->buffer[x] + 1
+token_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]
+
+    ; r10 is used earlier in the loop, but r10 is used as
+    ; temp variable here.  So after r10 is used, reload
+    ; vp8_coef_tree_dcd into r10
+    ldr     r10, [sp, #60]              ; vp8_coef_tree
+
+token_count_lt_zero
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    subs    r8, r8, #1                  ; --n
+    bne     token_loop
+
+    ldr     r6, [r1, #tokenextra_token] ; t
+    ldr     r7, [sp, #8]                ; vp8_extra_bits
+    ; Add t * sizeof (vp8_extra_bit_struct) to get the desired
+    ;  element.  Here vp8_extra_bit_struct == 20
+    add     r6, r6, r6, lsl #2          ; b = vp8_extra_bits + t
+    add     r12, r7, r6, lsl #2         ; b = vp8_extra_bits + t
+
+    ldr     r4, [r12, #vp8_extra_bit_struct_base_val]
+    cmp     r4, #0
+    beq     skip_extra_bits
+
+;   if( b->base_val)
+    ldr     r8, [r12, #vp8_extra_bit_struct_len] ; L
+    ldr     lr, [r1, #tokenextra_extra] ; e = p->Extra
+    cmp     r8, #0                      ; if( L)
+    beq     no_extra_bits
+
+    ldr     r9, [r12, #vp8_extra_bit_struct_prob]
+    asr     r7, lr, #1                  ; v=e>>1
+
+    ldr     r10, [r12, #vp8_extra_bit_struct_tree]
+    str     r10, [sp, #4]               ; b->tree
+
+    rbit    r12, r7                     ; reverse v
+    rsb     r4, r8, #32
+    lsr     r12, r12, r4
+
+    mov     lr, #0                      ; i = 0
+
+extra_bits_loop
+    ldrb    r4, [r9, lr, asr #1]            ; pp[i>>1]
+    sub     r7, r5, #1                  ; range-1
+    lsrs    r12, r12, #1                ; v >> n
+    mul     r4, r4, r7                  ; (range-1) * pp[i>>1]
+    addcs   lr, lr, #1                  ; i + bb
+
+    mov     r7, #1
+    ldrsb   lr, [r10, lr]               ; i = b->tree[i+bb]
+    add     r4, r7, r4, lsr #8          ; split = 1 +  (((range-1) * pp[i>>1]) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bb) range = range-split
+
+    clz     r6, r4
+    sub     r6, r6, #24
+
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     extra_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset= shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     extra_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos - 1
+    b       extra_zero_while_start
+extra_zero_while_loop
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+extra_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     extra_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]
+extra_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]=(lowvalue >> (24-offset))
+    ldr     r10, [sp, #4]               ; b->tree
+extra_count_lt_zero
+    lsl     r2, r2, r6
+
+    subs    r8, r8, #1                  ; --n
+    bne     extra_bits_loop             ; while (n)
+
+no_extra_bits
+    ldr     lr, [r1, #4]                ; e = p->Extra
+    add     r4, r5, #1                  ; range + 1
+    tst     lr, #1
+    lsr     r4, r4, #1                  ; split = (range + 1) >> 1
+    addne   r2, r2, r4                  ; lowvalue += split
+    subne   r4, r5, r4                  ; range = range-split
+    tst     r2, #0x80000000             ; lowvalue & 0x80000000
+    lsl     r5, r4, #1                  ; range <<= 1
+    beq     end_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]
+    mov     r7, #0
+    sub     r4, r4, #1
+    b       end_zero_while_start
+end_zero_while_loop
+    strb    r7, [r6, r4]
+    sub     r4, r4, #1                  ; x--
+end_zero_while_start
+    cmp     r4, #0
+    ldrge   r6, [r0, #vp8_writer_buffer]
+    ldrb    r12, [r6, r4]
+    cmpge   r12, #0xff
+    beq     end_zero_while_loop
+
+    ldr     r6, [r0, #vp8_writer_buffer]
+    ldrb    r7, [r6, r4]
+    add     r7, r7, #1
+    strb    r7, [r6, r4]
+end_high_bit_not_set
+    adds    r3, r3, #1                  ; ++count
+    lsl     r2, r2, #1                  ; lowvalue  <<= 1
+    bne     end_count_zero
+
+    ldr     r4, [r0, #vp8_writer_pos]
+    mvn     r3, #7
+    ldr     r7, [r0, #vp8_writer_buffer]
+    lsr     r6, r2, #24                 ; lowvalue >> 24
+    add     r12, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r12, [r0, #0x10]
+    strb    r6, [r7, r4]
+end_count_zero
+skip_extra_bits
+    add     r1, r1, #TOKENEXTRA_SZ      ; ++p
+check_p_lt_stop
+    ldr     r4, [sp, #0]                ; stop
+    cmp     r1, r4                      ; while( p < stop)
+    bcc     while_p_lt_stop
+
+    ldr     r6, [sp, #12]               ; mb_rows
+    ldr     r7, [sp, #16]               ; tokenlist address
+    subs    r6, r6, #1
+    add     r7, r7, #TOKENLIST_SZ       ; next element in the array
+    str     r6, [sp, #12]
+    bne     mb_row_loop
+
+    str     r2, [r0, #vp8_writer_lowvalue]
+    str     r5, [r0, #vp8_writer_range]
+    str     r3, [r0, #vp8_writer_count]
+    add     sp, sp, #24
+    pop     {r4-r11, pc}
+    ENDP
+
+_VP8_COMP_common_
+    DCD     vp8_comp_common
+_VP8_COMMON_MBrows_
+    DCD     vp8_common_mb_rows
+_VP8_COMP_tplist_
+    DCD     vp8_comp_tplist
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_packtokens_partitions_armv7.asm b/vp8/encoder/arm/neon/vp8_packtokens_partitions_armv7.asm
new file mode 100644 (file)
index 0000000..6d5f882
--- /dev/null
@@ -0,0 +1,471 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT |vp8cx_pack_tokens_into_partitions_armv7|
+
+    INCLUDE vpx_vp8_enc_asm_offsets.asm
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA    |.text|, CODE, READONLY
+
+; r0 VP8_COMP *cpi
+; r1 unsigned char *cx_data
+; r2 int num_part
+; r3 *size
+; s0 vp8_coef_encodings
+; s1 vp8_extra_bits,
+; s2 const vp8_tree_index *,
+
+|vp8cx_pack_tokens_into_partitions_armv7| PROC
+    push    {r4-r11, lr}
+    sub     sp, sp, #44
+
+    ; Compute address of cpi->common.mb_rows
+    ldr     r4, _VP8_COMP_common_
+    ldr     r6, _VP8_COMMON_MBrows_
+    add     r4, r0, r4
+
+    ldr     r5, [r4, r6]                ; load up mb_rows
+
+    str     r5, [sp, #36]               ; save mb_rows
+    str     r1, [sp, #24]               ; save cx_data
+    str     r2, [sp, #20]               ; save num_part
+    str     r3, [sp, #8]                ; save *size
+
+    ; *size = 3*(num_part -1 );
+    sub     r2, r2, #1                  ; num_part - 1
+    add     r2, r2, r2, lsl #1          ; 3*(num_part - 1)
+    str     r2, [r3]
+
+    add     r2, r2, r1                  ; cx_data + *size
+    str     r2, [sp, #40]               ; ptr
+
+    ldr     r4, _VP8_COMP_tplist_
+    add     r4, r0, r4
+    ldr     r7, [r4, #0]                ; dereference cpi->tp_list
+    str     r7, [sp, #32]               ; store start of cpi->tp_list
+
+    ldr     r11, _VP8_COMP_bc2_         ; load up vp8_writer out of cpi
+    add     r0, r0, r11
+
+    mov     r11, #0
+    str     r11, [sp, #28]              ; i
+
+numparts_loop
+    ldr     r10, [sp, #40]              ; ptr
+    ldr     r5,  [sp, #36]              ; move mb_rows to the counting section
+    str     r5,  [sp, #12]
+
+    ; Reset all of the VP8 Writer data for each partition that
+    ; is processed.
+    ; start_encode
+    mov     r2, #0                      ; vp8_writer_lowvalue
+    mov     r5, #255                    ; vp8_writer_range
+    mvn     r3, #23                     ; vp8_writer_count
+
+    str     r2,  [r0, #vp8_writer_value]
+    str     r2,  [r0, #vp8_writer_pos]
+    str     r10, [r0, #vp8_writer_buffer]
+
+mb_row_loop
+
+    ldr     r1, [r7, #tokenlist_start]
+    ldr     r9, [r7, #tokenlist_stop]
+    str     r9, [sp, #0]                ; save stop for later comparison
+    str     r7, [sp, #16]               ; tokenlist address for next time
+
+    b       check_p_lt_stop
+
+    ; actual work gets done here!
+
+while_p_lt_stop
+    ldr     r6, [r1, #tokenextra_token] ; t
+    ldr     r4, [sp, #80]               ; vp8_coef_encodings
+    mov     lr, #0
+    add     r4, r4, r6, lsl #3          ; a = vp8_coef_encodings + t
+    ldr     r9, [r1, #tokenextra_context_tree]   ; pp
+
+    ldr     r7, [r1, #tokenextra_skip_eob_node]
+
+    ldr     r6, [r4, #vp8_token_value]  ; v
+    ldr     r8, [r4, #vp8_token_len]    ; n
+
+    ; vp8 specific skip_eob_node
+    cmp     r7, #0
+    movne   lr, #2                      ; i = 2
+    subne   r8, r8, #1                  ; --n
+
+    ; reverse the stream of bits to be packed.  Normally
+    ; the most significant bit is peeled off and compared
+    ; in the form of (v >> --n) & 1.  ARM architecture has
+    ; the ability to set a flag based on the value of the
+    ; bit shifted off the bottom of the register.  To make
+    ; that happen the bitstream is reversed.
+    rbit    r12, r6
+    rsb     r4, r8, #32                 ; 32-n
+    ldr     r10, [sp, #88]              ; vp8_coef_tree
+
+    ; v is kept in r12 during the token pack loop
+    lsr     r12, r12, r4                ; v >>= 32 - n
+
+; loop start
+token_loop
+    ldrb    r4, [r9, lr, asr #1]        ; pp [i>>1]
+    sub     r7, r5, #1                  ; range-1
+
+    ; Decisions are made based on the bit value shifted
+    ; off of v, so set a flag here based on this.
+    ; This value is refered to as "bb"
+    lsrs    r12, r12, #1                ; bb = v >> n
+    mul     r4, r4, r7                  ; ((range-1) * pp[i>>1]))
+
+    ; bb can only be 0 or 1.  So only execute this statement
+    ; if bb == 1, otherwise it will act like i + 0
+    addcs   lr, lr, #1                  ; i + bb
+
+    mov     r7, #1
+    ldrsb   lr, [r10, lr]               ; i = vp8_coef_tree[i+bb]
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * pp[i>>1]) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bb) range = range-split
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start
+token_zero_while_loop
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     token_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]               ; w->buffer[x]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]               ; w->buffer[x] + 1
+token_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]
+
+    ; r10 is used earlier in the loop, but r10 is used as
+    ; temp variable here.  So after r10 is used, reload
+    ; vp8_coef_tree_dcd into r10
+    ldr     r10, [sp, #88]              ; vp8_coef_tree
+
+token_count_lt_zero
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    subs    r8, r8, #1                  ; --n
+    bne     token_loop
+
+    ldr     r6, [r1, #tokenextra_token] ; t
+    ldr     r7, [sp, #84]                ; vp8_extra_bits
+    ; Add t * sizeof (vp8_extra_bit_struct) to get the desired
+    ;  element.  Here vp8_extra_bit_struct == 20
+    add     r6, r6, r6, lsl #2          ; b = vp8_extra_bits + t
+    add     r12, r7, r6, lsl #2         ; b = vp8_extra_bits + t
+
+    ldr     r4, [r12, #vp8_extra_bit_struct_base_val]
+    cmp     r4, #0
+    beq     skip_extra_bits
+
+;   if( b->base_val)
+    ldr     r8, [r12, #vp8_extra_bit_struct_len] ; L
+    ldr     lr, [r1, #tokenextra_extra] ; e = p->Extra
+    cmp     r8, #0                      ; if( L)
+    beq     no_extra_bits
+
+    ldr     r9, [r12, #vp8_extra_bit_struct_prob]
+    asr     r7, lr, #1                  ; v=e>>1
+
+    ldr     r10, [r12, #vp8_extra_bit_struct_tree]
+    str     r10, [sp, #4]               ; b->tree
+
+    rbit    r12, r7                     ; reverse v
+    rsb     r4, r8, #32
+    lsr     r12, r12, r4
+
+    mov     lr, #0                      ; i = 0
+
+extra_bits_loop
+    ldrb    r4, [r9, lr, asr #1]        ; pp[i>>1]
+    sub     r7, r5, #1                  ; range-1
+    lsrs    r12, r12, #1                ; v >> n
+    mul     r4, r4, r7                  ; (range-1) * pp[i>>1]
+    addcs   lr, lr, #1                  ; i + bb
+
+    mov     r7, #1
+    ldrsb   lr, [r10, lr]               ; i = b->tree[i+bb]
+    add     r4, r7, r4, lsr #8          ; split = 1 +  (((range-1) * pp[i>>1]) >> 8)
+
+    addcs   r2, r2, r4                  ; if  (bb) lowvalue += split
+    subcs   r4, r5, r4                  ; if  (bb) range = range-split
+
+    clz     r6, r4
+    sub     r6, r6, #24
+
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     extra_count_lt_zero         ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset= shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     extra_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos - 1
+    b       extra_zero_while_start
+extra_zero_while_loop
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+extra_zero_while_start
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     extra_zero_while_loop
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]
+extra_high_bit_not_set
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]=(lowvalue >> (24-offset))
+    ldr     r10, [sp, #4]               ; b->tree
+extra_count_lt_zero
+    lsl     r2, r2, r6
+
+    subs    r8, r8, #1                  ; --n
+    bne     extra_bits_loop             ; while (n)
+
+no_extra_bits
+    ldr     lr, [r1, #4]                ; e = p->Extra
+    add     r4, r5, #1                  ; range + 1
+    tst     lr, #1
+    lsr     r4, r4, #1                  ; split = (range + 1) >> 1
+    addne   r2, r2, r4                  ; lowvalue += split
+    subne   r4, r5, r4                  ; range = range-split
+    tst     r2, #0x80000000             ; lowvalue & 0x80000000
+    lsl     r5, r4, #1                  ; range <<= 1
+    beq     end_high_bit_not_set
+
+    ldr     r4, [r0, #vp8_writer_pos]
+    mov     r7, #0
+    sub     r4, r4, #1
+    b       end_zero_while_start
+end_zero_while_loop
+    strb    r7, [r6, r4]
+    sub     r4, r4, #1                  ; x--
+end_zero_while_start
+    cmp     r4, #0
+    ldrge   r6, [r0, #vp8_writer_buffer]
+    ldrb    r12, [r6, r4]
+    cmpge   r12, #0xff
+    beq     end_zero_while_loop
+
+    ldr     r6, [r0, #vp8_writer_buffer]
+    ldrb    r7, [r6, r4]
+    add     r7, r7, #1
+    strb    r7, [r6, r4]
+end_high_bit_not_set
+    adds    r3, r3, #1                  ; ++count
+    lsl     r2, r2, #1                  ; lowvalue  <<= 1
+    bne     end_count_zero
+
+    ldr     r4, [r0, #vp8_writer_pos]
+    mvn     r3, #7
+    ldr     r7, [r0, #vp8_writer_buffer]
+    lsr     r6, r2, #24                 ; lowvalue >> 24
+    add     r12, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r12, [r0, #0x10]
+    strb    r6, [r7, r4]
+end_count_zero
+skip_extra_bits
+    add     r1, r1, #TOKENEXTRA_SZ      ; ++p
+check_p_lt_stop
+    ldr     r4, [sp, #0]                ; stop
+    cmp     r1, r4                      ; while( p < stop)
+    bcc     while_p_lt_stop
+
+    ldr     r10, [sp, #20]              ; num_parts
+    mov     r1, #TOKENLIST_SZ
+    mul     r1, r10, r1
+
+    ldr     r6, [sp, #12]               ; mb_rows
+    ldr     r7, [sp, #16]               ; tokenlist address
+    subs    r6, r6, r10
+    add     r7, r7, r1                  ; next element in the array
+    str     r6, [sp, #12]
+    bgt     mb_row_loop
+
+    mov     r12, #32
+
+stop_encode_loop
+    sub     r7, r5, #1                  ; range-1
+
+    mov     r4, r7, lsl #7              ; ((range-1) * 128)
+
+    mov     r7, #1
+    add     r4, r7, r4, lsr #8          ; 1 + (((range-1) * 128) >> 8)
+
+    ; Counting the leading zeros is used to normalize range.
+    clz     r6, r4
+    sub     r6, r6, #24                 ; shift
+
+    ; Flag is set on the sum of count.  This flag is used later
+    ; to determine if count >= 0
+    adds    r3, r3, r6                  ; count += shift
+    lsl     r5, r4, r6                  ; range <<= shift
+    bmi     token_count_lt_zero_se      ; if(count >= 0)
+
+    sub     r6, r6, r3                  ; offset = shift - count
+    sub     r4, r6, #1                  ; offset-1
+    lsls    r4, r2, r4                  ; if((lowvalue<<(offset-1)) & 0x80000000 )
+    bpl     token_high_bit_not_set_se
+
+    ldr     r4, [r0, #vp8_writer_pos]   ; x
+    sub     r4, r4, #1                  ; x = w->pos-1
+    b       token_zero_while_start_se
+token_zero_while_loop_se
+    mov     r10, #0
+    strb    r10, [r7, r4]               ; w->buffer[x] =(unsigned char)0
+    sub     r4, r4, #1                  ; x--
+token_zero_while_start_se
+    cmp     r4, #0
+    ldrge   r7, [r0, #vp8_writer_buffer]
+    ldrb    r11, [r7, r4]
+    cmpge   r11, #0xff
+    beq     token_zero_while_loop_se
+
+    ldr     r7, [r0, #vp8_writer_buffer]
+    ldrb    r10, [r7, r4]               ; w->buffer[x]
+    add     r10, r10, #1
+    strb    r10, [r7, r4]               ; w->buffer[x] + 1
+token_high_bit_not_set_se
+    rsb     r4, r6, #24                 ; 24-offset
+    ldr     r10, [r0, #vp8_writer_buffer]
+    lsr     r7, r2, r4                  ; lowvalue >> (24-offset)
+    ldr     r4, [r0, #vp8_writer_pos]   ; w->pos
+    lsl     r2, r2, r6                  ; lowvalue <<= offset
+    mov     r6, r3                      ; shift = count
+    add     r11, r4, #1                 ; w->pos++
+    bic     r2, r2, #0xff000000         ; lowvalue &= 0xffffff
+    str     r11, [r0, #vp8_writer_pos]
+    sub     r3, r3, #8                  ; count -= 8
+    strb    r7, [r10, r4]               ; w->buffer[w->pos++]
+
+token_count_lt_zero_se
+    lsl     r2, r2, r6                  ; lowvalue <<= shift
+
+    subs    r12, r12, #1
+    bne     stop_encode_loop
+
+    ldr     r10, [sp, #8]               ; *size
+    ldr     r11, [r10]
+    ldr     r4,  [r0, #vp8_writer_pos]  ; w->pos
+    add     r11, r11, r4                ; *size += w->pos
+    str     r11, [r10]
+
+    ldr     r9, [sp, #20]               ; num_parts
+    sub     r9, r9, #1
+    ldr     r10, [sp, #28]              ; i
+    cmp     r10, r9                     ; if(i<(num_part - 1))
+    bge     skip_write_partition
+
+    ldr     r12, [sp, #40]              ; ptr
+    add     r12, r12, r4                ; ptr += w->pos
+    str     r12, [sp, #40]
+
+    ldr     r9, [sp, #24]               ; cx_data
+    mov     r8, r4, asr #8
+    strb    r4, [r9, #0]
+    strb    r8, [r9, #1]
+    mov     r4, r4, asr #16
+    strb    r4, [r9, #2]
+
+    add     r9, r9, #3                  ; cx_data += 3
+    str     r9, [sp, #24]
+
+skip_write_partition
+
+    ldr     r11, [sp, #28]              ; i
+    ldr     r10, [sp, #20]              ; num_parts
+
+    add     r11, r11, #1                ; i++
+    str     r11, [sp, #28]
+
+    ldr     r7, [sp, #32]               ; cpi->tp_list[i]
+    mov     r1, #TOKENLIST_SZ
+    add     r7, r7, r1                  ; next element in cpi->tp_list
+    str     r7, [sp, #32]               ; cpi->tp_list[i+1]
+
+    cmp     r10, r11
+    bgt     numparts_loop
+
+
+    add     sp, sp, #44
+    pop     {r4-r11, pc}
+    ENDP
+
+_VP8_COMP_common_
+    DCD     vp8_comp_common
+_VP8_COMMON_MBrows_
+    DCD     vp8_common_mb_rows
+_VP8_COMP_tplist_
+    DCD     vp8_comp_tplist
+_VP8_COMP_bc2_
+    DCD     vp8_comp_bc2
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm b/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.asm
new file mode 100644 (file)
index 0000000..5269c0a
--- /dev/null
@@ -0,0 +1,75 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_short_walsh4x4_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
+
+|vp8_short_walsh4x4_neon| PROC
+    vld1.16         {d2}, [r0], r2              ;load input
+    vld1.16         {d3}, [r0], r2
+    vld1.16         {d4}, [r0], r2
+    vld1.16         {d5}, [r0], r2
+
+    ;First for-loop
+    ;transpose d2, d3, d4, d5. Then, d2=ip[0], d3=ip[1], d4=ip[2], d5=ip[3]
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vadd.s16        d6, d2, d5              ;a1 = ip[0]+ip[3]
+    vadd.s16        d7, d3, d4              ;b1 = ip[1]+ip[2]
+    vsub.s16        d8, d3, d4              ;c1 = ip[1]-ip[2]
+    vsub.s16        d9, d2, d5              ;d1 = ip[0]-ip[3]
+
+    vadd.s16        d2, d6, d7             ;op[0] = a1 + b1
+    vsub.s16        d4, d6, d7             ;op[2] = a1 - b1
+    vadd.s16        d3, d8, d9             ;op[1] = c1 + d1
+    vsub.s16        d5, d9, d8             ;op[3] = d1 - c1
+
+    ;Second for-loop
+    ;transpose d2, d3, d4, d5. Then, d2=ip[0], d3=ip[4], d4=ip[8], d5=ip[12]
+    vtrn.32         d2, d4
+    vtrn.32         d3, d5
+    vtrn.16         d2, d3
+    vtrn.16         d4, d5
+
+    vadd.s16        d6, d2, d5              ;a1 = ip[0]+ip[12]
+    vadd.s16        d7, d3, d4              ;b1 = ip[4]+ip[8]
+    vsub.s16        d8, d3, d4              ;c1 = ip[4]-ip[8]
+    vsub.s16        d9, d2, d5              ;d1 = ip[0]-ip[12]
+
+    vadd.s16        d2, d6, d7              ;a2 = a1 + b1;
+    vsub.s16        d4, d6, d7              ;c2 = a1 - b1;
+    vadd.s16        d3, d8, d9              ;b2 = c1 + d1;
+    vsub.s16        d5, d9, d8              ;d2 = d1 - c1;
+
+    vcgt.s16        q3, q1, #0
+    vcgt.s16        q4, q2, #0
+
+    vsub.s16        q1, q1, q3
+    vsub.s16        q2, q2, q4
+
+    vshr.s16        q1, q1, #1
+    vshr.s16        q2, q2, #1
+
+    vst1.16         {q1, q2}, [r1]
+
+    bx              lr
+
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_subpixelvariance16x16_neon.asm b/vp8/encoder/arm/neon/vp8_subpixelvariance16x16_neon.asm
new file mode 100644 (file)
index 0000000..aec716e
--- /dev/null
@@ -0,0 +1,427 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sub_pixel_variance16x16_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; stack(r4) unsigned char *dst_ptr,
+; stack(r5) int dst_pixels_per_line,
+; stack(r6) unsigned int *sse
+;note: most of the code is copied from bilinear_predict16x16_neon and vp8_variance16x16_neon.
+
+|vp8_sub_pixel_variance16x16_neon| PROC
+    push            {r4-r6, lr}
+
+    ldr             r12, _BilinearTaps_coeff_
+    ldr             r4, [sp, #16]           ;load *dst_ptr from stack
+    ldr             r5, [sp, #20]           ;load dst_pixels_per_line from stack
+    ldr             r6, [sp, #24]           ;load *sse from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_bfilter16x16_only
+
+    add             r2, r12, r2, lsl #3     ;calculate filter location
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+
+    vld1.s32        {d31}, [r2]             ;load first_pass filter
+
+    beq             firstpass_bfilter16x16_only
+
+    sub             sp, sp, #272            ;reserve space on stack for temporary storage
+    vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
+    mov             lr, sp
+    vld1.u8         {d5, d6, d7}, [r0], r1
+
+    mov             r2, #3                  ;loop counter
+    vld1.u8         {d8, d9, d10}, [r0], r1
+
+    vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
+    vld1.u8         {d11, d12, d13}, [r0], r1
+
+    vdup.8          d1, d31[4]
+
+;First Pass: output_height lines x output_width columns (17x16)
+vp8e_filt_blk2d_fp16x16_loop_neon
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d2, d0              ;(src_ptr[0] * Filter[0])
+    vmull.u8        q8, d3, d0
+    vmull.u8        q9, d5, d0
+    vmull.u8        q10, d6, d0
+    vmull.u8        q11, d8, d0
+    vmull.u8        q12, d9, d0
+    vmull.u8        q13, d11, d0
+    vmull.u8        q14, d12, d0
+
+    vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
+    vext.8          d5, d5, d6, #1
+    vext.8          d8, d8, d9, #1
+    vext.8          d11, d11, d12, #1
+
+    vmlal.u8        q7, d2, d1              ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q9, d5, d1
+    vmlal.u8        q11, d8, d1
+    vmlal.u8        q13, d11, d1
+
+    vext.8          d3, d3, d4, #1
+    vext.8          d6, d6, d7, #1
+    vext.8          d9, d9, d10, #1
+    vext.8          d12, d12, d13, #1
+
+    vmlal.u8        q8, d3, d1              ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q10, d6, d1
+    vmlal.u8        q12, d9, d1
+    vmlal.u8        q14, d12, d1
+
+    subs            r2, r2, #1
+
+    vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d15, q8, #7
+    vqrshrn.u16    d16, q9, #7
+    vqrshrn.u16    d17, q10, #7
+    vqrshrn.u16    d18, q11, #7
+    vqrshrn.u16    d19, q12, #7
+    vqrshrn.u16    d20, q13, #7
+
+    vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
+    vqrshrn.u16    d21, q14, #7
+    vld1.u8         {d5, d6, d7}, [r0], r1
+
+    vst1.u8         {d14, d15, d16, d17}, [lr]!     ;store result
+    vld1.u8         {d8, d9, d10}, [r0], r1
+    vst1.u8         {d18, d19, d20, d21}, [lr]!
+    vld1.u8         {d11, d12, d13}, [r0], r1
+
+    bne             vp8e_filt_blk2d_fp16x16_loop_neon
+
+;First-pass filtering for rest 5 lines
+    vld1.u8         {d14, d15, d16}, [r0], r1
+
+    vmull.u8        q9, d2, d0              ;(src_ptr[0] * Filter[0])
+    vmull.u8        q10, d3, d0
+    vmull.u8        q11, d5, d0
+    vmull.u8        q12, d6, d0
+    vmull.u8        q13, d8, d0
+    vmull.u8        q14, d9, d0
+
+    vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
+    vext.8          d5, d5, d6, #1
+    vext.8          d8, d8, d9, #1
+
+    vmlal.u8        q9, d2, d1              ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q11, d5, d1
+    vmlal.u8        q13, d8, d1
+
+    vext.8          d3, d3, d4, #1
+    vext.8          d6, d6, d7, #1
+    vext.8          d9, d9, d10, #1
+
+    vmlal.u8        q10, d3, d1             ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q12, d6, d1
+    vmlal.u8        q14, d9, d1
+
+    vmull.u8        q1, d11, d0
+    vmull.u8        q2, d12, d0
+    vmull.u8        q3, d14, d0
+    vmull.u8        q4, d15, d0
+
+    vext.8          d11, d11, d12, #1       ;construct src_ptr[1]
+    vext.8          d14, d14, d15, #1
+
+    vmlal.u8        q1, d11, d1             ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q3, d14, d1
+
+    vext.8          d12, d12, d13, #1
+    vext.8          d15, d15, d16, #1
+
+    vmlal.u8        q2, d12, d1             ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q4, d15, d1
+
+    vqrshrn.u16    d10, q9, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d11, q10, #7
+    vqrshrn.u16    d12, q11, #7
+    vqrshrn.u16    d13, q12, #7
+    vqrshrn.u16    d14, q13, #7
+    vqrshrn.u16    d15, q14, #7
+    vqrshrn.u16    d16, q1, #7
+    vqrshrn.u16    d17, q2, #7
+    vqrshrn.u16    d18, q3, #7
+    vqrshrn.u16    d19, q4, #7
+
+    vst1.u8         {d10, d11, d12, d13}, [lr]!         ;store result
+    vst1.u8         {d14, d15, d16, d17}, [lr]!
+    vst1.u8         {d18, d19}, [lr]!
+
+;Second pass: 16x16
+;secondpass_filter
+    add             r3, r12, r3, lsl #3
+    sub             lr, lr, #272
+
+    vld1.u32        {d31}, [r3]             ;load second_pass filter
+
+    sub             sp, sp, #256
+    mov             r3, sp
+
+    vld1.u8         {d22, d23}, [lr]!       ;load src data
+
+    vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+    mov             r12, #4                 ;loop counter
+
+vp8e_filt_blk2d_sp16x16_loop_neon
+    vld1.u8         {d24, d25}, [lr]!
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * Filter[0])
+    vld1.u8         {d26, d27}, [lr]!
+    vmull.u8        q2, d23, d0
+    vld1.u8         {d28, d29}, [lr]!
+    vmull.u8        q3, d24, d0
+    vld1.u8         {d30, d31}, [lr]!
+
+    vmull.u8        q4, d25, d0
+    vmull.u8        q5, d26, d0
+    vmull.u8        q6, d27, d0
+    vmull.u8        q7, d28, d0
+    vmull.u8        q8, d29, d0
+
+    vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * Filter[1])
+    vmlal.u8        q2, d25, d1
+    vmlal.u8        q3, d26, d1
+    vmlal.u8        q4, d27, d1
+    vmlal.u8        q5, d28, d1
+    vmlal.u8        q6, d29, d1
+    vmlal.u8        q7, d30, d1
+    vmlal.u8        q8, d31, d1
+
+    subs            r12, r12, #1
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+    vqrshrn.u16    d4, q3, #7
+    vqrshrn.u16    d5, q4, #7
+    vqrshrn.u16    d6, q5, #7
+    vqrshrn.u16    d7, q6, #7
+    vqrshrn.u16    d8, q7, #7
+    vqrshrn.u16    d9, q8, #7
+
+    vst1.u8         {d2, d3}, [r3]!         ;store result
+    vst1.u8         {d4, d5}, [r3]!
+    vst1.u8         {d6, d7}, [r3]!
+    vmov            q11, q15
+    vst1.u8         {d8, d9}, [r3]!
+
+    bne             vp8e_filt_blk2d_sp16x16_loop_neon
+
+    b               sub_pixel_variance16x16_neon
+
+;--------------------
+firstpass_bfilter16x16_only
+    mov             r2, #4                      ;loop counter
+    sub             sp, sp, #528            ;reserve space on stack for temporary storage
+    vdup.8          d0, d31[0]                  ;first_pass filter (d0 d1)
+    vdup.8          d1, d31[4]
+    mov             r3, sp
+
+;First Pass: output_height lines x output_width columns (16x16)
+vp8e_filt_blk2d_fpo16x16_loop_neon
+    vld1.u8         {d2, d3, d4}, [r0], r1      ;load src data
+    vld1.u8         {d5, d6, d7}, [r0], r1
+    vld1.u8         {d8, d9, d10}, [r0], r1
+    vld1.u8         {d11, d12, d13}, [r0], r1
+
+    pld             [r0]
+    pld             [r0, r1]
+    pld             [r0, r1, lsl #1]
+
+    vmull.u8        q7, d2, d0              ;(src_ptr[0] * Filter[0])
+    vmull.u8        q8, d3, d0
+    vmull.u8        q9, d5, d0
+    vmull.u8        q10, d6, d0
+    vmull.u8        q11, d8, d0
+    vmull.u8        q12, d9, d0
+    vmull.u8        q13, d11, d0
+    vmull.u8        q14, d12, d0
+
+    vext.8          d2, d2, d3, #1          ;construct src_ptr[1]
+    vext.8          d5, d5, d6, #1
+    vext.8          d8, d8, d9, #1
+    vext.8          d11, d11, d12, #1
+
+    vmlal.u8        q7, d2, d1              ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q9, d5, d1
+    vmlal.u8        q11, d8, d1
+    vmlal.u8        q13, d11, d1
+
+    vext.8          d3, d3, d4, #1
+    vext.8          d6, d6, d7, #1
+    vext.8          d9, d9, d10, #1
+    vext.8          d12, d12, d13, #1
+
+    vmlal.u8        q8, d3, d1              ;(src_ptr[0] * Filter[1])
+    vmlal.u8        q10, d6, d1
+    vmlal.u8        q12, d9, d1
+    vmlal.u8        q14, d12, d1
+
+    subs            r2, r2, #1
+
+    vqrshrn.u16    d14, q7, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d15, q8, #7
+    vqrshrn.u16    d16, q9, #7
+    vqrshrn.u16    d17, q10, #7
+    vqrshrn.u16    d18, q11, #7
+    vqrshrn.u16    d19, q12, #7
+    vqrshrn.u16    d20, q13, #7
+    vst1.u8         {d14, d15}, [r3]!       ;store result
+    vqrshrn.u16    d21, q14, #7
+
+    vst1.u8         {d16, d17}, [r3]!
+    vst1.u8         {d18, d19}, [r3]!
+    vst1.u8         {d20, d21}, [r3]!
+
+    bne             vp8e_filt_blk2d_fpo16x16_loop_neon
+
+    b               sub_pixel_variance16x16_neon
+
+;---------------------
+secondpass_bfilter16x16_only
+;Second pass: 16x16
+;secondpass_filter
+    sub             sp, sp, #528            ;reserve space on stack for temporary storage
+    add             r3, r12, r3, lsl #3
+    mov             r12, #4                     ;loop counter
+    vld1.u32        {d31}, [r3]                 ;load second_pass filter
+    vld1.u8         {d22, d23}, [r0], r1        ;load src data
+    mov             r3, sp
+
+    vdup.8          d0, d31[0]                  ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+
+vp8e_filt_blk2d_spo16x16_loop_neon
+    vld1.u8         {d24, d25}, [r0], r1
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * Filter[0])
+    vld1.u8         {d26, d27}, [r0], r1
+    vmull.u8        q2, d23, d0
+    vld1.u8         {d28, d29}, [r0], r1
+    vmull.u8        q3, d24, d0
+    vld1.u8         {d30, d31}, [r0], r1
+
+    vmull.u8        q4, d25, d0
+    vmull.u8        q5, d26, d0
+    vmull.u8        q6, d27, d0
+    vmull.u8        q7, d28, d0
+    vmull.u8        q8, d29, d0
+
+    vmlal.u8        q1, d24, d1             ;(src_ptr[pixel_step] * Filter[1])
+    vmlal.u8        q2, d25, d1
+    vmlal.u8        q3, d26, d1
+    vmlal.u8        q4, d27, d1
+    vmlal.u8        q5, d28, d1
+    vmlal.u8        q6, d29, d1
+    vmlal.u8        q7, d30, d1
+    vmlal.u8        q8, d31, d1
+
+    vqrshrn.u16    d2, q1, #7               ;shift/round/saturate to u8
+    vqrshrn.u16    d3, q2, #7
+    vqrshrn.u16    d4, q3, #7
+    vqrshrn.u16    d5, q4, #7
+    vqrshrn.u16    d6, q5, #7
+    vqrshrn.u16    d7, q6, #7
+    vqrshrn.u16    d8, q7, #7
+    vqrshrn.u16    d9, q8, #7
+
+    vst1.u8         {d2, d3}, [r3]!         ;store result
+    subs            r12, r12, #1
+    vst1.u8         {d4, d5}, [r3]!
+    vmov            q11, q15
+    vst1.u8         {d6, d7}, [r3]!
+    vst1.u8         {d8, d9}, [r3]!
+
+    bne             vp8e_filt_blk2d_spo16x16_loop_neon
+
+    b               sub_pixel_variance16x16_neon
+
+;----------------------------
+;variance16x16
+sub_pixel_variance16x16_neon
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    sub             r3, r3, #256
+    mov             r12, #8
+
+sub_pixel_variance16x16_neon_loop
+    vld1.8          {q0}, [r3]!                 ;Load up source and reference
+    vld1.8          {q2}, [r4], r5
+    vld1.8          {q1}, [r3]!
+    vld1.8          {q3}, [r4], r5
+
+    vsubl.u8        q11, d0, d4                 ;diff
+    vsubl.u8        q12, d1, d5
+    vsubl.u8        q13, d2, d6
+    vsubl.u8        q14, d3, d7
+
+    vpadal.s16      q8, q11                     ;sum
+    vmlal.s16       q9, d22, d22                ;sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    bne             sub_pixel_variance16x16_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [r6]               ;store sse
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    add             sp, sp, #528
+    vmov.32         r0, d0[0]                   ;return
+
+    pop             {r4-r6,pc}
+
+    ENDP
+
+;-----------------
+    AREA    vp8e_bilinear_taps_dat, DATA, READWRITE          ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_BilinearTaps_coeff_
+    DCD     bilinear_taps_coeff
+bilinear_taps_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_subpixelvariance16x16s_neon.asm b/vp8/encoder/arm/neon/vp8_subpixelvariance16x16s_neon.asm
new file mode 100644 (file)
index 0000000..3d02d7c
--- /dev/null
@@ -0,0 +1,571 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sub_pixel_variance16x16s_4_0_neon|
+    EXPORT  |vp8_sub_pixel_variance16x16s_0_4_neon|
+    EXPORT  |vp8_sub_pixel_variance16x16s_4_4_neon|
+    EXPORT  |vp8_sub_pixel_variance16x16s_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+;================================================
+;unsigned int vp8_sub_pixel_variance16x16s_4_0_neon
+;(
+;    unsigned char  *src_ptr, r0
+;    int  src_pixels_per_line,  r1
+;    unsigned char *dst_ptr,  r2
+;    int dst_pixels_per_line,   r3
+;    unsigned int *sse
+;);
+;================================================
+|vp8_sub_pixel_variance16x16s_4_0_neon| PROC
+    push            {lr}
+
+    mov             r12, #4                  ;loop counter
+    ldr             lr, [sp, #4]           ;load *sse from stack
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+;First Pass: output_height lines x output_width columns (16x16)
+vp8_filt_fpo16x16s_4_0_loop_neon
+    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
+    vld1.8          {q11}, [r2], r3
+    vld1.u8         {d4, d5, d6, d7}, [r0], r1
+    vld1.8          {q12}, [r2], r3
+    vld1.u8         {d8, d9, d10, d11}, [r0], r1
+    vld1.8          {q13}, [r2], r3
+    vld1.u8         {d12, d13, d14, d15}, [r0], r1
+
+    ;pld                [r0]
+    ;pld                [r0, r1]
+    ;pld                [r0, r1, lsl #1]
+
+    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
+    vext.8          q3, q2, q3, #1
+    vext.8          q5, q4, q5, #1
+    vext.8          q7, q6, q7, #1
+
+    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
+    vld1.8          {q14}, [r2], r3
+    vrhadd.u8       q1, q2, q3
+    vrhadd.u8       q2, q4, q5
+    vrhadd.u8       q3, q6, q7
+
+    vsubl.u8        q4, d0, d22                 ;diff
+    vsubl.u8        q5, d1, d23
+    vsubl.u8        q6, d2, d24
+    vsubl.u8        q7, d3, d25
+    vsubl.u8        q0, d4, d26
+    vsubl.u8        q1, d5, d27
+    vsubl.u8        q2, d6, d28
+    vsubl.u8        q3, d7, d29
+
+    vpadal.s16      q8, q4                     ;sum
+    vmlal.s16       q9, d8, d8                ;sse
+    vmlal.s16       q10, d9, d9
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q5
+    vmlal.s16       q9, d10, d10
+    vmlal.s16       q10, d11, d11
+    vpadal.s16      q8, q6
+    vmlal.s16       q9, d12, d12
+    vmlal.s16       q10, d13, d13
+    vpadal.s16      q8, q7
+    vmlal.s16       q9, d14, d14
+    vmlal.s16       q10, d15, d15
+
+    vpadal.s16      q8, q0                     ;sum
+    vmlal.s16       q9, d0, d0                ;sse
+    vmlal.s16       q10, d1, d1
+    vpadal.s16      q8, q1
+    vmlal.s16       q9, d2, d2
+    vmlal.s16       q10, d3, d3
+    vpadal.s16      q8, q2
+    vmlal.s16       q9, d4, d4
+    vmlal.s16       q10, d5, d5
+    vpadal.s16      q8, q3
+    vmlal.s16       q9, d6, d6
+    vmlal.s16       q10, d7, d7
+
+    bne             vp8_filt_fpo16x16s_4_0_loop_neon
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [lr]               ;store sse
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    pop             {pc}
+    ENDP
+
+;================================================
+;unsigned int vp8_sub_pixel_variance16x16s_0_4_neon
+;(
+;    unsigned char  *src_ptr, r0
+;    int  src_pixels_per_line,  r1
+;    unsigned char *dst_ptr,  r2
+;    int dst_pixels_per_line,   r3
+;    unsigned int *sse
+;);
+;================================================
+|vp8_sub_pixel_variance16x16s_0_4_neon| PROC
+    push            {lr}
+
+    mov             r12, #4                     ;loop counter
+
+    vld1.u8         {q0}, [r0], r1              ;load src data
+    ldr             lr, [sp, #4]                ;load *sse from stack
+
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+vp8_filt_spo16x16s_0_4_loop_neon
+    vld1.u8         {q2}, [r0], r1
+    vld1.8          {q1}, [r2], r3
+    vld1.u8         {q4}, [r0], r1
+    vld1.8          {q3}, [r2], r3
+    vld1.u8         {q6}, [r0], r1
+    vld1.8          {q5}, [r2], r3
+    vld1.u8         {q15}, [r0], r1
+
+    vrhadd.u8       q0, q0, q2
+    vld1.8          {q7}, [r2], r3
+    vrhadd.u8       q2, q2, q4
+    vrhadd.u8       q4, q4, q6
+    vrhadd.u8       q6, q6, q15
+
+    vsubl.u8        q11, d0, d2                 ;diff
+    vsubl.u8        q12, d1, d3
+    vsubl.u8        q13, d4, d6
+    vsubl.u8        q14, d5, d7
+    vsubl.u8        q0, d8, d10
+    vsubl.u8        q1, d9, d11
+    vsubl.u8        q2, d12, d14
+    vsubl.u8        q3, d13, d15
+
+    vpadal.s16      q8, q11                     ;sum
+    vmlal.s16       q9, d22, d22                ;sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    vpadal.s16      q8, q0                     ;sum
+    vmlal.s16       q9, d0, d0                 ;sse
+    vmlal.s16       q10, d1, d1
+    vpadal.s16      q8, q1
+    vmlal.s16       q9, d2, d2
+    vmlal.s16       q10, d3, d3
+    vpadal.s16      q8, q2
+    vmlal.s16       q9, d4, d4
+    vmlal.s16       q10, d5, d5
+
+    vmov            q0, q15
+
+    vpadal.s16      q8, q3
+    vmlal.s16       q9, d6, d6
+    vmlal.s16       q10, d7, d7
+
+    bne             vp8_filt_spo16x16s_0_4_loop_neon
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [lr]               ;store sse
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    pop             {pc}
+    ENDP
+
+;================================================
+;unsigned int vp8_sub_pixel_variance16x16s_4_4_neon
+;(
+;    unsigned char  *src_ptr, r0
+;    int  src_pixels_per_line,  r1
+;    unsigned char *dst_ptr,  r2
+;    int dst_pixels_per_line,   r3
+;    unsigned int *sse
+;);
+;================================================
+|vp8_sub_pixel_variance16x16s_4_4_neon| PROC
+    push            {lr}
+
+    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
+
+    ldr             lr, [sp, #4]           ;load *sse from stack
+    vmov.i8         q13, #0                      ;q8 - sum
+    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
+
+    vmov.i8         q14, #0                      ;q9, q10 - sse
+    vmov.i8         q15, #0
+
+    mov             r12, #4                  ;loop counter
+    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
+
+;First Pass: output_height lines x output_width columns (17x16)
+vp8_filt16x16s_4_4_loop_neon
+    vld1.u8         {d4, d5, d6, d7}, [r0], r1
+    vld1.u8         {d8, d9, d10, d11}, [r0], r1
+    vld1.u8         {d12, d13, d14, d15}, [r0], r1
+    vld1.u8         {d16, d17, d18, d19}, [r0], r1
+
+    ;pld                [r0]
+    ;pld                [r0, r1]
+    ;pld                [r0, r1, lsl #1]
+
+    vext.8          q3, q2, q3, #1          ;construct src_ptr[1]
+    vext.8          q5, q4, q5, #1
+    vext.8          q7, q6, q7, #1
+    vext.8          q9, q8, q9, #1
+
+    vrhadd.u8       q1, q2, q3              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
+    vrhadd.u8       q2, q4, q5
+    vrhadd.u8       q3, q6, q7
+    vrhadd.u8       q4, q8, q9
+
+    vld1.8          {q5}, [r2], r3
+    vrhadd.u8       q0, q0, q1
+    vld1.8          {q6}, [r2], r3
+    vrhadd.u8       q1, q1, q2
+    vld1.8          {q7}, [r2], r3
+    vrhadd.u8       q2, q2, q3
+    vld1.8          {q8}, [r2], r3
+    vrhadd.u8       q3, q3, q4
+
+    vsubl.u8        q9, d0, d10                 ;diff
+    vsubl.u8        q10, d1, d11
+    vsubl.u8        q11, d2, d12
+    vsubl.u8        q12, d3, d13
+
+    vsubl.u8        q0, d4, d14                 ;diff
+    vsubl.u8        q1, d5, d15
+    vsubl.u8        q5, d6, d16
+    vsubl.u8        q6, d7, d17
+
+    vpadal.s16      q13, q9                     ;sum
+    vmlal.s16       q14, d18, d18                ;sse
+    vmlal.s16       q15, d19, d19
+
+    vpadal.s16      q13, q10                     ;sum
+    vmlal.s16       q14, d20, d20                ;sse
+    vmlal.s16       q15, d21, d21
+
+    vpadal.s16      q13, q11                     ;sum
+    vmlal.s16       q14, d22, d22                ;sse
+    vmlal.s16       q15, d23, d23
+
+    vpadal.s16      q13, q12                     ;sum
+    vmlal.s16       q14, d24, d24                ;sse
+    vmlal.s16       q15, d25, d25
+
+    subs            r12, r12, #1
+
+    vpadal.s16      q13, q0                     ;sum
+    vmlal.s16       q14, d0, d0                ;sse
+    vmlal.s16       q15, d1, d1
+
+    vpadal.s16      q13, q1                     ;sum
+    vmlal.s16       q14, d2, d2                ;sse
+    vmlal.s16       q15, d3, d3
+
+    vpadal.s16      q13, q5                     ;sum
+    vmlal.s16       q14, d10, d10                ;sse
+    vmlal.s16       q15, d11, d11
+
+    vmov            q0, q4
+
+    vpadal.s16      q13, q6                     ;sum
+    vmlal.s16       q14, d12, d12                ;sse
+    vmlal.s16       q15, d13, d13
+
+    bne             vp8_filt16x16s_4_4_loop_neon
+
+    vadd.u32        q15, q14, q15                ;accumulate sse
+    vpaddl.s32      q0, q13                      ;accumulate sum
+
+    vpaddl.u32      q1, q15
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [lr]               ;store sse
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    pop             {pc}
+    ENDP
+
+;==============================
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; stack unsigned char *dst_ptr,
+; stack int dst_pixels_per_line,
+; stack unsigned int *sse
+;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
+;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
+;or filter coeff is {64, 64}. This simplified program only works in this situation.
+;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
+
+|vp8_sub_pixel_variance16x16s_neon| PROC
+    push            {r4, lr}
+
+    ldr             r4, [sp, #8]            ;load *dst_ptr from stack
+    ldr             r12, [sp, #12]          ;load dst_pixels_per_line from stack
+    ldr             lr, [sp, #16]           ;load *sse from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             secondpass_bfilter16x16s_only
+
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+    beq             firstpass_bfilter16x16s_only
+
+    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
+    sub             sp, sp, #256            ;reserve space on stack for temporary storage
+    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
+    mov             r3, sp
+    mov             r2, #4                  ;loop counter
+    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
+
+;First Pass: output_height lines x output_width columns (17x16)
+vp8e_filt_blk2d_fp16x16s_loop_neon
+    vld1.u8         {d4, d5, d6, d7}, [r0], r1
+    vld1.u8         {d8, d9, d10, d11}, [r0], r1
+    vld1.u8         {d12, d13, d14, d15}, [r0], r1
+    vld1.u8         {d16, d17, d18, d19}, [r0], r1
+
+    ;pld                [r0]
+    ;pld                [r0, r1]
+    ;pld                [r0, r1, lsl #1]
+
+    vext.8          q3, q2, q3, #1          ;construct src_ptr[1]
+    vext.8          q5, q4, q5, #1
+    vext.8          q7, q6, q7, #1
+    vext.8          q9, q8, q9, #1
+
+    vrhadd.u8       q1, q2, q3              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
+    vrhadd.u8       q2, q4, q5
+    vrhadd.u8       q3, q6, q7
+    vrhadd.u8       q4, q8, q9
+
+    vrhadd.u8       q0, q0, q1
+    vrhadd.u8       q1, q1, q2
+    vrhadd.u8       q2, q2, q3
+    vrhadd.u8       q3, q3, q4
+
+    subs            r2, r2, #1
+    vst1.u8         {d0, d1 ,d2, d3}, [r3]!         ;store result
+    vmov            q0, q4
+    vst1.u8         {d4, d5, d6, d7}, [r3]!
+
+    bne             vp8e_filt_blk2d_fp16x16s_loop_neon
+
+    b               sub_pixel_variance16x16s_neon
+
+;--------------------
+firstpass_bfilter16x16s_only
+    mov             r2, #2                  ;loop counter
+    sub             sp, sp, #256            ;reserve space on stack for temporary storage
+    mov             r3, sp
+
+;First Pass: output_height lines x output_width columns (16x16)
+vp8e_filt_blk2d_fpo16x16s_loop_neon
+    vld1.u8         {d0, d1, d2, d3}, [r0], r1      ;load src data
+    vld1.u8         {d4, d5, d6, d7}, [r0], r1
+    vld1.u8         {d8, d9, d10, d11}, [r0], r1
+    vld1.u8         {d12, d13, d14, d15}, [r0], r1
+
+    ;pld                [r0]
+    ;pld                [r0, r1]
+    ;pld                [r0, r1, lsl #1]
+
+    vext.8          q1, q0, q1, #1          ;construct src_ptr[1]
+    vld1.u8         {d16, d17, d18, d19}, [r0], r1
+    vext.8          q3, q2, q3, #1
+    vld1.u8         {d20, d21, d22, d23}, [r0], r1
+    vext.8          q5, q4, q5, #1
+    vld1.u8         {d24, d25, d26, d27}, [r0], r1
+    vext.8          q7, q6, q7, #1
+    vld1.u8         {d28, d29, d30, d31}, [r0], r1
+    vext.8          q9, q8, q9, #1
+    vext.8          q11, q10, q11, #1
+    vext.8          q13, q12, q13, #1
+    vext.8          q15, q14, q15, #1
+
+    vrhadd.u8       q0, q0, q1              ;(src_ptr[0]+src_ptr[1])/round/shift right 1
+    vrhadd.u8       q1, q2, q3
+    vrhadd.u8       q2, q4, q5
+    vrhadd.u8       q3, q6, q7
+    vrhadd.u8       q4, q8, q9
+    vrhadd.u8       q5, q10, q11
+    vrhadd.u8       q6, q12, q13
+    vrhadd.u8       q7, q14, q15
+
+    subs            r2, r2, #1
+
+    vst1.u8         {d0, d1, d2, d3}, [r3]!         ;store result
+    vst1.u8         {d4, d5, d6, d7}, [r3]!
+    vst1.u8         {d8, d9, d10, d11}, [r3]!
+    vst1.u8         {d12, d13, d14, d15}, [r3]!
+
+    bne             vp8e_filt_blk2d_fpo16x16s_loop_neon
+
+    b               sub_pixel_variance16x16s_neon
+
+;---------------------
+secondpass_bfilter16x16s_only
+    sub             sp, sp, #256            ;reserve space on stack for temporary storage
+
+    mov             r2, #2                  ;loop counter
+    vld1.u8         {d0, d1}, [r0], r1      ;load src data
+    mov             r3, sp
+
+vp8e_filt_blk2d_spo16x16s_loop_neon
+    vld1.u8         {d2, d3}, [r0], r1
+    vld1.u8         {d4, d5}, [r0], r1
+    vld1.u8         {d6, d7}, [r0], r1
+    vld1.u8         {d8, d9}, [r0], r1
+
+    vrhadd.u8       q0, q0, q1
+    vld1.u8         {d10, d11}, [r0], r1
+    vrhadd.u8       q1, q1, q2
+    vld1.u8         {d12, d13}, [r0], r1
+    vrhadd.u8       q2, q2, q3
+    vld1.u8         {d14, d15}, [r0], r1
+    vrhadd.u8       q3, q3, q4
+    vld1.u8         {d16, d17}, [r0], r1
+    vrhadd.u8       q4, q4, q5
+    vrhadd.u8       q5, q5, q6
+    vrhadd.u8       q6, q6, q7
+    vrhadd.u8       q7, q7, q8
+
+    subs            r2, r2, #1
+
+    vst1.u8         {d0, d1, d2, d3}, [r3]!         ;store result
+    vmov            q0, q8
+    vst1.u8         {d4, d5, d6, d7}, [r3]!
+    vst1.u8         {d8, d9, d10, d11}, [r3]!           ;store result
+    vst1.u8         {d12, d13, d14, d15}, [r3]!
+
+    bne             vp8e_filt_blk2d_spo16x16s_loop_neon
+
+    b               sub_pixel_variance16x16s_neon
+
+;----------------------------
+;variance16x16
+sub_pixel_variance16x16s_neon
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    sub             r3, r3, #256
+    mov             r2, #4
+
+sub_pixel_variance16x16s_neon_loop
+    vld1.8          {q0}, [r3]!                 ;Load up source and reference
+    vld1.8          {q1}, [r4], r12
+    vld1.8          {q2}, [r3]!
+    vld1.8          {q3}, [r4], r12
+    vld1.8          {q4}, [r3]!
+    vld1.8          {q5}, [r4], r12
+    vld1.8          {q6}, [r3]!
+    vld1.8          {q7}, [r4], r12
+
+    vsubl.u8        q11, d0, d2                 ;diff
+    vsubl.u8        q12, d1, d3
+    vsubl.u8        q13, d4, d6
+    vsubl.u8        q14, d5, d7
+    vsubl.u8        q0, d8, d10
+    vsubl.u8        q1, d9, d11
+    vsubl.u8        q2, d12, d14
+    vsubl.u8        q3, d13, d15
+
+    vpadal.s16      q8, q11                     ;sum
+    vmlal.s16       q9, d22, d22                ;sse
+    vmlal.s16       q10, d23, d23
+
+    subs            r2, r2, #1
+
+    vpadal.s16      q8, q12
+    vmlal.s16       q9, d24, d24
+    vmlal.s16       q10, d25, d25
+    vpadal.s16      q8, q13
+    vmlal.s16       q9, d26, d26
+    vmlal.s16       q10, d27, d27
+    vpadal.s16      q8, q14
+    vmlal.s16       q9, d28, d28
+    vmlal.s16       q10, d29, d29
+
+    vpadal.s16      q8, q0                     ;sum
+    vmlal.s16       q9, d0, d0                ;sse
+    vmlal.s16       q10, d1, d1
+    vpadal.s16      q8, q1
+    vmlal.s16       q9, d2, d2
+    vmlal.s16       q10, d3, d3
+    vpadal.s16      q8, q2
+    vmlal.s16       q9, d4, d4
+    vmlal.s16       q10, d5, d5
+    vpadal.s16      q8, q3
+    vmlal.s16       q9, d6, d6
+    vmlal.s16       q10, d7, d7
+
+    bne             sub_pixel_variance16x16s_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [lr]               ;store sse
+    vshr.s32        d10, d10, #8
+    vsub.s32        d0, d1, d10
+
+    add             sp, sp, #256
+    vmov.32         r0, d0[0]                   ;return
+
+    pop             {r4, pc}
+    ENDP
+
+    END
diff --git a/vp8/encoder/arm/neon/vp8_subpixelvariance8x8_neon.asm b/vp8/encoder/arm/neon/vp8_subpixelvariance8x8_neon.asm
new file mode 100644 (file)
index 0000000..bd56761
--- /dev/null
@@ -0,0 +1,226 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_sub_pixel_variance8x8_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+; r0    unsigned char  *src_ptr,
+; r1    int  src_pixels_per_line,
+; r2    int  xoffset,
+; r3    int  yoffset,
+; stack(r4) unsigned char *dst_ptr,
+; stack(r5) int dst_pixels_per_line,
+; stack(r6) unsigned int *sse
+;note: most of the code is copied from bilinear_predict8x8_neon and vp8_variance8x8_neon.
+
+|vp8_sub_pixel_variance8x8_neon| PROC
+    push            {r4-r5, lr}
+
+    ldr             r12, _BilinearTaps_coeff_
+    ldr             r4, [sp, #12]           ;load *dst_ptr from stack
+    ldr             r5, [sp, #16]           ;load dst_pixels_per_line from stack
+    ldr             lr, [sp, #20]           ;load *sse from stack
+
+    cmp             r2, #0                  ;skip first_pass filter if xoffset=0
+    beq             skip_firstpass_filter
+
+;First pass: output_height lines x output_width columns (9x8)
+    add             r2, r12, r2, lsl #3     ;calculate filter location
+
+    vld1.u8         {q1}, [r0], r1          ;load src data
+    vld1.u32        {d31}, [r2]             ;load first_pass filter
+    vld1.u8         {q2}, [r0], r1
+    vdup.8          d0, d31[0]              ;first_pass filter (d0 d1)
+    vld1.u8         {q3}, [r0], r1
+    vdup.8          d1, d31[4]
+    vld1.u8         {q4}, [r0], r1
+
+    vmull.u8        q6, d2, d0              ;(src_ptr[0] * Filter[0])
+    vmull.u8        q7, d4, d0
+    vmull.u8        q8, d6, d0
+    vmull.u8        q9, d8, d0
+
+    vext.8          d3, d2, d3, #1          ;construct src_ptr[-1]
+    vext.8          d5, d4, d5, #1
+    vext.8          d7, d6, d7, #1
+    vext.8          d9, d8, d9, #1
+
+    vmlal.u8        q6, d3, d1              ;(src_ptr[1] * Filter[1])
+    vmlal.u8        q7, d5, d1
+    vmlal.u8        q8, d7, d1
+    vmlal.u8        q9, d9, d1
+
+    vld1.u8         {q1}, [r0], r1          ;load src data
+    vqrshrn.u16    d22, q6, #7              ;shift/round/saturate to u8
+    vld1.u8         {q2}, [r0], r1
+    vqrshrn.u16    d23, q7, #7
+    vld1.u8         {q3}, [r0], r1
+    vqrshrn.u16    d24, q8, #7
+    vld1.u8         {q4}, [r0], r1
+    vqrshrn.u16    d25, q9, #7
+
+    ;first_pass filtering on the rest 5-line data
+    vld1.u8         {q5}, [r0], r1
+
+    vmull.u8        q6, d2, d0              ;(src_ptr[0] * Filter[0])
+    vmull.u8        q7, d4, d0
+    vmull.u8        q8, d6, d0
+    vmull.u8        q9, d8, d0
+    vmull.u8        q10, d10, d0
+
+    vext.8          d3, d2, d3, #1          ;construct src_ptr[-1]
+    vext.8          d5, d4, d5, #1
+    vext.8          d7, d6, d7, #1
+    vext.8          d9, d8, d9, #1
+    vext.8          d11, d10, d11, #1
+
+    vmlal.u8        q6, d3, d1              ;(src_ptr[1] * Filter[1])
+    vmlal.u8        q7, d5, d1
+    vmlal.u8        q8, d7, d1
+    vmlal.u8        q9, d9, d1
+    vmlal.u8        q10, d11, d1
+
+    vqrshrn.u16    d26, q6, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d27, q7, #7
+    vqrshrn.u16    d28, q8, #7
+    vqrshrn.u16    d29, q9, #7
+    vqrshrn.u16    d30, q10, #7
+
+;Second pass: 8x8
+secondpass_filter
+    cmp             r3, #0                  ;skip second_pass filter if yoffset=0
+    ;skip_secondpass_filter
+    beq             sub_pixel_variance8x8_neon
+
+    add             r3, r12, r3, lsl #3
+
+    vld1.u32        {d31}, [r3]             ;load second_pass filter
+
+    vdup.8          d0, d31[0]              ;second_pass filter parameters (d0 d1)
+    vdup.8          d1, d31[4]
+
+    vmull.u8        q1, d22, d0             ;(src_ptr[0] * Filter[0])
+    vmull.u8        q2, d23, d0
+    vmull.u8        q3, d24, d0
+    vmull.u8        q4, d25, d0
+    vmull.u8        q5, d26, d0
+    vmull.u8        q6, d27, d0
+    vmull.u8        q7, d28, d0
+    vmull.u8        q8, d29, d0
+
+    vmlal.u8        q1, d23, d1             ;(src_ptr[pixel_step] * Filter[1])
+    vmlal.u8        q2, d24, d1
+    vmlal.u8        q3, d25, d1
+    vmlal.u8        q4, d26, d1
+    vmlal.u8        q5, d27, d1
+    vmlal.u8        q6, d28, d1
+    vmlal.u8        q7, d29, d1
+    vmlal.u8        q8, d30, d1
+
+    vqrshrn.u16    d22, q1, #7              ;shift/round/saturate to u8
+    vqrshrn.u16    d23, q2, #7
+    vqrshrn.u16    d24, q3, #7
+    vqrshrn.u16    d25, q4, #7
+    vqrshrn.u16    d26, q5, #7
+    vqrshrn.u16    d27, q6, #7
+    vqrshrn.u16    d28, q7, #7
+    vqrshrn.u16    d29, q8, #7
+
+    b               sub_pixel_variance8x8_neon
+
+;--------------------
+skip_firstpass_filter
+    vld1.u8         {d22}, [r0], r1         ;load src data
+    vld1.u8         {d23}, [r0], r1
+    vld1.u8         {d24}, [r0], r1
+    vld1.u8         {d25}, [r0], r1
+    vld1.u8         {d26}, [r0], r1
+    vld1.u8         {d27}, [r0], r1
+    vld1.u8         {d28}, [r0], r1
+    vld1.u8         {d29}, [r0], r1
+    vld1.u8         {d30}, [r0], r1
+
+    b               secondpass_filter
+
+;----------------------
+;vp8_variance8x8_neon
+sub_pixel_variance8x8_neon
+    vmov.i8         q8, #0                      ;q8 - sum
+    vmov.i8         q9, #0                      ;q9, q10 - sse
+    vmov.i8         q10, #0
+
+    mov             r12, #2
+
+sub_pixel_variance8x8_neon_loop
+    vld1.8          {d0}, [r4], r5              ;load dst data
+    subs            r12, r12, #1
+    vld1.8          {d1}, [r4], r5
+    vld1.8          {d2}, [r4], r5
+    vsubl.u8        q4, d22, d0                 ;calculate diff
+    vld1.8          {d3}, [r4], r5
+
+    vsubl.u8        q5, d23, d1
+    vsubl.u8        q6, d24, d2
+
+    vpadal.s16      q8, q4                      ;sum
+    vmlal.s16       q9, d8, d8                  ;sse
+    vmlal.s16       q10, d9, d9
+
+    vsubl.u8        q7, d25, d3
+
+    vpadal.s16      q8, q5
+    vmlal.s16       q9, d10, d10
+    vmlal.s16       q10, d11, d11
+
+    vmov            q11, q13
+
+    vpadal.s16      q8, q6
+    vmlal.s16       q9, d12, d12
+    vmlal.s16       q10, d13, d13
+
+    vmov            q12, q14
+
+    vpadal.s16      q8, q7
+    vmlal.s16       q9, d14, d14
+    vmlal.s16       q10, d15, d15
+
+    bne             sub_pixel_variance8x8_neon_loop
+
+    vadd.u32        q10, q9, q10                ;accumulate sse
+    vpaddl.s32      q0, q8                      ;accumulate sum
+
+    vpaddl.u32      q1, q10
+    vadd.s64        d0, d0, d1
+    vadd.u64        d1, d2, d3
+
+    vmull.s32       q5, d0, d0
+    vst1.32         {d1[0]}, [lr]               ;store sse
+    vshr.s32        d10, d10, #6
+    vsub.s32        d0, d1, d10
+
+    vmov.32         r0, d0[0]                   ;return
+    pop             {r4-r5, pc}
+
+    ENDP
+
+;-----------------
+    AREA    bilinear_taps_dat, DATA, READWRITE           ;read/write by default
+;Data section with name data_area is specified. DCD reserves space in memory for 48 data.
+;One word each is reserved. Label filter_coeff can be used to access the data.
+;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
+_BilinearTaps_coeff_
+    DCD     bilinear_taps_coeff
+bilinear_taps_coeff
+    DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
+
+    END
diff --git a/vp8/encoder/arm/picklpf_arm.c b/vp8/encoder/arm/picklpf_arm.c
new file mode 100644 (file)
index 0000000..0586e55
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxc_int.h"
+#include "onyx_int.h"
+#include "quantize.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/yv12extend.h"
+#include "vpx_scale/vpxscale.h"
+#include "alloccommon.h"
+
+extern void vp8_memcpy_neon(unsigned char *dst_ptr, unsigned char *src_ptr, int sz);
+
+
+void
+vpxyv12_copy_partial_frame_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction)
+{
+    unsigned char *src_y, *dst_y;
+    int yheight;
+    int ystride;
+    int border;
+    int yoffset;
+    int linestocopy;
+
+    border   = src_ybc->border;
+    yheight  = src_ybc->y_height;
+    ystride  = src_ybc->y_stride;
+
+    linestocopy = (yheight >> (Fraction + 4));
+
+    if (linestocopy < 1)
+        linestocopy = 1;
+
+    linestocopy <<= 4;
+
+    yoffset  = ystride * ((yheight >> 5) * 16 - 8);
+    src_y = src_ybc->y_buffer + yoffset;
+    dst_y = dst_ybc->y_buffer + yoffset;
+
+    //vpx_memcpy (dst_y, src_y, ystride * (linestocopy +16));
+    vp8_memcpy_neon((unsigned char *)dst_y, (unsigned char *)src_y, (int)(ystride *(linestocopy + 16)));
+}
diff --git a/vp8/encoder/arm/quantize_arm.c b/vp8/encoder/arm/quantize_arm.c
new file mode 100644 (file)
index 0000000..46906d3
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <math.h>
+#include "vpx_mem/vpx_mem.h"
+
+#include "quantize.h"
+#include "entropy.h"
+#include "predictdc.h"
+
+DECLARE_ALIGNED(16, const short, vp8_rvsplus1_default_zig_zag1d[16]) =
+{
+    1,  2,  6,  7,
+    3,  5,  8,  13,
+    4,  9,  12, 14,
+    10, 11, 15, 16,
+};
+
+
+extern int vp8_fast_quantize_b_neon_func(short *coeff_ptr, short *zbin_ptr, short *qcoeff_ptr, short *dqcoeff_ptr, short *dequant_ptr, const short *scan_mask, short *round_ptr, short *quant_ptr);
+
+void vp8_fast_quantize_b_neon(BLOCK *b, BLOCKD *d)
+{
+    d->eob = vp8_fast_quantize_b_neon_func(b->coeff, &b->zbin[0][0], d->qcoeff, d->dqcoeff, d->dequant[0], vp8_rvsplus1_default_zig_zag1d, &b->round[0][0], &b->quant[0][0]);
+}
+
+/*
+//neon code is written according to the following rewritten c code
+void vp8_fast_quantize_b_neon(BLOCK *b,BLOCKD *d)
+{
+    int i, rc, eob;
+    int zbin;
+    int x, x1, y, z, sz;
+    short *coeff_ptr  = &b->Coeff[0];
+    short *zbin_ptr   = &b->Zbin[0][0];
+    short *round_ptr  = &b->Round[0][0];
+    short *quant_ptr  = &b->Quant[0][0];
+    short *qcoeff_ptr = d->qcoeff;
+    short *dqcoeff_ptr= d->dqcoeff;
+    short *dequant_ptr= &d->Dequant[0][0];
+
+    eob = 0;
+
+    for(i=0;i<16;i++)
+    {
+        z    = coeff_ptr[i];
+        zbin = zbin_ptr[i] ;
+        x  = abs(z);                                    // x = abs(z)
+
+        if(x>=zbin)
+        {
+            sz = (z>>31);                               // sign of z
+            y  = ((x+round_ptr[i])*quant_ptr[i])>>16;     // quantize (x)
+            x1  = (y^sz) - sz;                          // get the sign back
+
+            qcoeff_ptr[i] = x1;                          // write to destination
+            dqcoeff_ptr[i] = x1 * dequant_ptr[i];         // dequantized value
+
+            if(y)
+            {
+                if(eob<vp8_rvsplus1_default_zig_zag1d[i])
+                    eob=(int)vp8_rvsplus1_default_zig_zag1d[i];         // last nonzero coeffs
+            }
+        }else
+        {
+            qcoeff_ptr[i] = 0;                          // write to destination
+            dqcoeff_ptr[i] = 0;         // dequantized value
+        }
+    }
+        d->eob = eob;
+}
+*/
diff --git a/vp8/encoder/arm/quantize_arm.h b/vp8/encoder/arm/quantize_arm.h
new file mode 100644 (file)
index 0000000..e93f0fe
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef QUANTIZE_ARM_H
+#define QUANTIZE_ARM_H
+
+#if HAVE_ARMV7
+extern prototype_quantize_block(vp8_fast_quantize_b_neon);
+
+#undef  vp8_quantize_fastquantb
+#define vp8_quantize_fastquantb vp8_fast_quantize_b_neon
+
+#endif
+
+#endif
diff --git a/vp8/encoder/arm/variance_arm.h b/vp8/encoder/arm/variance_arm.h
new file mode 100644 (file)
index 0000000..d9fc9b3
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VARIANCE_ARM_H
+#define VARIANCE_ARM_H
+
+#if HAVE_ARMV7
+extern prototype_sad(vp8_sad4x4_neon);
+extern prototype_sad(vp8_sad8x8_neon);
+extern prototype_sad(vp8_sad8x16_neon);
+extern prototype_sad(vp8_sad16x8_neon);
+extern prototype_sad(vp8_sad16x16_neon);
+
+//extern prototype_variance(vp8_variance4x4_c);
+extern prototype_variance(vp8_variance8x8_neon);
+extern prototype_variance(vp8_variance8x16_neon);
+extern prototype_variance(vp8_variance16x8_neon);
+extern prototype_variance(vp8_variance16x16_neon);
+
+//extern prototype_subpixvariance(vp8_sub_pixel_variance4x4_c);
+extern prototype_subpixvariance(vp8_sub_pixel_variance8x8_neon);
+//extern prototype_subpixvariance(vp8_sub_pixel_variance8x16_c);
+//extern prototype_subpixvariance(vp8_sub_pixel_variance16x8_c);
+extern prototype_subpixvariance(vp8_sub_pixel_variance16x16_neon);
+
+//extern prototype_getmbss(vp8_get_mb_ss_c);
+extern prototype_variance(vp8_mse16x16_neon);
+extern prototype_sad(vp8_get16x16pred_error_neon);
+//extern prototype_variance2(vp8_get8x8var_c);
+//extern prototype_variance2(vp8_get16x16var_c);
+extern prototype_sad(vp8_get4x4sse_cs_neon);
+
+#undef  vp8_variance_sad4x4
+#define vp8_variance_sad4x4 vp8_sad4x4_neon
+
+#undef  vp8_variance_sad8x8
+#define vp8_variance_sad8x8 vp8_sad8x8_neon
+
+#undef  vp8_variance_sad8x16
+#define vp8_variance_sad8x16 vp8_sad8x16_neon
+
+#undef  vp8_variance_sad16x8
+#define vp8_variance_sad16x8 vp8_sad16x8_neon
+
+#undef  vp8_variance_sad16x16
+#define vp8_variance_sad16x16 vp8_sad16x16_neon
+
+//#undef  vp8_variance_var4x4
+//#define vp8_variance_var4x4 vp8_variance4x4_c
+
+#undef  vp8_variance_var8x8
+#define vp8_variance_var8x8 vp8_variance8x8_neon
+
+#undef  vp8_variance_var8x16
+#define vp8_variance_var8x16 vp8_variance8x16_neon
+
+#undef  vp8_variance_var16x8
+#define vp8_variance_var16x8 vp8_variance16x8_neon
+
+#undef  vp8_variance_var16x16
+#define vp8_variance_var16x16 vp8_variance16x16_neon
+
+//#undef  vp8_variance_subpixvar4x4
+//#define vp8_variance_subpixvar4x4 vp8_sub_pixel_variance4x4_c
+
+#undef  vp8_variance_subpixvar8x8
+#define vp8_variance_subpixvar8x8 vp8_sub_pixel_variance8x8_neon
+
+//#undef  vp8_variance_subpixvar8x16
+//#define vp8_variance_subpixvar8x16 vp8_sub_pixel_variance8x16_c
+
+//#undef  vp8_variance_subpixvar16x8
+//#define vp8_variance_subpixvar16x8 vp8_sub_pixel_variance16x8_c
+
+#undef  vp8_variance_subpixvar16x16
+#define vp8_variance_subpixvar16x16 vp8_sub_pixel_variance16x16_neon
+
+//#undef  vp8_variance_getmbss
+//#define vp8_variance_getmbss vp8_get_mb_ss_c
+
+#undef  vp8_variance_mse16x16
+#define vp8_variance_mse16x16 vp8_mse16x16_neon
+
+#undef  vp8_variance_get16x16prederror
+#define vp8_variance_get16x16prederror vp8_get16x16pred_error_neon
+
+//#undef  vp8_variance_get8x8var
+//#define vp8_variance_get8x8var vp8_get8x8var_c
+
+//#undef  vp8_variance_get16x16var
+//#define vp8_variance_get16x16var vp8_get16x16var_c
+
+#undef  vp8_variance_get4x4sse_cs
+#define vp8_variance_get4x4sse_cs vp8_get4x4sse_cs_neon
+
+#endif
+
+#endif
diff --git a/vp8/encoder/arm/vpx_vp8_enc_asm_offsets.c b/vp8/encoder/arm/vpx_vp8_enc_asm_offsets.c
new file mode 100644 (file)
index 0000000..8cdf079
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include <stddef.h>
+
+#include "../treewriter.h"
+#include "../tokenize.h"
+#include "../onyx_int.h"
+
+#define ct_assert(name,cond) \
+    static void assert_##name(void) UNUSED;\
+    static void assert_##name(void) {switch(0){case 0:case !!(cond):;}}
+
+#define DEFINE(sym, val) int sym = val;
+
+/*
+#define BLANK() asm volatile("\n->" : : )
+*/
+
+/*
+ * int main(void)
+ * {
+ */
+
+DEFINE(vp8_writer_lowvalue,                     offsetof(vp8_writer, lowvalue));
+DEFINE(vp8_writer_range,                        offsetof(vp8_writer, range));
+DEFINE(vp8_writer_value,                        offsetof(vp8_writer, value));
+DEFINE(vp8_writer_count,                        offsetof(vp8_writer, count));
+DEFINE(vp8_writer_pos,                          offsetof(vp8_writer, pos));
+DEFINE(vp8_writer_buffer,                       offsetof(vp8_writer, buffer));
+
+DEFINE(tokenextra_token,                        offsetof(TOKENEXTRA, Token));
+DEFINE(tokenextra_extra,                        offsetof(TOKENEXTRA, Extra));
+DEFINE(tokenextra_context_tree,                  offsetof(TOKENEXTRA, context_tree));
+DEFINE(tokenextra_skip_eob_node,                offsetof(TOKENEXTRA, skip_eob_node));
+DEFINE(TOKENEXTRA_SZ,                           sizeof(TOKENEXTRA));
+
+DEFINE(vp8_extra_bit_struct_sz,                   sizeof(vp8_extra_bit_struct));
+
+DEFINE(vp8_token_value,                         offsetof(vp8_token, value));
+DEFINE(vp8_token_len,                           offsetof(vp8_token, Len));
+
+DEFINE(vp8_extra_bit_struct_tree,                 offsetof(vp8_extra_bit_struct, tree));
+DEFINE(vp8_extra_bit_struct_prob,                 offsetof(vp8_extra_bit_struct, prob));
+DEFINE(vp8_extra_bit_struct_prob_bc,               offsetof(vp8_extra_bit_struct, prob_bc));
+DEFINE(vp8_extra_bit_struct_len,                  offsetof(vp8_extra_bit_struct, Len));
+DEFINE(vp8_extra_bit_struct_base_val,              offsetof(vp8_extra_bit_struct, base_val));
+
+DEFINE(vp8_comp_tplist,                         offsetof(VP8_COMP, tplist));
+DEFINE(vp8_comp_common,                         offsetof(VP8_COMP, common));
+DEFINE(vp8_comp_bc2,                            offsetof(VP8_COMP, bc2));
+
+DEFINE(tokenlist_start,                         offsetof(TOKENLIST, start));
+DEFINE(tokenlist_stop,                          offsetof(TOKENLIST, stop));
+DEFINE(TOKENLIST_SZ,                            sizeof(TOKENLIST));
+
+DEFINE(vp8_common_mb_rows,                       offsetof(VP8_COMMON, mb_rows));
+
+// These two sizes are used in vp7cx_pack_tokens.  They are hard coded
+//  so if the size changes this will have to be adjusted.
+ct_assert(TOKENEXTRA_SZ, sizeof(TOKENEXTRA) == 20)
+ct_assert(vp8_extra_bit_struct_sz, sizeof(vp8_extra_bit_struct) == 20)
+
+//add asserts for any offset that is not supported by assembly code
+//add asserts for any size that is not supported by assembly code
+/*
+ * return 0;
+ * }
+ */
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
new file mode 100644 (file)
index 0000000..31ad56a
--- /dev/null
@@ -0,0 +1,1719 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "header.h"
+#include "encodemv.h"
+#include "entropymode.h"
+#include "findnearmv.h"
+#include "mcomp.h"
+#include "systemdependent.h"
+#include <assert.h>
+#include <stdio.h>
+#include "pragmas.h"
+#include "vpx_mem/vpx_mem.h"
+#include "bitstream.h"
+
+const int vp8cx_base_skip_false_prob[128] =
+{
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+    251, 248, 244, 240, 236, 232, 229, 225,
+    221, 217, 213, 208, 204, 199, 194, 190,
+    187, 183, 179, 175, 172, 168, 164, 160,
+    157, 153, 149, 145, 142, 138, 134, 130,
+    127, 124, 120, 117, 114, 110, 107, 104,
+    101, 98,  95,  92,  89,  86,  83, 80,
+    77,  74,  71,  68,  65,  62,  59, 56,
+    53,  50,  47,  44,  41,  38,  35, 32,
+    30,  28,  26,  24,  22,  20,  18, 16,
+};
+#ifdef VP8REF
+#define __int64 long long
+#endif
+
+#if defined(SECTIONBITS_OUTPUT)
+unsigned __int64 Sectionbits[500];
+#endif
+
+#ifdef ENTROPY_STATS
+int intra_mode_stats[10][10][10];
+static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] [2];
+extern unsigned int active_section;
+#endif
+
+#ifdef MODE_STATS
+int count_mb_seg[4] = { 0, 0, 0, 0 };
+#endif
+
+#if CONFIG_BIG_ENDIAN
+# define make_endian_16(a)  \
+    (((unsigned int)(a & 0xff)) << 8) | (((unsigned int)(a & 0xff00)) >> 8)
+# define make_endian_32(a)                              \
+    (((unsigned int)(a & 0xff)) << 24)    | (((unsigned int)(a & 0xff00)) << 8) |   \
+    (((unsigned int)(a & 0xff0000)) >> 8) | (((unsigned int)(a & 0xff000000)) >> 24)
+#else
+# define make_endian_16(a)  a
+# define make_endian_32(a)  a
+#endif
+
+static void update_mode(
+    vp8_writer *const w,
+    int n,
+    vp8_token tok               [/* n */],
+    vp8_tree tree,
+    vp8_prob Pnew               [/* n-1 */],
+    vp8_prob Pcur               [/* n-1 */],
+    unsigned int bct            [/* n-1 */] [2],
+    const unsigned int num_events[/* n */]
+)
+{
+    unsigned int new_b = 0, old_b = 0;
+    int i = 0;
+
+    vp8_tree_probs_from_distribution(
+        n--, tok, tree,
+        Pnew, bct, num_events,
+        256, 1
+    );
+
+    do
+    {
+        new_b += vp8_cost_branch(bct[i], Pnew[i]);
+        old_b += vp8_cost_branch(bct[i], Pcur[i]);
+    }
+    while (++i < n);
+
+    if (new_b + (n << 8) < old_b)
+    {
+        int i = 0;
+
+        vp8_write_bit(w, 1);
+
+        do
+        {
+            const vp8_prob p = Pnew[i];
+
+            vp8_write_literal(w, Pcur[i] = p ? p : 1, 8);
+        }
+        while (++i < n);
+    }
+    else
+        vp8_write_bit(w, 0);
+}
+
+static void update_mbintra_mode_probs(VP8_COMP *cpi)
+{
+    VP8_COMMON *const x = & cpi->common;
+
+    vp8_writer *const w = & cpi->bc;
+
+    {
+        vp8_prob Pnew   [VP8_YMODES-1];
+        unsigned int bct [VP8_YMODES-1] [2];
+
+        update_mode(
+            w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree,
+            Pnew, x->fc.ymode_prob, bct, (unsigned int *)cpi->ymode_count
+        );
+    }
+    {
+        vp8_prob Pnew   [VP8_UV_MODES-1];
+        unsigned int bct [VP8_UV_MODES-1] [2];
+
+        update_mode(
+            w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
+            Pnew, x->fc.uv_mode_prob, bct, (unsigned int *)cpi->uv_mode_count
+        );
+    }
+}
+
+static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p)
+{
+    vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
+}
+
+static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p)
+{
+    vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);
+}
+
+static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p)
+{
+    vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);
+}
+
+
+static void write_bmode(vp8_writer *bc, int m, const vp8_prob *p)
+{
+    vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m);
+}
+
+static void write_split(vp8_writer *bc, int x)
+{
+    vp8_write_token(
+        bc, vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + x
+    );
+}
+
+static const unsigned int norm[256] =
+{
+    0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
+{
+    const TOKENEXTRA *const stop = p + xcount;
+    unsigned int split;
+    unsigned int shift;
+    int count = w->count;
+    unsigned int range = w->range;
+    unsigned int lowvalue = w->lowvalue;
+
+    while (p < stop)
+    {
+        const int t = p->Token;
+        vp8_token *const a = vp8_coef_encodings + t;
+        const vp8_extra_bit_struct *const b = vp8_extra_bits + t;
+        int i = 0;
+        const unsigned char *pp = p->context_tree;
+        int v = a->value;
+        int n = a->Len;
+
+        if (p->skip_eob_node)
+        {
+            n--;
+            i = 2;
+        }
+
+        do
+        {
+            const int bb = (v >> --n) & 1;
+            split = 1 + (((range - 1) * pp[i>>1]) >> 8);
+            i = vp8_coef_tree[i+bb];
+
+            if (bb)
+            {
+                lowvalue += split;
+                range = range - split;
+            }
+            else
+            {
+                range = split;
+            }
+
+            shift = norm[range];
+            range <<= shift;
+            count += shift;
+
+            if (count >= 0)
+            {
+                int offset = shift - count;
+
+                if ((lowvalue << (offset - 1)) & 0x80000000)
+                {
+                    int x = w->pos - 1;
+
+                    while (x >= 0 && w->buffer[x] == 0xff)
+                    {
+                        w->buffer[x] = (unsigned char)0;
+                        x--;
+                    }
+
+                    w->buffer[x] += 1;
+                }
+
+                w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+                lowvalue <<= offset;
+                shift = count;
+                lowvalue &= 0xffffff;
+                count -= 8 ;
+            }
+
+            lowvalue <<= shift;
+        }
+        while (n);
+
+
+        if (b->base_val)
+        {
+            const int e = p->Extra, L = b->Len;
+
+            if (L)
+            {
+                const unsigned char *pp = b->prob;
+                int v = e >> 1;
+                int n = L;              /* number of bits in v, assumed nonzero */
+                int i = 0;
+
+                do
+                {
+                    const int bb = (v >> --n) & 1;
+                    split = 1 + (((range - 1) * pp[i>>1]) >> 8);
+                    i = b->tree[i+bb];
+
+                    if (bb)
+                    {
+                        lowvalue += split;
+                        range = range - split;
+                    }
+                    else
+                    {
+                        range = split;
+                    }
+
+                    shift = norm[range];
+                    range <<= shift;
+                    count += shift;
+
+                    if (count >= 0)
+                    {
+                        int offset = shift - count;
+
+                        if ((lowvalue << (offset - 1)) & 0x80000000)
+                        {
+                            int x = w->pos - 1;
+
+                            while (x >= 0 && w->buffer[x] == 0xff)
+                            {
+                                w->buffer[x] = (unsigned char)0;
+                                x--;
+                            }
+
+                            w->buffer[x] += 1;
+                        }
+
+                        w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+                        lowvalue <<= offset;
+                        shift = count;
+                        lowvalue &= 0xffffff;
+                        count -= 8 ;
+                    }
+
+                    lowvalue <<= shift;
+                }
+                while (n);
+            }
+
+
+            {
+
+                split = (range + 1) >> 1;
+
+                if (e & 1)
+                {
+                    lowvalue += split;
+                    range = range - split;
+                }
+                else
+                {
+                    range = split;
+                }
+
+                range <<= 1;
+
+                if ((lowvalue & 0x80000000))
+                {
+                    int x = w->pos - 1;
+
+                    while (x >= 0 && w->buffer[x] == 0xff)
+                    {
+                        w->buffer[x] = (unsigned char)0;
+                        x--;
+                    }
+
+                    w->buffer[x] += 1;
+
+                }
+
+                lowvalue  <<= 1;
+
+                if (!++count)
+                {
+                    count = -8;
+                    w->buffer[w->pos++] = (lowvalue >> 24);
+                    lowvalue &= 0xffffff;
+                }
+            }
+
+        }
+
+        ++p;
+    }
+
+    w->count = count;
+    w->lowvalue = lowvalue;
+    w->range = range;
+
+}
+
+static void write_partition_size(unsigned char *cx_data, int size)
+{
+    signed char csize;
+
+    csize = size & 0xff;
+    *cx_data = csize;
+    csize = (size >> 8) & 0xff;
+    *(cx_data + 1) = csize;
+    csize = (size >> 16) & 0xff;
+    *(cx_data + 2) = csize;
+
+}
+
+static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data, int num_part, int *size)
+{
+
+    int i;
+    unsigned char *ptr = cx_data;
+    unsigned int shift;
+    vp8_writer *w = &cpi->bc2;
+    *size = 3 * (num_part - 1);
+    ptr = cx_data + (*size);
+
+    for (i = 0; i < num_part; i++)
+    {
+        vp8_start_encode(w, ptr);
+        {
+            unsigned int split;
+            int count = w->count;
+            unsigned int range = w->range;
+            unsigned int lowvalue = w->lowvalue;
+            int mb_row;
+
+            for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part)
+            {
+                TOKENEXTRA *p    = cpi->tplist[mb_row].start;
+                TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
+
+                while (p < stop)
+                {
+                    const int t = p->Token;
+                    vp8_token *const a = vp8_coef_encodings + t;
+                    const vp8_extra_bit_struct *const b = vp8_extra_bits + t;
+                    int i = 0;
+                    const unsigned char *pp = p->context_tree;
+                    int v = a->value;
+                    int n = a->Len;
+
+                    if (p->skip_eob_node)
+                    {
+                        n--;
+                        i = 2;
+                    }
+
+                    do
+                    {
+                        const int bb = (v >> --n) & 1;
+                        split = 1 + (((range - 1) * pp[i>>1]) >> 8);
+                        i = vp8_coef_tree[i+bb];
+
+                        if (bb)
+                        {
+                            lowvalue += split;
+                            range = range - split;
+                        }
+                        else
+                        {
+                            range = split;
+                        }
+
+                        shift = norm[range];
+                        range <<= shift;
+                        count += shift;
+
+                        if (count >= 0)
+                        {
+                            int offset = shift - count;
+
+                            if ((lowvalue << (offset - 1)) & 0x80000000)
+                            {
+                                int x = w->pos - 1;
+
+                                while (x >= 0 && w->buffer[x] == 0xff)
+                                {
+                                    w->buffer[x] = (unsigned char)0;
+                                    x--;
+                                }
+
+                                w->buffer[x] += 1;
+                            }
+
+                            w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+                            lowvalue <<= offset;
+                            shift = count;
+                            lowvalue &= 0xffffff;
+                            count -= 8 ;
+                        }
+
+                        lowvalue <<= shift;
+                    }
+                    while (n);
+
+
+                    if (b->base_val)
+                    {
+                        const int e = p->Extra, L = b->Len;
+
+                        if (L)
+                        {
+                            const unsigned char *pp = b->prob;
+                            int v = e >> 1;
+                            int n = L;              /* number of bits in v, assumed nonzero */
+                            int i = 0;
+
+                            do
+                            {
+                                const int bb = (v >> --n) & 1;
+                                split = 1 + (((range - 1) * pp[i>>1]) >> 8);
+                                i = b->tree[i+bb];
+
+                                if (bb)
+                                {
+                                    lowvalue += split;
+                                    range = range - split;
+                                }
+                                else
+                                {
+                                    range = split;
+                                }
+
+                                shift = norm[range];
+                                range <<= shift;
+                                count += shift;
+
+                                if (count >= 0)
+                                {
+                                    int offset = shift - count;
+
+                                    if ((lowvalue << (offset - 1)) & 0x80000000)
+                                    {
+                                        int x = w->pos - 1;
+
+                                        while (x >= 0 && w->buffer[x] == 0xff)
+                                        {
+                                            w->buffer[x] = (unsigned char)0;
+                                            x--;
+                                        }
+
+                                        w->buffer[x] += 1;
+                                    }
+
+                                    w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+                                    lowvalue <<= offset;
+                                    shift = count;
+                                    lowvalue &= 0xffffff;
+                                    count -= 8 ;
+                                }
+
+                                lowvalue <<= shift;
+                            }
+                            while (n);
+                        }
+
+                        {
+                            split = (range + 1) >> 1;
+
+                            if (e & 1)
+                            {
+                                lowvalue += split;
+                                range = range - split;
+                            }
+                            else
+                            {
+                                range = split;
+                            }
+
+                            range <<= 1;
+
+                            if ((lowvalue & 0x80000000))
+                            {
+                                int x = w->pos - 1;
+
+                                while (x >= 0 && w->buffer[x] == 0xff)
+                                {
+                                    w->buffer[x] = (unsigned char)0;
+                                    x--;
+                                }
+
+                                w->buffer[x] += 1;
+
+                            }
+
+                            lowvalue  <<= 1;
+
+                            if (!++count)
+                            {
+                                count = -8;
+                                w->buffer[w->pos++] = (lowvalue >> 24);
+                                lowvalue &= 0xffffff;
+                            }
+                        }
+
+                    }
+
+                    ++p;
+                }
+            }
+
+            w->count    = count;
+            w->lowvalue = lowvalue;
+            w->range    = range;
+
+        }
+
+        vp8_stop_encode(w);
+        *size +=   w->pos;
+
+        if (i < (num_part - 1))
+        {
+            write_partition_size(cx_data, w->pos);
+            cx_data += 3;
+            ptr += w->pos;
+        }
+    }
+}
+
+
+static void pack_mb_row_tokens_c(VP8_COMP *cpi, vp8_writer *w)
+{
+
+    unsigned int split;
+    int count = w->count;
+    unsigned int range = w->range;
+    unsigned int lowvalue = w->lowvalue;
+    unsigned int shift;
+    int mb_row;
+
+    for (mb_row = 0; mb_row < cpi->common.mb_rows; mb_row++)
+    {
+        TOKENEXTRA *p    = cpi->tplist[mb_row].start;
+        TOKENEXTRA *stop = cpi->tplist[mb_row].stop;
+
+        while (p < stop)
+        {
+            const int t = p->Token;
+            vp8_token *const a = vp8_coef_encodings + t;
+            const vp8_extra_bit_struct *const b = vp8_extra_bits + t;
+            int i = 0;
+            const unsigned char *pp = p->context_tree;
+            int v = a->value;
+            int n = a->Len;
+
+            if (p->skip_eob_node)
+            {
+                n--;
+                i = 2;
+            }
+
+            do
+            {
+                const int bb = (v >> --n) & 1;
+                split = 1 + (((range - 1) * pp[i>>1]) >> 8);
+                i = vp8_coef_tree[i+bb];
+
+                if (bb)
+                {
+                    lowvalue += split;
+                    range = range - split;
+                }
+                else
+                {
+                    range = split;
+                }
+
+                shift = norm[range];
+                range <<= shift;
+                count += shift;
+
+                if (count >= 0)
+                {
+                    int offset = shift - count;
+
+                    if ((lowvalue << (offset - 1)) & 0x80000000)
+                    {
+                        int x = w->pos - 1;
+
+                        while (x >= 0 && w->buffer[x] == 0xff)
+                        {
+                            w->buffer[x] = (unsigned char)0;
+                            x--;
+                        }
+
+                        w->buffer[x] += 1;
+                    }
+
+                    w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+                    lowvalue <<= offset;
+                    shift = count;
+                    lowvalue &= 0xffffff;
+                    count -= 8 ;
+                }
+
+                lowvalue <<= shift;
+            }
+            while (n);
+
+
+            if (b->base_val)
+            {
+                const int e = p->Extra, L = b->Len;
+
+                if (L)
+                {
+                    const unsigned char *pp = b->prob;
+                    int v = e >> 1;
+                    int n = L;              /* number of bits in v, assumed nonzero */
+                    int i = 0;
+
+                    do
+                    {
+                        const int bb = (v >> --n) & 1;
+                        split = 1 + (((range - 1) * pp[i>>1]) >> 8);
+                        i = b->tree[i+bb];
+
+                        if (bb)
+                        {
+                            lowvalue += split;
+                            range = range - split;
+                        }
+                        else
+                        {
+                            range = split;
+                        }
+
+                        shift = norm[range];
+                        range <<= shift;
+                        count += shift;
+
+                        if (count >= 0)
+                        {
+                            int offset = shift - count;
+
+                            if ((lowvalue << (offset - 1)) & 0x80000000)
+                            {
+                                int x = w->pos - 1;
+
+                                while (x >= 0 && w->buffer[x] == 0xff)
+                                {
+                                    w->buffer[x] = (unsigned char)0;
+                                    x--;
+                                }
+
+                                w->buffer[x] += 1;
+                            }
+
+                            w->buffer[w->pos++] = (lowvalue >> (24 - offset));
+                            lowvalue <<= offset;
+                            shift = count;
+                            lowvalue &= 0xffffff;
+                            count -= 8 ;
+                        }
+
+                        lowvalue <<= shift;
+                    }
+                    while (n);
+                }
+
+                {
+                    split = (range + 1) >> 1;
+
+                    if (e & 1)
+                    {
+                        lowvalue += split;
+                        range = range - split;
+                    }
+                    else
+                    {
+                        range = split;
+                    }
+
+                    range <<= 1;
+
+                    if ((lowvalue & 0x80000000))
+                    {
+                        int x = w->pos - 1;
+
+                        while (x >= 0 && w->buffer[x] == 0xff)
+                        {
+                            w->buffer[x] = (unsigned char)0;
+                            x--;
+                        }
+
+                        w->buffer[x] += 1;
+
+                    }
+
+                    lowvalue  <<= 1;
+
+                    if (!++count)
+                    {
+                        count = -8;
+                        w->buffer[w->pos++] = (lowvalue >> 24);
+                        lowvalue &= 0xffffff;
+                    }
+                }
+
+            }
+
+            ++p;
+        }
+    }
+
+    w->count = count;
+    w->lowvalue = lowvalue;
+    w->range = range;
+
+}
+
+static void write_mv_ref
+(
+    vp8_writer *w, MB_PREDICTION_MODE m, const vp8_prob *p
+)
+{
+
+    assert(NEARESTMV <= m  &&  m <= SPLITMV);
+
+    vp8_write_token(w, vp8_mv_ref_tree, p, VP8_MVREFENCODINGS + m);
+}
+
+static void write_sub_mv_ref
+(
+    vp8_writer *w, B_PREDICTION_MODE m, const vp8_prob *p
+)
+{
+    assert(LEFT4X4 <= m  &&  m <= NEW4X4);
+
+    vp8_write_token(w, vp8_sub_mv_ref_tree, p, VP8_SUBMVREFENCODINGS + m);
+}
+
+static void write_mv
+(
+    vp8_writer *w, const MV *mv, const MV *ref, const MV_CONTEXT *mvc
+)
+{
+    MV e;
+    e.row = mv->row - ref->row;
+    e.col = mv->col - ref->col;
+
+    vp8_encode_motion_vector(w, &e, mvc);
+}
+
+static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACROBLOCKD *x)
+{
+    // Encode the MB segment id.
+    if (x->segmentation_enabled && x->update_mb_segmentation_map)
+    {
+        switch (mi->segment_id)
+        {
+        case 0:
+            vp8_write(w, 0, x->mb_segment_tree_probs[0]);
+            vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+            break;
+        case 1:
+            vp8_write(w, 0, x->mb_segment_tree_probs[0]);
+            vp8_write(w, 1, x->mb_segment_tree_probs[1]);
+            break;
+        case 2:
+            vp8_write(w, 1, x->mb_segment_tree_probs[0]);
+            vp8_write(w, 0, x->mb_segment_tree_probs[2]);
+            break;
+        case 3:
+            vp8_write(w, 1, x->mb_segment_tree_probs[0]);
+            vp8_write(w, 1, x->mb_segment_tree_probs[2]);
+            break;
+
+            // TRAP.. This should not happen
+        default:
+            vp8_write(w, 0, x->mb_segment_tree_probs[0]);
+            vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+            break;
+        }
+    }
+}
+
+
+static void pack_inter_mode_mvs(VP8_COMP *const cpi)
+{
+    VP8_COMMON *const pc = & cpi->common;
+    vp8_writer *const w = & cpi->bc;
+    const MV_CONTEXT *mvc = pc->fc.mvc;
+
+    const int *const rfct = cpi->count_mb_ref_frame_usage;
+    const int rf_intra = rfct[INTRA_FRAME];
+    const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
+
+    MODE_INFO *m = pc->mi, *ms;
+    const int mis = pc->mode_info_stride;
+    int mb_row = -1;
+
+    int prob_last_coded;
+    int prob_gf_coded;
+    int prob_skip_false = 0;
+    ms = pc->mi - 1;
+
+    // Calculate the probabilities to be used to code the reference frame based on actual useage this frame
+    if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter)))
+        cpi->prob_intra_coded = 1;
+
+    prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+
+    if (!prob_last_coded)
+        prob_last_coded = 1;
+
+    prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+                    ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+    if (!prob_gf_coded)
+        prob_gf_coded = 1;
+
+
+#ifdef ENTROPY_STATS
+    active_section = 1;
+#endif
+
+    if (pc->mb_no_coeff_skip)
+    {
+        prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count);
+
+        if (prob_skip_false <= 1)
+            prob_skip_false = 1;
+
+        if (prob_skip_false > 255)
+            prob_skip_false = 255;
+
+        cpi->prob_skip_false = prob_skip_false;
+        vp8_write_literal(w, prob_skip_false, 8);
+    }
+
+    vp8_write_literal(w, cpi->prob_intra_coded, 8);
+    vp8_write_literal(w, prob_last_coded, 8);
+    vp8_write_literal(w, prob_gf_coded, 8);
+
+    update_mbintra_mode_probs(cpi);
+
+    vp8_write_mvprobs(cpi);
+
+    while (++mb_row < pc->mb_rows)
+    {
+        int mb_col = -1;
+
+        while (++mb_col < pc->mb_cols)
+        {
+            const MB_MODE_INFO *const mi = & m->mbmi;
+            const MV_REFERENCE_FRAME rf = mi->ref_frame;
+            const MB_PREDICTION_MODE mode = mi->mode;
+
+            MACROBLOCKD *xd = &cpi->mb.e_mbd;
+
+            // Distance of Mb to the various image edges.
+            // These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
+            xd->mb_to_left_edge = -((mb_col * 16) << 3);
+            xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+            xd->mb_to_top_edge = -((mb_row * 16)) << 3;
+            xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+
+#ifdef ENTROPY_STATS
+            active_section = 9;
+#endif
+
+            if (cpi->mb.e_mbd.update_mb_segmentation_map)
+                write_mb_features(w, mi, &cpi->mb.e_mbd);
+
+            if (pc->mb_no_coeff_skip)
+                vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
+
+            if (rf == INTRA_FRAME)
+            {
+                vp8_write(w, 0, cpi->prob_intra_coded);
+#ifdef ENTROPY_STATS
+                active_section = 6;
+#endif
+                write_ymode(w, mode, pc->fc.ymode_prob);
+
+                if (mode == B_PRED)
+                {
+                    int j = 0;
+
+                    do
+                        write_bmode(w, m->bmi[j].mode, pc->fc.bmode_prob);
+
+                    while (++j < 16);
+                }
+
+                write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob);
+            }
+            else    /* inter coded */
+            {
+                MV best_mv;
+                vp8_prob mv_ref_p [VP8_MVREFS-1];
+
+                vp8_write(w, 1, cpi->prob_intra_coded);
+
+                if (rf == LAST_FRAME)
+                    vp8_write(w, 0, prob_last_coded);
+                else
+                {
+                    vp8_write(w, 1, prob_last_coded);
+                    vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, prob_gf_coded);
+                }
+
+                {
+                    MV n1, n2;
+                    int ct[4];
+
+                    vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf, cpi->common.ref_frame_sign_bias);
+                    vp8_mv_ref_probs(mv_ref_p, ct);
+
+#ifdef ENTROPY_STATS
+                    accum_mv_refs(mode, ct);
+#endif
+
+                }
+
+#ifdef ENTROPY_STATS
+                active_section = 3;
+#endif
+
+                write_mv_ref(w, mode, mv_ref_p);
+
+                switch (mode)   /* new, split require MVs */
+                {
+                case NEWMV:
+
+#ifdef ENTROPY_STATS
+                    active_section = 5;
+#endif
+
+                    write_mv(w, &mi->mv.as_mv, &best_mv, mvc);
+                    break;
+
+                case SPLITMV:
+                {
+                    int j = 0;
+
+#ifdef MODE_STATS
+                    ++count_mb_seg [mi->partitioning];
+#endif
+
+                    write_split(w, mi->partitioning);
+
+                    do
+                    {
+                        const B_MODE_INFO *const b = mi->partition_bmi + j;
+                        const int *const  L = vp8_mbsplits [mi->partitioning];
+                        int k = -1;  /* first block in subset j */
+                        int mv_contz;
+
+                        while (j != L[++k])
+                            if (k >= 16)
+                                assert(0);
+
+                        mv_contz = vp8_mv_cont
+                                   (&(vp8_left_bmi(m, k)->mv.as_mv),
+                                    &(vp8_above_bmi(m, k, mis)->mv.as_mv));
+                        write_sub_mv_ref(w, b->mode, vp8_sub_mv_ref_prob2 [mv_contz]); //pc->fc.sub_mv_ref_prob);
+
+                        if (b->mode == NEW4X4)
+                        {
+#ifdef ENTROPY_STATS
+                            active_section = 11;
+#endif
+                            write_mv(w, &b->mv.as_mv, &best_mv, (const MV_CONTEXT *) mvc);
+                        }
+                    }
+                    while (++j < mi->partition_count);
+                }
+                break;
+                default:
+                    break;
+                }
+            }
+
+            ++m;
+        }
+
+        ++m;  /* skip L prediction border */
+    }
+}
+
+
+static void write_kfmodes(VP8_COMP *cpi)
+{
+    vp8_writer *const bc = & cpi->bc;
+    const VP8_COMMON *const c = & cpi->common;
+    /* const */
+    MODE_INFO *m = c->mi;
+
+    int mb_row = -1;
+    int prob_skip_false = 0;
+
+    if (c->mb_no_coeff_skip)
+    {
+        prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count);
+
+        if (prob_skip_false <= 1)
+            prob_skip_false = 1;
+
+        if (prob_skip_false >= 255)
+            prob_skip_false = 255;
+
+        cpi->prob_skip_false = prob_skip_false;
+        vp8_write_literal(bc, prob_skip_false, 8);
+    }
+
+    while (++mb_row < c->mb_rows)
+    {
+        int mb_col = -1;
+
+        while (++mb_col < c->mb_cols)
+        {
+            const int ym = m->mbmi.mode;
+
+            if (cpi->mb.e_mbd.update_mb_segmentation_map)
+                write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+
+            if (c->mb_no_coeff_skip)
+                vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
+
+            kfwrite_ymode(bc, ym, c->kf_ymode_prob);
+
+            if (ym == B_PRED)
+            {
+                const int mis = c->mode_info_stride;
+                int i = 0;
+
+                do
+                {
+                    const B_PREDICTION_MODE A = vp8_above_bmi(m, i, mis)->mode;
+                    const B_PREDICTION_MODE L = vp8_left_bmi(m, i)->mode;
+                    const int bm = m->bmi[i].mode;
+
+#ifdef ENTROPY_STATS
+                    ++intra_mode_stats [A] [L] [bm];
+#endif
+
+                    write_bmode(bc, bm, c->kf_bmode_prob [A] [L]);
+                }
+                while (++i < 16);
+            }
+
+            write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob);
+        }
+
+        m++;    // skip L prediction border
+    }
+}
+int vp8_estimate_entropy_savings(VP8_COMP *cpi)
+{
+    int i = 0;
+    int savings = 0;
+
+    const int *const rfct = cpi->count_mb_ref_frame_usage;
+    const int rf_intra = rfct[INTRA_FRAME];
+    const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
+    int new_intra, new_last, gf_last, oldtotal, newtotal;
+    int ref_frame_cost[MAX_REF_FRAMES];
+
+    vp8_clear_system_state(); //__asm emms;
+
+    if (cpi->common.frame_type != KEY_FRAME)
+    {
+        if (!(new_intra = rf_intra * 255 / (rf_intra + rf_inter)))
+            new_intra = 1;
+
+        new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+
+        gf_last = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+                  ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+        // new costs
+        ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(new_intra);
+        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(new_intra)
+                                        + vp8_cost_zero(new_last);
+        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(new_intra)
+                                        + vp8_cost_one(new_last)
+                                        + vp8_cost_zero(gf_last);
+        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(new_intra)
+                                        + vp8_cost_one(new_last)
+                                        + vp8_cost_one(gf_last);
+
+        newtotal =
+            rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
+            rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
+            rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
+            rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
+
+
+        // old costs
+        ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(cpi->prob_intra_coded);
+        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_zero(cpi->prob_last_coded);
+        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(cpi->prob_last_coded)
+                                        + vp8_cost_zero(cpi->prob_gf_coded);
+        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(cpi->prob_last_coded)
+                                        + vp8_cost_one(cpi->prob_gf_coded);
+
+        oldtotal =
+            rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
+            rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
+            rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
+            rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
+
+        savings += (oldtotal - newtotal) / 256;
+    }
+
+
+    do
+    {
+        int j = 0;
+
+        do
+        {
+            int k = 0;
+
+            do
+            {
+                /* at every context */
+
+                /* calc probs and branch cts for this frame only */
+                //vp8_prob new_p           [vp8_coef_tokens-1];
+                //unsigned int branch_ct   [vp8_coef_tokens-1] [2];
+
+                int t = 0;      /* token/prob index */
+
+                vp8_tree_probs_from_distribution(
+                    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree,
+                    cpi->frame_coef_probs [i][j][k], cpi->frame_branch_ct [i][j][k], cpi->coef_counts [i][j][k],
+                    256, 1
+                );
+
+                do
+                {
+                    const unsigned int *ct  = cpi->frame_branch_ct [i][j][k][t];
+                    const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+
+                    const vp8_prob old = cpi->common.fc.coef_probs [i][j][k][t];
+                    const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+
+                    const int old_b = vp8_cost_branch(ct, old);
+                    const int new_b = vp8_cost_branch(ct, newp);
+
+                    const int update_b = 8 +
+                                         ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
+
+                    const int s = old_b - new_b - update_b;
+
+                    if (s > 0)
+                        savings += s;
+
+
+                }
+                while (++t < vp8_coef_tokens - 1);
+
+
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+        }
+        while (++j < COEF_BANDS);
+    }
+    while (++i < BLOCK_TYPES);
+
+    return savings;
+}
+
+static void update_coef_probs(VP8_COMP *cpi)
+{
+    int i = 0;
+    vp8_writer *const w = & cpi->bc;
+    int savings = 0;
+
+    vp8_clear_system_state(); //__asm emms;
+
+
+    do
+    {
+        int j = 0;
+
+        do
+        {
+            int k = 0;
+
+            do
+            {
+                //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
+                /* at every context */
+
+                /* calc probs and branch cts for this frame only */
+                //vp8_prob new_p           [vp8_coef_tokens-1];
+                //unsigned int branch_ct   [vp8_coef_tokens-1] [2];
+
+                int t = 0;      /* token/prob index */
+
+                //vp8_tree_probs_from_distribution(
+                //    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree,
+                //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
+                //    256, 1
+                //    );
+
+                do
+                {
+                    const unsigned int *ct  = cpi->frame_branch_ct [i][j][k][t];
+                    const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+
+                    vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
+                    const vp8_prob old = *Pold;
+                    const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+
+                    const int old_b = vp8_cost_branch(ct, old);
+                    const int new_b = vp8_cost_branch(ct, newp);
+
+                    const int update_b = 8 +
+                                         ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
+
+                    const int s = old_b - new_b - update_b;
+                    const int u = s > 0 ? 1 : 0;
+
+                    vp8_write(w, u, upd);
+
+
+#ifdef ENTROPY_STATS
+                    ++ tree_update_hist [i][j][k][t] [u];
+#endif
+
+                    if (u)
+                    {
+                        /* send/use new probability */
+
+                        *Pold = newp;
+                        vp8_write_literal(w, newp, 8);
+
+                        savings += s;
+
+                    }
+
+                }
+                while (++t < vp8_coef_tokens - 1);
+
+                /* Accum token counts for generation of default statistics */
+#ifdef ENTROPY_STATS
+                t = 0;
+
+                do
+                {
+                    context_counters [i][j][k][t] += cpi->coef_counts [i][j][k][t];
+                }
+                while (++t < vp8_coef_tokens);
+
+#endif
+
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+        }
+        while (++j < COEF_BANDS);
+    }
+    while (++i < BLOCK_TYPES);
+
+}
+#ifdef PACKET_TESTING
+FILE *vpxlogc = 0;
+#endif
+
+static void put_delta_q(vp8_writer *bc, int delta_q)
+{
+    if (delta_q != 0)
+    {
+        vp8_write_bit(bc, 1);
+        vp8_write_literal(bc, abs(delta_q), 4);
+
+        if (delta_q < 0)
+            vp8_write_bit(bc, 1);
+        else
+            vp8_write_bit(bc, 0);
+    }
+    else
+        vp8_write_bit(bc, 0);
+}
+
+void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
+{
+    int i, j;
+    VP8_HEADER oh;
+    VP8_COMMON *const pc = & cpi->common;
+    vp8_writer *const bc = & cpi->bc;
+    MACROBLOCKD *const xd = & cpi->mb.e_mbd;
+    int extra_bytes_packed = 0;
+
+    unsigned char *cx_data = dest;
+    const int *mb_feature_data_bits;
+
+    oh.show_frame = (int) pc->show_frame;
+    oh.type = (int)pc->frame_type;
+    oh.version = pc->version;
+
+    mb_feature_data_bits = vp8_mb_feature_data_bits;
+    cx_data += 3;
+
+#if defined(SECTIONBITS_OUTPUT)
+    Sectionbits[active_section = 1] += sizeof(VP8_HEADER) * 8 * 256;
+#endif
+
+    //vp8_kf_default_bmode_probs() is called in vp8_setup_key_frame() once for each
+    //K frame before encode frame. pc->kf_bmode_prob doesn't get changed anywhere
+    //else. No need to call it again here. --yw
+    //vp8_kf_default_bmode_probs( pc->kf_bmode_prob);
+
+    // every keyframe send startcode, width, height, scale factor, clamp and color type
+    if (oh.type == KEY_FRAME)
+    {
+        int w, h, hs, vs;
+
+        // Start / synch code
+        cx_data[0] = 0x9D;
+        cx_data[1] = 0x01;
+        cx_data[2] = 0x2a;
+
+        *((unsigned short *)(cx_data + 3)) = make_endian_16((pc->horiz_scale << 14) | pc->Width);
+        *((unsigned short *)(cx_data + 5)) = make_endian_16((pc->vert_scale << 14) | pc->Height);
+
+        extra_bytes_packed = 7;
+        cx_data += extra_bytes_packed ;
+
+        vp8_start_encode(bc, cx_data);
+
+        // signal clr type
+        vp8_write_bit(bc, pc->clr_type);
+        vp8_write_bit(bc, pc->clamp_type);
+
+    }
+    else
+        vp8_start_encode(bc, cx_data);
+
+
+    // Signal whether or not Segmentation is enabled
+    vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0);
+
+    // Indicate which features are enabled
+    if (xd->segmentation_enabled)
+    {
+        // Signal whether or not the segmentation map is being updated.
+        vp8_write_bit(bc, (xd->update_mb_segmentation_map) ? 1 : 0);
+        vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
+
+        if (xd->update_mb_segmentation_data)
+        {
+            signed char Data;
+
+            vp8_write_bit(bc, (xd->mb_segement_abs_delta) ? 1 : 0);
+
+            // For each segmentation feature (Quant and loop filter level)
+            for (i = 0; i < MB_LVL_MAX; i++)
+            {
+                // For each of the segments
+                for (j = 0; j < MAX_MB_SEGMENTS; j++)
+                {
+                    Data = xd->segment_feature_data[i][j];
+
+                    // Frame level data
+                    if (Data)
+                    {
+                        vp8_write_bit(bc, 1);
+
+                        if (Data < 0)
+                        {
+                            Data = - Data;
+                            vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
+                            vp8_write_bit(bc, 1);
+                        }
+                        else
+                        {
+                            vp8_write_literal(bc, Data, mb_feature_data_bits[i]);
+                            vp8_write_bit(bc, 0);
+                        }
+                    }
+                    else
+                        vp8_write_bit(bc, 0);
+                }
+            }
+        }
+
+        if (xd->update_mb_segmentation_map)
+        {
+            // Write the probs used to decode the segment id for each macro block.
+            for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+            {
+                int Data = xd->mb_segment_tree_probs[i];
+
+                if (Data != 255)
+                {
+                    vp8_write_bit(bc, 1);
+                    vp8_write_literal(bc, Data, 8);
+                }
+                else
+                    vp8_write_bit(bc, 0);
+            }
+        }
+    }
+
+    // Code to determine whether or not to update the scan order.
+    vp8_write_bit(bc, pc->filter_type);
+    vp8_write_literal(bc, pc->filter_level, 6);
+    vp8_write_literal(bc, pc->sharpness_level, 3);
+
+    // Write out loop filter deltas applied at the MB level based on mode or ref frame (if they are enabled).
+    vp8_write_bit(bc, (xd->mode_ref_lf_delta_enabled) ? 1 : 0);
+
+    if (xd->mode_ref_lf_delta_enabled)
+    {
+        // Do the deltas need to be updated
+        vp8_write_bit(bc, (xd->mode_ref_lf_delta_update) ? 1 : 0);
+
+        if (xd->mode_ref_lf_delta_update)
+        {
+            int Data;
+
+            // Send update
+            for (i = 0; i < MAX_REF_LF_DELTAS; i++)
+            {
+                Data = xd->ref_lf_deltas[i];
+
+                // Frame level data
+                if (Data)
+                {
+                    vp8_write_bit(bc, 1);
+
+                    if (Data > 0)
+                    {
+                        vp8_write_literal(bc, (Data & 0x3F), 6);
+                        vp8_write_bit(bc, 0);    // sign
+                    }
+                    else
+                    {
+                        Data = -Data;
+                        vp8_write_literal(bc, (Data & 0x3F), 6);
+                        vp8_write_bit(bc, 1);    // sign
+                    }
+                }
+                else
+                    vp8_write_bit(bc, 0);
+            }
+
+            // Send update
+            for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
+            {
+                Data = xd->mode_lf_deltas[i];
+
+                if (Data)
+                {
+                    vp8_write_bit(bc, 1);
+
+                    if (Data > 0)
+                    {
+                        vp8_write_literal(bc, (Data & 0x3F), 6);
+                        vp8_write_bit(bc, 0);    // sign
+                    }
+                    else
+                    {
+                        Data = -Data;
+                        vp8_write_literal(bc, (Data & 0x3F), 6);
+                        vp8_write_bit(bc, 1);    // sign
+                    }
+                }
+                else
+                    vp8_write_bit(bc, 0);
+            }
+        }
+    }
+
+    //signal here is multi token partition is enabled
+    vp8_write_literal(bc, pc->multi_token_partition, 2);
+
+    // Frame Qbaseline quantizer index
+    vp8_write_literal(bc, pc->base_qindex, 7);
+
+    // Transmit Dc, Second order and Uv quantizer delta information
+    put_delta_q(bc, pc->y1dc_delta_q);
+    put_delta_q(bc, pc->y2dc_delta_q);
+    put_delta_q(bc, pc->y2ac_delta_q);
+    put_delta_q(bc, pc->uvdc_delta_q);
+    put_delta_q(bc, pc->uvac_delta_q);
+
+    // When there is a key frame all reference buffers are updated using the new key frame
+    if (pc->frame_type != KEY_FRAME)
+    {
+        // Should the GF or ARF be updated using the transmitted frame or buffer
+        vp8_write_bit(bc, pc->refresh_golden_frame);
+        vp8_write_bit(bc, pc->refresh_alt_ref_frame);
+
+        // If not being updated from current frame should either GF or ARF be updated from another buffer
+        if (!pc->refresh_golden_frame)
+            vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);
+
+        if (!pc->refresh_alt_ref_frame)
+            vp8_write_literal(bc, pc->copy_buffer_to_arf, 2);
+
+        // Indicate reference frame sign bias for Golden and ARF frames (always 0 for last frame buffer)
+        vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]);
+        vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
+    }
+
+    vp8_write_bit(bc, pc->refresh_entropy_probs);
+
+    if (pc->frame_type != KEY_FRAME)
+        vp8_write_bit(bc, pc->refresh_last_frame);
+
+#ifdef ENTROPY_STATS
+
+    if (pc->frame_type == INTER_FRAME)
+        active_section = 0;
+    else
+        active_section = 7;
+
+#endif
+
+    vp8_clear_system_state();  //__asm emms;
+
+    //************************************************
+    // save a copy for later refresh
+    {
+        vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
+    }
+
+    update_coef_probs(cpi);
+
+#ifdef ENTROPY_STATS
+    active_section = 2;
+#endif
+
+    // Write out the mb_no_coeff_skip flag
+    vp8_write_bit(bc, pc->mb_no_coeff_skip);
+
+    if (pc->frame_type == KEY_FRAME)
+    {
+        write_kfmodes(cpi);
+
+#ifdef ENTROPY_STATS
+        active_section = 8;
+#endif
+    }
+    else
+    {
+        pack_inter_mode_mvs(cpi);
+
+#ifdef ENTROPY_STATS
+        active_section = 1;
+#endif
+    }
+
+    vp8_stop_encode(bc);
+
+
+    if (pc->multi_token_partition != ONE_PARTITION)
+    {
+        int num_part;
+        int asize;
+        num_part = 1 << pc->multi_token_partition;
+
+        pack_tokens_into_partitions(cpi, cx_data + bc->pos, num_part, &asize);
+
+        oh.first_partition_length_in_bytes = cpi->bc.pos;
+
+        *size = cpi->bc.pos + VP8_HEADER_SIZE + asize + extra_bytes_packed;
+    }
+    else
+    {
+        vp8_start_encode(&cpi->bc2, cx_data + bc->pos);
+
+        if (!cpi->b_multi_threaded)
+            pack_tokens(&cpi->bc2, cpi->tok, cpi->tok_count);
+        else
+            pack_mb_row_tokens(cpi, &cpi->bc2);
+
+        vp8_stop_encode(&cpi->bc2);
+        oh.first_partition_length_in_bytes = cpi->bc.pos ;
+        *size = cpi->bc2.pos + cpi->bc.pos + VP8_HEADER_SIZE + extra_bytes_packed;
+    }
+
+#if CONFIG_BIG_ENDIAN
+    {
+        int v = (oh.first_partition_length_in_bytes << 5) |
+                (oh.show_frame << 4) |
+                (oh.version << 1) |
+                oh.type;
+
+        v = make_endian_32(v);
+        vpx_memcpy(dest, &v, 3);
+    }
+#else
+    vpx_memcpy(dest, &oh, 3);
+#endif
+}
+
+#ifdef ENTROPY_STATS
+void print_tree_update_probs()
+{
+    int i, j, k, l;
+    FILE *f = fopen("context.c", "a");
+    int Sum;
+    fprintf(f, "\n/* Update probabilities for token entropy tree. */\n\n");
+    fprintf(f, "const vp8_prob tree_update_probs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] = {\n");
+
+    for (i = 0; i < BLOCK_TYPES; i++)
+    {
+        fprintf(f, "  { \n");
+
+        for (j = 0; j < COEF_BANDS; j++)
+        {
+            fprintf(f, "    {\n");
+
+            for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+            {
+                fprintf(f, "      {");
+
+                for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++)
+                {
+                    Sum = tree_update_hist[i][j][k][l][0] + tree_update_hist[i][j][k][l][1];
+
+                    if (Sum > 0)
+                    {
+                        if (((tree_update_hist[i][j][k][l][0] * 255) / Sum) > 0)
+                            fprintf(f, "%3ld, ", (tree_update_hist[i][j][k][l][0] * 255) / Sum);
+                        else
+                            fprintf(f, "%3ld, ", 1);
+                    }
+                    else
+                        fprintf(f, "%3ld, ", 128);
+                }
+
+                fprintf(f, "},\n");
+            }
+
+            fprintf(f, "    },\n");
+        }
+
+        fprintf(f, "  },\n");
+    }
+
+    fprintf(f, "};\n");
+    fclose(f);
+}
+#endif
diff --git a/vp8/encoder/bitstream.h b/vp8/encoder/bitstream.h
new file mode 100644 (file)
index 0000000..ee69f66
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_BITSTREAM_H
+#define __INC_BITSTREAM_H
+
+#if HAVE_ARMV7
+void vp8cx_pack_tokens_armv7(vp8_writer *w, const TOKENEXTRA *p, int xcount,
+                             vp8_token *,
+                             vp8_extra_bit_struct *,
+                             const vp8_tree_index *);
+void vp8cx_pack_tokens_into_partitions_armv7(VP8_COMP *, unsigned char *, int , int *,
+        vp8_token *,
+        vp8_extra_bit_struct *,
+        const vp8_tree_index *);
+void vp8cx_pack_mb_row_tokens_armv7(VP8_COMP *cpi, vp8_writer *w,
+                                    vp8_token *,
+                                    vp8_extra_bit_struct *,
+                                    const vp8_tree_index *);
+# define pack_tokens(a,b,c)                  \
+    vp8cx_pack_tokens_armv7(a,b,c,vp8_coef_encodings,vp8_extra_bits,vp8_coef_tree)
+# define pack_tokens_into_partitions(a,b,c,d)  \
+    vp8cx_pack_tokens_into_partitions_armv7(a,b,c,d,vp8_coef_encodings,vp8_extra_bits,vp8_coef_tree)
+# define pack_mb_row_tokens(a,b)               \
+    vp8cx_pack_mb_row_tokens_armv7(a,b,vp8_coef_encodings,vp8_extra_bits,vp8_coef_tree)
+#else
+# define pack_tokens(a,b,c)                  pack_tokens_c(a,b,c)
+# define pack_tokens_into_partitions(a,b,c,d)  pack_tokens_into_partitions_c(a,b,c,d)
+# define pack_mb_row_tokens(a,b)               pack_mb_row_tokens_c(a,b)
+#endif
+#endif
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
new file mode 100644 (file)
index 0000000..cc4cbe0
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_BLOCK_H
+#define __INC_BLOCK_H
+
+#include "onyx.h"
+#include "blockd.h"
+#include "entropymv.h"
+#include "entropy.h"
+#include "vpx_ports/mem.h"
+
+// motion search site
+typedef struct
+{
+    MV mv;
+    int offset;
+} search_site;
+
+typedef struct
+{
+    // 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries
+    short *src_diff;
+    short *coeff;
+
+    // 16 Y blocks, 4 U blocks, 4 V blocks each with 16 entries
+    short(*quant)[4];
+    short(*zbin)[4];
+    short(*zrun_zbin_boost);
+    short(*round)[4];
+
+    // Zbin Over Quant value
+    short zbin_extra;
+
+    unsigned char **base_src;
+    int src;
+    int src_stride;
+
+//  MV  enc_mv;
+    int force_empty;
+
+} BLOCK;
+
+typedef struct
+{
+    DECLARE_ALIGNED(16, short, src_diff[400]);       // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y
+    DECLARE_ALIGNED(16, short, coeff[400]);     // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y
+
+    // 16 Y blocks, 4 U blocks, 4 V blocks, 1 DC 2nd order block each with 16 entries
+    BLOCK block[25];
+
+    YV12_BUFFER_CONFIG src;
+
+    MACROBLOCKD e_mbd;
+
+    search_site *ss;
+    int ss_count;
+    int searches_per_step;
+
+    int errorperbit;
+    int sadperbit16;
+    int sadperbit4;
+    int errthresh;
+    int rddiv;
+    int rdmult;
+
+    int mvcosts[2][MVvals+1];
+    int *mvcost[2];
+    int mvsadcosts[2][MVvals+1];
+    int *mvsadcost[2];
+    int mbmode_cost[2][MB_MODE_COUNT];
+    int intra_uv_mode_cost[2][MB_MODE_COUNT];
+    unsigned int bmode_costs[10][10][10];
+    unsigned int inter_bmode_costs[B_MODE_COUNT];
+
+    // These define limits to motion vector components to prevent them from extending outside the UMV borders
+    int mv_col_min;
+    int mv_col_max;
+    int mv_row_min;
+    int mv_row_max;
+
+    int vector_range;    // Used to monitor limiting range of recent vectors to guide search.
+    int skip;
+
+    int encode_breakout;
+
+    unsigned char *active_ptr;
+    MV_CONTEXT *mvc;
+
+    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
+    int optimize;
+
+    void (*vp8_short_fdct4x4)(short *input, short *output, int pitch);
+    void (*vp8_short_fdct8x4)(short *input, short *output, int pitch);
+    void (*short_fdct4x4rd)(short *input, short *output, int pitch);
+    void (*short_fdct8x4rd)(short *input, short *output, int pitch);
+    void (*vp8_short_fdct4x4_ptr)(short *input, short *output, int pitch);
+    void (*short_walsh4x4)(short *input, short *output, int pitch);
+
+    void (*quantize_b)(BLOCK *b, BLOCKD *d);
+    void (*quantize_brd)(BLOCK *b, BLOCKD *d);
+
+
+
+} MACROBLOCK;
+
+
+#endif
diff --git a/vp8/encoder/boolhuff.c b/vp8/encoder/boolhuff.c
new file mode 100644 (file)
index 0000000..c101384
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "boolhuff.h"
+#include "blockd.h"
+
+
+
+#if defined(SECTIONBITS_OUTPUT)
+unsigned __int64 Sectionbits[500];
+
+#endif
+
+#ifdef ENTROPY_STATS
+unsigned int active_section = 0;
+#endif
+
+const unsigned int vp8_prob_cost[256] =
+{
+    2047, 2047, 1791, 1641, 1535, 1452, 1385, 1328, 1279, 1235, 1196, 1161, 1129, 1099, 1072, 1046,
+    1023, 1000,  979,  959,  940,  922,  905,  889,  873,  858,  843,  829,  816,  803,  790,  778,
+    767,  755,  744,  733,  723,  713,  703,  693,  684,  675,  666,  657,  649,  641,  633,  625,
+    617,  609,  602,  594,  587,  580,  573,  567,  560,  553,  547,  541,  534,  528,  522,  516,
+    511,  505,  499,  494,  488,  483,  477,  472,  467,  462,  457,  452,  447,  442,  437,  433,
+    428,  424,  419,  415,  410,  406,  401,  397,  393,  389,  385,  381,  377,  373,  369,  365,
+    361,  357,  353,  349,  346,  342,  338,  335,  331,  328,  324,  321,  317,  314,  311,  307,
+    304,  301,  297,  294,  291,  288,  285,  281,  278,  275,  272,  269,  266,  263,  260,  257,
+    255,  252,  249,  246,  243,  240,  238,  235,  232,  229,  227,  224,  221,  219,  216,  214,
+    211,  208,  206,  203,  201,  198,  196,  194,  191,  189,  186,  184,  181,  179,  177,  174,
+    172,  170,  168,  165,  163,  161,  159,  156,  154,  152,  150,  148,  145,  143,  141,  139,
+    137,  135,  133,  131,  129,  127,  125,  123,  121,  119,  117,  115,  113,  111,  109,  107,
+    105,  103,  101,   99,   97,   95,   93,   92,   90,   88,   86,   84,   82,   81,   79,   77,
+    75,   73,   72,   70,   68,   66,   65,   63,   61,   60,   58,   56,   55,   53,   51,   50,
+    48,   46,   45,   43,   41,   40,   38,   37,   35,   33,   32,   30,   29,   27,   25,   24,
+    22,   21,   19,   18,   16,   15,   13,   12,   10,    9,    7,    6,    4,    3,    1,   1
+};
+
+void vp8_start_encode(BOOL_CODER *br, unsigned char *source)
+{
+
+    br->lowvalue = 0;
+    br->range    = 255;
+    br->value    = 0;
+    br->count    = -24;
+    br->buffer   = source;
+    br->pos      = 0;
+}
+
+void vp8_stop_encode(BOOL_CODER *br)
+{
+    int i;
+
+    for (i = 0; i < 32; i++)
+        vp8_encode_bool(br, 0, 128);
+}
+
+DECLARE_ALIGNED(16, static const unsigned int, norm[256]) =
+{
+    0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void vp8_encode_bool(BOOL_CODER *br, int bit, int probability)
+{
+    unsigned int split;
+    int count = br->count;
+    unsigned int range = br->range;
+    unsigned int lowvalue = br->lowvalue;
+    register unsigned int shift;
+
+#ifdef ENTROPY_STATS
+#if defined(SECTIONBITS_OUTPUT)
+
+    if (bit)
+        Sectionbits[active_section] += vp8_prob_cost[255-probability];
+    else
+        Sectionbits[active_section] += vp8_prob_cost[probability];
+
+#endif
+#endif
+
+    split = 1 + (((range - 1) * probability) >> 8);
+
+    range = split;
+
+    if (bit)
+    {
+        lowvalue += split;
+        range = br->range - split;
+    }
+
+    shift = norm[range];
+
+    range <<= shift;
+    count += shift;
+
+    if (count >= 0)
+    {
+        int offset = shift - count;
+
+        if ((lowvalue << (offset - 1)) & 0x80000000)
+        {
+            int x = br->pos - 1;
+
+            while (x >= 0 && br->buffer[x] == 0xff)
+            {
+                br->buffer[x] = (unsigned char)0;
+                x--;
+            }
+
+            br->buffer[x] += 1;
+        }
+
+        br->buffer[br->pos++] = (lowvalue >> (24 - offset));
+        lowvalue <<= offset;
+        shift = count;
+        lowvalue &= 0xffffff;
+        count -= 8 ;
+    }
+
+    lowvalue <<= shift;
+    br->count = count;
+    br->lowvalue = lowvalue;
+    br->range = range;
+}
+
+void vp8_encode_value(BOOL_CODER *br, int data, int bits)
+{
+    int bit;
+
+    for (bit = bits - 1; bit >= 0; bit--)
+        vp8_encode_bool(br, (1 & (data >> bit)), 0x80);
+
+}
diff --git a/vp8/encoder/boolhuff.h b/vp8/encoder/boolhuff.h
new file mode 100644 (file)
index 0000000..0d929f0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     boolhuff.h
+*
+*   Description  :     Bool Coder header file.
+*
+****************************************************************************/
+#ifndef __INC_BOOLHUFF_H
+#define __INC_BOOLHUFF_H
+
+
+typedef struct
+{
+    unsigned int lowvalue;
+    unsigned int range;
+    unsigned int value;
+    int count;
+    unsigned int pos;
+    unsigned char *buffer;
+
+    // Variables used to track bit costs without outputing to the bitstream
+    unsigned int  measure_cost;
+    unsigned long bit_counter;
+} BOOL_CODER;
+
+extern void vp8_start_encode(BOOL_CODER *bc, unsigned char *buffer);
+extern void vp8_encode_bool(BOOL_CODER *bc, int x, int context);
+extern void vp8_encode_value(BOOL_CODER *br, int data, int bits);
+extern void vp8_stop_encode(BOOL_CODER *bc);
+extern const unsigned int vp8_prob_cost[256];
+
+#endif
diff --git a/vp8/encoder/dct.c b/vp8/encoder/dct.c
new file mode 100644 (file)
index 0000000..5207e39
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <math.h>
+
+
+static const short dct_matrix2[4][4] =
+{
+    { 23170,  30274,  23170, 12540 },
+    { 23170,  12540, -23170, -30274 },
+    { 23170, -12540, -23170, 30274 },
+    { 23170, -30274,  23170, -12540 }
+};
+
+static const short dct_matrix1[4][4] =
+{
+    { 23170,  23170,  23170,  23170 },
+    { 30274,  12540, -12540, -30274 },
+    { 23170, -23170, -23170,  23170 },
+    { 12540, -30274,  30274, -12540 }
+};
+
+
+#define _1STSTAGESHIFT           14
+#define _1STSTAGEROUNDING        (1<<( _1STSTAGESHIFT-1))
+#define _2NDSTAGESHIFT           16
+#define _2NDSTAGEROUNDING        (1<<( _2NDSTAGESHIFT-1))
+
+// using matrix multiply
+void vp8_short_fdct4x4_c(short *input, short *output, int pitch)
+{
+    int i, j, k;
+    short temp[4][4];
+    int sumtemp;
+    pitch >>= 1;
+
+    for (i = 0; i < 4; i++)
+    {
+        for (j = 0; j < 4; j++)
+        {
+            sumtemp = 0;
+
+            for (k = 0; k < 4; k++)
+            {
+                sumtemp += input[i*pitch+k] * dct_matrix2[k][j];
+
+            }
+
+            temp[i][j] = (short)((sumtemp + _1STSTAGEROUNDING) >> _1STSTAGESHIFT);
+        }
+    }
+
+
+    for (i = 0; i < 4; i++)
+    {
+        for (j = 0; j < 4; j++)
+        {
+            sumtemp = 0;
+
+            for (k = 0; k < 4; k++)
+            {
+                sumtemp += dct_matrix1[i][ k] * temp[k][ j];
+            }
+
+            output[i*4+j] = (short)((sumtemp + _2NDSTAGEROUNDING) >> _2NDSTAGESHIFT);
+        }
+    }
+
+}
+
+
+void vp8_short_fdct8x4_c(short *input, short *output, int pitch)
+{
+    vp8_short_fdct4x4_c(input,   output,    pitch);
+    vp8_short_fdct4x4_c(input + 4, output + 16, pitch);
+}
+
+
+static const signed short x_c1 = 60547;
+static const signed short x_c2 = 46341;
+static const signed short x_c3 = 25080;
+
+void vp8_fast_fdct4x4_c(short *input, short *output, int pitch)
+{
+    int i;
+    int a1, b1, c1, d1;
+    int a2, b2, c2, d2;
+    short *ip = input;
+
+    short *op = output;
+    int temp1, temp2;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = (ip[0] + ip[3]) * 2;
+        b1 = (ip[1] + ip[2]) * 2;
+        c1 = (ip[1] - ip[2]) * 2;
+        d1 = (ip[0] - ip[3]) * 2;
+
+        temp1 = a1 + b1;
+        temp2 = a1 - b1;
+
+        op[0] = ((temp1 * x_c2) >> 16) + temp1;
+        op[2] = ((temp2 * x_c2) >> 16) + temp2;
+
+        temp1 = (c1 * x_c3) >> 16;
+        temp2 = ((d1 * x_c1) >> 16) + d1;
+
+        op[1] = temp1 + temp2;
+
+        temp1 = (d1 * x_c3) >> 16;
+        temp2 = ((c1 * x_c1) >> 16) + c1;
+
+        op[3] = temp1 - temp2;
+
+        ip += pitch / 2;
+        op += 4;
+    }
+
+    ip = output;
+    op = output;
+
+    for (i = 0; i < 4; i++)
+    {
+
+        a1 = ip[0] + ip[12];
+        b1 = ip[4] + ip[8];
+        c1 = ip[4] - ip[8];
+        d1 = ip[0] - ip[12];
+
+
+        temp1 = a1 + b1;
+        temp2 = a1 - b1;
+
+        a2 = ((temp1 * x_c2) >> 16) + temp1;
+        c2 = ((temp2 * x_c2) >> 16) + temp2;
+
+        temp1 = (c1 * x_c3) >> 16;
+        temp2 = ((d1 * x_c1) >> 16) + d1;
+
+        b2 = temp1 + temp2;
+
+        temp1 = (d1 * x_c3) >> 16;
+        temp2 = ((c1 * x_c1) >> 16) + c1;
+
+        d2 = temp1 - temp2;
+
+
+        op[0]   = (a2 + 1) >> 1;
+        op[4]   = (b2 + 1) >> 1;
+        op[8]   = (c2 + 1) >> 1;
+        op[12]  = (d2 + 1) >> 1;
+
+        ip++;
+        op++;
+    }
+}
+
+void vp8_fast_fdct8x4_c(short *input, short *output, int pitch)
+{
+    vp8_fast_fdct4x4_c(input,   output,    pitch);
+    vp8_fast_fdct4x4_c(input + 4, output + 16, pitch);
+}
+
+void vp8_short_walsh4x4_c(short *input, short *output, int pitch)
+{
+    int i;
+    int a1, b1, c1, d1;
+    int a2, b2, c2, d2;
+    short *ip = input;
+    short *op = output;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = ip[0] + ip[3];
+        b1 = ip[1] + ip[2];
+        c1 = ip[1] - ip[2];
+        d1 = ip[0] - ip[3];
+
+        op[0] = a1 + b1;
+        op[1] = c1 + d1;
+        op[2] = a1 - b1;
+        op[3] = d1 - c1;
+        ip += pitch / 2;
+        op += 4;
+    }
+
+    ip = output;
+    op = output;
+
+    for (i = 0; i < 4; i++)
+    {
+        a1 = ip[0] + ip[12];
+        b1 = ip[4] + ip[8];
+        c1 = ip[4] - ip[8];
+        d1 = ip[0] - ip[12];
+
+        a2 = a1 + b1;
+        b2 = c1 + d1;
+        c2 = a1 - b1;
+        d2 = d1 - c1;
+
+        a2 += (a2 > 0);
+        b2 += (b2 > 0);
+        c2 += (c2 > 0);
+        d2 += (d2 > 0);
+
+        op[0] = (a2) >> 1;
+        op[4] = (b2) >> 1;
+        op[8] = (c2) >> 1;
+        op[12] = (d2) >> 1;
+
+        ip++;
+        op++;
+    }
+}
diff --git a/vp8/encoder/dct.h b/vp8/encoder/dct.h
new file mode 100644 (file)
index 0000000..fb307cf
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_DCT_H
+#define __INC_DCT_H
+
+#define prototype_fdct(sym) void (sym)(short *input, short *output, int pitch)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/dct_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/dct_arm.h"
+#endif
+
+#ifndef vp8_fdct_short4x4
+#define vp8_fdct_short4x4  vp8_short_fdct4x4_c
+#endif
+extern prototype_fdct(vp8_fdct_short4x4);
+
+#ifndef vp8_fdct_short8x4
+#define vp8_fdct_short8x4  vp8_short_fdct8x4_c
+#endif
+extern prototype_fdct(vp8_fdct_short8x4);
+
+#ifndef vp8_fdct_fast4x4
+#define vp8_fdct_fast4x4  vp8_fast_fdct4x4_c
+#endif
+extern prototype_fdct(vp8_fdct_fast4x4);
+
+#ifndef vp8_fdct_fast8x4
+#define vp8_fdct_fast8x4  vp8_fast_fdct8x4_c
+#endif
+extern prototype_fdct(vp8_fdct_fast8x4);
+
+#ifndef vp8_fdct_walsh_short4x4
+#define vp8_fdct_walsh_short4x4  vp8_short_walsh4x4_c
+#endif
+extern prototype_fdct(vp8_fdct_walsh_short4x4);
+
+typedef prototype_fdct(*vp8_fdct_fn_t);
+typedef struct
+{
+    vp8_fdct_fn_t    short4x4;
+    vp8_fdct_fn_t    short8x4;
+    vp8_fdct_fn_t    fast4x4;
+    vp8_fdct_fn_t    fast8x4;
+    vp8_fdct_fn_t    walsh_short4x4;
+} vp8_fdct_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define FDCT_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define FDCT_INVOKE(ctx,fn) vp8_fdct_##fn
+#endif
+
+#endif
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
new file mode 100644 (file)
index 0000000..a4e3772
--- /dev/null
@@ -0,0 +1,1223 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "encodemb.h"
+#include "encodemv.h"
+#include "common.h"
+#include "onyx_int.h"
+#include "extend.h"
+#include "entropymode.h"
+#include "quant_common.h"
+#include "segmentation_common.h"
+#include "setupintrarecon.h"
+#include "encodeintra.h"
+#include "reconinter.h"
+#include "rdopt.h"
+#include "pickinter.h"
+#include "findnearmv.h"
+#include "reconintra.h"
+#include <stdio.h>
+#include <limits.h>
+#include "subpixel.h"
+#include "vpx_ports/vpx_timer.h"
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define RTCD(x)     &cpi->common.rtcd.x
+#define IF_RTCD(x)  (x)
+#else
+#define RTCD(x)     NULL
+#define IF_RTCD(x)  NULL
+#endif
+extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
+
+extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex);
+extern void vp8_auto_select_speed(VP8_COMP *cpi);
+extern void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
+                                      MACROBLOCK *x,
+                                      MB_ROW_COMP *mbr_ei,
+                                      int mb_row,
+                                      int count);
+void vp8_build_block_offsets(MACROBLOCK *x);
+void vp8_setup_block_ptrs(MACROBLOCK *x);
+int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int recon_yoffset, int recon_uvoffset);
+int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
+
+#ifdef MODE_STATS
+unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned int inter_uv_modes[4] = {0, 0, 0, 0};
+unsigned int inter_b_modes[15]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned int y_modes[5]   = {0, 0, 0, 0, 0};
+unsigned int uv_modes[4]  = {0, 0, 0, 0};
+unsigned int b_modes[14]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+#endif
+
+// The first four entries are dummy values
+static const int qrounding_factors[129] =
+{
+    56, 56, 56, 56, 56, 56, 56, 56,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48, 48, 48, 48, 48, 48, 48, 48,
+    48,
+};
+
+static const int qzbin_factors[129] =
+{
+    64, 64, 64, 64, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80,
+    80,
+};
+
+void vp8cx_init_quantizer(VP8_COMP *cpi)
+{
+    int r, c;
+    int i;
+    int quant_val;
+    int Q;
+
+    int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44};
+
+    for (Q = 0; Q < QINDEX_RANGE; Q++)
+    {
+        // dc values
+        quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
+        cpi->Y1quant[Q][0][0] = (1 << 16) / quant_val;
+        cpi->Y1zbin[Q][0][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
+        cpi->Y1round[Q][0][0] = (qrounding_factors[Q] * quant_val) >> 7;
+        cpi->common.Y1dequant[Q][0][0] = quant_val;
+        cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
+
+        quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
+        cpi->Y2quant[Q][0][0] = (1 << 16) / quant_val;
+        cpi->Y2zbin[Q][0][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
+        cpi->Y2round[Q][0][0] = (qrounding_factors[Q] * quant_val) >> 7;
+        cpi->common.Y2dequant[Q][0][0] = quant_val;
+        cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
+
+        quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
+        cpi->UVquant[Q][0][0] = (1 << 16) / quant_val;
+        cpi->UVzbin[Q][0][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
+        cpi->UVround[Q][0][0] = (qrounding_factors[Q] * quant_val) >> 7;
+        cpi->common.UVdequant[Q][0][0] = quant_val;
+        cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
+
+        // all the ac values = ;
+        for (i = 1; i < 16; i++)
+        {
+            int rc = vp8_default_zig_zag1d[i];
+            r = (rc >> 2);
+            c = (rc & 3);
+
+            quant_val = vp8_ac_yquant(Q);
+            cpi->Y1quant[Q][r][c] = (1 << 16) / quant_val;
+            cpi->Y1zbin[Q][r][c] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
+            cpi->Y1round[Q][r][c] = (qrounding_factors[Q] * quant_val) >> 7;
+            cpi->common.Y1dequant[Q][r][c] = quant_val;
+            cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
+
+            quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
+            cpi->Y2quant[Q][r][c] = (1 << 16) / quant_val;
+            cpi->Y2zbin[Q][r][c] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
+            cpi->Y2round[Q][r][c] = (qrounding_factors[Q] * quant_val) >> 7;
+            cpi->common.Y2dequant[Q][r][c] = quant_val;
+            cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
+
+            quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
+            cpi->UVquant[Q][r][c] = (1 << 16) / quant_val;
+            cpi->UVzbin[Q][r][c] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
+            cpi->UVround[Q][r][c] = (qrounding_factors[Q] * quant_val) >> 7;
+            cpi->common.UVdequant[Q][r][c] = quant_val;
+            cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7;
+        }
+    }
+}
+
+void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x)
+{
+    int i;
+    int QIndex;
+    MACROBLOCKD *xd = &x->e_mbd;
+    MB_MODE_INFO *mbmi = &xd->mbmi;
+    int zbin_extra;
+
+    // Select the baseline MB Q index.
+    if (xd->segmentation_enabled)
+    {
+        // Abs Value
+        if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
+            QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id];
+
+        // Delta Value
+        else
+        {
+            QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id];
+            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;    // Clamp to valid range
+        }
+    }
+    else
+        QIndex = cpi->common.base_qindex;
+
+    // Y
+    zbin_extra = (cpi->common.Y1dequant[QIndex][0][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
+
+    for (i = 0; i < 16; i++)
+    {
+        x->block[i].quant = cpi->Y1quant[QIndex];
+        x->block[i].zbin = cpi->Y1zbin[QIndex];
+        x->block[i].round = cpi->Y1round[QIndex];
+        x->e_mbd.block[i].dequant = cpi->common.Y1dequant[QIndex];
+        x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
+        x->block[i].zbin_extra = (short)zbin_extra;
+    }
+
+    // UV
+    zbin_extra = (cpi->common.UVdequant[QIndex][0][1] * (cpi->zbin_over_quant + cpi->zbin_mode_boost)) >> 7;
+
+    for (i = 16; i < 24; i++)
+    {
+        x->block[i].quant = cpi->UVquant[QIndex];
+        x->block[i].zbin = cpi->UVzbin[QIndex];
+        x->block[i].round = cpi->UVround[QIndex];
+        x->e_mbd.block[i].dequant = cpi->common.UVdequant[QIndex];
+        x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
+        x->block[i].zbin_extra = (short)zbin_extra;
+    }
+
+    // Y2
+    zbin_extra = (cpi->common.Y2dequant[QIndex][0][1] * ((cpi->zbin_over_quant / 2) + cpi->zbin_mode_boost)) >> 7;
+    x->block[24].quant = cpi->Y2quant[QIndex];
+    x->block[24].zbin = cpi->Y2zbin[QIndex];
+    x->block[24].round = cpi->Y2round[QIndex];
+    x->e_mbd.block[24].dequant = cpi->common.Y2dequant[QIndex];
+    x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
+    x->block[24].zbin_extra = (short)zbin_extra;
+}
+
+void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
+{
+    // vp8cx_init_quantizer() is first called in vp8_create_compressor(). A check is added here so that vp8cx_init_quantizer() is only called
+    // when these values are not all zero.
+    if (cpi->common.y1dc_delta_q | cpi->common.y2dc_delta_q | cpi->common.uvdc_delta_q | cpi->common.y2ac_delta_q | cpi->common.uvac_delta_q)
+    {
+        vp8cx_init_quantizer(cpi);
+    }
+
+    // MB level quantizer setup
+    vp8cx_mb_init_quantizer(cpi, &cpi->mb);
+}
+
+
+
+static
+void encode_mb_row(VP8_COMP *cpi,
+                   VP8_COMMON *cm,
+                   int mb_row,
+                   MACROBLOCK  *x,
+                   MACROBLOCKD *xd,
+                   TOKENEXTRA **tp,
+                   int *segment_counts,
+                   int *totalrate)
+{
+    int i;
+    int recon_yoffset, recon_uvoffset;
+    int mb_col;
+    int recon_y_stride = cm->last_frame.y_stride;
+    int recon_uv_stride = cm->last_frame.uv_stride;
+    int seg_map_index = (mb_row * cpi->common.mb_cols);
+
+
+    // reset above block coeffs
+    xd->above_context[Y1CONTEXT] = cm->above_context[Y1CONTEXT];
+    xd->above_context[UCONTEXT ] = cm->above_context[UCONTEXT ];
+    xd->above_context[VCONTEXT ] = cm->above_context[VCONTEXT ];
+    xd->above_context[Y2CONTEXT] = cm->above_context[Y2CONTEXT];
+
+    xd->up_available = (mb_row != 0);
+    recon_yoffset = (mb_row * recon_y_stride * 16);
+    recon_uvoffset = (mb_row * recon_uv_stride * 8);
+
+    cpi->tplist[mb_row].start = *tp;
+    //printf("Main mb_row = %d\n", mb_row);
+
+    // for each macroblock col in image
+    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+    {
+        // Distance of Mb to the various image edges.
+        // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
+        xd->mb_to_left_edge = -((mb_col * 16) << 3);
+        xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
+        xd->mb_to_top_edge = -((mb_row * 16) << 3);
+        xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
+
+        // Set up limit values for motion vectors used to prevent them extending outside the UMV borders
+        x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
+        x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
+        x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
+        x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);
+
+        xd->dst.y_buffer = cm->new_frame.y_buffer + recon_yoffset;
+        xd->dst.u_buffer = cm->new_frame.u_buffer + recon_uvoffset;
+        xd->dst.v_buffer = cm->new_frame.v_buffer + recon_uvoffset;
+        xd->left_available = (mb_col != 0);
+
+        // Is segmentation enabled
+        // MB level adjutment to quantizer
+        if (xd->segmentation_enabled)
+        {
+            // Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
+            if (cpi->segmentation_map[seg_map_index+mb_col] <= 3)
+                xd->mbmi.segment_id = cpi->segmentation_map[seg_map_index+mb_col];
+            else
+                xd->mbmi.segment_id = 0;
+
+            vp8cx_mb_init_quantizer(cpi, x);
+        }
+        else
+            xd->mbmi.segment_id = 0;         // Set to Segment 0 by default
+
+        x->active_ptr = cpi->active_map + seg_map_index + mb_col;
+
+        if (cm->frame_type == KEY_FRAME)
+        {
+            *totalrate += vp8cx_encode_intra_macro_block(cpi, x, tp);
+#ifdef MODE_STATS
+            y_modes[xd->mbmi.mode] ++;
+#endif
+        }
+        else
+        {
+            *totalrate += vp8cx_encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset);
+
+#ifdef MODE_STATS
+            inter_y_modes[xd->mbmi.mode] ++;
+
+            if (xd->mbmi.mode == SPLITMV)
+            {
+                int b;
+
+                for (b = 0; b < xd->mbmi.partition_count; b++)
+                {
+                    inter_b_modes[xd->mbmi.partition_bmi[b].mode] ++;
+                }
+            }
+
+#endif
+
+            // Count of last ref frame 0,0 useage
+            if ((xd->mbmi.mode == ZEROMV) && (xd->mbmi.ref_frame == LAST_FRAME))
+                cpi->inter_zz_count ++;
+
+            // Special case code for cyclic refresh
+            // If cyclic update enabled then copy xd->mbmi.segment_id; (which may have been updated based on mode
+            // during vp8cx_encode_inter_macroblock()) back into the global sgmentation map
+            if (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)
+            {
+                cpi->segmentation_map[seg_map_index+mb_col] = xd->mbmi.segment_id;
+
+                // If the block has been refreshed mark it as clean (the magnitude of the -ve influences how long it will be before we consider another refresh):
+                // Else if it was coded (last frame 0,0) and has not already been refreshed then mark it as a candidate for cleanup next time (marked 0)
+                // else mark it as dirty (1).
+                if (xd->mbmi.segment_id)
+                    cpi->cyclic_refresh_map[seg_map_index+mb_col] = -1;
+                else if ((xd->mbmi.mode == ZEROMV) && (xd->mbmi.ref_frame == LAST_FRAME))
+                {
+                    if (cpi->cyclic_refresh_map[seg_map_index+mb_col] == 1)
+                        cpi->cyclic_refresh_map[seg_map_index+mb_col] = 0;
+                }
+                else
+                    cpi->cyclic_refresh_map[seg_map_index+mb_col] = 1;
+
+            }
+        }
+
+        cpi->tplist[mb_row].stop = *tp;
+
+        xd->gf_active_ptr++;      // Increment pointer into gf useage flags structure for next mb
+
+        // store macroblock mode info into context array
+        vpx_memcpy(&xd->mode_info_context->mbmi, &xd->mbmi, sizeof(xd->mbmi));
+
+        for (i = 0; i < 16; i++)
+            vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
+
+        // adjust to the next column of macroblocks
+        x->src.y_buffer += 16;
+        x->src.u_buffer += 8;
+        x->src.v_buffer += 8;
+
+        recon_yoffset += 16;
+        recon_uvoffset += 8;
+
+        // Keep track of segment useage
+        segment_counts[xd->mbmi.segment_id] ++;
+
+        // skip to next mb
+        xd->mode_info_context++;
+
+        xd->above_context[Y1CONTEXT] += 4;
+        xd->above_context[UCONTEXT ] += 2;
+        xd->above_context[VCONTEXT ] += 2;
+        xd->above_context[Y2CONTEXT] ++;
+        cpi->current_mb_col_main = mb_col;
+    }
+
+    //extend the recon for intra prediction
+    vp8_extend_mb_row(
+        &cm->new_frame,
+        xd->dst.y_buffer + 16,
+        xd->dst.u_buffer + 8,
+        xd->dst.v_buffer + 8);
+
+    // this is to account for the border
+    xd->mode_info_context++;
+}
+
+
+
+
+
+void vp8_encode_frame(VP8_COMP *cpi)
+{
+    int mb_row;
+    MACROBLOCK *const x = & cpi->mb;
+    VP8_COMMON *const cm = & cpi->common;
+    MACROBLOCKD *const xd = & x->e_mbd;
+
+    int i;
+    TOKENEXTRA *tp = cpi->tok;
+    int segment_counts[MAX_MB_SEGMENTS];
+    int totalrate;
+
+    if (cm->frame_type != KEY_FRAME)
+    {
+        if (cm->mcomp_filter_type == SIXTAP)
+        {
+            xd->subpixel_predict     = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, sixtap4x4);
+            xd->subpixel_predict8x4      = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, sixtap8x4);
+            xd->subpixel_predict8x8      = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, sixtap8x8);
+            xd->subpixel_predict16x16    = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, sixtap16x16);
+        }
+        else
+        {
+            xd->subpixel_predict     = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, bilinear4x4);
+            xd->subpixel_predict8x4      = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, bilinear8x4);
+            xd->subpixel_predict8x8      = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, bilinear8x8);
+            xd->subpixel_predict16x16    = SUBPIX_INVOKE(&cpi->common.rtcd.subpix, bilinear16x16);
+        }
+    }
+
+    //else  // Key Frame
+    //{
+    // For key frames make sure the intra ref frame probability value
+    // is set to "all intra"
+    //cpi->prob_intra_coded = 255;
+    //}
+
+
+    xd->gf_active_ptr = (signed char *)cm->gf_active_flags;     // Point to base of GF active flags data structure
+
+    x->vector_range = 32;
+
+    // Count of MBs using the alternate Q if any
+    cpi->alt_qcount = 0;
+
+    // Reset frame count of inter 0,0 motion vector useage.
+    cpi->inter_zz_count = 0;
+
+    vpx_memset(segment_counts, 0, sizeof(segment_counts));
+
+    cpi->prediction_error = 0;
+    cpi->intra_error = 0;
+    cpi->skip_true_count = 0;
+    cpi->skip_false_count = 0;
+
+#if 0
+    // Experimental code
+    cpi->frame_distortion = 0;     
+    cpi->last_mb_distortion = 0;
+#endif
+
+    totalrate = 0;
+
+    xd->mode_info = cm->mi - 1;
+
+    xd->mode_info_context = cm->mi;
+    xd->mode_info_stride = cm->mode_info_stride;
+
+    xd->frame_type = cm->frame_type;
+
+    xd->frames_since_golden = cm->frames_since_golden;
+    xd->frames_till_alt_ref_frame = cm->frames_till_alt_ref_frame;
+    vp8_zero(cpi->MVcount);
+    // vp8_zero( Contexts)
+    vp8_zero(cpi->coef_counts);
+
+    // reset intra mode contexts
+    if (cm->frame_type == KEY_FRAME)
+        vp8_init_mbmode_probs(cm);
+
+
+    vp8cx_frame_init_quantizer(cpi);
+
+    if (cpi->compressor_speed == 2)
+    {
+        if (cpi->oxcf.cpu_used < 0)
+            cpi->Speed = -(cpi->oxcf.cpu_used);
+        else
+            vp8_auto_select_speed(cpi);
+    }
+
+    vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
+    //vp8_initialize_rd_consts( cpi, vp8_dc_quant(cpi->avg_frame_qindex, cm->y1dc_delta_q) );
+    vp8cx_initialize_me_consts(cpi, cm->base_qindex);
+    //vp8cx_initialize_me_consts( cpi, cpi->avg_frame_qindex);
+
+    // Copy data over into macro block data sturctures.
+
+    x->src = * cpi->Source;
+    xd->pre = cm->last_frame;
+    xd->dst = cm->new_frame;
+
+    // set up frame new frame for intra coded blocks
+
+    vp8_setup_intra_recon(&cm->new_frame);
+
+    vp8_build_block_offsets(x);
+
+    vp8_setup_block_dptrs(&x->e_mbd);
+
+    vp8_setup_block_ptrs(x);
+
+    x->rddiv = cpi->RDDIV;
+    x->rdmult = cpi->RDMULT;
+
+#if 0
+    // Experimental rd code
+    // 2 Pass - Possibly set Rdmult based on last frame distortion + this frame target bits or other metrics
+    // such as cpi->rate_correction_factor that indicate relative complexity.
+    /*if ( cpi->pass == 2 && (cpi->last_frame_distortion > 0) && (cpi->target_bits_per_mb > 0) )
+    {
+        //x->rdmult = ((cpi->last_frame_distortion * 256)/cpi->common.MBs)/ cpi->target_bits_per_mb;
+        x->rdmult = (int)(cpi->RDMULT * cpi->rate_correction_factor);
+    }
+    else
+        x->rdmult = cpi->RDMULT; */
+    //x->rdmult = (int)(cpi->RDMULT * pow( (cpi->rate_correction_factor * 2.0), 0.75 ));
+#endif
+
+    xd->mbmi.mode = DC_PRED;
+    xd->mbmi.uv_mode = DC_PRED;
+
+    xd->left_context = cm->left_context;
+
+    vp8_zero(cpi->count_mb_ref_frame_usage)
+    vp8_zero(cpi->ymode_count)
+    vp8_zero(cpi->uv_mode_count)
+
+    x->mvc = cm->fc.mvc;
+
+    // vp8_zero( entropy_stats)
+    {
+        ENTROPY_CONTEXT **p = cm->above_context;
+        const size_t L = cm->mb_cols;
+
+        vp8_zero_array(p [Y1CONTEXT], L * 4)
+        vp8_zero_array(p [ UCONTEXT], L * 2)
+        vp8_zero_array(p [ VCONTEXT], L * 2)
+        vp8_zero_array(p [Y2CONTEXT], L)
+    }
+
+
+    {
+        struct vpx_usec_timer  emr_timer;
+        vpx_usec_timer_start(&emr_timer);
+
+        if (!cpi->b_multi_threaded)
+        {
+            // for each macroblock row in image
+            for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+            {
+
+                vp8_zero(cm->left_context)
+
+                encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
+
+                // adjust to the next row of mbs
+                x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
+                x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
+                x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
+            }
+
+            cpi->tok_count = tp - cpi->tok;
+
+        }
+        else
+        {
+#if CONFIG_MULTITHREAD
+            vp8cx_init_mbrthread_data(cpi, x, cpi->mb_row_ei, 1,  cpi->encoding_thread_count);
+
+            for (mb_row = 0; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
+            {
+                int i;
+                cpi->current_mb_col_main = -1;
+
+                for (i = 0; i < cpi->encoding_thread_count; i++)
+                {
+                    if ((mb_row + i + 1) >= cm->mb_rows)
+                        break;
+
+                    cpi->mb_row_ei[i].mb_row = mb_row + i + 1;
+                    cpi->mb_row_ei[i].tp  = cpi->tok + (mb_row + i + 1) * (cm->mb_cols * 16 * 24);
+                    cpi->mb_row_ei[i].current_mb_col = -1;
+                    //SetEvent(cpi->h_event_mbrencoding[i]);
+                    sem_post(&cpi->h_event_mbrencoding[i]);
+                }
+
+                vp8_zero(cm->left_context)
+
+                tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);
+
+                encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
+
+                // adjust to the next row of mbs
+                x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
+                x->src.u_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
+                x->src.v_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
+
+                xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
+
+                if (mb_row < cm->mb_rows - 1)
+                    //WaitForSingleObject(cpi->h_event_main, INFINITE);
+                    sem_wait(&cpi->h_event_main);
+            }
+
+            /*
+            for( ;mb_row<cm->mb_rows; mb_row ++)
+            {
+            vp8_zero( cm->left_context)
+
+            tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);
+
+            encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
+            // adjust to the next row of mbs
+            x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
+            x->src.u_buffer +=  8 * x->src.uv_stride - 8 * cm->mb_cols;
+            x->src.v_buffer +=  8 * x->src.uv_stride - 8 * cm->mb_cols;
+
+            }
+            */
+            cpi->tok_count = 0;
+
+            for (mb_row = 0; mb_row < cm->mb_rows; mb_row ++)
+            {
+                cpi->tok_count += cpi->tplist[mb_row].stop - cpi->tplist[mb_row].start;
+            }
+
+            if (xd->segmentation_enabled)
+            {
+
+                int i, j;
+
+                if (xd->segmentation_enabled)
+                {
+
+                    for (i = 0; i < cpi->encoding_thread_count; i++)
+                    {
+                        for (j = 0; j < 4; j++)
+                            segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
+                    }
+                }
+
+            }
+
+            for (i = 0; i < cpi->encoding_thread_count; i++)
+            {
+                totalrate += cpi->mb_row_ei[i].totalrate;
+            }
+
+#endif
+
+        }
+
+        vpx_usec_timer_mark(&emr_timer);
+        cpi->time_encode_mb_row += vpx_usec_timer_elapsed(&emr_timer);
+
+    }
+
+
+    // Work out the segment probabilites if segmentation is enabled
+    if (xd->segmentation_enabled)
+    {
+        int tot_count;
+        int i;
+
+        // Set to defaults
+        vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
+
+        tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
+
+        if (tot_count)
+        {
+            xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;
+
+            tot_count = segment_counts[0] + segment_counts[1];
+
+            if (tot_count > 0)
+            {
+                xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
+            }
+
+            tot_count = segment_counts[2] + segment_counts[3];
+
+            if (tot_count > 0)
+                xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
+
+            // Zero probabilities not allowed
+            for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
+            {
+                if (xd->mb_segment_tree_probs[i] == 0)
+                    xd->mb_segment_tree_probs[i] = 1;
+            }
+        }
+    }
+
+    // 256 rate units to the bit
+    cpi->projected_frame_size = totalrate >> 8;   // projected_frame_size in units of BYTES
+
+    // Make a note of the percentage MBs coded Intra.
+    if (cm->frame_type == KEY_FRAME)
+    {
+        cpi->this_frame_percent_intra = 100;
+    }
+    else
+    {
+        int tot_modes;
+
+        tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
+                    + cpi->count_mb_ref_frame_usage[LAST_FRAME]
+                    + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
+                    + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
+
+        if (tot_modes)
+            cpi->this_frame_percent_intra = cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;
+
+    }
+
+#if 0
+    {
+        int cnt = 0;
+        int flag[2] = {0, 0};
+
+        for (cnt = 0; cnt < MVPcount; cnt++)
+        {
+            if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
+            {
+                flag[0] = 1;
+                vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
+                break;
+            }
+        }
+
+        for (cnt = 0; cnt < MVPcount; cnt++)
+        {
+            if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
+            {
+                flag[1] = 1;
+                vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
+                break;
+            }
+        }
+
+        if (flag[0] || flag[1])
+            vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
+    }
+#endif
+
+    // Adjust the projected reference frame useage probability numbers to reflect
+    // what we have just seen. This may be usefull when we make multiple itterations
+    // of the recode loop rather than continuing to use values from the previous frame.
+    if ((cm->frame_type != KEY_FRAME) && !cm->refresh_alt_ref_frame && !cm->refresh_golden_frame)
+    {
+        const int *const rfct = cpi->count_mb_ref_frame_usage;
+        const int rf_intra = rfct[INTRA_FRAME];
+        const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
+
+        if ((rf_intra + rf_inter) > 0)
+        {
+            cpi->prob_intra_coded = (rf_intra * 255) / (rf_intra + rf_inter);
+
+            if (cpi->prob_intra_coded < 1)
+                cpi->prob_intra_coded = 1;
+
+            if ((cm->frames_since_golden > 0) || cpi->source_alt_ref_active)
+            {
+                cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+
+                if (cpi->prob_last_coded < 1)
+                    cpi->prob_last_coded = 1;
+
+                cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+                                     ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+                if (cpi->prob_gf_coded < 1)
+                    cpi->prob_gf_coded = 1;
+            }
+        }
+    }
+
+#if 0
+    // Keep record of the total distortion this time around for future use
+    cpi->last_frame_distortion = cpi->frame_distortion;
+#endif
+
+}
+void vp8_setup_block_ptrs(MACROBLOCK *x)
+{
+    int r, c;
+    int i;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 4; c++)
+        {
+            x->block[r*4+c].src_diff = x->src_diff + r * 4 * 16 + c * 4;
+        }
+    }
+
+    for (r = 0; r < 2; r++)
+    {
+        for (c = 0; c < 2; c++)
+        {
+            x->block[16 + r*2+c].src_diff = x->src_diff + 256 + r * 4 * 8 + c * 4;
+        }
+    }
+
+
+    for (r = 0; r < 2; r++)
+    {
+        for (c = 0; c < 2; c++)
+        {
+            x->block[20 + r*2+c].src_diff = x->src_diff + 320 + r * 4 * 8 + c * 4;
+        }
+    }
+
+    x->block[24].src_diff = x->src_diff + 384;
+
+
+    for (i = 0; i < 25; i++)
+    {
+        x->block[i].coeff = x->coeff + i * 16;
+    }
+}
+
+void vp8_build_block_offsets(MACROBLOCK *x)
+{
+    int block = 0;
+    int br, bc;
+
+    vp8_build_block_doffsets(&x->e_mbd);
+
+    // y blocks
+    for (br = 0; br < 4; br++)
+    {
+        for (bc = 0; bc < 4; bc++)
+        {
+            BLOCK *this_block = &x->block[block];
+            this_block->base_src = &x->src.y_buffer;
+            this_block->src_stride = x->src.y_stride;
+            this_block->src = 4 * br * this_block->src_stride + 4 * bc;
+            ++block;
+        }
+    }
+
+    // u blocks
+    for (br = 0; br < 2; br++)
+    {
+        for (bc = 0; bc < 2; bc++)
+        {
+            BLOCK *this_block = &x->block[block];
+            this_block->base_src = &x->src.u_buffer;
+            this_block->src_stride = x->src.uv_stride;
+            this_block->src = 4 * br * this_block->src_stride + 4 * bc;
+            ++block;
+        }
+    }
+
+    // v blocks
+    for (br = 0; br < 2; br++)
+    {
+        for (bc = 0; bc < 2; bc++)
+        {
+            BLOCK *this_block = &x->block[block];
+            this_block->base_src = &x->src.v_buffer;
+            this_block->src_stride = x->src.uv_stride;
+            this_block->src = 4 * br * this_block->src_stride + 4 * bc;
+            ++block;
+        }
+    }
+}
+
+static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x)
+{
+    const MACROBLOCKD *xd = & x->e_mbd;
+    const MB_PREDICTION_MODE m = xd->mbmi.mode;
+    const MB_PREDICTION_MODE uvm = xd->mbmi.uv_mode;
+
+#ifdef MODE_STATS
+    const int is_key = cpi->common.frame_type == KEY_FRAME;
+
+    ++ (is_key ? uv_modes : inter_uv_modes)[uvm];
+
+    if (m == B_PRED)
+    {
+        unsigned int *const bct = is_key ? b_modes : inter_b_modes;
+
+        int b = 0;
+
+        do
+        {
+            ++ bct[xd->block[b].bmi.mode];
+        }
+        while (++b < 16);
+    }
+
+#endif
+
+    ++cpi->ymode_count[m];
+    ++cpi->uv_mode_count[uvm];
+
+}
+int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
+{
+    int Error4x4, Error16x16, error_uv;
+    B_PREDICTION_MODE intra_bmodes[16];
+    int rate4x4, rate16x16, rateuv;
+    int dist4x4, dist16x16, distuv;
+    int rate = 0;
+    int rate4x4_tokenonly = 0;
+    int rate16x16_tokenonly = 0;
+    int rateuv_tokenonly = 0;
+    int i;
+
+    x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
+
+#if !(CONFIG_REALTIME_ONLY)
+
+    if (cpi->sf.RD || cpi->compressor_speed != 2)
+    {
+        Error4x4 = vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate4x4, &rate4x4_tokenonly, &dist4x4);
+
+        //save the b modes for possible later use
+        for (i = 0; i < 16; i++)
+            intra_bmodes[i] = x->e_mbd.block[i].bmi.mode;
+
+        Error16x16 = vp8_rd_pick_intra16x16mby_mode(cpi, x, &rate16x16, &rate16x16_tokenonly, &dist16x16);
+
+        error_uv = vp8_rd_pick_intra_mbuv_mode(cpi, x, &rateuv, &rateuv_tokenonly, &distuv);
+
+        x->e_mbd.mbmi.mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+
+        vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
+        rate += rateuv;
+
+        if (Error4x4 < Error16x16)
+        {
+            rate += rate4x4;
+            x->e_mbd.mbmi.mode = B_PRED;
+
+            // get back the intra block modes
+            for (i = 0; i < 16; i++)
+                x->e_mbd.block[i].bmi.mode = intra_bmodes[i];
+
+            vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
+            cpi->prediction_error += Error4x4 ;
+#if 0
+            // Experimental RD code
+            cpi->frame_distortion += dist4x4;
+#endif
+        }
+        else
+        {
+            vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
+            rate += rate16x16;
+
+#if 0
+            // Experimental RD code
+            cpi->prediction_error += Error16x16;
+            cpi->frame_distortion += dist16x16;
+#endif
+        }
+
+        sum_intra_stats(cpi, x);
+
+        vp8_tokenize_mb(cpi, &x->e_mbd, t);
+    }
+    else
+#endif
+    {
+
+        int rate2, distortion2;
+        MB_PREDICTION_MODE mode, best_mode = DC_PRED;
+        int this_rd;
+        Error16x16 = INT_MAX;
+
+        for (mode = DC_PRED; mode <= TM_PRED; mode ++)
+        {
+            x->e_mbd.mbmi.mode = mode;
+            vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
+            distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16prederror)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, 0x7fffffff);
+            rate2  = x->mbmode_cost[x->e_mbd.frame_type][mode];
+            this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
+
+            if (Error16x16 > this_rd)
+            {
+                Error16x16 = this_rd;
+                best_mode = mode;
+            }
+        }
+
+        vp8_pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate2, &distortion2);
+
+        if (distortion2 == INT_MAX)
+            Error4x4 = INT_MAX;
+        else
+            Error4x4 = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
+
+        x->e_mbd.mbmi.mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+
+        if (Error4x4 < Error16x16)
+        {
+            x->e_mbd.mbmi.mode = B_PRED;
+            vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
+            cpi->prediction_error += Error4x4;
+        }
+        else
+        {
+            x->e_mbd.mbmi.mode = best_mode;
+            vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
+            cpi->prediction_error += Error16x16;
+        }
+
+        vp8_pick_intra_mbuv_mode(x);
+        vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
+        sum_intra_stats(cpi, x);
+        vp8_tokenize_mb(cpi, &x->e_mbd, t);
+    }
+
+    return rate;
+}
+#ifdef SPEEDSTATS
+extern int cnt_pm;
+#endif
+
+extern void vp8_fix_contexts(VP8_COMP *cpi, MACROBLOCKD *x);
+
+int vp8cx_encode_inter_macroblock
+(
+    VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
+    int recon_yoffset, int recon_uvoffset
+)
+{
+    MACROBLOCKD *const xd = &x->e_mbd;
+    int inter_error;
+    int intra_error = 0;
+    int rate;
+    int distortion;
+
+    x->skip = 0;
+
+    if (xd->segmentation_enabled)
+        x->encode_breakout = cpi->segment_encode_breakout[xd->mbmi.segment_id];
+    else
+        x->encode_breakout = cpi->oxcf.encode_breakout;
+
+#if !(CONFIG_REALTIME_ONLY)
+
+    if (cpi->sf.RD)
+    {
+        inter_error = vp8_rd_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, &distortion, &intra_error);
+    }
+    else
+#endif
+        inter_error = vp8_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate, &distortion, &intra_error);
+
+
+    cpi->prediction_error += inter_error;
+    cpi->intra_error += intra_error;
+
+#if 0
+    // Experimental RD code
+    cpi->frame_distortion += distortion;
+    cpi->last_mb_distortion = distortion;
+#endif
+
+    // MB level adjutment to quantizer setup
+    if (xd->segmentation_enabled || cpi->zbin_mode_boost_enabled)
+    {
+        // If cyclic update enabled
+        if (cpi->cyclic_refresh_mode_enabled)
+        {
+            // Clear segment_id back to 0 if not coded (last frame 0,0)
+            if ((xd->mbmi.segment_id == 1) &&
+                ((xd->mbmi.ref_frame != LAST_FRAME) || (xd->mbmi.mode != ZEROMV)))
+            {
+                xd->mbmi.segment_id = 0;
+            }
+        }
+
+        // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
+        if (cpi->zbin_mode_boost_enabled)
+        {
+            if ((xd->mbmi.mode == ZEROMV) && (xd->mbmi.ref_frame != LAST_FRAME))
+                cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
+            else
+                cpi->zbin_mode_boost = 0;
+        }
+
+        vp8cx_mb_init_quantizer(cpi,  x);
+    }
+
+    cpi->count_mb_ref_frame_usage[xd->mbmi.ref_frame] ++;
+
+    if (xd->mbmi.ref_frame == INTRA_FRAME)
+    {
+        x->e_mbd.mbmi.mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+
+        vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
+
+        if (xd->mbmi.mode == B_PRED)
+        {
+            vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
+        }
+        else
+        {
+            vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
+        }
+
+        sum_intra_stats(cpi, x);
+    }
+    else
+    {
+        MV best_ref_mv;
+        MV nearest, nearby;
+        int mdcounts[4];
+
+        vp8_find_near_mvs(xd, xd->mode_info_context,
+                          &nearest, &nearby, &best_ref_mv, mdcounts, xd->mbmi.ref_frame, cpi->common.ref_frame_sign_bias);
+
+        vp8_build_uvmvs(xd, cpi->common.full_pixel);
+
+        // store motion vectors in our motion vector list
+        if (xd->mbmi.ref_frame == LAST_FRAME)
+        {
+            // Set up pointers for this macro block into the previous frame recon buffer
+            xd->pre.y_buffer = cpi->common.last_frame.y_buffer + recon_yoffset;
+            xd->pre.u_buffer = cpi->common.last_frame.u_buffer + recon_uvoffset;
+            xd->pre.v_buffer = cpi->common.last_frame.v_buffer + recon_uvoffset;
+        }
+        else if (xd->mbmi.ref_frame == GOLDEN_FRAME)
+        {
+            // Set up pointers for this macro block into the golden frame recon buffer
+            xd->pre.y_buffer = cpi->common.golden_frame.y_buffer + recon_yoffset;
+            xd->pre.u_buffer = cpi->common.golden_frame.u_buffer + recon_uvoffset;
+            xd->pre.v_buffer = cpi->common.golden_frame.v_buffer + recon_uvoffset;
+        }
+        else
+        {
+            // Set up pointers for this macro block into the alternate reference frame recon buffer
+            xd->pre.y_buffer = cpi->common.alt_ref_frame.y_buffer + recon_yoffset;
+            xd->pre.u_buffer = cpi->common.alt_ref_frame.u_buffer + recon_uvoffset;
+            xd->pre.v_buffer = cpi->common.alt_ref_frame.v_buffer + recon_uvoffset;
+        }
+
+        if (xd->mbmi.mode == SPLITMV)
+        {
+            int i;
+
+            for (i = 0; i < 16; i++)
+            {
+                if (xd->block[i].bmi.mode == NEW4X4)
+                {
+                    cpi->MVcount[0][mv_max+((xd->block[i].bmi.mv.as_mv.row - best_ref_mv.row) >> 1)]++;
+                    cpi->MVcount[1][mv_max+((xd->block[i].bmi.mv.as_mv.col - best_ref_mv.col) >> 1)]++;
+                }
+            }
+        }
+        else if (xd->mbmi.mode == NEWMV)
+        {
+            cpi->MVcount[0][mv_max+((xd->block[0].bmi.mv.as_mv.row - best_ref_mv.row) >> 1)]++;
+            cpi->MVcount[1][mv_max+((xd->block[0].bmi.mv.as_mv.col - best_ref_mv.col) >> 1)]++;
+        }
+
+        if (!x->skip && !x->e_mbd.mbmi.force_no_skip)
+        {
+            vp8_encode_inter16x16(IF_RTCD(&cpi->rtcd), x);
+
+            // Clear mb_skip_coeff if mb_no_coeff_skip is not set
+            if (!cpi->common.mb_no_coeff_skip)
+                xd->mbmi.mb_skip_coeff = 0;
+
+        }
+        else
+            vp8_stuff_inter16x16(x);
+    }
+
+    if (!x->skip)
+        vp8_tokenize_mb(cpi, xd, t);
+    else
+    {
+        if (cpi->common.mb_no_coeff_skip)
+        {
+            if (xd->mbmi.mode != B_PRED && xd->mbmi.mode != SPLITMV)
+                xd->mbmi.dc_diff = 0;
+            else
+                xd->mbmi.dc_diff = 1;
+
+            xd->mbmi.mb_skip_coeff = 1;
+            cpi->skip_true_count ++;
+            vp8_fix_contexts(cpi, xd);
+        }
+        else
+        {
+            vp8_stuff_mb(cpi, xd, t);
+            xd->mbmi.mb_skip_coeff = 0;
+            cpi->skip_false_count ++;
+        }
+    }
+
+    return rate;
+}
diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c
new file mode 100644 (file)
index 0000000..403d020
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "idct.h"
+#include "quantize.h"
+#include "reconintra.h"
+#include "reconintra4x4.h"
+#include "encodemb.h"
+#include "invtrans.h"
+#include "recon.h"
+#include "dct.h"
+#include "g_common.h"
+#include "encodeintra.h"
+
+#define intra4x4ibias_rate    128
+#define intra4x4pbias_rate    256
+
+
+void vp8_update_mode_context(int *abmode, int *lbmode, int i, int best_mode)
+{
+    if (i < 12)
+    {
+        abmode[i+4] = best_mode;
+    }
+
+    if ((i & 3) != 3)
+    {
+        lbmode[i+1] = best_mode;
+    }
+
+}
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x) (x)
+#else
+#define IF_RTCD(x) NULL
+#endif
+void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode)
+{
+    vp8_predict_intra4x4(b, best_mode, b->predictor);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
+
+    x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
+
+    x->quantize_b(be, b);
+
+    x->e_mbd.mbmi.mb_skip_coeff &= (!b->eob);
+
+    vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32);
+
+    RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+}
+
+void vp8_encode_intra4x4block_rd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode)
+{
+    vp8_predict_intra4x4(b, best_mode, b->predictor);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
+
+    x->short_fdct4x4rd(be->src_diff, be->coeff, 32);
+
+    x->quantize_brd(be, b);
+
+    x->e_mbd.mbmi.mb_skip_coeff &= (!b->eob);
+
+    IDCT_INVOKE(&rtcd->common->idct, idct16)(b->dqcoeff, b->diff, 32);
+
+    RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+}
+
+void vp8_encode_intra4x4mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb)
+{
+    int i;
+
+    MACROBLOCKD *x = &mb->e_mbd;
+    vp8_intra_prediction_down_copy(x);
+
+    for (i = 0; i < 16; i++)
+    {
+        BLOCK *be = &mb->block[i];
+        BLOCKD *b = &x->block[i];
+
+        vp8_encode_intra4x4block(rtcd, mb, be, b, b->bmi.mode);
+    }
+
+    return;
+}
+
+void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    int b;
+
+    vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);
+
+    vp8_transform_intra_mby(x);
+
+    vp8_quantize_mby(x);
+
+#if !(CONFIG_REALTIME_ONLY)
+#if 1
+
+    if (x->optimize && x->rddiv > 1)
+        vp8_optimize_mby(x, rtcd);
+
+#endif
+#endif
+
+    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+
+    // make sure block modes are set the way we want them for context updates
+    for (b = 0; b < 16; b++)
+    {
+        BLOCKD *d = &x->e_mbd.block[b];
+
+        switch (x->e_mbd.mbmi.mode)
+        {
+
+        case DC_PRED:
+            d->bmi.mode = B_DC_PRED;
+            break;
+        case V_PRED:
+            d->bmi.mode = B_VE_PRED;
+            break;
+        case H_PRED:
+            d->bmi.mode = B_HE_PRED;
+            break;
+        case TM_PRED:
+            d->bmi.mode = B_TM_PRED;
+            break;
+        default:
+            d->bmi.mode = B_DC_PRED;
+            break;
+
+        }
+    }
+}
+
+void vp8_encode_intra16x16mbyrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    int b;
+
+    vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);
+
+    vp8_transform_intra_mbyrd(x);
+
+    x->e_mbd.mbmi.mb_skip_coeff = 1;
+
+    vp8_quantize_mbyrd(x);
+
+
+    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+
+    // make sure block modes are set the way we want them for context updates
+    for (b = 0; b < 16; b++)
+    {
+        BLOCKD *d = &x->e_mbd.block[b];
+
+        switch (x->e_mbd.mbmi.mode)
+        {
+
+        case DC_PRED:
+            d->bmi.mode = B_DC_PRED;
+            break;
+        case V_PRED:
+            d->bmi.mode = B_VE_PRED;
+            break;
+        case H_PRED:
+            d->bmi.mode = B_HE_PRED;
+            break;
+        case TM_PRED:
+            d->bmi.mode = B_TM_PRED;
+            break;
+        default:
+            d->bmi.mode = B_DC_PRED;
+            break;
+
+        }
+    }
+}
+
+void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    vp8_build_intra_predictors_mbuv(&x->e_mbd);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
+
+    vp8_transform_mbuv(x);
+
+    vp8_quantize_mbuv(x);
+
+#if !(CONFIG_REALTIME_ONLY)
+#if 1
+
+    if (x->optimize && x->rddiv > 1)
+        vp8_optimize_mbuv(x, rtcd);
+
+#endif
+#endif
+
+    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+}
+
+void vp8_encode_intra16x16mbuvrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    vp8_build_intra_predictors_mbuv(&x->e_mbd);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
+
+    vp8_transform_mbuvrd(x);
+
+    vp8_quantize_mbuvrd(x);
+
+
+
+    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+}
diff --git a/vp8/encoder/encodeintra.h b/vp8/encoder/encodeintra.h
new file mode 100644 (file)
index 0000000..4a43ab2
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef _ENCODEINTRA_H_
+#define _ENCODEINTRA_H_
+#include "onyx_int.h"
+
+void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *, MACROBLOCK *x);
+void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *, MACROBLOCK *x);
+void vp8_encode_intra4x4mby(const VP8_ENCODER_RTCD *, MACROBLOCK *mb);
+void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode);
+void vp8_update_mode_context(int *abmode, int *lbmode, int i, int best_mode);
+void vp8_encode_intra4x4block_rd(const VP8_ENCODER_RTCD *, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode);
+void vp8_encode_intra16x16mbyrd(const VP8_ENCODER_RTCD *, MACROBLOCK *x);
+void vp8_encode_intra16x16mbuvrd(const VP8_ENCODER_RTCD *, MACROBLOCK *x);
+
+#endif
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
new file mode 100644 (file)
index 0000000..d825133
--- /dev/null
@@ -0,0 +1,1129 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "encodemb.h"
+#include "reconinter.h"
+#include "quantize.h"
+#include "invtrans.h"
+#include "recon.h"
+#include "reconintra.h"
+#include "dct.h"
+#include "vpx_mem/vpx_mem.h"
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x) (x)
+#else
+#define IF_RTCD(x) NULL
+#endif
+void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch)
+{
+    unsigned char *src_ptr = (*(be->base_src) + be->src);
+    short *diff_ptr = be->src_diff;
+    unsigned char *pred_ptr = bd->predictor;
+    int src_stride = be->src_stride;
+
+    int r, c;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 4; c++)
+        {
+            diff_ptr[c] = src_ptr[c] - pred_ptr[c];
+        }
+
+        diff_ptr += pitch;
+        pred_ptr += pitch;
+        src_ptr  += src_stride;
+    }
+}
+
+void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride)
+{
+    short *udiff = diff + 256;
+    short *vdiff = diff + 320;
+    unsigned char *upred = pred + 256;
+    unsigned char *vpred = pred + 320;
+
+    int r, c;
+
+    for (r = 0; r < 8; r++)
+    {
+        for (c = 0; c < 8; c++)
+        {
+            udiff[c] = usrc[c] - upred[c];
+        }
+
+        udiff += 8;
+        upred += 8;
+        usrc  += stride;
+    }
+
+    for (r = 0; r < 8; r++)
+    {
+        for (c = 0; c < 8; c++)
+        {
+            vdiff[c] = vsrc[c] - vpred[c];
+        }
+
+        vdiff += 8;
+        vpred += 8;
+        vsrc  += stride;
+    }
+}
+
+void vp8_subtract_mby_c(short *diff, unsigned char *src, unsigned char *pred, int stride)
+{
+    int r, c;
+
+    for (r = 0; r < 16; r++)
+    {
+        for (c = 0; c < 16; c++)
+        {
+            diff[c] = src[c] - pred[c];
+        }
+
+        diff += 16;
+        pred += 16;
+        src  += stride;
+    }
+}
+
+static void vp8_subtract_mb(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);
+    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
+}
+
+void vp8_build_dcblock(MACROBLOCK *x)
+{
+    short *src_diff_ptr = &x->src_diff[384];
+    int i;
+
+    for (i = 0; i < 16; i++)
+    {
+        src_diff_ptr[i] = x->coeff[i * 16];
+    }
+}
+
+void vp8_transform_mbuv(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 16; i < 24; i += 2)
+    {
+        x->vp8_short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
+    }
+}
+
+void vp8_transform_mbuvrd(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 16; i < 24; i += 2)
+    {
+        x->short_fdct8x4rd(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
+    }
+}
+
+void vp8_transform_intra_mby(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 2)
+    {
+        x->vp8_short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
+    }
+
+    // build dc block from 16 y dc values
+    vp8_build_dcblock(x);
+
+    // do 2nd order transform on the dc block
+    x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
+
+}
+
+void vp8_transform_intra_mbyrd(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 2)
+    {
+        x->short_fdct8x4rd(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
+    }
+
+    // build dc block from 16 y dc values
+    vp8_build_dcblock(x);
+
+    // do 2nd order transform on the dc block
+    x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
+}
+
+void vp8_transform_mb(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 2)
+    {
+        x->vp8_short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
+    }
+
+    // build dc block from 16 y dc values
+    if (x->e_mbd.mbmi.mode != SPLITMV)
+        vp8_build_dcblock(x);
+
+    for (i = 16; i < 24; i += 2)
+    {
+        x->vp8_short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
+    }
+
+    // do 2nd order transform on the dc block
+    if (x->e_mbd.mbmi.mode != SPLITMV)
+        x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
+
+}
+
+void vp8_transform_mby(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 2)
+    {
+        x->vp8_short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
+    }
+
+    // build dc block from 16 y dc values
+    if (x->e_mbd.mbmi.mode != SPLITMV)
+    {
+        vp8_build_dcblock(x);
+        x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
+    }
+}
+
+void vp8_transform_mbrd(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 0; i < 16; i += 2)
+    {
+        x->short_fdct8x4rd(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
+    }
+
+    // build dc block from 16 y dc values
+    if (x->e_mbd.mbmi.mode != SPLITMV)
+        vp8_build_dcblock(x);
+
+    for (i = 16; i < 24; i += 2)
+    {
+        x->short_fdct8x4rd(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
+    }
+
+    // do 2nd order transform on the dc block
+    if (x->e_mbd.mbmi.mode != SPLITMV)
+        x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
+}
+
+void vp8_stuff_inter16x16(MACROBLOCK *x)
+{
+    vp8_build_inter_predictors_mb_s(&x->e_mbd);
+    /*
+        // recon = copy from predictors to destination
+        {
+            BLOCKD *b = &x->e_mbd.block[0];
+            unsigned char *pred_ptr = b->predictor;
+            unsigned char *dst_ptr = *(b->base_dst) + b->dst;
+            int stride = b->dst_stride;
+
+            int i;
+            for(i=0;i<16;i++)
+                vpx_memcpy(dst_ptr+i*stride,pred_ptr+16*i,16);
+
+            b = &x->e_mbd.block[16];
+            pred_ptr = b->predictor;
+            dst_ptr = *(b->base_dst) + b->dst;
+            stride = b->dst_stride;
+
+            for(i=0;i<8;i++)
+                vpx_memcpy(dst_ptr+i*stride,pred_ptr+8*i,8);
+
+            b = &x->e_mbd.block[20];
+            pred_ptr = b->predictor;
+            dst_ptr = *(b->base_dst) + b->dst;
+            stride = b->dst_stride;
+
+            for(i=0;i<8;i++)
+                vpx_memcpy(dst_ptr+i*stride,pred_ptr+8*i,8);
+        }
+    */
+}
+
+#if !(CONFIG_REALTIME_ONLY)
+extern const TOKENEXTRA vp8_dct_value_tokens[DCT_MAX_VALUE*2];
+extern const TOKENEXTRA *vp8_dct_value_tokens_ptr;
+extern int vp8_dct_value_cost[DCT_MAX_VALUE*2];
+extern int *vp8_dct_value_cost_ptr;
+
+static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
+{
+    int c = !type;              /* start at coef 0, unless Y with Y2 */
+    int eob = b->eob;
+    int pt ;    /* surrounding block/prev coef predictor */
+    int cost = 0;
+    short *qcoeff_ptr = b->qcoeff;
+
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+
+# define QC( I)  ( qcoeff_ptr [vp8_default_zig_zag1d[I]] )
+
+    for (; c < eob; c++)
+    {
+        int v = QC(c);
+        int t = vp8_dct_value_tokens_ptr[v].Token;
+        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [t];
+        cost += vp8_dct_value_cost_ptr[v];
+        pt = vp8_prev_token_class[t];
+    }
+
+# undef QC
+
+    if (c < 16)
+        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [DCT_EOB_TOKEN];
+
+    return cost;
+}
+
+static int mbycost_coeffs(MACROBLOCK *mb)
+{
+    int cost = 0;
+    int b;
+    TEMP_CONTEXT t;
+    int type = 0;
+
+    MACROBLOCKD *x = &mb->e_mbd;
+
+    vp8_setup_temp_context(&t, x->above_context[Y1CONTEXT], x->left_context[Y1CONTEXT], 4);
+
+    if (x->mbmi.mode == SPLITMV)
+        type = 3;
+
+    for (b = 0; b < 16; b++)
+        cost += cost_coeffs(mb, x->block + b, type,
+                            t.a + vp8_block2above[b], t.l + vp8_block2left[b]);
+
+    return cost;
+}
+
+#define RDFUNC(RM,DM,R,D,target_rd) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
+
+void vp8_optimize_b(MACROBLOCK *x, int i, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, const VP8_ENCODER_RTCD *rtcd)
+{
+    BLOCK *b = &x->block[i];
+    BLOCKD *bd = &x->e_mbd.block[i];
+    short *dequant_ptr = &bd->dequant[0][0];
+    int nzpos[16] = {0};
+    short saved_qcoefs[16];
+    short saved_dqcoefs[16];
+    int baserate, baseerror, baserd;
+    int rate, error, thisrd;
+    int k;
+    int nzcoefcount = 0;
+    int nc, bestnc = 0;
+    int besteob;
+
+    // count potential coefficient to be optimized
+    for (k = !type; k < 16; k++)
+    {
+        int qcoef = abs(bd->qcoeff[k]);
+        int coef = abs(b->coeff[k]);
+        int dq   = dequant_ptr[k];
+
+        if (qcoef && (qcoef * dq > coef) && (qcoef * dq < coef + dq))
+        {
+            nzpos[nzcoefcount] = k;
+            nzcoefcount++;
+        }
+    }
+
+    // if nothing here, do nothing for this block.
+    if (!nzcoefcount)
+    {
+        *a = *l = (bd->eob != !type);
+        return;
+    }
+
+    // save a copy of quantized coefficients
+    vpx_memcpy(saved_qcoefs, bd->qcoeff, 32);
+    vpx_memcpy(saved_dqcoefs, bd->dqcoeff, 32);
+
+    besteob   = bd->eob;
+    baserate  = cost_coeffs(x, bd, type, a, l);
+    baseerror = ENCODEMB_INVOKE(&rtcd->encodemb, berr)(b->coeff, bd->dqcoeff) >> 2;
+    baserd    = RDFUNC(x->rdmult, x->rddiv, baserate, baseerror, 100);
+
+    for (nc = 1; nc < (1 << nzcoefcount); nc++)
+    {
+        //reset coefficients
+        vpx_memcpy(bd->qcoeff,  saved_qcoefs,  32);
+        vpx_memcpy(bd->dqcoeff, saved_dqcoefs, 32);
+
+        for (k = 0; k < nzcoefcount; k++)
+        {
+            int pos = nzpos[k];
+
+            if ((nc & (1 << k)))
+            {
+                int cur_qcoef = bd->qcoeff[pos];
+
+                if (cur_qcoef < 0)
+                {
+                    bd->qcoeff[pos]++;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+                else
+                {
+                    bd->qcoeff[pos]--;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+            }
+        }
+
+        {
+            int eob = -1;
+            int rc;
+            int m;
+
+            for (m = 0; m < 16; m++)
+            {
+                rc   = vp8_default_zig_zag1d[m];
+
+                if (bd->qcoeff[rc])
+                    eob = m;
+            }
+
+            bd->eob = eob + 1;
+        }
+
+        rate  = cost_coeffs(x, bd, type, a, l);
+        error = ENCODEMB_INVOKE(&rtcd->encodemb, berr)(b->coeff, bd->dqcoeff) >> 2;
+        thisrd = RDFUNC(x->rdmult, x->rddiv, rate, error, 100);
+
+        if (thisrd < baserd)
+        {
+            baserd = thisrd;
+            bestnc = nc;
+            besteob = bd->eob;
+        }
+    }
+
+    //reset coefficients
+    vpx_memcpy(bd->qcoeff,  saved_qcoefs, 32);
+    vpx_memcpy(bd->dqcoeff, saved_dqcoefs, 32);
+
+    if (bestnc)
+    {
+        for (k = 0; k < nzcoefcount; k++)
+        {
+            int pos = nzpos[k];
+
+            if (bestnc & (1 << k))
+            {
+                int cur_qcoef = bd->qcoeff[pos];
+
+                if (cur_qcoef < 0)
+                {
+                    bd->qcoeff[pos]++;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+                else
+                {
+                    bd->qcoeff[pos]--;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+            }
+        }
+
+#if 0
+        {
+            int eob = -1;
+            int rc;
+            int m;
+
+            for (m = 0; m < 16; m++)
+            {
+                rc   = vp8_default_zig_zag1d[m];
+
+                if (bd->qcoeff[rc])
+                    eob = m;
+            }
+
+            bd->eob = eob + 1;
+        }
+#endif
+    }
+
+#if 1
+    bd->eob = besteob;
+#endif
+#if 0
+    {
+        int eob = -1;
+        int rc;
+        int m;
+
+        for (m = 0; m < 16; m++)
+        {
+            rc   = vp8_default_zig_zag1d[m];
+
+            if (bd->qcoeff[rc])
+                eob = m;
+        }
+
+        bd->eob = eob + 1;
+    }
+
+#endif
+    *a = *l = (bd->eob != !type);
+    return;
+}
+
+void vp8_optimize_bplus(MACROBLOCK *x, int i, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, const VP8_ENCODER_RTCD *rtcd)
+{
+    BLOCK *b = &x->block[i];
+    BLOCKD *bd = &x->e_mbd.block[i];
+    short *dequant_ptr = &bd->dequant[0][0];
+    int nzpos[16] = {0};
+    short saved_qcoefs[16];
+    short saved_dqcoefs[16];
+    int baserate, baseerror, baserd;
+    int rate, error, thisrd;
+    int k;
+    int nzcoefcount = 0;
+    int nc, bestnc = 0;
+    int besteob;
+
+    // count potential coefficient to be optimized
+    for (k = !type; k < 16; k++)
+    {
+        int qcoef = abs(bd->qcoeff[k]);
+        int coef = abs(b->coeff[k]);
+        int dq   = dequant_ptr[k];
+
+        if (qcoef && (qcoef * dq < coef) && (coef < (qcoef * dq + dq)))
+        {
+            nzpos[nzcoefcount] = k;
+            nzcoefcount++;
+        }
+    }
+
+    // if nothing here, do nothing for this block.
+    if (!nzcoefcount)
+    {
+        //do not update context, we need do the other half.
+        //*a = *l = (bd->eob != !type);
+        return;
+    }
+
+    // save a copy of quantized coefficients
+    vpx_memcpy(saved_qcoefs, bd->qcoeff, 32);
+    vpx_memcpy(saved_dqcoefs, bd->dqcoeff, 32);
+
+    besteob   = bd->eob;
+    baserate  = cost_coeffs(x, bd, type, a, l);
+    baseerror = ENCODEMB_INVOKE(&rtcd->encodemb, berr)(b->coeff, bd->dqcoeff) >> 2;
+    baserd    = RDFUNC(x->rdmult, x->rddiv, baserate, baseerror, 100);
+
+    for (nc = 1; nc < (1 << nzcoefcount); nc++)
+    {
+        //reset coefficients
+        vpx_memcpy(bd->qcoeff, saved_qcoefs, 32);
+        vpx_memcpy(bd->dqcoeff, saved_dqcoefs, 32);
+
+        for (k = 0; k < nzcoefcount; k++)
+        {
+            int pos = nzpos[k];
+
+            if ((nc & (1 << k)))
+            {
+                int cur_qcoef = bd->qcoeff[pos];
+
+                if (cur_qcoef < 0)
+                {
+                    bd->qcoeff[pos]--;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+                else
+                {
+                    bd->qcoeff[pos]++;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+            }
+        }
+
+        {
+            int eob = -1;
+            int rc;
+            int m;
+
+            for (m = 0; m < 16; m++)
+            {
+                rc   = vp8_default_zig_zag1d[m];
+
+                if (bd->qcoeff[rc])
+                    eob = m;
+            }
+
+            bd->eob = eob + 1;
+        }
+
+        rate  = cost_coeffs(x, bd, type, a, l);
+        error = ENCODEMB_INVOKE(&rtcd->encodemb, berr)(b->coeff, bd->dqcoeff) >> 2;
+        thisrd = RDFUNC(x->rdmult, x->rddiv, rate, error, 100);
+
+        if (thisrd < baserd)
+        {
+            baserd = thisrd;
+            bestnc = nc;
+            besteob = bd->eob;
+        }
+    }
+
+    //reset coefficients
+    vpx_memcpy(bd->qcoeff,  saved_qcoefs, 32);
+    vpx_memcpy(bd->dqcoeff, saved_dqcoefs, 32);
+
+    if (bestnc)
+    {
+        for (k = 0; k < nzcoefcount; k++)
+        {
+            int pos = nzpos[k];
+
+            if (bestnc & (1 << k))
+            {
+                int cur_qcoef = bd->qcoeff[pos];
+
+                if (cur_qcoef < 0)
+                {
+                    bd->qcoeff[pos]++;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+                else
+                {
+                    bd->qcoeff[pos]--;
+                    bd->dqcoeff[pos] = bd->qcoeff[pos] * dequant_ptr[pos];
+                }
+            }
+        }
+    }
+
+    bd->eob = besteob;
+    //do not update context, we need do the other half.
+    //*a = *l = (bd->eob != !type);
+    return;
+}
+
+void vp8_optimize_y2b(MACROBLOCK *x, int i, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, const VP8_ENCODER_RTCD *rtcd)
+{
+
+    BLOCK *b = &x->block[i];
+    BLOCKD *bd = &x->e_mbd.block[i];
+    short *dequant_ptr = &bd->dequant[0][0];
+
+    int baserate, baseerror, baserd;
+    int rate, error, thisrd;
+    int k;
+
+    if (bd->eob == 0)
+        return;
+
+    baserate  = cost_coeffs(x, bd, type, a, l);
+    baseerror = ENCODEMB_INVOKE(&rtcd->encodemb, berr)(b->coeff, bd->dqcoeff) >> 4;
+    baserd = RDFUNC(x->rdmult, x->rddiv, baserate, baseerror, 100);
+
+    for (k = 0; k < 16; k++)
+    {
+        int cur_qcoef = bd->qcoeff[k];
+
+        if (!cur_qcoef)
+            continue;
+
+        if (cur_qcoef < 0)
+        {
+            bd->qcoeff[k]++;
+            bd->dqcoeff[k] = bd->qcoeff[k] * dequant_ptr[k];
+        }
+        else
+        {
+            bd->qcoeff[k]--;
+            bd->dqcoeff[k] = bd->qcoeff[k] * dequant_ptr[k];
+        }
+
+        if (bd->qcoeff[k] == 0)
+        {
+            int eob = -1;
+            int rc;
+            int l;
+
+            for (l = 0; l < 16; l++)
+            {
+                rc   = vp8_default_zig_zag1d[l];
+
+                if (bd->qcoeff[rc])
+                    eob = l;
+            }
+
+            bd->eob = eob + 1;
+        }
+
+        rate  =   cost_coeffs(x, bd, type, a, l);
+        error = ENCODEMB_INVOKE(&rtcd->encodemb, berr)(b->coeff, bd->dqcoeff) >> 4;
+        thisrd = RDFUNC(x->rdmult, x->rddiv, rate, error, 100);
+
+        if (thisrd > baserd)
+        {
+            bd->qcoeff[k] = cur_qcoef;
+            bd->dqcoeff[k] = cur_qcoef * dequant_ptr[k];
+        }
+        else
+        {
+            baserd = thisrd;
+        }
+
+    }
+
+    {
+        int eob = -1;
+        int rc;
+
+        for (k = 0; k < 16; k++)
+        {
+            rc   = vp8_default_zig_zag1d[k];
+
+            if (bd->qcoeff[rc])
+                eob = k;
+        }
+
+        bd->eob = eob + 1;
+    }
+
+    return;
+}
+
+
+void vp8_optimize_mb(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+    int cost = 0;
+    int b;
+    TEMP_CONTEXT t, t2;
+    int type = 0;
+
+    vp8_setup_temp_context(&t, x->e_mbd.above_context[Y1CONTEXT], x->e_mbd.left_context[Y1CONTEXT], 4);
+
+    if (x->e_mbd.mbmi.mode == SPLITMV || x->e_mbd.mbmi.mode == B_PRED)
+        type = 3;
+
+    for (b = 0; b < 16; b++)
+    {
+        //vp8_optimize_bplus(x, b, type, t.a + vp8_block2above[b], t.l + vp8_block2left[b]);
+        vp8_optimize_b(x, b, type, t.a + vp8_block2above[b], t.l + vp8_block2left[b], rtcd);
+    }
+
+    vp8_setup_temp_context(&t, x->e_mbd.above_context[UCONTEXT], x->e_mbd.left_context[UCONTEXT], 2);
+    vp8_setup_temp_context(&t2, x->e_mbd.above_context[VCONTEXT], x->e_mbd.left_context[VCONTEXT], 2);
+
+    for (b = 16; b < 20; b++)
+    {
+        //vp8_optimize_bplus(x, b, vp8_block2type[b], t.a + vp8_block2above[b], t.l + vp8_block2left[b]);
+        vp8_optimize_b(x, b, vp8_block2type[b], t.a + vp8_block2above[b], t.l + vp8_block2left[b], rtcd);
+    }
+
+    for (b = 20; b < 24; b++)
+    {
+        //vp8_optimize_bplus(x, b, vp8_block2type[b], t2.a + vp8_block2above[b], t2.l + vp8_block2left[b]);
+        vp8_optimize_b(x, b, vp8_block2type[b], t2.a + vp8_block2above[b], t2.l + vp8_block2left[b], rtcd);
+    }
+}
+
+
+
+void vp8_super_slow_yquant_optimization(MACROBLOCK *x, int type, const VP8_ENCODER_RTCD *rtcd)
+{
+    BLOCK  *b = &x->block[0];
+    BLOCKD *bd = &x->e_mbd.block[0];
+    short *dequant_ptr = &bd->dequant[0][0];
+    struct
+    {
+        int block;
+        int pos;
+    } nzpos[256];
+    short saved_qcoefs[256];
+    short saved_dqcoefs[256];
+    short *coef_ptr   = x->coeff;
+    short *qcoef_ptr  = x->e_mbd.qcoeff;
+    short *dqcoef_ptr = x->e_mbd.dqcoeff;
+
+    int baserate, baseerror, baserd;
+    int rate, error, thisrd;
+    int i, k;
+    int nzcoefcount = 0;
+    int nc, bestnc = 0;
+    int besteob;
+
+    //this code has assumption in macroblock coeff buffer layout
+    for (i = 0; i < 16; i++)
+    {
+        // count potential coefficient to be optimized
+        for (k = !type; k < 16; k++)
+        {
+            int qcoef = abs(qcoef_ptr[i*16 + k]);
+            int coef = abs(coef_ptr[i*16 + k]);
+            int dq   = dequant_ptr[k];
+
+            if (qcoef && (qcoef * dq > coef) && (qcoef * dq < coef + dq))
+            {
+                nzpos[nzcoefcount].block = i;
+                nzpos[nzcoefcount].pos   = k;
+                nzcoefcount++;
+            }
+        }
+    }
+
+    // if nothing here, do nothing for this macro_block.
+    if (!nzcoefcount || nzcoefcount > 15)
+    {
+        return;
+    }
+
+    /******************************************************************************
+    looking from each coeffient's perspective, each identifed coefficent above could
+    have 2 values:roundeddown(x) and roundedup(x). Therefore the total number of
+    different states is less than 2**nzcoefcount.
+    ******************************************************************************/
+    // save the qunatized coefficents and dequantized coefficicents
+    vpx_memcpy(saved_qcoefs, x->e_mbd.qcoeff,  256);
+    vpx_memcpy(saved_dqcoefs, x->e_mbd.dqcoeff, 256);
+
+    baserate    = mbycost_coeffs(x);
+    baseerror   = ENCODEMB_INVOKE(&rtcd->encodemb, mberr)(x, !type);
+    baserd      = RDFUNC(x->rdmult, x->rddiv, baserate, baseerror, 100);
+
+    for (nc = 1; nc < (1 << nzcoefcount); nc++)
+    {
+        //reset coefficients
+        vpx_memcpy(x->e_mbd.qcoeff,  saved_qcoefs, 256);
+        vpx_memcpy(x->e_mbd.dqcoeff, saved_dqcoefs, 256);
+
+        for (k = 0; k < nzcoefcount; k++)
+        {
+            int bk  = nzpos[k].block;
+            int pos = nzpos[k].pos;
+            int mbkpos  = bk * 16 + pos;
+
+            if ((nc & (1 << k)))
+            {
+                int cur_qcoef = x->e_mbd.qcoeff[mbkpos];
+
+                if (cur_qcoef < 0)
+                {
+                    x->e_mbd.qcoeff[mbkpos]++;
+                    x->e_mbd.dqcoeff[mbkpos] = x->e_mbd.qcoeff[mbkpos] * dequant_ptr[pos];
+                }
+                else
+                {
+                    x->e_mbd.qcoeff[mbkpos]--;
+                    x->e_mbd.dqcoeff[mbkpos] = x->e_mbd.qcoeff[mbkpos] * dequant_ptr[pos];
+                }
+            }
+        }
+
+        for (i = 0; i < 16; i++)
+        {
+            BLOCKD *bd = &x->e_mbd.block[i];
+            {
+                int eob = -1;
+                int rc;
+                int l;
+
+                for (l = 0; l < 16; l++)
+                {
+                    rc   = vp8_default_zig_zag1d[l];
+
+                    if (bd->qcoeff[rc])
+                        eob = l;
+                }
+
+                bd->eob = eob + 1;
+            }
+        }
+
+        rate  = mbycost_coeffs(x);
+        error = ENCODEMB_INVOKE(&rtcd->encodemb, mberr)(x, !type);;
+        thisrd = RDFUNC(x->rdmult, x->rddiv, rate, error, 100);
+
+        if (thisrd < baserd)
+        {
+            baserd = thisrd;
+            bestnc = nc;
+            besteob = bd->eob;
+        }
+    }
+
+    //reset coefficients
+    vpx_memcpy(x->e_mbd.qcoeff,  saved_qcoefs, 256);
+    vpx_memcpy(x->e_mbd.dqcoeff, saved_dqcoefs, 256);
+
+    if (bestnc)
+    {
+        for (k = 0; k < nzcoefcount; k++)
+        {
+            int bk  = nzpos[k].block;
+            int pos = nzpos[k].pos;
+            int mbkpos  = bk * 16 + pos;
+
+            if ((nc & (1 << k)))
+            {
+                int cur_qcoef = x->e_mbd.qcoeff[mbkpos];
+
+                if (cur_qcoef < 0)
+                {
+                    x->e_mbd.qcoeff[mbkpos]++;
+                    x->e_mbd.dqcoeff[mbkpos] = x->e_mbd.qcoeff[mbkpos] * dequant_ptr[pos];
+                }
+                else
+                {
+                    x->e_mbd.qcoeff[mbkpos]--;
+                    x->e_mbd.dqcoeff[mbkpos] = x->e_mbd.qcoeff[mbkpos] * dequant_ptr[pos];
+                }
+            }
+        }
+    }
+
+    for (i = 0; i < 16; i++)
+    {
+        BLOCKD *bd = &x->e_mbd.block[i];
+        {
+            int eob = -1;
+            int rc;
+            int l;
+
+            for (l = 0; l < 16; l++)
+            {
+                rc   = vp8_default_zig_zag1d[l];
+
+                if (bd->qcoeff[rc])
+                    eob = l;
+            }
+
+            bd->eob = eob + 1;
+        }
+    }
+
+    return;
+}
+
+static void vp8_find_mb_skip_coef(MACROBLOCK *x)
+{
+    int i;
+
+    x->e_mbd.mbmi.mb_skip_coeff = 1;
+
+    if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2);
+        }
+
+        for (i = 16; i < 25; i++)
+        {
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+    else
+    {
+        for (i = 0; i < 24; i++)
+        {
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+}
+
+
+void vp8_optimize_mb_slow(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+    int cost = 0;
+    int b;
+    TEMP_CONTEXT t, t2;
+    int type = 0;
+
+
+    vp8_setup_temp_context(&t, x->e_mbd.above_context[Y1CONTEXT], x->e_mbd.left_context[Y1CONTEXT], 4);
+
+    if (x->e_mbd.mbmi.mode == SPLITMV || x->e_mbd.mbmi.mode == B_PRED)
+        type = 3;
+
+    vp8_super_slow_yquant_optimization(x, type, rtcd);
+    /*
+    for(b=0;b<16;b++)
+    {
+        vp8_optimize_b(x, b, type, t.a + vp8_block2above[b], t.l + vp8_block2left[b]);
+    }
+    */
+
+    vp8_setup_temp_context(&t, x->e_mbd.above_context[UCONTEXT], x->e_mbd.left_context[UCONTEXT], 2);
+
+    for (b = 16; b < 20; b++)
+    {
+        vp8_optimize_b(x, b, vp8_block2type[b], t.a + vp8_block2above[b], t.l + vp8_block2left[b], rtcd);
+    }
+
+    vp8_setup_temp_context(&t2, x->e_mbd.above_context[VCONTEXT], x->e_mbd.left_context[VCONTEXT], 2);
+
+    for (b = 20; b < 24; b++)
+    {
+        vp8_optimize_b(x, b, vp8_block2type[b], t2.a + vp8_block2above[b], t2.l + vp8_block2left[b], rtcd);
+    }
+}
+
+
+void vp8_optimize_mby(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+    int cost = 0;
+    int b;
+    TEMP_CONTEXT t;
+    int type = 0;
+
+    if (!x->e_mbd.above_context[Y1CONTEXT])
+        return;
+
+    if (!x->e_mbd.left_context[Y1CONTEXT])
+        return;
+
+    vp8_setup_temp_context(&t, x->e_mbd.above_context[Y1CONTEXT], x->e_mbd.left_context[Y1CONTEXT], 4);
+
+    if (x->e_mbd.mbmi.mode == SPLITMV || x->e_mbd.mbmi.mode == B_PRED)
+        type = 3;
+
+    for (b = 0; b < 16; b++)
+    {
+        vp8_optimize_b(x, b, type, t.a + vp8_block2above[b], t.l + vp8_block2left[b], rtcd);
+    }
+
+}
+
+void vp8_optimize_mbuv(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
+{
+    int cost = 0;
+    int b;
+    TEMP_CONTEXT t, t2;
+    int type = 0;
+
+    if (!x->e_mbd.above_context[UCONTEXT])
+        return;
+
+    if (!x->e_mbd.left_context[UCONTEXT])
+        return;
+
+    if (!x->e_mbd.above_context[VCONTEXT])
+        return;
+
+    if (!x->e_mbd.left_context[VCONTEXT])
+        return;
+
+
+    vp8_setup_temp_context(&t, x->e_mbd.above_context[UCONTEXT], x->e_mbd.left_context[UCONTEXT], 2);
+    vp8_setup_temp_context(&t2, x->e_mbd.above_context[VCONTEXT], x->e_mbd.left_context[VCONTEXT], 2);
+
+    for (b = 16; b < 20; b++)
+    {
+        vp8_optimize_b(x, b, vp8_block2type[b],
+                       t.a + vp8_block2above[b], t.l + vp8_block2left[b], rtcd);
+
+    }
+
+    for (b = 20; b < 24; b++)
+    {
+        vp8_optimize_b(x, b, vp8_block2type[b],
+                       t2.a + vp8_block2above[b], t2.l + vp8_block2left[b], rtcd);
+    }
+
+}
+#endif
+
+void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    vp8_build_inter_predictors_mb(&x->e_mbd);
+
+    vp8_subtract_mb(rtcd, x);
+
+    vp8_transform_mb(x);
+
+    vp8_quantize_mb(x);
+
+#if !(CONFIG_REALTIME_ONLY)
+#if 1
+
+    if (x->optimize && x->rddiv > 1)
+    {
+        vp8_optimize_mb(x, rtcd);
+        vp8_find_mb_skip_coef(x);
+    }
+
+#endif
+#endif
+
+    vp8_inverse_transform_mb(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon16x16mb(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+}
+
+
+/* this funciton is used by first pass only */
+void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    vp8_build_inter_predictors_mby(&x->e_mbd);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);
+
+    vp8_transform_mby(x);
+
+    vp8_quantize_mby(x);
+
+    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+}
+
+
+void vp8_encode_inter16x16uv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    vp8_build_inter_predictors_mbuv(&x->e_mbd);
+
+    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
+
+    vp8_transform_mbuv(x);
+
+    vp8_quantize_mbuv(x);
+
+    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
+
+    vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
+}
+
+
+void vp8_encode_inter16x16uvrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+    vp8_build_inter_predictors_mbuv(&x->e_mbd);
+    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
+
+    vp8_transform_mbuvrd(x);
+
+    vp8_quantize_mbuvrd(x);
+
+}
diff --git a/vp8/encoder/encodemb.h b/vp8/encoder/encodemb.h
new file mode 100644 (file)
index 0000000..91ca8f5
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_ENCODEMB_H
+#define __INC_ENCODEMB_H
+
+#include "vpx_ports/config.h"
+#include "block.h"
+
+#define prototype_mberr(sym) \
+    int (sym)(MACROBLOCK *mb, int dc)
+
+#define prototype_berr(sym) \
+    int (sym)(short *coeff, short *dqcoeff)
+
+#define prototype_mbuverr(sym) \
+    int (sym)(MACROBLOCK *mb)
+
+#define prototype_subb(sym) \
+    void (sym)(BLOCK *be,BLOCKD *bd, int pitch)
+
+#define prototype_submby(sym) \
+    void (sym)(short *diff, unsigned char *src, unsigned char *pred, int stride)
+
+#define prototype_submbuv(sym) \
+    void (sym)(short *diff, unsigned char *usrc, unsigned char *vsrc,\
+               unsigned char *pred, int stride)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/encodemb_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/encodemb_arm.h"
+#endif
+
+#ifndef vp8_encodemb_berr
+#define vp8_encodemb_berr vp8_block_error_c
+#endif
+extern prototype_berr(vp8_encodemb_berr);
+
+#ifndef vp8_encodemb_mberr
+#define vp8_encodemb_mberr vp8_mbblock_error_c
+#endif
+extern prototype_mberr(vp8_encodemb_mberr);
+
+#ifndef vp8_encodemb_mbuverr
+#define vp8_encodemb_mbuverr vp8_mbuverror_c
+#endif
+extern prototype_mbuverr(vp8_encodemb_mbuverr);
+
+#ifndef vp8_encodemb_subb
+#define vp8_encodemb_subb vp8_subtract_b_c
+#endif
+extern prototype_subb(vp8_encodemb_subb);
+
+#ifndef vp8_encodemb_submby
+#define vp8_encodemb_submby vp8_subtract_mby_c
+#endif
+extern prototype_submby(vp8_encodemb_submby);
+
+#ifndef vp8_encodemb_submbuv
+#define vp8_encodemb_submbuv vp8_subtract_mbuv_c
+#endif
+extern prototype_submbuv(vp8_encodemb_submbuv);
+
+
+typedef struct
+{
+    prototype_berr(*berr);
+    prototype_mberr(*mberr);
+    prototype_mbuverr(*mbuverr);
+    prototype_subb(*subb);
+    prototype_submby(*submby);
+    prototype_submbuv(*submbuv);
+} vp8_encodemb_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define ENCODEMB_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define ENCODEMB_INVOKE(ctx,fn) vp8_encodemb_##fn
+#endif
+
+
+
+#include "onyx_int.h"
+struct VP8_ENCODER_RTCD;
+void vp8_encode_inter16x16(const struct VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x);
+
+extern void vp8_stuff_inter16x16(MACROBLOCK *x);
+
+void vp8_build_dcblock(MACROBLOCK *b);
+void vp8_transform_mb(MACROBLOCK *mb);
+void vp8_transform_mbuv(MACROBLOCK *x);
+void vp8_transform_mbuvrd(MACROBLOCK *x);
+void vp8_transform_intra_mby(MACROBLOCK *x);
+void vp8_transform_intra_mbyrd(MACROBLOCK *x);
+void Encode16x16Y(MACROBLOCK *x);
+void Encode16x16UV(MACROBLOCK *x);
+void vp8_encode_inter16x16uv(const struct VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x);
+void vp8_encode_inter16x16uvrd(const struct VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x);
+void vp8_optimize_mby(MACROBLOCK *x, const struct VP8_ENCODER_RTCD *rtcd);
+void vp8_optimize_mbuv(MACROBLOCK *x, const struct VP8_ENCODER_RTCD *rtcd);
+void vp8_encode_inter16x16y(const struct VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x);
+#endif
diff --git a/vp8/encoder/encodemv.c b/vp8/encoder/encodemv.c
new file mode 100644 (file)
index 0000000..f287edc
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "common.h"
+#include "encodemv.h"
+#include "entropymode.h"
+#include "systemdependent.h"
+
+#include <math.h>
+
+#ifdef ENTROPY_STATS
+extern unsigned int active_section;
+#endif
+
+static void encode_mvcomponent(
+    vp8_writer *const w,
+    const int v,
+    const struct mv_context *mvc
+)
+{
+    const vp8_prob *p = mvc->prob;
+    const int x = v < 0 ? -v : v;
+
+    if (x < mvnum_short)     // Small
+    {
+        vp8_write(w, 0, p [mvpis_short]);
+        vp8_treed_write(w, vp8_small_mvtree, p + MVPshort, x, 3);
+
+        if (!x)
+            return;         // no sign bit
+    }
+    else                    // Large
+    {
+        int i = 0;
+
+        vp8_write(w, 1, p [mvpis_short]);
+
+        do
+            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
+
+        while (++i < 3);
+
+        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
+
+        do
+            vp8_write(w, (x >> i) & 1, p [MVPbits + i]);
+
+        while (--i > 3);
+
+        if (x & 0xFFF0)
+            vp8_write(w, (x >> 3) & 1, p [MVPbits + 3]);
+    }
+
+    vp8_write(w, v < 0, p [MVPsign]);
+}
+#if 0
+static int max_mv_r = 0;
+static int max_mv_c = 0;
+#endif
+void vp8_encode_motion_vector(vp8_writer *w, const MV *mv, const MV_CONTEXT *mvc)
+{
+
+#if 0
+    {
+        if (abs(mv->row >> 1) > max_mv_r)
+        {
+            FILE *f = fopen("maxmv.stt", "a");
+            max_mv_r = abs(mv->row >> 1);
+            fprintf(f, "New Mv Row Max %6d\n", (mv->row >> 1));
+
+            if ((abs(mv->row) / 2) != max_mv_r)
+                fprintf(f, "MV Row conversion error %6d\n", abs(mv->row) / 2);
+
+            fclose(f);
+        }
+
+        if (abs(mv->col >> 1) > max_mv_c)
+        {
+            FILE *f = fopen("maxmv.stt", "a");
+            fprintf(f, "New Mv Col Max %6d\n", (mv->col >> 1));
+            max_mv_c = abs(mv->col >> 1);
+            fclose(f);
+        }
+    }
+#endif
+
+    encode_mvcomponent(w, mv->row >> 1, &mvc[0]);
+    encode_mvcomponent(w, mv->col >> 1, &mvc[1]);
+}
+
+
+static unsigned int cost_mvcomponent(const int v, const struct mv_context *mvc)
+{
+    const vp8_prob *p = mvc->prob;
+    const int x = v;   //v<0? -v:v;
+    unsigned int cost;
+
+    if (x < mvnum_short)
+    {
+        cost = vp8_cost_zero(p [mvpis_short])
+               + vp8_treed_cost(vp8_small_mvtree, p + MVPshort, x, 3);
+
+        if (!x)
+            return cost;
+    }
+    else
+    {
+        int i = 0;
+        cost = vp8_cost_one(p [mvpis_short]);
+
+        do
+            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
+
+        while (++i < 3);
+
+        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */
+
+        do
+            cost += vp8_cost_bit(p [MVPbits + i], (x >> i) & 1);
+
+        while (--i > 3);
+
+        if (x & 240)
+            cost += vp8_cost_bit(p [MVPbits + 3], (x >> 3) & 1);
+    }
+
+    return cost;   // + vp8_cost_bit( p [MVPsign], v < 0);
+}
+//#define M_LOG2_E 0.693147180559945309417
+//#define log2f(x) (log (x) / (float) M_LOG2_E)
+
+void vp8_build_component_cost_table(int *mvcost[2], int *mvsadcost[2], const MV_CONTEXT *mvc, int mvc_flag[2])
+{
+    int i = 1;   //-mv_max;
+    unsigned int cost0 = 0;
+    unsigned int cost1 = 0;
+
+    vp8_clear_system_state();
+#if 0
+    mvsadcost [0] [0] = 300;
+    mvsadcost [1] [0] = 300;
+
+    do
+    {
+        double z = 256 * (2 * (log2f(2 * i) + .6));
+        mvsadcost [0][i] = (int) z;
+        mvsadcost [1][i] = (int) z;
+        mvsadcost [0][-i] = (int) z;
+        mvsadcost [1][-i] = (int) z;
+    }
+    while (++i <= mv_max);
+
+#endif
+
+    i = 1;
+
+    if (mvc_flag[0])
+    {
+        mvcost [0] [0] = cost_mvcomponent(0, &mvc[0]);
+
+        do
+        {
+            //mvcost [0] [i] = cost_mvcomponent( i, &mvc[0]);
+            cost0 = cost_mvcomponent(i, &mvc[0]);
+
+            mvcost [0] [i] = cost0 + vp8_cost_zero(mvc[0].prob[MVPsign]);
+            mvcost [0] [-i] = cost0 + vp8_cost_one(mvc[0].prob[MVPsign]);
+        }
+        while (++i <= mv_max);
+    }
+
+    i = 1;
+
+    if (mvc_flag[1])
+    {
+        mvcost [1] [0] = cost_mvcomponent(0, &mvc[1]);
+
+        do
+        {
+            //mvcost [1] [i] = cost_mvcomponent( i, mvc[1]);
+            cost1 = cost_mvcomponent(i, &mvc[1]);
+
+            mvcost [1] [i] = cost1 + vp8_cost_zero(mvc[1].prob[MVPsign]);
+            mvcost [1] [-i] = cost1 + vp8_cost_one(mvc[1].prob[MVPsign]);
+        }
+        while (++i <= mv_max);
+    }
+
+    /*
+        i=-mv_max;
+        do
+        {
+            mvcost [0] [i] = cost_mvcomponent( i, mvc[0]);
+            mvcost [1] [i] = cost_mvcomponent( i, mvc[1]);
+        }
+        while( ++i <= mv_max);
+    */
+}
+
+
+// Motion vector probability table update depends on benefit.
+// Small correction allows for the fact that an update to an MV probability
+// may have benefit in subsequent frames as well as the current one.
+
+#define MV_PROB_UPDATE_CORRECTION   -1
+
+
+__inline static void calc_prob(vp8_prob *p, const unsigned int ct[2])
+{
+    const unsigned int tot = ct[0] + ct[1];
+
+    if (tot)
+    {
+        const vp8_prob x = ((ct[0] * 255) / tot) & -2;
+        *p = x ? x : 1;
+    }
+}
+
+static void update(
+    vp8_writer *const w,
+    const unsigned int ct[2],
+    vp8_prob *const cur_p,
+    const vp8_prob new_p,
+    const vp8_prob update_p,
+    int *updated
+)
+{
+    const int cur_b = vp8_cost_branch(ct, *cur_p);
+    const int new_b = vp8_cost_branch(ct, new_p);
+    const int cost = 7 + MV_PROB_UPDATE_CORRECTION + ((vp8_cost_one(update_p) - vp8_cost_zero(update_p) + 128) >> 8);
+
+    if (cur_b - new_b > cost)
+    {
+        *cur_p = new_p;
+        vp8_write(w, 1, update_p);
+        vp8_write_literal(w, new_p >> 1, 7);
+        *updated = 1;
+
+    }
+    else
+        vp8_write(w, 0, update_p);
+}
+
+static void write_component_probs(
+    vp8_writer *const w,
+    struct mv_context *cur_mvc,
+    const struct mv_context *default_mvc_,
+    const struct mv_context *update_mvc,       
+    const unsigned int events [MVvals],
+    unsigned int rc,
+    int *updated
+)
+{
+    vp8_prob *Pcur = cur_mvc->prob;
+    const vp8_prob *default_mvc = default_mvc_->prob;
+    const vp8_prob *Pupdate = update_mvc->prob;
+    unsigned int is_short_ct[2], sign_ct[2];
+
+    unsigned int bit_ct [mvlong_width] [2];
+
+    unsigned int short_ct  [mvnum_short];
+    unsigned int short_bct [mvnum_short-1] [2];
+
+    vp8_prob Pnew [MVPcount];
+
+    (void) rc;
+    vp8_copy_array(Pnew, default_mvc, MVPcount);
+
+    vp8_zero(is_short_ct)
+    vp8_zero(sign_ct)
+    vp8_zero(bit_ct)
+    vp8_zero(short_ct)
+    vp8_zero(short_bct)
+
+
+    //j=0
+    {
+        int j = 0;
+
+        const int c = events [mv_max];
+
+        is_short_ct [0] += c;     // Short vector
+        short_ct [0] += c;       // Magnitude distribution
+    }
+
+    //j: 1 ~ mv_max (1023)
+    {
+        int j = 1;
+
+        do
+        {
+            const int c1 = events [mv_max + j];  //positive
+            const int c2 = events [mv_max - j];  //negative
+            const int c  = c1 + c2;
+            int a = j;
+
+            sign_ct [0] += c1;
+            sign_ct [1] += c2;
+
+            if (a < mvnum_short)
+            {
+                is_short_ct [0] += c;     // Short vector
+                short_ct [a] += c;       // Magnitude distribution
+            }
+            else
+            {
+                int k = mvlong_width - 1;
+                is_short_ct [1] += c;     // Long vector
+
+                /*  bit 3 not always encoded. */
+                do
+                    bit_ct [k] [(a >> k) & 1] += c;
+
+                while (--k >= 0);
+            }
+        }
+        while (++j <= mv_max);
+    }
+
+    /*
+    {
+        int j = -mv_max;
+        do
+        {
+
+            const int c = events [mv_max + j];
+            int a = j;
+
+            if( j < 0)
+            {
+                sign_ct [1] += c;
+                a = -j;
+            }
+            else if( j)
+                sign_ct [0] += c;
+
+            if( a < mvnum_short)
+            {
+                is_short_ct [0] += c;     // Short vector
+                short_ct [a] += c;       // Magnitude distribution
+            }
+            else
+            {
+                int k = mvlong_width - 1;
+                is_short_ct [1] += c;     // Long vector
+
+                //  bit 3 not always encoded.
+
+                do
+                    bit_ct [k] [(a >> k) & 1] += c;
+                while( --k >= 0);
+            }
+        } while( ++j <= mv_max);
+    }
+    */
+
+    calc_prob(Pnew + mvpis_short, is_short_ct);
+
+    calc_prob(Pnew + MVPsign, sign_ct);
+
+    {
+        vp8_prob p [mvnum_short - 1];    /* actually only need branch ct */
+        int j = 0;
+
+        vp8_tree_probs_from_distribution(
+            8, vp8_small_mvencodings, vp8_small_mvtree,
+            p, short_bct, short_ct,
+            256, 1
+        );
+
+        do
+            calc_prob(Pnew + MVPshort + j, short_bct[j]);
+
+        while (++j < mvnum_short - 1);
+    }
+
+    {
+        int j = 0;
+
+        do
+            calc_prob(Pnew + MVPbits + j, bit_ct[j]);
+
+        while (++j < mvlong_width);
+    }
+
+    update(w, is_short_ct, Pcur + mvpis_short, Pnew[mvpis_short], *Pupdate++, updated);
+
+    update(w, sign_ct, Pcur + MVPsign, Pnew[MVPsign], *Pupdate++, updated);
+
+    {
+        const vp8_prob *const new_p = Pnew + MVPshort;
+        vp8_prob *const cur_p = Pcur + MVPshort;
+
+        int j = 0;
+
+        do
+
+            update(w, short_bct[j], cur_p + j, new_p[j], *Pupdate++, updated);
+
+        while (++j < mvnum_short - 1);
+    }
+
+    {
+        const vp8_prob *const new_p = Pnew + MVPbits;
+        vp8_prob *const cur_p = Pcur + MVPbits;
+
+        int j = 0;
+
+        do
+
+            update(w, bit_ct[j], cur_p + j, new_p[j], *Pupdate++, updated);
+
+        while (++j < mvlong_width);
+    }
+}
+
+void vp8_write_mvprobs(VP8_COMP *cpi)
+{
+    vp8_writer *const w  = & cpi->bc;
+    MV_CONTEXT *mvc = cpi->common.fc.mvc;
+    int flags[2] = {0, 0};
+#ifdef ENTROPY_STATS
+    active_section = 4;
+#endif
+    write_component_probs(
+        w, &mvc[0], &vp8_default_mv_context[0], &vp8_mv_update_probs[0], cpi->MVcount[0], 0, &flags[0]
+    );
+    write_component_probs(
+        w, &mvc[1], &vp8_default_mv_context[1], &vp8_mv_update_probs[1], cpi->MVcount[1], 1, &flags[1]
+    );
+
+    if (flags[0] || flags[1])
+        vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flags);
+
+#ifdef ENTROPY_STATS
+    active_section = 5;
+#endif
+}
diff --git a/vp8/encoder/encodemv.h b/vp8/encoder/encodemv.h
new file mode 100644 (file)
index 0000000..1c1f450
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_ENCODEMV_H
+#define __INC_ENCODEMV_H
+
+#include "onyx_int.h"
+
+void vp8_write_mvprobs(VP8_COMP *);
+void vp8_encode_motion_vector(vp8_writer *, const MV *, const MV_CONTEXT *);
+void vp8_build_component_cost_table(int *mvcost[2], int *mvsadcost[2], const MV_CONTEXT *mvc, int mvc_flag[2]);
+
+#endif
diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c
new file mode 100644 (file)
index 0000000..a0b50d2
--- /dev/null
@@ -0,0 +1,510 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyx_int.h"
+#include "threading.h"
+#include "common.h"
+#include "extend.h"
+
+
+extern int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t, int recon_yoffset, int recon_uvoffset);
+extern int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t);
+extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
+extern void vp8_build_block_offsets(MACROBLOCK *x);
+extern void vp8_setup_block_ptrs(MACROBLOCK *x);
+
+static
+THREAD_FUNCTION thread_encoding_proc(void *p_data)
+{
+#if CONFIG_MULTITHREAD
+    int ithread = ((ENCODETHREAD_DATA *)p_data)->ithread;
+    VP8_COMP *cpi   = (VP8_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr1);
+    MB_ROW_COMP *mbri = (MB_ROW_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr2);
+    ENTROPY_CONTEXT mb_row_left_context[4][4];
+
+    //printf("Started thread %d\n", ithread);
+
+    while (1)
+    {
+        if (cpi->b_multi_threaded == 0)
+            break;
+
+        //if(WaitForSingleObject(cpi->h_event_mbrencoding[ithread], INFINITE) == WAIT_OBJECT_0)
+        if (sem_wait(&cpi->h_event_mbrencoding[ithread]) == 0)
+        {
+            if (cpi->b_multi_threaded == FALSE) // we're shutting down
+                break;
+            else
+            {
+                VP8_COMMON *cm      = &cpi->common;
+                int mb_row           = mbri->mb_row;
+                MACROBLOCK  *x      = &mbri->mb;
+                MACROBLOCKD *xd     = &x->e_mbd;
+                TOKENEXTRA **tp     = &mbri->tp;
+                int *segment_counts  = mbri->segment_counts;
+                int *totalrate      = &mbri->totalrate;
+
+                {
+                    int i;
+                    int recon_yoffset, recon_uvoffset;
+                    int mb_col;
+                    int recon_y_stride = cm->last_frame.y_stride;
+                    int recon_uv_stride = cm->last_frame.uv_stride;
+                    volatile int *last_row_current_mb_col;
+
+                    if (ithread > 0)
+                        last_row_current_mb_col = &cpi->mb_row_ei[ithread-1].current_mb_col;
+                    else
+                        last_row_current_mb_col = &cpi->current_mb_col_main;
+
+                    // reset above block coeffs
+                    xd->above_context[Y1CONTEXT] = cm->above_context[Y1CONTEXT];
+                    xd->above_context[UCONTEXT ] = cm->above_context[UCONTEXT ];
+                    xd->above_context[VCONTEXT ] = cm->above_context[VCONTEXT ];
+                    xd->above_context[Y2CONTEXT] = cm->above_context[Y2CONTEXT];
+                    xd->left_context = mb_row_left_context;
+
+                    vp8_zero(mb_row_left_context);
+
+                    xd->up_available = (mb_row != 0);
+                    recon_yoffset = (mb_row * recon_y_stride * 16);
+                    recon_uvoffset = (mb_row * recon_uv_stride * 8);
+
+
+                    cpi->tplist[mb_row].start = *tp;
+
+                    //printf("Thread mb_row = %d\n", mb_row);
+
+                    // for each macroblock col in image
+                    for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+                    {
+                        int seg_map_index = (mb_row * cm->mb_cols);
+
+                        while (mb_col > (*last_row_current_mb_col - 1) && *last_row_current_mb_col != cm->mb_cols - 1)
+                        {
+                            x86_pause_hint();
+                            thread_sleep(0);
+                        }
+
+                        // Distance of Mb to the various image edges.
+                        // These specified to 8th pel as they are always compared to values that are in 1/8th pel units
+                        xd->mb_to_left_edge = -((mb_col * 16) << 3);
+                        xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
+                        xd->mb_to_top_edge = -((mb_row * 16) << 3);
+                        xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
+
+                        // Set up limit values for motion vectors used to prevent them extending outside the UMV borders
+                        x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
+                        x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
+                        x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
+                        x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);
+
+                        xd->dst.y_buffer = cm->new_frame.y_buffer + recon_yoffset;
+                        xd->dst.u_buffer = cm->new_frame.u_buffer + recon_uvoffset;
+                        xd->dst.v_buffer = cm->new_frame.v_buffer + recon_uvoffset;
+                        xd->left_available = (mb_col != 0);
+
+                        // Is segmentation enabled
+                        // MB level adjutment to quantizer
+                        if (xd->segmentation_enabled)
+                        {
+                            // Code to set segment id in xd->mbmi.segment_id for current MB (with range checking)
+                            if (cpi->segmentation_map[seg_map_index+mb_col] <= 3)
+                                xd->mbmi.segment_id = cpi->segmentation_map[seg_map_index+mb_col];
+                            else
+                                xd->mbmi.segment_id = 0;
+
+                            vp8cx_mb_init_quantizer(cpi, x);
+                        }
+                        else
+                            xd->mbmi.segment_id = 0;         // Set to Segment 0 by default
+
+
+                        if (cm->frame_type == KEY_FRAME)
+                        {
+                            *totalrate += vp8cx_encode_intra_macro_block(cpi, x, tp);
+#ifdef MODE_STATS
+                            y_modes[xd->mbmi.mode] ++;
+#endif
+                        }
+                        else
+                        {
+                            *totalrate += vp8cx_encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset);
+
+#ifdef MODE_STATS
+                            inter_y_modes[xd->mbmi.mode] ++;
+
+                            if (xd->mbmi.mode == SPLITMV)
+                            {
+                                int b;
+
+                                for (b = 0; b < xd->mbmi.partition_count; b++)
+                                {
+                                    inter_b_modes[xd->mbmi.partition_bmi[b].mode] ++;
+                                }
+                            }
+
+#endif
+
+                            // Count of last ref frame 0,0 useage
+                            if ((xd->mbmi.mode == ZEROMV) && (xd->mbmi.ref_frame == LAST_FRAME))
+                                cpi->inter_zz_count ++;
+
+                        }
+
+                        cpi->tplist[mb_row].stop = *tp;
+
+                        xd->gf_active_ptr++;      // Increment pointer into gf useage flags structure for next mb
+
+                        // store macroblock mode info into context array
+                        vpx_memcpy(&xd->mode_info_context->mbmi, &xd->mbmi, sizeof(xd->mbmi));
+
+                        for (i = 0; i < 16; i++)
+                            vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi));
+
+                        // adjust to the next column of macroblocks
+                        x->src.y_buffer += 16;
+                        x->src.u_buffer += 8;
+                        x->src.v_buffer += 8;
+
+                        recon_yoffset += 16;
+                        recon_uvoffset += 8;
+
+                        // Keep track of segment useage
+                        segment_counts[xd->mbmi.segment_id] ++;
+
+                        // skip to next mb
+                        xd->mode_info_context++;
+
+                        xd->above_context[Y1CONTEXT] += 4;
+                        xd->above_context[UCONTEXT ] += 2;
+                        xd->above_context[VCONTEXT ] += 2;
+                        xd->above_context[Y2CONTEXT] ++;
+
+                        cpi->mb_row_ei[ithread].current_mb_col = mb_col;
+
+                    }
+
+                    //extend the recon for intra prediction
+                    vp8_extend_mb_row(
+                        &cm->new_frame,
+                        xd->dst.y_buffer + 16,
+                        xd->dst.u_buffer + 8,
+                        xd->dst.v_buffer + 8);
+
+                    // this is to account for the border
+                    xd->mode_info_context++;
+
+                    x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
+                    x->src.u_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
+                    x->src.v_buffer +=  8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
+
+                    xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
+
+                    if (ithread == (cpi->encoding_thread_count - 1) || mb_row == cm->mb_rows - 1)
+                    {
+                        //SetEvent(cpi->h_event_main);
+                        sem_post(&cpi->h_event_main);
+                    }
+
+                }
+
+            }
+        }
+    }
+
+#else
+    (void) p_data;
+#endif
+
+    //printf("exit thread %d\n", ithread);
+    return 0;
+}
+
+static void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc)
+{
+
+    MACROBLOCK *x = mbsrc;
+    MACROBLOCK *z = mbdst;
+    int i;
+
+    z->ss               = x->ss;
+    z->ss_count          = x->ss_count;
+    z->searches_per_step  = x->searches_per_step;
+    z->errorperbit      = x->errorperbit;
+
+    z->sadperbit16      = x->sadperbit16;
+    z->sadperbit4       = x->sadperbit4;
+    z->errthresh        = x->errthresh;
+    z->rddiv            = x->rddiv;
+    z->rdmult           = x->rdmult;
+
+    /*
+    z->mv_col_min    = x->mv_col_min;
+    z->mv_col_max    = x->mv_col_max;
+    z->mv_row_min    = x->mv_row_min;
+    z->mv_row_max    = x->mv_row_max;
+    z->vector_range = x->vector_range ;
+    */
+
+    z->vp8_short_fdct4x4     = x->vp8_short_fdct4x4;
+    z->vp8_short_fdct8x4     = x->vp8_short_fdct8x4;
+    z->short_fdct4x4rd   = x->short_fdct4x4rd;
+    z->short_fdct8x4rd   = x->short_fdct8x4rd;
+    z->short_fdct8x4rd   = x->short_fdct8x4rd;
+    z->vp8_short_fdct4x4_ptr = x->vp8_short_fdct4x4_ptr;
+    z->short_walsh4x4    = x->short_walsh4x4;
+    z->quantize_b        = x->quantize_b;
+    z->quantize_brd      = x->quantize_brd;
+
+    /*
+    z->mvc              = x->mvc;
+    z->src.y_buffer      = x->src.y_buffer;
+    z->src.u_buffer      = x->src.u_buffer;
+    z->src.v_buffer      = x->src.v_buffer;
+    */
+
+
+    vpx_memcpy(z->mvcosts,          x->mvcosts,         sizeof(x->mvcosts));
+    z->mvcost[0] = &z->mvcosts[0][mv_max+1];
+    z->mvcost[1] = &z->mvcosts[1][mv_max+1];
+    z->mvsadcost[0] = &z->mvsadcosts[0][mv_max+1];
+    z->mvsadcost[1] = &z->mvsadcosts[1][mv_max+1];
+
+
+    vpx_memcpy(z->token_costs,       x->token_costs,      sizeof(x->token_costs));
+    vpx_memcpy(z->inter_bmode_costs,  x->inter_bmode_costs, sizeof(x->inter_bmode_costs));
+    //memcpy(z->mvcosts,            x->mvcosts,         sizeof(x->mvcosts));
+    //memcpy(z->mvcost,         x->mvcost,          sizeof(x->mvcost));
+    vpx_memcpy(z->mbmode_cost,       x->mbmode_cost,      sizeof(x->mbmode_cost));
+    vpx_memcpy(z->intra_uv_mode_cost,  x->intra_uv_mode_cost, sizeof(x->intra_uv_mode_cost));
+    vpx_memcpy(z->bmode_costs,       x->bmode_costs,      sizeof(x->bmode_costs));
+
+    for (i = 0; i < 25; i++)
+    {
+        z->block[i].quant           = x->block[i].quant;
+        z->block[i].zbin            = x->block[i].zbin;
+        z->block[i].zrun_zbin_boost   = x->block[i].zrun_zbin_boost;
+        z->block[i].round           = x->block[i].round;
+        /*
+        z->block[i].src             = x->block[i].src;
+        */
+        z->block[i].src_stride       = x->block[i].src_stride;
+        z->block[i].force_empty      = x->block[i].force_empty;
+
+    }
+
+    {
+        MACROBLOCKD *xd = &x->e_mbd;
+        MACROBLOCKD *zd = &z->e_mbd;
+
+        /*
+        zd->mode_info_context = xd->mode_info_context;
+        zd->mode_info        = xd->mode_info;
+
+        zd->mode_info_stride  = xd->mode_info_stride;
+        zd->frame_type       = xd->frame_type;
+        zd->up_available     = xd->up_available   ;
+        zd->left_available   = xd->left_available;
+        zd->left_context     = xd->left_context;
+        zd->last_frame_dc     = xd->last_frame_dc;
+        zd->last_frame_dccons = xd->last_frame_dccons;
+        zd->gold_frame_dc     = xd->gold_frame_dc;
+        zd->gold_frame_dccons = xd->gold_frame_dccons;
+        zd->mb_to_left_edge    = xd->mb_to_left_edge;
+        zd->mb_to_right_edge   = xd->mb_to_right_edge;
+        zd->mb_to_top_edge     = xd->mb_to_top_edge   ;
+        zd->mb_to_bottom_edge  = xd->mb_to_bottom_edge;
+        zd->gf_active_ptr     = xd->gf_active_ptr;
+        zd->frames_since_golden       = xd->frames_since_golden;
+        zd->frames_till_alt_ref_frame   = xd->frames_till_alt_ref_frame;
+        */
+        zd->subpixel_predict         = xd->subpixel_predict;
+        zd->subpixel_predict8x4      = xd->subpixel_predict8x4;
+        zd->subpixel_predict8x8      = xd->subpixel_predict8x8;
+        zd->subpixel_predict16x16    = xd->subpixel_predict16x16;
+        zd->segmentation_enabled     = xd->segmentation_enabled;
+        zd->mb_segement_abs_delta      = xd->mb_segement_abs_delta;
+        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data, sizeof(xd->segment_feature_data));
+
+        /*
+        memcpy(zd->above_context,        xd->above_context, sizeof(xd->above_context));
+        memcpy(zd->mb_segment_tree_probs,  xd->mb_segment_tree_probs, sizeof(xd->mb_segment_tree_probs));
+        memcpy(zd->segment_feature_data,  xd->segment_feature_data, sizeof(xd->segment_feature_data));
+        */
+        for (i = 0; i < 25; i++)
+        {
+            zd->block[i].dequant = xd->block[i].dequant;
+        }
+    }
+}
+
+
+void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
+                               MACROBLOCK *x,
+                               MB_ROW_COMP *mbr_ei,
+                               int mb_row,
+                               int count
+                              )
+{
+
+    VP8_COMMON *const cm = & cpi->common;
+    MACROBLOCKD *const xd = & x->e_mbd;
+    int i;
+    (void) mb_row;
+
+    for (i = 0; i < count; i++)
+    {
+        MACROBLOCK *mb = & mbr_ei[i].mb;
+        MACROBLOCKD *mbd = &mb->e_mbd;
+
+        mbd->subpixel_predict        = xd->subpixel_predict;
+        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
+        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
+        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
+#if CONFIG_RUNTIME_CPU_DETECT
+        mbd->rtcd                   = xd->rtcd;
+#endif
+        mbd->gf_active_ptr            = xd->gf_active_ptr;
+
+        mb->vector_range             = 32;
+
+        vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts));
+        mbr_ei[i].totalrate = 0;
+
+        mbd->mode_info        = cm->mi - 1;
+        mbd->mode_info_context = cm->mi   + x->e_mbd.mode_info_stride * (i + 1);
+        mbd->mode_info_stride  = cm->mode_info_stride;
+
+        mbd->frame_type = cm->frame_type;
+
+        mbd->frames_since_golden = cm->frames_since_golden;
+        mbd->frames_till_alt_ref_frame = cm->frames_till_alt_ref_frame;
+
+        mb->src = * cpi->Source;
+        mbd->pre = cm->last_frame;
+        mbd->dst = cm->new_frame;
+
+        mb->src.y_buffer += 16 * x->src.y_stride * (i + 1);
+        mb->src.u_buffer +=  8 * x->src.uv_stride * (i + 1);
+        mb->src.v_buffer +=  8 * x->src.uv_stride * (i + 1);
+
+
+        vp8_build_block_offsets(mb);
+
+        vp8_setup_block_dptrs(mbd);
+
+        vp8_setup_block_ptrs(mb);
+
+        mb->rddiv = cpi->RDDIV;
+        mb->rdmult = cpi->RDMULT;
+
+        mbd->mbmi.mode = DC_PRED;
+        mbd->mbmi.uv_mode = DC_PRED;
+
+        mbd->left_context = cm->left_context;
+        mb->mvc = cm->fc.mvc;
+
+        setup_mbby_copy(&mbr_ei[i].mb, x);
+
+    }
+}
+
+
+void vp8cx_create_encoder_threads(VP8_COMP *cpi)
+{
+    cpi->b_multi_threaded = 0;
+
+    cpi->processor_core_count = 32; //vp8_get_proc_core_count();
+
+    CHECK_MEM_ERROR(cpi->tplist, vpx_malloc(sizeof(TOKENLIST) * cpi->common.mb_rows));
+
+#if CONFIG_MULTITHREAD
+
+    if (cpi->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1)
+    {
+        int ithread;
+
+        if (cpi->oxcf.multi_threaded > cpi->processor_core_count)
+            cpi->encoding_thread_count = cpi->processor_core_count - 1;
+        else
+            cpi->encoding_thread_count = cpi->oxcf.multi_threaded - 1;
+
+
+        CHECK_MEM_ERROR(cpi->h_encoding_thread, vpx_malloc(sizeof(pthread_t) * cpi->encoding_thread_count));
+        CHECK_MEM_ERROR(cpi->h_event_mbrencoding, vpx_malloc(sizeof(sem_t) * cpi->encoding_thread_count));
+        CHECK_MEM_ERROR(cpi->mb_row_ei, vpx_memalign(32, sizeof(MB_ROW_COMP) * cpi->encoding_thread_count));
+        vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * cpi->encoding_thread_count);
+        CHECK_MEM_ERROR(cpi->en_thread_data, vpx_malloc(sizeof(ENCODETHREAD_DATA) * cpi->encoding_thread_count));
+        //cpi->h_event_main = CreateEvent(NULL, FALSE, FALSE, NULL);
+        sem_init(&cpi->h_event_main, 0, 0);
+
+        cpi->b_multi_threaded = 1;
+
+        //printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n", (cpi->encoding_thread_count +1));
+
+        for (ithread = 0; ithread < cpi->encoding_thread_count; ithread++)
+        {
+            //cpi->h_event_mbrencoding[ithread] = CreateEvent(NULL, FALSE, FALSE, NULL);
+            sem_init(&cpi->h_event_mbrencoding[ithread], 0, 0);
+            cpi->en_thread_data[ithread].ithread = ithread;
+            cpi->en_thread_data[ithread].ptr1 = (void *)cpi;
+            cpi->en_thread_data[ithread].ptr2 = (void *)&cpi->mb_row_ei[ithread];
+
+            //printf(" call begin thread %d \n", ithread);
+
+            //cpi->h_encoding_thread[ithread] =   (HANDLE)_beginthreadex(
+            //  NULL,           // security
+            //  0,              // stksize
+            //  thread_encoding_proc,
+            //  (&cpi->en_thread_data[ithread]),          // Thread data
+            //  0,
+            //  NULL);
+
+            pthread_create(&cpi->h_encoding_thread[ithread], 0, thread_encoding_proc, (&cpi->en_thread_data[ithread]));
+
+        }
+
+    }
+
+#endif
+}
+
+void vp8cx_remove_encoder_threads(VP8_COMP *cpi)
+{
+#if CONFIG_MULTITHREAD
+
+    if (cpi->b_multi_threaded)
+    {
+        //shutdown other threads
+        cpi->b_multi_threaded = 0;
+        {
+            int i;
+
+            for (i = 0; i < cpi->encoding_thread_count; i++)
+            {
+                //SetEvent(cpi->h_event_mbrencoding[i]);
+                sem_post(&cpi->h_event_mbrencoding[i]);
+                pthread_join(cpi->h_encoding_thread[i], 0);
+            }
+
+            for (i = 0; i < cpi->encoding_thread_count; i++)
+                sem_destroy(&cpi->h_event_mbrencoding[i]);
+        }
+        //free thread related resources
+        vpx_free(cpi->h_event_mbrencoding);
+        vpx_free(cpi->h_encoding_thread);
+        vpx_free(cpi->mb_row_ei);
+        vpx_free(cpi->en_thread_data);
+    }
+
+#endif
+    vpx_free(cpi->tplist);
+}
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
new file mode 100644 (file)
index 0000000..c519080
--- /dev/null
@@ -0,0 +1,2512 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "math.h"
+#include "limits.h"
+#include "block.h"
+#include "onyx_int.h"
+#include "variance.h"
+#include "encodeintra.h"
+#include "setupintrarecon.h"
+#include "mcomp.h"
+#include "vpx_scale/vpxscale.h"
+#include "encodemb.h"
+#include "extend.h"
+#include "systemdependent.h"
+#include "vpx_scale/yv12extend.h"
+#include "vpx_mem/vpx_mem.h"
+#include "swapyv12buffer.h"
+#include <stdio.h>
+#include "rdopt.h"
+#include "quant_common.h"
+#include "encodemv.h"
+
+//#define OUTPUT_FPF 1
+//#define FIRSTPASS_MM 1
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x) (x)
+#else
+#define IF_RTCD(x) NULL
+#endif
+
+extern void vp8_build_block_offsets(MACROBLOCK *x);
+extern void vp8_setup_block_ptrs(MACROBLOCK *x);
+extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);
+extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, MV *mv);
+extern void vp8_alloc_compressor_data(VP8_COMP *cpi);
+
+//#define GFQ_ADJUSTMENT (40 + ((15*Q)/10))
+//#define GFQ_ADJUSTMENT (80 + ((15*Q)/10))
+#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q]
+extern int vp8_kf_boost_qadjustment[QINDEX_RANGE];
+
+extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
+
+#define IIFACTOR   1.4
+#define IIKFACTOR1 1.40
+#define IIKFACTOR2 1.5
+#define RMAX    14.0
+#define GF_RMAX 48.0        // 128.0
+
+#define DOUBLE_DIVIDE_CHECK(X) ((X)<0?(X)-.000001:(X)+.000001)
+
+#define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0
+#define POW2 (double)cpi->oxcf.two_pass_vbrbias/100.0
+
+static int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3};
+static int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3};
+
+
+void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame);
+int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps);
+
+int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_dc_pred)
+{
+
+    int i;
+    int intra_pred_var = 0;
+    (void) cpi;
+
+    if (use_dc_pred)
+    {
+        x->e_mbd.mbmi.mode = DC_PRED;
+        x->e_mbd.mbmi.uv_mode = DC_PRED;
+        x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
+
+        vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
+    }
+    else
+    {
+        for (i = 0; i < 16; i++)
+        {
+            BLOCKD *b = &x->e_mbd.block[i];
+            BLOCK  *be = &x->block[i];
+
+            vp8_encode_intra4x4block(IF_RTCD(&cpi->rtcd), x, be, b, B_DC_PRED);
+        }
+    }
+
+    intra_pred_var = VARIANCE_INVOKE(&cpi->rtcd.variance, getmbss)(x->src_diff);
+
+    return intra_pred_var;
+}
+
+// Resets the first pass file to the given position using a relative seek from the current position
+static void reset_fpf_position(VP8_COMP *cpi, FIRSTPASS_STATS *Position)
+{
+    cpi->stats_in = Position;
+}
+
+static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
+{
+    /*FIRSTPASS_STATS * start_pos;
+    int ret_val;
+
+    start_pos = cpi->stats_in;
+    ret_val = vp8_input_stats(cpi, next_frame);
+    reset_fpf_position(cpi, start_pos);
+
+    return ret_val;*/
+
+    if (cpi->stats_in >= cpi->stats_in_end)
+        return EOF;
+
+    *next_frame = *cpi->stats_in;
+    return 1;
+}
+
+// Calculate a modified Error used in distributing bits between easier and harder frames
+static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
+{
+    double av_err = cpi->total_stats.ssim_weighted_pred_err;
+    double this_err = this_frame->ssim_weighted_pred_err;
+    double modified_err;
+
+    //double relative_next_iiratio;
+    //double next_iiratio;
+    //double sum_iiratio;
+    //int i;
+
+    //FIRSTPASS_STATS next_frame;
+    //FIRSTPASS_STATS *start_pos;
+
+    /*start_pos = cpi->stats_in;
+    sum_iiratio = 0.0;
+    i = 0;
+    while ( (i < 1) && vp8_input_stats(cpi,&next_frame) != EOF )
+    {
+
+        next_iiratio = next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error);
+        next_iiratio = ( next_iiratio < 1.0 ) ? 1.0 : (next_iiratio > 20.0) ? 20.0 : next_iiratio;
+        sum_iiratio += next_iiratio;
+        i++;
+    }
+    if ( i > 0 )
+    {
+        relative_next_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK(cpi->avg_iiratio * (double)i);
+    }
+    else
+    {
+        relative_next_iiratio = 1.0;
+    }
+    reset_fpf_position(cpi, start_pos);*/
+
+    if (this_err > av_err)
+        modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1);
+    else
+        modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2);
+
+    /*
+    relative_next_iiratio = pow(relative_next_iiratio,0.25);
+    modified_err = modified_err * relative_next_iiratio;
+    */
+
+    return modified_err;
+}
+
+double vp8_simple_weight(YV12_BUFFER_CONFIG *source)
+{
+    int i, j;
+    int Total = 0;
+
+    unsigned char *src = source->y_buffer;
+    unsigned char value;
+    double sum_weights = 0.0;
+    double Weight;
+
+    // Loop throught the Y plane raw examining levels and creating a weight for the image
+    for (i = 0; i < source->y_height; i++)
+    {
+        for (j = 0; j < source->y_width; j++)
+        {
+            value = src[j];
+
+            if (value >= 64)
+                Weight = 1.0;
+            else if (value > 32)
+                Weight = (value - 32.0f) / 32.0f;
+            else
+                Weight = 0.02;
+
+            sum_weights += Weight;
+        }
+
+        src += source->y_stride;
+    }
+
+    sum_weights /= (source->y_height * source->y_width);
+
+    return sum_weights;
+}
+
+// This function returns the current per frame maximum bitrate target
+int frame_max_bits(VP8_COMP *cpi)
+{
+    // Max allocation for a single frame based on the max section guidelines passed in and how many bits are left
+    int max_bits;
+
+    // For CBR we need to also consider buffer fullness.
+    // If we are running below the optimal level then we need to gradually tighten up on max_bits.
+    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+    {
+        double buffer_fullness_ratio = (double)DOUBLE_DIVIDE_CHECK(cpi->buffer_level) / (double)cpi->oxcf.optimal_buffer_level;
+
+        // For CBR base this on the target average bits per frame plus the maximum sedction rate passed in by the user
+        max_bits = (int)(cpi->av_per_frame_bandwidth * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
+
+        // If our buffer is below the optimum level
+        if (buffer_fullness_ratio < 1.0)
+        {
+            // The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4.
+            int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) ? cpi->av_per_frame_bandwidth >> 2 : max_bits >> 2;
+
+            max_bits = (int)(max_bits * buffer_fullness_ratio);
+
+            if (max_bits < min_max_bits)
+                max_bits = min_max_bits;       // Lowest value we will set ... which should allow the buffer to refil.
+        }
+    }
+    // VBR
+    else
+    {
+        // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
+        max_bits = (int)(((double)cpi->bits_left / (cpi->total_stats.count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
+    }
+
+    // Trap case where we are out of bits
+    if (max_bits < 0)
+        max_bits = 0;
+
+    return max_bits;
+}
+
+void vp8_output_stats(struct vpx_codec_pkt_list *pktlist,
+                      FIRSTPASS_STATS            *stats)
+{
+    struct vpx_codec_cx_pkt pkt;
+    pkt.kind = VPX_CODEC_STATS_PKT;
+    pkt.data.twopass_stats.buf = stats;
+    pkt.data.twopass_stats.sz = sizeof(*stats);
+    vpx_codec_pkt_list_add(pktlist, &pkt);
+
+// TEMP debug code
+#ifdef OUTPUT_FPF
+    {
+        FILE *fpfile;
+        fpfile = fopen("firstpass.stt", "a");
+
+        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.0f\n",
+                stats->frame,
+                stats->intra_error,
+                stats->coded_error,
+                stats->ssim_weighted_pred_err,
+                stats->pcnt_inter,
+                stats->pcnt_motion,
+                stats->pcnt_second_ref,
+                stats->MVr,
+                stats->mvr_abs,
+                stats->MVc,
+                stats->mvc_abs,
+                stats->MVrv,
+                stats->MVcv,
+                stats->mv_in_out_count,
+                stats->count);
+        fclose(fpfile);
+    }
+#endif
+}
+
+int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
+{
+    if (cpi->stats_in >= cpi->stats_in_end)
+        return EOF;
+
+    *fps = *cpi->stats_in++;
+    return 1;
+}
+
+void vp8_zero_stats(FIRSTPASS_STATS *section)
+{
+    section->frame      = 0.0;
+    section->intra_error = 0.0;
+    section->coded_error = 0.0;
+    section->ssim_weighted_pred_err = 0.0;
+    section->pcnt_inter  = 0.0;
+    section->pcnt_motion  = 0.0;
+    section->pcnt_second_ref = 0.0;
+    section->MVr        = 0.0;
+    section->mvr_abs     = 0.0;
+    section->MVc        = 0.0;
+    section->mvc_abs     = 0.0;
+    section->MVrv       = 0.0;
+    section->MVcv       = 0.0;
+    section->mv_in_out_count  = 0.0;
+    section->count      = 0.0;
+    section->duration   = 1.0;
+}
+void vp8_accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
+{
+    section->frame += frame->frame;
+    section->intra_error += frame->intra_error;
+    section->coded_error += frame->coded_error;
+    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
+    section->pcnt_inter  += frame->pcnt_inter;
+    section->pcnt_motion += frame->pcnt_motion;
+    section->pcnt_second_ref += frame->pcnt_second_ref;
+    section->MVr        += frame->MVr;
+    section->mvr_abs     += frame->mvr_abs;
+    section->MVc        += frame->MVc;
+    section->mvc_abs     += frame->mvc_abs;
+    section->MVrv       += frame->MVrv;
+    section->MVcv       += frame->MVcv;
+    section->mv_in_out_count  += frame->mv_in_out_count;
+    section->count      += frame->count;
+    section->duration   += frame->duration;
+}
+void vp8_avg_stats(FIRSTPASS_STATS *section)
+{
+    if (section->count < 1.0)
+        return;
+
+    section->intra_error /= section->count;
+    section->coded_error /= section->count;
+    section->ssim_weighted_pred_err /= section->count;
+    section->pcnt_inter  /= section->count;
+    section->pcnt_second_ref /= section->count;
+    section->pcnt_motion /= section->count;
+    section->MVr        /= section->count;
+    section->mvr_abs     /= section->count;
+    section->MVc        /= section->count;
+    section->mvc_abs     /= section->count;
+    section->MVrv       /= section->count;
+    section->MVcv       /= section->count;
+    section->mv_in_out_count   /= section->count;
+    section->duration   /= section->count;
+}
+
+int vp8_fpmm_get_pos(VP8_COMP *cpi)
+{
+    return ftell(cpi->fp_motion_mapfile);
+}
+void vp8_fpmm_reset_pos(VP8_COMP *cpi, int target_pos)
+{
+    int Offset;
+
+    if (cpi->fp_motion_mapfile)
+    {
+        Offset = ftell(cpi->fp_motion_mapfile) - target_pos;
+        fseek(cpi->fp_motion_mapfile, (int) - Offset, SEEK_CUR);
+    }
+}
+
+void vp8_advance_fpmm(VP8_COMP *cpi, int count)
+{
+#ifdef FIRSTPASS_MM
+    fseek(cpi->fp_motion_mapfile, (int)(count * cpi->common.MBs), SEEK_CUR);
+#endif
+}
+
+void vp8_input_fpmm(VP8_COMP *cpi, int count)
+{
+#ifdef FIRSTPASS_MM
+
+    unsigned char *tmp_motion_map;
+    int i, j;
+
+    if (!cpi->fp_motion_mapfile)
+        return;                 // Error
+
+    // Create the first pass motion map structure and set to 0
+    CHECK_MEM_ERROR(tmp_motion_map, vpx_calloc(cpi->common.MBs, 1));
+
+    // Reset the state of the global map
+    vpx_memset(cpi->fp_motion_map, 0, cpi->common.MBs);
+
+    // Read the specified number of frame maps and set the global map to the highest value seen for each mb.
+    for (i = 0; i < count; i++)
+    {
+        if (fread(tmp_motion_map, 1, cpi->common.MBs, cpi->fp_motion_mapfile) == cpi->common.MBs)
+        {
+            for (j = 0; j < cpi->common.MBs; j++)
+            {
+                if (tmp_motion_map[j] > 1)
+                    cpi->fp_motion_map[j] += 5;   // Intra is flagged
+                else
+                    cpi->fp_motion_map[j] += tmp_motion_map[j];
+            }
+        }
+        else
+            break;  // Read error
+
+    }
+
+    if (tmp_motion_map != 0)
+        vpx_free(tmp_motion_map);
+
+#endif
+
+}
+
+void vp8_init_first_pass(VP8_COMP *cpi)
+{
+    vp8_zero_stats(&cpi->total_stats);
+
+#ifdef FIRSTPASS_MM
+    cpi->fp_motion_mapfile = fopen("fpmotionmap.stt", "wb");
+#endif
+
+// TEMP debug code
+#ifdef OUTPUT_FPF
+    {
+        FILE *fpfile;
+        fpfile = fopen("firstpass.stt", "w");
+        fclose(fpfile);
+    }
+#endif
+
+}
+
+void vp8_end_first_pass(VP8_COMP *cpi)
+{
+    vp8_output_stats(cpi->output_pkt_list, &cpi->total_stats);
+
+#ifdef FIRSTPASS_MM
+
+    if (cpi->fp_motion_mapfile)
+        fclose(cpi->fp_motion_mapfile);
+
+#endif
+
+}
+void vp8_zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x, YV12_BUFFER_CONFIG * recon_buffer, int * best_motion_err, int recon_yoffset )
+{
+    MACROBLOCKD * const xd = & x->e_mbd;
+    BLOCK *b = &x->block[0];
+    BLOCKD *d = &x->e_mbd.block[0];
+
+    unsigned char *src_ptr = (*(b->base_src) + b->src);
+    int src_stride = b->src_stride;
+    unsigned char *ref_ptr;
+    int ref_stride=d->pre_stride;
+
+    // Set up pointers for this macro block recon buffer
+    xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;
+
+    ref_ptr = (unsigned char *)(*(d->base_pre) + d->pre );
+
+    VARIANCE_INVOKE(IF_RTCD(&cpi->rtcd.variance), mse16x16) ( src_ptr, src_stride, ref_ptr, ref_stride, (unsigned int *)(best_motion_err));
+}
+
+
+void vp8_first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x, MV *ref_mv, MV *best_mv, YV12_BUFFER_CONFIG *recon_buffer, int *best_motion_err, int recon_yoffset )
+{
+    MACROBLOCKD *const xd = & x->e_mbd;
+    BLOCK *b = &x->block[0];
+    BLOCKD *d = &x->e_mbd.block[0];
+    int num00;
+
+    MV tmp_mv = {0, 0};
+
+    int tmp_err;
+    int step_param = 3;                                       //3;          // Dont search over full range for first pass
+    int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; //3;
+    int n;
+    vp8_variance_fn_ptr_t v_fn_ptr;
+    int new_mv_mode_penalty = 256;
+
+    v_fn_ptr.vf    = VARIANCE_INVOKE(IF_RTCD(&cpi->rtcd.variance), mse16x16);
+    v_fn_ptr.sdf   = cpi->fn_ptr.sdf;
+    v_fn_ptr.sdx4df = cpi->fn_ptr.sdx4df;
+
+    // Set up pointers for this macro block recon buffer
+    xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;
+
+    // Initial step/diamond search centred on best mv
+    tmp_err = cpi->diamond_search_sad(x, b, d, ref_mv, &tmp_mv, step_param, x->errorperbit, &num00, &v_fn_ptr, x->mvsadcost, x->mvcost);
+    if ( tmp_err < INT_MAX-new_mv_mode_penalty )
+        tmp_err += new_mv_mode_penalty;
+
+    if (tmp_err < *best_motion_err)
+    {
+        *best_motion_err = tmp_err;
+        best_mv->row = tmp_mv.row;
+        best_mv->col = tmp_mv.col;
+    }
+
+    // Further step/diamond searches as necessary
+    n = num00;
+    num00 = 0;
+
+    while (n < further_steps)
+    {
+        n++;
+
+        if (num00)
+            num00--;
+        else
+        {
+            tmp_err = cpi->diamond_search_sad(x, b, d, ref_mv, &tmp_mv, step_param + n, x->errorperbit, &num00, &v_fn_ptr, x->mvsadcost, x->mvcost);
+            if ( tmp_err < INT_MAX-new_mv_mode_penalty )
+                tmp_err += new_mv_mode_penalty;
+
+            if (tmp_err < *best_motion_err)
+            {
+                *best_motion_err = tmp_err;
+                best_mv->row = tmp_mv.row;
+                best_mv->col = tmp_mv.col;
+            }
+        }
+    }
+}
+
+void vp8_first_pass(VP8_COMP *cpi)
+{
+    int mb_row, mb_col;
+    MACROBLOCK *const x = & cpi->mb;
+    VP8_COMMON *const cm = & cpi->common;
+    MACROBLOCKD *const xd = & x->e_mbd;
+
+    int col_blocks = 4 * cm->mb_cols;
+    int recon_yoffset, recon_uvoffset;
+    int recon_y_stride = cm->last_frame.y_stride;
+    int recon_uv_stride = cm->last_frame.uv_stride;
+    int intra_error = 0;
+    int coded_error = 0;
+
+    int sum_mvr = 0, sum_mvc = 0;
+    int sum_mvr_abs = 0, sum_mvc_abs = 0;
+    int sum_mvrs = 0, sum_mvcs = 0;
+    int mvcount = 0;
+    int intercount = 0;
+    int second_ref_count = 0;
+    int intrapenalty = 256;
+
+    int sum_in_vectors = 0;
+
+    MV best_ref_mv = {0, 0};
+    MV zero_ref_mv = {0, 0};
+
+    unsigned char *fp_motion_map_ptr = cpi->fp_motion_map;
+
+    vp8_clear_system_state();  //__asm emms;
+
+    x->src = * cpi->Source;
+    xd->pre = cm->last_frame;
+    xd->dst = cm->new_frame;
+
+    vp8_build_block_offsets(x);
+
+    vp8_setup_block_dptrs(&x->e_mbd);
+
+    vp8_setup_block_ptrs(x);
+
+    // set up frame new frame for intra coded blocks
+    vp8_setup_intra_recon(&cm->new_frame);
+    vp8cx_frame_init_quantizer(cpi);
+
+    // Initialise the MV cost table to the defaults
+    //if( cm->current_video_frame == 0)
+    //if ( 0 )
+    {
+        int flag[2] = {1, 1};
+        vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
+        vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
+        vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
+    }
+
+    // for each macroblock row in image
+    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+    {
+        MV best_ref_mv = {0, 0};
+
+        // reset above block coeffs
+        xd->up_available = (mb_row != 0);
+        recon_yoffset = (mb_row * recon_y_stride * 16);
+        recon_uvoffset = (mb_row * recon_uv_stride * 8);
+
+        // for each macroblock col in image
+        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+        {
+            int this_error;
+            int gf_motion_error = INT_MAX;
+            int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
+
+            xd->dst.y_buffer = cm->new_frame.y_buffer + recon_yoffset;
+            xd->dst.u_buffer = cm->new_frame.u_buffer + recon_uvoffset;
+            xd->dst.v_buffer = cm->new_frame.v_buffer + recon_uvoffset;
+            xd->left_available = (mb_col != 0);
+
+            // do intra 16x16 prediction
+            this_error = vp8_encode_intra(cpi, x, use_dc_pred);
+
+            // "intrapenalty" below deals with situations where the intra and inter error scores are very low (eg a plain black frame)
+            // We do not have special cases in first pass for 0,0 and nearest etc so all inter modes carry an overhead cost estimate fot the mv.
+            // When the error score is very low this causes us to pick all or lots of INTRA modes and throw lots of key frames.
+            // This penalty adds a cost matching that of a 0,0 mv to the intra case.
+            this_error += intrapenalty;
+
+            // Cumulative intra error total
+            intra_error += this_error;
+
+            // Indicate default assumption of intra in the motion map
+            *fp_motion_map_ptr = 2;
+
+            // Set up limit values for motion vectors to prevent them extending outside the UMV borders
+            x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
+            x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
+            x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
+            x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);
+
+            // Other than for the first frame do a motion search
+            if (cm->current_video_frame > 0)
+            {
+                BLOCK *b = &x->block[0];
+                BLOCKD *d = &x->e_mbd.block[0];
+                MV tmp_mv = {0, 0};
+                int tmp_err;
+                int motion_error = INT_MAX;
+
+                // Simple 0,0 motion with no mv overhead
+                vp8_zz_motion_search( cpi, x, &cm->last_frame, &motion_error, recon_yoffset );
+                d->bmi.mv.as_mv.row = 0;
+                d->bmi.mv.as_mv.col = 0;
+
+                // Test last reference frame using the previous best mv as the starting point (best reference) for the search
+                vp8_first_pass_motion_search(cpi, x, &best_ref_mv, &d->bmi.mv.as_mv, &cm->last_frame, &motion_error, recon_yoffset);
+
+                // If the current best reference mv is not centred on 0,0 then do a 0,0 based search as well
+                if ((best_ref_mv.col != 0) || (best_ref_mv.row != 0))
+                {
+                   tmp_err = INT_MAX;
+                   vp8_first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, &cm->last_frame, &motion_error, recon_yoffset);
+
+                   if ( tmp_err < motion_error )
+                   {
+                        motion_error = tmp_err;
+                        d->bmi.mv.as_mv.row = tmp_mv.row;
+                        d->bmi.mv.as_mv.col = tmp_mv.col;
+                   }
+
+                }
+
+                // Experimental search in a second reference frame ((0,0) based only)
+                if (cm->current_video_frame > 1)
+                {
+                    vp8_first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, &cm->golden_frame, &gf_motion_error, recon_yoffset);
+
+                    if ((gf_motion_error < motion_error) && (gf_motion_error < this_error))
+                    {
+                        second_ref_count++;
+                        //motion_error = gf_motion_error;
+                        //d->bmi.mv.as_mv.row = tmp_mv.row;
+                        //d->bmi.mv.as_mv.col = tmp_mv.col;
+                    }
+                    /*else
+                    {
+                        xd->pre.y_buffer = cm->last_frame.y_buffer + recon_yoffset;
+                        xd->pre.u_buffer = cm->last_frame.u_buffer + recon_uvoffset;
+                        xd->pre.v_buffer = cm->last_frame.v_buffer + recon_uvoffset;
+                    }*/
+
+
+                    // Reset to last frame as reference buffer
+                    xd->pre.y_buffer = cm->last_frame.y_buffer + recon_yoffset;
+                    xd->pre.u_buffer = cm->last_frame.u_buffer + recon_uvoffset;
+                    xd->pre.v_buffer = cm->last_frame.v_buffer + recon_uvoffset;
+                }
+
+                if (motion_error <= this_error)
+                {
+                    d->bmi.mv.as_mv.row <<= 3;
+                    d->bmi.mv.as_mv.col <<= 3;
+                    this_error = motion_error;
+                    vp8_set_mbmode_and_mvs(x, NEWMV, &d->bmi.mv.as_mv);
+                    vp8_encode_inter16x16y(IF_RTCD(&cpi->rtcd), x);
+                    sum_mvr += d->bmi.mv.as_mv.row;
+                    sum_mvr_abs += abs(d->bmi.mv.as_mv.row);
+                    sum_mvc += d->bmi.mv.as_mv.col;
+                    sum_mvc_abs += abs(d->bmi.mv.as_mv.col);
+                    sum_mvrs += d->bmi.mv.as_mv.row * d->bmi.mv.as_mv.row;
+                    sum_mvcs += d->bmi.mv.as_mv.col * d->bmi.mv.as_mv.col;
+                    intercount++;
+
+                    best_ref_mv.row = d->bmi.mv.as_mv.row;
+                    best_ref_mv.col = d->bmi.mv.as_mv.col;
+                    //best_ref_mv.row = 0;
+                    //best_ref_mv.col = 0;
+
+                    // Was the vector non-zero
+                    if (d->bmi.mv.as_mv.row || d->bmi.mv.as_mv.col)
+                    {
+                        mvcount++;
+
+                        *fp_motion_map_ptr = 1;
+
+                        // Does the Row vector point inwards or outwards
+                        if (mb_row < cm->mb_rows / 2)
+                        {
+                            if (d->bmi.mv.as_mv.row > 0)
+                                sum_in_vectors--;
+                            else if (d->bmi.mv.as_mv.row < 0)
+                                sum_in_vectors++;
+                        }
+                        else if (mb_row > cm->mb_rows / 2)
+                        {
+                            if (d->bmi.mv.as_mv.row > 0)
+                                sum_in_vectors++;
+                            else if (d->bmi.mv.as_mv.row < 0)
+                                sum_in_vectors--;
+                        }
+
+                        // Does the Row vector point inwards or outwards
+                        if (mb_col < cm->mb_cols / 2)
+                        {
+                            if (d->bmi.mv.as_mv.col > 0)
+                                sum_in_vectors--;
+                            else if (d->bmi.mv.as_mv.col < 0)
+                                sum_in_vectors++;
+                        }
+                        else if (mb_col > cm->mb_cols / 2)
+                        {
+                            if (d->bmi.mv.as_mv.col > 0)
+                                sum_in_vectors++;
+                            else if (d->bmi.mv.as_mv.col < 0)
+                                sum_in_vectors--;
+                        }
+                    }
+                    else
+                        *fp_motion_map_ptr = 0;    // 0,0 mv was best
+                }
+                else
+                {
+                    best_ref_mv.row = 0;
+                    best_ref_mv.col = 0;
+                }
+            }
+
+            coded_error += this_error;
+
+            // adjust to the next column of macroblocks
+            x->src.y_buffer += 16;
+            x->src.u_buffer += 8;
+            x->src.v_buffer += 8;
+
+            recon_yoffset += 16;
+            recon_uvoffset += 8;
+
+            // Update the motion map
+            fp_motion_map_ptr++;
+        }
+
+        // adjust to the next row of mbs
+        x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
+        x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
+        x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
+
+        //extend the recon for intra prediction
+        vp8_extend_mb_row(&cm->new_frame, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
+        vp8_clear_system_state();  //__asm emms;
+    }
+
+    vp8_clear_system_state();  //__asm emms;
+    {
+        double weight = 0.0;
+        double weigth2 = 0.0;
+
+        FIRSTPASS_STATS fps;
+
+        fps.frame      = cm->current_video_frame ;
+        fps.intra_error = intra_error >> 8;
+        fps.coded_error = coded_error >> 8;
+        weight = vp8_simple_weight(cpi->Source);
+
+        if (weight < 0.1)
+            weight = 0.1;
+
+        fps.ssim_weighted_pred_err = fps.coded_error * weight;
+
+        fps.pcnt_inter  = 0.0;
+        fps.pcnt_motion = 0.0;
+        fps.MVr        = 0.0;
+        fps.mvr_abs     = 0.0;
+        fps.MVc        = 0.0;
+        fps.mvc_abs     = 0.0;
+        fps.MVrv       = 0.0;
+        fps.MVcv       = 0.0;
+        fps.mv_in_out_count  = 0.0;
+        fps.count      = 1.0;
+
+        fps.pcnt_inter   = 1.0 * (double)intercount / cm->MBs;
+        fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs;
+
+        if (mvcount > 0)
+        {
+            fps.MVr = (double)sum_mvr / (double)mvcount;
+            fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount;
+            fps.MVc = (double)sum_mvc / (double)mvcount;
+            fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount;
+            fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / (double)mvcount;
+            fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / (double)mvcount;
+            fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2);
+
+            fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs;
+        }
+
+        // TODO:  handle the case when duration is set to 0, or something less
+        // than the full time between subsequent cpi->source_time_stamp s  .
+        fps.duration = cpi->source_end_time_stamp - cpi->source_time_stamp;
+
+        // don't want to do outputstats with a stack variable!
+        cpi->this_frame_stats = fps;
+        vp8_output_stats(cpi->output_pkt_list, &cpi->this_frame_stats);
+        vp8_accumulate_stats(&cpi->total_stats, &fps);
+
+#ifdef FIRSTPASS_MM
+        fwrite(cpi->fp_motion_map, 1, cpi->common.MBs, cpi->fp_motion_mapfile);
+#endif
+    }
+
+    // Copy the previous Last Frame into the GF buffer if specific conditions for doing so are met
+    if ((cm->current_video_frame > 0) &&
+        (cpi->this_frame_stats.pcnt_inter > 0.20) &&
+        ((cpi->this_frame_stats.intra_error / cpi->this_frame_stats.coded_error) > 2.0))
+    {
+        vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
+    }
+
+    // swap frame pointers so last frame refers to the frame we just compressed
+    vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);
+    vp8_yv12_extend_frame_borders(&cm->last_frame);
+
+    // Special case for the first frame. Copy into the GF buffer as a second reference.
+    if (cm->current_video_frame == 0)
+    {
+        vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
+    }
+
+
+    // use this to see what the first pass reconstruction looks like
+    if (0)
+    {
+        char filename[512];
+        FILE *recon_file;
+        sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame);
+
+        if (cm->current_video_frame == 0)
+            recon_file = fopen(filename, "wb");
+        else
+            recon_file = fopen(filename, "ab");
+
+        fwrite(cm->last_frame.buffer_alloc, cm->last_frame.frame_size, 1, recon_file);
+        fclose(recon_file);
+    }
+
+    cm->current_video_frame++;
+
+}
+extern const int vp8_bits_per_mb[2][QINDEX_RANGE];
+
+#define BASE_ERRPERMB   150
+static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width)
+{
+    int Q;
+    int num_mbs = ((Height * Width) / (16 * 16));
+    int target_norm_bits_per_mb;
+
+    double err_per_mb = section_err / num_mbs;
+    double correction_factor;
+    double corr_high;
+    double speed_correction = 1.0;
+    double rolling_ratio;
+
+    double pow_highq = 0.90;
+    double pow_lowq = 0.40;
+
+    if (section_target_bandwitdh <= 0)
+        return MAXQ;
+
+    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
+
+    // Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
+    if ((cpi->rolling_target_bits > 0.0) && (cpi->active_worst_quality < cpi->worst_quality))
+    {
+        //double adjustment_rate = 0.985 + (0.00005 * cpi->active_worst_quality);
+        double adjustment_rate = 0.99;
+
+        rolling_ratio = (double)cpi->rolling_actual_bits / (double)cpi->rolling_target_bits;
+
+        //if ( cpi->est_max_qcorrection_factor > rolling_ratio )
+        if (rolling_ratio < 0.95)
+            //cpi->est_max_qcorrection_factor *= adjustment_rate;
+            cpi->est_max_qcorrection_factor -= 0.005;
+        //else if ( cpi->est_max_qcorrection_factor < rolling_ratio )
+        else if (rolling_ratio > 1.05)
+            cpi->est_max_qcorrection_factor += 0.005;
+
+        //cpi->est_max_qcorrection_factor /= adjustment_rate;
+
+        cpi->est_max_qcorrection_factor = (cpi->est_max_qcorrection_factor < 0.1) ? 0.1 : (cpi->est_max_qcorrection_factor > 10.0) ? 10.0 : cpi->est_max_qcorrection_factor;
+    }
+
+    // Corrections for higher compression speed settings (reduced compression expected)
+    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
+    {
+        if (cpi->oxcf.cpu_used <= 5)
+            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
+        else
+            speed_correction = 1.25;
+    }
+
+    // Correction factor used for Q values >= 20
+    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
+    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
+
+    // Try and pick a Q that should be high enough to encode the content at the given rate.
+    for (Q = 0; Q < MAXQ; Q++)
+    {
+        int bits_per_mb_at_this_q;
+
+        if (Q < 50)
+        {
+            correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
+            correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
+        }
+        else
+            correction_factor = corr_high;
+
+        bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->est_max_qcorrection_factor * cpi->section_max_qfactor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
+        //bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->est_max_qcorrection_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
+
+        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
+            break;
+    }
+
+    return Q;
+}
+static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width)
+{
+    int Q;
+    int num_mbs = ((Height * Width) / (16 * 16));
+    int target_norm_bits_per_mb;
+
+    double err_per_mb = section_err / num_mbs;
+    double correction_factor;
+    double corr_high;
+    double speed_correction = 1.0;
+    double pow_highq = 0.90;
+    double pow_lowq = 0.40;
+
+    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
+
+    // Corrections for higher compression speed settings (reduced compression expected)
+    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
+    {
+        if (cpi->oxcf.cpu_used <= 5)
+            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
+        else
+            speed_correction = 1.25;
+    }
+
+    // Correction factor used for Q values >= 20
+    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
+    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
+
+    // Try and pick a Q that can encode the content at the given rate.
+    for (Q = 0; Q < MAXQ; Q++)
+    {
+        int bits_per_mb_at_this_q;
+
+        if (Q < 50)
+        {
+            correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
+            correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
+        }
+        else
+            correction_factor = corr_high;
+
+        bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->est_max_qcorrection_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
+
+        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
+            break;
+    }
+
+    return Q;
+}
+
+// Estimate a worst case Q for a KF group
+static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width, double group_iiratio)
+{
+    int Q;
+    int num_mbs = ((Height * Width) / (16 * 16));
+    int target_norm_bits_per_mb = (512 * section_target_bandwitdh) / num_mbs;
+    int bits_per_mb_at_this_q;
+
+    double err_per_mb = section_err / num_mbs;
+    double err_correction_factor;
+    double corr_high;
+    double speed_correction = 1.0;
+    double current_spend_ratio = 1.0;
+
+    double pow_highq = (POW1 < 0.6) ? POW1 + 0.3 : 0.90;
+    double pow_lowq = (POW1 < 0.7) ? POW1 + 0.1 : 0.80;
+
+    double iiratio_correction_factor = 1.0;
+
+    double combined_correction_factor;
+
+    // Trap special case where the target is <= 0
+    if (target_norm_bits_per_mb <= 0)
+        return MAXQ * 2;
+
+    // Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
+    // This is clamped to the range 0.1 to 10.0
+    if (cpi->long_rolling_target_bits <= 0)
+        current_spend_ratio = 10.0;
+    else
+    {
+        current_spend_ratio = (double)cpi->long_rolling_actual_bits / (double)cpi->long_rolling_target_bits;
+        current_spend_ratio = (current_spend_ratio > 10.0) ? 10.0 : (current_spend_ratio < 0.1) ? 0.1 : current_spend_ratio;
+    }
+
+    // Calculate a correction factor based on the quality of prediction in the sequence as indicated by intra_inter error score ratio (IIRatio)
+    // The idea here is to favour subsampling in the hardest sections vs the easyest.
+    iiratio_correction_factor = 1.0 - ((group_iiratio - 6.0) * 0.1);
+
+    if (iiratio_correction_factor < 0.5)
+        iiratio_correction_factor = 0.5;
+
+    // Corrections for higher compression speed settings (reduced compression expected)
+    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
+    {
+        if (cpi->oxcf.cpu_used <= 5)
+            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
+        else
+            speed_correction = 1.25;
+    }
+
+    // Combine the various factors calculated above
+    combined_correction_factor = speed_correction * iiratio_correction_factor * current_spend_ratio;
+
+    // Correction factor used for Q values >= 20
+    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
+    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
+
+    // Try and pick a Q that should be high enough to encode the content at the given rate.
+    for (Q = 0; Q < MAXQ; Q++)
+    {
+        // Q values < 20 treated as a special case
+        if (Q < 20)
+        {
+            err_correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
+            err_correction_factor = (err_correction_factor < 0.05) ? 0.05 : (err_correction_factor > 5.0) ? 5.0 : err_correction_factor;
+        }
+        else
+            err_correction_factor = corr_high;
+
+        bits_per_mb_at_this_q = (int)(.5 + err_correction_factor * combined_correction_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q]);
+
+        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
+            break;
+    }
+
+    // If we could not hit the target even at Max Q then estimate what Q would have bee required
+    while ((bits_per_mb_at_this_q > target_norm_bits_per_mb)  && (Q < (MAXQ * 2)))
+    {
+
+        bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q);
+        Q++;
+    }
+
+    if (0)
+    {
+        FILE *f = fopen("estkf_q.stt", "a");
+        fprintf(f, "%8d %8d %8d %8.2f %8.3f %8.2f %8.3f %8.3f %8.3f %8d\n", cpi->common.current_video_frame, bits_per_mb_at_this_q,
+                target_norm_bits_per_mb, err_per_mb, err_correction_factor,
+                current_spend_ratio, group_iiratio, iiratio_correction_factor,
+                (double)cpi->buffer_level / (double)cpi->oxcf.optimal_buffer_level, Q);
+        fclose(f);
+    }
+
+    return Q;
+}
+extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate);
+
+void vp8_init_second_pass(VP8_COMP *cpi)
+{
+    FIRSTPASS_STATS this_frame;
+    FIRSTPASS_STATS *start_pos;
+
+    double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
+
+    vp8_zero_stats(&cpi->total_stats);
+
+    if (!cpi->stats_in_end)
+        return;
+
+    cpi->total_stats = *cpi->stats_in_end;
+
+    cpi->total_error_left = cpi->total_stats.ssim_weighted_pred_err;
+    cpi->total_intra_error_left = cpi->total_stats.intra_error;
+    cpi->total_coded_error_left = cpi->total_stats.coded_error;
+    cpi->start_tot_err_left = cpi->total_error_left;
+
+    //cpi->bits_left = (long long)(cpi->total_stats.count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
+    //cpi->bits_left -= (long long)(cpi->total_stats.count * two_pass_min_rate / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
+
+    // each frame can have a different duration, as the frame rate in the source
+    // isn't guaranteed to be constant.   The frame rate prior to the first frame
+    // encoded in the second pass is a guess.  However the sum duration is not.
+    // Its calculated based on the actual durations of all frames from the first
+    // pass.
+    vp8_new_frame_rate(cpi, 10000000.0 * cpi->total_stats.count / cpi->total_stats.duration);
+
+    cpi->output_frame_rate = cpi->oxcf.frame_rate;
+    cpi->bits_left = (long long)(cpi->total_stats.duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
+    cpi->bits_left -= (long long)(cpi->total_stats.duration * two_pass_min_rate / 10000000.0);
+
+    vp8_avg_stats(&cpi->total_stats);
+
+    // Scan the first pass file and calculate an average Intra / Inter error score ratio for the sequence
+    {
+        double sum_iiratio = 0.0;
+        double IIRatio;
+
+        start_pos = cpi->stats_in;               // Note starting "file" position
+
+        while (vp8_input_stats(cpi, &this_frame) != EOF)
+        {
+            IIRatio = this_frame.intra_error / DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
+            IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio;
+            sum_iiratio += IIRatio;
+        }
+
+        cpi->avg_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK((double)cpi->total_stats.count);
+
+        // Reset file position
+        reset_fpf_position(cpi, start_pos);
+    }
+
+    // Scan the first pass file and calculate a modified total error based upon the bias/power function
+    // used to allocate bits
+    {
+        start_pos = cpi->stats_in;               // Note starting "file" position
+
+        cpi->modified_total_error_left = 0.0;
+
+        while (vp8_input_stats(cpi, &this_frame) != EOF)
+        {
+            cpi->modified_total_error_left += calculate_modified_err(cpi, &this_frame);
+        }
+
+        reset_fpf_position(cpi, start_pos);            // Reset file position
+
+    }
+
+#ifdef FIRSTPASS_MM
+    cpi->fp_motion_mapfile = 0;
+    cpi->fp_motion_mapfile = fopen("fpmotionmap.stt", "rb");
+#endif
+
+}
+
+void vp8_end_second_pass(VP8_COMP *cpi)
+{
+#ifdef FIRSTPASS_MM
+
+    if (cpi->fp_motion_mapfile)
+        fclose(cpi->fp_motion_mapfile);
+
+#endif
+}
+
+// Analyse and define a gf/arf group .
+static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
+{
+    FIRSTPASS_STATS next_frame;
+    FIRSTPASS_STATS *start_pos;
+    int i;
+    int count = 0;
+    int image_size = cpi->common.last_frame.y_width  * cpi->common.last_frame.y_height;
+    double boost_score = 0.0;
+    double old_boost_score = 0.0;
+    double gf_group_err = 0.0;
+    double gf_first_frame_err = 0.0;
+    double mod_frame_err = 0.0;
+
+    double mv_accumulator_rabs  = 0.0;
+    double mv_accumulator_cabs  = 0.0;
+    double this_mv_rabs;
+    double this_mv_cabs;
+    double mv_ratio_accumulator = 0.0;
+    double distance_factor = 0.0;
+    double decay_accumulator = 1.0;
+
+    double boost_factor = IIFACTOR;
+    double loop_decay_rate = 1.00;        // Starting decay rate
+
+    double this_frame_mv_in_out = 0.0;
+    double mv_in_out_accumulator = 0.0;
+    double abs_mv_in_out_accumulator = 0.0;
+    double mod_err_per_mb_accumulator = 0.0;
+
+    int max_bits = frame_max_bits(cpi);    // Max for a single frame
+
+#ifdef FIRSTPASS_MM
+    int fpmm_pos;
+#endif
+
+    cpi->gf_group_bits = 0;
+    cpi->gf_decay_rate = 0;
+
+    vp8_clear_system_state();  //__asm emms;
+
+#ifdef FIRSTPASS_MM
+    fpmm_pos = vp8_fpmm_get_pos(cpi);
+#endif
+
+    start_pos = cpi->stats_in;
+
+    // Preload the stats for the next frame.
+    mod_frame_err = calculate_modified_err(cpi, this_frame);
+
+    // Note the error of the frame at the start of the group (this will be the GF frame error if we code a normal gf
+    gf_first_frame_err = mod_frame_err;
+
+    // Special treatment if the current frame is a key frame (which is also a gf).
+    // If it is then its error score (and hence bit allocation) need to be subtracted out
+    // from the calculation for the GF group
+    if (cpi->common.frame_type == KEY_FRAME)
+        gf_group_err -= gf_first_frame_err;
+
+    // Scan forward to try and work out how many frames the next gf group should contain and
+    // what level of boost is appropriate for the GF or ARF that will be coded with the group
+    i = 0;
+
+    while (((i < cpi->max_gf_interval) || ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) && (i < cpi->frames_to_key))
+    {
+        double r;
+        double motion_factor;
+        double this_frame_mvr_ratio;
+        double this_frame_mvc_ratio;
+
+        i++;                                                    // Increment the loop counter
+
+        // Accumulate error score of frames in this gf group
+        mod_frame_err = calculate_modified_err(cpi, this_frame);
+
+        gf_group_err += mod_frame_err;
+
+        mod_err_per_mb_accumulator += mod_frame_err / DOUBLE_DIVIDE_CHECK((double)cpi->common.MBs);
+
+        if (EOF == vp8_input_stats(cpi, &next_frame))
+            break;
+
+        // Accumulate motion stats.
+        motion_factor = next_frame.pcnt_motion;
+        this_mv_rabs = fabs(next_frame.mvr_abs * motion_factor);
+        this_mv_cabs = fabs(next_frame.mvc_abs * motion_factor);
+
+        mv_accumulator_rabs += fabs(next_frame.mvr_abs * motion_factor);
+        mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_factor);
+
+        //Accumulate Motion In/Out of frame stats
+        this_frame_mv_in_out = next_frame.mv_in_out_count * next_frame.pcnt_motion;
+        mv_in_out_accumulator += next_frame.mv_in_out_count * next_frame.pcnt_motion;
+        abs_mv_in_out_accumulator += fabs(next_frame.mv_in_out_count * next_frame.pcnt_motion);
+
+        // If there is a significant amount of motion
+        if (motion_factor > 0.05)
+        {
+            this_frame_mvr_ratio = fabs(next_frame.mvr_abs) / DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVr));
+            this_frame_mvc_ratio = fabs(next_frame.mvc_abs) / DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));
+
+            mv_ratio_accumulator += (this_frame_mvr_ratio < next_frame.mvr_abs) ? (this_frame_mvr_ratio * motion_factor) : next_frame.mvr_abs * motion_factor;
+            mv_ratio_accumulator += (this_frame_mvc_ratio < next_frame.mvc_abs) ? (this_frame_mvc_ratio * motion_factor) : next_frame.mvc_abs * motion_factor;
+        }
+        else
+        {
+            mv_ratio_accumulator += 0.0;
+            this_frame_mvr_ratio = 1.0;
+            this_frame_mvc_ratio = 1.0;
+        }
+
+        // Underlying boost factor is based on inter intra error ratio
+        r = (boost_factor * (next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error)));
+
+        // Increase boost for frames where new data coming into frame (eg zoom out)
+        // Slightly reduce boost if there is a net balance of motion out of the frame (zoom in)
+        // The range for this_frame_mv_in_out is -1.0 to +1.0
+        if (this_frame_mv_in_out > 0.0)
+            r += r * (this_frame_mv_in_out * 2.0);
+        else
+            r += r * (this_frame_mv_in_out / 2.0);  // In extreme case boost is halved
+
+        if (r > GF_RMAX)
+            r = GF_RMAX;
+
+        // Adjust loop decay rate
+        //if ( next_frame.pcnt_inter < loop_decay_rate )
+        loop_decay_rate = next_frame.pcnt_inter;
+
+        // High % motion -> somewhat higher decay rate
+        if ((1.0 - (next_frame.pcnt_motion / 10.0)) < loop_decay_rate)
+            loop_decay_rate = (1.0 - (next_frame.pcnt_motion / 10.0));
+
+        distance_factor = sqrt((this_mv_rabs * this_mv_rabs) + (this_mv_cabs * this_mv_cabs)) / 300.0;
+        distance_factor = ((distance_factor > 1.0) ? 0.0 : (1.0 - distance_factor));
+
+        if (distance_factor < loop_decay_rate)
+            loop_decay_rate = distance_factor;
+
+        // Cumulative effect of decay
+        decay_accumulator = decay_accumulator * loop_decay_rate;
+        decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
+        //decay_accumulator = ( loop_decay_rate < decay_accumulator ) ? loop_decay_rate : decay_accumulator;
+
+        boost_score += (decay_accumulator * r);
+
+        // Break out conditions.
+        if (   /* i>4 || */
+            (
+                (i > MIN_GF_INTERVAL) &&                            // Dont break out with a very short interval
+                ((cpi->frames_to_key - i) >= MIN_GF_INTERVAL) &&      // Dont break out very close to a key frame
+                ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) &&
+                ((mv_ratio_accumulator > 100.0) ||
+                 (abs_mv_in_out_accumulator > 3.0) ||
+                 (mv_in_out_accumulator < -2.0) ||
+                 ((boost_score - old_boost_score) < 2.0)
+                )
+            )
+        )
+        {
+            boost_score = old_boost_score;
+            break;
+        }
+
+        vpx_memcpy(this_frame, &next_frame, sizeof(*this_frame));
+
+        old_boost_score = boost_score;
+    }
+
+    cpi->gf_decay_rate = (i > 0) ? (int)(100.0 * (1.0 - decay_accumulator)) / i : 0;
+
+    // When using CBR apply additional buffer related upper limits
+    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+    {
+        double max_boost;
+
+        // For cbr apply buffer related limits
+        if (cpi->drop_frames_allowed)
+        {
+            int df_buffer_level = cpi->oxcf.drop_frames_water_mark * (cpi->oxcf.optimal_buffer_level / 100);
+
+            if (cpi->buffer_level > df_buffer_level)
+                max_boost = ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
+            else
+                max_boost = 0.0;
+        }
+        else if (cpi->buffer_level > 0)
+        {
+            max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
+        }
+        else
+        {
+            max_boost = 0.0;
+        }
+
+        if (boost_score > max_boost)
+            boost_score = max_boost;
+    }
+
+    cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
+
+    // Should we use the alternate refernce frame
+    if (cpi->oxcf.play_alternate &&
+        (i >= MIN_GF_INTERVAL) &&
+        (i <= (cpi->frames_to_key - MIN_GF_INTERVAL)) &&          // dont use ARF very near next kf
+        (((next_frame.pcnt_inter > 0.75) &&
+          ((mv_in_out_accumulator / (double)i > -0.2) || (mv_in_out_accumulator > -2.0)) &&
+          //(cpi->gfu_boost>150) &&
+          (cpi->gfu_boost > 100) &&
+          //(cpi->gfu_boost>AF_THRESH2) &&
+          //((cpi->gfu_boost/i)>AF_THRESH) &&
+          //(decay_accumulator > 0.5) &&
+          (cpi->gf_decay_rate <= (ARF_DECAY_THRESH + (cpi->gfu_boost / 200)))
+         )
+        )
+       )
+    {
+        int Boost;
+        int allocation_chunks;
+        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+        int tmp_q;
+        int arf_frame_bits = 0;
+        int group_bits;
+
+        // Estimate the bits to be allocated to the group as a whole
+        if ((cpi->kf_group_bits > 0) && (cpi->kf_group_error_left > 0))
+            group_bits = (int)((double)cpi->kf_group_bits * (gf_group_err / (double)cpi->kf_group_error_left));
+        else
+            group_bits = 0;
+
+        // Boost for arf frame
+        Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
+        Boost += (cpi->baseline_gf_interval * 50);
+        allocation_chunks = (i * 100) + Boost;
+
+        // Normalize Altboost and allocations chunck down to prevent overflow
+        while (Boost > 1000)
+        {
+            Boost /= 2;
+            allocation_chunks /= 2;
+        }
+
+        // Calculate the number of bits to be spent on the arf based on the boost number
+        arf_frame_bits = (int)((double)Boost * (group_bits / (double)allocation_chunks));
+
+        // Estimate if there are enough bits available to make worthwhile use of an arf.
+        tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits, cpi->common.Height, cpi->common.Width);
+
+        // Only use an arf if it is likely we will be able to code it at a lower Q than the surrounding frames.
+        if (tmp_q < cpi->worst_quality)
+        {
+            cpi->source_alt_ref_pending = TRUE;
+
+            // For alt ref frames the error score for the end frame of the group (the alt ref frame) should not contribute to the group total and hence
+            // the number of bit allocated to the group. Rather it forms part of the next group (it is the GF at the start of the next group)
+            gf_group_err -= mod_frame_err;
+
+            // Set the interval till the next gf or arf. For ARFs this is the number of frames to be coded before the future frame that is coded as an ARF.
+            // The future frame itself is part of the next group
+            cpi->baseline_gf_interval = i - 1;
+
+#ifdef FIRSTPASS_MM
+            // Read through the motion map to load up the entry for the ARF
+            {
+                int j;
+
+                // Advance to the region of interest
+                // Current default 2 frames before to 2 frames after the ARF frame itsef
+                vp8_fpmm_reset_pos(cpi, cpi->fpmm_pos);
+
+                for (j = 0; j < cpi->baseline_gf_interval - 2; j++)
+                    vp8_advance_fpmm(cpi, 1);
+
+                // Read / create a motion map for the region of interest
+                vp8_input_fpmm(cpi, 5);
+            }
+#endif
+        }
+        else
+        {
+            cpi->source_alt_ref_pending = FALSE;
+            cpi->baseline_gf_interval = i;
+        }
+    }
+    else
+    {
+        cpi->source_alt_ref_pending = FALSE;
+        cpi->baseline_gf_interval = i;
+    }
+
+    // Conventional GF
+    if (!cpi->source_alt_ref_pending)
+    {
+        // Dont allow conventional gf too near the next kf
+        if ((cpi->frames_to_key - cpi->baseline_gf_interval) < MIN_GF_INTERVAL)
+        {
+            while (cpi->baseline_gf_interval < cpi->frames_to_key)
+            {
+                if (EOF == vp8_input_stats(cpi, this_frame))
+                    break;
+
+                cpi->baseline_gf_interval++;
+
+                if (cpi->baseline_gf_interval < cpi->frames_to_key)
+                    gf_group_err += calculate_modified_err(cpi, this_frame);
+            }
+        }
+    }
+
+    // Now decide how many bits should be allocated to the GF group as  a proportion of those remaining in the kf group.
+    // The final key frame group in the clip is treated as a special case where cpi->kf_group_bits is tied to cpi->bits_left.
+    // This is also important for short clips where there may only be one key frame.
+    if (cpi->frames_to_key >= (int)(cpi->total_stats.count - cpi->common.current_video_frame))
+    {
+        cpi->kf_group_bits = (cpi->bits_left > 0) ? cpi->bits_left : 0;
+    }
+
+    // Calculate the bits to be allocated to the group as a whole
+    if ((cpi->kf_group_bits > 0) && (cpi->kf_group_error_left > 0))
+        cpi->gf_group_bits = (int)((double)cpi->kf_group_bits * (gf_group_err / (double)cpi->kf_group_error_left));
+    else
+        cpi->gf_group_bits = 0;
+
+    cpi->gf_group_bits = (cpi->gf_group_bits < 0) ? 0 : (cpi->gf_group_bits > cpi->kf_group_bits) ? cpi->kf_group_bits : cpi->gf_group_bits;
+
+    // Clip cpi->gf_group_bits based on user supplied data rate variability limit (cpi->oxcf.two_pass_vbrmax_section)
+    if (cpi->gf_group_bits > max_bits * cpi->baseline_gf_interval)
+        cpi->gf_group_bits = max_bits * cpi->baseline_gf_interval;
+
+    // Reset the file position
+    reset_fpf_position(cpi, start_pos);
+
+    // Assign  bits to the arf or gf.
+    {
+        int Boost;
+        int frames_in_section;
+        int allocation_chunks;
+        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+
+        // For ARF frames
+        if (cpi->source_alt_ref_pending)
+        {
+            Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
+            //Boost += (cpi->baseline_gf_interval * 25);
+            Boost += (cpi->baseline_gf_interval * 50);
+
+            // Set max and minimum boost and hence minimum allocation
+            if (Boost > ((cpi->baseline_gf_interval + 1) * 200))
+                Boost = ((cpi->baseline_gf_interval + 1) * 200);
+            else if (Boost < 125)
+                Boost = 125;
+
+            frames_in_section = cpi->baseline_gf_interval + 1;
+            allocation_chunks = (frames_in_section * 100) + Boost;
+        }
+        // Else for standard golden frames
+        else
+        {
+            // boost based on inter / intra ratio of subsequent frames
+            Boost = (cpi->gfu_boost * GFQ_ADJUSTMENT) / 100;
+
+            // Set max and minimum boost and hence minimum allocation
+            if (Boost > (cpi->baseline_gf_interval * 150))
+                Boost = (cpi->baseline_gf_interval * 150);
+            else if (Boost < 125)
+                Boost = 125;
+
+            frames_in_section = cpi->baseline_gf_interval;
+            allocation_chunks = (frames_in_section * 100) + (Boost - 100);
+        }
+
+        // Normalize Altboost and allocations chunck down to prevent overflow
+        while (Boost > 1000)
+        {
+            Boost /= 2;
+            allocation_chunks /= 2;
+        }
+
+        // Calculate the number of bits to be spent on the gf or arf based on the boost number
+        cpi->gf_bits = (int)((double)Boost * (cpi->gf_group_bits / (double)allocation_chunks));
+
+        // If the frame that is to be boosted is simpler than the average for the gf/arf group then use an alternative calculation
+        // based on the error score of the frame itself
+        if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval)
+        {
+            double  alt_gf_grp_bits;
+            int     alt_gf_bits;
+
+            alt_gf_grp_bits = ((double)cpi->kf_group_bits  * (mod_frame_err * (double)cpi->baseline_gf_interval) / (double)cpi->kf_group_error_left) ;
+            alt_gf_bits = (int)((double)Boost * (alt_gf_grp_bits / (double)allocation_chunks));
+
+            if (cpi->gf_bits > alt_gf_bits)
+            {
+                cpi->gf_bits = alt_gf_bits;
+            }
+        }
+        // Else if it is harder than other frames in the group make sure it at least receives an allocation in keeping with
+        // its relative error score, otherwise it may be worse off than an "un-boosted" frame
+        else
+        {
+            int alt_gf_bits = (int)((double)cpi->kf_group_bits * (mod_frame_err / (double)cpi->kf_group_error_left));
+
+            if (alt_gf_bits > cpi->gf_bits)
+            {
+                cpi->gf_bits = alt_gf_bits;
+            }
+        }
+
+        // Apply an additional limit for CBR
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            if (cpi->gf_bits > (cpi->buffer_level >> 1))
+                cpi->gf_bits = cpi->buffer_level >> 1;
+        }
+
+        // Dont allow a negative value for gf_bits
+        if (cpi->gf_bits < 0)
+            cpi->gf_bits = 0;
+
+        // Adjust KF group bits and error remainin
+        cpi->kf_group_error_left -= gf_group_err;
+        cpi->kf_group_bits -= cpi->gf_group_bits;
+
+        if (cpi->kf_group_bits < 0)
+            cpi->kf_group_bits = 0;
+
+        // Note the error score left in the remaining frames of the group.
+        // For normal GFs we want to remove the error score for the first frame of the group (except in Key frame case where this has already happened)
+        if (!cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME)
+            cpi->gf_group_error_left = gf_group_err - gf_first_frame_err;
+        else
+            cpi->gf_group_error_left = gf_group_err;
+
+        cpi->gf_group_bits -= cpi->gf_bits;
+
+        if (cpi->gf_group_bits < 0)
+            cpi->gf_group_bits = 0;
+
+        // Set aside some bits for a mid gf sequence boost
+        if ((cpi->gfu_boost > 150) && (cpi->baseline_gf_interval > 5))
+        {
+            int pct_extra = (cpi->gfu_boost - 100) / 50;
+            pct_extra = (pct_extra > 10) ? 10 : pct_extra;
+
+            cpi->mid_gf_extra_bits = (cpi->gf_group_bits * pct_extra) / 100;
+            cpi->gf_group_bits -= cpi->mid_gf_extra_bits;
+        }
+        else
+            cpi->mid_gf_extra_bits = 0;
+
+        cpi->gf_bits += cpi->min_frame_bandwidth;                                              // Add in minimum for a frame
+    }
+
+    if (!cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))                  // Normal GF and not a KF
+    {
+        cpi->per_frame_bandwidth = cpi->gf_bits;                                               // Per frame bit target for this frame
+    }
+
+    // Adjustment to estimate_max_q based on a measure of complexity of the section
+    if (cpi->common.frame_type != KEY_FRAME)
+    {
+        FIRSTPASS_STATS sectionstats;
+        double Ratio;
+
+        vp8_zero_stats(&sectionstats);
+        reset_fpf_position(cpi, start_pos);
+
+        for (i = 0 ; i < cpi->baseline_gf_interval ; i++)
+        {
+            vp8_input_stats(cpi, &next_frame);
+            vp8_accumulate_stats(&sectionstats, &next_frame);
+        }
+
+        vp8_avg_stats(&sectionstats);
+
+        if (sectionstats.pcnt_motion < .17)
+            cpi->section_is_low_motion = 1;
+        else
+            cpi->section_is_low_motion = 0;
+
+        if (sectionstats.mvc_abs + sectionstats.mvr_abs > 45)
+            cpi->section_is_fast_motion = 1;
+        else
+            cpi->section_is_fast_motion = 0;
+
+        cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
+
+        Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
+        //if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) )
+        //{
+        cpi->section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);
+
+        if (cpi->section_max_qfactor < 0.80)
+            cpi->section_max_qfactor = 0.80;
+
+        //}
+        //else
+        //    cpi->section_max_qfactor = 1.0;
+
+        reset_fpf_position(cpi, start_pos);
+    }
+
+#ifdef FIRSTPASS_MM
+    // Reset the First pass motion map file position
+    vp8_fpmm_reset_pos(cpi, fpmm_pos);
+#endif
+}
+
+// Allocate bits to a normal frame that is neither a gf an arf or a key frame.
+static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
+{
+    int    target_frame_size;                                                             // gf_group_error_left
+
+    double modified_err;
+    double err_fraction;                                                                 // What portion of the remaining GF group error is used by this frame
+
+    int max_bits = frame_max_bits(cpi);    // Max for a single frame
+
+    // The final few frames have special treatment
+    if (cpi->frames_till_gf_update_due >= (int)(cpi->total_stats.count - cpi->common.current_video_frame))
+    {
+        cpi->gf_group_bits = (cpi->bits_left > 0) ? cpi->bits_left : 0;;
+    }
+
+    // Calculate modified prediction error used in bit allocation
+    modified_err = calculate_modified_err(cpi, this_frame);
+
+    if (cpi->gf_group_error_left > 0)
+        err_fraction = modified_err / cpi->gf_group_error_left;                              // What portion of the remaining GF group error is used by this frame
+    else
+        err_fraction = 0.0;
+
+    target_frame_size = (int)((double)cpi->gf_group_bits * err_fraction);                    // How many of those bits available for allocation should we give it?
+
+    // Clip to target size to 0 - max_bits (or cpi->gf_group_bits) at the top end.
+    if (target_frame_size < 0)
+        target_frame_size = 0;
+    else
+    {
+        if (target_frame_size > max_bits)
+            target_frame_size = max_bits;
+
+        if (target_frame_size > cpi->gf_group_bits)
+            target_frame_size = cpi->gf_group_bits;
+    }
+
+    cpi->gf_group_error_left -= modified_err;                                               // Adjust error remaining
+    cpi->gf_group_bits -= target_frame_size;                                                // Adjust bits remaining
+
+    if (cpi->gf_group_bits < 0)
+        cpi->gf_group_bits = 0;
+
+    target_frame_size += cpi->min_frame_bandwidth;                                          // Add in the minimum number of bits that is set aside for every frame.
+
+    // Special case for the frame that lies half way between two gfs
+    if (cpi->common.frames_since_golden == cpi->baseline_gf_interval / 2)
+        target_frame_size += cpi->mid_gf_extra_bits;
+
+    cpi->per_frame_bandwidth = target_frame_size;                                           // Per frame bit target for this frame
+}
+
+void vp8_second_pass(VP8_COMP *cpi)
+{
+    int tmp_q;
+    int frames_left = (int)(cpi->total_stats.count - cpi->common.current_video_frame);
+
+    FIRSTPASS_STATS this_frame;
+    FIRSTPASS_STATS this_frame_copy;
+
+    VP8_COMMON *cm = &cpi->common;
+
+    double this_frame_error;
+    double this_frame_intra_error;
+    double this_frame_coded_error;
+
+    FIRSTPASS_STATS *start_pos;
+
+    if (!cpi->stats_in)
+    {
+        return ;
+    }
+
+    vp8_clear_system_state();
+
+    if (EOF == vp8_input_stats(cpi, &this_frame))
+        return;
+
+#ifdef FIRSTPASS_MM
+    vpx_memset(cpi->fp_motion_map, 0, cpi->common.MBs);
+    cpi->fpmm_pos = vp8_fpmm_get_pos(cpi);
+    vp8_advance_fpmm(cpi, 1);         // Read this frame's first pass motion map
+#endif
+
+    this_frame_error = this_frame.ssim_weighted_pred_err;
+    this_frame_intra_error = this_frame.intra_error;
+    this_frame_coded_error = this_frame.coded_error;
+
+    // Store information regarding level of motion etc for use mode decisions.
+    cpi->motion_speed = (int)(fabs(this_frame.MVr) + fabs(this_frame.MVc));
+    cpi->motion_var = (int)(fabs(this_frame.MVrv) + fabs(this_frame.MVcv));
+    cpi->inter_lvl = (int)(this_frame.pcnt_inter * 100);
+    cpi->intra_lvl = (int)((1.0 - this_frame.pcnt_inter) * 100);
+    cpi->motion_lvl = (int)(this_frame.pcnt_motion * 100);
+
+    start_pos = cpi->stats_in;
+
+    // keyframe and section processing !
+    if (cpi->frames_to_key == 0)
+    {
+        // Define next KF group and assign bits to it
+        vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+        vp8_find_next_key_frame(cpi, &this_frame_copy);
+
+        // Special case: Error error_resilient_mode mode does not make much sense for two pass but with its current meaning but this code is designed to stop
+        // outlandish behaviour if someone does set it when using two pass. It effectively disables GF groups.
+        // This is temporary code till we decide what should really happen in this case.
+        if (cpi->oxcf.error_resilient_mode)
+        {
+            cpi->gf_group_bits = cpi->kf_group_bits;
+            cpi->gf_group_error_left = cpi->kf_group_error_left;
+            cpi->baseline_gf_interval = cpi->frames_to_key;
+            cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+            cpi->source_alt_ref_pending = FALSE;
+        }
+
+    }
+
+    // Is this a GF / ARF (Note that a KF is always also a GF)
+    if (cpi->frames_till_gf_update_due == 0)
+    {
+        // Define next gf group and assign bits to it
+        vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+        define_gf_group(cpi, &this_frame_copy);
+
+        // If we are going to code an altref frame at the end of the group and the current frame is not a key frame....
+        // If the previous group used an arf this frame has already benefited from that arf boost and it should not be given extra bits
+        // If the previous group was NOT coded using arf we may want to apply some boost to this GF as well
+        if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))
+        {
+            // Assign a standard frames worth of bits from those allocated to the GF group
+            vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+            assign_std_frame_bits(cpi, &this_frame_copy);
+
+            // If appropriate (we are switching into ARF active but it was not previously active) apply a boost for the gf at the start of the group.
+            //if ( !cpi->source_alt_ref_active && (cpi->gfu_boost > 150) )
+            if (FALSE)
+            {
+                int extra_bits;
+                int pct_extra = (cpi->gfu_boost - 100) / 50;
+
+                pct_extra = (pct_extra > 20) ? 20 : pct_extra;
+
+                extra_bits = (cpi->gf_group_bits * pct_extra) / 100;
+                cpi->gf_group_bits -= extra_bits;
+                cpi->per_frame_bandwidth += extra_bits;
+            }
+        }
+    }
+
+    // Otherwise this is an ordinary frame
+    else
+    {
+        // Special case: Error error_resilient_mode mode does not make much sense for two pass but with its current meaning but this code is designed to stop
+        // outlandish behaviour if someone does set it when using two pass. It effectively disables GF groups.
+        // This is temporary code till we decide what should really happen in this case.
+        if (cpi->oxcf.error_resilient_mode)
+        {
+            cpi->frames_till_gf_update_due = cpi->frames_to_key;
+
+            if (cpi->common.frame_type != KEY_FRAME)
+            {
+                // Assign bits from those allocated to the GF group
+                vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+                assign_std_frame_bits(cpi, &this_frame_copy);
+            }
+        }
+        else
+        {
+            // Assign bits from those allocated to the GF group
+            vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
+            assign_std_frame_bits(cpi, &this_frame_copy);
+        }
+    }
+
+    // Set nominal per second bandwidth for this frame
+    cpi->target_bandwidth = cpi->per_frame_bandwidth * cpi->output_frame_rate;
+    if (cpi->target_bandwidth < 0)
+        cpi->target_bandwidth = 0;
+
+    if (cpi->common.current_video_frame == 0)
+    {
+        // guess at 2nd pass q
+        cpi->est_max_qcorrection_factor = 1.0;
+        tmp_q = estimate_max_q(cpi, (cpi->total_coded_error_left / frames_left), (int)(cpi->bits_left / frames_left), cpi->common.Height, cpi->common.Width);
+
+        if (tmp_q < cpi->worst_quality)
+        {
+            cpi->active_worst_quality         = tmp_q;
+            cpi->ni_av_qi                     = tmp_q;
+        }
+        else
+        {
+            cpi->active_worst_quality         = cpi->worst_quality;
+            cpi->ni_av_qi                     = cpi->worst_quality;
+        }
+    }
+    else
+    {
+        if (frames_left < 1)
+            frames_left = 1;
+
+        tmp_q = estimate_max_q(cpi, (cpi->total_coded_error_left / frames_left), (int)(cpi->bits_left / frames_left), cpi->common.Height, cpi->common.Width);
+
+        // Move active_worst_quality but in a damped way
+        if (tmp_q > cpi->active_worst_quality)
+            cpi->active_worst_quality ++;
+        else if (tmp_q < cpi->active_worst_quality)
+            cpi->active_worst_quality --;
+
+        cpi->active_worst_quality = ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
+
+        // Clamp to user set limits
+        if (cpi->active_worst_quality > cpi->worst_quality)
+            cpi->active_worst_quality = cpi->worst_quality;
+        else if (cpi->active_worst_quality < cpi->best_quality)
+            cpi->active_worst_quality = cpi->best_quality;
+
+    }
+
+    cpi->frames_to_key --;
+    cpi->total_error_left      -= this_frame_error;
+    cpi->total_intra_error_left -= this_frame_intra_error;
+    cpi->total_coded_error_left -= this_frame_coded_error;
+}
+
+
+static BOOL test_candidate_kf(VP8_COMP *cpi,  FIRSTPASS_STATS *last_frame, FIRSTPASS_STATS *this_frame, FIRSTPASS_STATS *next_frame)
+{
+    BOOL is_viable_kf = FALSE;
+
+    // Does the frame satisfy the primary criteria of a key frame
+    //      If so, then examine how well it predicts subsequent frames
+    if ((this_frame->pcnt_second_ref < 0.10) &&
+        (next_frame->pcnt_second_ref < 0.10) &&
+        ((this_frame->pcnt_inter < 0.05) ||
+         (
+             (this_frame->pcnt_inter < .25) &&
+             ((this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) &&
+             ((fabs(last_frame->coded_error - this_frame->coded_error) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > .40) ||
+              (fabs(last_frame->intra_error - this_frame->intra_error) / DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > .40) ||
+              ((next_frame->intra_error / DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5)
+             )
+         )
+        )
+       )
+    {
+        int i;
+        FIRSTPASS_STATS *start_pos;
+
+        FIRSTPASS_STATS local_next_frame;
+
+        double boost_score = 0.0;
+        double old_boost_score = 0.0;
+        double decay_accumulator = 1.0;
+        double next_iiratio;
+
+        vpx_memcpy(&local_next_frame, next_frame, sizeof(*next_frame));
+
+        // Note the starting file position so we can reset to it
+        start_pos = cpi->stats_in;
+
+        // Examine how well the key frame predicts subsequent frames
+        for (i = 0 ; i < 16; i++)
+        {
+            next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error / DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error)) ;
+
+            if (next_iiratio > RMAX)
+                next_iiratio = RMAX;
+
+            // Cumulative effect of decay in prediction quality
+            if (local_next_frame.pcnt_inter > 0.85)
+                decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter;
+            else
+                decay_accumulator = decay_accumulator * ((0.85 + local_next_frame.pcnt_inter) / 2.0);
+
+            //decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter;
+
+            // Keep a running total
+            boost_score += (decay_accumulator * next_iiratio);
+
+            // Test various breakout clauses
+            if ((local_next_frame.pcnt_inter < 0.05) ||
+                (next_iiratio < 1.5) ||
+                ((local_next_frame.pcnt_inter < 0.20) && (next_iiratio < 3.0)) ||
+                ((boost_score - old_boost_score) < 0.5) ||
+                (local_next_frame.intra_error < 200)
+               )
+            {
+                break;
+            }
+
+            old_boost_score = boost_score;
+
+            // Get the next frame details
+            if (EOF == vp8_input_stats(cpi, &local_next_frame))
+                break;
+        }
+
+        // If there is tolerable prediction for at least the next 3 frames then break out else discard this pottential key frame and move on
+        if (boost_score > 5.0 && (i > 3))
+            is_viable_kf = TRUE;
+        else
+        {
+            // Reset the file position
+            reset_fpf_position(cpi, start_pos);
+
+            is_viable_kf = FALSE;
+        }
+    }
+
+    return is_viable_kf;
+}
+void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
+{
+    int i;
+    FIRSTPASS_STATS last_frame;
+    FIRSTPASS_STATS first_frame;
+    FIRSTPASS_STATS next_frame;
+    FIRSTPASS_STATS *start_position;
+
+    double decay_accumulator = 0;
+    double boost_score = 0;
+    double old_boost_score = 0.0;
+    double loop_decay_rate;
+
+    double kf_mod_err = 0.0;
+    double kf_group_err = 0.0;
+    double kf_group_intra_err = 0.0;
+    double kf_group_coded_err = 0.0;
+    double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
+
+    vp8_clear_system_state();  //__asm emms;
+    start_position = cpi->stats_in;
+
+    cpi->common.frame_type = KEY_FRAME;
+
+    // Clear the alt ref active flag as this can never be active on a key frame
+    cpi->source_alt_ref_active = FALSE;
+
+    // Kf is always a gf so clear frames till next gf counter
+    cpi->frames_till_gf_update_due = 0;
+
+    cpi->frames_to_key = 1;
+
+    // Take a copy of the initial frame details
+    vpx_memcpy(&first_frame, this_frame, sizeof(*this_frame));
+
+    cpi->kf_group_bits = 0;       // Estimate of total bits avaialable to kf group
+    cpi->kf_group_error_left = 0;  // Group modified error score.
+
+    kf_mod_err = calculate_modified_err(cpi, this_frame);
+
+    // find the next keyframe
+    while (cpi->stats_in < cpi->stats_in_end)
+    {
+        // Accumulate kf group error
+        kf_group_err += calculate_modified_err(cpi, this_frame);
+
+        // These figures keep intra and coded error counts for all frames including key frames in the group.
+        // The effect of the key frame itself can be subtracted out using the first_frame data collected above
+        kf_group_intra_err += this_frame->intra_error;
+        kf_group_coded_err += this_frame->coded_error;
+
+        vpx_memcpy(&last_frame, this_frame, sizeof(*this_frame));
+
+        // Provided that we are not at the end of the file...
+        if (EOF != vp8_input_stats(cpi, this_frame))
+        {
+            if (lookup_next_frame_stats(cpi, &next_frame) != EOF)
+            {
+                if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
+                    break;
+            }
+        }
+
+        // Step on to the next frame
+        cpi->frames_to_key ++;
+
+        // If we don't have a real key frame within the next two
+        // forcekeyframeevery intervals then break out of the loop.
+        if (cpi->frames_to_key >= 2 *(int)cpi->key_frame_frequency)
+            break;
+
+    }
+
+    // If there is a max kf interval set by the user we must obey it.
+    // We already breakout of the loop above at 2x max.
+    // This code centers the extra kf if the actual natural
+    // interval is between 1x and 2x
+    if ( cpi->frames_to_key > (int)cpi->key_frame_frequency )
+    {
+        cpi->frames_to_key /= 2;
+
+        // Estimate corrected kf group error
+        kf_group_err /= 2.0;
+        kf_group_intra_err /= 2.0;
+        kf_group_coded_err /= 2.0;
+    }
+
+    // Special case for the last frame of the file
+    if (cpi->stats_in >= cpi->stats_in_end)
+    {
+        // Accumulate kf group error
+        kf_group_err += calculate_modified_err(cpi, this_frame);
+
+        // These figures keep intra and coded error counts for all frames including key frames in the group.
+        // The effect of the key frame itself can be subtracted out using the first_frame data collected above
+        kf_group_intra_err += this_frame->intra_error;
+        kf_group_coded_err += this_frame->coded_error;
+    }
+
+    // Calculate the number of bits that should be assigned to the kf group.
+    if ((cpi->bits_left > 0) && ((int)cpi->modified_total_error_left > 0))
+    {
+        int max_bits = frame_max_bits(cpi);    // Max for a single normal frame (not key frame)
+
+        // Default allocation based on bits left and relative complexity of the section
+        cpi->kf_group_bits = (int)(cpi->bits_left * (kf_group_err / cpi->modified_total_error_left));
+
+        // Clip based on maximum per frame rate defined by the user.
+        if (cpi->kf_group_bits > max_bits * cpi->frames_to_key)
+            cpi->kf_group_bits = max_bits * cpi->frames_to_key;
+
+        // Additional special case for CBR if buffer is getting full.
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            // If the buffer is near or above the optimal and this kf group is not being allocated much
+            // then increase the allocation a bit.
+            if (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level)
+            {
+                int high_water_mark = (cpi->oxcf.optimal_buffer_level + cpi->oxcf.maximum_buffer_size) >> 1;
+                int min_group_bits;
+
+                // We are at or above the maximum.
+                if (cpi->buffer_level >= high_water_mark)
+                {
+                    min_group_bits = (cpi->av_per_frame_bandwidth * cpi->frames_to_key) + (cpi->buffer_level - high_water_mark);
+
+                    if (cpi->kf_group_bits < min_group_bits)
+                        cpi->kf_group_bits = min_group_bits;
+                }
+                // We are above optimal but below the maximum
+                else if (cpi->kf_group_bits < (cpi->av_per_frame_bandwidth * cpi->frames_to_key))
+                {
+                    int bits_below_av = (cpi->av_per_frame_bandwidth * cpi->frames_to_key) - cpi->kf_group_bits;
+                    cpi->kf_group_bits += (int)((double)bits_below_av * (double)(cpi->buffer_level - cpi->oxcf.optimal_buffer_level) /
+                                                (double)(high_water_mark - cpi->oxcf.optimal_buffer_level));
+                }
+            }
+        }
+    }
+    else
+        cpi->kf_group_bits = 0;
+
+    // Reset the first pass file position
+    reset_fpf_position(cpi, start_position);
+
+    // determine how big to make this keyframe based on how well the subsequent frames use inter blocks
+    decay_accumulator = 1.0;
+    boost_score = 0.0;
+    loop_decay_rate = 1.00;       // Starting decay rate
+
+    for (i = 0 ; i < cpi->frames_to_key ; i++)
+    {
+        double r;
+
+        if (EOF == vp8_input_stats(cpi, &next_frame))
+            break;
+
+        r = (IIKFACTOR2 * next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error)) ;
+
+        if (r > RMAX)
+            r = RMAX;
+
+        // Adjust loop decay rate
+        //if ( next_frame.pcnt_inter < loop_decay_rate )
+        loop_decay_rate = next_frame.pcnt_inter;
+
+        if ((1.0 - (next_frame.pcnt_motion / 10.0)) < loop_decay_rate)
+            loop_decay_rate = (1.0 - (next_frame.pcnt_motion / 10.0));
+
+        decay_accumulator = decay_accumulator * loop_decay_rate;
+
+        boost_score += (decay_accumulator * r);
+
+        if ((i > MIN_GF_INTERVAL) &&
+            ((boost_score - old_boost_score) < 1.0))
+        {
+            break;
+        }
+
+        old_boost_score = boost_score;
+    }
+
+    if (1)
+    {
+        FIRSTPASS_STATS sectionstats;
+        double Ratio;
+
+        vp8_zero_stats(&sectionstats);
+        reset_fpf_position(cpi, start_position);
+
+        for (i = 0 ; i < cpi->frames_to_key ; i++)
+        {
+            vp8_input_stats(cpi, &next_frame);
+            vp8_accumulate_stats(&sectionstats, &next_frame);
+        }
+
+        vp8_avg_stats(&sectionstats);
+
+        if (sectionstats.pcnt_motion < .17)
+            cpi->section_is_low_motion = 1;
+        else
+            cpi->section_is_low_motion = 0;
+
+        if (sectionstats.mvc_abs + sectionstats.mvr_abs > 45)
+            cpi->section_is_fast_motion = 1;
+        else
+            cpi->section_is_fast_motion = 0;
+
+        cpi->section_intra_rating = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
+
+        Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
+        // if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) )
+        //{
+        cpi->section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);
+
+        if (cpi->section_max_qfactor < 0.80)
+            cpi->section_max_qfactor = 0.80;
+
+        //}
+        //else
+        //    cpi->section_max_qfactor = 1.0;
+    }
+
+    // When using CBR apply additional buffer fullness related upper limits
+    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+    {
+        double max_boost;
+
+        if (cpi->drop_frames_allowed)
+        {
+            int df_buffer_level = cpi->oxcf.drop_frames_water_mark * (cpi->oxcf.optimal_buffer_level / 100);
+
+            if (cpi->buffer_level > df_buffer_level)
+                max_boost = ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
+            else
+                max_boost = 0.0;
+        }
+        else if (cpi->buffer_level > 0)
+        {
+            max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
+        }
+        else
+        {
+            max_boost = 0.0;
+        }
+
+        if (boost_score > max_boost)
+            boost_score = max_boost;
+    }
+
+    // Reset the first pass file position
+    reset_fpf_position(cpi, start_position);
+
+    // Work out how many bits to allocate for the key frame itself
+    if (1)
+    {
+        int kf_boost = boost_score;
+        int allocation_chunks;
+        int Counter = cpi->frames_to_key;
+        int alt_kf_bits;
+
+        // Min boost based on kf interval
+#if 0
+
+        while ((kf_boost < 48) && (Counter > 0))
+        {
+            Counter -= 2;
+            kf_boost ++;
+        }
+
+#endif
+
+        if (kf_boost < 48)
+        {
+            kf_boost += ((Counter + 1) >> 1);
+
+            if (kf_boost > 48) kf_boost = 48;
+        }
+
+        // bigger frame sizes need larger kf boosts, smaller frames smaller boosts...
+        if ((cpi->common.last_frame.y_width  * cpi->common.last_frame.y_height) > (320 * 240))
+            kf_boost += 2 * (cpi->common.last_frame.y_width  * cpi->common.last_frame.y_height) / (320 * 240);
+        else if ((cpi->common.last_frame.y_width  * cpi->common.last_frame.y_height) < (320 * 240))
+            kf_boost -= 4 * (320 * 240) / (cpi->common.last_frame.y_width  * cpi->common.last_frame.y_height);
+
+        kf_boost = (int)((double)kf_boost * 100.0) >> 4;                          // Scale 16 to 100
+
+        // Adjustment to boost based on recent average q
+        kf_boost = kf_boost * vp8_kf_boost_qadjustment[cpi->ni_av_qi] / 100;
+
+        if (kf_boost < 250)                                                      // Min KF boost
+            kf_boost = 250;
+
+        // We do three calculations for kf size.
+        // The first is based on the error score for the whole kf group.
+        // The second (optionaly) on the key frames own error if this is smaller than the average for the group.
+        // The final one insures that the frame receives at least the allocation it would have received based on its own error score vs the error score remaining
+
+        allocation_chunks = ((cpi->frames_to_key - 1) * 100) + kf_boost;           // cpi->frames_to_key-1 because key frame itself is taken care of by kf_boost
+
+        // Normalize Altboost and allocations chunck down to prevent overflow
+        while (kf_boost > 1000)
+        {
+            kf_boost /= 2;
+            allocation_chunks /= 2;
+        }
+
+        cpi->kf_group_bits = (cpi->kf_group_bits < 0) ? 0 : cpi->kf_group_bits;
+
+        // Calculate the number of bits to be spent on the key frame
+        cpi->kf_bits  = (int)((double)kf_boost * ((double)cpi->kf_group_bits / (double)allocation_chunks));
+
+        // Apply an additional limit for CBR
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            if (cpi->kf_bits > ((3 * cpi->buffer_level) >> 2))
+                cpi->kf_bits = (3 * cpi->buffer_level) >> 2;
+        }
+
+        // If the key frame is actually easier than the average for the kf group (which does sometimes happen... eg a blank intro frame)
+        // Then use an alternate calculation based on the kf error score which should give a smaller key frame.
+        if (kf_mod_err < kf_group_err / cpi->frames_to_key)
+        {
+            double  alt_kf_grp_bits = ((double)cpi->bits_left * (kf_mod_err * (double)cpi->frames_to_key) / cpi->modified_total_error_left) ;
+
+            alt_kf_bits = (int)((double)kf_boost * (alt_kf_grp_bits / (double)allocation_chunks));
+
+            if (cpi->kf_bits > alt_kf_bits)
+            {
+                cpi->kf_bits = alt_kf_bits;
+            }
+        }
+        // Else if it is much harder than other frames in the group make sure it at least receives an allocation in keeping with its relative error score
+        else
+        {
+            alt_kf_bits = (int)((double)cpi->bits_left * (kf_mod_err / cpi->modified_total_error_left));
+
+            if (alt_kf_bits > cpi->kf_bits)
+            {
+                cpi->kf_bits = alt_kf_bits;
+            }
+        }
+
+        cpi->kf_group_bits -= cpi->kf_bits;
+        cpi->kf_bits += cpi->min_frame_bandwidth;                                          // Add in the minimum frame allowance
+
+        cpi->per_frame_bandwidth = cpi->kf_bits;                                           // Peer frame bit target for this frame
+        cpi->target_bandwidth = cpi->kf_bits * cpi->output_frame_rate;                      // Convert to a per second bitrate
+    }
+
+    // Note the total error score of the kf group minus the key frame itself
+    cpi->kf_group_error_left = (int)(kf_group_err - kf_mod_err);
+
+    // Adjust the count of total modified error left.
+    // The count of bits left is adjusted elsewhere based on real coded frame sizes
+    cpi->modified_total_error_left -= kf_group_err;
+
+    if (cpi->oxcf.allow_spatial_resampling)
+    {
+        int resample_trigger = FALSE;
+        int last_kf_resampled = FALSE;
+        int kf_q;
+        int scale_val = 0;
+        int hr, hs, vr, vs;
+        int new_width = cpi->oxcf.Width;
+        int new_height = cpi->oxcf.Height;
+
+        int projected_buffer_level = cpi->buffer_level;
+        int tmp_q;
+
+        double projected_bits_perframe;
+        double group_iiratio = (kf_group_intra_err - first_frame.intra_error) / (kf_group_coded_err - first_frame.coded_error);
+        double err_per_frame = kf_group_err / cpi->frames_to_key;
+        double bits_per_frame;
+        double av_bits_per_frame;
+        double effective_size_ratio;
+
+        if ((cpi->common.Width != cpi->oxcf.Width) || (cpi->common.Height != cpi->oxcf.Height))
+            last_kf_resampled = TRUE;
+
+        // Set back to unscaled by defaults
+        cpi->common.horiz_scale = NORMAL;
+        cpi->common.vert_scale = NORMAL;
+
+        // Calculate Average bits per frame.
+        //av_bits_per_frame = cpi->bits_left/(double)(cpi->total_stats.count - cpi->common.current_video_frame);
+        av_bits_per_frame = cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate);
+        //if ( av_bits_per_frame < 0.0 )
+        //  av_bits_per_frame = 0.0
+
+        // CBR... Use the clip average as the target for deciding resample
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            bits_per_frame = av_bits_per_frame;
+        }
+
+        // In VBR we want to avoid downsampling in easy section unless we are under extreme pressure
+        // So use the larger of target bitrate for this sectoion or average bitrate for sequence
+        else
+        {
+            bits_per_frame = cpi->kf_group_bits / cpi->frames_to_key;     // This accounts for how hard the section is...
+
+            if (bits_per_frame < av_bits_per_frame)                      // Dont turn to resampling in easy sections just because they have been assigned a small number of bits
+                bits_per_frame = av_bits_per_frame;
+        }
+
+        // bits_per_frame should comply with our minimum
+        if (bits_per_frame < (cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100))
+            bits_per_frame = (cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
+
+        // Work out if spatial resampling is necessary
+        kf_q = estimate_kf_group_q(cpi, err_per_frame, bits_per_frame, new_height, new_width, group_iiratio);
+
+        // If we project a required Q higher than the maximum allowed Q then make a guess at the actual size of frames in this section
+        projected_bits_perframe = bits_per_frame;
+        tmp_q = kf_q;
+
+        while (tmp_q > cpi->worst_quality)
+        {
+            projected_bits_perframe *= 1.04;
+            tmp_q--;
+        }
+
+        // Guess at buffer level at the end of the section
+        projected_buffer_level = cpi->buffer_level - (int)((projected_bits_perframe - av_bits_per_frame) * cpi->frames_to_key);
+
+        if (0)
+        {
+            FILE *f = fopen("Subsamle.stt", "a");
+            fprintf(f, " %8d %8d %8d %8d %12.0f %8d %8d %8d\n",  cpi->common.current_video_frame, kf_q, cpi->common.horiz_scale, cpi->common.vert_scale,  kf_group_err / cpi->frames_to_key, cpi->kf_group_bits / cpi->frames_to_key, new_height, new_width);
+            fclose(f);
+        }
+
+        // The trigger for spatial resampling depends on the various parameters such as whether we are streaming (CBR) or VBR.
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            // Trigger resample if we are projected to fall below down sample level or
+            // resampled last time and are projected to remain below the up sample level
+            if ((projected_buffer_level < (cpi->oxcf.resample_down_water_mark * cpi->oxcf.optimal_buffer_level / 100)) ||
+                (last_kf_resampled && (projected_buffer_level < (cpi->oxcf.resample_up_water_mark * cpi->oxcf.optimal_buffer_level / 100))))
+                //( ((cpi->buffer_level < (cpi->oxcf.resample_down_water_mark * cpi->oxcf.optimal_buffer_level / 100))) &&
+                //  ((projected_buffer_level < (cpi->oxcf.resample_up_water_mark * cpi->oxcf.optimal_buffer_level / 100))) ))
+                resample_trigger = TRUE;
+            else
+                resample_trigger = FALSE;
+        }
+        else
+        {
+            long long clip_bits = (long long)(cpi->total_stats.count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
+            long long over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level;
+            long long over_spend2 = cpi->oxcf.starting_buffer_level - projected_buffer_level;
+
+            if ((last_kf_resampled && (kf_q > cpi->worst_quality)) ||                                               // If triggered last time the threshold for triggering again is reduced
+                ((kf_q > cpi->worst_quality) &&                                                                  // Projected Q higher than allowed and ...
+                 (over_spend > clip_bits / 20)))                                                               // ... Overspend > 5% of total bits
+                resample_trigger = TRUE;
+            else
+                resample_trigger = FALSE;
+
+        }
+
+        if (resample_trigger)
+        {
+            while ((kf_q >= cpi->worst_quality) && (scale_val < 6))
+            {
+                scale_val ++;
+
+                cpi->common.vert_scale   = vscale_lookup[scale_val];
+                cpi->common.horiz_scale  = hscale_lookup[scale_val];
+
+                Scale2Ratio(cpi->common.horiz_scale, &hr, &hs);
+                Scale2Ratio(cpi->common.vert_scale, &vr, &vs);
+
+                new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs;
+                new_height = ((vs - 1) + (cpi->oxcf.Height * vr)) / vs;
+
+                // Reducing the area to 1/4 does not reduce the complexity (err_per_frame) to 1/4...
+                // effective_sizeratio attempts to provide a crude correction for this
+                effective_size_ratio = (double)(new_width * new_height) / (double)(cpi->oxcf.Width * cpi->oxcf.Height);
+                effective_size_ratio = (1.0 + (3.0 * effective_size_ratio)) / 4.0;
+
+                // Now try again and see what Q we get with the smaller image size
+                kf_q = estimate_kf_group_q(cpi, err_per_frame * effective_size_ratio, bits_per_frame, new_height, new_width, group_iiratio);
+
+                if (0)
+                {
+                    FILE *f = fopen("Subsamle.stt", "a");
+                    fprintf(f, "******** %8d %8d %8d %12.0f %8d %8d %8d\n",  kf_q, cpi->common.horiz_scale, cpi->common.vert_scale,  kf_group_err / cpi->frames_to_key, cpi->kf_group_bits / cpi->frames_to_key, new_height, new_width);
+                    fclose(f);
+                }
+            }
+        }
+
+        if ((cpi->common.Width != new_width) || (cpi->common.Height != new_height))
+        {
+            cpi->common.Width = new_width;
+            cpi->common.Height = new_height;
+            vp8_alloc_compressor_data(cpi);
+        }
+    }
+}
diff --git a/vp8/encoder/firstpass.h b/vp8/encoder/firstpass.h
new file mode 100644 (file)
index 0000000..d7b52f3
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if !defined __INC_FIRSTPASS_H
+#define      __INC_FIRSTPASS_H
+
+extern void vp8_init_first_pass(VP8_COMP *cpi);
+extern void vp8_first_pass(VP8_COMP *cpi);
+extern void vp8_end_first_pass(VP8_COMP *cpi);
+
+extern void vp8_init_second_pass(VP8_COMP *cpi);
+extern void vp8_second_pass(VP8_COMP *cpi);
+extern void vp8_end_second_pass(VP8_COMP *cpi);
+
+#endif
diff --git a/vp8/encoder/generic/csystemdependent.c b/vp8/encoder/generic/csystemdependent.c
new file mode 100644 (file)
index 0000000..52aab66
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "variance.h"
+#include "onyx_int.h"
+
+
+void vp8_arch_x86_encoder_init(VP8_COMP *cpi);
+
+
+void (*vp8_fast_quantize_b)(BLOCK *b, BLOCKD *d);
+extern void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d);
+
+void (*vp8_yv12_copy_partial_frame_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction);
+extern void vp8_yv12_copy_partial_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction);
+
+void vp8_cmachine_specific_config(VP8_COMP *cpi)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    cpi->rtcd.common                    = &cpi->common.rtcd;
+    cpi->rtcd.variance.sad16x16              = vp8_sad16x16_c;
+    cpi->rtcd.variance.sad16x8               = vp8_sad16x8_c;
+    cpi->rtcd.variance.sad8x16               = vp8_sad8x16_c;
+    cpi->rtcd.variance.sad8x8                = vp8_sad8x8_c;
+    cpi->rtcd.variance.sad4x4                = vp8_sad4x4_c;
+
+    cpi->rtcd.variance.sad16x16x3            = vp8_sad16x16x3_c;
+    cpi->rtcd.variance.sad16x8x3             = vp8_sad16x8x3_c;
+    cpi->rtcd.variance.sad8x16x3             = vp8_sad8x16x3_c;
+    cpi->rtcd.variance.sad8x8x3              = vp8_sad8x8x3_c;
+    cpi->rtcd.variance.sad4x4x3              = vp8_sad4x4x3_c;
+
+    cpi->rtcd.variance.sad16x16x4d           = vp8_sad16x16x4d_c;
+    cpi->rtcd.variance.sad16x8x4d            = vp8_sad16x8x4d_c;
+    cpi->rtcd.variance.sad8x16x4d            = vp8_sad8x16x4d_c;
+    cpi->rtcd.variance.sad8x8x4d             = vp8_sad8x8x4d_c;
+    cpi->rtcd.variance.sad4x4x4d             = vp8_sad4x4x4d_c;
+
+    cpi->rtcd.variance.var4x4                = vp8_variance4x4_c;
+    cpi->rtcd.variance.var8x8                = vp8_variance8x8_c;
+    cpi->rtcd.variance.var8x16               = vp8_variance8x16_c;
+    cpi->rtcd.variance.var16x8               = vp8_variance16x8_c;
+    cpi->rtcd.variance.var16x16              = vp8_variance16x16_c;
+
+    cpi->rtcd.variance.subpixvar4x4          = vp8_sub_pixel_variance4x4_c;
+    cpi->rtcd.variance.subpixvar8x8          = vp8_sub_pixel_variance8x8_c;
+    cpi->rtcd.variance.subpixvar8x16         = vp8_sub_pixel_variance8x16_c;
+    cpi->rtcd.variance.subpixvar16x8         = vp8_sub_pixel_variance16x8_c;
+    cpi->rtcd.variance.subpixvar16x16        = vp8_sub_pixel_variance16x16_c;
+    cpi->rtcd.variance.subpixmse16x16        = vp8_sub_pixel_mse16x16_c;
+
+    cpi->rtcd.variance.mse16x16              = vp8_mse16x16_c;
+    cpi->rtcd.variance.getmbss               = vp8_get_mb_ss_c;
+
+    cpi->rtcd.variance.get16x16prederror     = vp8_get16x16pred_error_c;
+    cpi->rtcd.variance.get8x8var             = vp8_get8x8var_c;
+    cpi->rtcd.variance.get16x16var           = vp8_get16x16var_c;;
+    cpi->rtcd.variance.get4x4sse_cs          = vp8_get4x4sse_cs_c;
+
+    cpi->rtcd.fdct.short4x4                  = vp8_short_fdct4x4_c;
+    cpi->rtcd.fdct.short8x4                  = vp8_short_fdct8x4_c;
+    cpi->rtcd.fdct.fast4x4                   = vp8_fast_fdct4x4_c;
+    cpi->rtcd.fdct.fast8x4                   = vp8_fast_fdct8x4_c;
+    cpi->rtcd.fdct.walsh_short4x4            = vp8_short_walsh4x4_c;
+
+    cpi->rtcd.encodemb.berr                  = vp8_block_error_c;
+    cpi->rtcd.encodemb.mberr                 = vp8_mbblock_error_c;
+    cpi->rtcd.encodemb.mbuverr               = vp8_mbuverror_c;
+    cpi->rtcd.encodemb.subb                  = vp8_subtract_b_c;
+    cpi->rtcd.encodemb.submby                = vp8_subtract_mby_c;
+    cpi->rtcd.encodemb.submbuv               = vp8_subtract_mbuv_c;
+
+    cpi->rtcd.quantize.quantb                = vp8_regular_quantize_b;
+    cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_c;
+
+    cpi->rtcd.search.full_search             = vp8_full_search_sad;
+    cpi->rtcd.search.diamond_search          = vp8_diamond_search_sad;
+#endif
+
+    // Pure C:
+    vp8_yv12_copy_partial_frame_ptr = vp8_yv12_copy_partial_frame;
+
+
+#if ARCH_X86 || ARCH_X86_64
+    vp8_arch_x86_encoder_init(cpi);
+#endif
+
+}
diff --git a/vp8/encoder/mcomp.c b/vp8/encoder/mcomp.c
new file mode 100644 (file)
index 0000000..d80059d
--- /dev/null
@@ -0,0 +1,1467 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "mcomp.h"
+#include "vpx_mem/vpx_mem.h"
+
+#include <stdio.h>
+#include <limits.h>
+#include <math.h>
+
+#ifdef ENTROPY_STATS
+static int mv_ref_ct [31] [4] [2];
+static int mv_mode_cts [4] [2];
+#endif
+
+static int mv_bits_sadcost[256];
+
+void vp8cx_init_mv_bits_sadcost()
+{
+    int i;
+
+    for (i = 0; i < 256; i++)
+    {
+        mv_bits_sadcost[i] = (int)sqrt(i * 16);
+    }
+}
+
+
+int vp8_mv_bit_cost(MV *mv, MV *ref, int *mvcost[2], int Weight)
+{
+    // MV costing is based on the distribution of vectors in the previous frame and as such will tend to
+    // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
+    // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
+    // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
+    return ((mvcost[0][(mv->row - ref->row) >> 1] + mvcost[1][(mv->col - ref->col) >> 1]) * Weight) >> 7;
+}
+
+int vp8_mv_err_cost(MV *mv, MV *ref, int *mvcost[2], int error_per_bit)
+{
+    //int i;
+    //return ((mvcost[0][(mv->row - ref->row)>>1] + mvcost[1][(mv->col - ref->col)>>1] + 128) * error_per_bit) >> 8;
+    //return ( (vp8_mv_bit_cost(mv,  ref, mvcost, 100) + 128) * error_per_bit) >> 8;
+
+    //i = (vp8_mv_bit_cost(mv,  ref, mvcost, 100) * error_per_bit + 128) >> 8;
+    return ((mvcost[0][(mv->row - ref->row) >> 1] + mvcost[1][(mv->col - ref->col) >> 1]) * error_per_bit + 128) >> 8;
+    //return (vp8_mv_bit_cost(mv,  ref, mvcost, 128) * error_per_bit + 128) >> 8;
+}
+
+
+static int mv_bits(MV *mv, MV *ref, int *mvcost[2])
+{
+    // get the estimated number of bits for a motion vector, to be used for costing in SAD based
+    // motion estimation
+    return ((mvcost[0][(mv->row - ref->row) >> 1]  +  mvcost[1][(mv->col - ref->col)>> 1]) + 128) >> 8;
+}
+
+void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride)
+{
+    int Len;
+    int search_site_count = 0;
+
+
+    // Generate offsets for 4 search sites per step.
+    Len = MAX_FIRST_STEP;
+    x->ss[search_site_count].mv.col = 0;
+    x->ss[search_site_count].mv.row = 0;
+    x->ss[search_site_count].offset = 0;
+    search_site_count++;
+
+    while (Len > 0)
+    {
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = -Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = Len;
+        search_site_count++;
+
+        // Contract.
+        Len /= 2;
+    }
+
+    x->ss_count = search_site_count;
+    x->searches_per_step = 4;
+}
+
+void vp8_init3smotion_compensation(MACROBLOCK *x, int stride)
+{
+    int Len;
+    int search_site_count = 0;
+
+    // Generate offsets for 8 search sites per step.
+    Len = MAX_FIRST_STEP;
+    x->ss[search_site_count].mv.col = 0;
+    x->ss[search_site_count].mv.row = 0;
+    x->ss[search_site_count].offset = 0;
+    search_site_count++;
+
+    while (Len > 0)
+    {
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = 0;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = -Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = 0;
+        x->ss[search_site_count].offset = Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride - Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = -Len;
+        x->ss[search_site_count].offset = -Len * stride + Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = -Len;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride - Len;
+        search_site_count++;
+
+        // Compute offsets for search sites.
+        x->ss[search_site_count].mv.col = Len;
+        x->ss[search_site_count].mv.row = Len;
+        x->ss[search_site_count].offset = Len * stride + Len;
+        search_site_count++;
+
+
+        // Contract.
+        Len /= 2;
+    }
+
+    x->ss_count = search_site_count;
+    x->searches_per_step = 8;
+}
+
+
+#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+#define PRE(r,c) (*(d->base_pre) + d->pre + ((r)>>2) * d->pre_stride + ((c)>>2)) // pointer to predictor base of a motionvector
+#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
+#define DIST(r,c) svf( PRE(r,c), d->pre_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
+#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
+#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
+#define CHECK_BETTER(v,r,c) IFMVCV(r,c,{if((v = ERR(r,c)) < besterr) { besterr = v; br=r; bc=c; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MAX(x,y) (((x)>(y))?(x):(y))
+
+//#define CHECK_BETTER(v,r,c) if((v = ERR(r,c)) < besterr) { besterr = v; br=r; bc=c; }
+
+int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->row) * d->pre_stride + bestmv->col;
+    unsigned char *z = (*(b->base_src) + b->src);
+
+    int rr = ref_mv->row >> 1, rc = ref_mv->col >> 1;
+    int br = bestmv->row << 2, bc = bestmv->col << 2;
+    int tr = br, tc = bc;
+    unsigned int besterr = INT_MAX;
+    unsigned int left, right, up, down, diag;
+    unsigned int sse;
+    unsigned int whichdir;
+    unsigned int halfiters = 4;
+    unsigned int quarteriters = 4;
+
+    int minc = MAX(x->mv_col_min << 2, (ref_mv->col >> 1) - ((1 << mvlong_width) - 1));
+    int maxc = MIN(x->mv_col_max << 2, (ref_mv->col >> 1) + ((1 << mvlong_width) - 1));
+    int minr = MAX(x->mv_row_min << 2, (ref_mv->row >> 1) - ((1 << mvlong_width) - 1));
+    int maxr = MIN(x->mv_row_max << 2, (ref_mv->row >> 1) + ((1 << mvlong_width) - 1));
+
+    // central mv
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+
+    // calculate central point error
+    besterr = vf(y, d->pre_stride, z, b->src_stride, &sse);
+    besterr += vp8_mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+
+    // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
+    while (--halfiters)
+    {
+        // 1/2 pel
+        CHECK_BETTER(left, tr, tc - 2);
+        CHECK_BETTER(right, tr, tc + 2);
+        CHECK_BETTER(up, tr - 2, tc);
+        CHECK_BETTER(down, tr + 2, tc);
+
+        whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+        switch (whichdir)
+        {
+        case 0:
+            CHECK_BETTER(diag, tr - 2, tc - 2);
+            break;
+        case 1:
+            CHECK_BETTER(diag, tr - 2, tc + 2);
+            break;
+        case 2:
+            CHECK_BETTER(diag, tr + 2, tc - 2);
+            break;
+        case 3:
+            CHECK_BETTER(diag, tr + 2, tc + 2);
+            break;
+        }
+
+        // no reason to check the same one again.
+        if (tr == br && tc == bc)
+            break;
+
+        tr = br;
+        tc = bc;
+    }
+
+    // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
+    // 1/4 pel
+    while (--quarteriters)
+    {
+        CHECK_BETTER(left, tr, tc - 1);
+        CHECK_BETTER(right, tr, tc + 1);
+        CHECK_BETTER(up, tr - 1, tc);
+        CHECK_BETTER(down, tr + 1, tc);
+
+        whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+        switch (whichdir)
+        {
+        case 0:
+            CHECK_BETTER(diag, tr - 1, tc - 1);
+            break;
+        case 1:
+            CHECK_BETTER(diag, tr - 1, tc + 1);
+            break;
+        case 2:
+            CHECK_BETTER(diag, tr + 1, tc - 1);
+            break;
+        case 3:
+            CHECK_BETTER(diag, tr + 1, tc + 1);
+            break;
+        }
+
+        // no reason to check the same one again.
+        if (tr == br && tc == bc)
+            break;
+
+        tr = br;
+        tc = bc;
+    }
+
+    bestmv->row = br << 1;
+    bestmv->col = bc << 1;
+
+    if ((abs(bestmv->col - ref_mv->col) > MAX_FULL_PEL_VAL) || (abs(bestmv->row - ref_mv->row) > MAX_FULL_PEL_VAL))
+        return INT_MAX;
+
+    return besterr;
+}
+#undef MVC
+#undef PRE
+#undef SP
+#undef DIST
+#undef ERR
+#undef CHECK_BETTER
+#undef MIN
+#undef MAX
+int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    int bestmse = INT_MAX;
+    MV startmv;
+    //MV this_mv;
+    MV this_mv;
+    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->row) * d->pre_stride + bestmv->col;
+    unsigned char *z = (*(b->base_src) + b->src);
+    int left, right, up, down, diag;
+    unsigned int sse;
+    int whichdir ;
+
+
+    // Trap uncodable vectors
+    if ((abs((bestmv->col << 3) - ref_mv->col) > MAX_FULL_PEL_VAL) || (abs((bestmv->row << 3) - ref_mv->row) > MAX_FULL_PEL_VAL))
+    {
+        bestmv->row <<= 3;
+        bestmv->col <<= 3;
+        return INT_MAX;
+    }
+
+    // central mv
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+    startmv = *bestmv;
+
+    // calculate central point error
+    bestmse = vf(y, d->pre_stride, z, b->src_stride, &sse);
+    bestmse += vp8_mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+
+    // go left then right and check error
+    this_mv.row = startmv.row;
+    this_mv.col = ((startmv.col - 8) | 4);
+    left = svf(y - 1, d->pre_stride, 4, 0, z, b->src_stride, &sse);
+    left += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+    }
+
+    this_mv.col += 8;
+    right = svf(y, d->pre_stride, 4, 0, z, b->src_stride, &sse);
+    right += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+    }
+
+    // go up then down and check error
+    this_mv.col = startmv.col;
+    this_mv.row = ((startmv.row - 8) | 4);
+    up = svf(y - d->pre_stride, d->pre_stride, 0, 4, z, b->src_stride, &sse);
+    up += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+    }
+
+    this_mv.row += 8;
+    down = svf(y, d->pre_stride, 0, 4, z, b->src_stride, &sse);
+    down += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+    }
+
+
+    // now check 1 more diagonal
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+    // whichdir must be 0-4. Therefore, one of the cases below
+    // must run through. However, because there is no default
+    // and diag is not set elsewhere, we get a compile warning
+    diag = 0;
+    //for(whichdir =0;whichdir<4;whichdir++)
+    //{
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = svf(y - 1 - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 1:
+        this_mv.col += 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = svf(y - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 2:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row += 4;
+        diag = svf(y - 1, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 3:
+        this_mv.col += 4;
+        this_mv.row += 4;
+        diag = svf(y, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    }
+
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+//  }
+
+
+    // time to check quarter pels.
+    if (bestmv->row < startmv.row)
+        y -= d->pre_stride;
+
+    if (bestmv->col < startmv.col)
+        y--;
+
+    startmv = *bestmv;
+
+
+
+    // go left then right and check error
+    this_mv.row = startmv.row;
+
+    if (startmv.col & 7)
+    {
+        this_mv.col = startmv.col - 2;
+        left = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    }
+    else
+    {
+        this_mv.col = (startmv.col - 8) | 6;
+        left = svf(y - 1, d->pre_stride, 6, this_mv.row & 7, z, b->src_stride, &sse);
+    }
+
+    left += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+    }
+
+    this_mv.col += 4;
+    right = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    right += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+    }
+
+    // go up then down and check error
+    this_mv.col = startmv.col;
+
+    if (startmv.row & 7)
+    {
+        this_mv.row = startmv.row - 2;
+        up = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    }
+    else
+    {
+        this_mv.row = (startmv.row - 8) | 6;
+        up = svf(y - d->pre_stride, d->pre_stride, this_mv.col & 7, 6, z, b->src_stride, &sse);
+    }
+
+    up += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+    }
+
+    this_mv.row += 4;
+    down = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+    down += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+    }
+
+
+    // now check 1 more diagonal
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+
+//  for(whichdir=0;whichdir<4;whichdir++)
+//  {
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+
+        if (startmv.row & 7)
+        {
+            this_mv.row -= 2;
+
+            if (startmv.col & 7)
+            {
+                this_mv.col -= 2;
+                diag = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+            }
+            else
+            {
+                this_mv.col = (startmv.col - 8) | 6;
+                diag = svf(y - 1, d->pre_stride, 6, this_mv.row & 7, z, b->src_stride, &sse);;
+            }
+        }
+        else
+        {
+            this_mv.row = (startmv.row - 8) | 6;
+
+            if (startmv.col & 7)
+            {
+                this_mv.col -= 2;
+                diag = svf(y - d->pre_stride, d->pre_stride, this_mv.col & 7, 6, z, b->src_stride, &sse);
+            }
+            else
+            {
+                this_mv.col = (startmv.col - 8) | 6;
+                diag = svf(y - d->pre_stride - 1, d->pre_stride, 6, 6, z, b->src_stride, &sse);
+            }
+        }
+
+        break;
+    case 1:
+        this_mv.col += 2;
+
+        if (startmv.row & 7)
+        {
+            this_mv.row -= 2;
+            diag = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+        }
+        else
+        {
+            this_mv.row = (startmv.row - 8) | 6;
+            diag = svf(y - d->pre_stride, d->pre_stride, this_mv.col & 7, 6, z, b->src_stride, &sse);
+        }
+
+        break;
+    case 2:
+        this_mv.row += 2;
+
+        if (startmv.col & 7)
+        {
+            this_mv.col -= 2;
+            diag = svf(y, d->pre_stride, this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+        }
+        else
+        {
+            this_mv.col = (startmv.col - 8) | 6;
+            diag = svf(y - 1, d->pre_stride, 6, this_mv.row & 7, z, b->src_stride, &sse);;
+        }
+
+        break;
+    case 3:
+        this_mv.col += 2;
+        this_mv.row += 2;
+        diag = svf(y, d->pre_stride,  this_mv.col & 7, this_mv.row & 7, z, b->src_stride, &sse);
+        break;
+    }
+
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+//  }
+
+    return bestmse;
+}
+
+int vp8_find_best_half_pixel_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    int bestmse = INT_MAX;
+    MV startmv;
+    //MV this_mv;
+    MV this_mv;
+    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->row) * d->pre_stride + bestmv->col;
+    unsigned char *z = (*(b->base_src) + b->src);
+    int left, right, up, down, diag;
+    unsigned int sse;
+
+    // Trap uncodable vectors
+    if ((abs((bestmv->col << 3) - ref_mv->col) > MAX_FULL_PEL_VAL) || (abs((bestmv->row << 3) - ref_mv->row) > MAX_FULL_PEL_VAL))
+    {
+        bestmv->row <<= 3;
+        bestmv->col <<= 3;
+        return INT_MAX;
+    }
+
+    // central mv
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+    startmv = *bestmv;
+
+    // calculate central point error
+    bestmse = vf(y, d->pre_stride, z, b->src_stride, &sse);
+    bestmse += vp8_mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
+
+    // go left then right and check error
+    this_mv.row = startmv.row;
+    this_mv.col = ((startmv.col - 8) | 4);
+    left = svf(y - 1, d->pre_stride, 4, 0, z, b->src_stride, &sse);
+    left += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (left < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = left;
+    }
+
+    this_mv.col += 8;
+    right = svf(y, d->pre_stride, 4, 0, z, b->src_stride, &sse);
+    right += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (right < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = right;
+    }
+
+    // go up then down and check error
+    this_mv.col = startmv.col;
+    this_mv.row = ((startmv.row - 8) | 4);
+    up = svf(y - d->pre_stride, d->pre_stride, 0, 4, z, b->src_stride, &sse);
+    up += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (up < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = up;
+    }
+
+    this_mv.row += 8;
+    down = svf(y, d->pre_stride, 0, 4, z, b->src_stride, &sse);
+    down += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (down < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = down;
+    }
+
+    // somewhat strangely not doing all the diagonals for half pel is slower than doing them.
+#if 0
+    // now check 1 more diagonal -
+    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
+    this_mv = startmv;
+
+    switch (whichdir)
+    {
+    case 0:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = svf(y - 1 - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 1:
+        this_mv.col += 4;
+        this_mv.row = (this_mv.row - 8) | 4;
+        diag = svf(y - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 2:
+        this_mv.col = (this_mv.col - 8) | 4;
+        this_mv.row += 4;
+        diag = svf(y - 1, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    case 3:
+        this_mv.col += 4;
+        this_mv.row += 4;
+        diag = svf(y, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+        break;
+    }
+
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+#else
+    this_mv.col = (this_mv.col - 8) | 4;
+    this_mv.row = (this_mv.row - 8) | 4;
+    diag = svf(y - 1 - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+    this_mv.col += 8;
+    diag = svf(y - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+    this_mv.col = (this_mv.col - 8) | 4;
+    this_mv.row = startmv.row + 4;
+    diag = svf(y - 1, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+    this_mv.col += 8;
+    diag = svf(y, d->pre_stride, 4, 4, z, b->src_stride, &sse);
+    diag += vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+
+    if (diag < bestmse)
+    {
+        *bestmv = this_mv;
+        bestmse = diag;
+    }
+
+#endif
+    return bestmse;
+}
+
+
+#define MVC(r,c) (((mvsadcost[0][((r)<<2)-rr] + mvsadcost[1][((c)<<2) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
+#define PRE(r,c) (*(d->base_pre) + d->pre + (r) * d->pre_stride + (c)) // pointer to predictor base of a motionvector
+#define DIST(r,c,v) sf( src,src_stride,PRE(r,c),d->pre_stride, v) // returns sad error score.
+#define ERR(r,c,v) (MVC(r,c)+DIST(r,c,v)) // returns distortion + motion vector cost
+#define CHECK_BETTER(v,r,c) if ((v = ERR(r,c,besterr)) < besterr) { besterr = v; br=r; bc=c; } // checks if (r,c) has better score than previous best
+
+int vp8_hex_search
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_t vf,
+    vp8_sad_fn_t      sf,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    MV hex[6] = { { -2, 0}, { -1, -2}, { -1, 2}, {2, 0}, {1, 2}, {1, -2} } ;
+    MV neighbors[8] = { { -1, -1}, { -1, 0}, { -1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} } ;
+    int i, j;
+    unsigned char *src = (*(b->base_src) + b->src);
+    int src_stride = b->src_stride;
+    int rr = ref_mv->row, rc = ref_mv->col, br = rr, bc = rc, tr, tc;
+    unsigned int besterr, thiserr = 0x7fffffff;
+
+    if (rc < x->mv_col_min) bc = x->mv_col_min;
+
+    if (rc > x->mv_col_max) bc = x->mv_col_max;
+
+    if (rr < x->mv_row_min) br = x->mv_row_min;
+
+    if (rr > x->mv_row_max) br = x->mv_row_max;
+
+    rr >>= 1;
+    rc >>= 1;
+    br >>= 3;
+    bc >>= 3;
+
+    besterr = ERR(br, bc, thiserr);
+
+    // hex search  jbb changed to 127 to avoid max 256 problem steping by 2.
+    for (j = 0; j < 127; j++)
+    {
+        tr = br;
+        tc = bc;
+
+        for (i = 0; i < 6; i++)
+        {
+            int nr = tr + hex[i].row, nc = tc + hex[i].col;
+
+            if (nc < x->mv_col_min) continue;
+
+            if (nc > x->mv_col_max) continue;
+
+            if (nr < x->mv_row_min) continue;
+
+            if (nr > x->mv_row_max) continue;
+
+            CHECK_BETTER(thiserr, nr, nc);
+        }
+
+        if (tr == br && tc == bc)
+            break;
+    }
+
+    // check 8 1 away neighbors
+    tr = br;
+    tc = bc;
+
+    for (i = 0; i < 8; i++)
+    {
+        int nr = tr + neighbors[i].row, nc = tc + neighbors[i].col;
+
+        if (nc < x->mv_col_min) continue;
+
+        if (nc > x->mv_col_max) continue;
+
+        if (nr < x->mv_row_min) continue;
+
+        if (nr > x->mv_row_max) continue;
+
+        CHECK_BETTER(thiserr, nr, nc);
+    }
+
+    best_mv->row = br;
+    best_mv->col = bc;
+
+    return vf(src, src_stride, PRE(br, bc), d->pre_stride, &thiserr) + MVC(br, bc) ;
+}
+#undef MVC
+#undef PRE
+#undef SP
+#undef DIST
+#undef ERR
+#undef CHECK_BETTER
+int vp8_diamond_search_sad
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_ptr_t *fn_ptr,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    int i, j, step;
+
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    unsigned char *best_address;
+
+    int tot_steps;
+    MV this_mv;
+
+    int bestsad = INT_MAX;
+    int best_site = 0;
+    int last_site = 0;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+    int this_row_offset;
+    int this_col_offset;
+    search_site *ss;
+
+    unsigned char *check_here;
+    int thissad;
+
+    // Work out the start point for the search
+    in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col);
+    best_address = in_what;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Check the starting position
+        bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // search_param determines the length of the initial step and hence the number of iterations
+    // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
+    ss = &x->ss[search_param * x->searches_per_step];
+    tot_steps = (x->ss_count / x->searches_per_step) - search_param;
+
+    i = 1;
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    *num00 = 0;
+
+    for (step = 0; step < tot_steps ; step++)
+    {
+        for (j = 0 ; j < x->searches_per_step ; j++)
+        {
+            // Trap illegal vectors
+            this_row_offset = best_mv->row + ss[i].mv.row;
+            this_col_offset = best_mv->col + ss[i].mv.col;
+
+            if ((this_col_offset > x->mv_col_min) && (this_col_offset < x->mv_col_max) &&
+            (this_row_offset > x->mv_row_min) && (this_row_offset < x->mv_row_max))
+
+            {
+                check_here = ss[i].offset + best_address;
+                thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+                if (thissad < bestsad)
+                {
+                    this_mv.row = this_row_offset << 3;
+                    this_mv.col = this_col_offset << 3;
+                    thissad += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                    if (thissad < bestsad)
+                    {
+                        bestsad = thissad;
+                        best_site = i;
+                    }
+                }
+            }
+
+            i++;
+        }
+
+        if (best_site != last_site)
+        {
+            best_mv->row += ss[best_site].mv.row;
+            best_mv->col += ss[best_site].mv.col;
+            best_address += ss[best_site].offset;
+            last_site = best_site;
+        }
+        else if (best_address == in_what)
+            (*num00)++;
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad == INT_MAX)
+        return INT_MAX;
+
+    return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+    + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+}
+
+int vp8_diamond_search_sadx4
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_ptr_t *fn_ptr,
+    int *mvsadcost[2],
+    int *mvcost[2]
+)
+{
+    int i, j, step;
+
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    unsigned char *best_address;
+
+    int tot_steps;
+    MV this_mv;
+
+    unsigned int bestsad = UINT_MAX;
+    int best_site = 0;
+    int last_site = 0;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+    int this_row_offset;
+    int this_col_offset;
+    search_site *ss;
+
+    unsigned char *check_here;
+    unsigned int thissad;
+
+    // Work out the start point for the search
+    in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col);
+    best_address = in_what;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Check the starting position
+        bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // search_param determines the length of the initial step and hence the number of iterations
+    // 0 = initial step (MAX_FIRST_STEP) pel : 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
+    ss = &x->ss[search_param * x->searches_per_step];
+    tot_steps = (x->ss_count / x->searches_per_step) - search_param;
+
+    i = 1;
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    *num00 = 0;
+
+    for (step = 0; step < tot_steps ; step++)
+    {
+        int check_row_min, check_col_min, check_row_max, check_col_max;
+
+        check_row_min = x->mv_row_min - best_mv->row;
+        check_row_max = x->mv_row_max - best_mv->row;
+        check_col_min = x->mv_col_min - best_mv->col;
+        check_col_max = x->mv_col_max - best_mv->col;
+
+        for (j = 0 ; j < x->searches_per_step ; j += 4)
+        {
+            unsigned char *block_offset[4];
+            unsigned int valid_block[4];
+            int all_in = 1, t;
+
+            for (t = 0; t < 4; t++)
+            {
+                valid_block [t]  = (ss[t+i].mv.col > check_col_min);
+                valid_block [t] &= (ss[t+i].mv.col < check_col_max);
+                valid_block [t] &= (ss[t+i].mv.row > check_row_min);
+                valid_block [t] &= (ss[t+i].mv.row < check_row_max);
+
+                all_in &= valid_block[t];
+                block_offset[t] = ss[i+t].offset + best_address;
+            }
+
+            if (all_in)
+            {
+                unsigned int sad_array[4];
+
+                fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, sad_array);
+
+                for (t = 0; t < 4; t++, i++)
+                {
+                    thissad = sad_array[t];
+
+                    if (thissad < bestsad)
+                    {
+                        this_mv.row = (best_mv->row + ss[i].mv.row) << 3;
+                        this_mv.col = (best_mv->col + ss[i].mv.col) << 3;
+                        thissad += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                        if (thissad < bestsad)
+                        {
+                            bestsad = thissad;
+                            best_site = i;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                int t;
+
+                for (t = 0; t < 4; i++, t++)
+                {
+                    // Trap illegal vectors
+                    if (valid_block[t])
+
+                    {
+                        check_here = block_offset[t];
+                        thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+                        if (thissad < bestsad)
+                        {
+                            this_row_offset = best_mv->row + ss[i].mv.row;
+                            this_col_offset = best_mv->col + ss[i].mv.col;
+
+                            this_mv.row = this_row_offset << 3;
+                            this_mv.col = this_col_offset << 3;
+                            thissad += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                            if (thissad < bestsad)
+                            {
+                                bestsad = thissad;
+                                best_site = i;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (best_site != last_site)
+        {
+            best_mv->row += ss[best_site].mv.row;
+            best_mv->col += ss[best_site].mv.col;
+            best_address += ss[best_site].offset;
+            last_site = best_site;
+        }
+        else if (best_address == in_what)
+            (*num00)++;
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad == INT_MAX)
+        return INT_MAX;
+
+    return fn_ptr->vf(what, what_stride, best_address, in_what_stride, (unsigned int *)(&thissad))
+    + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+}
+
+
+#if !(CONFIG_REALTIME_ONLY)
+int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int error_per_bit, int distance, vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], int *mvsadcost[2])
+{
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    int mv_stride = d->pre_stride;
+    unsigned char *bestaddress;
+    MV *best_mv = &d->bmi.mv.as_mv;
+    MV this_mv;
+    int bestsad = INT_MAX;
+    int r, c;
+
+    unsigned char *check_here;
+    int thissad;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
+
+    // Work out the mid point for the search
+    in_what = *(d->base_pre) + d->pre;
+    bestaddress = in_what + (ref_row * d->pre_stride) + ref_col;
+
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Baseline value at the centre
+
+        //bestsad = fn_ptr->sf( what,what_stride,bestaddress,in_what_stride) + (int)sqrt(vp8_mv_err_cost(ref_mv,ref_mv, mvcost,error_per_bit*14));
+        bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border
+    if (col_min < x->mv_col_min)
+        col_min = x->mv_col_min;
+
+    if (col_max > x->mv_col_max)
+        col_max = x->mv_col_max;
+
+    if (row_min < x->mv_row_min)
+        row_min = x->mv_row_min;
+
+    if (row_max > x->mv_row_max)
+        row_max = x->mv_row_max;
+
+    for (r = row_min; r < row_max ; r++)
+    {
+        this_mv.row = r << 3;
+        check_here = r * mv_stride + in_what + col_min;
+
+        for (c = col_min; c < col_max; c++)
+        {
+            thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+            this_mv.col = c << 3;
+            //thissad += (int)sqrt(vp8_mv_err_cost(&this_mv,ref_mv, mvcost,error_per_bit*14));
+            //thissad  += error_per_bit * mv_bits_sadcost[mv_bits(&this_mv, ref_mv, mvcost)];
+            thissad  += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit); //mv_bits(error_per_bit, &this_mv, ref_mv, mvsadcost);
+
+            if (thissad < bestsad)
+            {
+                bestsad = thissad;
+                best_mv->row = r;
+                best_mv->col = c;
+                bestaddress = check_here;
+            }
+
+            check_here++;
+        }
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad < INT_MAX)
+        return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+        + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    else
+        return INT_MAX;
+}
+
+int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int error_per_bit, int distance, vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2], int *mvsadcost[2])
+{
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what;
+    int in_what_stride = d->pre_stride;
+    int mv_stride = d->pre_stride;
+    unsigned char *bestaddress;
+    MV *best_mv = &d->bmi.mv.as_mv;
+    MV this_mv;
+    unsigned int bestsad = UINT_MAX;
+    int r, c;
+
+    unsigned char *check_here;
+    unsigned int thissad;
+
+    int ref_row = ref_mv->row >> 3;
+    int ref_col = ref_mv->col >> 3;
+
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
+
+    unsigned int sad_array[3];
+
+    // Work out the mid point for the search
+    in_what = *(d->base_pre) + d->pre;
+    bestaddress = in_what + (ref_row * d->pre_stride) + ref_col;
+
+    best_mv->row = ref_row;
+    best_mv->col = ref_col;
+
+    // We need to check that the starting point for the search (as indicated by ref_mv) is within the buffer limits
+    if ((ref_col > x->mv_col_min) && (ref_col < x->mv_col_max) &&
+    (ref_row > x->mv_row_min) && (ref_row < x->mv_row_max))
+    {
+        // Baseline value at the centre
+        bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride, 0x7fffffff) + vp8_mv_err_cost(ref_mv, ref_mv, mvsadcost, error_per_bit);
+    }
+
+    // Apply further limits to prevent us looking using vectors that stretch beyiond the UMV border
+    if (col_min < x->mv_col_min)
+        col_min = x->mv_col_min;
+
+    if (col_max > x->mv_col_max)
+        col_max = x->mv_col_max;
+
+    if (row_min < x->mv_row_min)
+        row_min = x->mv_row_min;
+
+    if (row_max > x->mv_row_max)
+        row_max = x->mv_row_max;
+
+    for (r = row_min; r < row_max ; r++)
+    {
+        this_mv.row = r << 3;
+        check_here = r * mv_stride + in_what + col_min;
+        c = col_min;
+
+        while ((c + 3) < col_max)
+        {
+            int i;
+
+            fn_ptr->sdx3f(what, what_stride, check_here , in_what_stride, sad_array);
+
+            for (i = 0; i < 3; i++)
+            {
+                thissad = sad_array[i];
+
+                if (thissad < bestsad)
+                {
+                    this_mv.col = c << 3;
+                    thissad  += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                    if (thissad < bestsad)
+                    {
+                        bestsad = thissad;
+                        best_mv->row = r;
+                        best_mv->col = c;
+                        bestaddress = check_here;
+                    }
+                }
+
+                check_here++;
+                c++;
+            }
+        }
+
+        while (c < col_max)
+        {
+            thissad = fn_ptr->sdf(what, what_stride, check_here , in_what_stride, bestsad);
+
+            if (thissad < bestsad)
+            {
+                this_mv.col = c << 3;
+                thissad  += vp8_mv_err_cost(&this_mv, ref_mv, mvsadcost, error_per_bit);
+
+                if (thissad < bestsad)
+                {
+                    bestsad = thissad;
+                    best_mv->row = r;
+                    best_mv->col = c;
+                    bestaddress = check_here;
+                }
+            }
+
+            check_here ++;
+            c ++;
+        }
+
+    }
+
+    this_mv.row = best_mv->row << 3;
+    this_mv.col = best_mv->col << 3;
+
+    if (bestsad < INT_MAX)
+        return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, (unsigned int *)(&thissad))
+        + vp8_mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
+    else
+        return INT_MAX;
+}
+#endif
+
+#ifdef ENTROPY_STATS
+void print_mode_context(void)
+{
+    FILE *f = fopen("modecont.c", "w");
+    int i, j;
+
+    fprintf(f, "#include \"entropy.h\"\n");
+    fprintf(f, "const int vp8_mode_contexts[6][4] =\n");
+    fprintf(f, "{\n");
+
+    for (j = 0; j < 6; j++)
+    {
+        fprintf(f, "  { // %d \n", j);
+        fprintf(f, "    ");
+
+        for (i = 0; i < 4; i++)
+        {
+            int overal_prob;
+            int this_prob;
+            int count; // = mv_ref_ct[j][i][0]+mv_ref_ct[j][i][1];
+
+            // Overall probs
+            count = mv_mode_cts[i][0] + mv_mode_cts[i][1];
+
+            if (count)
+                overal_prob = 256 * mv_mode_cts[i][0] / count;
+            else
+                overal_prob = 128;
+
+            if (overal_prob == 0)
+                overal_prob = 1;
+
+            // context probs
+            count = mv_ref_ct[j][i][0] + mv_ref_ct[j][i][1];
+
+            if (count)
+                this_prob = 256 * mv_ref_ct[j][i][0] / count;
+            else
+                this_prob = 128;
+
+            if (this_prob == 0)
+                this_prob = 1;
+
+            fprintf(f, "%5d, ", this_prob);
+            //fprintf(f,"%5d, %5d, %8d,", this_prob, overal_prob, (this_prob << 10)/overal_prob);
+            //fprintf(f,"%8d, ", (this_prob << 10)/overal_prob);
+        }
+
+        fprintf(f, "  },\n");
+    }
+
+    fprintf(f, "};\n");
+    fclose(f);
+}
+
+/* MV ref count ENTROPY_STATS stats code */
+#ifdef ENTROPY_STATS
+void init_mv_ref_counts()
+{
+    vpx_memset(mv_ref_ct, 0, sizeof(mv_ref_ct));
+    vpx_memset(mv_mode_cts, 0, sizeof(mv_mode_cts));
+}
+
+void accum_mv_refs(MB_PREDICTION_MODE m, const int ct[4])
+{
+    if (m == ZEROMV)
+    {
+        ++mv_ref_ct [ct[0]] [0] [0];
+        ++mv_mode_cts[0][0];
+    }
+    else
+    {
+        ++mv_ref_ct [ct[0]] [0] [1];
+        ++mv_mode_cts[0][1];
+
+        if (m == NEARESTMV)
+        {
+            ++mv_ref_ct [ct[1]] [1] [0];
+            ++mv_mode_cts[1][0];
+        }
+        else
+        {
+            ++mv_ref_ct [ct[1]] [1] [1];
+            ++mv_mode_cts[1][1];
+
+            if (m == NEARMV)
+            {
+                ++mv_ref_ct [ct[2]] [2] [0];
+                ++mv_mode_cts[2][0];
+            }
+            else
+            {
+                ++mv_ref_ct [ct[2]] [2] [1];
+                ++mv_mode_cts[2][1];
+
+                if (m == NEWMV)
+                {
+                    ++mv_ref_ct [ct[3]] [3] [0];
+                    ++mv_mode_cts[3][0];
+                }
+                else
+                {
+                    ++mv_ref_ct [ct[3]] [3] [1];
+                    ++mv_mode_cts[3][1];
+                }
+            }
+        }
+    }
+}
+
+#endif/* END MV ref count ENTROPY_STATS stats code */
+
+#endif
diff --git a/vp8/encoder/mcomp.h b/vp8/encoder/mcomp.h
new file mode 100644 (file)
index 0000000..921206f
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_MCOMP_H
+#define __INC_MCOMP_H
+
+#include "block.h"
+#include "variance.h"
+
+#ifdef ENTROPY_STATS
+extern void init_mv_ref_counts();
+extern void accum_mv_refs(MB_PREDICTION_MODE, const int near_mv_ref_cts[4]);
+#endif
+
+
+#define MAX_MVSEARCH_STEPS 8                                    // The maximum number of steps in a step search given the largest allowed initial step
+#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS+3)) - 8)    // Max full pel mv specified in 1/8 pel units
+#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1))            // Maximum size of the first step in full pel units
+
+
+extern void print_mode_context(void);
+extern int vp8_mv_bit_cost(MV *mv, MV *ref, int *mvcost[2], int Weight);
+extern void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride);
+extern void vp8_init3smotion_compensation(MACROBLOCK *x,  int stride);
+
+
+extern int vp8_hex_search
+(
+    MACROBLOCK *x,
+    BLOCK *b,
+    BLOCKD *d,
+    MV *ref_mv,
+    MV *best_mv,
+    int search_param,
+    int error_per_bit,
+    int *num00,
+    vp8_variance_fn_t vf,
+    vp8_sad_fn_t sf,
+    int *mvsadcost[2],
+    int *mvcost[2]
+
+);
+
+typedef int (fractional_mv_step_fp)(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2]);
+extern fractional_mv_step_fp vp8_find_best_sub_pixel_step_iteratively;
+extern fractional_mv_step_fp vp8_find_best_sub_pixel_step;
+extern fractional_mv_step_fp vp8_find_best_half_pixel_step;
+extern fractional_mv_step_fp vp8_skip_fractional_mv_step;
+
+#define prototype_full_search_sad(sym)\
+    int (sym)\
+    (\
+     MACROBLOCK *x, \
+     BLOCK *b, \
+     BLOCKD *d, \
+     MV *ref_mv, \
+     int error_per_bit, \
+     int distance, \
+     vp8_variance_fn_ptr_t *fn_ptr, \
+     int *mvcost[2], \
+     int *mvsadcost[2] \
+    )
+
+#define prototype_diamond_search_sad(sym)\
+    int (sym)\
+    (\
+     MACROBLOCK *x, \
+     BLOCK *b, \
+     BLOCKD *d, \
+     MV *ref_mv, \
+     MV *best_mv, \
+     int search_param, \
+     int error_per_bit, \
+     int *num00, \
+     vp8_variance_fn_ptr_t *fn_ptr, \
+     int *mvsadcost[2], \
+     int *mvcost[2] \
+    )
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/mcomp_x86.h"
+#endif
+
+typedef prototype_full_search_sad(*vp8_full_search_fn_t);
+extern prototype_full_search_sad(vp8_full_search_sad);
+extern prototype_full_search_sad(vp8_full_search_sadx3);
+
+typedef prototype_diamond_search_sad(*vp8_diamond_search_fn_t);
+extern prototype_diamond_search_sad(vp8_diamond_search_sad);
+extern prototype_diamond_search_sad(vp8_diamond_search_sadx4);
+
+#ifndef vp8_search_full_search
+#define vp8_search_full_search vp8_full_search_sad
+#endif
+extern prototype_full_search_sad(vp8_search_full_search);
+
+#ifndef vp8_search_diamond_search
+#define vp8_search_diamond_search vp8_diamond_search_sad
+#endif
+extern prototype_diamond_search_sad(vp8_search_diamond_search);
+
+typedef struct
+{
+    prototype_full_search_sad(*full_search);
+    prototype_diamond_search_sad(*diamond_search);
+} vp8_search_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define SEARCH_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define SEARCH_INVOKE(ctx,fn) vp8_search_##fn
+#endif
+
+#endif
diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c
new file mode 100644 (file)
index 0000000..73170cf
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "blockd.h"
+#include "onyx_int.h"
+#include "treewriter.h"
+#include "entropymode.h"
+
+
+void vp8_init_mode_costs(VP8_COMP *c)
+{
+    VP8_COMMON *x = &c->common;
+    {
+        const vp8_tree_p T = vp8_bmode_tree;
+
+        int i = 0;
+
+        do
+        {
+            int j = 0;
+
+            do
+            {
+                vp8_cost_tokens((int *)c->mb.bmode_costs[i][j], x->kf_bmode_prob[i][j], T);
+            }
+            while (++j < VP8_BINTRAMODES);
+        }
+        while (++i < VP8_BINTRAMODES);
+
+        vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.bmode_prob, T);
+    }
+    vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_tree);
+
+    vp8_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree);
+    vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree);
+
+    vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], x->fc.uv_mode_prob, vp8_uv_mode_tree);
+    vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob, vp8_uv_mode_tree);
+}
diff --git a/vp8/encoder/modecosts.h b/vp8/encoder/modecosts.h
new file mode 100644 (file)
index 0000000..5ade265
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_MODECOSTS_H
+#define __INC_MODECOSTS_H
+
+void vp8_init_mode_costs(VP8_COMP *x);
+
+#endif
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
new file mode 100644 (file)
index 0000000..7662720
--- /dev/null
@@ -0,0 +1,5428 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxc_int.h"
+#include "onyx_int.h"
+#include "systemdependent.h"
+#include "quantize.h"
+#include "alloccommon.h"
+#include "mcomp.h"
+#include "firstpass.h"
+#include "psnr.h"
+#include "vpx_scale/vpxscale.h"
+#include "extend.h"
+#include "ratectrl.h"
+#include "quant_common.h"
+#include "segmentation_common.h"
+#include "g_common.h"
+#include "vpx_scale/yv12extend.h"
+#include "postproc.h"
+#include "vpx_mem/vpx_mem.h"
+#include "swapyv12buffer.h"
+#include "threading.h"
+#include "vpx_ports/vpx_timer.h"
+#include <math.h>
+#include <stdio.h>
+#include <limits.h>
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x) (x)
+#define RTCD(x) &cpi->common.rtcd.x
+#else
+#define IF_RTCD(x) NULL
+#define RTCD(x) NULL
+#endif
+
+extern void vp8cx_init_mv_bits_sadcost();
+extern void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi);
+extern void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val);
+extern void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi);
+
+extern void vp8_init_loop_filter(VP8_COMMON *cm);
+extern void vp8_loop_filter_frame(VP8_COMMON *cm,    MACROBLOCKD *mbd,  int filt_val);
+extern void vp8_loop_filter_frame_yonly(VP8_COMMON *cm,    MACROBLOCKD *mbd,  int filt_val, int sharpness_lvl);
+extern void vp8_dmachine_specific_config(VP8_COMP *cpi);
+extern void vp8_cmachine_specific_config(VP8_COMP *cpi);
+extern void vp8_calc_auto_iframe_target_size(VP8_COMP *cpi);
+extern void vp8_deblock_frame(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *post, int filt_lvl, int low_var_thresh, int flag);
+extern void print_parms(VP8_CONFIG *ocf, char *filenam);
+extern unsigned int vp8_get_processor_freq();
+extern void print_tree_update_probs();
+extern void vp8cx_create_encoder_threads(VP8_COMP *cpi);
+extern void vp8cx_remove_encoder_threads(VP8_COMP *cpi);
+#if HAVE_ARMV7
+extern void vp8_yv12_copy_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_src_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+#endif
+
+int vp8_estimate_entropy_savings(VP8_COMP *cpi);
+int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd);
+int vp8_calc_low_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd);
+
+
+static void mode_ref_lf_test_function(VP8_COMP *cpi);
+
+extern const int vp8_gf_interval_table[101];
+
+#if CONFIG_PSNR
+#include "math.h"
+
+extern double vp8_calc_ssim
+(
+    YV12_BUFFER_CONFIG *source,
+    YV12_BUFFER_CONFIG *dest,
+    int lumamask,
+    double *weight
+);
+
+extern double vp8_calc_ssimg
+(
+    YV12_BUFFER_CONFIG *source,
+    YV12_BUFFER_CONFIG *dest,
+    double *ssim_y,
+    double *ssim_u,
+    double *ssim_v
+);
+
+
+#endif
+
+
+#ifdef OUTPUT_YUV_SRC
+FILE *yuv_file;
+#endif
+
+#if 0
+FILE *framepsnr;
+FILE *kf_list;
+FILE *keyfile;
+#endif
+
+#if 0
+extern int skip_true_count;
+extern int skip_false_count;
+#endif
+
+
+#ifdef ENTROPY_STATS
+extern int intra_mode_stats[10][10][10];
+#endif
+
+#ifdef SPEEDSTATS
+unsigned int frames_at_speed[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned int tot_pm = 0;
+unsigned int cnt_pm = 0;
+unsigned int tot_ef = 0;
+unsigned int cnt_ef = 0;
+#endif
+
+#ifdef MODE_STATS
+extern unsigned __int64 Sectionbits[50];
+extern int y_modes[5]  ;
+extern int uv_modes[4] ;
+extern int b_modes[10]  ;
+
+extern int inter_y_modes[10] ;
+extern int inter_uv_modes[4] ;
+extern unsigned int inter_b_modes[15];
+#endif
+
+extern void (*vp8_short_fdct4x4)(short *input, short *output, int pitch);
+extern void (*vp8_short_fdct8x4)(short *input, short *output, int pitch);
+extern void (*vp8_fast_fdct4x4)(short *input, short *output, int pitch);
+extern void (*vp8_fast_fdct8x4)(short *input, short *output, int pitch);
+
+extern const int vp8_bits_per_mb[2][QINDEX_RANGE];
+
+extern const int qrounding_factors[129];
+extern const int qzbin_factors[129];
+extern void vp8cx_init_quantizer(VP8_COMP *cpi);
+extern const int vp8cx_base_skip_false_prob[128];
+
+
+void vp8_initialize()
+{
+    static int init_done = 0;
+
+    if (!init_done)
+    {
+        vp8_scale_machine_specific_config();
+        vp8_initialize_common();
+        //vp8_dmachine_specific_config();
+        vp8_tokenize_initialize();
+
+        vp8cx_init_mv_bits_sadcost();
+        init_done = 1;
+    }
+}
+#ifdef PACKET_TESTING
+extern FILE *vpxlogc;
+#endif
+
+static void setup_features(VP8_COMP *cpi)
+{
+    // Set up default state for MB feature flags
+    cpi->mb.e_mbd.segmentation_enabled = 0;
+    cpi->mb.e_mbd.update_mb_segmentation_map = 0;
+    cpi->mb.e_mbd.update_mb_segmentation_data = 0;
+    vpx_memset(cpi->mb.e_mbd.mb_segment_tree_probs, 255, sizeof(cpi->mb.e_mbd.mb_segment_tree_probs));
+    vpx_memset(cpi->mb.e_mbd.segment_feature_data, 0, sizeof(cpi->mb.e_mbd.segment_feature_data));
+
+    cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 0;
+    cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
+    vpx_memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas));
+    vpx_memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas));
+
+    // jbb trial !
+    mode_ref_lf_test_function(cpi);
+
+}
+
+
+void vp8_dealloc_compressor_data(VP8_COMP *cpi)
+{
+
+    // Delete sementation map
+    if (cpi->segmentation_map != 0)
+        vpx_free(cpi->segmentation_map);
+
+    cpi->segmentation_map = 0;
+
+    if (cpi->active_map != 0)
+        vpx_free(cpi->active_map);
+
+    cpi->active_map = 0;
+
+    // Delete first pass motion map
+    if (cpi->fp_motion_map != 0)
+        vpx_free(cpi->fp_motion_map);
+
+    cpi->fp_motion_map = 0;
+
+    vp8_de_alloc_frame_buffers(&cpi->common);
+
+    vp8_yv12_de_alloc_frame_buffer(&cpi->last_frame_uf);
+    vp8_yv12_de_alloc_frame_buffer(&cpi->scaled_source);
+#if VP8_TEMPORAL_ALT_REF
+    vp8_yv12_de_alloc_frame_buffer(&cpi->alt_ref_buffer.source_buffer);
+#endif
+    {
+        int i;
+
+        for (i = 0; i < MAX_LAG_BUFFERS; i++)
+            vp8_yv12_de_alloc_frame_buffer(&cpi->src_buffer[i].source_buffer);
+
+        cpi->source_buffer_count = 0;
+    }
+
+    vpx_free(cpi->tok);
+    cpi->tok = 0;
+
+}
+
+static void enable_segmentation(VP8_PTR ptr)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    // Set the appropriate feature bit
+    cpi->mb.e_mbd.segmentation_enabled = 1;
+    cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+    cpi->mb.e_mbd.update_mb_segmentation_data = 1;
+}
+static void disable_segmentation(VP8_PTR ptr)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    // Clear the appropriate feature bit
+    cpi->mb.e_mbd.segmentation_enabled = 0;
+}
+
+// Valid values for a segment are 0 to 3
+// Segmentation map is arrange as [Rows][Columns]
+static void set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_map)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    // Copy in the new segmentation map
+    vpx_memcpy(cpi->segmentation_map, segmentation_map, (cpi->common.mb_rows * cpi->common.mb_cols));
+
+    // Signal that the map should be updated.
+    cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+    cpi->mb.e_mbd.update_mb_segmentation_data = 1;
+}
+
+// The values given for each segment can be either deltas (from the default value chosen for the frame) or absolute values.
+//
+// Valid range for abs values is (0-127 for MB_LVL_ALT_Q) , (0-63 for SEGMENT_ALT_LF)
+// Valid range for delta values are (+/-127 for MB_LVL_ALT_Q) , (+/-63 for SEGMENT_ALT_LF)
+//
+// abs_delta = SEGMENT_DELTADATA (deltas) abs_delta = SEGMENT_ABSDATA (use the absolute values given).
+//
+//
+static void set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned char abs_delta)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    cpi->mb.e_mbd.mb_segement_abs_delta = abs_delta;
+    vpx_memcpy(cpi->segment_feature_data, feature_data, sizeof(cpi->segment_feature_data));
+}
+
+
+static void segmentation_test_function(VP8_PTR ptr)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    unsigned char *seg_map;
+    signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
+    int i, j;
+
+    // Create a temporary map for segmentation data.
+    CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+
+    // MB loop to set local segmentation map
+    /*for ( i = 0; i < cpi->common.mb_rows; i++ )
+    {
+        for ( j = 0; j < cpi->common.mb_cols; j++ )
+        {
+            //seg_map[(i*cpi->common.mb_cols) + j] = (j % 2) + ((i%2)* 2);
+            //if ( j < cpi->common.mb_cols/2 )
+
+            // Segment 1 around the edge else 0
+            if ( (i == 0) || (j == 0) || (i == (cpi->common.mb_rows-1)) || (j == (cpi->common.mb_cols-1)) )
+                seg_map[(i*cpi->common.mb_cols) + j] = 1;
+            //else if ( (i < 2) || (j < 2) || (i > (cpi->common.mb_rows-3)) || (j > (cpi->common.mb_cols-3)) )
+            //  seg_map[(i*cpi->common.mb_cols) + j] = 2;
+            //else if ( (i < 5) || (j < 5) || (i > (cpi->common.mb_rows-6)) || (j > (cpi->common.mb_cols-6)) )
+            //  seg_map[(i*cpi->common.mb_cols) + j] = 3;
+            else
+                seg_map[(i*cpi->common.mb_cols) + j] = 0;
+        }
+    }*/
+
+    // Set the segmentation Map
+    set_segmentation_map(ptr, seg_map);
+
+    // Activate segmentation.
+    enable_segmentation(ptr);
+
+    // Set up the quant segment data
+    feature_data[MB_LVL_ALT_Q][0] = 0;
+    feature_data[MB_LVL_ALT_Q][1] = 4;
+    feature_data[MB_LVL_ALT_Q][2] = 0;
+    feature_data[MB_LVL_ALT_Q][3] = 0;
+    // Set up the loop segment data
+    feature_data[MB_LVL_ALT_LF][0] = 0;
+    feature_data[MB_LVL_ALT_LF][1] = 0;
+    feature_data[MB_LVL_ALT_LF][2] = 0;
+    feature_data[MB_LVL_ALT_LF][3] = 0;
+
+    // Initialise the feature data structure
+    // SEGMENT_DELTADATA    0, SEGMENT_ABSDATA      1
+    set_segment_data(ptr, &feature_data[0][0], SEGMENT_DELTADATA);
+
+    // Delete sementation map
+    if (seg_map != 0)
+        vpx_free(seg_map);
+
+    seg_map = 0;
+
+}
+
+// A simple function to cyclically refresh the background at a lower Q
+static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment)
+{
+    unsigned char *seg_map;
+    signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
+    int i;
+    int block_count = cpi->cyclic_refresh_mode_max_mbs_perframe;
+    int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols;
+
+    // Create a temporary map for segmentation data.
+    CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+
+    cpi->cyclic_refresh_q = Q;
+
+    for (i = Q; i > 0; i--)
+    {
+        if (vp8_bits_per_mb[cpi->common.frame_type][i] >= ((vp8_bits_per_mb[cpi->common.frame_type][Q]*(Q + 128)) / 64))
+            //if ( vp8_bits_per_mb[cpi->common.frame_type][i] >= ((vp8_bits_per_mb[cpi->common.frame_type][Q]*((2*Q)+96))/64) )
+        {
+            break;
+        }
+    }
+
+    cpi->cyclic_refresh_q = i;
+
+    // Only update for inter frames
+    if (cpi->common.frame_type != KEY_FRAME)
+    {
+        // Cycle through the macro_block rows
+        // MB loop to set local segmentation map
+        for (i = cpi->cyclic_refresh_mode_index; i < mbs_in_frame; i++)
+        {
+            // If the MB is as a candidate for clean up then mark it for possible boost/refresh (segment 1)
+            // The segment id may get reset to 0 later if the MB gets coded anything other than last frame 0,0
+            // as only (last frame 0,0) MBs are eligable for refresh : that is to say Mbs likely to be background blocks.
+            if (cpi->cyclic_refresh_map[i] == 0)
+            {
+                seg_map[i] = 1;
+            }
+            else
+            {
+                seg_map[i] = 0;
+
+                // Skip blocks that have been refreshed recently anyway.
+                if (cpi->cyclic_refresh_map[i] < 0)
+                    //cpi->cyclic_refresh_map[i] = cpi->cyclic_refresh_map[i] / 16;
+                    cpi->cyclic_refresh_map[i]++;
+            }
+
+
+            if (block_count > 0)
+                block_count--;
+            else
+                break;
+
+        }
+
+        // If we have gone through the frame reset to the start
+        cpi->cyclic_refresh_mode_index = i;
+
+        if (cpi->cyclic_refresh_mode_index >= mbs_in_frame)
+            cpi->cyclic_refresh_mode_index = 0;
+    }
+
+    // Set the segmentation Map
+    set_segmentation_map((VP8_PTR)cpi, seg_map);
+
+    // Activate segmentation.
+    enable_segmentation((VP8_PTR)cpi);
+
+    // Set up the quant segment data
+    feature_data[MB_LVL_ALT_Q][0] = 0;
+    feature_data[MB_LVL_ALT_Q][1] = (cpi->cyclic_refresh_q - Q);
+    feature_data[MB_LVL_ALT_Q][2] = 0;
+    feature_data[MB_LVL_ALT_Q][3] = 0;
+
+    // Set up the loop segment data
+    feature_data[MB_LVL_ALT_LF][0] = 0;
+    feature_data[MB_LVL_ALT_LF][1] = lf_adjustment;
+    feature_data[MB_LVL_ALT_LF][2] = 0;
+    feature_data[MB_LVL_ALT_LF][3] = 0;
+
+    // Initialise the feature data structure
+    // SEGMENT_DELTADATA    0, SEGMENT_ABSDATA      1
+    set_segment_data((VP8_PTR)cpi, &feature_data[0][0], SEGMENT_DELTADATA);
+
+    // Delete sementation map
+    if (seg_map != 0)
+        vpx_free(seg_map);
+
+    seg_map = 0;
+
+}
+
+static void mode_ref_lf_test_function(VP8_COMP *cpi)
+{
+    cpi->mb.e_mbd.mode_ref_lf_delta_enabled = 1;
+    cpi->mb.e_mbd.mode_ref_lf_delta_update = 1;
+
+    vpx_memset(cpi->mb.e_mbd.ref_lf_deltas, 0, sizeof(cpi->mb.e_mbd.ref_lf_deltas));
+    vpx_memset(cpi->mb.e_mbd.mode_lf_deltas, 0, sizeof(cpi->mb.e_mbd.mode_lf_deltas));
+
+    // Test of ref frame deltas
+    cpi->mb.e_mbd.ref_lf_deltas[INTRA_FRAME] = 2;
+    cpi->mb.e_mbd.ref_lf_deltas[LAST_FRAME] = 0;
+    cpi->mb.e_mbd.ref_lf_deltas[GOLDEN_FRAME] = -2;
+    cpi->mb.e_mbd.ref_lf_deltas[ALTREF_FRAME] = -2;
+
+    cpi->mb.e_mbd.mode_lf_deltas[0] = 4;               // BPRED
+    cpi->mb.e_mbd.mode_lf_deltas[1] = -2;              // Zero
+    cpi->mb.e_mbd.mode_lf_deltas[2] = 2;               // New mv
+    cpi->mb.e_mbd.mode_lf_deltas[3] = 4;               // Split mv
+}
+
+void vp8_set_speed_features(VP8_COMP *cpi)
+{
+    SPEED_FEATURES *sf = &cpi->sf;
+    int Mode = cpi->compressor_speed;
+    int Speed = cpi->Speed;
+    int i;
+    VP8_COMMON *cm = &cpi->common;
+
+    // Initialise default mode frequency sampling variables
+    for (i = 0; i < MAX_MODES; i ++)
+    {
+        cpi->mode_check_freq[i] = 0;
+        cpi->mode_test_hit_counts[i] = 0;
+        cpi->mode_chosen_counts[i] = 0;
+    }
+
+    cpi->mbs_tested_so_far = 0;
+
+    // best quality
+    sf->RD = 1;
+    sf->search_method = NSTEP;
+    sf->improved_quant = 1;
+    sf->improved_dct = 1;
+    sf->auto_filter = 1;
+    sf->recode_loop = 1;
+    sf->quarter_pixel_search = 1;
+    sf->half_pixel_search = 1;
+    sf->full_freq[0] = 7;
+    sf->full_freq[1] = 7;
+    sf->min_fs_radius = 8;
+    sf->max_fs_radius = 32;
+    sf->iterative_sub_pixel = 1;
+    sf->optimize_coefficients = 1;
+
+    sf->first_step = 0;
+    sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
+
+    cpi->do_full[0] = 0;
+    cpi->do_full[1] = 0;
+
+    // default thresholds to 0
+    for (i = 0; i < MAX_MODES; i++)
+        sf->thresh_mult[i] = 0;
+
+    switch (Mode)
+    {
+#if !(CONFIG_REALTIME_ONLY)
+    case 0: // best quality mode
+        sf->thresh_mult[THR_ZEROMV   ] = 0;
+        sf->thresh_mult[THR_ZEROG    ] = 0;
+        sf->thresh_mult[THR_ZEROA    ] = 0;
+        sf->thresh_mult[THR_NEARESTMV] = 0;
+        sf->thresh_mult[THR_NEARESTG ] = 0;
+        sf->thresh_mult[THR_NEARESTA ] = 0;
+        sf->thresh_mult[THR_NEARMV   ] = 0;
+        sf->thresh_mult[THR_NEARG    ] = 0;
+        sf->thresh_mult[THR_NEARA    ] = 0;
+
+        sf->thresh_mult[THR_DC       ] = 0;
+
+        sf->thresh_mult[THR_V_PRED   ] = 1000;
+        sf->thresh_mult[THR_H_PRED   ] = 1000;
+        sf->thresh_mult[THR_B_PRED   ] = 2000;
+        sf->thresh_mult[THR_TM       ] = 1000;
+
+        sf->thresh_mult[THR_NEWMV    ] = 1000;
+        sf->thresh_mult[THR_NEWG     ] = 1000;
+        sf->thresh_mult[THR_NEWA     ] = 1000;
+
+        sf->thresh_mult[THR_SPLITMV  ] = 2500;
+        sf->thresh_mult[THR_SPLITG   ] = 5000;
+        sf->thresh_mult[THR_SPLITA   ] = 5000;
+
+        sf->full_freq[0] = 7;
+        sf->full_freq[1] = 15;
+
+        sf->first_step = 0;
+        sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
+
+        if (!(cpi->ref_frame_flags & VP8_LAST_FLAG))
+        {
+            sf->thresh_mult[THR_NEWMV    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARESTMV] = INT_MAX;
+            sf->thresh_mult[THR_ZEROMV   ] = INT_MAX;
+            sf->thresh_mult[THR_NEARMV   ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
+        }
+
+        if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG))
+        {
+            sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
+            sf->thresh_mult[THR_ZEROG    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARG    ] = INT_MAX;
+            sf->thresh_mult[THR_NEWG     ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITG   ] = INT_MAX;
+        }
+        else if (!(cpi->ref_frame_flags & VP8_ALT_FLAG))
+        {
+            sf->thresh_mult[THR_NEARESTA ] = INT_MAX;
+            sf->thresh_mult[THR_ZEROA    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARA    ] = INT_MAX;
+            sf->thresh_mult[THR_NEWA     ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITA   ] = INT_MAX;
+        }
+
+        break;
+    case 1:
+    case 3:
+        sf->optimize_coefficients = 0;
+        sf->thresh_mult[THR_NEARESTMV] = 0;
+        sf->thresh_mult[THR_ZEROMV   ] = 0;
+        sf->thresh_mult[THR_DC       ] = 0;
+        sf->thresh_mult[THR_NEARMV   ] = 0;
+        sf->thresh_mult[THR_V_PRED   ] = 1000;
+        sf->thresh_mult[THR_H_PRED   ] = 1000;
+        sf->thresh_mult[THR_B_PRED   ] = 2500;
+        sf->thresh_mult[THR_TM       ] = 1000;
+
+        sf->thresh_mult[THR_NEARESTG ] = 1000;
+        sf->thresh_mult[THR_NEARESTA ] = 1000;
+
+        sf->thresh_mult[THR_ZEROG    ] = 1000;
+        sf->thresh_mult[THR_ZEROA    ] = 1000;
+        sf->thresh_mult[THR_NEARG    ] = 1000;
+        sf->thresh_mult[THR_NEARA    ] = 1000;
+
+        sf->thresh_mult[THR_NEWMV    ] = 1500;
+        sf->thresh_mult[THR_NEWG     ] = 1500;
+        sf->thresh_mult[THR_NEWA     ] = 1500;
+
+        sf->thresh_mult[THR_SPLITMV  ] = 5000;
+        sf->thresh_mult[THR_SPLITG   ] = 10000;
+        sf->thresh_mult[THR_SPLITA   ] = 10000;
+
+        sf->full_freq[0] = 15;
+        sf->full_freq[1] = 31;
+
+        sf->first_step = 0;
+        sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
+
+        if (!(cpi->ref_frame_flags & VP8_LAST_FLAG))
+        {
+            sf->thresh_mult[THR_NEWMV    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARESTMV] = INT_MAX;
+            sf->thresh_mult[THR_ZEROMV   ] = INT_MAX;
+            sf->thresh_mult[THR_NEARMV   ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
+        }
+        else if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG))
+        {
+            sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
+            sf->thresh_mult[THR_ZEROG    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARG    ] = INT_MAX;
+            sf->thresh_mult[THR_NEWG     ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITG   ] = INT_MAX;
+        }
+        else if (!(cpi->ref_frame_flags & VP8_ALT_FLAG))
+        {
+            sf->thresh_mult[THR_NEARESTA ] = INT_MAX;
+            sf->thresh_mult[THR_ZEROA    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARA    ] = INT_MAX;
+            sf->thresh_mult[THR_NEWA     ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITA   ] = INT_MAX;
+        }
+
+        if (Speed > 0)
+        {
+            cpi->mode_check_freq[THR_SPLITG] = 4;
+            cpi->mode_check_freq[THR_SPLITA] = 4;
+            cpi->mode_check_freq[THR_SPLITMV] = 2;
+
+            sf->thresh_mult[THR_TM       ] = 1500;
+            sf->thresh_mult[THR_V_PRED   ] = 1500;
+            sf->thresh_mult[THR_H_PRED   ] = 1500;
+            sf->thresh_mult[THR_B_PRED   ] = 5000;
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            {
+                sf->thresh_mult[THR_NEWMV    ] = 2000;
+                sf->thresh_mult[THR_SPLITMV  ] = 10000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTG ] = 1500;
+                sf->thresh_mult[THR_ZEROG    ] = 1500;
+                sf->thresh_mult[THR_NEARG    ] = 1500;
+                sf->thresh_mult[THR_NEWG     ] = 2000;
+                sf->thresh_mult[THR_SPLITG   ] = 20000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTA ] = 1500;
+                sf->thresh_mult[THR_ZEROA    ] = 1500;
+                sf->thresh_mult[THR_NEARA    ] = 1500;
+                sf->thresh_mult[THR_NEWA     ] = 2000;
+                sf->thresh_mult[THR_SPLITA   ] = 20000;
+            }
+
+            sf->improved_quant = 0;
+            sf->improved_dct = 0;
+
+            sf->first_step = 1;
+            sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
+        }
+
+        if (Speed > 1)
+        {
+            cpi->mode_check_freq[THR_SPLITG] = 15;
+            cpi->mode_check_freq[THR_SPLITA] = 15;
+            cpi->mode_check_freq[THR_SPLITMV] = 7;
+
+            sf->thresh_mult[THR_TM       ] = 2000;
+            sf->thresh_mult[THR_V_PRED   ] = 2000;
+            sf->thresh_mult[THR_H_PRED   ] = 2000;
+            sf->thresh_mult[THR_B_PRED   ] = 7500;
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            {
+                sf->thresh_mult[THR_NEWMV    ] = 2000;
+                sf->thresh_mult[THR_SPLITMV  ] = 25000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTG ] = 2000;
+                sf->thresh_mult[THR_ZEROG    ] = 2000;
+                sf->thresh_mult[THR_NEARG    ] = 2000;
+                sf->thresh_mult[THR_NEWG     ] = 2500;
+                sf->thresh_mult[THR_SPLITG   ] = 50000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTA ] = 2000;
+                sf->thresh_mult[THR_ZEROA    ] = 2000;
+                sf->thresh_mult[THR_NEARA    ] = 2000;
+                sf->thresh_mult[THR_NEWA     ] = 2500;
+                sf->thresh_mult[THR_SPLITA   ] = 50000;
+            }
+
+            // Only do recode loop on key frames and golden frames
+            sf->recode_loop = 2;
+
+            sf->full_freq[0] = 31;
+            sf->full_freq[1] = 63;
+
+        }
+
+        if (Speed > 2)
+        {
+            sf->auto_filter = 0;                     // Faster selection of loop filter
+            cpi->mode_check_freq[THR_V_PRED] = 2;
+            cpi->mode_check_freq[THR_H_PRED] = 2;
+            cpi->mode_check_freq[THR_B_PRED] = 2;
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARG] = 2;
+                cpi->mode_check_freq[THR_NEWG] = 4;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARA] = 2;
+                cpi->mode_check_freq[THR_NEWA] = 4;
+            }
+
+            sf->thresh_mult[THR_SPLITA  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITG  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
+
+            sf->full_freq[0] = 63;
+            sf->full_freq[1] = 127;
+        }
+
+        if (Speed > 3)
+        {
+            cpi->mode_check_freq[THR_V_PRED] = 0;
+            cpi->mode_check_freq[THR_H_PRED] = 0;
+            cpi->mode_check_freq[THR_B_PRED] = 0;
+            cpi->mode_check_freq[THR_NEARG] = 0;
+            cpi->mode_check_freq[THR_NEWG] = 0;
+            cpi->mode_check_freq[THR_NEARA] = 0;
+            cpi->mode_check_freq[THR_NEWA] = 0;
+
+            sf->auto_filter = 1;
+            sf->recode_loop = 0; // recode loop off
+            sf->RD = 0;         // Turn rd off
+            sf->full_freq[0] = INT_MAX;
+            sf->full_freq[1] = INT_MAX;
+        }
+
+        if (Speed > 4)
+        {
+            sf->auto_filter = 0;                     // Faster selection of loop filter
+
+            cpi->mode_check_freq[THR_V_PRED] = 2;
+            cpi->mode_check_freq[THR_H_PRED] = 2;
+            cpi->mode_check_freq[THR_B_PRED] = 2;
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARG] = 2;
+                cpi->mode_check_freq[THR_NEWG] = 4;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARA] = 2;
+                cpi->mode_check_freq[THR_NEWA] = 4;
+            }
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTG ] = 2000;
+                sf->thresh_mult[THR_ZEROG    ] = 2000;
+                sf->thresh_mult[THR_NEARG    ] = 2000;
+                sf->thresh_mult[THR_NEWG     ] = 4000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTA ] = 2000;
+                sf->thresh_mult[THR_ZEROA    ] = 2000;
+                sf->thresh_mult[THR_NEARA    ] = 2000;
+                sf->thresh_mult[THR_NEWA     ] = 4000;
+            }
+        }
+
+        break;
+#endif
+    case 2:
+        sf->optimize_coefficients = 0;
+        sf->recode_loop = 0;
+        sf->auto_filter = 1;
+        sf->iterative_sub_pixel = 1;
+        sf->thresh_mult[THR_NEARESTMV] = 0;
+        sf->thresh_mult[THR_ZEROMV   ] = 0;
+        sf->thresh_mult[THR_DC       ] = 0;
+        sf->thresh_mult[THR_TM       ] = 0;
+        sf->thresh_mult[THR_NEARMV   ] = 0;
+        sf->thresh_mult[THR_V_PRED   ] = 1000;
+        sf->thresh_mult[THR_H_PRED   ] = 1000;
+        sf->thresh_mult[THR_B_PRED   ] = 2500;
+        sf->thresh_mult[THR_NEARESTG ] = 1000;
+        sf->thresh_mult[THR_ZEROG    ] = 1000;
+        sf->thresh_mult[THR_NEARG    ] = 1000;
+        sf->thresh_mult[THR_NEARESTA ] = 1000;
+        sf->thresh_mult[THR_ZEROA    ] = 1000;
+        sf->thresh_mult[THR_NEARA    ] = 1000;
+        sf->thresh_mult[THR_NEWMV    ] = 2000;
+        sf->thresh_mult[THR_NEWG     ] = 2000;
+        sf->thresh_mult[THR_NEWA     ] = 2000;
+        sf->thresh_mult[THR_SPLITMV  ] = 5000;
+        sf->thresh_mult[THR_SPLITG   ] = 10000;
+        sf->thresh_mult[THR_SPLITA   ] = 10000;
+        sf->full_freq[0] = 15;
+        sf->full_freq[1] = 31;
+        sf->search_method = NSTEP;
+
+        if (!cpi->ref_frame_flags & VP8_LAST_FLAG)
+        {
+            sf->thresh_mult[THR_NEWMV    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARESTMV] = INT_MAX;
+            sf->thresh_mult[THR_ZEROMV   ] = INT_MAX;
+            sf->thresh_mult[THR_NEARMV   ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
+        }
+
+        if (!cpi->ref_frame_flags & VP8_GOLD_FLAG)
+        {
+            sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
+            sf->thresh_mult[THR_ZEROG    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARG    ] = INT_MAX;
+            sf->thresh_mult[THR_NEWG     ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITG   ] = INT_MAX;
+        }
+
+        if (!cpi->ref_frame_flags & VP8_ALT_FLAG)
+        {
+            sf->thresh_mult[THR_NEARESTA ] = INT_MAX;
+            sf->thresh_mult[THR_ZEROA    ] = INT_MAX;
+            sf->thresh_mult[THR_NEARA    ] = INT_MAX;
+            sf->thresh_mult[THR_NEWA     ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITA   ] = INT_MAX;
+        }
+
+        if (Speed > 0)
+        {
+            cpi->mode_check_freq[THR_SPLITG] = 4;
+            cpi->mode_check_freq[THR_SPLITA] = 4;
+            cpi->mode_check_freq[THR_SPLITMV] = 2;
+
+            sf->thresh_mult[THR_DC       ] = 0;
+            sf->thresh_mult[THR_TM       ] = 1000;
+            sf->thresh_mult[THR_V_PRED   ] = 2000;
+            sf->thresh_mult[THR_H_PRED   ] = 2000;
+            sf->thresh_mult[THR_B_PRED   ] = 5000;
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTMV] = 0;
+                sf->thresh_mult[THR_ZEROMV   ] = 0;
+                sf->thresh_mult[THR_NEARMV   ] = 0;
+                sf->thresh_mult[THR_NEWMV    ] = 2000;
+                sf->thresh_mult[THR_SPLITMV  ] = 10000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTG ] = 1000;
+                sf->thresh_mult[THR_ZEROG    ] = 1000;
+                sf->thresh_mult[THR_NEARG    ] = 1000;
+                sf->thresh_mult[THR_NEWG     ] = 2000;
+                sf->thresh_mult[THR_SPLITG   ] = 20000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTA ] = 1000;
+                sf->thresh_mult[THR_ZEROA    ] = 1000;
+                sf->thresh_mult[THR_NEARA    ] = 1000;
+                sf->thresh_mult[THR_NEWA     ] = 2000;
+                sf->thresh_mult[THR_SPLITA   ] = 20000;
+            }
+
+            sf->improved_quant = 0;
+            sf->improved_dct = 0;
+        }
+
+        if (Speed > 1)
+        {
+            cpi->mode_check_freq[THR_SPLITMV] = 7;
+            cpi->mode_check_freq[THR_SPLITG] = 15;
+            cpi->mode_check_freq[THR_SPLITA] = 15;
+
+            sf->thresh_mult[THR_TM       ] = 2000;
+            sf->thresh_mult[THR_V_PRED   ] = 2000;
+            sf->thresh_mult[THR_H_PRED   ] = 2000;
+            sf->thresh_mult[THR_B_PRED   ] = 5000;
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            {
+                sf->thresh_mult[THR_NEWMV    ] = 2000;
+                sf->thresh_mult[THR_SPLITMV  ] = 25000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTG ] = 2000;
+                sf->thresh_mult[THR_ZEROG    ] = 2000;
+                sf->thresh_mult[THR_NEARG    ] = 2000;
+                sf->thresh_mult[THR_NEWG     ] = 2500;
+                sf->thresh_mult[THR_SPLITG   ] = 50000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTA ] = 2000;
+                sf->thresh_mult[THR_ZEROA    ] = 2000;
+                sf->thresh_mult[THR_NEARA    ] = 2000;
+                sf->thresh_mult[THR_NEWA     ] = 2500;
+                sf->thresh_mult[THR_SPLITA   ] = 50000;
+            }
+
+            sf->full_freq[0] = 31;
+            sf->full_freq[1] = 63;
+        }
+
+        if (Speed > 2)
+        {
+            sf->auto_filter = 0;                     // Faster selection of loop filter
+
+            cpi->mode_check_freq[THR_V_PRED] = 2;
+            cpi->mode_check_freq[THR_H_PRED] = 2;
+            cpi->mode_check_freq[THR_B_PRED] = 2;
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARG] = 2;
+                cpi->mode_check_freq[THR_NEWG] = 4;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARA] = 2;
+                cpi->mode_check_freq[THR_NEWA] = 4;
+            }
+
+            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITG  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLITA  ] = INT_MAX;
+
+            sf->full_freq[0] = 63;
+            sf->full_freq[1] = 127;
+        }
+
+        if (Speed > 3)
+        {
+            sf->RD = 0;
+            sf->full_freq[0] = INT_MAX;
+            sf->full_freq[1] = INT_MAX;
+
+            sf->auto_filter = 1;
+        }
+
+        if (Speed > 4)
+        {
+            sf->auto_filter = 0;                     // Faster selection of loop filter
+
+#if CONFIG_REALTIME_ONLY
+            sf->search_method = HEX;
+#else
+            sf->search_method = DIAMOND;
+#endif
+
+            cpi->mode_check_freq[THR_V_PRED] = 4;
+            cpi->mode_check_freq[THR_H_PRED] = 4;
+            cpi->mode_check_freq[THR_B_PRED] = 4;
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARG] = 2;
+                cpi->mode_check_freq[THR_NEWG] = 4;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                cpi->mode_check_freq[THR_NEARA] = 2;
+                cpi->mode_check_freq[THR_NEWA] = 4;
+            }
+
+            sf->thresh_mult[THR_TM       ] = 2000;
+            sf->thresh_mult[THR_B_PRED   ] = 5000;
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTG ] = 2000;
+                sf->thresh_mult[THR_ZEROG    ] = 2000;
+                sf->thresh_mult[THR_NEARG    ] = 2000;
+                sf->thresh_mult[THR_NEWG     ] = 4000;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEARESTA ] = 2000;
+                sf->thresh_mult[THR_ZEROA    ] = 2000;
+                sf->thresh_mult[THR_NEARA    ] = 2000;
+                sf->thresh_mult[THR_NEWA     ] = 4000;
+            }
+        }
+
+        if (Speed > 5)
+        {
+            // Disable split MB intra prediction mode
+            sf->thresh_mult[THR_B_PRED] = INT_MAX;
+        }
+
+        if (Speed > 6)
+        {
+            unsigned int i, sum = 0;
+            unsigned int total_mbs = cm->MBs;
+            int thresh;
+            int total_skip;
+
+            int min = 2000;
+            sf->iterative_sub_pixel = 0;
+
+            if (cpi->oxcf.encode_breakout > 2000)
+                min = cpi->oxcf.encode_breakout;
+
+            min >>= 7;
+
+            for (i = 0; i < min; i++)
+            {
+                sum += cpi->error_bins[i];
+            }
+
+            total_skip = sum;
+            sum = 0;
+
+            // i starts from 2 to make sure thresh started from 2048
+            for (; i < 1024; i++)
+            {
+                sum += cpi->error_bins[i];
+
+                if (10 * sum >= (unsigned int)(cpi->Speed - 6)*(total_mbs - total_skip))
+                    break;
+            }
+
+            i--;
+            thresh = (i << 7);
+
+            if (thresh < 2000)
+                thresh = 2000;
+
+            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            {
+                sf->thresh_mult[THR_NEWMV] = thresh;
+                sf->thresh_mult[THR_NEARESTMV ] = thresh >> 1;
+                sf->thresh_mult[THR_NEARMV    ] = thresh >> 1;
+            }
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                sf->thresh_mult[THR_NEWG] = thresh << 1;
+                sf->thresh_mult[THR_NEARESTG ] = thresh;
+                sf->thresh_mult[THR_NEARG    ] = thresh;
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                sf->thresh_mult[THR_NEWA] = thresh << 1;
+                sf->thresh_mult[THR_NEARESTA ] = thresh;
+                sf->thresh_mult[THR_NEARA    ] = thresh;
+            }
+
+            // Disable other intra prediction modes
+            sf->thresh_mult[THR_TM] = INT_MAX;
+            sf->thresh_mult[THR_V_PRED] = INT_MAX;
+            sf->thresh_mult[THR_H_PRED] = INT_MAX;
+
+        }
+
+        if (Speed > 8)
+        {
+            sf->quarter_pixel_search = 0;
+        }
+
+        if (Speed > 9)
+        {
+            int Tmp = cpi->Speed - 8;
+
+            if (Tmp > 4)
+                Tmp = 4;
+
+            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            {
+                cpi->mode_check_freq[THR_ZEROG] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEARESTG] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEARG] = 1 << Tmp;
+                cpi->mode_check_freq[THR_NEWG] = 1 << (Tmp + 1);
+            }
+
+            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            {
+                cpi->mode_check_freq[THR_ZEROA] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEARESTA] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEARA] = 1 << Tmp;
+                cpi->mode_check_freq[THR_NEWA] = 1 << (Tmp + 1);
+            }
+
+            cpi->mode_check_freq[THR_NEWMV] = 1 << (Tmp - 1);
+        }
+
+        cm->filter_type = NORMAL_LOOPFILTER;
+
+        if (Speed >= 14)
+            cm->filter_type = SIMPLE_LOOPFILTER;
+
+        if (Speed >= 15)
+        {
+            sf->half_pixel_search = 0;        // This has a big hit on quality. Last resort
+        }
+
+        vpx_memset(cpi->error_bins, 0, sizeof(cpi->error_bins));
+
+    };
+
+    if (cpi->sf.search_method == NSTEP)
+    {
+        vp8_init3smotion_compensation(&cpi->mb, cm->last_frame.y_stride);
+    }
+    else if (cpi->sf.search_method == DIAMOND)
+    {
+        vp8_init_dsmotion_compensation(&cpi->mb, cm->last_frame.y_stride);
+    }
+
+    if (cpi->sf.improved_dct)
+    {
+        cpi->mb.vp8_short_fdct8x4 = FDCT_INVOKE(&cpi->rtcd.fdct, short8x4);
+        cpi->mb.vp8_short_fdct4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4);
+        cpi->mb.short_fdct8x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, short8x4);
+        cpi->mb.short_fdct4x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4);
+    }
+    else
+    {
+        cpi->mb.vp8_short_fdct8x4   = FDCT_INVOKE(&cpi->rtcd.fdct, fast8x4);
+        cpi->mb.vp8_short_fdct4x4   = FDCT_INVOKE(&cpi->rtcd.fdct, fast4x4);
+        cpi->mb.short_fdct8x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, fast8x4);
+        cpi->mb.short_fdct4x4rd = FDCT_INVOKE(&cpi->rtcd.fdct, fast4x4);
+    }
+
+    cpi->mb.vp8_short_fdct4x4_ptr = FDCT_INVOKE(&cpi->rtcd.fdct, short4x4);
+    cpi->mb.short_walsh4x4 = FDCT_INVOKE(&cpi->rtcd.fdct, walsh_short4x4);
+
+    if (cpi->sf.improved_quant)
+    {
+        cpi->mb.quantize_b    = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb);
+        cpi->mb.quantize_brd  = QUANTIZE_INVOKE(&cpi->rtcd.quantize, quantb);
+    }
+    else
+    {
+        cpi->mb.quantize_b      = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb);
+        cpi->mb.quantize_brd    = QUANTIZE_INVOKE(&cpi->rtcd.quantize, fastquantb);
+    }
+
+#if CONFIG_RUNTIME_CPU_DETECT
+    cpi->mb.e_mbd.rtcd = &cpi->common.rtcd;
+#endif
+
+    if (cpi->sf.iterative_sub_pixel == 1)
+    {
+        cpi->find_fractional_mv_step = vp8_find_best_sub_pixel_step_iteratively;
+    }
+    else if (cpi->sf.quarter_pixel_search)
+    {
+        cpi->find_fractional_mv_step = vp8_find_best_sub_pixel_step;
+    }
+    else if (cpi->sf.half_pixel_search)
+    {
+        cpi->find_fractional_mv_step = vp8_find_best_half_pixel_step;
+    }
+    else
+    {
+        cpi->find_fractional_mv_step = vp8_skip_fractional_mv_step;
+    }
+
+    if (cpi->sf.optimize_coefficients == 1)
+        cpi->mb.optimize = 1;
+    else
+        cpi->mb.optimize = 0;
+
+    if (cpi->common.full_pixel)
+        cpi->find_fractional_mv_step = vp8_skip_fractional_mv_step;
+
+#ifdef SPEEDSTATS
+    frames_at_speed[cpi->Speed]++;
+#endif
+}
+static void alloc_raw_frame_buffers(VP8_COMP *cpi)
+{
+    int i, buffers;
+
+    buffers = cpi->oxcf.lag_in_frames;
+
+    if (buffers > MAX_LAG_BUFFERS)
+        buffers = MAX_LAG_BUFFERS;
+
+    if (buffers < 1)
+        buffers = 1;
+
+    for (i = 0; i < buffers; i++)
+        if (vp8_yv12_alloc_frame_buffer(&cpi->src_buffer[i].source_buffer,
+                                        cpi->oxcf.Width, cpi->oxcf.Height,
+                                        16))
+            vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                               "Failed to allocate lag buffer");
+
+#if VP8_TEMPORAL_ALT_REF
+
+    if (vp8_yv12_alloc_frame_buffer(&cpi->alt_ref_buffer.source_buffer,
+                                    cpi->oxcf.Width, cpi->oxcf.Height, 16))
+        vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                           "Failed to allocate altref buffer");
+
+#endif
+
+    cpi->source_buffer_count = 0;
+}
+void vp8_alloc_compressor_data(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = & cpi->common;
+
+    int width = cm->Width;
+    int height = cm->Height;
+
+    if (vp8_alloc_frame_buffers(cm, width, height))
+        vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                           "Failed to allocate frame buffers");
+
+    if ((width & 0xf) != 0)
+        width += 16 - (width & 0xf);
+
+    if ((height & 0xf) != 0)
+        height += 16 - (height & 0xf);
+
+
+    if (vp8_yv12_alloc_frame_buffer(&cpi->last_frame_uf,
+                                    width, height, VP8BORDERINPIXELS))
+        vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                           "Failed to allocate last frame buffer");
+
+    if (vp8_yv12_alloc_frame_buffer(&cpi->scaled_source, width, height, 16))
+        vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                           "Failed to allocate scaled source buffer");
+
+
+    if (cpi->tok != 0)
+        vpx_free(cpi->tok);
+
+    {
+        unsigned int tokens = cm->mb_rows * cm->mb_cols * 24 * 16;
+
+        CHECK_MEM_ERROR(cpi->tok, vpx_calloc(tokens, sizeof(*cpi->tok)));
+    }
+
+    // Data used for real time vc mode to see if gf needs refreshing
+    cpi->inter_zz_count = 0;
+    cpi->gf_bad_count = 0;
+    cpi->gf_update_recommended = 0;
+}
+
+
+// Quant MOD
+static const int q_trans[] =
+{
+    0,   1,  2,  3,  4,  5,  7,  8,
+    9,  10, 12, 13, 15, 17, 18, 19,
+    20,  21, 23, 24, 25, 26, 27, 28,
+    29,  30, 31, 33, 35, 37, 39, 41,
+    43,  45, 47, 49, 51, 53, 55, 57,
+    59,  61, 64, 67, 70, 73, 76, 79,
+    82,  85, 88, 91, 94, 97, 100, 103,
+    106, 109, 112, 115, 118, 121, 124, 127,
+};
+
+int vp8_reverse_trans(int x)
+{
+    int i;
+
+    for (i = 0; i < 64; i++)
+        if (q_trans[i] >= x)
+            return i;
+
+    return 63;
+};
+void vp8_new_frame_rate(VP8_COMP *cpi, double framerate)
+{
+    cpi->oxcf.frame_rate             = framerate;
+    cpi->output_frame_rate            = cpi->oxcf.frame_rate;
+    cpi->per_frame_bandwidth          = (int)(cpi->oxcf.target_bandwidth / cpi->output_frame_rate);
+    cpi->av_per_frame_bandwidth        = (int)(cpi->oxcf.target_bandwidth / cpi->output_frame_rate);
+    cpi->min_frame_bandwidth          = (int)(cpi->av_per_frame_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
+    cpi->rolling_target_bits          = cpi->av_per_frame_bandwidth;
+    cpi->rolling_actual_bits          = cpi->av_per_frame_bandwidth;
+
+    cpi->long_rolling_target_bits      = cpi->av_per_frame_bandwidth;
+    cpi->long_rolling_actual_bits      = cpi->av_per_frame_bandwidth;
+    cpi->max_gf_interval = (int)(cpi->output_frame_rate / 2) + 2;
+
+    //cpi->max_gf_interval = (int)(cpi->output_frame_rate * 2 / 3) + 1;
+    //cpi->max_gf_interval = 24;
+
+    if (cpi->max_gf_interval < 12)
+        cpi->max_gf_interval = 12;
+
+
+    // Special conditions when altr ref frame enabled
+    if (cpi->oxcf.play_alternate)
+    {
+        if (cpi->max_gf_interval > cpi->oxcf.lag_in_frames - 1)
+            cpi->max_gf_interval = cpi->oxcf.lag_in_frames - 1;
+    }
+}
+
+void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+    VP8_COMMON *cm = &cpi->common;
+
+    if (!cpi)
+        return;
+
+    cpi->auto_gold = 1;
+    cpi->auto_adjust_gold_quantizer = 1;
+    cpi->goldquantizer = 1;
+    cpi->goldfreq = 7;
+    cpi->auto_adjust_key_quantizer = 1;
+    cpi->keyquantizer = 1;
+
+    cm->version = oxcf->Version;
+    vp8_setup_version(cm);
+
+    if (oxcf == 0)
+    {
+        cpi->pass                     = 0;
+
+        cpi->auto_worst_q              = 0;
+        cpi->oxcf.best_allowed_q            = MINQ;
+        cpi->oxcf.worst_allowed_q           = MAXQ;
+
+        cpi->oxcf.end_usage                = USAGE_STREAM_FROM_SERVER;
+        cpi->oxcf.starting_buffer_level     =   4;
+        cpi->oxcf.optimal_buffer_level      =   5;
+        cpi->oxcf.maximum_buffer_size       =   6;
+        cpi->oxcf.under_shoot_pct           =  90;
+        cpi->oxcf.allow_df                 =   0;
+        cpi->oxcf.drop_frames_water_mark     =  20;
+
+        cpi->oxcf.allow_spatial_resampling  = 0;
+        cpi->oxcf.resample_down_water_mark   = 40;
+        cpi->oxcf.resample_up_water_mark     = 60;
+
+        cpi->oxcf.fixed_q = cpi->interquantizer;
+
+        cpi->filter_type = NORMAL_LOOPFILTER;
+
+        if (cm->simpler_lpf)
+            cpi->filter_type = SIMPLE_LOOPFILTER;
+
+        cpi->compressor_speed = 1;
+        cpi->horiz_scale = 0;
+        cpi->vert_scale = 0;
+        cpi->oxcf.two_pass_vbrbias = 50;
+        cpi->oxcf.two_pass_vbrmax_section = 400;
+        cpi->oxcf.two_pass_vbrmin_section = 0;
+
+        cpi->oxcf.Sharpness = 0;
+        cpi->oxcf.noise_sensitivity = 0;
+    }
+    else
+        cpi->oxcf = *oxcf;
+
+
+    switch (cpi->oxcf.Mode)
+    {
+
+    case MODE_REALTIME:
+        cpi->pass = 0;
+        cpi->compressor_speed = 2;
+
+        if (cpi->oxcf.cpu_used < -16)
+        {
+            cpi->oxcf.cpu_used = -16;
+        }
+
+        if (cpi->oxcf.cpu_used > 16)
+            cpi->oxcf.cpu_used = 16;
+
+        break;
+
+#if !(CONFIG_REALTIME_ONLY)
+    case MODE_GOODQUALITY:
+        cpi->pass = 0;
+        cpi->compressor_speed = 1;
+
+        if (cpi->oxcf.cpu_used < -5)
+        {
+            cpi->oxcf.cpu_used = -5;
+        }
+
+        if (cpi->oxcf.cpu_used > 5)
+            cpi->oxcf.cpu_used = 5;
+
+        break;
+
+    case MODE_BESTQUALITY:
+        cpi->pass = 0;
+        cpi->compressor_speed = 0;
+        break;
+
+    case MODE_FIRSTPASS:
+        cpi->pass = 1;
+        cpi->compressor_speed = 1;
+        break;
+    case MODE_SECONDPASS:
+        cpi->pass = 2;
+        cpi->compressor_speed = 1;
+
+        if (cpi->oxcf.cpu_used < -5)
+        {
+            cpi->oxcf.cpu_used = -5;
+        }
+
+        if (cpi->oxcf.cpu_used > 5)
+            cpi->oxcf.cpu_used = 5;
+
+        break;
+    case MODE_SECONDPASS_BEST:
+        cpi->pass = 2;
+        cpi->compressor_speed = 0;
+        break;
+#endif
+    }
+
+    if (cpi->pass == 0)
+        cpi->auto_worst_q = 1;
+
+    cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
+    cpi->oxcf.best_allowed_q  = q_trans[oxcf->best_allowed_q];
+
+    if (oxcf->fixed_q >= 0)
+    {
+        if (oxcf->worst_allowed_q < 0)
+            cpi->oxcf.fixed_q = q_trans[0];
+        else
+            cpi->oxcf.fixed_q = q_trans[oxcf->worst_allowed_q];
+
+        if (oxcf->alt_q < 0)
+            cpi->oxcf.alt_q = q_trans[0];
+        else
+            cpi->oxcf.alt_q = q_trans[oxcf->alt_q];
+
+        if (oxcf->key_q < 0)
+            cpi->oxcf.key_q = q_trans[0];
+        else
+            cpi->oxcf.key_q = q_trans[oxcf->key_q];
+
+        if (oxcf->gold_q < 0)
+            cpi->oxcf.gold_q = q_trans[0];
+        else
+            cpi->oxcf.gold_q = q_trans[oxcf->gold_q];
+
+    }
+
+    cpi->baseline_gf_interval = cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
+    cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
+
+    //cpi->use_golden_frame_only = 0;
+    //cpi->use_last_frame_only = 0;
+    cm->refresh_golden_frame = 0;
+    cm->refresh_last_frame = 1;
+    cm->refresh_entropy_probs = 1;
+
+    if (cpi->oxcf.token_partitions >= 0 && cpi->oxcf.token_partitions <= 3)
+        cm->multi_token_partition = (TOKEN_PARTITION) cpi->oxcf.token_partitions;
+
+    setup_features(cpi);
+
+    {
+        int i;
+
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+            cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
+    }
+
+    // At the moment the first order values may not be > MAXQ
+    if (cpi->oxcf.fixed_q > MAXQ)
+        cpi->oxcf.fixed_q = MAXQ;
+
+    // local file playback mode == really big buffer
+    if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK)
+    {
+        cpi->oxcf.starting_buffer_level   = 60;
+        cpi->oxcf.optimal_buffer_level    = 60;
+        cpi->oxcf.maximum_buffer_size     = 240;
+
+    }
+
+
+    // Convert target bandwidth from Kbit/s to Bit/s
+    cpi->oxcf.target_bandwidth       *= 1000;
+    cpi->oxcf.starting_buffer_level   *= cpi->oxcf.target_bandwidth;
+
+    if (cpi->oxcf.optimal_buffer_level == 0)
+        cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
+    else
+        cpi->oxcf.optimal_buffer_level *= cpi->oxcf.target_bandwidth;
+
+    if (cpi->oxcf.maximum_buffer_size == 0)
+        cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8;
+    else
+        cpi->oxcf.maximum_buffer_size     *= cpi->oxcf.target_bandwidth;
+
+    cpi->buffer_level                = cpi->oxcf.starting_buffer_level;
+    cpi->bits_off_target              = cpi->oxcf.starting_buffer_level;
+
+    vp8_new_frame_rate(cpi, cpi->oxcf.frame_rate);
+    cpi->worst_quality               = cpi->oxcf.worst_allowed_q;
+    cpi->active_worst_quality         = cpi->oxcf.worst_allowed_q;
+    cpi->avg_frame_qindex             = cpi->oxcf.worst_allowed_q;
+    cpi->best_quality                = cpi->oxcf.best_allowed_q;
+    cpi->active_best_quality          = cpi->oxcf.best_allowed_q;
+    cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
+
+
+    cpi->total_actual_bits            = 0;
+    cpi->total_target_vs_actual        = 0;
+
+    // Only allow dropped frames in buffered mode
+    cpi->drop_frames_allowed          = cpi->oxcf.allow_df && cpi->buffered_mode;
+
+    cm->filter_type      = (LOOPFILTERTYPE) cpi->filter_type;
+
+    if (!cm->use_bilinear_mc_filter)
+        cm->mcomp_filter_type = SIXTAP;
+    else
+        cm->mcomp_filter_type = BILINEAR;
+
+    cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
+
+    cm->Width       = cpi->oxcf.Width     ;
+    cm->Height      = cpi->oxcf.Height    ;
+
+    cpi->intra_frame_target = (4 * (cm->Width + cm->Height) / 15) * 1000; // As per VP8
+
+    cm->horiz_scale  = cpi->horiz_scale;
+    cm->vert_scale   = cpi->vert_scale ;
+
+    // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
+    if (cpi->oxcf.Sharpness > 7)
+        cpi->oxcf.Sharpness = 7;
+
+    cm->sharpness_level = cpi->oxcf.Sharpness;
+
+    if (cm->horiz_scale != NORMAL || cm->vert_scale != NORMAL)
+    {
+        int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
+        int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+
+        Scale2Ratio(cm->horiz_scale, &hr, &hs);
+        Scale2Ratio(cm->vert_scale, &vr, &vs);
+
+        // always go to the next whole number
+        cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs;
+        cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
+    }
+
+    if (((cm->Width + 15) & 0xfffffff0) != cm->last_frame.y_width ||
+        ((cm->Height + 15) & 0xfffffff0) != cm->last_frame.y_height ||
+        cm->last_frame.y_width == 0)
+    {
+        alloc_raw_frame_buffers(cpi);
+        vp8_alloc_compressor_data(cpi);
+    }
+
+    // Clamp KF frame size to quarter of data rate
+    if (cpi->intra_frame_target > cpi->target_bandwidth >> 2)
+        cpi->intra_frame_target = cpi->target_bandwidth >> 2;
+
+    if (cpi->oxcf.fixed_q >= 0)
+    {
+        cpi->last_q[0] = cpi->oxcf.fixed_q;
+        cpi->last_q[1] = cpi->oxcf.fixed_q;
+    }
+
+    cpi->Speed = cpi->oxcf.cpu_used;
+
+    // force to allowlag to 0 if lag_in_frames is 0;
+    if (cpi->oxcf.lag_in_frames == 0)
+    {
+        cpi->oxcf.allow_lag = 0;
+    }
+    // Limit on lag buffers as these are not currently dynamically allocated
+    else if (cpi->oxcf.lag_in_frames > MAX_LAG_BUFFERS)
+        cpi->oxcf.lag_in_frames = MAX_LAG_BUFFERS;
+
+    // force play_alternate to 0 if allow_lag is 0, lag_in_frames is too small, Mode is real time or one pass compress enabled.
+    if (cpi->oxcf.allow_lag == 0 || cpi->oxcf.lag_in_frames <= 5 || (cpi->oxcf.Mode < MODE_SECONDPASS))
+    {
+        cpi->oxcf.play_alternate = 0;
+        cpi->ref_frame_flags = cpi->ref_frame_flags & ~VP8_ALT_FLAG;
+    }
+
+    // YX Temp
+    cpi->last_alt_ref_sei    = -1;
+    cpi->is_src_frame_alt_ref = 0;
+
+#if 0
+    // Experimental RD Code
+    cpi->frame_distortion = 0;
+    cpi->last_frame_distortion = 0;
+#endif
+
+#if VP8_TEMPORAL_ALT_REF
+    {
+        int i;
+
+        cpi->fixed_divide[0] = 0;
+
+        for (i = 1; i < 255; i++)
+            cpi->fixed_divide[i] = 0x10000 / i;
+    }
+#endif
+}
+
+/*
+ * This function needs more clean up, i.e. be more tuned torwards
+ * change_config rather than init_config  !!!!!!!!!!!!!!!!
+ * YX - 5/28/2009
+ *
+ */
+
+void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+    VP8_COMMON *cm = &cpi->common;
+
+    if (!cpi)
+        return;
+
+    if (!oxcf)
+        return;
+
+    if (cm->version != oxcf->Version)
+    {
+        cm->version = oxcf->Version;
+        vp8_setup_version(cm);
+    }
+
+    cpi->oxcf = *oxcf;
+
+    switch (cpi->oxcf.Mode)
+    {
+
+    case MODE_REALTIME:
+        cpi->pass = 0;
+        cpi->compressor_speed = 2;
+
+        if (cpi->oxcf.cpu_used < -16)
+        {
+            cpi->oxcf.cpu_used = -16;
+        }
+
+        if (cpi->oxcf.cpu_used > 16)
+            cpi->oxcf.cpu_used = 16;
+
+        break;
+
+#if !(CONFIG_REALTIME_ONLY)
+    case MODE_GOODQUALITY:
+        cpi->pass = 0;
+        cpi->compressor_speed = 1;
+
+        if (cpi->oxcf.cpu_used < -5)
+        {
+            cpi->oxcf.cpu_used = -5;
+        }
+
+        if (cpi->oxcf.cpu_used > 5)
+            cpi->oxcf.cpu_used = 5;
+
+        break;
+
+    case MODE_BESTQUALITY:
+        cpi->pass = 0;
+        cpi->compressor_speed = 0;
+        break;
+
+    case MODE_FIRSTPASS:
+        cpi->pass = 1;
+        cpi->compressor_speed = 1;
+        break;
+    case MODE_SECONDPASS:
+        cpi->pass = 2;
+        cpi->compressor_speed = 1;
+
+        if (cpi->oxcf.cpu_used < -5)
+        {
+            cpi->oxcf.cpu_used = -5;
+        }
+
+        if (cpi->oxcf.cpu_used > 5)
+            cpi->oxcf.cpu_used = 5;
+
+        break;
+    case MODE_SECONDPASS_BEST:
+        cpi->pass = 2;
+        cpi->compressor_speed = 0;
+        break;
+#endif
+    }
+
+    if (cpi->pass == 0)
+        cpi->auto_worst_q = 1;
+
+    cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
+    cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q];
+
+    if (oxcf->fixed_q >= 0)
+    {
+        if (oxcf->worst_allowed_q < 0)
+            cpi->oxcf.fixed_q = q_trans[0];
+        else
+            cpi->oxcf.fixed_q = q_trans[oxcf->worst_allowed_q];
+
+        if (oxcf->alt_q < 0)
+            cpi->oxcf.alt_q = q_trans[0];
+        else
+            cpi->oxcf.alt_q = q_trans[oxcf->alt_q];
+
+        if (oxcf->key_q < 0)
+            cpi->oxcf.key_q = q_trans[0];
+        else
+            cpi->oxcf.key_q = q_trans[oxcf->key_q];
+
+        if (oxcf->gold_q < 0)
+            cpi->oxcf.gold_q = q_trans[0];
+        else
+            cpi->oxcf.gold_q = q_trans[oxcf->gold_q];
+
+    }
+
+    cpi->baseline_gf_interval = cpi->oxcf.alt_freq ? cpi->oxcf.alt_freq : DEFAULT_GF_INTERVAL;
+
+    cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
+
+    //cpi->use_golden_frame_only = 0;
+    //cpi->use_last_frame_only = 0;
+    cm->refresh_golden_frame = 0;
+    cm->refresh_last_frame = 1;
+    cm->refresh_entropy_probs = 1;
+
+    if (cpi->oxcf.token_partitions >= 0 && cpi->oxcf.token_partitions <= 3)
+        cm->multi_token_partition = (TOKEN_PARTITION) cpi->oxcf.token_partitions;
+
+    setup_features(cpi);
+
+    {
+        int i;
+
+        for (i = 0; i < MAX_MB_SEGMENTS; i++)
+            cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
+    }
+
+    // At the moment the first order values may not be > MAXQ
+    if (cpi->oxcf.fixed_q > MAXQ)
+        cpi->oxcf.fixed_q = MAXQ;
+
+    // local file playback mode == really big buffer
+    if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK)
+    {
+        cpi->oxcf.starting_buffer_level   = 60;
+        cpi->oxcf.optimal_buffer_level    = 60;
+        cpi->oxcf.maximum_buffer_size     = 240;
+
+    }
+
+    // Convert target bandwidth from Kbit/s to Bit/s
+    cpi->oxcf.target_bandwidth       *= 1000;
+
+    cpi->oxcf.starting_buffer_level   *= cpi->oxcf.target_bandwidth;
+
+    if (cpi->oxcf.optimal_buffer_level == 0)
+        cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
+    else
+        cpi->oxcf.optimal_buffer_level *= cpi->oxcf.target_bandwidth;
+
+    if (cpi->oxcf.maximum_buffer_size == 0)
+        cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8;
+    else
+        cpi->oxcf.maximum_buffer_size     *= cpi->oxcf.target_bandwidth;
+
+    cpi->buffer_level                = cpi->oxcf.starting_buffer_level;
+    cpi->bits_off_target              = cpi->oxcf.starting_buffer_level;
+
+    vp8_new_frame_rate(cpi, cpi->oxcf.frame_rate);
+    cpi->worst_quality               = cpi->oxcf.worst_allowed_q;
+    cpi->active_worst_quality         = cpi->oxcf.worst_allowed_q;
+    cpi->avg_frame_qindex             = cpi->oxcf.worst_allowed_q;
+    cpi->best_quality                = cpi->oxcf.best_allowed_q;
+    cpi->active_best_quality          = cpi->oxcf.best_allowed_q;
+    cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
+
+
+    cpi->total_actual_bits            = 0;
+    cpi->total_target_vs_actual        = 0;
+
+    // Only allow dropped frames in buffered mode
+    cpi->drop_frames_allowed          = cpi->oxcf.allow_df && cpi->buffered_mode;
+
+    cm->filter_type                  = (LOOPFILTERTYPE) cpi->filter_type;
+
+    if (!cm->use_bilinear_mc_filter)
+        cm->mcomp_filter_type = SIXTAP;
+    else
+        cm->mcomp_filter_type = BILINEAR;
+
+    cpi->target_bandwidth = cpi->oxcf.target_bandwidth;
+
+    cm->Width       = cpi->oxcf.Width     ;
+    cm->Height      = cpi->oxcf.Height    ;
+
+    cm->horiz_scale  = cpi->horiz_scale;
+    cm->vert_scale   = cpi->vert_scale ;
+
+    cpi->intra_frame_target           = (4 * (cm->Width + cm->Height) / 15) * 1000; // As per VP8
+
+    // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs)
+    if (cpi->oxcf.Sharpness > 7)
+        cpi->oxcf.Sharpness = 7;
+
+    cm->sharpness_level = cpi->oxcf.Sharpness;
+
+    if (cm->horiz_scale != NORMAL || cm->vert_scale != NORMAL)
+    {
+        int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
+        int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+
+        Scale2Ratio(cm->horiz_scale, &hr, &hs);
+        Scale2Ratio(cm->vert_scale, &vr, &vs);
+
+        // always go to the next whole number
+        cm->Width = (hs - 1 + cpi->oxcf.Width * hr) / hs;
+        cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
+    }
+
+    if (((cm->Width + 15) & 0xfffffff0) != cm->last_frame.y_width ||
+        ((cm->Height + 15) & 0xfffffff0) != cm->last_frame.y_height ||
+        cm->last_frame.y_width == 0)
+    {
+        alloc_raw_frame_buffers(cpi);
+        vp8_alloc_compressor_data(cpi);
+    }
+
+    // Clamp KF frame size to quarter of data rate
+    if (cpi->intra_frame_target > cpi->target_bandwidth >> 2)
+        cpi->intra_frame_target = cpi->target_bandwidth >> 2;
+
+    if (cpi->oxcf.fixed_q >= 0)
+    {
+        cpi->last_q[0] = cpi->oxcf.fixed_q;
+        cpi->last_q[1] = cpi->oxcf.fixed_q;
+    }
+
+    cpi->Speed = cpi->oxcf.cpu_used;
+
+    // force to allowlag to 0 if lag_in_frames is 0;
+    if (cpi->oxcf.lag_in_frames == 0)
+    {
+        cpi->oxcf.allow_lag = 0;
+    }
+    // Limit on lag buffers as these are not currently dynamically allocated
+    else if (cpi->oxcf.lag_in_frames > MAX_LAG_BUFFERS)
+        cpi->oxcf.lag_in_frames = MAX_LAG_BUFFERS;
+
+    // force play_alternate to 0 if allow_lag is 0, lag_in_frames is too small, Mode is real time or one pass compress enabled.
+    if (cpi->oxcf.allow_lag == 0 || cpi->oxcf.lag_in_frames <= 5 || (cpi->oxcf.Mode < MODE_SECONDPASS))
+    {
+        cpi->oxcf.play_alternate = 0;
+        cpi->ref_frame_flags = cpi->ref_frame_flags & ~VP8_ALT_FLAG;
+    }
+
+    // YX Temp
+    cpi->last_alt_ref_sei    = -1;
+    cpi->is_src_frame_alt_ref = 0;
+
+#if 0
+    // Experimental RD Code
+    cpi->frame_distortion = 0;
+    cpi->last_frame_distortion = 0;
+#endif
+
+}
+
+#define M_LOG2_E 0.693147180559945309417
+#define log2f(x) (log (x) / (float) M_LOG2_E)
+static void cal_mvsadcosts(int *mvsadcost[2])
+{
+    int i = 1;
+
+    mvsadcost [0] [0] = 300;
+    mvsadcost [1] [0] = 300;
+
+    do
+    {
+        double z = 256 * (2 * (log2f(2 * i) + .6));
+        mvsadcost [0][i] = (int) z;
+        mvsadcost [1][i] = (int) z;
+        mvsadcost [0][-i] = (int) z;
+        mvsadcost [1][-i] = (int) z;
+    }
+    while (++i <= mv_max);
+}
+
+VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
+{
+    int i;
+    volatile union
+    {
+        VP8_COMP *cpi;
+        VP8_PTR   ptr;
+    } ctx;
+    
+    VP8_COMP *cpi;
+    VP8_COMMON *cm;
+
+    cpi = ctx.cpi = vpx_memalign(32, sizeof(VP8_COMP));
+    // Check that the CPI instance is valid
+    if (!cpi)
+        return 0;
+
+    cm = &cpi->common;
+
+    vpx_memset(cpi, 0, sizeof(VP8_COMP));
+
+    if (setjmp(cm->error.jmp))
+    {
+        VP8_PTR ptr = ctx.ptr;
+
+        ctx.cpi->common.error.setjmp = 0;
+        vp8_remove_compressor(&ptr);
+        return 0;
+    }
+
+    cpi->common.error.setjmp = 1;
+
+    CHECK_MEM_ERROR(cpi->rdtok, vpx_calloc(256 * 3 / 2, sizeof(TOKENEXTRA)));
+    CHECK_MEM_ERROR(cpi->mb.ss, vpx_calloc(sizeof(search_site), (MAX_MVSEARCH_STEPS * 8) + 1));
+
+    vp8_cmachine_specific_config(cpi);
+    vp8_create_common(&cpi->common);
+
+    vp8_init_config((VP8_PTR)cpi, oxcf);
+
+    memcpy(cpi->base_skip_false_prob, vp8cx_base_skip_false_prob, sizeof(vp8cx_base_skip_false_prob));
+    cpi->common.current_video_frame   = 0;
+    cpi->kf_overspend_bits            = 0;
+    cpi->kf_bitrate_adjustment        = 0;
+    cpi->frames_till_gf_update_due      = 0;
+    cpi->gf_overspend_bits            = 0;
+    cpi->non_gf_bitrate_adjustment     = 0;
+    cpi->prob_last_coded              = 128;
+    cpi->prob_gf_coded                = 128;
+    cpi->prob_intra_coded             = 63;
+
+    // Prime the recent reference frame useage counters.
+    // Hereafter they will be maintained as a sort of moving average
+    cpi->recent_ref_frame_usage[INTRA_FRAME]  = 1;
+    cpi->recent_ref_frame_usage[LAST_FRAME]   = 1;
+    cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1;
+    cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1;
+
+    // Set reference frame sign bias for ALTREF frame to 1 (for now)
+    cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1;
+
+    cpi->gf_decay_rate = 0;
+    cpi->baseline_gf_interval = DEFAULT_GF_INTERVAL;
+
+    cpi->gold_is_last = 0 ;
+    cpi->alt_is_last  = 0 ;
+    cpi->gold_is_alt  = 0 ;
+
+
+
+    // Create the encoder segmentation map and set all entries to 0
+    CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+    CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+    vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
+    cpi->active_map_enabled = 0;
+
+    // Create the first pass motion map structure and set to 0
+    CHECK_MEM_ERROR(cpi->fp_motion_map, vpx_calloc(cpi->common.MBs, 1));
+
+#if 0
+    // Experimental code for lagged and one pass
+    // Initialise one_pass GF frames stats
+    // Update stats used for GF selection
+    if (cpi->pass == 0)
+    {
+        cpi->one_pass_frame_index = 0;
+
+        for (i = 0; i < MAX_LAG_BUFFERS; i++)
+        {
+            cpi->one_pass_frame_stats[i].frames_so_far = 0;
+            cpi->one_pass_frame_stats[i].frame_intra_error = 0.0;
+            cpi->one_pass_frame_stats[i].frame_coded_error = 0.0;
+            cpi->one_pass_frame_stats[i].frame_pcnt_inter = 0.0;
+            cpi->one_pass_frame_stats[i].frame_pcnt_motion = 0.0;
+            cpi->one_pass_frame_stats[i].frame_mvr = 0.0;
+            cpi->one_pass_frame_stats[i].frame_mvr_abs = 0.0;
+            cpi->one_pass_frame_stats[i].frame_mvc = 0.0;
+            cpi->one_pass_frame_stats[i].frame_mvc_abs = 0.0;
+        }
+    }
+#endif
+
+    // Should we use the cyclic refresh method.
+    // Currently this is tied to error resilliant mode
+    cpi->cyclic_refresh_mode_enabled = cpi->oxcf.error_resilient_mode;
+    cpi->cyclic_refresh_mode_max_mbs_perframe = (cpi->common.mb_rows * cpi->common.mb_cols) / 40;
+    cpi->cyclic_refresh_mode_index = 0;
+    cpi->cyclic_refresh_q = 32;
+
+    if (cpi->cyclic_refresh_mode_enabled)
+    {
+        CHECK_MEM_ERROR(cpi->cyclic_refresh_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
+    }
+    else
+        cpi->cyclic_refresh_map = (signed char *) NULL;
+
+    // Test function for segmentation
+    //segmentation_test_function((VP8_PTR) cpi);
+
+    // Loop filter mode / ref deltas test function
+    //mode_ref_lf_test_function(cpi);
+
+#ifdef ENTROPY_STATS
+    init_context_counters();
+#endif
+
+
+#ifdef INTRARDOPT
+    cpi->intra_rd_opt = 1;
+
+#endif
+
+    cpi->frames_since_key = 8;        // Give a sensible default for the first frame.
+    cpi->key_frame_frequency = cpi->oxcf.key_freq;
+
+    cpi->source_alt_ref_pending = FALSE;
+    cpi->source_alt_ref_active = FALSE;
+    cpi->common.refresh_alt_ref_frame = 0;
+
+    cpi->b_calculate_psnr = CONFIG_PSNR;
+#if CONFIG_PSNR
+    cpi->b_calculate_ssimg = 0;
+
+    cpi->count = 0;
+    cpi->bytes = 0;
+
+    if (cpi->b_calculate_psnr)
+    {
+        cpi->total_sq_error = 0.0;
+        cpi->total_sq_error2 = 0.0;
+        cpi->total_y = 0.0;
+        cpi->total_u = 0.0;
+        cpi->total_v = 0.0;
+        cpi->total = 0.0;
+        cpi->totalp_y = 0.0;
+        cpi->totalp_u = 0.0;
+        cpi->totalp_v = 0.0;
+        cpi->totalp = 0.0;
+        cpi->tot_recode_hits = 0;
+        cpi->summed_quality = 0;
+        cpi->summed_weights = 0;
+    }
+
+    if (cpi->b_calculate_ssimg)
+    {
+        cpi->total_ssimg_y = 0;
+        cpi->total_ssimg_u = 0;
+        cpi->total_ssimg_v = 0;
+        cpi->total_ssimg_all = 0;
+    }
+
+#ifndef LLONG_MAX
+#define LLONG_MAX  9223372036854775807LL
+#endif
+    cpi->first_time_stamp_ever = LLONG_MAX;
+
+#endif
+
+    cpi->frames_till_gf_update_due      = 0;
+    cpi->key_frame_count              = 1;
+    cpi->tot_key_frame_bits            = 0;
+
+    cpi->ni_av_qi                     = cpi->oxcf.worst_allowed_q;
+    cpi->ni_tot_qi                    = 0;
+    cpi->ni_frames                   = 0;
+    cpi->total_byte_count             = 0;
+
+    cpi->drop_frame                  = 0;
+    cpi->drop_count                  = 0;
+    cpi->max_drop_count               = 0;
+    cpi->max_consec_dropped_frames     = 4;
+
+    cpi->rate_correction_factor         = 1.0;
+    cpi->key_frame_rate_correction_factor = 1.0;
+    cpi->gf_rate_correction_factor  = 1.0;
+    cpi->est_max_qcorrection_factor  = 1.0;
+
+    cpi->mb.mvcost[0] = &cpi->mb.mvcosts[0][mv_max+1];
+    cpi->mb.mvcost[1] = &cpi->mb.mvcosts[1][mv_max+1];
+    cpi->mb.mvsadcost[0] = &cpi->mb.mvsadcosts[0][mv_max+1];
+    cpi->mb.mvsadcost[1] = &cpi->mb.mvsadcosts[1][mv_max+1];
+
+    cal_mvsadcosts(cpi->mb.mvsadcost);
+
+    for (i = 0; i < KEY_FRAME_CONTEXT; i++)
+    {
+        cpi->prior_key_frame_size[i]     = cpi->intra_frame_target;
+        cpi->prior_key_frame_distance[i] = (int)cpi->output_frame_rate;
+    }
+
+    cpi->check_freq[0] = 15;
+    cpi->check_freq[1] = 15;
+
+#ifdef OUTPUT_YUV_SRC
+    yuv_file = fopen("bd.yuv", "ab");
+#endif
+
+#if 0
+    framepsnr = fopen("framepsnr.stt", "a");
+    kf_list = fopen("kf_list.stt", "w");
+#endif
+
+    cpi->output_pkt_list = oxcf->output_pkt_list;
+
+#if !(CONFIG_REALTIME_ONLY)
+
+    if (cpi->pass == 1)
+    {
+        vp8_init_first_pass(cpi);
+    }
+    else if (cpi->pass == 2)
+    {
+        cpi->stats_in = oxcf->two_pass_stats_in.buf;
+        cpi->stats_in_end = cpi->stats_in
+                            + oxcf->two_pass_stats_in.sz / sizeof(FIRSTPASS_STATS)
+                            - 1;
+        vp8_init_second_pass(cpi);
+    }
+
+#endif
+
+    if (cpi->compressor_speed == 2)
+    {
+        cpi->cpu_freq            = 0; //vp8_get_processor_freq();
+        cpi->avg_encode_time      = 0;
+        cpi->avg_pick_mode_time    = 0;
+    }
+
+    vp8_set_speed_features(cpi);
+
+    // Set starting values of RD threshold multipliers (128 = *1)
+    for (i = 0; i < MAX_MODES; i++)
+    {
+        cpi->rd_thresh_mult[i] = 128;
+    }
+
+#ifdef ENTROPY_STATS
+    init_mv_ref_counts();
+#endif
+
+    vp8cx_create_encoder_threads(cpi);
+
+    cpi->fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16);
+    cpi->fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16);
+    cpi->fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar16x16);
+    cpi->fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16x3);
+    cpi->fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16x4d);
+
+#if !(CONFIG_REALTIME_ONLY)
+    cpi->full_search_sad = SEARCH_INVOKE(&cpi->rtcd.search, full_search);
+#endif
+    cpi->diamond_search_sad = SEARCH_INVOKE(&cpi->rtcd.search, diamond_search);
+
+    cpi->ready_for_new_frame = 1;
+
+    cpi->source_encode_index = 0;
+
+    // make sure frame 1 is okay
+    cpi->error_bins[0] = cpi->common.MBs;
+
+    //vp8cx_init_quantizer() is first called here. Add check in vp8cx_frame_init_quantizer() so that vp8cx_init_quantizer is only called later
+    //when needed. This will avoid unnecessary calls of vp8cx_init_quantizer() for every frame.
+    vp8cx_init_quantizer(cpi);
+    {
+        vp8_init_loop_filter(cm);
+        cm->last_frame_type = KEY_FRAME;
+        cm->last_filter_type = cm->filter_type;
+        cm->last_sharpness_level = cm->sharpness_level;
+    }
+    cpi->common.error.setjmp = 0;
+    return (VP8_PTR) cpi;
+
+}
+
+
+void vp8_remove_compressor(VP8_PTR *ptr)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(*ptr);
+
+    if (!cpi)
+        return;
+
+    if (cpi && (cpi->common.current_video_frame > 0))
+    {
+#if !(CONFIG_REALTIME_ONLY)
+
+        if (cpi->pass == 2)
+        {
+            vp8_end_second_pass(cpi);
+        }
+
+#endif
+
+#ifdef ENTROPY_STATS
+        print_context_counters();
+        print_tree_update_probs();
+        print_mode_context();
+#endif
+
+#if CONFIG_PSNR
+
+        if (cpi->pass != 1)
+        {
+            FILE *f = fopen("opsnr.stt", "a");
+            double time_encoded = (cpi->source_end_time_stamp - cpi->first_time_stamp_ever) / 10000000.000;
+            double total_encode_time = (cpi->time_receive_data + cpi->time_compress_data)   / 1000.000;
+            double dr = (double)cpi->bytes * (double) 8 / (double)1000  / time_encoded;
+
+            if (cpi->b_calculate_psnr)
+            {
+                double samples = 3.0 / 2 * cpi->count * cpi->common.last_frame.y_width * cpi->common.last_frame.y_height;
+                double total_psnr = vp8_mse2psnr(samples, 255.0, cpi->total_sq_error);
+                double total_psnr2 = vp8_mse2psnr(samples, 255.0, cpi->total_sq_error2);
+                double total_ssim = 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
+
+                fprintf(f, "Bitrate\AVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\tVPXSSIM\t  Time(us)\n");
+                fprintf(f, "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f %8.0f\n",
+                        dr, cpi->total / cpi->count, total_psnr, cpi->totalp / cpi->count, total_psnr2, total_ssim,
+                        total_encode_time);
+            }
+
+            if (cpi->b_calculate_ssimg)
+            {
+                fprintf(f, "BitRate\tSSIM_Y\tSSIM_U\tSSIM_V\tSSIM_A\t  Time(us)\n");
+                fprintf(f, "%7.3f\t%6.4f\t%6.4f\t%6.4f\t%6.4f\t%8.0f\n", dr,
+                        cpi->total_ssimg_y / cpi->count, cpi->total_ssimg_u / cpi->count,
+                        cpi->total_ssimg_v / cpi->count, cpi->total_ssimg_all / cpi->count, total_encode_time);
+            }
+
+            fclose(f);
+#if 0
+            f = fopen("qskip.stt", "a");
+            fprintf(f, "minq:%d -maxq:%d skipture:skipfalse = %d:%d\n", cpi->oxcf.best_allowed_q, cpi->oxcf.worst_allowed_q, skiptruecount, skipfalsecount);
+            fclose(f);
+#endif
+
+        }
+
+#endif
+
+
+#ifdef SPEEDSTATS
+
+        if (cpi->compressor_speed == 2)
+        {
+            int i;
+            FILE *f = fopen("cxspeed.stt", "a");
+            cnt_pm /= cpi->common.MBs;
+
+            for (i = 0; i < 16; i++)
+                fprintf(f, "%5d", frames_at_speed[i]);
+
+            fprintf(f, "\n");
+            //fprintf(f, "%10d PM %10d %10d %10d EF %10d %10d %10d\n", cpi->Speed, cpi->avg_pick_mode_time, (tot_pm/cnt_pm), cnt_pm,  cpi->avg_encode_time, 0, 0);
+            fclose(f);
+        }
+
+#endif
+
+
+#ifdef MODE_STATS
+        {
+            extern int count_mb_seg[4];
+            FILE *f = fopen("modes.stt", "a");
+            double dr = (double)cpi->oxcf.frame_rate * (double)bytes * (double)8 / (double)count / (double)1000 ;
+            fprintf(f, "intra_mode in Intra Frames:\n");
+            fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4]);
+            fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], uv_modes[2], uv_modes[3]);
+            fprintf(f, "B: ");
+            {
+                int i;
+
+                for (i = 0; i < 10; i++)
+                    fprintf(f, "%8d, ", b_modes[i]);
+
+                fprintf(f, "\n");
+
+            }
+
+            fprintf(f, "Modes in Inter Frames:\n");
+            fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n",
+                    inter_y_modes[0], inter_y_modes[1], inter_y_modes[2], inter_y_modes[3], inter_y_modes[4],
+                    inter_y_modes[5], inter_y_modes[6], inter_y_modes[7], inter_y_modes[8], inter_y_modes[9]);
+            fprintf(f, "UV:%8d, %8d, %8d, %8d\n", inter_uv_modes[0], inter_uv_modes[1], inter_uv_modes[2], inter_uv_modes[3]);
+            fprintf(f, "B: ");
+            {
+                int i;
+
+                for (i = 0; i < 15; i++)
+                    fprintf(f, "%8d, ", inter_b_modes[i]);
+
+                fprintf(f, "\n");
+
+            }
+            fprintf(f, "P:%8d, %8d, %8d, %8d\n", count_mb_seg[0], count_mb_seg[1], count_mb_seg[2], count_mb_seg[3]);
+            fprintf(f, "PB:%8d, %8d, %8d, %8d\n", inter_b_modes[LEFT4X4], inter_b_modes[ABOVE4X4], inter_b_modes[ZERO4X4], inter_b_modes[NEW4X4]);
+
+
+
+            fclose(f);
+        }
+#endif
+
+#ifdef ENTROPY_STATS
+        {
+            int i, j, k;
+            FILE *fmode = fopen("modecontext.c", "w");
+
+            fprintf(fmode, "\n#include \"entropymode.h\"\n\n");
+            fprintf(fmode, "const unsigned int vp8_kf_default_bmode_counts ");
+            fprintf(fmode, "[VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES] =\n{\n");
+
+            for (i = 0; i < 10; i++)
+            {
+
+                fprintf(fmode, "    { //Above Mode :  %d\n", i);
+
+                for (j = 0; j < 10; j++)
+                {
+
+                    fprintf(fmode, "        {");
+
+                    for (k = 0; k < 10; k++)
+                    {
+                        if (!intra_mode_stats[i][j][k])
+                            fprintf(fmode, " %5d, ", 1);
+                        else
+                            fprintf(fmode, " %5d, ", intra_mode_stats[i][j][k]);
+                    }
+
+                    fprintf(fmode, "}, // left_mode %d\n", j);
+
+                }
+
+                fprintf(fmode, "    },\n");
+
+            }
+
+            fprintf(fmode, "};\n");
+        }
+#endif
+
+
+#if defined(SECTIONBITS_OUTPUT)
+
+        if (0)
+        {
+            int i;
+            FILE *f = fopen("tokenbits.stt", "a");
+
+            for (i = 0; i < 28; i++)
+                fprintf(f, "%8d", (int)(Sectionbits[i] / 256));
+
+            fprintf(f, "\n");
+            fclose(f);
+        }
+
+#endif
+
+#if 0
+        {
+            printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000);
+            printf("\n_frames recive_data encod_mb_row compress_frame  Total\n");
+            printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame, cpi->time_receive_data / 1000, cpi->time_encode_mb_row / 1000, cpi->time_compress_data / 1000, (cpi->time_receive_data + cpi->time_compress_data) / 1000);
+        }
+#endif
+
+    }
+
+    vp8cx_remove_encoder_threads(cpi);
+
+    vp8_dealloc_compressor_data(cpi);
+    vpx_free(cpi->mb.ss);
+    vpx_free(cpi->tok);
+    vpx_free(cpi->rdtok);
+    vpx_free(cpi->cyclic_refresh_map);
+
+    vp8_remove_common(&cpi->common);
+    vpx_free(cpi);
+    *ptr = 0;
+
+#ifdef OUTPUT_YUV_SRC
+    fclose(yuv_file);
+#endif
+
+#if 0
+
+    if (keyfile)
+        fclose(keyfile);
+
+    if (framepsnr)
+        fclose(framepsnr);
+
+    if (kf_list)
+        fclose(kf_list);
+
+#endif
+
+}
+
+
+static uint64_t calc_plane_error(unsigned char *orig, int orig_stride,
+                                 unsigned char *recon, int recon_stride,
+                                 unsigned int cols, unsigned int rows,
+                                 vp8_variance_rtcd_vtable_t *rtcd)
+{
+    unsigned int row, col;
+    uint64_t total_sse = 0;
+    int diff;
+
+    for (row = 0; row + 16 <= rows; row += 16)
+    {
+        for (col = 0; col + 16 <= cols; col += 16)
+        {
+            unsigned int sse;
+
+            VARIANCE_INVOKE(rtcd, mse16x16)(orig + col, orig_stride,
+                                            recon + col, recon_stride,
+                                            &sse);
+            total_sse += sse;
+        }
+
+        /* Handle odd-sized width */
+        if (col < cols)
+        {
+            unsigned int   border_row, border_col;
+            unsigned char *border_orig = orig;
+            unsigned char *border_recon = recon;
+
+            for (border_row = 0; border_row < 16; border_row++)
+            {
+                for (border_col = col; border_col < cols; border_col++)
+                {
+                    diff = border_orig[border_col] - border_recon[border_col];
+                    total_sse += diff * diff;
+                }
+
+                border_orig += orig_stride;
+                border_recon += recon_stride;
+            }
+        }
+
+        orig += orig_stride * 16;
+        recon += recon_stride * 16;
+    }
+
+    /* Handle odd-sized height */
+    for (; row < rows; row++)
+    {
+        for (col = 0; col < cols; col++)
+        {
+            diff = orig[col] - recon[col];
+            total_sse += diff * diff;
+        }
+
+        orig += orig_stride;
+        recon += recon_stride;
+    }
+
+    return total_sse;
+}
+
+
+static void generate_psnr_packet(VP8_COMP *cpi)
+{
+    YV12_BUFFER_CONFIG      *orig = cpi->Source;
+    YV12_BUFFER_CONFIG      *recon = cpi->common.frame_to_show;
+    struct vpx_codec_cx_pkt  pkt;
+    uint64_t                 sse;
+    int                      i;
+    unsigned int             width = cpi->common.Width;
+    unsigned int             height = cpi->common.Height;
+
+    pkt.kind = VPX_CODEC_PSNR_PKT;
+    sse = calc_plane_error(orig->y_buffer, orig->y_stride,
+                           recon->y_buffer, recon->y_stride,
+                           width, height,
+                           IF_RTCD(&cpi->rtcd.variance));
+    pkt.data.psnr.sse[0] = sse;
+    pkt.data.psnr.sse[1] = sse;
+    pkt.data.psnr.samples[0] = width * height;
+    pkt.data.psnr.samples[1] = width * height;
+
+    width = (width + 1) / 2;
+    height = (height + 1) / 2;
+
+    sse = calc_plane_error(orig->u_buffer, orig->uv_stride,
+                           recon->u_buffer, recon->uv_stride,
+                           width, height,
+                           IF_RTCD(&cpi->rtcd.variance));
+    pkt.data.psnr.sse[0] += sse;
+    pkt.data.psnr.sse[2] = sse;
+    pkt.data.psnr.samples[0] += width * height;
+    pkt.data.psnr.samples[2] = width * height;
+
+    sse = calc_plane_error(orig->v_buffer, orig->uv_stride,
+                           recon->v_buffer, recon->uv_stride,
+                           width, height,
+                           IF_RTCD(&cpi->rtcd.variance));
+    pkt.data.psnr.sse[0] += sse;
+    pkt.data.psnr.sse[3] = sse;
+    pkt.data.psnr.samples[0] += width * height;
+    pkt.data.psnr.samples[3] = width * height;
+
+    for (i = 0; i < 4; i++)
+        pkt.data.psnr.psnr[i] = vp8_mse2psnr(pkt.data.psnr.samples[i], 255.0,
+                                             pkt.data.psnr.sse[i]);
+
+    vpx_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
+}
+
+
+int vp8_use_as_reference(VP8_PTR ptr, int ref_frame_flags)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    if (ref_frame_flags > 7)
+        return -1 ;
+
+    cpi->ref_frame_flags = ref_frame_flags;
+    return 0;
+}
+int vp8_update_reference(VP8_PTR ptr, int ref_frame_flags)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+
+    if (ref_frame_flags > 7)
+        return -1 ;
+
+    cpi->common.refresh_golden_frame = 0;
+    cpi->common.refresh_alt_ref_frame = 0;
+    cpi->common.refresh_last_frame   = 0;
+
+    if (ref_frame_flags & VP8_LAST_FLAG)
+        cpi->common.refresh_last_frame = 1;
+
+    if (ref_frame_flags & VP8_GOLD_FLAG)
+        cpi->common.refresh_golden_frame = 1;
+
+    if (ref_frame_flags & VP8_ALT_FLAG)
+        cpi->common.refresh_alt_ref_frame = 1;
+
+    return 0;
+}
+
+int vp8_get_reference(VP8_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+    VP8_COMMON *cm = &cpi->common;
+
+    if (ref_frame_flag == VP8_LAST_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->last_frame, sd);
+
+    else if (ref_frame_flag == VP8_GOLD_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->golden_frame, sd);
+
+    else if (ref_frame_flag == VP8_ALT_FLAG)
+        vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, sd);
+
+    else
+        return -1;
+
+    return 0;
+}
+int vp8_set_reference(VP8_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+{
+    VP8_COMP *cpi = (VP8_COMP *)(ptr);
+    VP8_COMMON *cm = &cpi->common;
+
+    if (ref_frame_flag == VP8_LAST_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->last_frame);
+
+    else if (ref_frame_flag == VP8_GOLD_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->golden_frame);
+
+    else if (ref_frame_flag == VP8_ALT_FLAG)
+        vp8_yv12_copy_frame_ptr(sd, &cm->alt_ref_frame);
+
+    else
+        return -1;
+
+    return 0;
+}
+int vp8_update_entropy(VP8_PTR comp, int update)
+{
+    VP8_COMP *cpi = (VP8_COMP *) comp;
+    VP8_COMMON *cm = &cpi->common;
+    cm->refresh_entropy_probs = update;
+
+    return 0;
+}
+
+void vp8_write_yuv_frame(const char *name, YV12_BUFFER_CONFIG *s)
+{
+    FILE *yuv_file = fopen(name, "ab");
+    unsigned char *src = s->y_buffer;
+    int h = s->y_height;
+
+    do
+    {
+        fwrite(src, s->y_width, 1,  yuv_file);
+        src += s->y_stride;
+    }
+    while (--h);
+
+    src = s->u_buffer;
+    h = s->uv_height;
+
+    do
+    {
+        fwrite(src, s->uv_width, 1,  yuv_file);
+        src += s->uv_stride;
+    }
+    while (--h);
+
+    src = s->v_buffer;
+    h = s->uv_height;
+
+    do
+    {
+        fwrite(src, s->uv_width, 1, yuv_file);
+        src += s->uv_stride;
+    }
+    while (--h);
+
+    fclose(yuv_file);
+}
+
+static void scale_and_extend_source(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    // are we resizing the image
+    if (cm->horiz_scale != 0 || cm->vert_scale != 0)
+    {
+#if CONFIG_SPATIAL_RESAMPLING
+        int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
+        int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+        int tmp_height;
+
+        if (cm->vert_scale == 3)
+            tmp_height = 9;
+        else
+            tmp_height = 11;
+
+        Scale2Ratio(cm->horiz_scale, &hr, &hs);
+        Scale2Ratio(cm->vert_scale, &vr, &vs);
+
+        vp8_scale_frame(sd, &cpi->scaled_source, cm->temp_scale_frame.y_buffer,
+                        tmp_height, hs, hr, vs, vr, 0);
+
+        cpi->Source = &cpi->scaled_source;
+#endif
+    }
+    // we may need to copy to a buffer so we can extend the image...
+    else if (cm->Width != cm->last_frame.y_width ||
+             cm->Height != cm->last_frame.y_height)
+    {
+        //vp8_yv12_copy_frame_ptr(sd, &cpi->scaled_source);
+#if HAVE_ARMV7
+        vp8_yv12_copy_src_frame_func_neon(sd, &cpi->scaled_source);
+#else
+        vp8_yv12_copy_frame_ptr(sd, &cpi->scaled_source);
+#endif
+
+        cpi->Source = &cpi->scaled_source;
+    }
+
+    vp8_extend_to_multiple_of16(cpi->Source, cm->Width, cm->Height);
+
+}
+static void resize_key_frame(VP8_COMP *cpi)
+{
+#if CONFIG_SPATIAL_RESAMPLING
+    VP8_COMMON *cm = &cpi->common;
+
+    // Do we need to apply resampling for one pass cbr.
+    // In one pass this is more limited than in two pass cbr
+    // The test and any change is only made one per key frame sequence
+    if (cpi->oxcf.allow_spatial_resampling && (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER))
+    {
+        int UNINITIALIZED_IS_SAFE(hr), UNINITIALIZED_IS_SAFE(hs);
+        int UNINITIALIZED_IS_SAFE(vr), UNINITIALIZED_IS_SAFE(vs);
+        int new_width, new_height;
+
+        // If we are below the resample DOWN watermark then scale down a notch.
+        if (cpi->buffer_level < (cpi->oxcf.resample_down_water_mark * cpi->oxcf.optimal_buffer_level / 100))
+        {
+            cm->horiz_scale = (cm->horiz_scale < ONETWO) ? cm->horiz_scale + 1 : ONETWO;
+            cm->vert_scale = (cm->vert_scale < ONETWO) ? cm->vert_scale + 1 : ONETWO;
+        }
+        // Should we now start scaling back up
+        else if (cpi->buffer_level > (cpi->oxcf.resample_up_water_mark * cpi->oxcf.optimal_buffer_level / 100))
+        {
+            cm->horiz_scale = (cm->horiz_scale > NORMAL) ? cm->horiz_scale - 1 : NORMAL;
+            cm->vert_scale = (cm->vert_scale > NORMAL) ? cm->vert_scale - 1 : NORMAL;
+        }
+
+        // Get the new hieght and width
+        Scale2Ratio(cm->horiz_scale, &hr, &hs);
+        Scale2Ratio(cm->vert_scale, &vr, &vs);
+        new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs;
+        new_height = ((vs - 1) + (cpi->oxcf.Height * vr)) / vs;
+
+        // If the image size has changed we need to reallocate the buffers
+        // and resample the source image
+        if ((cm->Width != new_width) || (cm->Height != new_height))
+        {
+            cm->Width = new_width;
+            cm->Height = new_height;
+            vp8_alloc_compressor_data(cpi);
+            scale_and_extend_source(cpi->un_scaled_source, cpi);
+        }
+    }
+
+#endif
+}
+// return of 0 means drop frame
+static int pick_frame_size(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    // First Frame is a special case
+    if (cm->current_video_frame == 0)
+    {
+#if !(CONFIG_REALTIME_ONLY)
+
+        if (cpi->pass == 2)
+            vp8_calc_auto_iframe_target_size(cpi);
+
+        // 1 Pass there is no information on which to base size so use bandwidth per second * fixed fraction
+        else
+#endif
+            cpi->this_frame_target = cpi->oxcf.target_bandwidth / 2;
+
+        // in error resilient mode the first frame is bigger since it likely contains
+        // all the static background
+        if (cpi->oxcf.error_resilient_mode == 1 || (cpi->compressor_speed == 2))
+        {
+            cpi->this_frame_target *= 3;      // 5;
+        }
+
+        // Key frame from VFW/auto-keyframe/first frame
+        cm->frame_type = KEY_FRAME;
+
+    }
+    // Auto key frames (Only two pass will enter here)
+    else if (cm->frame_type == KEY_FRAME)
+    {
+        vp8_calc_auto_iframe_target_size(cpi);
+    }
+    // Forced key frames (by interval or an external signal)
+    else if ((cm->frame_flags & FRAMEFLAGS_KEY) ||
+             (cpi->oxcf.auto_key && (cpi->frames_since_key % cpi->key_frame_frequency == 0)))
+    {
+        // Key frame from VFW/auto-keyframe/first frame
+        cm->frame_type = KEY_FRAME;
+
+        resize_key_frame(cpi);
+
+        // Compute target frame size
+        if (cpi->pass != 2)
+            vp8_calc_iframe_target_size(cpi);
+    }
+    else
+    {
+        // INTER frame: compute target frame size
+        cm->frame_type = INTER_FRAME;
+        vp8_calc_pframe_target_size(cpi);
+
+        // Check if we're dropping the frame:
+        if (cpi->drop_frame)
+        {
+            cpi->drop_frame = FALSE;
+            cpi->drop_count++;
+            return 0;
+        }
+    }
+
+    // Note target_size in bits * 256 per MB
+    cpi->target_bits_per_mb = (cpi->this_frame_target * 256) / cpi->common.MBs;
+
+    return 1;
+}
+static void set_quantizer(VP8_COMP *cpi, int Q)
+{
+    VP8_COMMON *cm = &cpi->common;
+    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
+
+    cm->base_qindex = Q;
+
+    cm->y1dc_delta_q = 0;
+    cm->y2dc_delta_q = 0;
+    cm->y2ac_delta_q = 0;
+    cm->uvdc_delta_q = 0;
+    cm->uvac_delta_q = 0;
+
+    // Set Segment specific quatizers
+    mbd->segment_feature_data[MB_LVL_ALT_Q][0] = cpi->segment_feature_data[MB_LVL_ALT_Q][0];
+    mbd->segment_feature_data[MB_LVL_ALT_Q][1] = cpi->segment_feature_data[MB_LVL_ALT_Q][1];
+    mbd->segment_feature_data[MB_LVL_ALT_Q][2] = cpi->segment_feature_data[MB_LVL_ALT_Q][2];
+    mbd->segment_feature_data[MB_LVL_ALT_Q][3] = cpi->segment_feature_data[MB_LVL_ALT_Q][3];
+}
+
+static void update_alt_ref_frame_and_stats(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    // Update the golden frame buffer
+    vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);
+
+    // Select an interval before next GF or altref
+    if (!cpi->auto_gold)
+        cpi->frames_till_gf_update_due = cpi->goldfreq;
+
+    if ((cpi->pass != 2) && cpi->frames_till_gf_update_due)
+    {
+        cpi->current_gf_interval = cpi->frames_till_gf_update_due;
+
+        // Set the bits per frame that we should try and recover in subsequent inter frames
+        // to account for the extra GF spend... note that his does not apply for GF updates
+        // that occur coincident with a key frame as the extra cost of key frames is dealt
+        // with elsewhere.
+
+        cpi->gf_overspend_bits += cpi->projected_frame_size;
+        cpi->non_gf_bitrate_adjustment = cpi->gf_overspend_bits / cpi->frames_till_gf_update_due;
+    }
+
+    // Update data structure that monitors level of reference to last GF
+    vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
+    cm->gf_active_count = cm->mb_rows * cm->mb_cols;
+    // this frame refreshes means next frames don't unless specified by user
+
+    cpi->common.frames_since_golden = 0;
+
+    // Clear the alternate reference update pending flag.
+    cpi->source_alt_ref_pending = FALSE;
+
+    // Set the alternate refernce frame active flag
+    cpi->source_alt_ref_active = TRUE;
+
+
+}
+static void update_golden_frame_and_stats(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    // Update the Golden frame reconstruction buffer if signalled and the GF usage counts.
+    if (cm->refresh_golden_frame)
+    {
+        // Update the golden frame buffer
+        vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);
+
+        // Select an interval before next GF
+        if (!cpi->auto_gold)
+            cpi->frames_till_gf_update_due = cpi->goldfreq;
+
+        if ((cpi->pass != 2) && (cpi->frames_till_gf_update_due > 0))
+        {
+            cpi->current_gf_interval = cpi->frames_till_gf_update_due;
+
+            // Set the bits per frame that we should try and recover in subsequent inter frames
+            // to account for the extra GF spend... note that his does not apply for GF updates
+            // that occur coincident with a key frame as the extra cost of key frames is dealt
+            // with elsewhere.
+            if ((cm->frame_type != KEY_FRAME) && !cpi->source_alt_ref_active)
+            {
+                // Calcluate GF bits to be recovered
+                // Projected size - av frame bits available for inter frames for clip as a whole
+                cpi->gf_overspend_bits += (cpi->projected_frame_size - cpi->inter_frame_target);
+            }
+
+            cpi->non_gf_bitrate_adjustment = cpi->gf_overspend_bits / cpi->frames_till_gf_update_due;
+
+        }
+
+        // Update data structure that monitors level of reference to last GF
+        vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
+        cm->gf_active_count = cm->mb_rows * cm->mb_cols;
+
+        // this frame refreshes means next frames don't unless specified by user
+        cm->refresh_golden_frame = 0;
+        cpi->common.frames_since_golden = 0;
+
+        //if ( cm->frame_type == KEY_FRAME )
+        //{
+        cpi->recent_ref_frame_usage[INTRA_FRAME] = 1;
+        cpi->recent_ref_frame_usage[LAST_FRAME] = 1;
+        cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1;
+        cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1;
+        //}
+        //else
+        //{
+        //  // Carry a potrtion of count over to begining of next gf sequence
+        //  cpi->recent_ref_frame_usage[INTRA_FRAME] >>= 5;
+        //  cpi->recent_ref_frame_usage[LAST_FRAME] >>= 5;
+        //  cpi->recent_ref_frame_usage[GOLDEN_FRAME] >>= 5;
+        //  cpi->recent_ref_frame_usage[ALTREF_FRAME] >>= 5;
+        //}
+
+        // ******** Fixed Q test code only ************
+        // If we are going to use the ALT reference for the next group of frames set a flag to say so.
+        if (cpi->oxcf.fixed_q >= 0 &&
+            cpi->oxcf.play_alternate && !cpi->common.refresh_alt_ref_frame)
+        {
+            cpi->source_alt_ref_pending = TRUE;
+            cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+        }
+
+        if (!cpi->source_alt_ref_pending)
+            cpi->source_alt_ref_active = FALSE;
+
+        // Decrement count down till next gf
+        if (cpi->frames_till_gf_update_due > 0)
+            cpi->frames_till_gf_update_due--;
+
+    }
+    else if (!cpi->common.refresh_alt_ref_frame)
+    {
+        // Decrement count down till next gf
+        if (cpi->frames_till_gf_update_due > 0)
+            cpi->frames_till_gf_update_due--;
+
+        if (cpi->common.frames_till_alt_ref_frame)
+            cpi->common.frames_till_alt_ref_frame --;
+
+        cpi->common.frames_since_golden ++;
+
+        if (cpi->common.frames_since_golden > 1)
+        {
+            cpi->recent_ref_frame_usage[INTRA_FRAME] += cpi->count_mb_ref_frame_usage[INTRA_FRAME];
+            cpi->recent_ref_frame_usage[LAST_FRAME] += cpi->count_mb_ref_frame_usage[LAST_FRAME];
+            cpi->recent_ref_frame_usage[GOLDEN_FRAME] += cpi->count_mb_ref_frame_usage[GOLDEN_FRAME];
+            cpi->recent_ref_frame_usage[ALTREF_FRAME] += cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
+        }
+    }
+}
+
+// This function updates the reference frame probability estimates that
+// will be used during mode selection
+static void update_rd_ref_frame_probs(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+#if 0
+    const int *const rfct = cpi->recent_ref_frame_usage;
+    const int rf_intra = rfct[INTRA_FRAME];
+    const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
+
+    if (cm->frame_type == KEY_FRAME)
+    {
+        cpi->prob_intra_coded = 255;
+        cpi->prob_last_coded  = 128;
+        cpi->prob_gf_coded  = 128;
+    }
+    else if (!(rf_intra + rf_inter))
+    {
+        // This is a trap in case this function is called with cpi->recent_ref_frame_usage[] blank.
+        cpi->prob_intra_coded = 63;
+        cpi->prob_last_coded  = 128;
+        cpi->prob_gf_coded    = 128;
+    }
+    else
+    {
+        cpi->prob_intra_coded = (rf_intra * 255) / (rf_intra + rf_inter);
+
+        if (cpi->prob_intra_coded < 1)
+            cpi->prob_intra_coded = 1;
+
+        if ((cm->frames_since_golden > 0) || cpi->source_alt_ref_active)
+        {
+            cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+
+            if (cpi->prob_last_coded < 1)
+                cpi->prob_last_coded = 1;
+
+            cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+                                 ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+            if (cpi->prob_gf_coded < 1)
+                cpi->prob_gf_coded = 1;
+        }
+    }
+
+#else
+    const int *const rfct = cpi->count_mb_ref_frame_usage;
+    const int rf_intra = rfct[INTRA_FRAME];
+    const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
+
+    if (cm->frame_type == KEY_FRAME)
+    {
+        cpi->prob_intra_coded = 255;
+        cpi->prob_last_coded  = 128;
+        cpi->prob_gf_coded  = 128;
+    }
+    else if (!(rf_intra + rf_inter))
+    {
+        // This is a trap in case this function is called with cpi->recent_ref_frame_usage[] blank.
+        cpi->prob_intra_coded = 63;
+        cpi->prob_last_coded  = 128;
+        cpi->prob_gf_coded    = 128;
+    }
+    else
+    {
+        cpi->prob_intra_coded = (rf_intra * 255) / (rf_intra + rf_inter);
+
+        if (cpi->prob_intra_coded < 1)
+            cpi->prob_intra_coded = 1;
+
+        cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+
+        if (cpi->prob_last_coded < 1)
+            cpi->prob_last_coded = 1;
+
+        cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+                             ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+        if (cpi->prob_gf_coded < 1)
+            cpi->prob_gf_coded = 1;
+    }
+
+    // update reference frame costs since we can do better than what we got last frame.
+
+    if (cpi->common.refresh_alt_ref_frame)
+    {
+        cpi->prob_intra_coded += 40;
+        cpi->prob_last_coded = 200;
+        cpi->prob_gf_coded = 1;
+    }
+    else if (cpi->common.frames_since_golden == 0)
+    {
+        cpi->prob_last_coded = 214;
+        cpi->prob_gf_coded = 1;
+    }
+    else if (cpi->common.frames_since_golden == 1)
+    {
+        cpi->prob_last_coded = 192;
+        cpi->prob_gf_coded = 220;
+    }
+    else if (cpi->source_alt_ref_active)
+    {
+        //int dist = cpi->common.frames_till_alt_ref_frame + cpi->common.frames_since_golden;
+        cpi->prob_gf_coded -= 20;
+
+        if (cpi->prob_gf_coded < 10)
+            cpi->prob_gf_coded = 10;
+    }
+
+#endif
+}
+
+
+// 1 = key, 0 = inter
+static int decide_key_frame(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    int code_key_frame = FALSE;
+
+    cpi->kf_boost = 0;
+
+    if (cpi->Speed > 11)
+        return FALSE;
+
+    // Clear down mmx registers
+    vp8_clear_system_state();  //__asm emms;
+
+    if ((cpi->compressor_speed == 2) && (cpi->Speed >= 5) && (cpi->sf.RD == 0))
+    {
+        double change = 1.0 * abs((int)(cpi->intra_error - cpi->last_intra_error)) / (1 + cpi->last_intra_error);
+        double change2 = 1.0 * abs((int)(cpi->prediction_error - cpi->last_prediction_error)) / (1 + cpi->last_prediction_error);
+        double minerror = cm->MBs * 256;
+
+#if 0
+
+        if (10 * cpi->intra_error / (1 + cpi->prediction_error) < 15
+            && cpi->prediction_error > minerror
+            && (change > .25 || change2 > .25))
+        {
+            FILE *f = fopen("intra_inter.stt", "a");
+
+            if (cpi->prediction_error <= 0)
+                cpi->prediction_error = 1;
+
+            fprintf(f, "%d %d %d %d %14.4f\n",
+                    cm->current_video_frame,
+                    (int) cpi->prediction_error,
+                    (int) cpi->intra_error,
+                    (int)((10 * cpi->intra_error) / cpi->prediction_error),
+                    change);
+
+            fclose(f);
+        }
+
+#endif
+
+        cpi->last_intra_error = cpi->intra_error;
+        cpi->last_prediction_error = cpi->prediction_error;
+
+        if (10 * cpi->intra_error / (1 + cpi->prediction_error) < 15
+            && cpi->prediction_error > minerror
+            && (change > .25 || change2 > .25))
+        {
+            /*(change > 1.4 || change < .75)&& cpi->this_frame_percent_intra > cpi->last_frame_percent_intra + 3*/
+            return TRUE;
+        }
+
+        return FALSE;
+
+    }
+
+    // If the following are true we might as well code a key frame
+    if (((cpi->this_frame_percent_intra == 100) &&
+         (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 2))) ||
+        ((cpi->this_frame_percent_intra > 95) &&
+         (cpi->this_frame_percent_intra >= (cpi->last_frame_percent_intra + 5))))
+    {
+        code_key_frame = TRUE;
+    }
+    // in addition if the following are true and this is not a golden frame then code a key frame
+    // Note that on golden frames there often seems to be a pop in intra useage anyway hence this
+    // restriction is designed to prevent spurious key frames. The Intra pop needs to be investigated.
+    else if (((cpi->this_frame_percent_intra > 60) &&
+              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 2))) ||
+             ((cpi->this_frame_percent_intra > 75) &&
+              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 3 / 2))) ||
+             ((cpi->this_frame_percent_intra > 90) &&
+              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 10))))
+    {
+        if (!cm->refresh_golden_frame)
+            code_key_frame = TRUE;
+    }
+
+    return code_key_frame;
+
+}
+
+#if !(CONFIG_REALTIME_ONLY)
+static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
+{
+    (void) size;
+    (void) dest;
+    (void) frame_flags;
+    set_quantizer(cpi, 26);
+
+    scale_and_extend_source(cpi->un_scaled_source, cpi);
+    vp8_first_pass(cpi);
+}
+#endif
+
+#if 0
+void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
+{
+
+    // write the frame
+    FILE *yframe;
+    int i;
+    char filename[255];
+
+    sprintf(filename, "cx\\y%04d.raw", this_frame);
+    yframe = fopen(filename, "wb");
+
+    for (i = 0; i < frame->y_height; i++)
+        fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe);
+
+    fclose(yframe);
+    sprintf(filename, "cx\\u%04d.raw", this_frame);
+    yframe = fopen(filename, "wb");
+
+    for (i = 0; i < frame->uv_height; i++)
+        fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+
+    fclose(yframe);
+    sprintf(filename, "cx\\v%04d.raw", this_frame);
+    yframe = fopen(filename, "wb");
+
+    for (i = 0; i < frame->uv_height; i++)
+        fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+
+    fclose(yframe);
+}
+#endif
+// return of 0 means drop frame
+
+#if VP8_TEMPORAL_ALT_REF
+static void vp8cx_temp_blur1_c
+(
+    unsigned char **frames,
+    int frame_count,
+    unsigned char *src,
+    unsigned char *dst,
+    int width,
+    int stride,
+    int height,
+    int strength,
+    int *fixed_divide,
+    unsigned char *motion_map_ptr,
+    unsigned char block_size
+)
+{
+    int byte = 0;           // Buffer offset for the current pixel value being filtered
+    int frame = 0;
+    int modifier = 0;
+    int i, j, k;
+    int block_ofset;
+    int Cols, Rows;
+    unsigned char Shift = (block_size == 16) ? 4 : 3;
+
+    Cols = width / block_size;
+    Rows = height / block_size;
+
+    for (i = 0; i < height; i++)
+    {
+        block_ofset = (i >> Shift) * Cols;
+
+        for (j = 0; j < Cols; j ++)
+        {
+            if (motion_map_ptr[block_ofset] > 2)
+            {
+                vpx_memcpy(&dst[byte], &src[byte], block_size);
+                byte += block_size;
+            }
+            else
+            {
+                for (k = 0; k < block_size; k++)
+                {
+                    int accumulator = 0;
+                    int count = 0;
+                    int src_byte = src[byte];
+
+                    for (frame = 0; frame < frame_count; frame++)
+                    {
+                        // get current frame pixel value
+                        int pixel_value = frames[frame][byte];       // int pixel_value = *frameptr;
+
+                        modifier   = src_byte;                       // modifier   = s[byte];
+                        modifier  -= pixel_value;
+                        modifier  *= modifier;
+                        modifier >>= strength;
+                        modifier  *= 3;
+
+                        if (modifier > 16)
+                            modifier = 16;
+
+                        modifier = 16 - modifier;
+
+                        accumulator += modifier * pixel_value;
+
+                        count += modifier;
+                    }
+
+                    accumulator += (count >> 1);
+                    accumulator *= fixed_divide[count];          // accumulator *= ppi->fixed_divide[count];
+                    accumulator >>= 16;
+
+                    dst[byte] = accumulator;        // d[byte] = accumulator;
+
+                    // move to next pixel
+                    byte++;
+                }
+            }
+
+            block_ofset++;
+        }
+
+        // Step byte on over the UMV border to the start of the next line
+        byte += stride - width;
+    }
+}
+
+static void vp8cx_temp_filter_c
+(
+    VP8_COMP *cpi
+)
+{
+    YV12_BUFFER_CONFIG *temp_source_buffer;
+    int *fixed_divide = cpi->fixed_divide;
+
+    int frame = 0;
+    int max_frames = 11;
+
+    int num_frames_backward = 0;
+    int num_frames_forward = 0;
+    int frames_to_blur_backward = 0;
+    int frames_to_blur_forward = 0;
+    int frames_to_blur = 0;
+    int start_frame = 0;
+
+    int strength = cpi->oxcf.arnr_strength;
+
+    int blur_type = cpi->oxcf.arnr_type;
+
+    int new_max_frames = cpi->oxcf.arnr_max_frames;
+
+    if (new_max_frames > 0)
+        max_frames = new_max_frames;
+
+    num_frames_backward = cpi->last_alt_ref_sei - cpi->source_encode_index;
+
+    if (num_frames_backward < 0)
+        num_frames_backward += cpi->oxcf.lag_in_frames;
+
+    num_frames_forward = cpi->oxcf.lag_in_frames - (num_frames_backward + 1);
+
+    switch (blur_type)
+    {
+    case 1:
+        /////////////////////////////////////////
+        // Backward Blur
+
+        frames_to_blur_backward = num_frames_backward;
+
+        if (frames_to_blur_backward >= max_frames)
+            frames_to_blur_backward = max_frames - 1;
+
+        frames_to_blur = frames_to_blur_backward + 1;
+        break;
+
+    case 2:
+        /////////////////////////////////////////
+        // Forward Blur
+
+        frames_to_blur_forward = num_frames_forward;
+
+        if (frames_to_blur_forward >= max_frames)
+            frames_to_blur_forward = max_frames - 1;
+
+        frames_to_blur = frames_to_blur_forward + 1;
+        break;
+
+    case 3:
+        /////////////////////////////////////////
+        // Center Blur
+        frames_to_blur_forward = num_frames_forward;
+        frames_to_blur_backward = num_frames_backward;
+
+        if (frames_to_blur_forward > frames_to_blur_backward)
+            frames_to_blur_forward = frames_to_blur_backward;
+
+        if (frames_to_blur_backward > frames_to_blur_forward)
+            frames_to_blur_backward = frames_to_blur_forward;
+
+        if (frames_to_blur_forward > (max_frames / 2))
+            frames_to_blur_forward = (max_frames / 2);
+
+        if (frames_to_blur_backward > (max_frames / 2))
+            frames_to_blur_backward = (max_frames / 2);
+
+        frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
+        break;
+
+    default:
+        /////////////////////////////////////////
+        // At most 4 frames forward Blur
+        frames_to_blur_forward = 4;
+        frames_to_blur_backward = num_frames_backward;
+
+        if (max_frames > 5)
+        {
+            if ((frames_to_blur_backward + frames_to_blur_forward) >= max_frames)
+            {
+                frames_to_blur_backward = max_frames - frames_to_blur_forward - 1;
+            }
+        }
+        else
+        {
+            frames_to_blur_forward = max_frames - 1;
+            frames_to_blur_backward = 0;
+        }
+
+        frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
+        break;
+    }
+
+    start_frame = (cpi->last_alt_ref_sei + frames_to_blur_forward) % cpi->oxcf.lag_in_frames;
+
+#ifdef DEBUGFWG
+    // DEBUG FWG
+    printf("max:%d FBCK:%d FFWD:%d ftb:%d ftbbck:%d ftbfwd:%d sei:%d lasei:%d start:%d"
+           , max_frames
+           , num_frames_backward
+           , num_frames_forward
+           , frames_to_blur
+           , frames_to_blur_backward
+           , frames_to_blur_forward
+           , cpi->source_encode_index
+           , cpi->last_alt_ref_sei
+           , start_frame);
+#endif
+
+    for (frame = 0; frame < frames_to_blur; frame++)
+    {
+        int which_buffer =  start_frame - frame;
+
+        if (which_buffer < 0)
+            which_buffer += cpi->oxcf.lag_in_frames;
+
+        cpi->frames[frame] = cpi->src_buffer[which_buffer].source_buffer.y_buffer;
+    }
+
+    temp_source_buffer = &cpi->src_buffer[cpi->last_alt_ref_sei].source_buffer;
+
+    // Blur Y
+    vp8cx_temp_blur1_c(
+        cpi->frames,
+        frames_to_blur,
+        temp_source_buffer->y_buffer,  // cpi->Source->y_buffer,
+        cpi->alt_ref_buffer.source_buffer.y_buffer,  // cpi->Source->y_buffer,
+        temp_source_buffer->y_width,
+        temp_source_buffer->y_stride,
+        temp_source_buffer->y_height,
+        //temp_source_buffer->y_height * temp_source_buffer->y_stride,
+        strength,
+        fixed_divide,
+        cpi->fp_motion_map, 16);
+
+    for (frame = 0; frame < frames_to_blur; frame++)
+    {
+        int which_buffer =  cpi->last_alt_ref_sei - frame;
+
+        if (which_buffer < 0)
+            which_buffer += cpi->oxcf.lag_in_frames;
+
+        cpi->frames[frame] = cpi->src_buffer[which_buffer].source_buffer.u_buffer;
+    }
+
+    // Blur U
+    vp8cx_temp_blur1_c(
+        cpi->frames,
+        frames_to_blur,
+        temp_source_buffer->u_buffer,
+        cpi->alt_ref_buffer.source_buffer.u_buffer,  // cpi->Source->u_buffer,
+        temp_source_buffer->uv_width,
+        temp_source_buffer->uv_stride,
+        temp_source_buffer->uv_height,
+        //temp_source_buffer->uv_height * temp_source_buffer->uv_stride,
+        strength,
+        fixed_divide,
+        cpi->fp_motion_map, 8);
+
+    for (frame = 0; frame < frames_to_blur; frame++)
+    {
+        int which_buffer =  cpi->last_alt_ref_sei - frame;
+
+        if (which_buffer < 0)
+            which_buffer += cpi->oxcf.lag_in_frames;
+
+        cpi->frames[frame] = cpi->src_buffer[which_buffer].source_buffer.v_buffer;
+    }
+
+    // Blur V
+    vp8cx_temp_blur1_c(
+        cpi->frames,
+        frames_to_blur,
+        temp_source_buffer->v_buffer,
+        cpi->alt_ref_buffer.source_buffer.v_buffer,  // cpi->Source->v_buffer,
+        temp_source_buffer->uv_width,
+        temp_source_buffer->uv_stride,
+        //temp_source_buffer->uv_height * temp_source_buffer->uv_stride,
+        temp_source_buffer->uv_height,
+        strength,
+        fixed_divide,
+        cpi->fp_motion_map, 8);
+}
+#endif
+
+
+static void encode_frame_to_data_rate(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
+{
+    int Q;
+    int frame_over_shoot_limit;
+    int frame_under_shoot_limit;
+
+    int Loop = FALSE;
+    int loop_count;
+    int this_q;
+    int last_zbin_oq;
+
+    int q_low;
+    int q_high;
+    int zbin_oq_high;
+    int zbin_oq_low = 0;
+    int top_index;
+    int bottom_index;
+    VP8_COMMON *cm = &cpi->common;
+    int active_worst_qchanged = FALSE;
+
+    int overshoot_seen = FALSE;
+    int undershoot_seen = FALSE;
+    int drop_mark = cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100;
+    int drop_mark75 = drop_mark * 2 / 3;
+    int drop_mark50 = drop_mark / 4;
+    int drop_mark25 = drop_mark / 8;
+
+    // Clear down mmx registers to allow floating point in what follows
+    vp8_clear_system_state();
+
+    // Test code for segmentation of gf/arf (0,0)
+    //segmentation_test_function((VP8_PTR) cpi);
+
+    // For an alt ref frame in 2 pass we skip the call to the second pass function that sets the target bandwidth
+#if !(CONFIG_REALTIME_ONLY)
+
+    if (cpi->pass == 2)
+    {
+        if (cpi->common.refresh_alt_ref_frame)
+        {
+            cpi->per_frame_bandwidth = cpi->gf_bits;                           // Per frame bit target for the alt ref frame
+            cpi->target_bandwidth = cpi->gf_bits * cpi->output_frame_rate;      // per second target bitrate
+        }
+    }
+    else
+#endif
+        cpi->per_frame_bandwidth  = (int)(cpi->target_bandwidth / cpi->output_frame_rate);
+
+    // Default turn off buffer to buffer copying
+    cm->copy_buffer_to_gf = 0;
+    cm->copy_buffer_to_arf = 0;
+
+    // Clear zbin over-quant value and mode boost values.
+    cpi->zbin_over_quant = 0;
+    cpi->zbin_mode_boost = 0;
+
+    // Enable mode based tweaking of the zbin
+    cpi->zbin_mode_boost_enabled = TRUE;
+
+    // Current default encoder behaviour for the altref sign bias
+    if (cpi->source_alt_ref_active)
+        cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1;
+    else
+        cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 0;
+
+    // Check to see if a key frame is signalled
+    // For two pass with auto key frame enabled cm->frame_type may already be set, but not for one pass.
+    if ((cm->current_video_frame == 0) ||
+        (cm->frame_flags & FRAMEFLAGS_KEY) ||
+        (cpi->oxcf.auto_key && (cpi->frames_since_key % cpi->key_frame_frequency == 0)))
+    {
+        // Key frame from VFW/auto-keyframe/first frame
+        cm->frame_type = KEY_FRAME;
+    }
+
+    // Set default state for segment and mode based loop filter update flags
+    cpi->mb.e_mbd.update_mb_segmentation_map = 0;
+    cpi->mb.e_mbd.update_mb_segmentation_data = 0;
+    cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
+
+    // Set various flags etc to special state if it is a key frame
+    if (cm->frame_type == KEY_FRAME)
+    {
+        int i;
+
+        // If segmentation is enabled force a map update for key frames
+        if (cpi->mb.e_mbd.segmentation_enabled)
+        {
+            cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+            cpi->mb.e_mbd.update_mb_segmentation_data = 1;
+        }
+
+        // If mode or reference frame based loop filter deltas are enabled then force an update for key frames.
+        if (cpi->mb.e_mbd.mode_ref_lf_delta_enabled)
+        {
+            cpi->mb.e_mbd.mode_ref_lf_delta_update = 1;
+        }
+
+        // The alternate reference frame cannot be active for a key frame
+        cpi->source_alt_ref_active = FALSE;
+
+        // Reset the RD threshold multipliers to default of * 1 (128)
+        for (i = 0; i < MAX_MODES; i++)
+        {
+            cpi->rd_thresh_mult[i] = 128;
+        }
+    }
+
+    // Test code for segmentation
+    //if ( (cm->frame_type == KEY_FRAME) || ((cm->current_video_frame % 2) == 0))
+    //if ( (cm->current_video_frame % 2) == 0 )
+    //  enable_segmentation((VP8_PTR)cpi);
+    //else
+    //  disable_segmentation((VP8_PTR)cpi);
+
+#if 0
+    // Experimental code for lagged compress and one pass
+    // Initialise one_pass GF frames stats
+    // Update stats used for GF selection
+    //if ( cpi->pass == 0 )
+    {
+        cpi->one_pass_frame_index = cm->current_video_frame % MAX_LAG_BUFFERS;
+
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frames_so_far = 0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_intra_error = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_coded_error = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_pcnt_inter = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_pcnt_motion = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvr = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvr_abs = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvc = 0.0;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index ].frame_mvc_abs = 0.0;
+    }
+#endif
+
+    update_rd_ref_frame_probs(cpi);
+
+    if (cpi->drop_frames_allowed)
+    {
+        // The reset to decimation 0 is only done here for one pass.
+        // Once it is set two pass leaves decimation on till the next kf.
+        if ((cpi->buffer_level > drop_mark) && (cpi->decimation_factor > 0))
+            cpi->decimation_factor --;
+
+        if (cpi->buffer_level > drop_mark75 && cpi->decimation_factor > 0)
+            cpi->decimation_factor = 1;
+
+        else if (cpi->buffer_level < drop_mark25 && (cpi->decimation_factor == 2 || cpi->decimation_factor == 3))
+        {
+            cpi->decimation_factor = 3;
+        }
+        else if (cpi->buffer_level < drop_mark50 && (cpi->decimation_factor == 1 || cpi->decimation_factor == 2))
+        {
+            cpi->decimation_factor = 2;
+        }
+        else if (cpi->buffer_level < drop_mark75 && (cpi->decimation_factor == 0 || cpi->decimation_factor == 1))
+        {
+            cpi->decimation_factor = 1;
+        }
+
+        //vpx_log("Encoder: Decimation Factor: %d \n",cpi->decimation_factor);
+    }
+
+    // The following decimates the frame rate according to a regular pattern (i.e. to 1/2 or 2/3 frame rate)
+    // This can be used to help prevent buffer under-run in CBR mode. Alternatively it might be desirable in
+    // some situations to drop frame rate but throw more bits at each frame.
+    //
+    // Note that dropping a key frame can be problematic if spatial resampling is also active
+    if (cpi->decimation_factor > 0)
+    {
+        switch (cpi->decimation_factor)
+        {
+        case 1:
+            cpi->per_frame_bandwidth  = cpi->per_frame_bandwidth * 3 / 2;
+            break;
+        case 2:
+            cpi->per_frame_bandwidth  = cpi->per_frame_bandwidth * 5 / 4;
+            break;
+        case 3:
+            cpi->per_frame_bandwidth  = cpi->per_frame_bandwidth * 5 / 4;
+            break;
+        }
+
+        // Note that we should not throw out a key frame (especially when spatial resampling is enabled).
+        if ((cm->frame_type == KEY_FRAME)) // && cpi->oxcf.allow_spatial_resampling )
+        {
+            cpi->decimation_count = cpi->decimation_factor;
+        }
+        else if (cpi->decimation_count > 0)
+        {
+            cpi->decimation_count --;
+            cpi->bits_off_target += cpi->av_per_frame_bandwidth;
+            cm->current_video_frame++;
+            cpi->frames_since_key++;
+
+#if CONFIG_PSNR
+            cpi->count ++;
+#endif
+
+            cpi->buffer_level = cpi->bits_off_target;
+
+            return;
+        }
+        else
+            cpi->decimation_count = cpi->decimation_factor;
+    }
+
+    // Decide how big to make the frame
+    if (!pick_frame_size(cpi))
+    {
+        cm->current_video_frame++;
+        cpi->frames_since_key++;
+        return;
+    }
+
+    // Reduce active_worst_allowed_q for CBR if our buffer is getting too full.
+    // This has a knock on effect on active best quality as well.
+    // For CBR if the buffer reaches its maximum level then we can no longer
+    // save up bits for later frames so we might as well use them up
+    // on the current frame.
+    if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+        (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level) && cpi->buffered_mode)
+    {
+        int Adjustment = cpi->active_worst_quality / 4;       // Max adjustment is 1/4
+
+        if (Adjustment)
+        {
+            int buff_lvl_step;
+            int tmp_lvl = cpi->buffer_level;
+
+            if (cpi->buffer_level < cpi->oxcf.maximum_buffer_size)
+            {
+                buff_lvl_step = (cpi->oxcf.maximum_buffer_size - cpi->oxcf.optimal_buffer_level) / Adjustment;
+
+                if (buff_lvl_step)
+                {
+                    Adjustment = (cpi->buffer_level - cpi->oxcf.optimal_buffer_level) / buff_lvl_step;
+                    cpi->active_worst_quality -= Adjustment;
+                }
+            }
+            else
+            {
+                cpi->active_worst_quality -= Adjustment;
+            }
+        }
+    }
+
+    // Set an active best quality and if necessary active worst quality
+    if (cpi->pass == 2 || (cm->current_video_frame > 150))
+    {
+        //if ( (cm->frame_type == KEY_FRAME) || cm->refresh_golden_frame  )
+        int Q;
+        int i;
+        int bpm_target;
+
+        Q = cpi->active_worst_quality;
+
+        if ((cm->frame_type == KEY_FRAME) || cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame)
+        {
+            vp8_clear_system_state();
+
+            if (cm->frame_type != KEY_FRAME)
+            {
+                // Where a gf overlays an existing arf then allow active max Q to drift to highest allowed value.
+                //if ( cpi->common.refresh_golden_frame && cpi->source_alt_ref_active )
+                //cpi->active_worst_quality = cpi->worst_quality;
+
+                if (cpi->avg_frame_qindex < cpi->active_worst_quality)
+                    Q = cpi->avg_frame_qindex;
+
+                if (cpi->section_is_low_motion)
+                    bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * ((Q * 3 / 2) + 128)) / 64;
+                else if (cpi->section_is_fast_motion)
+                    bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * (Q + 128)) / 64;
+                else
+                    bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * ((Q * 5 / 4) + 128)) / 64;
+            }
+            // KEY FRAMES
+            else
+            {
+                if (cpi->section_is_low_motion)
+                    bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * (Q + 240)) / 64; // Approx 2.5 to 4.5 where Q has the range 0-127
+                else
+                    bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * (Q + 160)) / 64;
+            }
+
+            for (i = Q; i > 0; i--)
+            {
+                if (bpm_target <= vp8_bits_per_mb[cm->frame_type][i])
+                    break;
+            }
+
+            cpi->active_best_quality = i;
+
+            // this entire section could be replaced by a look up table
+#if 0
+            {
+                int Q, best_q[128];
+
+                for (Q = 0; Q < 128; Q++)
+                {
+                    bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * (Q + 160)) / 64; // Approx 2.5 to 4.5 where Q has the range 0-127
+
+                    for (i = Q; i > 0; i--)
+                    {
+                        if (bpm_target <= vp8_bits_per_mb[cm->frame_type][i])
+                            break;
+                    }
+
+                    best_q[Q] = i;
+                }
+
+                Q += 0;
+            }
+#endif
+
+        }
+        else
+        {
+            vp8_clear_system_state();
+
+            //bpm_target = (vp8_bits_per_mb[cm->frame_type][Q]*(Q+128))/64; // Approx 2 to 4 where Q has the range 0-127
+            bpm_target = (vp8_bits_per_mb[cm->frame_type][Q] * (Q + 192)) / 128; // Approx * 1.5 to 2.5 where Q has range 0-127
+
+            for (i = Q; i > 0; i--)
+            {
+                if (bpm_target <= vp8_bits_per_mb[cm->frame_type][i])
+                    break;
+            }
+
+            cpi->active_best_quality = i;
+        }
+
+        // If CBR and the buffer is as full then it is reasonable to allow higher quality on the frames
+        // to prevent bits just going to waste.
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            // Note that the use of >= here elliminates the risk of a devide by 0 error in the else if clause
+            if (cpi->buffer_level >= cpi->oxcf.maximum_buffer_size)
+                cpi->active_best_quality = cpi->best_quality;
+
+            else if (cpi->buffer_level > cpi->oxcf.optimal_buffer_level)
+            {
+                int Fraction = ((cpi->buffer_level - cpi->oxcf.optimal_buffer_level) * 128) / (cpi->oxcf.maximum_buffer_size - cpi->oxcf.optimal_buffer_level);
+                int min_qadjustment = ((cpi->active_best_quality - cpi->best_quality) * Fraction) / 128;
+
+                cpi->active_best_quality -= min_qadjustment;
+            }
+
+        }
+    }
+
+    // Clip the active best and worst quality values to limits
+    if (cpi->active_worst_quality > cpi->worst_quality)
+        cpi->active_worst_quality = cpi->worst_quality;
+
+    if (cpi->active_best_quality < cpi->best_quality)
+        cpi->active_best_quality = cpi->best_quality;
+    else if (cpi->active_best_quality > cpi->active_worst_quality)
+        cpi->active_best_quality = cpi->active_worst_quality;
+
+    // Determine initial Q to try
+    Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+    last_zbin_oq = cpi->zbin_over_quant;
+
+    // Set highest allowed value for Zbin over quant
+    if (cm->frame_type == KEY_FRAME)
+        zbin_oq_high = 0; //ZBIN_OQ_MAX/16
+    else if (cm->refresh_alt_ref_frame || (cm->refresh_golden_frame && !cpi->source_alt_ref_active))
+        zbin_oq_high = 16;
+    else
+        zbin_oq_high = ZBIN_OQ_MAX;
+
+    // Setup background Q adjustment for error resilliant mode
+    if (cpi->cyclic_refresh_mode_enabled)
+        cyclic_background_refresh(cpi, Q, 0);
+
+    vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit);
+
+    // Limit Q range for the adaptive loop (Values not clipped to range 20-60 as in VP8).
+    bottom_index = cpi->active_best_quality;
+    top_index    = cpi->active_worst_quality;
+
+    vp8_save_coding_context(cpi);
+
+    loop_count = 0;
+
+    q_low  = cpi->best_quality;
+    q_high = cpi->worst_quality;
+
+
+    scale_and_extend_source(cpi->un_scaled_source, cpi);
+#if !(CONFIG_REALTIME_ONLY) && CONFIG_POSTPROC
+
+    if (cpi->oxcf.noise_sensitivity > 0)
+    {
+        unsigned char *src;
+        int l = 0;
+
+        switch (cpi->oxcf.noise_sensitivity)
+        {
+        case 1:
+            l = 20;
+            break;
+        case 2:
+            l = 40;
+            break;
+        case 3:
+            l = 60;
+            break;
+        case 4:
+            l = 80;
+            break;
+        case 5:
+            l = 100;
+            break;
+        case 6:
+            l = 150;
+            break;
+        }
+
+
+        if (cm->frame_type == KEY_FRAME)
+        {
+            vp8_de_noise(cpi->Source, cpi->Source, l , 1,  0, RTCD(postproc));
+            cpi->ppi.frame = 0;
+        }
+        else
+        {
+            vp8_de_noise(cpi->Source, cpi->Source, l , 1,  0, RTCD(postproc));
+
+            src = cpi->Source->y_buffer;
+
+            if (cpi->Source->y_stride < 0)
+            {
+                src += cpi->Source->y_stride * (cpi->Source->y_height - 1);
+            }
+
+            //temp_filter(&cpi->ppi,src,src,
+            //  cm->last_frame.y_width * cm->last_frame.y_height,
+            //  cpi->oxcf.noise_sensitivity);
+        }
+    }
+
+#endif
+
+#ifdef OUTPUT_YUV_SRC
+    vp8_write_yuv_frame(cpi->Source);
+#endif
+
+    do
+    {
+        vp8_clear_system_state();  //__asm emms;
+
+        /*
+        if(cpi->is_src_frame_alt_ref)
+            Q = 127;
+            */
+
+        set_quantizer(cpi, Q);
+        this_q = Q;
+
+        // setup skip prob for costing in mode/mv decision
+        if (cpi->common.mb_no_coeff_skip)
+        {
+            cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
+
+            if (cm->frame_type != KEY_FRAME)
+            {
+                if (cpi->common.refresh_alt_ref_frame)
+                {
+                    if (cpi->last_skip_false_probs[2] != 0)
+                        cpi->prob_skip_false = cpi->last_skip_false_probs[2];
+
+                    /*
+                                        if(cpi->last_skip_false_probs[2]!=0 && abs(Q- cpi->last_skip_probs_q[2])<=16 )
+                       cpi->prob_skip_false = cpi->last_skip_false_probs[2];
+                                        else if (cpi->last_skip_false_probs[2]!=0)
+                       cpi->prob_skip_false = (cpi->last_skip_false_probs[2]  + cpi->prob_skip_false ) / 2;
+                       */
+                }
+                else if (cpi->common.refresh_golden_frame)
+                {
+                    if (cpi->last_skip_false_probs[1] != 0)
+                        cpi->prob_skip_false = cpi->last_skip_false_probs[1];
+
+                    /*
+                                        if(cpi->last_skip_false_probs[1]!=0 && abs(Q- cpi->last_skip_probs_q[1])<=16 )
+                       cpi->prob_skip_false = cpi->last_skip_false_probs[1];
+                                        else if (cpi->last_skip_false_probs[1]!=0)
+                       cpi->prob_skip_false = (cpi->last_skip_false_probs[1]  + cpi->prob_skip_false ) / 2;
+                       */
+                }
+                else
+                {
+                    if (cpi->last_skip_false_probs[0] != 0)
+                        cpi->prob_skip_false = cpi->last_skip_false_probs[0];
+
+                    /*
+                    if(cpi->last_skip_false_probs[0]!=0 && abs(Q- cpi->last_skip_probs_q[0])<=16 )
+                        cpi->prob_skip_false = cpi->last_skip_false_probs[0];
+                    else if(cpi->last_skip_false_probs[0]!=0)
+                        cpi->prob_skip_false = (cpi->last_skip_false_probs[0]  + cpi->prob_skip_false ) / 2;
+                        */
+                }
+
+                //as this is for cost estimate, let's make sure it does not go extreme eitehr way
+                if (cpi->prob_skip_false < 5)
+                    cpi->prob_skip_false = 5;
+
+                if (cpi->prob_skip_false > 250)
+                    cpi->prob_skip_false = 250;
+
+                if (cpi->is_src_frame_alt_ref)
+                    cpi->prob_skip_false = 1;
+
+
+            }
+
+#if 0
+
+            if (cpi->pass != 1)
+            {
+                FILE *f = fopen("skip.stt", "a");
+                fprintf(f, "%d, %d, %4d ", cpi->common.refresh_golden_frame, cpi->common.refresh_alt_ref_frame, cpi->prob_skip_false);
+                fclose(f);
+            }
+
+#endif
+
+        }
+
+        if (cm->frame_type == KEY_FRAME)
+            vp8_setup_key_frame(cpi);
+
+        // transform / motion compensation build reconstruction frame
+
+        vp8_encode_frame(cpi);
+        cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
+        cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
+
+        vp8_clear_system_state();  //__asm emms;
+
+        // Test to see if the stats generated for this frame indicate that we should have coded a key frame
+        // (assuming that we didn't)!
+        if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME)
+        {
+            if (decide_key_frame(cpi))
+            {
+                vp8_calc_auto_iframe_target_size(cpi);
+
+                // Reset all our sizing numbers and recode
+                cm->frame_type = KEY_FRAME;
+
+                // Clear the Alt reference frame active flag when we have a key frame
+                cpi->source_alt_ref_active = FALSE;
+
+                // If segmentation is enabled force a map update for key frames
+                if (cpi->mb.e_mbd.segmentation_enabled)
+                {
+                    cpi->mb.e_mbd.update_mb_segmentation_map = 1;
+                    cpi->mb.e_mbd.update_mb_segmentation_data = 1;
+                }
+
+                // If mode or reference frame based loop filter deltas are enabled then force an update for key frames.
+                if (cpi->mb.e_mbd.mode_ref_lf_delta_enabled)
+                {
+                    cpi->mb.e_mbd.mode_ref_lf_delta_update = 1;
+                }
+
+                vp8_restore_coding_context(cpi);
+
+                Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+
+                q_low  = cpi->best_quality;
+                q_high = cpi->worst_quality;
+
+                vp8_compute_frame_size_bounds(cpi, &frame_under_shoot_limit, &frame_over_shoot_limit);
+
+                // Limit Q range for the adaptive loop (Values not clipped to range 20-60 as in VP8).
+                bottom_index = cpi->active_best_quality;
+                top_index    = cpi->active_worst_quality;
+
+
+                loop_count++;
+                Loop = TRUE;
+
+                resize_key_frame(cpi);
+                continue;
+            }
+        }
+
+        vp8_clear_system_state();
+
+        if (frame_over_shoot_limit == 0)
+            frame_over_shoot_limit = 1;
+
+        // Are we are overshooting and up against the limit of active max Q.
+        if (((cpi->pass != 2) || (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) &&
+            (Q == cpi->active_worst_quality)                     &&
+            (cpi->active_worst_quality < cpi->worst_quality)      &&
+            (cpi->projected_frame_size > frame_over_shoot_limit))
+        {
+            int over_size_percent = ((cpi->projected_frame_size - frame_over_shoot_limit) * 100) / frame_over_shoot_limit;
+
+            // If so is there any scope for relaxing it
+            while ((cpi->active_worst_quality < cpi->worst_quality) && (over_size_percent > 0))
+            {
+                cpi->active_worst_quality++;
+                top_index = cpi->active_worst_quality;
+                over_size_percent = (int)(over_size_percent * 0.96);        // Assume 1 qstep = about 4% on frame size.
+            }
+
+            // If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
+            active_worst_qchanged = TRUE;
+        }
+        else
+            active_worst_qchanged = FALSE;
+
+#if !(CONFIG_REALTIME_ONLY)
+
+        // Is the projected frame size out of range and are we allowed to attempt to recode.
+        if (((cpi->sf.recode_loop == 1) ||
+             ((cpi->sf.recode_loop == 2) && (cm->refresh_golden_frame || (cm->frame_type == KEY_FRAME)))) &&
+            (((cpi->projected_frame_size > frame_over_shoot_limit) && (Q < top_index)) ||
+             //((cpi->projected_frame_size > frame_over_shoot_limit ) && (Q == top_index) && (cpi->zbin_over_quant < ZBIN_OQ_MAX)) ||
+             ((cpi->projected_frame_size < frame_under_shoot_limit) && (Q > bottom_index)))
+           )
+        {
+            int last_q = Q;
+            int Retries = 0;
+
+            // Frame size out of permitted range:
+            // Update correction factor & compute new Q to try...
+            if (cpi->projected_frame_size > frame_over_shoot_limit)
+            {
+                //if ( cpi->zbin_over_quant == 0 )
+                q_low = (Q < q_high) ? (Q + 1) : q_high; // Raise Qlow as to at least the current value
+
+                if (cpi->zbin_over_quant > 0)           // If we are using over quant do the same for zbin_oq_low
+                    zbin_oq_low = (cpi->zbin_over_quant < zbin_oq_high) ? (cpi->zbin_over_quant + 1) : zbin_oq_high;
+
+                //if ( undershoot_seen || (Q == MAXQ) )
+                if (undershoot_seen)
+                {
+                    // Update rate_correction_factor unless cpi->active_worst_quality has changed.
+                    if (!active_worst_qchanged)
+                        vp8_update_rate_correction_factors(cpi, 1);
+
+                    Q = (q_high + q_low + 1) / 2;
+
+                    // Adjust cpi->zbin_over_quant (only allowed when Q is max)
+                    if (Q < MAXQ)
+                        cpi->zbin_over_quant = 0;
+                    else
+                    {
+                        zbin_oq_low = (cpi->zbin_over_quant < zbin_oq_high) ? (cpi->zbin_over_quant + 1) : zbin_oq_high;
+                        cpi->zbin_over_quant = (zbin_oq_high + zbin_oq_low) / 2;
+                    }
+                }
+                else
+                {
+                    // Update rate_correction_factor unless cpi->active_worst_quality has changed.
+                    if (!active_worst_qchanged)
+                        vp8_update_rate_correction_factors(cpi, 0);
+
+                    Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+
+                    while (((Q < q_low) || (cpi->zbin_over_quant < zbin_oq_low)) && (Retries < 10))
+                    {
+                        vp8_update_rate_correction_factors(cpi, 0);
+                        Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+                        Retries ++;
+                    }
+                }
+
+                overshoot_seen = TRUE;
+            }
+            else
+            {
+                if (cpi->zbin_over_quant == 0)
+                    q_high = (Q > q_low) ? (Q - 1) : q_low; // Lower q_high if not using over quant
+                else                                    // else lower zbin_oq_high
+                    zbin_oq_high = (cpi->zbin_over_quant > zbin_oq_low) ? (cpi->zbin_over_quant - 1) : zbin_oq_low;
+
+                if (overshoot_seen)
+                {
+                    // Update rate_correction_factor unless cpi->active_worst_quality has changed.
+                    if (!active_worst_qchanged)
+                        vp8_update_rate_correction_factors(cpi, 1);
+
+                    Q = (q_high + q_low) / 2;
+
+                    // Adjust cpi->zbin_over_quant (only allowed when Q is max)
+                    if (Q < MAXQ)
+                        cpi->zbin_over_quant = 0;
+                    else
+                        cpi->zbin_over_quant = (zbin_oq_high + zbin_oq_low) / 2;
+                }
+                else
+                {
+                    // Update rate_correction_factor unless cpi->active_worst_quality has changed.
+                    if (!active_worst_qchanged)
+                        vp8_update_rate_correction_factors(cpi, 0);
+
+                    Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+
+                    while (((Q > q_high) || (cpi->zbin_over_quant > zbin_oq_high)) && (Retries < 10))
+                    {
+                        vp8_update_rate_correction_factors(cpi, 0);
+                        Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+                        Retries ++;
+                    }
+                }
+
+                undershoot_seen = TRUE;
+            }
+
+            // Clamp Q to upper and lower limits:
+            if (Q > q_high)
+                Q = q_high;
+            else if (Q < q_low)
+                Q = q_low;
+
+            // Clamp cpi->zbin_over_quant
+            cpi->zbin_over_quant = (cpi->zbin_over_quant < zbin_oq_low) ? zbin_oq_low : (cpi->zbin_over_quant > zbin_oq_high) ? zbin_oq_high : cpi->zbin_over_quant;
+
+            //Loop = ((Q != last_q) || (last_zbin_oq != cpi->zbin_over_quant)) ? TRUE : FALSE;
+            Loop = ((Q != last_q)) ? TRUE : FALSE;
+            last_zbin_oq = cpi->zbin_over_quant;
+        }
+        else
+#endif
+            Loop = FALSE;
+
+        if (cpi->is_src_frame_alt_ref)
+            Loop = FALSE;
+
+        if (Loop == TRUE)
+        {
+            vp8_restore_coding_context(cpi);
+            loop_count++;
+#if CONFIG_PSNR
+            cpi->tot_recode_hits++;
+#endif
+        }
+    }
+    while (Loop == TRUE);
+
+#if 0
+    // Experimental code for lagged and one pass
+    // Update stats used for one pass GF selection
+    {
+        /*
+            int frames_so_far;
+            double frame_intra_error;
+            double frame_coded_error;
+            double frame_pcnt_inter;
+            double frame_pcnt_motion;
+            double frame_mvr;
+            double frame_mvr_abs;
+            double frame_mvc;
+            double frame_mvc_abs;
+        */
+
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_coded_error = (double)cpi->prediction_error;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_intra_error = (double)cpi->intra_error;
+        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_pcnt_inter = (double)(100 - cpi->this_frame_percent_intra) / 100.0;
+    }
+#endif
+
+    // Update the GF useage maps.
+    // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
+    vp8_update_gf_useage_maps(cm, &cpi->mb.e_mbd);
+
+    if (cm->frame_type == KEY_FRAME)
+        cm->refresh_last_frame = 1;
+
+    if (0)
+    {
+        FILE *f = fopen("gfactive.stt", "a");
+        fprintf(f, "%8d %8d %8d %8d %8d\n", cm->current_video_frame, (100 * cpi->common.gf_active_count) / (cpi->common.mb_rows * cpi->common.mb_cols), cpi->this_iiratio, cpi->next_iiratio, cm->refresh_golden_frame);
+        fclose(f);
+    }
+
+    // For inter frames the current default behaviour is that when cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
+    // This is purely an encoder descision at present.
+    if (!cpi->oxcf.error_resilient_mode && cm->refresh_golden_frame)
+        cm->copy_buffer_to_arf  = 2;
+    else
+        cm->copy_buffer_to_arf  = 0;
+
+    if (cm->refresh_last_frame)
+    {
+        vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);
+        cm->frame_to_show = &cm->last_frame;
+    }
+    else
+        cm->frame_to_show = &cm->new_frame;
+
+
+
+    //#pragma omp parallel sections
+    {
+
+        //#pragma omp section
+        {
+
+            struct vpx_usec_timer timer;
+
+            vpx_usec_timer_start(&timer);
+
+            if (cpi->sf.auto_filter == 0)
+                vp8cx_pick_filter_level_fast(cpi->Source, cpi);
+            else
+                vp8cx_pick_filter_level(cpi->Source, cpi);
+
+            vpx_usec_timer_mark(&timer);
+
+            cpi->time_pick_lpf +=  vpx_usec_timer_elapsed(&timer);
+
+            if (cm->no_lpf)
+                cm->filter_level = 0;
+
+            if (cm->filter_level > 0)
+            {
+                vp8cx_set_alt_lf_level(cpi, cm->filter_level);
+                vp8_loop_filter_frame(cm, &cpi->mb.e_mbd, cm->filter_level);
+                cm->last_frame_type = cm->frame_type;
+                cm->last_filter_type = cm->filter_type;
+                cm->last_sharpness_level = cm->sharpness_level;
+            }
+
+            vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
+
+            if (cpi->oxcf.error_resilient_mode == 1)
+            {
+                cm->refresh_entropy_probs = 0;
+            }
+
+        }
+//#pragma omp section
+        {
+            // build the bitstream
+            vp8_pack_bitstream(cpi, dest, size);
+        }
+    }
+
+
+    // At this point the new frame has been encoded coded.
+    // If any buffer copy / swaping is signalled it should be done here.
+    if (cm->frame_type == KEY_FRAME)
+    {
+        vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);
+        vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);
+    }
+    else    // For non key frames
+    {
+        // Code to copy between reference buffers
+        if (cm->copy_buffer_to_arf)
+        {
+            if (cm->copy_buffer_to_arf == 1)
+            {
+                if (cm->refresh_last_frame)
+                    // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set.
+                    vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame);
+                else
+                    vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame);
+            }
+            else if (cm->copy_buffer_to_arf == 2)
+                vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame);
+        }
+
+        if (cm->copy_buffer_to_gf)
+        {
+            if (cm->copy_buffer_to_gf == 1)
+            {
+                if (cm->refresh_last_frame)
+                    // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set.
+                    vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->golden_frame);
+                else
+                    vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
+            }
+            else if (cm->copy_buffer_to_gf == 2)
+                vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, &cm->golden_frame);
+        }
+    }
+
+    // Update rate control heuristics
+    cpi->total_byte_count += (*size);
+    cpi->projected_frame_size = (*size) << 3;
+
+    if (!active_worst_qchanged)
+        vp8_update_rate_correction_factors(cpi, 2);
+
+    cpi->last_q[cm->frame_type] = cm->base_qindex;
+
+    if (cm->frame_type == KEY_FRAME)
+    {
+        vp8_adjust_key_frame_context(cpi);
+    }
+
+    // Keep a record of ambient average Q.
+    if (cm->frame_type == KEY_FRAME)
+        cpi->avg_frame_qindex = cm->base_qindex;
+    else
+        cpi->avg_frame_qindex = (2 + 3 * cpi->avg_frame_qindex + cm->base_qindex) >> 2;
+
+    // Keep a record from which we can calculate the average Q excluding GF updates and key frames
+    if ((cm->frame_type != KEY_FRAME) && !cm->refresh_golden_frame && !cm->refresh_alt_ref_frame)
+    {
+        cpi->ni_frames++;
+
+        // Calculate the average Q for normal inter frames (not key or GFU frames)
+        // This is used as a basis for setting active worst quality.
+        if (cpi->ni_frames > 150)
+        {
+            cpi->ni_tot_qi += Q;
+            cpi->ni_av_qi = (cpi->ni_tot_qi / cpi->ni_frames);
+        }
+        // Early in the clip ... average the current frame Q value with the default
+        // entered by the user as a dampening measure
+        else
+        {
+            cpi->ni_tot_qi += Q;
+            cpi->ni_av_qi = ((cpi->ni_tot_qi / cpi->ni_frames) + cpi->worst_quality + 1) / 2;
+        }
+
+        // If the average Q is higher than what was used in the last frame
+        // (after going through the recode loop to keep the frame size within range)
+        // then use the last frame value - 1.
+        // The -1 is designed to stop Q and hence the data rate, from progressively
+        // falling away during difficult sections, but at the same time reduce the number of
+        // itterations around the recode loop.
+        if (Q > cpi->ni_av_qi)
+            cpi->ni_av_qi = Q - 1;
+
+    }
+
+#if 0
+
+    // If the frame was massively oversize and we are below optimal buffer level drop next frame
+    if ((cpi->drop_frames_allowed) &&
+        (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+        (cpi->buffer_level < cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100) &&
+        (cpi->projected_frame_size > (4 * cpi->this_frame_target)))
+    {
+        cpi->drop_frame = TRUE;
+    }
+
+#endif
+
+    // Set the count for maximum consequative dropped frames based upon the ratio of
+    // this frame size to the target average per frame bandwidth.
+    // (cpi->av_per_frame_bandwidth > 0) is just a sanity check to prevent / 0.
+    if (cpi->drop_frames_allowed && (cpi->av_per_frame_bandwidth > 0))
+    {
+        cpi->max_drop_count = cpi->projected_frame_size / cpi->av_per_frame_bandwidth;
+
+        if (cpi->max_drop_count > cpi->max_consec_dropped_frames)
+            cpi->max_drop_count = cpi->max_consec_dropped_frames;
+    }
+
+    // Update the buffer level variable.
+    if (cpi->common.refresh_alt_ref_frame)
+        cpi->bits_off_target -= cpi->projected_frame_size;
+    else
+        cpi->bits_off_target += cpi->av_per_frame_bandwidth - cpi->projected_frame_size;
+
+    // Rolling monitors of whether we are over or underspending used to help regulate min and Max Q in two pass.
+    cpi->rolling_target_bits = ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
+    cpi->rolling_actual_bits = ((cpi->rolling_actual_bits * 3) + cpi->projected_frame_size + 2) / 4;
+    cpi->long_rolling_target_bits = ((cpi->long_rolling_target_bits * 31) + cpi->this_frame_target + 16) / 32;
+    cpi->long_rolling_actual_bits = ((cpi->long_rolling_actual_bits * 31) + cpi->projected_frame_size + 16) / 32;
+
+    // Actual bits spent
+    cpi->total_actual_bits    += cpi->projected_frame_size;
+
+    // Debug stats
+    cpi->total_target_vs_actual += (cpi->this_frame_target - cpi->projected_frame_size);
+
+    cpi->buffer_level = cpi->bits_off_target;
+
+    // Update bits left to the kf and gf groups to account for overshoot or undershoot on these frames
+    if (cm->frame_type == KEY_FRAME)
+    {
+        cpi->kf_group_bits += cpi->this_frame_target - cpi->projected_frame_size;
+
+        if (cpi->kf_group_bits < 0)
+            cpi->kf_group_bits = 0 ;
+    }
+    else if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
+    {
+        cpi->gf_group_bits += cpi->this_frame_target - cpi->projected_frame_size;
+
+        if (cpi->gf_group_bits < 0)
+            cpi->gf_group_bits = 0 ;
+    }
+
+    if (cm->frame_type != KEY_FRAME)
+    {
+        if (cpi->common.refresh_alt_ref_frame)
+        {
+            cpi->last_skip_false_probs[2] = cpi->prob_skip_false;
+            cpi->last_skip_probs_q[2] = cm->base_qindex;
+        }
+        else if (cpi->common.refresh_golden_frame)
+        {
+            cpi->last_skip_false_probs[1] = cpi->prob_skip_false;
+            cpi->last_skip_probs_q[1] = cm->base_qindex;
+        }
+        else
+        {
+            cpi->last_skip_false_probs[0] = cpi->prob_skip_false;
+            cpi->last_skip_probs_q[0] = cm->base_qindex;
+
+            //update the baseline
+            cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false;
+
+        }
+    }
+
+#if CONFIG_PSNR
+
+    if (0)
+    {
+        FILE *f = fopen("tmp.stt", "a");
+
+        vp8_clear_system_state();  //__asm emms;
+
+        if (cpi->total_coded_error_left != 0.0)
+            fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6ld %6ld %6ld %6ld %5ld %5ld %5ld %8ld %8.2f %10d %10.3f %10.3f %8ld\n", cpi->common.current_video_frame, cpi->this_frame_target, cpi->projected_frame_size, (cpi->projected_frame_size - cpi->this_frame_target), (int)cpi->total_target_vs_actual, (cpi->oxcf.starting_buffer_level - cpi->bits_off_target), (int)cpi->total_actual_bits, cm->base_qindex, cpi->active_best_quality, cpi->active_worst_quality,  cpi->avg_frame_qindex, cpi->zbin_over_quant, cm->refresh_golden_frame, cm->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost, cpi->est_max_qcorrection_factor, (int)cpi->bits_left, cpi->total_coded_error_left, (double)cpi->bits_left / cpi->total_coded_error_left,  cpi->tot_recode_hits);
+        else
+            fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6ld %6ld %6ld %6ld %5ld %5ld %5ld %8ld %8.2f %10d %10.3f %8ld\n", cpi->common.current_video_frame, cpi->this_frame_target, cpi->projected_frame_size, (cpi->projected_frame_size - cpi->this_frame_target), (int)cpi->total_target_vs_actual, (cpi->oxcf.starting_buffer_level - cpi->bits_off_target), (int)cpi->total_actual_bits, cm->base_qindex, cpi->active_best_quality, cpi->active_worst_quality,  cpi->avg_frame_qindex, cpi->zbin_over_quant, cm->refresh_golden_frame, cm->refresh_alt_ref_frame, cm->frame_type, cpi->gfu_boost, cpi->est_max_qcorrection_factor, (int)cpi->bits_left, cpi->total_coded_error_left,   cpi->tot_recode_hits);
+
+        fclose(f);
+
+        {
+            FILE *fmodes = fopen("Modes.stt", "a");
+            int i;
+
+            fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame, cm->frame_type, cm->refresh_golden_frame, cm->refresh_alt_ref_frame);
+
+            for (i = 0; i < MAX_MODES; i++)
+                fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]);
+
+            fprintf(fmodes, "\n");
+
+            fclose(fmodes);
+        }
+    }
+
+#endif
+
+    // If this was a kf or Gf note the Q
+    if ((cm->frame_type == KEY_FRAME) || cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
+        cm->last_kf_gf_q = cm->base_qindex;
+
+    if (cm->refresh_golden_frame == 1)
+        cm->frame_flags = cm->frame_flags | FRAMEFLAGS_GOLDEN;
+    else
+        cm->frame_flags = cm->frame_flags&~FRAMEFLAGS_GOLDEN;
+
+    if (cm->refresh_alt_ref_frame == 1)
+        cm->frame_flags = cm->frame_flags | FRAMEFLAGS_ALTREF;
+    else
+        cm->frame_flags = cm->frame_flags&~FRAMEFLAGS_ALTREF;
+
+
+    if (cm->refresh_last_frame & cm->refresh_golden_frame) // both refreshed
+        cpi->gold_is_last = 1;
+    else if (cm->refresh_last_frame ^ cm->refresh_golden_frame) // 1 refreshed but not the other
+        cpi->gold_is_last = 0;
+
+    if (cm->refresh_last_frame & cm->refresh_alt_ref_frame) // both refreshed
+        cpi->alt_is_last = 1;
+    else if (cm->refresh_last_frame ^ cm->refresh_alt_ref_frame) // 1 refreshed but not the other
+        cpi->alt_is_last = 0;
+
+    if (cm->refresh_alt_ref_frame & cm->refresh_golden_frame) // both refreshed
+        cpi->gold_is_alt = 1;
+    else if (cm->refresh_alt_ref_frame ^ cm->refresh_golden_frame) // 1 refreshed but not the other
+        cpi->gold_is_alt = 0;
+
+    cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
+
+    if (cpi->gold_is_last)
+        cpi->ref_frame_flags &= !VP8_GOLD_FLAG;
+
+    if (cpi->alt_is_last)
+        cpi->ref_frame_flags &= !VP8_ALT_FLAG;
+
+    if (cpi->gold_is_alt)
+        cpi->ref_frame_flags &= !VP8_ALT_FLAG;
+
+
+    if (cpi->oxcf.error_resilient_mode)
+    {
+        // Is this an alternate reference update
+        if (cpi->common.refresh_alt_ref_frame)
+            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);
+
+        if (cpi->common.refresh_golden_frame)
+            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);
+    }
+    else
+    {
+        if (cpi->oxcf.play_alternate && cpi->common.refresh_alt_ref_frame)
+            // Update the alternate reference frame and stats as appropriate.
+            update_alt_ref_frame_and_stats(cpi);
+        else
+            // Update the Golden frame and golden frame and stats as appropriate.
+            update_golden_frame_and_stats(cpi);
+    }
+
+    if (cm->frame_type == KEY_FRAME)
+    {
+        // Tell the caller that the frame was coded as a key frame
+        *frame_flags = cm->frame_flags | FRAMEFLAGS_KEY;
+
+        // As this frame is a key frame  the next defaults to an inter frame.
+        cm->frame_type = INTER_FRAME;
+
+        cpi->last_frame_percent_intra = 100;
+    }
+    else
+    {
+        *frame_flags = cm->frame_flags&~FRAMEFLAGS_KEY;
+
+        cpi->last_frame_percent_intra = cpi->this_frame_percent_intra;
+    }
+
+    // Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
+    cpi->mb.e_mbd.update_mb_segmentation_map = 0;
+    cpi->mb.e_mbd.update_mb_segmentation_data = 0;
+    cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
+
+
+    // Dont increment frame counters if this was an altref buffer update not a real frame
+    if (cm->show_frame)
+    {
+        cm->current_video_frame++;
+        cpi->frames_since_key++;
+    }
+
+    // reset to normal state now that we are done.
+
+
+
+    if (0)
+    {
+        char filename[512];
+        FILE *recon_file;
+        sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame);
+        recon_file = fopen(filename, "wb");
+        fwrite(cm->last_frame.buffer_alloc, cm->last_frame.frame_size, 1, recon_file);
+        fclose(recon_file);
+    }
+
+    // DEBUG
+    //vp8_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show);
+
+
+}
+
+int vp8_is_gf_update_needed(VP8_PTR ptr)
+{
+    VP8_COMP *cpi = (VP8_COMP *) ptr;
+    int ret_val;
+
+    ret_val = cpi->gf_update_recommended;
+    cpi->gf_update_recommended = 0;
+
+    return ret_val;
+}
+
+void vp8_check_gf_quality(VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+    int gf_active_pct = (100 * cm->gf_active_count) / (cm->mb_rows * cm->mb_cols);
+    int gf_ref_usage_pct = (cpi->count_mb_ref_frame_usage[GOLDEN_FRAME] * 100) / (cm->mb_rows * cm->mb_cols);
+    int last_ref_zz_useage = (cpi->inter_zz_count * 100) / (cm->mb_rows * cm->mb_cols);
+
+    // Gf refresh is not currently being signalled
+    if (cpi->gf_update_recommended == 0)
+    {
+        if (cpi->common.frames_since_golden > 7)
+        {
+            // Low use of gf
+            if ((gf_active_pct < 10) || ((gf_active_pct + gf_ref_usage_pct) < 15))
+            {
+                // ...but last frame zero zero usage is reasonbable so a new gf might be appropriate
+                if (last_ref_zz_useage >= 25)
+                {
+                    cpi->gf_bad_count ++;
+
+                    if (cpi->gf_bad_count >= 8)   // Check that the condition is stable
+                    {
+                        cpi->gf_update_recommended = 1;
+                        cpi->gf_bad_count = 0;
+                    }
+                }
+                else
+                    cpi->gf_bad_count = 0;        // Restart count as the background is not stable enough
+            }
+            else
+                cpi->gf_bad_count = 0;            // Gf useage has picked up so reset count
+        }
+    }
+    // If the signal is set but has not been read should we cancel it.
+    else if (last_ref_zz_useage < 15)
+    {
+        cpi->gf_update_recommended = 0;
+        cpi->gf_bad_count = 0;
+    }
+
+#if 0
+
+    if (0)
+    {
+        FILE *f = fopen("gfneeded.stt", "a");
+        fprintf(f, "%10d %10d %10d %10d %10ld \n",
+                cm->current_video_frame,
+                cpi->common.frames_since_golden,
+                gf_active_pct, gf_ref_usage_pct,
+                cpi->gf_update_recommended);
+        fclose(f);
+    }
+
+#endif
+}
+
+#if !(CONFIG_REALTIME_ONLY)
+static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
+{
+    double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
+
+    if (!cpi->common.refresh_alt_ref_frame)
+        vp8_second_pass(cpi);
+
+    encode_frame_to_data_rate(cpi, size, dest, frame_flags);
+    cpi->bits_left -= 8 * *size;
+
+    if (!cpi->common.refresh_alt_ref_frame)
+        cpi->bits_left += (long long)(two_pass_min_rate / cpi->oxcf.frame_rate);
+}
+#endif
+
+//For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.
+#if HAVE_ARMV7
+extern void vp8_push_neon(INT64 *store);
+extern void vp8_pop_neon(INT64 *store);
+static INT64 store_reg[8];
+#endif
+int vp8_receive_raw_frame(VP8_PTR ptr, unsigned int frame_flags, YV12_BUFFER_CONFIG *sd, INT64 time_stamp, INT64 end_time)
+{
+    VP8_COMP *cpi = (VP8_COMP *) ptr;
+    VP8_COMMON *cm = &cpi->common;
+    struct vpx_usec_timer  timer;
+
+    if (!cpi)
+        return -1;
+
+#if HAVE_ARMV7
+    vp8_push_neon(store_reg);
+#endif
+
+    vpx_usec_timer_start(&timer);
+
+    // no more room for frames;
+    if (cpi->source_buffer_count != 0 && cpi->source_buffer_count >= cpi->oxcf.lag_in_frames)
+    {
+#if HAVE_ARMV7
+        vp8_pop_neon(store_reg);
+#endif
+        return -1;
+    }
+
+    //printf("in-cpi->source_buffer_count: %d\n", cpi->source_buffer_count);
+
+    cm->clr_type = sd->clrtype;
+
+    // make a copy of the frame for use later...
+#if !(CONFIG_REALTIME_ONLY)
+
+    if (cpi->oxcf.allow_lag)
+    {
+        int which_buffer =  cpi->source_encode_index - 1;
+        SOURCE_SAMPLE *s;
+
+        if (which_buffer == -1)
+            which_buffer = cpi->oxcf.lag_in_frames - 1;
+
+        if (cpi->source_buffer_count < cpi->oxcf.lag_in_frames - 1)
+            which_buffer = cpi->source_buffer_count;
+
+        s = &cpi->src_buffer[which_buffer];
+
+        s->source_time_stamp = time_stamp;
+        s->source_end_time_stamp = end_time;
+        s->source_frame_flags = frame_flags;
+        vp8_yv12_copy_frame_ptr(sd, &s->source_buffer);
+
+        cpi->source_buffer_count ++;
+    }
+    else
+#endif
+    {
+        SOURCE_SAMPLE *s;
+        s = &cpi->src_buffer[0];
+        s->source_end_time_stamp = end_time;
+        s->source_time_stamp = time_stamp;
+        s->source_frame_flags = frame_flags;
+#if HAVE_ARMV7
+        vp8_yv12_copy_src_frame_func_neon(sd, &s->source_buffer);
+#else
+        vp8_yv12_copy_frame_ptr(sd, &s->source_buffer);
+#endif
+        cpi->source_buffer_count = 1;
+    }
+
+    vpx_usec_timer_mark(&timer);
+    cpi->time_receive_data += vpx_usec_timer_elapsed(&timer);
+
+#if HAVE_ARMV7
+    vp8_pop_neon(store_reg);
+#endif
+
+    return 0;
+}
+int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, INT64 *time_stamp, INT64 *time_end, int flush)
+{
+
+    VP8_COMP *cpi = (VP8_COMP *) ptr;
+    VP8_COMMON *cm = &cpi->common;
+    struct vpx_usec_timer  tsctimer;
+    struct vpx_usec_timer  ticktimer;
+    struct vpx_usec_timer  cmptimer;
+
+    if (!cpi)
+        return -1;
+
+#if HAVE_ARMV7
+    vp8_push_neon(store_reg);
+#endif
+
+    vpx_usec_timer_start(&cmptimer);
+
+
+    // flush variable tells us that even though we have less than 10 frames
+    // in our buffer we need to start producing compressed frames.
+    // Probably because we are at the end of a file....
+    if ((cpi->source_buffer_count == cpi->oxcf.lag_in_frames && cpi->oxcf.lag_in_frames > 0)
+        || (!cpi->oxcf.allow_lag && cpi->source_buffer_count > 0)
+        || (flush && cpi->source_buffer_count > 0))
+    {
+
+        SOURCE_SAMPLE *s;
+
+        s = &cpi->src_buffer[cpi->source_encode_index];
+        cpi->source_time_stamp = s->source_time_stamp;
+        cpi->source_end_time_stamp = s->source_end_time_stamp;
+
+#if !(CONFIG_REALTIME_ONLY)
+
+        // Should we code an alternate reference frame
+        if (cpi->oxcf.error_resilient_mode == 0 &&
+            cpi->oxcf.play_alternate &&
+            cpi->source_alt_ref_pending  &&
+            (cpi->frames_till_gf_update_due < cpi->source_buffer_count) &&
+            cpi->oxcf.lag_in_frames != 0)
+        {
+            cpi->last_alt_ref_sei = (cpi->source_encode_index + cpi->frames_till_gf_update_due) % cpi->oxcf.lag_in_frames;
+
+#if VP8_TEMPORAL_ALT_REF
+
+            if (cpi->oxcf.arnr_max_frames > 0)
+            {
+#if 0
+                // my attempt at a loop that tests the results of strength filter.
+                int start_frame = cpi->last_alt_ref_sei - 3;
+
+                int i, besti = -1, pastin = cpi->oxcf.arnr_strength;
+
+                int besterr;
+
+                if (start_frame < 0)
+                    start_frame += cpi->oxcf.lag_in_frames;
+
+                besterr = vp8_calc_low_ss_err(&cpi->src_buffer[cpi->last_alt_ref_sei].source_buffer,
+                                              &cpi->src_buffer[start_frame].source_buffer, IF_RTCD(&cpi->rtcd.variance));
+
+                for (i = 0; i < 7; i++)
+                {
+                    int thiserr;
+                    cpi->oxcf.arnr_strength = i;
+                    vp8cx_temp_filter_c(cpi);
+
+                    thiserr = vp8_calc_low_ss_err(&cpi->alt_ref_buffer.source_buffer,
+                                                  &cpi->src_buffer[start_frame].source_buffer, IF_RTCD(&cpi->rtcd.variance));
+
+                    if (10 * thiserr < besterr * 8)
+                    {
+                        besterr = thiserr;
+                        besti = i;
+                    }
+                }
+
+                if (besti != -1)
+                {
+                    cpi->oxcf.arnr_strength = besti;
+                    vp8cx_temp_filter_c(cpi);
+                    s = &cpi->alt_ref_buffer;
+
+                    // FWG not sure if I need to copy this data for the Alt Ref frame
+                    s->source_time_stamp = cpi->src_buffer[cpi->last_alt_ref_sei].source_time_stamp;
+                    s->source_end_time_stamp = cpi->src_buffer[cpi->last_alt_ref_sei].source_end_time_stamp;
+                    s->source_frame_flags = cpi->src_buffer[cpi->last_alt_ref_sei].source_frame_flags;
+                }
+                else
+                    s = &cpi->src_buffer[cpi->last_alt_ref_sei];
+
+#else
+                vp8cx_temp_filter_c(cpi);
+                s = &cpi->alt_ref_buffer;
+
+                // FWG not sure if I need to copy this data for the Alt Ref frame
+                s->source_time_stamp = cpi->src_buffer[cpi->last_alt_ref_sei].source_time_stamp;
+                s->source_end_time_stamp = cpi->src_buffer[cpi->last_alt_ref_sei].source_end_time_stamp;
+                s->source_frame_flags = cpi->src_buffer[cpi->last_alt_ref_sei].source_frame_flags;
+
+#endif
+            }
+            else
+#endif
+                s = &cpi->src_buffer[cpi->last_alt_ref_sei];
+
+            cm->frames_till_alt_ref_frame = cpi->frames_till_gf_update_due;
+            cm->refresh_alt_ref_frame = 1;
+            cm->refresh_golden_frame = 0;
+            cm->refresh_last_frame = 0;
+            cm->show_frame = 0;
+            cpi->source_alt_ref_pending = FALSE;   // Clear Pending altf Ref flag.
+            cpi->is_src_frame_alt_ref = 0;
+        }
+        else
+#endif
+        {
+            cm->show_frame = 1;
+#if !(CONFIG_REALTIME_ONLY)
+
+            if (cpi->oxcf.allow_lag)
+            {
+                if (cpi->source_encode_index ==  cpi->last_alt_ref_sei)
+                {
+#if VP8_TEMPORAL_ALT_REF
+
+                    if (cpi->oxcf.arnr_max_frames == 0)
+                    {
+                        cpi->is_src_frame_alt_ref = 1; // copy alt ref
+                    }
+                    else
+                    {
+                        cpi->is_src_frame_alt_ref = 0;
+                    }
+
+#else
+                    cpi->is_src_frame_alt_ref = 1;
+#endif
+                    cpi->last_alt_ref_sei    = -1;
+                }
+                else
+                    cpi->is_src_frame_alt_ref = 0;
+
+                cpi->source_encode_index = (cpi->source_encode_index + 1) % cpi->oxcf.lag_in_frames;
+            }
+
+#endif
+            cpi->source_buffer_count--;
+        }
+
+        cpi->un_scaled_source = &s->source_buffer;
+        cpi->Source = &s->source_buffer;
+        cpi->source_frame_flags = s->source_frame_flags;
+
+        *time_stamp = cpi->source_time_stamp;
+        *time_end = cpi->source_end_time_stamp;
+    }
+    else
+    {
+        *size = 0;
+#if !(CONFIG_REALTIME_ONLY)
+
+        if (flush && cpi->pass == 1 && !cpi->first_pass_done)
+        {
+            vp8_end_first_pass(cpi);    /* get last stats packet */
+            cpi->first_pass_done = 1;
+        }
+
+#endif
+
+#if HAVE_ARMV7
+        vp8_pop_neon(store_reg);
+#endif
+        return -1;
+    }
+
+    *frame_flags = cpi->source_frame_flags;
+
+#if CONFIG_PSNR
+
+    if (cpi->source_time_stamp < cpi->first_time_stamp_ever)
+        cpi->first_time_stamp_ever = cpi->source_time_stamp;
+
+#endif
+
+    // adjust frame rates based on timestamps given
+    if (!cm->refresh_alt_ref_frame)
+    {
+        if (cpi->last_time_stamp_seen == 0)
+        {
+            double this_fps = 10000000.000 / (cpi->source_end_time_stamp - cpi->source_time_stamp);
+
+            vp8_new_frame_rate(cpi, this_fps);
+        }
+        else
+        {
+            long long nanosecs = cpi->source_time_stamp - cpi->last_time_stamp_seen;
+            double this_fps = 10000000.000 / nanosecs;
+
+            vp8_new_frame_rate(cpi, (7 * cpi->oxcf.frame_rate + this_fps) / 8);
+
+        }
+
+        cpi->last_time_stamp_seen = cpi->source_time_stamp;
+    }
+
+    if (cpi->compressor_speed == 2)
+    {
+        vp8_check_gf_quality(cpi);
+    }
+
+    if (!cpi)
+    {
+#if HAVE_ARMV7
+        vp8_pop_neon(store_reg);
+#endif
+        return 0;
+    }
+
+    if (cpi->compressor_speed == 2)
+    {
+        vpx_usec_timer_start(&tsctimer);
+        vpx_usec_timer_start(&ticktimer);
+    }
+
+    // start with a 0 size frame
+    *size = 0;
+
+    // Clear down mmx registers
+    vp8_clear_system_state();  //__asm emms;
+
+    cm->frame_type = INTER_FRAME;
+    cm->frame_flags = *frame_flags;
+
+#if 0
+
+    if (cm->refresh_alt_ref_frame)
+    {
+        //cm->refresh_golden_frame = 1;
+        cm->refresh_golden_frame = 0;
+        cm->refresh_last_frame = 0;
+    }
+    else
+    {
+        cm->refresh_golden_frame = 0;
+        cm->refresh_last_frame = 1;
+    }
+
+#endif
+
+#if !(CONFIG_REALTIME_ONLY)
+
+    if (cpi->pass == 1)
+    {
+        Pass1Encode(cpi, size, dest, frame_flags);
+    }
+    else if (cpi->pass == 2)
+    {
+        Pass2Encode(cpi, size, dest, frame_flags);
+    }
+    else
+#endif
+        encode_frame_to_data_rate(cpi, size, dest, frame_flags);
+
+    if (cpi->compressor_speed == 2)
+    {
+        unsigned int duration, duration2;
+        vpx_usec_timer_mark(&tsctimer);
+        vpx_usec_timer_mark(&ticktimer);
+
+        duration = vpx_usec_timer_elapsed(&ticktimer);
+        duration2 = (unsigned int)((double)duration / 2);
+
+        if (cm->frame_type != KEY_FRAME)
+        {
+            if (cpi->avg_encode_time == 0)
+                cpi->avg_encode_time = duration;
+            else
+                cpi->avg_encode_time = (7 * cpi->avg_encode_time + duration) >> 3;
+        }
+
+        if (duration2)
+        {
+            //if(*frame_flags!=1)
+            {
+
+                if (cpi->avg_pick_mode_time == 0)
+                    cpi->avg_pick_mode_time = duration2;
+                else
+                    cpi->avg_pick_mode_time = (7 * cpi->avg_pick_mode_time + duration2) >> 3;
+            }
+        }
+
+    }
+
+    if (cm->refresh_entropy_probs == 0)
+    {
+        vpx_memcpy(&cm->fc, &cm->lfc, sizeof(cm->fc));
+    }
+
+    // if its a dropped frame honor the requests on subsequent frames
+    if (*size > 0)
+    {
+
+        // return to normal state
+        cpi->ref_frame_flags = VP8_ALT_FLAG | VP8_GOLD_FLAG | VP8_LAST_FLAG;
+
+        cm->refresh_entropy_probs = 1;
+        cm->refresh_alt_ref_frame = 0;
+        cm->refresh_golden_frame = 0;
+        cm->refresh_last_frame = 1;
+        cm->frame_type = INTER_FRAME;
+
+    }
+
+    cpi->ready_for_new_frame = 1;
+
+    vpx_usec_timer_mark(&cmptimer);
+    cpi->time_compress_data += vpx_usec_timer_elapsed(&cmptimer);
+
+    if (cpi->b_calculate_psnr && cpi->pass != 1 && cm->show_frame)
+        generate_psnr_packet(cpi);
+
+#if CONFIG_PSNR
+
+    if (cpi->pass != 1)
+    {
+        cpi->bytes += *size;
+
+        if (cm->show_frame)
+        {
+
+            cpi->count ++;
+
+            if (cpi->b_calculate_psnr)
+            {
+                double y, u, v;
+                double sq_error;
+                double frame_psnr = vp8_calc_psnr(cpi->Source, cm->frame_to_show, &y, &u, &v, &sq_error);
+
+                cpi->total_y += y;
+                cpi->total_u += u;
+                cpi->total_v += v;
+                cpi->total_sq_error += sq_error;
+                cpi->total  += frame_psnr;
+                {
+                    double y2, u2, v2, frame_psnr2, frame_ssim2 = 0;
+                    double weight = 0;
+
+                    vp8_deblock(cm->frame_to_show, &cm->post_proc_buffer, cm->filter_level * 10 / 6, 1, 0, IF_RTCD(&cm->rtcd.postproc));
+                    vp8_clear_system_state();
+                    frame_psnr2 = vp8_calc_psnr(cpi->Source, &cm->post_proc_buffer, &y2, &u2, &v2, &sq_error);
+                    frame_ssim2 = vp8_calc_ssim(cpi->Source, &cm->post_proc_buffer, 1, &weight);
+
+                    cpi->summed_quality += frame_ssim2 * weight;
+                    cpi->summed_weights += weight;
+
+                    cpi->totalp_y += y2;
+                    cpi->totalp_u += u2;
+                    cpi->totalp_v += v2;
+                    cpi->totalp  += frame_psnr2;
+                    cpi->total_sq_error2 += sq_error;
+
+                }
+            }
+
+            if (cpi->b_calculate_ssimg)
+            {
+                double y, u, v, frame_all;
+                frame_all =  vp8_calc_ssimg(cpi->Source, cm->frame_to_show, &y, &u, &v);
+                cpi->total_ssimg_y += y;
+                cpi->total_ssimg_u += u;
+                cpi->total_ssimg_v += v;
+                cpi->total_ssimg_all += frame_all;
+            }
+
+        }
+    }
+
+#if 0
+
+    if (cpi->common.frame_type != 0 && cpi->common.base_qindex == cpi->oxcf.worst_allowed_q)
+    {
+        skiptruecount += cpi->skip_true_count;
+        skipfalsecount += cpi->skip_false_count;
+    }
+
+#endif
+#if 0
+
+    if (cpi->pass != 1)
+    {
+        FILE *f = fopen("skip.stt", "a");
+        fprintf(f, "frame:%4d flags:%4x Q:%4d P:%4d Size:%5d\n", cpi->common.current_video_frame, *frame_flags, cpi->common.base_qindex, cpi->prob_skip_false, *size);
+
+        if (cpi->is_src_frame_alt_ref == 1)
+            fprintf(f, "skipcount: %4d framesize: %d\n", cpi->skip_true_count , *size);
+
+        fclose(f);
+    }
+
+#endif
+#endif
+
+#if HAVE_ARMV7
+    vp8_pop_neon(store_reg);
+#endif
+
+    return 0;
+}
+
+int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, int deblock_level, int noise_level, int flags)
+{
+    VP8_COMP *cpi = (VP8_COMP *) comp;
+
+    if (cpi->common.refresh_alt_ref_frame)
+        return -1;
+    else
+    {
+        int ret;
+#if CONFIG_POSTPROC
+        ret = vp8_post_proc_frame(&cpi->common, dest, deblock_level, noise_level, flags);
+#else
+
+        if (cpi->common.frame_to_show)
+        {
+            *dest = *cpi->common.frame_to_show;
+            dest->y_width = cpi->common.Width;
+            dest->y_height = cpi->common.Height;
+            dest->uv_height = cpi->common.Height / 2;
+            ret = 0;
+        }
+        else
+        {
+            ret = -1;
+        }
+
+#endif //!CONFIG_POSTPROC
+        vp8_clear_system_state();
+        return ret;
+    }
+}
+
+int vp8_set_roimap(VP8_PTR comp, unsigned char *map, unsigned int rows, unsigned int cols, int delta_q[4], int delta_lf[4], unsigned int threshold[4])
+{
+    VP8_COMP *cpi = (VP8_COMP *) comp;
+    signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
+
+    if (cpi->common.mb_rows != rows || cpi->common.mb_cols != cols)
+        return -1;
+
+    if (!map)
+    {
+        disable_segmentation((VP8_PTR)cpi);
+        return 0;
+    }
+
+    // Set the segmentation Map
+    set_segmentation_map((VP8_PTR)cpi, map);
+
+    // Activate segmentation.
+    enable_segmentation((VP8_PTR)cpi);
+
+    // Set up the quant segment data
+    feature_data[MB_LVL_ALT_Q][0] = delta_q[0];
+    feature_data[MB_LVL_ALT_Q][1] = delta_q[1];
+    feature_data[MB_LVL_ALT_Q][2] = delta_q[2];
+    feature_data[MB_LVL_ALT_Q][3] = delta_q[3];
+
+    // Set up the loop segment data s
+    feature_data[MB_LVL_ALT_LF][0] = delta_lf[0];
+    feature_data[MB_LVL_ALT_LF][1] = delta_lf[1];
+    feature_data[MB_LVL_ALT_LF][2] = delta_lf[2];
+    feature_data[MB_LVL_ALT_LF][3] = delta_lf[3];
+
+    cpi->segment_encode_breakout[0] = threshold[0];
+    cpi->segment_encode_breakout[1] = threshold[1];
+    cpi->segment_encode_breakout[2] = threshold[2];
+    cpi->segment_encode_breakout[3] = threshold[3];
+
+    // Initialise the feature data structure
+    // SEGMENT_DELTADATA    0, SEGMENT_ABSDATA      1
+    set_segment_data((VP8_PTR)cpi, &feature_data[0][0], SEGMENT_DELTADATA);
+
+    return 0;
+}
+
+int vp8_set_active_map(VP8_PTR comp, unsigned char *map, unsigned int rows, unsigned int cols)
+{
+    VP8_COMP *cpi = (VP8_COMP *) comp;
+
+    if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols)
+    {
+        if (map)
+        {
+            vpx_memcpy(cpi->active_map, map, rows * cols);
+            cpi->active_map_enabled = 1;
+        }
+        else
+            cpi->active_map_enabled = 0;
+
+        return 0;
+    }
+    else
+    {
+        //cpi->active_map_enabled = 0;
+        return -1 ;
+    }
+}
+
+int vp8_set_internal_size(VP8_PTR comp, VPX_SCALING horiz_mode, VPX_SCALING vert_mode)
+{
+    VP8_COMP *cpi = (VP8_COMP *) comp;
+
+    if (horiz_mode >= NORMAL && horiz_mode <= ONETWO)
+        cpi->common.horiz_scale = horiz_mode;
+    else
+        return -1;
+
+    if (vert_mode >= NORMAL && vert_mode <= ONETWO)
+        cpi->common.vert_scale  = vert_mode;
+    else
+        return -1;
+
+    return 0;
+}
+
+
+
+int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd)
+{
+    int i, j;
+    int Total = 0;
+
+    unsigned char *src = source->y_buffer;
+    unsigned char *dst = dest->y_buffer;
+    (void)rtcd;
+
+    // Loop through the Y plane raw and reconstruction data summing (square differences)
+    for (i = 0; i < source->y_height; i += 16)
+    {
+        for (j = 0; j < source->y_width; j += 16)
+        {
+            unsigned int sse;
+            Total += VARIANCE_INVOKE(rtcd, mse16x16)(src + j, source->y_stride, dst + j, dest->y_stride, &sse);
+        }
+
+        src += 16 * source->y_stride;
+        dst += 16 * dest->y_stride;
+    }
+
+    return Total;
+}
+int vp8_calc_low_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd)
+{
+    int i, j;
+    int Total = 0;
+
+    unsigned char *src = source->y_buffer;
+    unsigned char *dst = dest->y_buffer;
+    (void)rtcd;
+
+    // Loop through the Y plane raw and reconstruction data summing (square differences)
+    for (i = 0; i < source->y_height; i += 16)
+    {
+        for (j = 0; j < source->y_width; j += 16)
+        {
+            unsigned int sse, sse2, sum2;
+            VARIANCE_INVOKE(rtcd, mse16x16)(src + j, source->y_stride, dst + j, dest->y_stride, &sse);
+
+            if (sse < 8096)
+                Total += sse;
+        }
+
+        src += 16 * source->y_stride;
+        dst += 16 * dest->y_stride;
+    }
+
+    return Total;
+}
+
+int vp8_get_speed(VP8_PTR c)
+{
+    VP8_COMP   *cpi = (VP8_COMP *) c;
+    return cpi->Speed;
+}
+int vp8_get_quantizer(VP8_PTR c)
+{
+    VP8_COMP   *cpi = (VP8_COMP *) c;
+    return cpi->common.base_qindex;
+}
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
new file mode 100644 (file)
index 0000000..29b120e
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_VP8_INT_H
+#define __INC_VP8_INT_H
+
+#include <stdio.h>
+#include "vpx_ports/config.h"
+#include "onyx.h"
+#include "treewriter.h"
+#include "tokenize.h"
+#include "onyxc_int.h"
+#include "preproc.h"
+#include "variance.h"
+#include "dct.h"
+#include "encodemb.h"
+#include "quantize.h"
+#include "entropy.h"
+#include "threading.h"
+#include "vpx_ports/mem.h"
+#include "vpx_codec/internal/vpx_codec_internal.h"
+#include "mcomp.h"
+
+#define INTRARDOPT
+//#define SPEEDSTATS 1
+#define MIN_GF_INTERVAL             4
+#define DEFAULT_GF_INTERVAL         7
+
+#define KEY_FRAME_CONTEXT 5
+
+#define MAX_LAG_BUFFERS (CONFIG_REALTIME_ONLY? 1 : 25)
+
+#define AF_THRESH   25
+#define AF_THRESH2  100
+#define ARF_DECAY_THRESH 12
+#define MAX_MODES 20
+
+#define MIN_THRESHMULT  32
+#define MAX_THRESHMULT  512
+
+#define GF_ZEROMV_ZBIN_BOOST 24
+#define ZBIN_OQ_MAX 192
+
+#define VP8_TEMPORAL_ALT_REF 1
+
+typedef struct
+{
+    int kf_indicated;
+    unsigned int frames_since_key;
+    unsigned int frames_since_golden;
+    int filter_level;
+    int frames_till_gf_update_due;
+    int recent_ref_frame_usage[MAX_REF_FRAMES];
+
+    MV_CONTEXT mvc[2];
+    int mvcosts[2][MVvals+1];
+
+#ifdef MODE_STATS
+    // Stats
+    int y_modes[5];
+    int uv_modes[4];
+    int b_modes[10];
+    int inter_y_modes[10];
+    int inter_uv_modes[4];
+    int inter_b_modes[10];
+#endif
+
+    vp8_prob ymode_prob[4], uv_mode_prob[3];   /* interframe intra mode probs */
+    vp8_prob kf_ymode_prob[4], kf_uv_mode_prob[3];   /* keyframe "" */
+
+    int ymode_count[5], uv_mode_count[4];  /* intra MB type cts this frame */
+
+    int count_mb_ref_frame_usage[MAX_REF_FRAMES];
+
+    int this_frame_percent_intra;
+    int last_frame_percent_intra;
+
+
+} CODING_CONTEXT;
+
+typedef struct
+{
+    double frame;
+    double intra_error;
+    double coded_error;
+    double ssim_weighted_pred_err;
+    double pcnt_inter;
+    double pcnt_motion;
+    double pcnt_second_ref;
+    double MVr;
+    double mvr_abs;
+    double MVc;
+    double mvc_abs;
+    double MVrv;
+    double MVcv;
+    double mv_in_out_count;
+    double duration;
+    double count;
+}
+FIRSTPASS_STATS;
+
+typedef struct
+{
+    int frames_so_far;
+    double frame_intra_error;
+    double frame_coded_error;
+    double frame_pcnt_inter;
+    double frame_pcnt_motion;
+    double frame_mvr;
+    double frame_mvr_abs;
+    double frame_mvc;
+    double frame_mvc_abs;
+
+} ONEPASS_FRAMESTATS;
+
+
+typedef enum
+{
+    THR_ZEROMV         = 0,
+    THR_DC             = 1,
+
+    THR_NEARESTMV      = 2,
+    THR_NEARMV         = 3,
+
+    THR_ZEROG          = 4,
+    THR_NEARESTG       = 5,
+
+    THR_ZEROA          = 6,
+    THR_NEARESTA       = 7,
+
+    THR_NEARG          = 8,
+    THR_NEARA          = 9,
+
+    THR_V_PRED         = 10,
+    THR_H_PRED         = 11,
+    THR_TM             = 12,
+
+    THR_NEWMV          = 13,
+    THR_NEWG           = 14,
+    THR_NEWA           = 15,
+
+    THR_SPLITMV        = 16,
+    THR_SPLITG         = 17,
+    THR_SPLITA         = 18,
+
+    THR_B_PRED         = 19,
+}
+THR_MODES;
+
+typedef enum
+{
+    DIAMOND = 0,
+    NSTEP = 1,
+    HEX = 2
+} SEARCH_METHODS;
+
+typedef struct
+{
+    int RD;
+    SEARCH_METHODS search_method;
+    int improved_quant;
+    int improved_dct;
+    int auto_filter;
+    int recode_loop;
+    int iterative_sub_pixel;
+    int half_pixel_search;
+    int quarter_pixel_search;
+    int thresh_mult[MAX_MODES];
+    int full_freq[2];
+    int min_fs_radius;
+    int max_fs_radius;
+    int max_step_search_steps;
+    int first_step;
+    int optimize_coefficients;
+
+} SPEED_FEATURES;
+
+typedef struct
+{
+    MACROBLOCK  mb;
+    int mb_row;
+    TOKENEXTRA *tp;
+    int segment_counts[MAX_MB_SEGMENTS];
+    int totalrate;
+    int current_mb_col;
+} MB_ROW_COMP;
+
+typedef struct
+{
+    TOKENEXTRA *start;
+    TOKENEXTRA *stop;
+} TOKENLIST;
+
+typedef struct
+{
+    int ithread;
+    void *ptr1;
+    void *ptr2;
+} ENCODETHREAD_DATA;
+typedef struct
+{
+    int ithread;
+    void *ptr1;
+} LPFTHREAD_DATA;
+
+typedef struct
+{
+    INT64  source_time_stamp;
+    INT64  source_end_time_stamp;
+
+    DECLARE_ALIGNED(16, YV12_BUFFER_CONFIG, source_buffer);
+    unsigned int source_frame_flags;
+} SOURCE_SAMPLE;
+
+typedef struct VP8_ENCODER_RTCD
+{
+    VP8_COMMON_RTCD            *common;
+    vp8_variance_rtcd_vtable_t  variance;
+    vp8_fdct_rtcd_vtable_t      fdct;
+    vp8_encodemb_rtcd_vtable_t  encodemb;
+    vp8_quantize_rtcd_vtable_t  quantize;
+    vp8_search_rtcd_vtable_t    search;
+} VP8_ENCODER_RTCD;
+
+typedef struct
+{
+
+    DECLARE_ALIGNED(16, short, Y1quant[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, Y1zbin[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, Y1round[QINDEX_RANGE][4][4]);
+
+    DECLARE_ALIGNED(16, short, Y2quant[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, Y2zbin[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, Y2round[QINDEX_RANGE][4][4]);
+
+    DECLARE_ALIGNED(16, short, UVquant[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, UVzbin[QINDEX_RANGE][4][4]);
+    DECLARE_ALIGNED(16, short, UVround[QINDEX_RANGE][4][4]);
+
+    DECLARE_ALIGNED(16, short, zrun_zbin_boost_y1[QINDEX_RANGE][16]);
+    DECLARE_ALIGNED(16, short, zrun_zbin_boost_y2[QINDEX_RANGE][16]);
+    DECLARE_ALIGNED(16, short, zrun_zbin_boost_uv[QINDEX_RANGE][16]);
+
+
+    MACROBLOCK mb;
+    VP8_COMMON common;
+    vp8_writer bc, bc2;
+    // bool_writer *bc2;
+
+    VP8_CONFIG oxcf;
+
+    YV12_BUFFER_CONFIG *Source;
+    YV12_BUFFER_CONFIG *un_scaled_source;
+    INT64 source_time_stamp;
+    INT64 source_end_time_stamp;
+    unsigned int source_frame_flags;
+    YV12_BUFFER_CONFIG scaled_source;
+
+    int source_buffer_count;
+    int source_encode_index;
+    int source_alt_ref_pending;
+    int source_alt_ref_active;
+
+    int last_alt_ref_sei;
+    int is_src_frame_alt_ref;
+
+    int gold_is_last; // golden frame same as last frame ( short circuit gold searches)
+    int alt_is_last;  // Alt reference frame same as last ( short circuit altref search)
+    int gold_is_alt;  // don't do both alt and gold search ( just do gold).
+
+    //int refresh_alt_ref_frame;
+    SOURCE_SAMPLE src_buffer[MAX_LAG_BUFFERS];
+
+    YV12_BUFFER_CONFIG last_frame_uf;
+
+    char *Dest;
+
+    TOKENEXTRA *tok;
+    unsigned int tok_count;
+
+
+    unsigned int frames_since_key;
+    unsigned int key_frame_frequency;
+    unsigned int next_key;
+
+    unsigned int mode_check_freq[MAX_MODES];
+    unsigned int mode_test_hit_counts[MAX_MODES];
+    unsigned int mode_chosen_counts[MAX_MODES];
+    unsigned int mbs_tested_so_far;
+
+    unsigned int check_freq[2];
+    unsigned int do_full[2];
+
+    int rd_thresh_mult[MAX_MODES];
+    int rd_baseline_thresh[MAX_MODES];
+    int rd_threshes[MAX_MODES];
+    int mvcostbase;
+    int mvcostmultiplier;
+    int subseqblockweight;
+    int errthresh;
+
+#ifdef INTRARDOPT
+    int RDMULT;
+    int RDDIV ;
+
+    TOKENEXTRA *rdtok;
+    int intra_rd_opt;
+    vp8_writer rdbc;
+    int intra_mode_costs[10];
+#endif
+
+
+    CODING_CONTEXT coding_context;
+
+    // Rate targetting variables
+    long long prediction_error;
+    long long last_prediction_error;
+    long long intra_error;
+    long long last_intra_error;
+    long long last_auto_filter_prediction_error;
+
+#if 0
+    // Experimental RD code
+    long long frame_distortion;
+    long long last_frame_distortion;
+#endif
+
+    int last_mb_distortion;
+
+    int frames_since_auto_filter;
+
+    int this_frame_target;
+    int projected_frame_size;
+    int last_q[2];                   // Separate values for Intra/Inter
+    int target_bits_per_mb;
+
+    double rate_correction_factor;
+    double key_frame_rate_correction_factor;
+    double gf_rate_correction_factor;
+    double est_max_qcorrection_factor;
+
+    int frames_till_gf_update_due;      // Count down till next GF
+    int current_gf_interval;          // GF interval chosen when we coded the last GF
+
+    int gf_overspend_bits;            // Total bits overspent becasue of GF boost (cumulative)
+
+    int gf_group_bits;                // Projected Bits available for a group of frames including 1 GF or ARF
+    int gf_bits;                     // Bits for the golden frame or ARF - 2 pass only
+    int mid_gf_extra_bits;             // A few extra bits for the frame half way between two gfs.
+
+    int kf_group_bits;                // Projected total bits available for a key frame group of frames
+    int kf_group_error_left;           // Error score of frames still to be coded in kf group
+    int kf_bits;                     // Bits for the key frame in a key frame group - 2 pass only
+
+    int non_gf_bitrate_adjustment;     // Used in the few frames following a GF to recover the extra bits spent in that GF
+    int initial_gf_use;               // percentage use of gf 2 frames after gf
+
+    int gf_group_error_left;           // Remaining error from uncoded frames in a gf group. Two pass use only
+
+    int kf_overspend_bits;            // Extra bits spent on key frames that need to be recovered on inter frames
+    int kf_bitrate_adjustment;        // Current number of bit s to try and recover on each inter frame.
+    int max_gf_interval;
+    int baseline_gf_interval;
+    int gf_decay_rate;
+
+    INT64 key_frame_count;
+    INT64 tot_key_frame_bits;
+    int prior_key_frame_size[KEY_FRAME_CONTEXT];
+    int prior_key_frame_distance[KEY_FRAME_CONTEXT];
+    int per_frame_bandwidth;          // Current section per frame bandwidth target
+    int av_per_frame_bandwidth;        // Average frame size target for clip
+    int min_frame_bandwidth;          // Minimum allocation that should be used for any frame
+    int last_key_frame_size;
+    int intra_frame_target;
+    int inter_frame_target;
+    double output_frame_rate;
+    long long last_time_stamp_seen;
+    long long first_time_stamp_ever;
+
+    int ni_av_qi;
+    int ni_tot_qi;
+    int ni_frames;
+    int avg_frame_qindex;
+
+    int zbin_over_quant;
+    int zbin_mode_boost;
+    int zbin_mode_boost_enabled;
+
+    INT64 total_byte_count;
+
+    int buffered_mode;
+
+    int buffer_level;
+    int bits_off_target;
+
+    int rolling_target_bits;
+    int rolling_actual_bits;
+
+    int long_rolling_target_bits;
+    int long_rolling_actual_bits;
+
+    long long total_actual_bits;
+    int total_target_vs_actual;        // debug stats
+
+    int worst_quality;
+    int active_worst_quality;
+    int best_quality;
+    int active_best_quality;
+
+    int drop_frames_allowed;          // Are we permitted to drop frames?
+    int drop_frame;                  // Drop this frame?
+    int drop_count;                  // How many frames have we dropped?
+    int max_drop_count;               // How many frames should we drop?
+    int max_consec_dropped_frames;     // Limit number of consecutive frames that can be dropped.
+
+
+    int ymode_count [VP8_YMODES];        /* intra MB type cts this frame */
+    int uv_mode_count[VP8_UV_MODES];       /* intra MB type cts this frame */
+
+    unsigned int MVcount [2] [MVvals];  /* (row,col) MV cts this frame */
+
+    unsigned int coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];  /* for this frame */
+    //DECLARE_ALIGNED(16, int, coef_counts_backup [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens]);   //not used any more
+    //save vp8_tree_probs_from_distribution result for each frame to avoid repeat calculation
+    vp8_prob frame_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
+    unsigned int frame_branch_ct [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1][2];
+
+    /* Second compressed data partition contains coefficient data. */
+
+    unsigned char *output_partition2;
+    size_t output_partition2size;
+
+    pre_proc_instance ppi;
+
+    int frames_to_key;
+    int gfu_boost;
+    int kf_boost;
+    int last_boost;
+    double total_error_left;
+    double total_intra_error_left;
+    double total_coded_error_left;
+    double start_tot_err_left;
+    double min_error;
+
+    double modified_total_error_left;
+    double avg_iiratio;
+
+    int target_bandwidth;
+    long long bits_left;
+    FIRSTPASS_STATS total_stats;
+    FIRSTPASS_STATS this_frame_stats;
+    FIRSTPASS_STATS *stats_in, *stats_in_end;
+    struct vpx_codec_pkt_list  *output_pkt_list;
+    int                          first_pass_done;
+    unsigned char *fp_motion_map;
+    FILE *fp_motion_mapfile;
+    int fpmm_pos;
+
+#if 0
+    // Experimental code for lagged and one pass
+    ONEPASS_FRAMESTATS one_pass_frame_stats[MAX_LAG_BUFFERS];
+    int one_pass_frame_index;
+#endif
+
+    int decimation_factor;
+    int decimation_count;
+
+    // for real time encoding
+    int avg_encode_time;              //microsecond
+    int avg_pick_mode_time;            //microsecond
+    int Speed;
+    unsigned int cpu_freq;           //Mhz
+    int compressor_speed;
+
+    int interquantizer;
+    int auto_gold;
+    int auto_adjust_gold_quantizer;
+    int goldquantizer;
+    int goldfreq;
+    int auto_adjust_key_quantizer;
+    int keyquantizer;
+    int auto_worst_q;
+    int filter_type;
+    int cpu_used;
+    int chroma_boost;
+    int horiz_scale;
+    int vert_scale;
+    int pass;
+
+
+    int prob_intra_coded;
+    int prob_last_coded;
+    int prob_gf_coded;
+    int prob_skip_false;
+    int last_skip_false_probs[3];
+    int last_skip_probs_q[3];
+    int recent_ref_frame_usage[MAX_REF_FRAMES];
+
+    int count_mb_ref_frame_usage[MAX_REF_FRAMES];
+    int this_frame_percent_intra;
+    int last_frame_percent_intra;
+
+    int last_key_frame_q;
+    int last_kffilt_lvl;
+
+    int ref_frame_flags;
+
+    int exp[512];
+
+    SPEED_FEATURES sf;
+    int error_bins[1024];
+
+    int inter_lvl;
+    int intra_lvl;
+    int motion_lvl;
+    int motion_speed;
+    int motion_var;
+    int next_iiratio;
+    int this_iiratio;
+    int this_frame_modified_error;
+
+    double norm_intra_err_per_mb;
+    double norm_inter_err_per_mb;
+    double norm_iidiff_per_mb;
+
+    int last_best_mode_index;          // Record of mode index chosen for previous macro block.
+    int last_auto_filt_val;
+    int last_auto_filt_q;
+
+    // Data used for real time conferencing mode to help determine if it would be good to update the gf
+    int inter_zz_count;
+    int gf_bad_count;
+    int gf_update_recommended;
+    int skip_true_count;
+    int skip_false_count;
+
+    int alt_qcount;
+
+    int ready_for_new_frame;
+
+    unsigned char *segmentation_map;
+    signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];            // Segment data (can be deltas or absolute values)
+    int  segment_encode_breakout[MAX_MB_SEGMENTS];                    // segment threashold for encode breakout
+
+    unsigned char *active_map;
+    unsigned int active_map_enabled;
+    // Video conferencing cyclic refresh mode flags etc
+    // This is a mode designed to clean up the background over time in live encoding scenarious. It uses segmentation
+    int cyclic_refresh_mode_enabled;
+    int cyclic_refresh_mode_max_mbs_perframe;
+    int cyclic_refresh_mode_index;
+    int cyclic_refresh_q;
+    signed char *cyclic_refresh_map;
+
+    // multithread data
+    int current_mb_col_main;
+    int processor_core_count;
+    int b_multi_threaded;
+    int encoding_thread_count;
+
+#if CONFIG_MULTITHREAD
+    pthread_t *h_encoding_thread;
+#endif
+    MB_ROW_COMP *mb_row_ei;
+    ENCODETHREAD_DATA *en_thread_data;
+
+#if CONFIG_MULTITHREAD
+    //events
+    sem_t *h_event_mbrencoding;
+    sem_t h_event_main;
+#endif
+
+    TOKENLIST *tplist;
+    // end of multithread data
+
+
+    fractional_mv_step_fp *find_fractional_mv_step;
+    vp8_full_search_fn_t full_search_sad;
+    vp8_diamond_search_fn_t diamond_search_sad;
+    vp8_variance_fn_ptr_t fn_ptr;
+    unsigned int time_receive_data;
+    unsigned int time_compress_data;
+    unsigned int time_pick_lpf;
+    unsigned int time_encode_mb_row;
+
+    unsigned int tempdata1;
+    unsigned int tempdata2;
+
+    int base_skip_false_prob[128];
+    unsigned int section_is_low_motion;
+    unsigned int section_benefits_from_aggresive_q;
+    unsigned int section_is_fast_motion;
+    unsigned int section_intra_rating;
+
+    double section_max_qfactor;
+
+
+#if CONFIG_RUNTIME_CPU_DETECT
+    VP8_ENCODER_RTCD            rtcd;
+#endif
+#if VP8_TEMPORAL_ALT_REF
+    SOURCE_SAMPLE alt_ref_buffer;
+    unsigned char *frames[MAX_LAG_BUFFERS];
+    int fixed_divide[255];
+#endif
+
+#if CONFIG_PSNR
+    int    count;
+    double total_y;
+    double total_u;
+    double total_v;
+    double total ;
+    double total_sq_error;
+    double totalp_y;
+    double totalp_u;
+    double totalp_v;
+    double totalp;
+    double total_sq_error2;
+    int    bytes;
+    double summed_quality;
+    double summed_weights;
+    unsigned int tot_recode_hits;
+
+
+    double total_ssimg_y;
+    double total_ssimg_u;
+    double total_ssimg_v;
+    double total_ssimg_all;
+
+    int b_calculate_ssimg;
+#endif
+    int b_calculate_psnr;
+} VP8_COMP;
+
+void control_data_rate(VP8_COMP *cpi);
+
+void vp8_encode_frame(VP8_COMP *cpi);
+
+void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size);
+
+int rd_cost_intra_mb(MACROBLOCKD *x);
+
+void vp8_tokenize_mb(VP8_COMP *, MACROBLOCKD *, TOKENEXTRA **);
+
+void vp8_set_speed_features(VP8_COMP *cpi);
+
+#if CONFIG_DEBUG
+#define CHECK_MEM_ERROR(lval,expr) do {\
+        lval = (expr); \
+        if(!lval) \
+            vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,\
+                               "Failed to allocate "#lval" at %s:%d", \
+                               __FILE__,__LINE__);\
+    } while(0)
+#else
+#define CHECK_MEM_ERROR(lval,expr) do {\
+        lval = (expr); \
+        if(!lval) \
+            vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,\
+                               "Failed to allocate "#lval);\
+    } while(0)
+#endif
+#endif
diff --git a/vp8/encoder/parms.cpp b/vp8/encoder/parms.cpp
new file mode 100644 (file)
index 0000000..66fdafb
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if 0
+
+#include <map>
+#include <string>
+#include <fstream>
+extern "C"
+{
+    #include "onyx.h"
+}
+
+
+using namespace std;
+
+typedef map<string,int> Parms;
+
+#define ALLPARMS(O,DOTHIS) \
+    DOTHIS(O,  interquantizer             )\
+    DOTHIS(O,  auto_gold                   )\
+    DOTHIS(O,  auto_adjust_gold_quantizer    )\
+    DOTHIS(O,  goldquantizer              )\
+    DOTHIS(O,  goldfreq                   )\
+    DOTHIS(O,  auto_key                    )\
+    DOTHIS(O,  auto_adjust_key_quantizer     )\
+    DOTHIS(O,  keyquantizer               )\
+    DOTHIS(O,  keyfreq                    )\
+    DOTHIS(O,  pass                       )\
+    DOTHIS(O,  fixed_q                     )\
+    DOTHIS(O,  target_bandwidth            )\
+    DOTHIS(O,  auto_worst_q                 )\
+    DOTHIS(O,  worst_quality               )\
+    DOTHIS(O,  best_allowed_q               )\
+    DOTHIS(O,  end_usage                   )\
+    DOTHIS(O,  starting_buffer_level        )\
+    DOTHIS(O,  optimal_buffer_level         )\
+    DOTHIS(O,  maximum_buffer_size          )\
+    DOTHIS(O,  under_shoot_pct              )\
+    DOTHIS(O,  allow_df                    )\
+    DOTHIS(O,  drop_frames_water_mark        )\
+    DOTHIS(O,  max_allowed_datarate         )\
+    DOTHIS(O,  two_pass_vbrbias             )\
+    DOTHIS(O,  two_pass_vbrmin_section       )\
+    DOTHIS(O,  two_pass_vbrmax_section       )\
+    DOTHIS(O,  filter_type                 )\
+    DOTHIS(O,  compressor_speed            )\
+    DOTHIS(O,  mbpitch_feature             )\
+    DOTHIS(O,  allow_spatial_resampling     )\
+    DOTHIS(O,  resample_down_water_mark      )\
+    DOTHIS(O,  resample_up_water_mark        )\
+    DOTHIS(O,  noise_sensitivity           )\
+    DOTHIS(O,  horiz_scale                 )\
+    DOTHIS(O,  vert_scale                  )
+
+
+#define GET(O,V) O->V = x[#V];
+#define PUT(O,V) x[#V] = O->V;
+
+
+extern "C" void get_parms(VP8_CONFIG *ocf,char *filename)
+{
+
+    Parms x;
+    int value;
+    string variable;
+    string equal;
+
+    ifstream config_file(filename);
+
+    ALLPARMS(ocf, PUT);
+
+    // store all the parms in a map (really simple parsing)
+    while(!config_file.eof() && config_file.is_open())
+    {
+        config_file >> variable;
+        config_file >> equal;
+
+        if(equal != "=")
+            continue;
+
+        config_file >> value;
+
+        x[variable] = value;
+    }
+
+    ALLPARMS(ocf, GET);
+
+}
+
+#define PRINT(O,V) debug_file<<#V <<" = " << O->V <<"\n";
+extern "C" void print_parms(VP8_CONFIG *ocf,char *filename)
+{
+    ofstream debug_file(filename,ios_base::app);
+    ALLPARMS(ocf, PRINT);
+    debug_file << "=============================================="<<"\n";
+}
+
+#endif
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
new file mode 100644 (file)
index 0000000..d61e2ce
--- /dev/null
@@ -0,0 +1,923 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <limits.h>
+#include "vpx_ports/config.h"
+#include "onyx_int.h"
+#include "modecosts.h"
+#include "encodeintra.h"
+#include "entropymode.h"
+#include "pickinter.h"
+#include "findnearmv.h"
+#include "encodemb.h"
+#include "reconinter.h"
+#include "reconintra.h"
+#include "reconintra4x4.h"
+#include "g_common.h"
+#include "variance.h"
+#include "mcomp.h"
+
+#include "vpx_mem/vpx_mem.h"
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x) (x)
+#else
+#define IF_RTCD(x)  NULL
+#endif
+
+extern int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd);
+
+#ifdef SPEEDSTATS
+extern unsigned int cnt_pm;
+#endif
+
+extern const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES];
+extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
+
+
+extern unsigned int (*vp8_get16x16pred_error)(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+extern unsigned int (*vp8_get4x4sse_cs)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
+extern int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *best_ref_mv, int best_rd, int *, int *, int *, int, int *mvcost[2], int, int fullpixel);
+extern int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4]);
+extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, MV *mv);
+
+
+int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d, MV *bestmv, MV *ref_mv, int error_per_bit, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, int *mvcost[2])
+{
+    (void) b;
+    (void) d;
+    (void) ref_mv;
+    (void) error_per_bit;
+    (void) svf;
+    (void) vf;
+    (void) mvcost;
+    bestmv->row <<= 3;
+    bestmv->col <<= 3;
+    return 0;
+}
+
+
+static int get_inter_mbpred_error(MACROBLOCK *mb, vp8_subpixvariance_fn_t svf, vp8_variance_fn_t vf, unsigned int *sse)
+{
+
+    BLOCK *b = &mb->block[0];
+    BLOCKD *d = &mb->e_mbd.block[0];
+    unsigned char *what = (*(b->base_src) + b->src);
+    int what_stride = b->src_stride;
+    unsigned char *in_what = *(d->base_pre) + d->pre ;
+    int in_what_stride = d->pre_stride;
+    int xoffset = d->bmi.mv.as_mv.col & 7;
+    int yoffset = d->bmi.mv.as_mv.row & 7;
+
+    in_what += (d->bmi.mv.as_mv.row >> 3) * d->pre_stride + (d->bmi.mv.as_mv.col >> 3);
+
+    if (xoffset | yoffset)
+    {
+        return svf(in_what, in_what_stride, xoffset, yoffset, what, what_stride, sse);
+    }
+    else
+    {
+        return vf(what, what_stride, in_what, in_what_stride, sse);
+    }
+
+}
+
+unsigned int vp8_get16x16pred_error_c
+(
+    unsigned char *src_ptr,
+    int src_stride,
+    unsigned char *ref_ptr,
+    int ref_stride,
+    int max_sad
+)
+{
+    unsigned pred_error = 0;
+    int i, j;
+    int sum = 0;
+
+    for (i = 0; i < 16; i++)
+    {
+        int diff;
+
+        for (j = 0; j < 16; j++)
+        {
+            diff = src_ptr[j] - ref_ptr[j];
+            sum += diff;
+            pred_error += diff * diff;
+        }
+
+        src_ptr += src_stride;
+        ref_ptr += ref_stride;
+    }
+
+    pred_error -= sum * sum / 256;
+    return pred_error;
+}
+
+
+unsigned int vp8_get4x4sse_cs_c
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    int max_sad
+)
+{
+    int distortion = 0;
+    int r, c;
+
+    for (r = 0; r < 4; r++)
+    {
+        for (c = 0; c < 4; c++)
+        {
+            int diff = src_ptr[c] - ref_ptr[c];
+            distortion += diff * diff;
+        }
+
+        src_ptr += source_stride;
+        ref_ptr += recon_stride;
+    }
+
+    return distortion;
+}
+
+static int get_prediction_error(BLOCK *be, BLOCKD *b, const vp8_variance_rtcd_vtable_t *rtcd)
+{
+    unsigned char *sptr;
+    unsigned char *dptr;
+    sptr = (*(be->base_src) + be->src);
+    dptr = b->predictor;
+
+    return VARIANCE_INVOKE(rtcd, get4x4sse_cs)(sptr, be->src_stride, dptr, 16, 0x7fffffff);
+
+}
+
+static int pick_intra4x4block(
+    const VP8_ENCODER_RTCD *rtcd,
+    MACROBLOCK *x,
+    BLOCK *be,
+    BLOCKD *b,
+    B_PREDICTION_MODE *best_mode,
+    B_PREDICTION_MODE above,
+    B_PREDICTION_MODE left,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+
+    int *bestrate,
+    int *bestdistortion)
+{
+    B_PREDICTION_MODE mode;
+    int best_rd = INT_MAX;       // 1<<30
+    int rate;
+    int distortion;
+    unsigned int *mode_costs;
+    (void) l;
+    (void) a;
+
+    if (x->e_mbd.frame_type == KEY_FRAME)
+    {
+        mode_costs = x->bmode_costs[above][left];
+    }
+    else
+    {
+        mode_costs = x->inter_bmode_costs;
+    }
+
+    for (mode = B_DC_PRED; mode <= B_HE_PRED /*B_HU_PRED*/; mode++)
+    {
+        int this_rd;
+
+        rate = mode_costs[mode];
+        vp8_predict_intra4x4(b, mode, b->predictor);
+        distortion = get_prediction_error(be, b, &rtcd->variance);
+        this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate, distortion);
+
+        if (this_rd < best_rd)
+        {
+            *bestrate = rate;
+            *bestdistortion = distortion;
+            best_rd = this_rd;
+            *best_mode = mode;
+        }
+    }
+
+    b->bmi.mode = (B_PREDICTION_MODE)(*best_mode);
+    vp8_encode_intra4x4block(rtcd, x, be, b, b->bmi.mode);
+    return best_rd;
+}
+
+
+int vp8_pick_intra4x4mby_modes(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb, int *Rate, int *best_dist)
+{
+    MACROBLOCKD *const xd = &mb->e_mbd;
+    int i;
+    TEMP_CONTEXT t;
+    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
+    int error = RD_ESTIMATE(mb->rdmult, mb->rddiv, cost, 0); // Rd estimate for the cost of the block prediction mode
+    int distortion = 0;
+
+    vp8_intra_prediction_down_copy(xd);
+    vp8_setup_temp_context(&t, xd->above_context[Y1CONTEXT], xd->left_context[Y1CONTEXT], 4);
+
+    for (i = 0; i < 16; i++)
+    {
+        MODE_INFO *const mic = xd->mode_info_context;
+        const int mis = xd->mode_info_stride;
+        const B_PREDICTION_MODE A = vp8_above_bmi(mic, i, mis)->mode;
+        const B_PREDICTION_MODE L = vp8_left_bmi(mic, i)->mode;
+        B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
+        int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(d);
+
+        error += pick_intra4x4block(rtcd,
+                                    mb, mb->block + i, xd->block + i, &best_mode, A, L,
+                                    t.a + vp8_block2above[i],
+                                    t.l + vp8_block2left[i], &r, &d);
+
+        cost += r;
+        distortion += d;
+
+        mic->bmi[i].mode = xd->block[i].bmi.mode = best_mode;
+
+        // Break out case where we have already exceeded best so far value that was bassed in
+        if (distortion > *best_dist)
+            break;
+    }
+
+    for (i = 0; i < 16; i++)
+        xd->block[i].bmi.mv.as_int = 0;
+
+    *Rate = cost;
+
+    if (i == 16)
+        *best_dist = distortion;
+    else
+        *best_dist = INT_MAX;
+
+
+    return error;
+}
+
+int vp8_pick_intra_mbuv_mode(MACROBLOCK *mb)
+{
+
+    MACROBLOCKD *x = &mb->e_mbd;
+    unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride;
+    unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride;
+    unsigned char *usrc_ptr = (mb->block[16].src + *mb->block[16].base_src);
+    unsigned char *vsrc_ptr = (mb->block[20].src + *mb->block[20].base_src);
+    int uvsrc_stride = mb->block[16].src_stride;
+    unsigned char uleft_col[8];
+    unsigned char vleft_col[8];
+    unsigned char utop_left = uabove_row[-1];
+    unsigned char vtop_left = vabove_row[-1];
+    int i, j;
+    int expected_udc;
+    int expected_vdc;
+    int shift;
+    int Uaverage = 0;
+    int Vaverage = 0;
+    int diff;
+    int pred_error[4] = {0, 0, 0, 0}, best_error = INT_MAX;
+    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
+
+
+    for (i = 0; i < 8; i++)
+    {
+        uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1];
+        vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1];
+    }
+
+    if (!x->up_available && !x->left_available)
+    {
+        expected_udc = 128;
+        expected_vdc = 128;
+    }
+    else
+    {
+        shift = 2;
+
+        if (x->up_available)
+        {
+
+            for (i = 0; i < 8; i++)
+            {
+                Uaverage += uabove_row[i];
+                Vaverage += vabove_row[i];
+            }
+
+            shift ++;
+
+        }
+
+        if (x->left_available)
+        {
+            for (i = 0; i < 8; i++)
+            {
+                Uaverage += uleft_col[i];
+                Vaverage += vleft_col[i];
+            }
+
+            shift ++;
+
+        }
+
+        expected_udc = (Uaverage + (1 << (shift - 1))) >> shift;
+        expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift;
+    }
+
+
+    for (i = 0; i < 8; i++)
+    {
+        for (j = 0; j < 8; j++)
+        {
+
+            int predu = uleft_col[i] + uabove_row[j] - utop_left;
+            int predv = vleft_col[i] + vabove_row[j] - vtop_left;
+            int u_p, v_p;
+
+            u_p = usrc_ptr[j];
+            v_p = vsrc_ptr[j];
+
+            if (predu < 0)
+                predu = 0;
+
+            if (predu > 255)
+                predu = 255;
+
+            if (predv < 0)
+                predv = 0;
+
+            if (predv > 255)
+                predv = 255;
+
+
+            diff = u_p - expected_udc;
+            pred_error[DC_PRED] += diff * diff;
+            diff = v_p - expected_vdc;
+            pred_error[DC_PRED] += diff * diff;
+
+
+            diff = u_p - uabove_row[j];
+            pred_error[V_PRED] += diff * diff;
+            diff = v_p - vabove_row[j];
+            pred_error[V_PRED] += diff * diff;
+
+
+            diff = u_p - uleft_col[i];
+            pred_error[H_PRED] += diff * diff;
+            diff = v_p - vleft_col[i];
+            pred_error[H_PRED] += diff * diff;
+
+
+            diff = u_p - predu;
+            pred_error[TM_PRED] += diff * diff;
+            diff = v_p - predv;
+            pred_error[TM_PRED] += diff * diff;
+
+
+        }
+
+        usrc_ptr += uvsrc_stride;
+        vsrc_ptr += uvsrc_stride;
+
+        if (i == 3)
+        {
+            usrc_ptr = (mb->block[18].src + *mb->block[18].base_src);
+            vsrc_ptr = (mb->block[22].src + *mb->block[22].base_src);
+        }
+
+
+
+    }
+
+
+    for (i = DC_PRED; i <= TM_PRED; i++)
+    {
+        if (best_error > pred_error[i])
+        {
+            best_error = pred_error[i];
+            best_mode = (MB_PREDICTION_MODE)i;
+        }
+    }
+
+
+    mb->e_mbd.mbmi.uv_mode = best_mode;
+    return best_error;
+
+}
+
+
+int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra)
+{
+    BLOCK *b = &x->block[0];
+    BLOCKD *d = &x->e_mbd.block[0];
+    MACROBLOCKD *xd = &x->e_mbd;
+    B_MODE_INFO best_bmodes[16];
+    MB_MODE_INFO best_mbmode;
+    MV best_ref_mv1;
+    MV mode_mv[MB_MODE_COUNT];
+    MB_PREDICTION_MODE this_mode;
+    int num00;
+    int i;
+    int mdcounts[4];
+    int best_rd = INT_MAX; // 1 << 30;
+    int best_intra_rd = INT_MAX;
+    int mode_index;
+    int ref_frame_cost[MAX_REF_FRAMES];
+    int rate;
+    int rate2;
+    int distortion2;
+    int bestsme;
+    //int all_rds[MAX_MODES];         // Experimental debug code.
+    int best_mode_index = 0;
+    int sse = INT_MAX;
+
+    MV nearest_mv[4];
+    MV near_mv[4];
+    MV best_ref_mv[4];
+    int MDCounts[4][4];
+    unsigned char *y_buffer[4];
+    unsigned char *u_buffer[4];
+    unsigned char *v_buffer[4];
+
+    int skip_mode[4] = {0, 0, 0, 0};
+
+    vpx_memset(mode_mv, 0, sizeof(mode_mv));
+    vpx_memset(nearest_mv, 0, sizeof(nearest_mv));
+    vpx_memset(near_mv, 0, sizeof(near_mv));
+
+
+    // set up all the refframe dependent pointers.
+    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+    {
+        vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &nearest_mv[LAST_FRAME], &near_mv[LAST_FRAME],
+                          &best_ref_mv[LAST_FRAME], MDCounts[LAST_FRAME], LAST_FRAME, cpi->common.ref_frame_sign_bias);
+
+        y_buffer[LAST_FRAME] = cpi->common.last_frame.y_buffer + recon_yoffset;
+        u_buffer[LAST_FRAME] = cpi->common.last_frame.u_buffer + recon_uvoffset;
+        v_buffer[LAST_FRAME] = cpi->common.last_frame.v_buffer + recon_uvoffset;
+    }
+    else
+        skip_mode[LAST_FRAME] = 1;
+
+    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+    {
+        vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &nearest_mv[GOLDEN_FRAME], &near_mv[GOLDEN_FRAME],
+                          &best_ref_mv[GOLDEN_FRAME], MDCounts[GOLDEN_FRAME], GOLDEN_FRAME, cpi->common.ref_frame_sign_bias);
+
+        y_buffer[GOLDEN_FRAME] = cpi->common.golden_frame.y_buffer + recon_yoffset;
+        u_buffer[GOLDEN_FRAME] = cpi->common.golden_frame.u_buffer + recon_uvoffset;
+        v_buffer[GOLDEN_FRAME] = cpi->common.golden_frame.v_buffer + recon_uvoffset;
+    }
+    else
+        skip_mode[GOLDEN_FRAME] = 1;
+
+    if (cpi->ref_frame_flags & VP8_ALT_FLAG && cpi->source_alt_ref_active)
+    {
+        vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &nearest_mv[ALTREF_FRAME], &near_mv[ALTREF_FRAME],
+                          &best_ref_mv[ALTREF_FRAME], MDCounts[ALTREF_FRAME], ALTREF_FRAME, cpi->common.ref_frame_sign_bias);
+
+        y_buffer[ALTREF_FRAME] = cpi->common.alt_ref_frame.y_buffer + recon_yoffset;
+        u_buffer[ALTREF_FRAME] = cpi->common.alt_ref_frame.u_buffer + recon_uvoffset;
+        v_buffer[ALTREF_FRAME] = cpi->common.alt_ref_frame.v_buffer + recon_uvoffset;
+    }
+    else
+        skip_mode[ALTREF_FRAME] = 1;
+
+    cpi->mbs_tested_so_far++;          // Count of the number of MBs tested so far this frame
+
+    *returnintra = best_intra_rd;
+    x->skip = 0;
+
+    ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(cpi->prob_intra_coded);
+
+    // Special case treatment when GF and ARF are not sensible options for reference
+    if (cpi->ref_frame_flags == VP8_LAST_FLAG)
+    {
+        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_zero(255);
+        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(255)
+                                        + vp8_cost_zero(128);
+        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(255)
+                                        + vp8_cost_one(128);
+    }
+    else
+    {
+        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_zero(cpi->prob_last_coded);
+        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(cpi->prob_last_coded)
+                                        + vp8_cost_zero(cpi->prob_gf_coded);
+        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(cpi->prob_last_coded)
+                                        + vp8_cost_one(cpi->prob_gf_coded);
+    }
+
+
+
+    best_rd = INT_MAX;
+
+    x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
+
+    // if we encode a new mv this is important
+    // find the best new motion vector
+    for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
+    {
+        int frame_cost;
+        int this_rd = INT_MAX;
+
+        if (best_rd <= cpi->rd_threshes[mode_index])
+            continue;
+
+        x->e_mbd.mbmi.ref_frame = vp8_ref_frame_order[mode_index];
+
+        if (skip_mode[x->e_mbd.mbmi.ref_frame])
+            continue;
+
+        // Check to see if the testing frequency for this mode is at its max
+        // If so then prevent it from being tested and increase the threshold for its testing
+        if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
+        {
+            //if ( (cpi->mbs_tested_so_far / cpi->mode_test_hit_counts[mode_index]) <= cpi->mode_check_freq[mode_index] )
+            if (cpi->mbs_tested_so_far <= (cpi->mode_check_freq[mode_index] * cpi->mode_test_hit_counts[mode_index]))
+            {
+                // Increase the threshold for coding this mode to make it less likely to be chosen
+                cpi->rd_thresh_mult[mode_index] += 4;
+
+                if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
+                    cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
+
+                cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+
+                continue;
+            }
+        }
+
+        // We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
+        cpi->mode_test_hit_counts[mode_index] ++;
+
+        rate2 = 0;
+        distortion2 = 0;
+
+        this_mode = vp8_mode_order[mode_index];
+        
+        // Experimental debug code.
+        //all_rds[mode_index] = -1;
+
+        x->e_mbd.mbmi.mode = this_mode;
+        x->e_mbd.mbmi.uv_mode = DC_PRED;
+
+        // Work out the cost assosciated with selecting the reference frame
+        frame_cost = ref_frame_cost[x->e_mbd.mbmi.ref_frame];
+        rate2 += frame_cost;
+
+        // everything but intra
+        if (x->e_mbd.mbmi.ref_frame)
+        {
+            x->e_mbd.pre.y_buffer = y_buffer[x->e_mbd.mbmi.ref_frame];
+            x->e_mbd.pre.u_buffer = u_buffer[x->e_mbd.mbmi.ref_frame];
+            x->e_mbd.pre.v_buffer = v_buffer[x->e_mbd.mbmi.ref_frame];
+            mode_mv[NEARESTMV] = nearest_mv[x->e_mbd.mbmi.ref_frame];
+            mode_mv[NEARMV] = near_mv[x->e_mbd.mbmi.ref_frame];
+            best_ref_mv1 = best_ref_mv[x->e_mbd.mbmi.ref_frame];
+            memcpy(mdcounts, MDCounts[x->e_mbd.mbmi.ref_frame], sizeof(mdcounts));
+        }
+
+        //Only consider ZEROMV/ALTREF_FRAME for alt ref frame.
+        if (cpi->is_src_frame_alt_ref)
+        {
+            if (this_mode != ZEROMV || x->e_mbd.mbmi.ref_frame != ALTREF_FRAME)
+                continue;
+        }
+
+        switch (this_mode)
+        {
+        case B_PRED:
+            distortion2 = *returndistortion;                    // Best so far passed in as breakout value to vp8_pick_intra4x4mby_modes
+            vp8_pick_intra4x4mby_modes(IF_RTCD(&cpi->rtcd), x, &rate, &distortion2);
+            rate2 += rate;
+            distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16prederror)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, 0x7fffffff);
+
+            if (distortion2 == INT_MAX)
+            {
+                this_rd = INT_MAX;
+            }
+            else
+            {
+                this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
+
+                if (this_rd < best_intra_rd)
+                {
+                    best_intra_rd = this_rd;
+                    *returnintra = best_intra_rd ;
+                }
+            }
+
+            break;
+
+        case SPLITMV:
+
+            // Split MV modes currently not supported when RD is nopt enabled.
+            break;
+
+        case DC_PRED:
+        case V_PRED:
+        case H_PRED:
+        case TM_PRED:
+            vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
+            distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16prederror)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, 0x7fffffff);
+            rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.mode];
+            this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
+
+            if (this_rd < best_intra_rd)
+            {
+                best_intra_rd = this_rd;
+                *returnintra = best_intra_rd ;
+            }
+
+            break;
+
+        case NEWMV:
+        {
+            int thissme;
+            int step_param;
+            int further_steps;
+            int n = 0;
+            int sadpb = x->sadperbit16;
+
+            // Further step/diamond searches as necessary
+            if (cpi->Speed < 8)
+            {
+                step_param = cpi->sf.first_step + ((cpi->Speed > 5) ? 1 : 0);
+                further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+            }
+            else
+            {
+                step_param = cpi->sf.first_step + 2;
+                further_steps = 0;
+            }
+
+#if 0
+
+            // Initial step Search
+            bestsme = vp8_diamond_search_sad(x, b, d, &best_ref_mv1, &d->bmi.mv.as_mv, step_param, x->errorperbit, &num00, &cpi->fn_ptr, cpi->mb.mvsadcost, cpi->mb.mvcost);
+            mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+            mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+
+            // Further step searches
+            while (n < further_steps)
+            {
+                n++;
+
+                if (num00)
+                    num00--;
+                else
+                {
+                    thissme = vp8_diamond_search_sad(x, b, d, &best_ref_mv1, &d->bmi.mv.as_mv, step_param + n, x->errorperbit, &num00, &cpi->fn_ptr, cpi->mb.mvsadcost, x->mvcost);
+
+                    if (thissme < bestsme)
+                    {
+                        bestsme = thissme;
+                        mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                        mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+                    }
+                    else
+                    {
+                        d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
+                        d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+                    }
+                }
+            }
+
+#else
+
+            if (cpi->sf.search_method == HEX)
+            {
+                bestsme = vp8_hex_search(x, b, d, &best_ref_mv1, &d->bmi.mv.as_mv, step_param, sadpb/*x->errorperbit*/, &num00, cpi->fn_ptr.vf, cpi->fn_ptr.sdf, x->mvsadcost, x->mvcost);
+                mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+            }
+            else
+            {
+                bestsme = cpi->diamond_search_sad(x, b, d, &best_ref_mv1, &d->bmi.mv.as_mv, step_param, sadpb / 2/*x->errorperbit*/, &num00, &cpi->fn_ptr, x->mvsadcost, x->mvcost); //sadpb < 9
+                mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+
+                // Further step/diamond searches as necessary
+                n = 0;
+                //further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+
+                n = num00;
+                num00 = 0;
+
+                while (n < further_steps)
+                {
+                    n++;
+
+                    if (num00)
+                        num00--;
+                    else
+                    {
+                        thissme = cpi->diamond_search_sad(x, b, d, &best_ref_mv1, &d->bmi.mv.as_mv, step_param + n, sadpb / 4/*x->errorperbit*/, &num00, &cpi->fn_ptr, x->mvsadcost, x->mvcost); //sadpb = 9
+
+                        if (thissme < bestsme)
+                        {
+                            bestsme = thissme;
+                            mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                            mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+                        }
+                        else
+                        {
+                            d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
+                            d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+                        }
+                    }
+                }
+            }
+
+#endif
+        }
+
+        if (bestsme < INT_MAX)
+            cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv1, x->errorperbit, cpi->fn_ptr.svf, cpi->fn_ptr.vf, cpi->mb.mvcost);
+
+        mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+        mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+
+        // mv cost;
+        rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv1, cpi->mb.mvcost, 128);
+
+
+        case NEARESTMV:
+        case NEARMV:
+
+            if (mode_mv[this_mode].row == 0 && mode_mv[this_mode].col == 0)
+                continue;
+
+        case ZEROMV:
+
+            // Trap vectors that reach beyond the UMV borders
+            // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
+            // because of the lack of break statements in the previous two cases.
+            if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) ||
+                ((mode_mv[this_mode].col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].col >> 3) > x->mv_col_max))
+                continue;
+
+            rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
+            x->e_mbd.mbmi.mode = this_mode;
+            x->e_mbd.mbmi.mv.as_mv = mode_mv[this_mode];
+            x->e_mbd.block[0].bmi.mode = this_mode;
+            x->e_mbd.block[0].bmi.mv.as_int = x->e_mbd.mbmi.mv.as_int;
+
+            distortion2 = get_inter_mbpred_error(x, cpi->fn_ptr.svf, cpi->fn_ptr.vf, (unsigned int *)(&sse));
+
+            this_rd = RD_ESTIMATE(x->rdmult, x->rddiv, rate2, distortion2);
+
+            if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+            {
+                x->skip = 1;
+            }
+            else if (sse < x->encode_breakout)
+            {
+                // Check u and v to make sure skip is ok
+                int sse2 = 0;
+
+                sse2 = VP8_UVSSE(x, IF_RTCD(&cpi->rtcd.variance));
+
+                if (sse2 * 2 < x->encode_breakout)
+                    x->skip = 1;
+                else
+                    x->skip = 0;
+            }
+
+            break;
+        default:
+            break;
+        }
+
+        // Experimental debug code.
+        //all_rds[mode_index] = this_rd;
+
+        if (this_rd < best_rd || x->skip)
+        {
+            // Note index of best mode
+            best_mode_index = mode_index;
+
+            *returnrate = rate2;
+            *returndistortion = distortion2;
+            best_rd = this_rd;
+            vpx_memcpy(&best_mbmode, &x->e_mbd.mbmi, sizeof(MB_MODE_INFO));
+
+            if (this_mode == B_PRED || this_mode == SPLITMV)
+                for (i = 0; i < 16; i++)
+                {
+                    vpx_memcpy(&best_bmodes[i], &x->e_mbd.block[i].bmi, sizeof(B_MODE_INFO));
+                }
+            else
+            {
+                best_bmodes[0].mv = x->e_mbd.block[0].bmi.mv;
+            }
+
+            // Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
+            cpi->rd_thresh_mult[mode_index] = (cpi->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) ? cpi->rd_thresh_mult[mode_index] - 2 : MIN_THRESHMULT;
+            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+        }
+
+        // If the mode did not help improve the best error case then raise the threshold for testing that mode next time around.
+        else
+        {
+            cpi->rd_thresh_mult[mode_index] += 4;
+
+            if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
+                cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
+
+            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+        }
+
+        if (x->skip)
+            break;
+    }
+
+    // Reduce the activation RD thresholds for the best choice mode
+    if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2)))
+    {
+        int best_adjustment = (cpi->rd_thresh_mult[best_mode_index] >> 3);
+
+        cpi->rd_thresh_mult[best_mode_index] = (cpi->rd_thresh_mult[best_mode_index] >= (MIN_THRESHMULT + best_adjustment)) ? cpi->rd_thresh_mult[best_mode_index] - best_adjustment : MIN_THRESHMULT;
+        cpi->rd_threshes[best_mode_index] = (cpi->rd_baseline_thresh[best_mode_index] >> 7) * cpi->rd_thresh_mult[best_mode_index];
+    }
+
+    // Keep a record of best mode index for use in next loop
+    cpi->last_best_mode_index = best_mode_index;
+
+    if (best_mbmode.mode <= B_PRED)
+    {
+        x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
+        vp8_pick_intra_mbuv_mode(x);
+        best_mbmode.uv_mode = x->e_mbd.mbmi.uv_mode;
+    }
+
+
+    {
+        int this_rdbin = (*returndistortion >> 7);
+
+        if (this_rdbin >= 1024)
+        {
+            this_rdbin = 1023;
+        }
+
+        cpi->error_bins[this_rdbin] ++;
+    }
+
+
+    if (cpi->is_src_frame_alt_ref && (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME))
+    {
+        best_mbmode.mode = ZEROMV;
+        best_mbmode.ref_frame = ALTREF_FRAME;
+        best_mbmode.mv.as_int = 0;
+        best_mbmode.uv_mode = 0;
+        best_mbmode.mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+        best_mbmode.partitioning = 0;
+        best_mbmode.dc_diff = 0;
+
+        vpx_memcpy(&x->e_mbd.mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
+
+        for (i = 0; i < 16; i++)
+        {
+            vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
+        }
+
+        x->e_mbd.mbmi.mv.as_int = 0;
+
+        return best_rd;
+    }
+
+
+    // macroblock modes
+    vpx_memcpy(&x->e_mbd.mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
+
+    if (x->e_mbd.mbmi.mode == B_PRED || x->e_mbd.mbmi.mode == SPLITMV)
+        for (i = 0; i < 16; i++)
+        {
+            vpx_memcpy(&x->e_mbd.block[i].bmi, &best_bmodes[i], sizeof(B_MODE_INFO));
+
+        }
+    else
+    {
+        vp8_set_mbmode_and_mvs(x, x->e_mbd.mbmi.mode, &best_bmodes[0].mv.as_mv);
+    }
+
+    x->e_mbd.mbmi.mv.as_mv = x->e_mbd.block[15].bmi.mv.as_mv;
+
+    return best_rd;
+}
diff --git a/vp8/encoder/pickinter.h b/vp8/encoder/pickinter.h
new file mode 100644 (file)
index 0000000..fb28837
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_PICKINTER_H
+#define __INC_PICKINTER_H
+#include "vpx_ports/config.h"
+#include "onyxc_int.h"
+
+#define RD_ESTIMATE(RM,DM,R,D) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
+extern int vp8_pick_intra4x4mby_modes(const VP8_ENCODER_RTCD *, MACROBLOCK *mb, int *Rate, int *Distortion);
+extern int vp8_pick_intra_mbuv_mode(MACROBLOCK *mb);
+extern int vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra);
+#endif
diff --git a/vp8/encoder/picklpf.c b/vp8/encoder/picklpf.c
new file mode 100644 (file)
index 0000000..bbd7840
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "onyxc_int.h"
+#include "onyx_int.h"
+#include "quantize.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/yv12extend.h"
+#include "vpx_scale/vpxscale.h"
+#include "alloccommon.h"
+
+extern void vp8_loop_filter_frame(VP8_COMMON *cm,    MACROBLOCKD *mbd,  int filt_val);
+extern void vp8_loop_filter_frame_yonly(VP8_COMMON *cm,    MACROBLOCKD *mbd,  int filt_val, int sharpness_lvl);
+extern int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd);
+#if HAVE_ARMV7
+extern void vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+#endif
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x) (x)
+#else
+#define IF_RTCD(x) NULL
+#endif
+
+extern void
+(*vp8_yv12_copy_partial_frame_ptr)(YV12_BUFFER_CONFIG *src_ybc,
+                                   YV12_BUFFER_CONFIG *dst_ybc,
+                                   int Fraction);
+void
+vp8_yv12_copy_partial_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc, int Fraction)
+{
+    unsigned char *src_y, *dst_y;
+    int yheight;
+    int ystride;
+    int border;
+    int yoffset;
+    int linestocopy;
+
+    border   = src_ybc->border;
+    yheight  = src_ybc->y_height;
+    ystride  = src_ybc->y_stride;
+
+    linestocopy = (yheight >> (Fraction + 4));
+
+    if (linestocopy < 1)
+        linestocopy = 1;
+
+    linestocopy <<= 4;
+
+    yoffset  = ystride * ((yheight >> 5) * 16 - 8);
+    src_y = src_ybc->y_buffer + yoffset;
+    dst_y = dst_ybc->y_buffer + yoffset;
+
+    vpx_memcpy(dst_y, src_y, ystride *(linestocopy + 16));
+}
+
+static int vp8_calc_partial_ssl_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, int Fraction, const vp8_variance_rtcd_vtable_t *rtcd)
+{
+    int i, j;
+    int Total = 0;
+    int srcoffset, dstoffset;
+    unsigned char *src = source->y_buffer;
+    unsigned char *dst = dest->y_buffer;
+
+    int linestocopy = (source->y_height >> (Fraction + 4));
+    (void)rtcd;
+
+    if (linestocopy < 1)
+        linestocopy = 1;
+
+    linestocopy <<= 4;
+
+
+    srcoffset = source->y_stride   * (dest->y_height >> 5) * 16;
+    dstoffset = dest->y_stride     * (dest->y_height >> 5) * 16;
+
+    src += srcoffset;
+    dst += dstoffset;
+
+    // Loop through the Y plane raw and reconstruction data summing (square differences)
+    for (i = 0; i < linestocopy; i += 16)
+    {
+        for (j = 0; j < source->y_width; j += 16)
+        {
+            unsigned int sse;
+            Total += VARIANCE_INVOKE(rtcd, mse16x16)(src + j, source->y_stride, dst + j, dest->y_stride, &sse);
+        }
+
+        src += 16 * source->y_stride;
+        dst += 16 * dest->y_stride;
+    }
+
+    return Total;
+}
+
+extern void vp8_loop_filter_partial_frame
+(
+    VP8_COMMON *cm,
+    MACROBLOCKD *mbd,
+    int default_filt_lvl,
+    int sharpness_lvl,
+    int Fraction
+);
+
+// Enforce a minimum filter level based upon baseline Q
+static int get_min_filter_level(VP8_COMP *cpi, int base_qindex)
+{
+    int min_filter_level;
+
+    if (cpi->source_alt_ref_active && cpi->common.refresh_golden_frame && !cpi->common.refresh_alt_ref_frame)
+        min_filter_level = 0;
+    else
+    {
+        if (base_qindex <= 6)
+            min_filter_level = 0;
+        else if (base_qindex <= 16)
+            min_filter_level = 1;
+        else
+            min_filter_level = (base_qindex / 8);
+    }
+
+    return min_filter_level;
+}
+
+// Enforce a maximum filter level based upon baseline Q
+static int get_max_filter_level(VP8_COMP *cpi, int base_qindex)
+{
+    // PGW August 2006: Highest filter values almost always a bad idea
+
+    // jbb chg: 20100118 - not so any more with this overquant stuff allow high values
+    // with lots of intra coming in.
+    int max_filter_level = MAX_LOOP_FILTER ;//* 3 / 4;
+
+    if (cpi->section_intra_rating > 8)
+        max_filter_level = MAX_LOOP_FILTER * 3 / 4;
+
+    (void) cpi;
+    (void) base_qindex;
+
+    return max_filter_level;
+}
+
+void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    int best_err = 0;
+    int filt_err = 0;
+    int min_filter_level = 0;
+    int max_filter_level = MAX_LOOP_FILTER * 3 / 4;   // PGW August 2006: Highest filter values almost always a bad idea
+    int filt_val;
+    int best_filt_val = cm->filter_level;
+
+    //  Make a copy of the unfiltered / processed recon buffer
+    //vp8_yv12_copy_frame_ptr( cm->frame_to_show, &cpi->last_frame_uf  );
+    vp8_yv12_copy_partial_frame_ptr(cm->frame_to_show, &cpi->last_frame_uf, 3);
+
+    if (cm->frame_type == KEY_FRAME)
+        cm->sharpness_level = 0;
+    else
+        cm->sharpness_level = cpi->oxcf.Sharpness;
+
+    // Enforce a minimum filter level based upon Q
+    min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
+    max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
+
+    // Start the search at the previous frame filter level unless it is now out of range.
+    if (cm->filter_level < min_filter_level)
+        cm->filter_level = min_filter_level;
+    else if (cm->filter_level > max_filter_level)
+        cm->filter_level = max_filter_level;
+
+    filt_val = cm->filter_level;
+    best_filt_val = filt_val;
+
+    // Set up alternate filter values
+
+    // Get the err using the previous frame's filter value.
+    vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val, 0  , 3);
+    cm->last_frame_type = cm->frame_type;
+    cm->last_filter_type = cm->filter_type;
+    cm->last_sharpness_level = cm->sharpness_level;
+
+    best_err = vp8_calc_partial_ssl_err(sd, cm->frame_to_show, 3, IF_RTCD(&cpi->rtcd.variance));
+
+    //  Re-instate the unfiltered frame
+    vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show, 3);
+
+    filt_val -= (1 + ((filt_val > 10) ? 1 : 0));
+
+    // Search lower filter levels
+    while (filt_val >= min_filter_level)
+    {
+        // Apply the loop filter
+        vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val, 0, 3);
+        cm->last_frame_type = cm->frame_type;
+        cm->last_filter_type = cm->filter_type;
+        cm->last_sharpness_level = cm->sharpness_level;
+
+        // Get the err for filtered frame
+        filt_err = vp8_calc_partial_ssl_err(sd, cm->frame_to_show, 3, IF_RTCD(&cpi->rtcd.variance));
+
+
+        //  Re-instate the unfiltered frame
+        vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show, 3);
+
+
+        // Update the best case record or exit loop.
+        if (filt_err < best_err)
+        {
+            best_err = filt_err;
+            best_filt_val = filt_val;
+        }
+        else
+            break;
+
+        // Adjust filter level
+        filt_val -= (1 + ((filt_val > 10) ? 1 : 0));
+    }
+
+    // Search up (note that we have already done filt_val = cm->filter_level)
+    filt_val = cm->filter_level + (1 + ((filt_val > 10) ? 1 : 0));
+
+    if (best_filt_val == cm->filter_level)
+    {
+        // Resist raising filter level for very small gains
+        best_err -= (best_err >> 10);
+
+        while (filt_val < max_filter_level)
+        {
+            // Apply the loop filter
+            vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val, 0, 3);
+            cm->last_frame_type = cm->frame_type;
+            cm->last_filter_type = cm->filter_type;
+            cm->last_sharpness_level = cm->sharpness_level;
+
+            // Get the err for filtered frame
+            filt_err = vp8_calc_partial_ssl_err(sd, cm->frame_to_show, 3, IF_RTCD(&cpi->rtcd.variance));
+
+            //  Re-instate the unfiltered frame
+            vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show, 3);
+
+            // Update the best case record or exit loop.
+            if (filt_err < best_err)
+            {
+                // Do not raise filter level if improvement is < 1 part in 4096
+                best_err = filt_err - (filt_err >> 10);
+
+                best_filt_val = filt_val;
+            }
+            else
+                break;
+
+            // Adjust filter level
+            filt_val += (1 + ((filt_val > 10) ? 1 : 0));
+        }
+    }
+
+    cm->filter_level = best_filt_val;
+
+    if (cm->filter_level < min_filter_level)
+        cm->filter_level = min_filter_level;
+
+    if (cm->filter_level > max_filter_level)
+        cm->filter_level = max_filter_level;
+}
+
+// Stub function for now Alt LF not used
+void vp8cx_set_alt_lf_level(VP8_COMP *cpi, int filt_val)
+{
+    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
+    (void) filt_val;
+
+    mbd->segment_feature_data[MB_LVL_ALT_LF][0] = cpi->segment_feature_data[MB_LVL_ALT_LF][0];
+    mbd->segment_feature_data[MB_LVL_ALT_LF][1] = cpi->segment_feature_data[MB_LVL_ALT_LF][1];
+    mbd->segment_feature_data[MB_LVL_ALT_LF][2] = cpi->segment_feature_data[MB_LVL_ALT_LF][2];
+    mbd->segment_feature_data[MB_LVL_ALT_LF][3] = cpi->segment_feature_data[MB_LVL_ALT_LF][3];
+}
+
+void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
+{
+    VP8_COMMON *cm = &cpi->common;
+
+    int best_err = 0;
+    int filt_err = 0;
+    int min_filter_level;
+    int max_filter_level;
+    int prediction_difference = (int)(100 * abs((int)(cpi->last_auto_filter_prediction_error - cpi->prediction_error)) / (1 + cpi->prediction_error));
+
+    int filter_step;
+    int filt_high = 0;
+    int filt_mid = cm->filter_level;      // Start search at previous frame filter level
+    int filt_low = 0;
+    int filt_best;
+    int filt_direction = 0;
+
+    int Bias = 0;                       // Bias against raising loop filter and in favour of lowering it
+
+    //  Make a copy of the unfiltered / processed recon buffer
+#if HAVE_ARMV7
+    vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(cm->frame_to_show, &cpi->last_frame_uf);
+#else
+    vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cpi->last_frame_uf);
+#endif
+
+    if (cm->frame_type == KEY_FRAME)
+        cm->sharpness_level = 0;
+    else
+        cm->sharpness_level = cpi->oxcf.Sharpness;
+
+    // Enforce a minimum filter level based upon Q
+    min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
+    max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
+
+    // Start the search at the previous frame filter level unless it is now out of range.
+    filt_mid = cm->filter_level;
+
+    if (filt_mid < min_filter_level)
+        filt_mid = min_filter_level;
+    else if (filt_mid > max_filter_level)
+        filt_mid = max_filter_level;
+
+    // Define the initial step size
+    filter_step = (filt_mid < 16) ? 4 : filt_mid / 4;
+
+    // Get baseline error score
+    vp8cx_set_alt_lf_level(cpi, filt_mid);
+    vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid, 0);
+    cm->last_frame_type = cm->frame_type;
+    cm->last_filter_type = cm->filter_type;
+    cm->last_sharpness_level = cm->sharpness_level;
+
+    best_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+    filt_best = filt_mid;
+
+    //  Re-instate the unfiltered frame
+#if HAVE_ARMV7
+    vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(&cpi->last_frame_uf, cm->frame_to_show);
+#else
+    vp8_yv12_copy_frame_yonly_ptr(&cpi->last_frame_uf, cm->frame_to_show);
+#endif
+
+    while (filter_step > 0)
+    {
+        Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; //PGW change 12/12/06 for small images
+
+        // jbb chg: 20100118 - in sections with lots of new material coming in don't bias as much to a low filter value
+        if (cpi->section_intra_rating < 20)
+            Bias = Bias * cpi->section_intra_rating / 20;
+
+        filt_high = ((filt_mid + filter_step) > max_filter_level) ? max_filter_level : (filt_mid + filter_step);
+        filt_low = ((filt_mid - filter_step) < min_filter_level) ? min_filter_level : (filt_mid - filter_step);
+
+        if ((filt_direction <= 0) && (filt_low != filt_mid))
+        {
+            // Get Low filter error score
+            vp8cx_set_alt_lf_level(cpi, filt_low);
+            vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low, 0);
+            cm->last_frame_type = cm->frame_type;
+            cm->last_filter_type = cm->filter_type;
+            cm->last_sharpness_level = cm->sharpness_level;
+
+            filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+
+            //  Re-instate the unfiltered frame
+#if HAVE_ARMV7
+            vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(&cpi->last_frame_uf, cm->frame_to_show);
+#else
+            vp8_yv12_copy_frame_yonly_ptr(&cpi->last_frame_uf, cm->frame_to_show);
+#endif
+
+            // If value is close to the best so far then bias towards a lower loop filter value.
+            if ((filt_err - Bias) < best_err)
+            {
+                // Was it actually better than the previous best?
+                if (filt_err < best_err)
+                    best_err = filt_err;
+
+                filt_best = filt_low;
+            }
+        }
+
+        // Now look at filt_high
+        if ((filt_direction >= 0) && (filt_high != filt_mid))
+        {
+            vp8cx_set_alt_lf_level(cpi, filt_high);
+            vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high, 0);
+            cm->last_frame_type = cm->frame_type;
+            cm->last_filter_type = cm->filter_type;
+            cm->last_sharpness_level = cm->sharpness_level;
+
+            filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+
+            //  Re-instate the unfiltered frame
+#if HAVE_ARMV7
+            vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon(&cpi->last_frame_uf, cm->frame_to_show);
+#else
+            vp8_yv12_copy_frame_yonly_ptr(&cpi->last_frame_uf, cm->frame_to_show);
+#endif
+
+            // Was it better than the previous best?
+            if (filt_err < (best_err - Bias))
+            {
+                best_err = filt_err;
+                filt_best = filt_high;
+            }
+        }
+
+        // Half the step distance if the best filter value was the same as last time
+        if (filt_best == filt_mid)
+        {
+            filter_step = filter_step / 2;
+            filt_direction = 0;
+        }
+        else
+        {
+            filt_direction = (filt_best < filt_mid) ? -1 : 1;
+            filt_mid = filt_best;
+        }
+    }
+
+    cm->filter_level = filt_best;
+    cpi->last_auto_filt_val = filt_best;
+    cpi->last_auto_filt_q  = cm->base_qindex;
+
+    cpi->last_auto_filter_prediction_error = cpi->prediction_error;
+    cpi->frames_since_auto_filter = 0;
+}
diff --git a/vp8/encoder/ppc/csystemdependent.c b/vp8/encoder/ppc/csystemdependent.c
new file mode 100644 (file)
index 0000000..f99277f
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "variance.h"
+#include "onyx_int.h"
+
+SADFunction *vp8_sad16x16;
+SADFunction *vp8_sad16x8;
+SADFunction *vp8_sad8x16;
+SADFunction *vp8_sad8x8;
+SADFunction *vp8_sad4x4;
+
+variance_function *vp8_variance4x4;
+variance_function *vp8_variance8x8;
+variance_function *vp8_variance8x16;
+variance_function *vp8_variance16x8;
+variance_function *vp8_variance16x16;
+
+variance_function *vp8_mse16x16;
+
+sub_pixel_variance_function *vp8_sub_pixel_variance4x4;
+sub_pixel_variance_function *vp8_sub_pixel_variance8x8;
+sub_pixel_variance_function *vp8_sub_pixel_variance8x16;
+sub_pixel_variance_function *vp8_sub_pixel_variance16x8;
+sub_pixel_variance_function *vp8_sub_pixel_variance16x16;
+
+int (*vp8_block_error)(short *coeff, short *dqcoeff);
+int (*vp8_mbblock_error)(MACROBLOCK *mb, int dc);
+
+int (*vp8_mbuverror)(MACROBLOCK *mb);
+unsigned int (*vp8_get_mb_ss)(short *);
+void (*vp8_short_fdct4x4)(short *input, short *output, int pitch);
+void (*vp8_short_fdct8x4)(short *input, short *output, int pitch);
+void (*vp8_fast_fdct4x4)(short *input, short *output, int pitch);
+void (*vp8_fast_fdct8x4)(short *input, short *output, int pitch);
+void (*short_walsh4x4)(short *input, short *output, int pitch);
+
+void (*vp8_subtract_b)(BLOCK *be, BLOCKD *bd, int pitch);
+void (*vp8_subtract_mby)(short *diff, unsigned char *src, unsigned char *pred, int stride);
+void (*vp8_subtract_mbuv)(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride);
+void (*vp8_fast_quantize_b)(BLOCK *b, BLOCKD *d);
+
+unsigned int (*vp8_get16x16pred_error)(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+unsigned int (*vp8_get8x8var)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+unsigned int (*vp8_get16x16var)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+unsigned int (*vp8_get4x4sse_cs)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
+
+// c imports
+extern int block_error_c(short *coeff, short *dqcoeff);
+extern int vp8_mbblock_error_c(MACROBLOCK *mb, int dc);
+
+extern int vp8_mbuverror_c(MACROBLOCK *mb);
+extern unsigned int vp8_get8x8var_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern void short_fdct4x4_c(short *input, short *output, int pitch);
+extern void short_fdct8x4_c(short *input, short *output, int pitch);
+extern void vp8_short_walsh4x4_c(short *input, short *output, int pitch);
+
+extern void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch);
+extern void subtract_mby_c(short *diff, unsigned char *src, unsigned char *pred, int stride);
+extern void subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride);
+extern void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d);
+
+extern SADFunction sad16x16_c;
+extern SADFunction sad16x8_c;
+extern SADFunction sad8x16_c;
+extern SADFunction sad8x8_c;
+extern SADFunction sad4x4_c;
+
+extern variance_function variance16x16_c;
+extern variance_function variance8x16_c;
+extern variance_function variance16x8_c;
+extern variance_function variance8x8_c;
+extern variance_function variance4x4_c;
+extern variance_function mse16x16_c;
+
+extern sub_pixel_variance_function sub_pixel_variance4x4_c;
+extern sub_pixel_variance_function sub_pixel_variance8x8_c;
+extern sub_pixel_variance_function sub_pixel_variance8x16_c;
+extern sub_pixel_variance_function sub_pixel_variance16x8_c;
+extern sub_pixel_variance_function sub_pixel_variance16x16_c;
+
+extern unsigned int vp8_get_mb_ss_c(short *);
+extern unsigned int vp8_get16x16pred_error_c(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+extern unsigned int vp8_get8x8var_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get16x16var_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get4x4sse_cs_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
+
+// ppc
+extern int vp8_block_error_ppc(short *coeff, short *dqcoeff);
+
+extern void vp8_short_fdct4x4_ppc(short *input, short *output, int pitch);
+extern void vp8_short_fdct8x4_ppc(short *input, short *output, int pitch);
+
+extern void vp8_subtract_mby_ppc(short *diff, unsigned char *src, unsigned char *pred, int stride);
+extern void vp8_subtract_mbuv_ppc(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride);
+
+extern SADFunction vp8_sad16x16_ppc;
+extern SADFunction vp8_sad16x8_ppc;
+extern SADFunction vp8_sad8x16_ppc;
+extern SADFunction vp8_sad8x8_ppc;
+extern SADFunction vp8_sad4x4_ppc;
+
+extern variance_function vp8_variance16x16_ppc;
+extern variance_function vp8_variance8x16_ppc;
+extern variance_function vp8_variance16x8_ppc;
+extern variance_function vp8_variance8x8_ppc;
+extern variance_function vp8_variance4x4_ppc;
+extern variance_function vp8_mse16x16_ppc;
+
+extern sub_pixel_variance_function vp8_sub_pixel_variance4x4_ppc;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x8_ppc;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x16_ppc;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x8_ppc;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x16_ppc;
+
+extern unsigned int vp8_get8x8var_ppc(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get16x16var_ppc(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+
+void vp8_cmachine_specific_config(void)
+{
+    // Pure C:
+    vp8_mbuverror               = vp8_mbuverror_c;
+    vp8_fast_quantize_b           = vp8_fast_quantize_b_c;
+    vp8_short_fdct4x4            = vp8_short_fdct4x4_ppc;
+    vp8_short_fdct8x4            = vp8_short_fdct8x4_ppc;
+    vp8_fast_fdct4x4             = vp8_short_fdct4x4_ppc;
+    vp8_fast_fdct8x4             = vp8_short_fdct8x4_ppc;
+    short_walsh4x4               = vp8_short_walsh4x4_c;
+
+    vp8_variance4x4             = vp8_variance4x4_ppc;
+    vp8_variance8x8             = vp8_variance8x8_ppc;
+    vp8_variance8x16            = vp8_variance8x16_ppc;
+    vp8_variance16x8            = vp8_variance16x8_ppc;
+    vp8_variance16x16           = vp8_variance16x16_ppc;
+    vp8_mse16x16                = vp8_mse16x16_ppc;
+
+    vp8_sub_pixel_variance4x4     = vp8_sub_pixel_variance4x4_ppc;
+    vp8_sub_pixel_variance8x8     = vp8_sub_pixel_variance8x8_ppc;
+    vp8_sub_pixel_variance8x16    = vp8_sub_pixel_variance8x16_ppc;
+    vp8_sub_pixel_variance16x8    = vp8_sub_pixel_variance16x8_ppc;
+    vp8_sub_pixel_variance16x16   = vp8_sub_pixel_variance16x16_ppc;
+
+    vp8_get_mb_ss                 = vp8_get_mb_ss_c;
+    vp8_get16x16pred_error       = vp8_get16x16pred_error_c;
+    vp8_get8x8var               = vp8_get8x8var_ppc;
+    vp8_get16x16var             = vp8_get16x16var_ppc;
+    vp8_get4x4sse_cs            = vp8_get4x4sse_cs_c;
+
+    vp8_sad16x16                = vp8_sad16x16_ppc;
+    vp8_sad16x8                 = vp8_sad16x8_ppc;
+    vp8_sad8x16                 = vp8_sad8x16_ppc;
+    vp8_sad8x8                  = vp8_sad8x8_ppc;
+    vp8_sad4x4                  = vp8_sad4x4_ppc;
+
+    vp8_block_error              = vp8_block_error_ppc;
+    vp8_mbblock_error            = vp8_mbblock_error_c;
+
+    vp8_subtract_b               = vp8_subtract_b_c;
+    vp8_subtract_mby             = vp8_subtract_mby_ppc;
+    vp8_subtract_mbuv            = vp8_subtract_mbuv_ppc;
+}
diff --git a/vp8/encoder/ppc/encodemb_altivec.asm b/vp8/encoder/ppc/encodemb_altivec.asm
new file mode 100644 (file)
index 0000000..e0e976d
--- /dev/null
@@ -0,0 +1,152 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl vp8_subtract_mbuv_ppc
+    .globl vp8_subtract_mby_ppc
+
+;# r3 short *diff
+;# r4 unsigned char *usrc
+;# r5 unsigned char *vsrc
+;# r6 unsigned char *pred
+;# r7 int stride
+vp8_subtract_mbuv_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xf000
+    mtspr   256, r12            ;# set VRSAVE
+
+    li      r9, 256
+    add     r3, r3, r9
+    add     r3, r3, r9
+    add     r6, r6, r9
+
+    li      r10, 16
+    li      r9,  4
+    mtctr   r9
+
+    vspltisw v0, 0
+
+mbu_loop:
+    lvsl    v5, 0, r4           ;# permutate value for alignment
+    lvx     v1, 0, r4           ;# src
+    lvx     v2, 0, r6           ;# pred
+
+    add     r4, r4, r7
+    addi    r6, r6, 16
+
+    vperm   v1, v1, v0, v5
+
+    vmrghb  v3, v0, v1          ;# unpack high src  to short
+    vmrghb  v4, v0, v2          ;# unpack high pred to short
+
+    lvsl    v5, 0, r4           ;# permutate value for alignment
+    lvx     v1, 0, r4           ;# src
+
+    add     r4, r4, r7
+
+    vsubshs v3, v3, v4
+
+    stvx    v3, 0, r3           ;# store out diff
+
+    vperm   v1, v1, v0, v5
+
+    vmrghb  v3, v0, v1          ;# unpack high src  to short
+    vmrglb  v4, v0, v2          ;# unpack high pred to short
+
+    vsubshs v3, v3, v4
+
+    stvx    v3, r10, r3         ;# store out diff
+
+    addi    r3, r3, 32
+
+    bdnz    mbu_loop
+
+    mtctr   r9
+
+mbv_loop:
+    lvsl    v5, 0, r5           ;# permutate value for alignment
+    lvx     v1, 0, r5           ;# src
+    lvx     v2, 0, r6           ;# pred
+
+    add     r5, r5, r7
+    addi    r6, r6, 16
+
+    vperm   v1, v1, v0, v5
+
+    vmrghb  v3, v0, v1          ;# unpack high src  to short
+    vmrghb  v4, v0, v2          ;# unpack high pred to short
+
+    lvsl    v5, 0, r5           ;# permutate value for alignment
+    lvx     v1, 0, r5           ;# src
+
+    add     r5, r5, r7
+
+    vsubshs v3, v3, v4
+
+    stvx    v3, 0, r3           ;# store out diff
+
+    vperm   v1, v1, v0, v5
+
+    vmrghb  v3, v0, v1          ;# unpack high src  to short
+    vmrglb  v4, v0, v2          ;# unpack high pred to short
+
+    vsubshs v3, v3, v4
+
+    stvx    v3, r10, r3         ;# store out diff
+
+    addi    r3, r3, 32
+
+    bdnz    mbv_loop
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+;# r3 short *diff
+;# r4 unsigned char *src
+;# r5 unsigned char *pred
+;# r6 int stride
+vp8_subtract_mby_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xf800
+    mtspr   256, r12            ;# set VRSAVE
+
+    li      r10, 16
+    mtctr   r10
+
+    vspltisw v0, 0
+
+mby_loop:
+    lvx     v1, 0, r4           ;# src
+    lvx     v2, 0, r5           ;# pred
+
+    add     r4, r4, r6
+    addi    r5, r5, 16
+
+    vmrghb  v3, v0, v1          ;# unpack high src  to short
+    vmrghb  v4, v0, v2          ;# unpack high pred to short
+
+    vsubshs v3, v3, v4
+
+    stvx    v3, 0, r3           ;# store out diff
+
+    vmrglb  v3, v0, v1          ;# unpack low src  to short
+    vmrglb  v4, v0, v2          ;# unpack low pred to short
+
+    vsubshs v3, v3, v4
+
+    stvx    v3, r10, r3         ;# store out diff
+
+    addi    r3, r3, 32
+
+    bdnz    mby_loop
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
diff --git a/vp8/encoder/ppc/fdct_altivec.asm b/vp8/encoder/ppc/fdct_altivec.asm
new file mode 100644 (file)
index 0000000..eaab14c
--- /dev/null
@@ -0,0 +1,204 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl vp8_short_fdct4x4_ppc
+    .globl vp8_short_fdct8x4_ppc
+
+.macro load_c V, LABEL, OFF, R0, R1
+    lis     \R0, \LABEL@ha
+    la      \R1, \LABEL@l(\R0)
+    lvx     \V, \OFF, \R1
+.endm
+
+;# Forward and inverse DCTs are nearly identical; only differences are
+;#   in normalization (fwd is twice unitary, inv is half unitary)
+;#   and that they are of course transposes of each other.
+;#
+;#   The following three accomplish most of implementation and
+;#   are used only by ppc_idct.c and ppc_fdct.c.
+.macro prologue
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xfffc
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    li      r6, 16
+
+    load_c v0, dct_tab, 0, r9, r10
+    lvx     v1,   r6, r10
+    addi    r10, r10, 32
+    lvx     v2,    0, r10
+    lvx     v3,   r6, r10
+
+    load_c v4, ppc_dctperm_tab,  0, r9, r10
+    load_c v5, ppc_dctperm_tab, r6, r9, r10
+
+    load_c v6, round_tab, 0, r10, r9
+.endm
+
+.macro epilogue
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+.endm
+
+;# Do horiz xf on two rows of coeffs  v8 = a0 a1 a2 a3  b0 b1 b2 b3.
+;#   a/A are the even rows 0,2   b/B are the odd rows 1,3
+;#   For fwd transform, indices are horizontal positions, then frequencies.
+;#   For inverse transform, frequencies then positions.
+;#   The two resulting  A0..A3  B0..B3  are later combined
+;#   and vertically transformed.
+
+.macro two_rows_horiz Dst
+    vperm   v9, v8, v8, v4      ;# v9 = a2 a3 a0 a1  b2 b3 b0 b1
+
+    vmsumshm v10, v0, v8, v6
+    vmsumshm v10, v1, v9, v10
+    vsraw   v10, v10, v7        ;# v10 = A0 A1  B0 B1
+
+    vmsumshm v11, v2, v8, v6
+    vmsumshm v11, v3, v9, v11
+    vsraw   v11, v11, v7        ;# v11 = A2 A3  B2 B3
+
+    vpkuwum v10, v10, v11       ;# v10  = A0 A1  B0 B1  A2 A3  B2 B3
+    vperm   \Dst, v10, v10, v5  ;# Dest = A0 B0  A1 B1  A2 B2  A3 B3
+.endm
+
+;# Vertical xf on two rows. DCT values in comments are for inverse transform;
+;#   forward transform uses transpose.
+
+.macro two_rows_vert Ceven, Codd
+    vspltw  v8, \Ceven, 0       ;# v8 = c00 c10  or  c02 c12 four times
+    vspltw  v9, \Codd,  0       ;# v9 = c20 c30  or  c22 c32 ""
+    vmsumshm v8, v8, v12, v6
+    vmsumshm v8, v9, v13, v8
+    vsraw   v10, v8, v7
+
+    vspltw  v8, \Codd,  1       ;# v8 = c01 c11  or  c03 c13
+    vspltw  v9, \Ceven, 1       ;# v9 = c21 c31  or  c23 c33
+    vmsumshm v8, v8, v12, v6
+    vmsumshm v8, v9, v13, v8
+    vsraw   v8, v8, v7
+
+    vpkuwum v8, v10, v8         ;# v8 = rows 0,1  or 2,3
+.endm
+
+.macro two_rows_h Dest
+    stw     r0,  0(r8)
+    lwz     r0,  4(r3)
+    stw     r0,  4(r8)
+    lwzux   r0, r3,r5
+    stw     r0,  8(r8)
+    lwz     r0,  4(r3)
+    stw     r0, 12(r8)
+    lvx     v8,  0,r8
+    two_rows_horiz \Dest
+.endm
+
+    .align 2
+;# r3 short *input
+;# r4 short *output
+;# r5 int pitch
+vp8_short_fdct4x4_ppc:
+
+    prologue
+
+    vspltisw v7, 14             ;# == 14, fits in 5 signed bits
+    addi    r8, r1, 0
+
+
+    lwz     r0, 0(r3)
+    two_rows_h v12                ;# v12 = H00 H10  H01 H11  H02 H12  H03 H13
+
+    lwzux   r0, r3, r5
+    two_rows_h v13                ;# v13 = H20 H30  H21 H31  H22 H32  H23 H33
+
+    lvx     v6, r6, r9          ;# v6 = Vround
+    vspltisw v7, -16            ;# == 16 == -16, only low 5 bits matter
+
+    two_rows_vert v0, v1
+    stvx    v8, 0, r4
+    two_rows_vert v2, v3
+    stvx    v8, r6, r4
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 short *input
+;# r4 short *output
+;# r5 int pitch
+vp8_short_fdct8x4_ppc:
+    prologue
+
+    vspltisw v7, 14             ;# == 14, fits in 5 signed bits
+    addi    r8,  r1, 0
+    addi    r10, r3, 0
+
+    lwz     r0, 0(r3)
+    two_rows_h v12                ;# v12 = H00 H10  H01 H11  H02 H12  H03 H13
+
+    lwzux   r0, r3, r5
+    two_rows_h v13                ;# v13 = H20 H30  H21 H31  H22 H32  H23 H33
+
+    lvx     v6, r6, r9          ;# v6 = Vround
+    vspltisw v7, -16            ;# == 16 == -16, only low 5 bits matter
+
+    two_rows_vert v0, v1
+    stvx    v8, 0, r4
+    two_rows_vert v2, v3
+    stvx    v8, r6, r4
+
+    ;# Next block
+    addi    r3, r10, 8
+    addi    r4, r4, 32
+    lvx     v6, 0, r9           ;# v6 = Hround
+
+    vspltisw v7, 14             ;# == 14, fits in 5 signed bits
+    addi    r8, r1, 0
+
+    lwz     r0, 0(r3)
+    two_rows_h v12                ;# v12 = H00 H10  H01 H11  H02 H12  H03 H13
+
+    lwzux   r0, r3, r5
+    two_rows_h v13                ;# v13 = H20 H30  H21 H31  H22 H32  H23 H33
+
+    lvx     v6, r6, r9          ;# v6 = Vround
+    vspltisw v7, -16            ;# == 16 == -16, only low 5 bits matter
+
+    two_rows_vert v0, v1
+    stvx    v8, 0, r4
+    two_rows_vert v2, v3
+    stvx    v8, r6, r4
+
+    epilogue
+
+    blr
+
+    .data
+    .align 4
+ppc_dctperm_tab:
+    .byte 4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11
+    .byte 0,1,4,5, 2,3,6,7, 8,9,12,13, 10,11,14,15
+
+    .align 4
+dct_tab:
+    .short  23170, 23170,-12540,-30274, 23170, 23170,-12540,-30274
+    .short  23170, 23170, 30274, 12540, 23170, 23170, 30274, 12540
+
+    .short  23170,-23170, 30274,-12540, 23170,-23170, 30274,-12540
+    .short -23170, 23170, 12540,-30274,-23170, 23170, 12540,-30274
+
+    .align 4
+round_tab:
+    .long (1 << (14-1)), (1 << (14-1)), (1 << (14-1)), (1 << (14-1))
+    .long (1 << (16-1)), (1 << (16-1)), (1 << (16-1)), (1 << (16-1))
diff --git a/vp8/encoder/ppc/rdopt_altivec.asm b/vp8/encoder/ppc/rdopt_altivec.asm
new file mode 100644 (file)
index 0000000..917bfe0
--- /dev/null
@@ -0,0 +1,50 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl vp8_block_error_ppc
+
+    .align 2
+;# r3 short *Coeff
+;# r4 short *dqcoeff
+vp8_block_error_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xf800
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    stw     r5, 12(r1)          ;# tranfer dc to vector register
+
+    lvx     v0, 0, r3           ;# Coeff
+    lvx     v1, 0, r4           ;# dqcoeff
+
+    li      r10, 16
+
+    vspltisw v3, 0
+
+    vsubshs v0, v0, v1
+
+    vmsumshm v2, v0, v0, v3     ;# multiply differences
+
+    lvx     v0, r10, r3         ;# Coeff
+    lvx     v1, r10, r4         ;# dqcoeff
+
+    vsubshs v0, v0, v1
+
+    vmsumshm v1, v0, v0, v2     ;# multiply differences
+    vsumsws v1, v1, v3          ;# sum up
+
+    stvx    v1, 0, r1
+    lwz     r3, 12(r1)          ;# return value
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
diff --git a/vp8/encoder/ppc/sad_altivec.asm b/vp8/encoder/ppc/sad_altivec.asm
new file mode 100644 (file)
index 0000000..1102ccf
--- /dev/null
@@ -0,0 +1,276 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl vp8_sad16x16_ppc
+    .globl vp8_sad16x8_ppc
+    .globl vp8_sad8x16_ppc
+    .globl vp8_sad8x8_ppc
+    .globl vp8_sad4x4_ppc
+
+.macro load_aligned_16 V R O
+    lvsl    v3,  0, \R          ;# permutate value for alignment
+
+    lvx     v1,  0, \R
+    lvx     v2, \O, \R
+
+    vperm   \V, v1, v2, v3
+.endm
+
+.macro prologue
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffc0
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1, -32(r1)         ;# create space on the stack
+
+    li      r10, 16             ;# load offset and loop counter
+
+    vspltisw v8, 0              ;# zero out total to start
+.endm
+
+.macro epilogue
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+.endm
+
+.macro SAD_16
+    ;# v6 = abs (v4 - v5)
+    vsububs v6, v4, v5
+    vsububs v7, v5, v4
+    vor     v6, v6, v7
+
+    ;# v8 += abs (v4 - v5)
+    vsum4ubs v8, v6, v8
+.endm
+
+.macro sad_16_loop loop_label
+    lvsl    v3,  0, r5          ;# only needs to be done once per block
+
+    ;# preload a line of data before getting into the loop
+    lvx     v4, 0, r3
+    lvx     v1,  0, r5
+    lvx     v2, r10, r5
+
+    add     r5, r5, r6
+    add     r3, r3, r4
+
+    vperm   v5, v1, v2, v3
+
+    .align 4
+\loop_label:
+    ;# compute difference on first row
+    vsububs v6, v4, v5
+    vsububs v7, v5, v4
+
+    ;# load up next set of data
+    lvx     v9, 0, r3
+    lvx     v1,  0, r5
+    lvx     v2, r10, r5
+
+    ;# perform abs() of difference
+    vor     v6, v6, v7
+    add     r3, r3, r4
+
+    ;# add to the running tally
+    vsum4ubs v8, v6, v8
+
+    ;# now onto the next line
+    vperm   v5, v1, v2, v3
+    add     r5, r5, r6
+    lvx     v4, 0, r3
+
+    ;# compute difference on second row
+    vsububs v6, v9, v5
+    lvx     v1,  0, r5
+    vsububs v7, v5, v9
+    lvx     v2, r10, r5
+    vor     v6, v6, v7
+    add     r3, r3, r4
+    vsum4ubs v8, v6, v8
+    vperm   v5, v1, v2, v3
+    add     r5, r5, r6
+
+    bdnz    \loop_label
+
+    vspltisw v7, 0
+
+    vsumsws v8, v8, v7
+
+    stvx    v8, 0, r1
+    lwz     r3, 12(r1)
+.endm
+
+.macro sad_8_loop loop_label
+    .align 4
+\loop_label:
+    ;# only one of the inputs should need to be aligned.
+    load_aligned_16 v4, r3, r10
+    load_aligned_16 v5, r5, r10
+
+    ;# move onto the next line
+    add     r3, r3, r4
+    add     r5, r5, r6
+
+    ;# only one of the inputs should need to be aligned.
+    load_aligned_16 v6, r3, r10
+    load_aligned_16 v7, r5, r10
+
+    ;# move onto the next line
+    add     r3, r3, r4
+    add     r5, r5, r6
+
+    vmrghb  v4, v4, v6
+    vmrghb  v5, v5, v7
+
+    SAD_16
+
+    bdnz    \loop_label
+
+    vspltisw v7, 0
+
+    vsumsws v8, v8, v7
+
+    stvx    v8, 0, r1
+    lwz     r3, 12(r1)
+.endm
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  src_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  ref_stride
+;#
+;# r3 return value
+vp8_sad16x16_ppc:
+
+    prologue
+
+    li      r9, 8
+    mtctr   r9
+
+    sad_16_loop sad16x16_loop
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  src_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  ref_stride
+;#
+;# r3 return value
+vp8_sad16x8_ppc:
+
+    prologue
+
+    li      r9, 4
+    mtctr   r9
+
+    sad_16_loop sad16x8_loop
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  src_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  ref_stride
+;#
+;# r3 return value
+vp8_sad8x16_ppc:
+
+    prologue
+
+    li      r9, 8
+    mtctr   r9
+
+    sad_8_loop sad8x16_loop
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  src_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  ref_stride
+;#
+;# r3 return value
+vp8_sad8x8_ppc:
+
+    prologue
+
+    li      r9, 4
+    mtctr   r9
+
+    sad_8_loop sad8x8_loop
+
+    epilogue
+
+    blr
+
+.macro transfer_4x4 I P
+    lwz     r0, 0(\I)
+    add     \I, \I, \P
+
+    lwz     r7, 0(\I)
+    add     \I, \I, \P
+
+    lwz     r8, 0(\I)
+    add     \I, \I, \P
+
+    lwz     r9, 0(\I)
+
+    stw     r0,  0(r1)
+    stw     r7,  4(r1)
+    stw     r8,  8(r1)
+    stw     r9, 12(r1)
+.endm
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  src_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  ref_stride
+;#
+;# r3 return value
+vp8_sad4x4_ppc:
+
+    prologue
+
+    transfer_4x4 r3, r4
+    lvx     v4, 0, r1
+
+    transfer_4x4 r5, r6
+    lvx     v5, 0, r1
+
+    vspltisw v8, 0              ;# zero out total to start
+
+    ;# v6 = abs (v4 - v5)
+    vsububs v6, v4, v5
+    vsububs v7, v5, v4
+    vor     v6, v6, v7
+
+    ;# v8 += abs (v4 - v5)
+    vsum4ubs v7, v6, v8
+    vsumsws v7, v7, v8
+
+    stvx    v7, 0, r1
+    lwz     r3, 12(r1)
+
+    epilogue
+
+    blr
diff --git a/vp8/encoder/ppc/variance_altivec.asm b/vp8/encoder/ppc/variance_altivec.asm
new file mode 100644 (file)
index 0000000..952bf72
--- /dev/null
@@ -0,0 +1,374 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl vp8_get8x8var_ppc
+    .globl vp8_get16x16var_ppc
+    .globl vp8_mse16x16_ppc
+    .globl vp8_variance16x16_ppc
+    .globl vp8_variance16x8_ppc
+    .globl vp8_variance8x16_ppc
+    .globl vp8_variance8x8_ppc
+    .globl vp8_variance4x4_ppc
+
+.macro load_aligned_16 V R O
+    lvsl    v3,  0, \R          ;# permutate value for alignment
+
+    lvx     v1,  0, \R
+    lvx     v2, \O, \R
+
+    vperm   \V, v1, v2, v3
+.endm
+
+.macro prologue
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffc0
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1, -32(r1)         ;# create space on the stack
+
+    li      r10, 16             ;# load offset and loop counter
+
+    vspltisw v7, 0              ;# zero for merging
+    vspltisw v8, 0              ;# zero out total to start
+    vspltisw v9, 0              ;# zero out total for dif^2
+.endm
+
+.macro epilogue
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+.endm
+
+.macro compute_sum_sse
+    ;# Compute sum first.  Unpack to so signed subract
+    ;#  can be used.  Only have a half word signed
+    ;#  subract.  Do high, then low.
+    vmrghb  v2, v7, v4
+    vmrghb  v3, v7, v5
+    vsubshs v2, v2, v3
+    vsum4shs v8, v2, v8
+
+    vmrglb  v2, v7, v4
+    vmrglb  v3, v7, v5
+    vsubshs v2, v2, v3
+    vsum4shs v8, v2, v8
+
+    ;# Now compute sse.
+    vsububs v2, v4, v5
+    vsububs v3, v5, v4
+    vor     v2, v2, v3
+
+    vmsumubm v9, v2, v2, v9
+.endm
+
+.macro variance_16 DS loop_label store_sum
+\loop_label:
+    ;# only one of the inputs should need to be aligned.
+    load_aligned_16 v4, r3, r10
+    load_aligned_16 v5, r5, r10
+
+    ;# move onto the next line
+    add     r3, r3, r4
+    add     r5, r5, r6
+
+    compute_sum_sse
+
+    bdnz    \loop_label
+
+    vsumsws v8, v8, v7
+    vsumsws v9, v9, v7
+
+    stvx    v8, 0, r1
+    lwz     r3, 12(r1)
+
+    stvx    v9, 0, r1
+    lwz     r4, 12(r1)
+
+.if \store_sum
+    stw     r3, 0(r8)           ;# sum
+.endif
+    stw     r4, 0(r7)           ;# sse
+
+    mullw   r3, r3, r3          ;# sum*sum
+    srawi   r3, r3, \DS         ;# (sum*sum) >> DS
+    subf    r3, r3, r4          ;# sse - ((sum*sum) >> DS)
+.endm
+
+.macro variance_8 DS loop_label store_sum
+\loop_label:
+    ;# only one of the inputs should need to be aligned.
+    load_aligned_16 v4, r3, r10
+    load_aligned_16 v5, r5, r10
+
+    ;# move onto the next line
+    add     r3, r3, r4
+    add     r5, r5, r6
+
+    ;# only one of the inputs should need to be aligned.
+    load_aligned_16 v6, r3, r10
+    load_aligned_16 v0, r5, r10
+
+    ;# move onto the next line
+    add     r3, r3, r4
+    add     r5, r5, r6
+
+    vmrghb  v4, v4, v6
+    vmrghb  v5, v5, v0
+
+    compute_sum_sse
+
+    bdnz    \loop_label
+
+    vsumsws v8, v8, v7
+    vsumsws v9, v9, v7
+
+    stvx    v8, 0, r1
+    lwz     r3, 12(r1)
+
+    stvx    v9, 0, r1
+    lwz     r4, 12(r1)
+
+.if \store_sum
+    stw     r3, 0(r8)           ;# sum
+.endif
+    stw     r4, 0(r7)           ;# sse
+
+    mullw   r3, r3, r3          ;# sum*sum
+    srawi   r3, r3, \DS         ;# (sum*sum) >> 8
+    subf    r3, r3, r4          ;# sse - ((sum*sum) >> 8)
+.endm
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *SSE
+;# r8 int *Sum
+;#
+;# r3 return value
+vp8_get8x8var_ppc:
+
+    prologue
+
+    li      r9, 4
+    mtctr   r9
+
+    variance_8 6, get8x8var_loop, 1
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *SSE
+;# r8 int *Sum
+;#
+;# r3 return value
+vp8_get16x16var_ppc:
+
+    prologue
+
+    mtctr   r10
+
+    variance_16 8, get16x16var_loop, 1
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *sse
+;#
+;# r 3 return value
+vp8_mse16x16_ppc:
+    prologue
+
+    mtctr   r10
+
+mse16x16_loop:
+    ;# only one of the inputs should need to be aligned.
+    load_aligned_16 v4, r3, r10
+    load_aligned_16 v5, r5, r10
+
+    ;# move onto the next line
+    add     r3, r3, r4
+    add     r5, r5, r6
+
+    ;# Now compute sse.
+    vsububs v2, v4, v5
+    vsububs v3, v5, v4
+    vor     v2, v2, v3
+
+    vmsumubm v9, v2, v2, v9
+
+    bdnz    mse16x16_loop
+
+    vsumsws v9, v9, v7
+
+    stvx    v9, 0, r1
+    lwz     r3, 12(r1)
+
+    stvx    v9, 0, r1
+    lwz     r3, 12(r1)
+
+    stw     r3, 0(r7)           ;# sse
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *sse
+;#
+;# r3 return value
+vp8_variance16x16_ppc:
+
+    prologue
+
+    mtctr   r10
+
+    variance_16 8, variance16x16_loop, 0
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *sse
+;#
+;# r3 return value
+vp8_variance16x8_ppc:
+
+    prologue
+
+    li      r9, 8
+    mtctr   r9
+
+    variance_16 7, variance16x8_loop, 0
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *sse
+;#
+;# r3 return value
+vp8_variance8x16_ppc:
+
+    prologue
+
+    li      r9, 8
+    mtctr   r9
+
+    variance_8 7, variance8x16_loop, 0
+
+    epilogue
+
+    blr
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *sse
+;#
+;# r3 return value
+vp8_variance8x8_ppc:
+
+    prologue
+
+    li      r9, 4
+    mtctr   r9
+
+    variance_8 6, variance8x8_loop, 0
+
+    epilogue
+
+    blr
+
+.macro transfer_4x4 I P
+    lwz     r0, 0(\I)
+    add     \I, \I, \P
+
+    lwz     r10,0(\I)
+    add     \I, \I, \P
+
+    lwz     r8, 0(\I)
+    add     \I, \I, \P
+
+    lwz     r9, 0(\I)
+
+    stw     r0,  0(r1)
+    stw     r10, 4(r1)
+    stw     r8,  8(r1)
+    stw     r9, 12(r1)
+.endm
+
+    .align 2
+;# r3 unsigned char *src_ptr
+;# r4 int  source_stride
+;# r5 unsigned char *ref_ptr
+;# r6 int  recon_stride
+;# r7 unsigned int *sse
+;#
+;# r3 return value
+vp8_variance4x4_ppc:
+
+    prologue
+
+    transfer_4x4 r3, r4
+    lvx     v4, 0, r1
+
+    transfer_4x4 r5, r6
+    lvx     v5, 0, r1
+
+    compute_sum_sse
+
+    vsumsws v8, v8, v7
+    vsumsws v9, v9, v7
+
+    stvx    v8, 0, r1
+    lwz     r3, 12(r1)
+
+    stvx    v9, 0, r1
+    lwz     r4, 12(r1)
+
+    stw     r4, 0(r7)           ;# sse
+
+    mullw   r3, r3, r3          ;# sum*sum
+    srawi   r3, r3, 4           ;# (sum*sum) >> 4
+    subf    r3, r3, r4          ;# sse - ((sum*sum) >> 4)
+
+    epilogue
+
+    blr
diff --git a/vp8/encoder/ppc/variance_subpixel_altivec.asm b/vp8/encoder/ppc/variance_subpixel_altivec.asm
new file mode 100644 (file)
index 0000000..148a8d2
--- /dev/null
@@ -0,0 +1,864 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    .globl vp8_sub_pixel_variance4x4_ppc
+    .globl vp8_sub_pixel_variance8x8_ppc
+    .globl vp8_sub_pixel_variance8x16_ppc
+    .globl vp8_sub_pixel_variance16x8_ppc
+    .globl vp8_sub_pixel_variance16x16_ppc
+
+.macro load_c V, LABEL, OFF, R0, R1
+    lis     \R0, \LABEL@ha
+    la      \R1, \LABEL@l(\R0)
+    lvx     \V, \OFF, \R1
+.endm
+
+.macro load_vfilter V0, V1
+    load_c \V0, vfilter_b, r6, r12, r10
+
+    addi    r6,  r6, 16
+    lvx     \V1, r6, r10
+.endm
+
+.macro HProlog jump_label
+    ;# load up horizontal filter
+    slwi.   r5, r5, 4           ;# index into horizontal filter array
+
+    ;# index to the next set of vectors in the row.
+    li      r10, 16
+
+    ;# downshift by 7 ( divide by 128 ) at the end
+    vspltish v19, 7
+
+    ;# If there isn't any filtering to be done for the horizontal, then
+    ;#  just skip to the second pass.
+    beq     \jump_label
+
+    load_c v20, hfilter_b, r5, r12, r0
+
+    ;# setup constants
+    ;# v14 permutation value for alignment
+    load_c v28, b_hperm_b, 0, r12, r0
+
+    ;# index to the next set of vectors in the row.
+    li      r12, 32
+
+    ;# rounding added in on the multiply
+    vspltisw v21, 8
+    vspltisw v18, 3
+    vslw    v18, v21, v18       ;# 0x00000040000000400000004000000040
+
+    slwi.   r6, r6, 5           ;# index into vertical filter array
+.endm
+
+;# Filters a horizontal line
+;# expects:
+;#  r3  src_ptr
+;#  r4  pitch
+;#  r10 16
+;#  r12 32
+;#  v17 perm intput
+;#  v18 rounding
+;#  v19 shift
+;#  v20 filter taps
+;#  v21 tmp
+;#  v22 tmp
+;#  v23 tmp
+;#  v24 tmp
+;#  v25 tmp
+;#  v26 tmp
+;#  v27 tmp
+;#  v28 perm output
+;#
+
+.macro hfilter_8 V, hp, lp, increment_counter
+    lvsl    v17,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 9 bytes wide, output is 8 bytes.
+    lvx     v21,   0, r3
+    lvx     v22, r10, r3
+
+.if \increment_counter
+    add     r3, r3, r4
+.endif
+    vperm   v21, v21, v22, v17
+
+    vperm   v24, v21, v21, \hp  ;# v20 = 0123 1234 2345 3456
+    vperm   v25, v21, v21, \lp  ;# v21 = 4567 5678 6789 789A
+
+    vmsummbm v24, v20, v24, v18
+    vmsummbm v25, v20, v25, v18
+
+    vpkswus v24, v24, v25       ;# v24 = 0 4 8 C 1 5 9 D (16-bit)
+
+    vsrh    v24, v24, v19       ;# divide v0, v1 by 128
+
+    vpkuhus \V, v24, v24        ;# \V = scrambled 8-bit result
+.endm
+
+.macro vfilter_16 P0 P1
+    vmuleub v22, \P0, v20       ;# 64 + 4 positive taps
+    vadduhm v22, v18, v22
+    vmuloub v23, \P0, v20
+    vadduhm v23, v18, v23
+
+    vmuleub v24, \P1, v21
+    vadduhm v22, v22, v24       ;# Re = evens, saturation unnecessary
+    vmuloub v25, \P1, v21
+    vadduhm v23, v23, v25       ;# Ro = odds
+
+    vsrh    v22, v22, v19       ;# divide by 128
+    vsrh    v23, v23, v19       ;# v16 v17 = evens, odds
+    vmrghh  \P0, v22, v23       ;# v18 v19 = 16-bit result in order
+    vmrglh  v23, v22, v23
+    vpkuhus \P0, \P0, v23       ;# P0 = 8-bit result
+.endm
+
+.macro compute_sum_sse src, ref, sum, sse, t1, t2, z0
+    ;# Compute sum first.  Unpack to so signed subract
+    ;#  can be used.  Only have a half word signed
+    ;#  subract.  Do high, then low.
+    vmrghb  \t1, \z0, \src
+    vmrghb  \t2, \z0, \ref
+    vsubshs \t1, \t1, \t2
+    vsum4shs \sum, \t1, \sum
+
+    vmrglb  \t1, \z0, \src
+    vmrglb  \t2, \z0, \ref
+    vsubshs \t1, \t1, \t2
+    vsum4shs \sum, \t1, \sum
+
+    ;# Now compute sse.
+    vsububs \t1, \src, \ref
+    vsububs \t2, \ref, \src
+    vor     \t1, \t1, \t2
+
+    vmsumubm \sse, \t1, \t1, \sse
+.endm
+
+.macro variance_final sum, sse, z0, DS
+    vsumsws \sum, \sum, \z0
+    vsumsws \sse, \sse, \z0
+
+    stvx    \sum, 0, r1
+    lwz     r3, 12(r1)
+
+    stvx    \sse, 0, r1
+    lwz     r4, 12(r1)
+
+    stw     r4, 0(r9)           ;# sse
+
+    mullw   r3, r3, r3          ;# sum*sum
+    srawi   r3, r3, \DS         ;# (sum*sum) >> 8
+    subf    r3, r3, r4          ;# sse - ((sum*sum) >> 8)
+.endm
+
+.macro compute_sum_sse_16 V, increment_counter
+    load_and_align_16  v16, r7, r8, \increment_counter
+    compute_sum_sse \V, v16, v18, v19, v20, v21, v23
+.endm
+
+.macro load_and_align_16 V, R, P, increment_counter
+    lvsl    v17,  0, \R         ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v21,   0, \R
+    lvx     v22, r10, \R
+
+.if \increment_counter
+    add     \R, \R, \P
+.endif
+
+    vperm   \V, v21, v22, v17
+.endm
+
+    .align 2
+;# r3 unsigned char  *src_ptr
+;# r4 int  src_pixels_per_line
+;# r5 int  xoffset
+;# r6 int  yoffset
+;# r7 unsigned char *dst_ptr
+;# r8 int dst_pixels_per_line
+;# r9 unsigned int *sse
+;#
+;# r3 return value
+vp8_sub_pixel_variance4x4_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xf830
+    ori     r12, r12, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    HProlog second_pass_4x4_pre_copy_b
+
+    ;# Load up permutation constants
+    load_c v10, b_0123_b, 0, r12, r0
+    load_c v11, b_4567_b, 0, r12, r0
+
+    hfilter_8 v0, v10, v11, 1
+    hfilter_8 v1, v10, v11, 1
+    hfilter_8 v2, v10, v11, 1
+    hfilter_8 v3, v10, v11, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     compute_sum_sse_4x4_b
+
+    hfilter_8 v4, v10, v11, 0
+
+    b   second_pass_4x4_b
+
+second_pass_4x4_pre_copy_b:
+    slwi    r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_16 v0, r3, r4, 1
+    load_and_align_16 v1, r3, r4, 1
+    load_and_align_16 v2, r3, r4, 1
+    load_and_align_16 v3, r3, r4, 1
+    load_and_align_16 v4, r3, r4, 0
+
+second_pass_4x4_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18       ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+
+compute_sum_sse_4x4_b:
+    vspltish v18, 0             ;# sum
+    vspltish v19, 0             ;# sse
+    vspltish v23, 0             ;# unpack
+    li      r10, 16
+
+    load_and_align_16 v4, r7, r8, 1
+    load_and_align_16 v5, r7, r8, 1
+    load_and_align_16 v6, r7, r8, 1
+    load_and_align_16 v7, r7, r8, 1
+
+    vmrghb  v0, v0, v1
+    vmrghb  v1, v2, v3
+
+    vmrghb  v2, v4, v5
+    vmrghb  v3, v6, v7
+
+    load_c v10, b_hilo_b, 0, r12, r0
+
+    vperm   v0, v0, v1, v10
+    vperm   v1, v2, v3, v10
+
+    compute_sum_sse v0, v1, v18, v19, v20, v21, v23
+
+    variance_final v18, v19, v23, 4
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;# r3 unsigned char  *src_ptr
+;# r4 int  src_pixels_per_line
+;# r5 int  xoffset
+;# r6 int  yoffset
+;# r7 unsigned char *dst_ptr
+;# r8 int dst_pixels_per_line
+;# r9 unsigned int *sse
+;#
+;# r3 return value
+vp8_sub_pixel_variance8x8_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xfff0
+    ori     r12, r12, 0xffff
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    HProlog second_pass_8x8_pre_copy_b
+
+    ;# Load up permutation constants
+    load_c v10, b_0123_b, 0, r12, r0
+    load_c v11, b_4567_b, 0, r12, r0
+
+    hfilter_8 v0, v10, v11, 1
+    hfilter_8 v1, v10, v11, 1
+    hfilter_8 v2, v10, v11, 1
+    hfilter_8 v3, v10, v11, 1
+    hfilter_8 v4, v10, v11, 1
+    hfilter_8 v5, v10, v11, 1
+    hfilter_8 v6, v10, v11, 1
+    hfilter_8 v7, v10, v11, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     compute_sum_sse_8x8_b
+
+    hfilter_8 v8, v10, v11, 0
+
+    b   second_pass_8x8_b
+
+second_pass_8x8_pre_copy_b:
+    slwi.   r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_16 v0, r3, r4, 1
+    load_and_align_16 v1, r3, r4, 1
+    load_and_align_16 v2, r3, r4, 1
+    load_and_align_16 v3, r3, r4, 1
+    load_and_align_16 v4, r3, r4, 1
+    load_and_align_16 v5, r3, r4, 1
+    load_and_align_16 v6, r3, r4, 1
+    load_and_align_16 v7, r3, r4, 1
+    load_and_align_16 v8, r3, r4, 0
+
+    beq     compute_sum_sse_8x8_b
+
+second_pass_8x8_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0, v1
+    vfilter_16 v1, v2
+    vfilter_16 v2, v3
+    vfilter_16 v3, v4
+    vfilter_16 v4, v5
+    vfilter_16 v5, v6
+    vfilter_16 v6, v7
+    vfilter_16 v7, v8
+
+compute_sum_sse_8x8_b:
+    vspltish v18, 0             ;# sum
+    vspltish v19, 0             ;# sse
+    vspltish v23, 0             ;# unpack
+    li      r10, 16
+
+    vmrghb  v0, v0, v1
+    vmrghb  v1, v2, v3
+    vmrghb  v2, v4, v5
+    vmrghb  v3, v6, v7
+
+    load_and_align_16 v4,  r7, r8, 1
+    load_and_align_16 v5,  r7, r8, 1
+    load_and_align_16 v6,  r7, r8, 1
+    load_and_align_16 v7,  r7, r8, 1
+    load_and_align_16 v8,  r7, r8, 1
+    load_and_align_16 v9,  r7, r8, 1
+    load_and_align_16 v10, r7, r8, 1
+    load_and_align_16 v11, r7, r8, 0
+
+    vmrghb  v4, v4,  v5
+    vmrghb  v5, v6,  v7
+    vmrghb  v6, v8,  v9
+    vmrghb  v7, v10, v11
+
+    compute_sum_sse v0, v4, v18, v19, v20, v21, v23
+    compute_sum_sse v1, v5, v18, v19, v20, v21, v23
+    compute_sum_sse v2, v6, v18, v19, v20, v21, v23
+    compute_sum_sse v3, v7, v18, v19, v20, v21, v23
+
+    variance_final v18, v19, v23, 6
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+    blr
+
+    .align 2
+;# r3 unsigned char  *src_ptr
+;# r4 int  src_pixels_per_line
+;# r5 int  xoffset
+;# r6 int  yoffset
+;# r7 unsigned char *dst_ptr
+;# r8 int dst_pixels_per_line
+;# r9 unsigned int *sse
+;#
+;# r3 return value
+vp8_sub_pixel_variance8x16_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xfffc
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1,-32(r1)          ;# create space on the stack
+
+    HProlog second_pass_8x16_pre_copy_b
+
+    ;# Load up permutation constants
+    load_c v29, b_0123_b, 0, r12, r0
+    load_c v30, b_4567_b, 0, r12, r0
+
+    hfilter_8 v0,  v29, v30, 1
+    hfilter_8 v1,  v29, v30, 1
+    hfilter_8 v2,  v29, v30, 1
+    hfilter_8 v3,  v29, v30, 1
+    hfilter_8 v4,  v29, v30, 1
+    hfilter_8 v5,  v29, v30, 1
+    hfilter_8 v6,  v29, v30, 1
+    hfilter_8 v7,  v29, v30, 1
+    hfilter_8 v8,  v29, v30, 1
+    hfilter_8 v9,  v29, v30, 1
+    hfilter_8 v10, v29, v30, 1
+    hfilter_8 v11, v29, v30, 1
+    hfilter_8 v12, v29, v30, 1
+    hfilter_8 v13, v29, v30, 1
+    hfilter_8 v14, v29, v30, 1
+    hfilter_8 v15, v29, v30, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     compute_sum_sse_8x16_b
+
+    hfilter_8 v16, v29, v30, 0
+
+    b   second_pass_8x16_b
+
+second_pass_8x16_pre_copy_b:
+    slwi.   r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_16 v0,  r3, r4, 1
+    load_and_align_16 v1,  r3, r4, 1
+    load_and_align_16 v2,  r3, r4, 1
+    load_and_align_16 v3,  r3, r4, 1
+    load_and_align_16 v4,  r3, r4, 1
+    load_and_align_16 v5,  r3, r4, 1
+    load_and_align_16 v6,  r3, r4, 1
+    load_and_align_16 v7,  r3, r4, 1
+    load_and_align_16 v8,  r3, r4, 1
+    load_and_align_16 v9,  r3, r4, 1
+    load_and_align_16 v10, r3, r4, 1
+    load_and_align_16 v11, r3, r4, 1
+    load_and_align_16 v12, r3, r4, 1
+    load_and_align_16 v13, r3, r4, 1
+    load_and_align_16 v14, r3, r4, 1
+    load_and_align_16 v15, r3, r4, 1
+    load_and_align_16 v16, r3, r4, 0
+
+    beq     compute_sum_sse_8x16_b
+
+second_pass_8x16_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+    vfilter_16 v4,  v5
+    vfilter_16 v5,  v6
+    vfilter_16 v6,  v7
+    vfilter_16 v7,  v8
+    vfilter_16 v8,  v9
+    vfilter_16 v9,  v10
+    vfilter_16 v10, v11
+    vfilter_16 v11, v12
+    vfilter_16 v12, v13
+    vfilter_16 v13, v14
+    vfilter_16 v14, v15
+    vfilter_16 v15, v16
+
+compute_sum_sse_8x16_b:
+    vspltish v18, 0             ;# sum
+    vspltish v19, 0             ;# sse
+    vspltish v23, 0             ;# unpack
+    li      r10, 16
+
+    vmrghb  v0, v0,  v1
+    vmrghb  v1, v2,  v3
+    vmrghb  v2, v4,  v5
+    vmrghb  v3, v6,  v7
+    vmrghb  v4, v8,  v9
+    vmrghb  v5, v10, v11
+    vmrghb  v6, v12, v13
+    vmrghb  v7, v14, v15
+
+    load_and_align_16 v8,  r7, r8, 1
+    load_and_align_16 v9,  r7, r8, 1
+    load_and_align_16 v10, r7, r8, 1
+    load_and_align_16 v11, r7, r8, 1
+    load_and_align_16 v12, r7, r8, 1
+    load_and_align_16 v13, r7, r8, 1
+    load_and_align_16 v14, r7, r8, 1
+    load_and_align_16 v15, r7, r8, 1
+
+    vmrghb  v8,  v8,  v9
+    vmrghb  v9,  v10, v11
+    vmrghb  v10, v12, v13
+    vmrghb  v11, v14, v15
+
+    compute_sum_sse v0, v8,  v18, v19, v20, v21, v23
+    compute_sum_sse v1, v9,  v18, v19, v20, v21, v23
+    compute_sum_sse v2, v10, v18, v19, v20, v21, v23
+    compute_sum_sse v3, v11, v18, v19, v20, v21, v23
+
+    load_and_align_16 v8,  r7, r8, 1
+    load_and_align_16 v9,  r7, r8, 1
+    load_and_align_16 v10, r7, r8, 1
+    load_and_align_16 v11, r7, r8, 1
+    load_and_align_16 v12, r7, r8, 1
+    load_and_align_16 v13, r7, r8, 1
+    load_and_align_16 v14, r7, r8, 1
+    load_and_align_16 v15, r7, r8, 0
+
+    vmrghb  v8,  v8,  v9
+    vmrghb  v9,  v10, v11
+    vmrghb  v10, v12, v13
+    vmrghb  v11, v14, v15
+
+    compute_sum_sse v4, v8,  v18, v19, v20, v21, v23
+    compute_sum_sse v5, v9,  v18, v19, v20, v21, v23
+    compute_sum_sse v6, v10, v18, v19, v20, v21, v23
+    compute_sum_sse v7, v11, v18, v19, v20, v21, v23
+
+    variance_final v18, v19, v23, 7
+
+    addi    r1, r1, 32          ;# recover stack
+    mtspr   256, r11            ;# reset old VRSAVE
+    blr
+
+;# Filters a horizontal line
+;# expects:
+;#  r3  src_ptr
+;#  r4  pitch
+;#  r10 16
+;#  r12 32
+;#  v17 perm intput
+;#  v18 rounding
+;#  v19 shift
+;#  v20 filter taps
+;#  v21 tmp
+;#  v22 tmp
+;#  v23 tmp
+;#  v24 tmp
+;#  v25 tmp
+;#  v26 tmp
+;#  v27 tmp
+;#  v28 perm output
+;#
+.macro hfilter_16 V, increment_counter
+
+    lvsl    v17,  0, r3         ;# permutate value for alignment
+
+    ;# input to filter is 21 bytes wide, output is 16 bytes.
+    ;#  input will can span three vectors if not aligned correctly.
+    lvx     v21,   0, r3
+    lvx     v22, r10, r3
+    lvx     v23, r12, r3
+
+.if \increment_counter
+    add     r3, r3, r4
+.endif
+    vperm   v21, v21, v22, v17
+    vperm   v22, v22, v23, v17  ;# v8 v9 = 21 input pixels left-justified
+
+    ;# set 0
+    vmsummbm v24, v20, v21, v18 ;# taps times elements
+
+    ;# set 1
+    vsldoi  v23, v21, v22, 1
+    vmsummbm v25, v20, v23, v18
+
+    ;# set 2
+    vsldoi  v23, v21, v22, 2
+    vmsummbm v26, v20, v23, v18
+
+    ;# set 3
+    vsldoi  v23, v21, v22, 3
+    vmsummbm v27, v20, v23, v18
+
+    vpkswus v24, v24, v25       ;# v24 = 0 4 8 C 1 5 9 D (16-bit)
+    vpkswus v25, v26, v27       ;# v25 = 2 6 A E 3 7 B F
+
+    vsrh    v24, v24, v19       ;# divide v0, v1 by 128
+    vsrh    v25, v25, v19
+
+    vpkuhus \V, v24, v25        ;# \V = scrambled 8-bit result
+    vperm   \V, \V, v0, v28     ;# \V = correctly-ordered result
+.endm
+
+    .align 2
+;# r3 unsigned char  *src_ptr
+;# r4 int  src_pixels_per_line
+;# r5 int  xoffset
+;# r6 int  yoffset
+;# r7 unsigned char *dst_ptr
+;# r8 int dst_pixels_per_line
+;# r9 unsigned int *sse
+;#
+;# r3 return value
+vp8_sub_pixel_variance16x8_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1, -32(r1)         ;# create space on the stack
+
+    HProlog second_pass_16x8_pre_copy_b
+
+    hfilter_16 v0, 1
+    hfilter_16 v1, 1
+    hfilter_16 v2, 1
+    hfilter_16 v3, 1
+    hfilter_16 v4, 1
+    hfilter_16 v5, 1
+    hfilter_16 v6, 1
+    hfilter_16 v7, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     compute_sum_sse_16x8_b
+
+    hfilter_16 v8, 0
+
+    b   second_pass_16x8_b
+
+second_pass_16x8_pre_copy_b:
+    slwi.   r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_16  v0,  r3, r4, 1
+    load_and_align_16  v1,  r3, r4, 1
+    load_and_align_16  v2,  r3, r4, 1
+    load_and_align_16  v3,  r3, r4, 1
+    load_and_align_16  v4,  r3, r4, 1
+    load_and_align_16  v5,  r3, r4, 1
+    load_and_align_16  v6,  r3, r4, 1
+    load_and_align_16  v7,  r3, r4, 1
+    load_and_align_16  v8,  r3, r4, 1
+
+    beq     compute_sum_sse_16x8_b
+
+second_pass_16x8_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+    vfilter_16 v4,  v5
+    vfilter_16 v5,  v6
+    vfilter_16 v6,  v7
+    vfilter_16 v7,  v8
+
+compute_sum_sse_16x8_b:
+    vspltish v18, 0             ;# sum
+    vspltish v19, 0             ;# sse
+    vspltish v23, 0             ;# unpack
+    li      r10, 16
+
+    compute_sum_sse_16 v0, 1
+    compute_sum_sse_16 v1, 1
+    compute_sum_sse_16 v2, 1
+    compute_sum_sse_16 v3, 1
+    compute_sum_sse_16 v4, 1
+    compute_sum_sse_16 v5, 1
+    compute_sum_sse_16 v6, 1
+    compute_sum_sse_16 v7, 0
+
+    variance_final v18, v19, v23, 7
+
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .align 2
+;# r3 unsigned char  *src_ptr
+;# r4 int  src_pixels_per_line
+;# r5 int  xoffset
+;# r6 int  yoffset
+;# r7 unsigned char *dst_ptr
+;# r8 int dst_pixels_per_line
+;# r9 unsigned int *sse
+;#
+;# r3 return value
+vp8_sub_pixel_variance16x16_ppc:
+    mfspr   r11, 256            ;# get old VRSAVE
+    oris    r12, r11, 0xffff
+    ori     r12, r12, 0xfff8
+    mtspr   256, r12            ;# set VRSAVE
+
+    stwu    r1, -32(r1)         ;# create space on the stack
+
+    HProlog second_pass_16x16_pre_copy_b
+
+    hfilter_16 v0,  1
+    hfilter_16 v1,  1
+    hfilter_16 v2,  1
+    hfilter_16 v3,  1
+    hfilter_16 v4,  1
+    hfilter_16 v5,  1
+    hfilter_16 v6,  1
+    hfilter_16 v7,  1
+    hfilter_16 v8,  1
+    hfilter_16 v9,  1
+    hfilter_16 v10, 1
+    hfilter_16 v11, 1
+    hfilter_16 v12, 1
+    hfilter_16 v13, 1
+    hfilter_16 v14, 1
+    hfilter_16 v15, 1
+
+    ;# Finished filtering main horizontal block.  If there is no
+    ;#  vertical filtering, jump to storing the data.  Otherwise
+    ;#  load up and filter the additional line that is needed
+    ;#  for the vertical filter.
+    beq     compute_sum_sse_16x16_b
+
+    hfilter_16 v16, 0
+
+    b   second_pass_16x16_b
+
+second_pass_16x16_pre_copy_b:
+    slwi.   r6, r6, 5           ;# index into vertical filter array
+
+    load_and_align_16  v0,  r3, r4, 1
+    load_and_align_16  v1,  r3, r4, 1
+    load_and_align_16  v2,  r3, r4, 1
+    load_and_align_16  v3,  r3, r4, 1
+    load_and_align_16  v4,  r3, r4, 1
+    load_and_align_16  v5,  r3, r4, 1
+    load_and_align_16  v6,  r3, r4, 1
+    load_and_align_16  v7,  r3, r4, 1
+    load_and_align_16  v8,  r3, r4, 1
+    load_and_align_16  v9,  r3, r4, 1
+    load_and_align_16  v10, r3, r4, 1
+    load_and_align_16  v11, r3, r4, 1
+    load_and_align_16  v12, r3, r4, 1
+    load_and_align_16  v13, r3, r4, 1
+    load_and_align_16  v14, r3, r4, 1
+    load_and_align_16  v15, r3, r4, 1
+    load_and_align_16  v16, r3, r4, 0
+
+    beq     compute_sum_sse_16x16_b
+
+second_pass_16x16_b:
+    vspltish v20, 8
+    vspltish v18, 3
+    vslh    v18, v20, v18   ;# 0x0040 0040 0040 0040 0040 0040 0040 0040
+
+    load_vfilter v20, v21
+
+    vfilter_16 v0,  v1
+    vfilter_16 v1,  v2
+    vfilter_16 v2,  v3
+    vfilter_16 v3,  v4
+    vfilter_16 v4,  v5
+    vfilter_16 v5,  v6
+    vfilter_16 v6,  v7
+    vfilter_16 v7,  v8
+    vfilter_16 v8,  v9
+    vfilter_16 v9,  v10
+    vfilter_16 v10, v11
+    vfilter_16 v11, v12
+    vfilter_16 v12, v13
+    vfilter_16 v13, v14
+    vfilter_16 v14, v15
+    vfilter_16 v15, v16
+
+compute_sum_sse_16x16_b:
+    vspltish v18, 0             ;# sum
+    vspltish v19, 0             ;# sse
+    vspltish v23, 0             ;# unpack
+    li      r10, 16
+
+    compute_sum_sse_16 v0,  1
+    compute_sum_sse_16 v1,  1
+    compute_sum_sse_16 v2,  1
+    compute_sum_sse_16 v3,  1
+    compute_sum_sse_16 v4,  1
+    compute_sum_sse_16 v5,  1
+    compute_sum_sse_16 v6,  1
+    compute_sum_sse_16 v7,  1
+    compute_sum_sse_16 v8,  1
+    compute_sum_sse_16 v9,  1
+    compute_sum_sse_16 v10, 1
+    compute_sum_sse_16 v11, 1
+    compute_sum_sse_16 v12, 1
+    compute_sum_sse_16 v13, 1
+    compute_sum_sse_16 v14, 1
+    compute_sum_sse_16 v15, 0
+
+    variance_final v18, v19, v23, 8
+
+    addi    r1, r1, 32          ;# recover stack
+
+    mtspr   256, r11            ;# reset old VRSAVE
+
+    blr
+
+    .data
+
+    .align 4
+hfilter_b:
+    .byte   128,  0,  0,  0,128,  0,  0,  0,128,  0,  0,  0,128,  0,  0,  0
+    .byte   112, 16,  0,  0,112, 16,  0,  0,112, 16,  0,  0,112, 16,  0,  0
+    .byte    96, 32,  0,  0, 96, 32,  0,  0, 96, 32,  0,  0, 96, 32,  0,  0
+    .byte    80, 48,  0,  0, 80, 48,  0,  0, 80, 48,  0,  0, 80, 48,  0,  0
+    .byte    64, 64,  0,  0, 64, 64,  0,  0, 64, 64,  0,  0, 64, 64,  0,  0
+    .byte    48, 80,  0,  0, 48, 80,  0,  0, 48, 80,  0,  0, 48, 80,  0,  0
+    .byte    32, 96,  0,  0, 32, 96,  0,  0, 32, 96,  0,  0, 32, 96,  0,  0
+    .byte    16,112,  0,  0, 16,112,  0,  0, 16,112,  0,  0, 16,112,  0,  0
+
+    .align 4
+vfilter_b:
+    .byte   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
+    .byte     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+    .byte   112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112
+    .byte    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+    .byte    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96
+    .byte    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
+    .byte    80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
+    .byte    48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
+    .byte    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+    .byte    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+    .byte    48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
+    .byte    80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
+    .byte    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
+    .byte    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96
+    .byte    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
+    .byte   112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112
+
+    .align 4
+b_hperm_b:
+    .byte     0,  4,  8, 12,  1,  5,  9, 13,  2,  6, 10, 14,  3,  7, 11, 15
+
+    .align 4
+b_0123_b:
+    .byte     0,  1,  2,  3,  1,  2,  3,  4,  2,  3,  4,  5,  3,  4,  5,  6
+
+    .align 4
+b_4567_b:
+    .byte     4,  5,  6,  7,  5,  6,  7,  8,  6,  7,  8,  9,  7,  8,  9, 10
+
+b_hilo_b:
+    .byte     0,  1,  2,  3,  4,  5,  6,  7, 16, 17, 18, 19, 20, 21, 22, 23
diff --git a/vp8/encoder/preproc.c b/vp8/encoder/preproc.c
new file mode 100644 (file)
index 0000000..d2a13dc
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     preproc.c
+*
+*   Description  :     Simple pre-processor.
+*
+****************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+
+#include "memory.h"
+#include "preproc7.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+*  Macros
+****************************************************************************/
+#define FRAMECOUNT 7
+#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
+
+/****************************************************************************
+*  Imports
+****************************************************************************/
+extern void vp8_get_processor_flags(int *mmx_enabled, int *xmm_enabled, int *wmt_enabled);
+
+/****************************************************************************
+*  Exported Global Variables
+****************************************************************************/
+void (*temp_filter)(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int bytes, int strength);
+void temp_filter_mmx
+(
+    pre_proc_instance *ppi,
+    unsigned char *s,
+    unsigned char *d,
+    int bytes,
+    int strength
+);
+void temp_filter_wmt
+(
+    pre_proc_instance *ppi,
+    unsigned char *s,
+    unsigned char *d,
+    int bytes,
+    int strength
+);
+
+/****************************************************************************
+ *
+ *  ROUTINE       : temp_filter_c
+ *
+ *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
+ *                  unsigned char *s     : Pointer to source frame.
+ *                  unsigned char *d     : Pointer to destination frame.
+ *                  int bytes            : Number of bytes to filter.
+ *                  int strength         : Strength of filter to apply.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs a closesness adjusted temporarl blur
+ *
+ *  SPECIAL NOTES : Destination frame can be same as source frame.
+ *
+ ****************************************************************************/
+void temp_filter_c
+(
+    pre_proc_instance *ppi,
+    unsigned char *s,
+    unsigned char *d,
+    int bytes,
+    int strength
+)
+{
+    int byte = 0;
+    unsigned char *frameptr = ppi->frame_buffer;
+
+    if (ppi->frame == 0)
+    {
+        do
+        {
+            int frame = 0;
+
+            do
+            {
+                *frameptr = s[byte];
+                ++frameptr;
+                ++frame;
+            }
+            while (frame < FRAMECOUNT);
+
+            d[byte] = s[byte];
+
+            ++byte;
+        }
+        while (byte < bytes);
+    }
+    else
+    {
+        int modifier;
+        int offset = (ppi->frame % FRAMECOUNT);
+
+        do
+        {
+            int accumulator = 0;
+            int count = 0;
+            int frame = 0;
+
+            frameptr[offset] = s[byte];
+
+            do
+            {
+                int pixel_value = *frameptr;
+
+                modifier   = s[byte];
+                modifier  -= pixel_value;
+                modifier  *= modifier;
+                modifier >>= strength;
+                modifier  *= 3;
+
+                if (modifier > 16)
+                    modifier = 16;
+
+                modifier = 16 - modifier;
+
+                accumulator += modifier * pixel_value;
+
+                count += modifier;
+
+                frameptr++;
+
+                ++frame;
+            }
+            while (frame < FRAMECOUNT);
+
+            accumulator += (count >> 1);
+            accumulator *= ppi->fixed_divide[count];
+            accumulator >>= 16;
+
+            d[byte] = accumulator;
+
+            ++byte;
+        }
+        while (byte < bytes);
+    }
+
+    ++ppi->frame;
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : delete_pre_proc
+ *
+ *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Deletes a pre-processing instance.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void delete_pre_proc(pre_proc_instance *ppi)
+{
+    if (ppi->frame_buffer_alloc)
+        vpx_free(ppi->frame_buffer_alloc);
+
+    ppi->frame_buffer_alloc = 0;
+    ppi->frame_buffer      = 0;
+
+    if (ppi->fixed_divide_alloc)
+        vpx_free(ppi->fixed_divide_alloc);
+
+    ppi->fixed_divide_alloc = 0;
+    ppi->fixed_divide      = 0;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : init_pre_proc
+ *
+ *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
+ *                  int frame_size        : Number of bytes in one frame.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int: 1 if successful, 0 if failed.
+ *
+ *  FUNCTION      : Initializes prepprocessor instance.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+int init_pre_proc7(pre_proc_instance *ppi, int frame_size)
+{
+    int i;
+    int mmx_enabled;
+    int xmm_enabled;
+    int wmt_enabled;
+
+    vp8_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled);
+
+    if (wmt_enabled)
+        temp_filter = temp_filter_wmt;
+    else if (mmx_enabled)
+        temp_filter = temp_filter_mmx;
+    else
+        temp_filter = temp_filter_c;
+
+
+    delete_pre_proc(ppi);
+
+    ppi->frame_buffer_alloc = vpx_malloc(32 + frame_size * FRAMECOUNT * sizeof(unsigned char));
+
+    if (!ppi->frame_buffer_alloc)
+    {
+        delete_pre_proc(ppi);
+        return 0;
+    }
+
+    ppi->frame_buffer = (unsigned char *) ROUNDUP32(ppi->frame_buffer_alloc);
+
+    ppi->fixed_divide_alloc = vpx_malloc(32 + 255 * sizeof(unsigned int));
+
+    if (!ppi->fixed_divide_alloc)
+    {
+        delete_pre_proc(ppi);
+        return 0;
+    }
+
+    ppi->fixed_divide = (unsigned int *) ROUNDUP32(ppi->fixed_divide_alloc);
+
+    for (i = 1; i < 255; i++)
+        ppi->fixed_divide[i] = 0x10000 / i;
+
+    return 1;
+}
diff --git a/vp8/encoder/psnr.c b/vp8/encoder/psnr.c
new file mode 100644 (file)
index 0000000..0e34cec
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/yv12config.h"
+#include "math.h"
+#include "systemdependent.h" /* for vp8_clear_system_state() */
+
+#define MAX_PSNR 60
+
+double vp8_mse2psnr(double Samples, double Peak, double Mse)
+{
+    double psnr;
+
+    if ((double)Mse > 0.0)
+        psnr = 10.0 * log10(Peak * Peak * Samples / Mse);
+    else
+        psnr = MAX_PSNR;      // Limit to prevent / 0
+
+    if (psnr > MAX_PSNR)
+        psnr = MAX_PSNR;
+
+    return psnr;
+}
+
+double vp8_calc_psnr(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, double *YPsnr, double *UPsnr, double *VPsnr, double *sq_error)
+{
+    int i, j;
+    int Diff;
+    double frame_psnr;
+    double Total;
+    double grand_total;
+    unsigned char *src = source->y_buffer;
+    unsigned char *dst = dest->y_buffer;
+
+    Total = 0.0;
+    grand_total = 0.0;
+
+    // Loop throught the Y plane raw and reconstruction data summing (square differences)
+    for (i = 0; i < source->y_height; i++)
+    {
+
+        for (j = 0; j < source->y_width; j++)
+        {
+            Diff        = (int)(src[j]) - (int)(dst[j]);
+            Total      += Diff * Diff;
+        }
+
+        src += source->y_stride;
+        dst += dest->y_stride;
+    }
+
+    // Work out Y PSNR
+    *YPsnr = vp8_mse2psnr(source->y_height * source->y_width, 255.0, Total);
+    grand_total += Total;
+    Total = 0;
+
+
+    // Loop through the U plane
+    src = source->u_buffer;
+    dst = dest->u_buffer;
+
+    for (i = 0; i < source->uv_height; i++)
+    {
+
+        for (j = 0; j < source->uv_width; j++)
+        {
+            Diff        = (int)(src[j]) - (int)(dst[j]);
+            Total      += Diff * Diff;
+        }
+
+        src += source->uv_stride;
+        dst += dest->uv_stride;
+    }
+
+    // Work out U PSNR
+    *UPsnr = vp8_mse2psnr(source->uv_height * source->uv_width, 255.0, Total);
+    grand_total += Total;
+    Total = 0;
+
+
+    // V PSNR
+    src = source->v_buffer;
+    dst = dest->v_buffer;
+
+    for (i = 0; i < source->uv_height; i++)
+    {
+
+        for (j = 0; j < source->uv_width; j++)
+        {
+            Diff        = (int)(src[j]) - (int)(dst[j]);
+            Total      += Diff * Diff;
+        }
+
+        src += source->uv_stride;
+        dst += dest->uv_stride;
+    }
+
+    // Work out UV PSNR
+    *VPsnr = vp8_mse2psnr(source->uv_height * source->uv_width, 255.0, Total);
+    grand_total += Total;
+    Total = 0;
+
+    // Work out total PSNR
+    frame_psnr = vp8_mse2psnr(source->y_height * source->y_width * 3 / 2 , 255.0, grand_total);
+
+    *sq_error = 1.0 * grand_total;
+
+    return frame_psnr;
+}
diff --git a/vp8/encoder/psnr.h b/vp8/encoder/psnr.h
new file mode 100644 (file)
index 0000000..9f6ca0b
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_PSNR_H
+#define __INC_PSNR_H
+
+extern double vp8_mse2psnr(double Samples, double Peak, double Mse);
+extern double vp8_calc_psnr(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, double *YPsnr, double *UPsnr, double *VPsnr, double *sq_error);
+
+#endif
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c
new file mode 100644 (file)
index 0000000..6028ebf
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <math.h>
+#include "vpx_mem/vpx_mem.h"
+
+#include "quantize.h"
+#include "entropy.h"
+#include "predictdc.h"
+
+void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
+{
+    int i, rc, eob;
+    int zbin;
+    int x, y, z, sz;
+    short *coeff_ptr  = &b->coeff[0];
+    short *zbin_ptr   = &b->zbin[0][0];
+    short *round_ptr  = &b->round[0][0];
+    short *quant_ptr  = &b->quant[0][0];
+    short *qcoeff_ptr = d->qcoeff;
+    short *dqcoeff_ptr = d->dqcoeff;
+    short *dequant_ptr = &d->dequant[0][0];
+
+    vpx_memset(qcoeff_ptr, 0, 32);
+    vpx_memset(dqcoeff_ptr, 0, 32);
+
+    eob = -1;
+
+    for (i = 0; i < 16; i++)
+    {
+        rc   = vp8_default_zig_zag1d[i];
+        z    = coeff_ptr[rc];
+        zbin = zbin_ptr[rc] ;
+
+        sz = (z >> 31);                                 // sign of z
+        x  = (z ^ sz) - sz;                             // x = abs(z)
+
+        if (x >= zbin)
+        {
+            y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
+            x  = (y ^ sz) - sz;                         // get the sign back
+            qcoeff_ptr[rc] = x;                          // write to destination
+            dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
+
+            if (y)
+            {
+                eob = i;                                // last nonzero coeffs
+            }
+        }
+    }
+
+    d->eob = eob + 1;
+
+}
+
+void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
+{
+    int i, rc, eob;
+    int zbin;
+    int x, y, z, sz;
+    short *zbin_boost_ptr = &b->zrun_zbin_boost[0];
+    short *coeff_ptr  = &b->coeff[0];
+    short *zbin_ptr   = &b->zbin[0][0];
+    short *round_ptr  = &b->round[0][0];
+    short *quant_ptr  = &b->quant[0][0];
+    short *qcoeff_ptr = d->qcoeff;
+    short *dqcoeff_ptr = d->dqcoeff;
+    short *dequant_ptr = &d->dequant[0][0];
+    short zbin_oq_value = b->zbin_extra;
+
+    vpx_memset(qcoeff_ptr, 0, 32);
+    vpx_memset(dqcoeff_ptr, 0, 32);
+
+    eob = -1;
+
+    for (i = 0; i < 16; i++)
+    {
+        rc   = vp8_default_zig_zag1d[i];
+        z    = coeff_ptr[rc];
+
+        //if ( i == 0 )
+        //    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
+        //else
+        zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
+
+        zbin_boost_ptr ++;
+        sz = (z >> 31);                                 // sign of z
+        x  = (z ^ sz) - sz;                             // x = abs(z)
+
+        if (x >= zbin)
+        {
+            y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
+            x  = (y ^ sz) - sz;                         // get the sign back
+            qcoeff_ptr[rc]  = x;                         // write to destination
+            dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
+
+            if (y)
+            {
+                eob = i;                                // last nonzero coeffs
+                zbin_boost_ptr = &b->zrun_zbin_boost[0];    // reset zero runlength
+            }
+        }
+    }
+
+    d->eob = eob + 1;
+}
+void vp8_quantize_mby(MACROBLOCK *x)
+{
+    int i;
+
+    if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2);
+        }
+
+        x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
+        x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[24].eob);
+
+    }
+    else
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+}
+
+void vp8_quantize_mb(MACROBLOCK *x)
+{
+    int i;
+
+    x->e_mbd.mbmi.mb_skip_coeff = 1;
+
+    if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2);
+        }
+
+        for (i = 16; i < 25; i++)
+        {
+            x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+    else
+    {
+        for (i = 0; i < 24; i++)
+        {
+            x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+
+}
+
+
+void vp8_quantize_mbuv(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 16; i < 24; i++)
+    {
+        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
+        x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+    }
+}
+
+// This function is not currently called
+void vp8_quantize_mbrd(MACROBLOCK *x)
+{
+    int i;
+
+    x->e_mbd.mbmi.mb_skip_coeff = 1;
+
+    if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->quantize_brd(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2);
+        }
+
+        for (i = 16; i < 25; i++)
+        {
+            x->quantize_brd(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+    else
+    {
+        for (i = 0; i < 24; i++)
+        {
+            x->quantize_brd(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+}
+
+void vp8_quantize_mbuvrd(MACROBLOCK *x)
+{
+    int i;
+
+    for (i = 16; i < 24; i++)
+    {
+        x->quantize_brd(&x->block[i], &x->e_mbd.block[i]);
+        x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+    }
+}
+
+void vp8_quantize_mbyrd(MACROBLOCK *x)
+{
+    int i;
+
+    if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV)
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->quantize_brd(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2);
+        }
+
+        x->quantize_brd(&x->block[24], &x->e_mbd.block[24]);
+        x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[24].eob);
+
+    }
+    else
+    {
+        for (i = 0; i < 16; i++)
+        {
+            x->quantize_brd(&x->block[i], &x->e_mbd.block[i]);
+            x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
+        }
+    }
+}
diff --git a/vp8/encoder/quantize.h b/vp8/encoder/quantize.h
new file mode 100644 (file)
index 0000000..868e8e3
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_QUANTIZE_H
+#define __INC_QUANTIZE_H
+
+#include "block.h"
+
+#define prototype_quantize_block(sym) \
+    void (sym)(BLOCK *b,BLOCKD *d)
+
+#if ARCH_ARM
+#include "arm/quantize_arm.h"
+#endif
+
+#ifndef vp8_quantize_quantb
+#define vp8_quantize_quantb vp8_regular_quantize_b
+#endif
+extern prototype_quantize_block(vp8_quantize_quantb);
+
+#ifndef vp8_quantize_fastquantb
+#define vp8_quantize_fastquantb vp8_fast_quantize_b_c
+#endif
+extern prototype_quantize_block(vp8_quantize_fastquantb);
+
+typedef struct
+{
+    prototype_quantize_block(*quantb);
+    prototype_quantize_block(*fastquantb);
+} vp8_quantize_rtcd_vtable_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define QUANTIZE_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define QUANTIZE_INVOKE(ctx,fn) vp8_quantize_##fn
+#endif
+
+extern void vp8_quantize_mb(MACROBLOCK *x);
+extern void vp8_quantize_mbuv(MACROBLOCK *x);
+extern void vp8_quantize_mby(MACROBLOCK *x);
+extern void vp8_quantize_mbyrd(MACROBLOCK *x);
+extern void vp8_quantize_mbuvrd(MACROBLOCK *x);
+extern void vp8_quantize_mbrd(MACROBLOCK *x);
+
+#endif
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
new file mode 100644 (file)
index 0000000..05040d3
--- /dev/null
@@ -0,0 +1,1552 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#include "math.h"
+#include "common.h"
+#include "ratectrl.h"
+#include "entropymode.h"
+#include "vpx_mem/vpx_mem.h"
+#include "systemdependent.h"
+#include "encodemv.h"
+
+
+#define MIN_BPB_FACTOR          0.01
+#define MAX_BPB_FACTOR          50
+
+extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
+extern const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES];
+
+
+
+#ifdef MODE_STATS
+extern int y_modes[5];
+extern int uv_modes[4];
+extern int b_modes[10];
+
+extern int inter_y_modes[10];
+extern int inter_uv_modes[4];
+extern int inter_b_modes[10];
+#endif
+
+// Bits Per MB at different Q (Multiplied by 512)
+#define BPER_MB_NORMBITS    9
+
+const int vp8_bits_per_mb[2][QINDEX_RANGE] =
+{
+    // (Updated 19 March 08) Baseline estimate of INTRA-frame Bits Per MB at each Q:
+    {
+        674781, 606845, 553905, 524293, 500428, 452540, 435379, 414719,
+        390970, 371082, 359416, 341807, 336957, 317263, 303724, 298402,
+        285688, 275237, 268455, 262560, 256038, 248734, 241087, 237615,
+        229247, 225211, 219112, 213920, 211559, 202714, 198482, 193401,
+        187866, 183453, 179212, 175965, 171852, 167235, 163972, 160560,
+        156032, 154349, 151390, 148725, 145708, 142311, 139981, 137700,
+        134084, 131863, 129746, 128498, 126077, 123461, 121290, 117782,
+        114883, 112332, 108410, 105685, 103434, 101192,  98587,  95959,
+        94059,  92017,  89970,  87936,  86142,  84801,  82736,  81106,
+        79668,  78135,  76641,  75103,  73943,  72693,  71401,  70098,
+        69165,  67901,  67170,  65987,  64923,  63534,  62378,  61302,
+        59921,  58941,  57844,  56782,  55960,  54973,  54257,  53454,
+        52230,  50938,  49962,  49190,  48288,  47270,  46738,  46037,
+        45020,  44027,  43216,  42287,  41594,  40702,  40081,  39414,
+        38282,  37627,  36987,  36375,  35808,  35236,  34710,  34162,
+        33659,  33327,  32751,  32384,  31936,  31461,  30982,  30582,
+    },
+
+    // (Updated 19 March 08) Baseline estimate of INTER-frame Bits Per MB at each Q:
+    {
+        497401, 426316, 372064, 352732, 335763, 283921, 273848, 253321,
+        233181, 217727, 210030, 196685, 194836, 178396, 167753, 164116,
+        154119, 146929, 142254, 138488, 133591, 127741, 123166, 120226,
+        114188, 111756, 107882, 104749, 102522,  96451,  94424,  90905,
+        87286,  84931,  82111,  80534,  77610,  74700,  73037,  70715,
+        68006,  67235,  65374,  64009,  62134,  60180,  59105,  57691,
+        55509,  54512,  53318,  52693,  51194,  49840,  48944,  46980,
+        45668,  44177,  42348,  40994,  39859,  38889,  37717,  36391,
+        35482,  34622,  33795,  32756,  32002,  31492,  30573,  29737,
+        29152,  28514,  27941,  27356,  26859,  26329,  25874,  25364,
+        24957,  24510,  24290,  23689,  23380,  22845,  22481,  22066,
+        21587,  21219,  20880,  20452,  20260,  19926,  19661,  19334,
+        18915,  18391,  18046,  17833,  17441,  17105,  16888,  16729,
+        16383,  16023,  15706,  15442,  15222,  14938,  14673,  14452,
+        14005,  13807,  13611,  13447,  13223,  13102,  12963,  12801,
+        12627,  12534,  12356,  12228,  12056,  11907,  11746,  11643,
+    }
+};
+
+const int vp8_kf_boost_qadjustment[QINDEX_RANGE] =
+{
+    128, 129, 130, 131, 132, 133, 134, 135,
+    136, 137, 138, 139, 140, 141, 142, 143,
+    144, 145, 146, 147, 148, 149, 150, 151,
+    152, 153, 154, 155, 156, 157, 158, 159,
+    160, 161, 162, 163, 164, 165, 166, 167,
+    168, 169, 170, 171, 172, 173, 174, 175,
+    176, 177, 178, 179, 180, 181, 182, 183,
+    184, 185, 186, 187, 188, 189, 190, 191,
+    192, 193, 194, 195, 196, 197, 198, 199,
+    200, 200, 201, 201, 202, 203, 203, 203,
+    204, 204, 205, 205, 206, 206, 207, 207,
+    208, 208, 209, 209, 210, 210, 211, 211,
+    212, 212, 213, 213, 214, 214, 215, 215,
+    216, 216, 217, 217, 218, 218, 219, 219,
+    220, 220, 220, 220, 220, 220, 220, 220,
+    220, 220, 220, 220, 220, 220, 220, 220,
+};
+
+//#define GFQ_ADJUSTMENT (Q+100)
+#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q]
+const int vp8_gf_boost_qadjustment[QINDEX_RANGE] =
+{
+    80, 82, 84, 86, 88, 90, 92, 94,
+    96, 97, 98, 99, 100, 101, 102, 103,
+    104, 105, 106, 107, 108, 109, 110, 111,
+    112, 113, 114, 115, 116, 117, 118, 119,
+    120, 121, 122, 123, 124, 125, 126, 127,
+    128, 129, 130, 131, 132, 133, 134, 135,
+    136, 137, 138, 139, 140, 141, 142, 143,
+    144, 145, 146, 147, 148, 149, 150, 151,
+    152, 153, 154, 155, 156, 157, 158, 159,
+    160, 161, 162, 163, 164, 165, 166, 167,
+    168, 169, 170, 171, 172, 173, 174, 175,
+    176, 177, 178, 179, 180, 181, 182, 183,
+    184, 184, 185, 185, 186, 186, 187, 187,
+    188, 188, 189, 189, 190, 190, 191, 191,
+    192, 192, 193, 193, 194, 194, 194, 194,
+    195, 195, 196, 196, 197, 197, 198, 198
+};
+
+/*
+const int vp8_gf_boost_qadjustment[QINDEX_RANGE] =
+{
+    100,101,102,103,104,105,105,106,
+    106,107,107,108,109,109,110,111,
+    112,113,114,115,116,117,118,119,
+    120,121,122,123,124,125,126,127,
+    128,129,130,131,132,133,134,135,
+    136,137,138,139,140,141,142,143,
+    144,145,146,147,148,149,150,151,
+    152,153,154,155,156,157,158,159,
+    160,161,162,163,164,165,166,167,
+    168,169,170,170,171,171,172,172,
+    173,173,173,174,174,174,175,175,
+    175,176,176,176,177,177,177,177,
+    178,178,179,179,180,180,181,181,
+    182,182,183,183,184,184,185,185,
+    186,186,187,187,188,188,189,189,
+    190,190,191,191,192,192,193,193,
+};
+*/
+
+const int vp8_kf_gf_boost_qlimits[QINDEX_RANGE] =
+{
+    150, 155, 160, 165, 170, 175, 180, 185,
+    190, 195, 200, 205, 210, 215, 220, 225,
+    230, 235, 240, 245, 250, 255, 260, 265,
+    270, 275, 280, 285, 290, 295, 300, 305,
+    310, 320, 330, 340, 350, 360, 370, 380,
+    390, 400, 410, 420, 430, 440, 450, 460,
+    470, 480, 490, 500, 510, 520, 530, 540,
+    550, 560, 570, 580, 590, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+    600, 600, 600, 600, 600, 600, 600, 600,
+};
+
+// % adjustment to target kf size based on seperation from previous frame
+const int vp8_kf_boost_seperationt_adjustment[16] =
+{
+    30,   40,   50,   55,   60,   65,   70,   75,
+    80,   85,   90,   95,  100,  100,  100,  100,
+};
+
+
+const int vp8_gf_adjust_table[101] =
+{
+    100,
+    115, 130, 145, 160, 175, 190, 200, 210, 220, 230,
+    240, 260, 270, 280, 290, 300, 310, 320, 330, 340,
+    350, 360, 370, 380, 390, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+    400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+};
+
+const int vp8_gf_intra_useage_adjustment[20] =
+{
+    125, 120, 115, 110, 105, 100,  95,  85,  80,  75,
+    70,  65,  60,  55,  50,  50,  50,  50,  50,  50,
+};
+
+const int vp8_gf_interval_table[101] =
+{
+    7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+};
+
+static const unsigned int prior_key_frame_weight[KEY_FRAME_CONTEXT] = { 1, 2, 3, 4, 5 };
+
+
+void vp8_save_coding_context(VP8_COMP *cpi)
+{
+    CODING_CONTEXT *const cc = & cpi->coding_context;
+
+    // Stores a snapshot of key state variables which can subsequently be
+    // restored with a call to vp8_restore_coding_context. These functions are
+    // intended for use in a re-code loop in vp8_compress_frame where the
+    // quantizer value is adjusted between loop iterations.
+
+    cc->frames_since_key          = cpi->frames_since_key;
+    cc->filter_level             = cpi->common.filter_level;
+    cc->frames_till_gf_update_due   = cpi->frames_till_gf_update_due;
+    cc->frames_since_golden       = cpi->common.frames_since_golden;
+
+    vp8_copy(cc->mvc,      cpi->common.fc.mvc);
+    vp8_copy(cc->mvcosts,  cpi->mb.mvcosts);
+
+    vp8_copy(cc->kf_ymode_prob,   cpi->common.kf_ymode_prob);
+    vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
+    vp8_copy(cc->kf_uv_mode_prob,  cpi->common.kf_uv_mode_prob);
+    vp8_copy(cc->uv_mode_prob,  cpi->common.fc.uv_mode_prob);
+
+    vp8_copy(cc->ymode_count, cpi->ymode_count);
+    vp8_copy(cc->uv_mode_count, cpi->uv_mode_count);
+
+
+    // Stats
+#ifdef MODE_STATS
+    vp8_copy(cc->y_modes,       y_modes);
+    vp8_copy(cc->uv_modes,      uv_modes);
+    vp8_copy(cc->b_modes,       b_modes);
+    vp8_copy(cc->inter_y_modes,  inter_y_modes);
+    vp8_copy(cc->inter_uv_modes, inter_uv_modes);
+    vp8_copy(cc->inter_b_modes,  inter_b_modes);
+#endif
+
+    cc->this_frame_percent_intra = cpi->this_frame_percent_intra;
+}
+
+
+void vp8_restore_coding_context(VP8_COMP *cpi)
+{
+    CODING_CONTEXT *const cc = & cpi->coding_context;
+
+    // Restore key state variables to the snapshot state stored in the
+    // previous call to vp8_save_coding_context.
+
+    cpi->frames_since_key         =   cc->frames_since_key;
+    cpi->common.filter_level     =   cc->filter_level;
+    cpi->frames_till_gf_update_due  =   cc->frames_till_gf_update_due;
+    cpi->common.frames_since_golden       =   cc->frames_since_golden;
+
+    vp8_copy(cpi->common.fc.mvc, cc->mvc);
+
+    vp8_copy(cpi->mb.mvcosts, cc->mvcosts);
+
+    vp8_copy(cpi->common.kf_ymode_prob,   cc->kf_ymode_prob);
+    vp8_copy(cpi->common.fc.ymode_prob,   cc->ymode_prob);
+    vp8_copy(cpi->common.kf_uv_mode_prob,  cc->kf_uv_mode_prob);
+    vp8_copy(cpi->common.fc.uv_mode_prob,  cc->uv_mode_prob);
+
+    vp8_copy(cpi->ymode_count, cc->ymode_count);
+    vp8_copy(cpi->uv_mode_count, cc->uv_mode_count);
+
+    // Stats
+#ifdef MODE_STATS
+    vp8_copy(y_modes, cc->y_modes);
+    vp8_copy(uv_modes, cc->uv_modes);
+    vp8_copy(b_modes, cc->b_modes);
+    vp8_copy(inter_y_modes, cc->inter_y_modes);
+    vp8_copy(inter_uv_modes, cc->inter_uv_modes);
+    vp8_copy(inter_b_modes, cc->inter_b_modes);
+#endif
+
+
+    cpi->this_frame_percent_intra = cc->this_frame_percent_intra;
+}
+
+
+void vp8_setup_key_frame(VP8_COMP *cpi)
+{
+    // Setup for Key frame:
+
+    vp8_default_coef_probs(& cpi->common);
+    vp8_kf_default_bmode_probs(cpi->common.kf_bmode_prob);
+
+    vpx_memcpy(cpi->common.fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
+    {
+        int flag[2] = {1, 1};
+        vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag);
+    }
+
+    vpx_memset(cpi->common.fc.pre_mvc, 0, sizeof(cpi->common.fc.pre_mvc));  //initialize pre_mvc to all zero.
+
+    //cpi->common.filter_level = 0;      // Reset every key frame.
+    cpi->common.filter_level = cpi->common.base_qindex * 3 / 8 ;
+
+    // Provisional interval before next GF
+    if (cpi->auto_gold)
+        //cpi->frames_till_gf_update_due = DEFAULT_GF_INTERVAL;
+        cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+    else
+        cpi->frames_till_gf_update_due = cpi->goldfreq;
+
+    cpi->common.refresh_golden_frame = TRUE;
+}
+
+void vp8_calc_auto_iframe_target_size(VP8_COMP *cpi)
+{
+    // boost defaults to half second
+    int kf_boost;
+
+    // Clear down mmx registers to allow floating point in what follows
+    vp8_clear_system_state();  //__asm emms;
+
+    if (cpi->oxcf.fixed_q >= 0)
+    {
+        vp8_calc_iframe_target_size(cpi);
+        return;
+    }
+
+    if (cpi->pass == 2)
+    {
+        cpi->this_frame_target = cpi->per_frame_bandwidth;      // New Two pass RC
+    }
+    else
+    {
+        // Boost depends somewhat on frame rate
+        kf_boost = (int)(2 * cpi->output_frame_rate - 16);
+
+        // adjustment up based on q
+        kf_boost = kf_boost * vp8_kf_boost_qadjustment[cpi->ni_av_qi] / 100;
+
+        // frame separation adjustment ( down)
+        if (cpi->frames_since_key  < cpi->output_frame_rate / 2)
+            kf_boost = (int)(kf_boost * cpi->frames_since_key / (cpi->output_frame_rate / 2));
+
+        if (kf_boost < 16)
+            kf_boost = 16;
+
+        // Reset the active worst quality to the baseline value for key frames.
+        cpi->active_worst_quality = cpi->worst_quality;
+
+        cpi->this_frame_target = ((16 + kf_boost)  * cpi->per_frame_bandwidth) >> 4;
+    }
+
+
+    // Should the next frame be an altref frame
+    if (cpi->pass != 2)
+    {
+        // For now Alt ref is not allowed except in 2 pass modes.
+        cpi->source_alt_ref_pending = FALSE;
+
+        /*if ( cpi->oxcf.fixed_q == -1)
+        {
+            if ( cpi->oxcf.play_alternate && ( (cpi->last_boost/2) > (100+(AF_THRESH*cpi->frames_till_gf_update_due)) ) )
+                cpi->source_alt_ref_pending = TRUE;
+            else
+                cpi->source_alt_ref_pending = FALSE;
+        }*/
+    }
+
+    if (0)
+    {
+        FILE *f;
+
+        f = fopen("kf_boost.stt", "a");
+        //fprintf(f, " %8d %10d %10d %10d %10d %10d %10d\n",
+        //  cpi->common.current_video_frame,  cpi->target_bandwidth, cpi->frames_to_key, kf_boost_qadjustment[cpi->ni_av_qi], cpi->kf_boost, (cpi->this_frame_target *100 / cpi->per_frame_bandwidth), cpi->this_frame_target );
+
+        fprintf(f, " %8u %10d %10d %10d\n",
+                cpi->common.current_video_frame,  cpi->gfu_boost, cpi->baseline_gf_interval, cpi->source_alt_ref_pending);
+
+        fclose(f);
+    }
+}
+
+//  Do the best we can to define the parameteres for the next GF based on what information we have available.
+static void calc_gf_params(VP8_COMP *cpi)
+{
+    int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+    int Boost = 0;
+
+    int gf_frame_useage = 0;      // Golden frame useage since last GF
+    int tot_mbs = cpi->recent_ref_frame_usage[INTRA_FRAME]  +
+                  cpi->recent_ref_frame_usage[LAST_FRAME]   +
+                  cpi->recent_ref_frame_usage[GOLDEN_FRAME] +
+                  cpi->recent_ref_frame_usage[ALTREF_FRAME];
+
+    int pct_gf_active = (100 * cpi->common.gf_active_count) / (cpi->common.mb_rows * cpi->common.mb_cols);
+
+    // Reset the last boost indicator
+    //cpi->last_boost = 100;
+
+    if (tot_mbs)
+        gf_frame_useage = (cpi->recent_ref_frame_usage[GOLDEN_FRAME] + cpi->recent_ref_frame_usage[ALTREF_FRAME]) * 100 / tot_mbs;
+
+    if (pct_gf_active > gf_frame_useage)
+        gf_frame_useage = pct_gf_active;
+
+    // Not two pass
+    if (cpi->pass != 2)
+    {
+        // Single Pass lagged mode: TBD
+        if (FALSE)
+        {
+        }
+
+        // Single Pass compression: Has to use current and historical data
+        else
+        {
+#if 0
+            // Experimental code
+            int index = cpi->one_pass_frame_index;
+            int frames_to_scan = (cpi->max_gf_interval <= MAX_LAG_BUFFERS) ? cpi->max_gf_interval : MAX_LAG_BUFFERS;
+
+            /*
+            // *************** Experimental code - incomplete
+            double decay_val = 1.0;
+            double IIAccumulator = 0.0;
+            double last_iiaccumulator = 0.0;
+            double IIRatio;
+
+            cpi->one_pass_frame_index = cpi->common.current_video_frame%MAX_LAG_BUFFERS;
+
+            for ( i = 0; i < (frames_to_scan - 1); i++ )
+            {
+                if ( index < 0 )
+                    index = MAX_LAG_BUFFERS;
+                index --;
+
+                if ( cpi->one_pass_frame_stats[index].frame_coded_error > 0.0 )
+                {
+                    IIRatio = cpi->one_pass_frame_stats[index].frame_intra_error / cpi->one_pass_frame_stats[index].frame_coded_error;
+
+                    if ( IIRatio > 30.0 )
+                        IIRatio = 30.0;
+                }
+                else
+                    IIRatio = 30.0;
+
+                IIAccumulator += IIRatio * decay_val;
+
+                decay_val = decay_val * cpi->one_pass_frame_stats[index].frame_pcnt_inter;
+
+                if (    (i > MIN_GF_INTERVAL) &&
+                        ((IIAccumulator - last_iiaccumulator) < 2.0) )
+                {
+                    break;
+                }
+                last_iiaccumulator = IIAccumulator;
+            }
+
+            Boost = IIAccumulator*100.0/16.0;
+            cpi->baseline_gf_interval = i;
+
+            */
+#else
+
+            /*************************************************************/
+            // OLD code
+
+            // Adjust boost based upon ambient Q
+            Boost = GFQ_ADJUSTMENT;
+
+            // Adjust based upon most recently measure intra useage
+            Boost = Boost * vp8_gf_intra_useage_adjustment[(cpi->this_frame_percent_intra < 15) ? cpi->this_frame_percent_intra : 14] / 100;
+
+            // Adjust gf boost based upon GF usage since last GF
+            Boost = Boost * vp8_gf_adjust_table[gf_frame_useage] / 100;
+#endif
+        }
+
+        // golden frame boost without recode loop often goes awry.  be safe by keeping numbers down.
+        if (!cpi->sf.recode_loop)
+        {
+            if (cpi->compressor_speed == 2)
+                Boost = Boost / 2;
+        }
+
+        // Apply an upper limit based on Q for 1 pass encodes
+        if (Boost > vp8_kf_gf_boost_qlimits[Q] && (cpi->pass == 0))
+            Boost = vp8_kf_gf_boost_qlimits[Q];
+
+        // Apply lower limits to boost.
+        else if (Boost < 110)
+            Boost = 110;
+
+        // Note the boost used
+        cpi->last_boost = Boost;
+
+    }
+
+    // Estimate next interval
+    // This is updated once the real frame size/boost is known.
+    if (cpi->oxcf.fixed_q == -1)
+    {
+        if (cpi->pass == 2)         // 2 Pass
+        {
+            cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+        }
+        else                            // 1 Pass
+        {
+            cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+
+            if (cpi->last_boost > 750)
+                cpi->frames_till_gf_update_due++;
+
+            if (cpi->last_boost > 1000)
+                cpi->frames_till_gf_update_due++;
+
+            if (cpi->last_boost > 1250)
+                cpi->frames_till_gf_update_due++;
+
+            if (cpi->last_boost >= 1500)
+                cpi->frames_till_gf_update_due ++;
+
+            if (vp8_gf_interval_table[gf_frame_useage] > cpi->frames_till_gf_update_due)
+                cpi->frames_till_gf_update_due = vp8_gf_interval_table[gf_frame_useage];
+
+            if (cpi->frames_till_gf_update_due > cpi->max_gf_interval)
+                cpi->frames_till_gf_update_due = cpi->max_gf_interval;
+        }
+    }
+    else
+        cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
+
+    // ARF on or off
+    if (cpi->pass != 2)
+    {
+        // For now Alt ref is not allowed except in 2 pass modes.
+        cpi->source_alt_ref_pending = FALSE;
+
+        /*if ( cpi->oxcf.fixed_q == -1)
+        {
+            if ( cpi->oxcf.play_alternate && (cpi->last_boost > (100 + (AF_THRESH*cpi->frames_till_gf_update_due)) ) )
+                cpi->source_alt_ref_pending = TRUE;
+            else
+                cpi->source_alt_ref_pending = FALSE;
+        }*/
+    }
+}
+/* This is equvialent to estimate_bits_at_q without the rate_correction_factor. */
+static int baseline_bits_at_q(int frame_kind, int Q, int MBs)
+{
+    int Bpm = vp8_bits_per_mb[frame_kind][Q];
+
+    /* Attempt to retain reasonable accuracy without overflow. The cutoff is
+     * chosen such that the maximum product of Bpm and MBs fits 31 bits. The
+     * largest Bpm takes 20 bits.
+     */
+    if (MBs > (1 << 11))
+        return (Bpm >> BPER_MB_NORMBITS) * MBs;
+    else
+        return (Bpm * MBs) >> BPER_MB_NORMBITS;
+}
+
+void vp8_calc_iframe_target_size(VP8_COMP *cpi)
+{
+    int Q;
+    int Boost = 100;
+
+    Q = (cpi->oxcf.fixed_q >= 0) ? cpi->oxcf.fixed_q : cpi->avg_frame_qindex;
+
+    if (cpi->auto_adjust_key_quantizer == 1)
+    {
+        // If (auto_adjust_key_quantizer==1) then a lower Q is selected for key-frames.
+        // The enhanced Q is calculated so as to boost the key frame size by a factor
+        // specified in kf_boost_qadjustment. Also, can adjust based on distance
+        // between key frames.
+
+        // Adjust boost based upon ambient Q
+        Boost = vp8_kf_boost_qadjustment[Q];
+
+        // Make the Key frame boost less if the seperation from the previous key frame is small
+        if (cpi->frames_since_key < 16)
+            Boost = Boost * vp8_kf_boost_seperationt_adjustment[cpi->frames_since_key] / 100;
+        else
+            Boost = Boost * vp8_kf_boost_seperationt_adjustment[15] / 100;
+
+        // Apply limits on boost
+        if (Boost > vp8_kf_gf_boost_qlimits[Q])
+            Boost = vp8_kf_gf_boost_qlimits[Q];
+        else if (Boost < 120)
+            Boost = 120;
+    }
+
+    // Keep a record of the boost that was used
+    cpi->last_boost = Boost;
+
+    // Should the next frame be an altref frame
+    if (cpi->pass != 2)
+    {
+        // For now Alt ref is not allowed except in 2 pass modes.
+        cpi->source_alt_ref_pending = FALSE;
+
+        /*if ( cpi->oxcf.fixed_q == -1)
+        {
+            if ( cpi->oxcf.play_alternate && ( (cpi->last_boost/2) > (100+(AF_THRESH*cpi->frames_till_gf_update_due)) ) )
+                cpi->source_alt_ref_pending = TRUE;
+            else
+                cpi->source_alt_ref_pending = FALSE;
+        }*/
+    }
+
+    if (cpi->oxcf.fixed_q >= 0)
+    {
+        cpi->this_frame_target = (baseline_bits_at_q(0, Q, cpi->common.MBs) * Boost) / 100;
+    }
+    else
+    {
+
+        int bits_per_mb_at_this_q ;
+
+        if (cpi->oxcf.error_resilient_mode == 1)
+        {
+            cpi->this_frame_target = 2 * cpi->av_per_frame_bandwidth;
+            return;
+        }
+
+        // Rate targetted scenario:
+        // Be careful of 32-bit OVERFLOW if restructuring the caluclation of cpi->this_frame_target
+        bits_per_mb_at_this_q = (int)(.5 +
+                                      cpi->key_frame_rate_correction_factor * vp8_bits_per_mb[0][Q]);
+
+        cpi->this_frame_target = (((bits_per_mb_at_this_q * cpi->common.MBs) >> BPER_MB_NORMBITS) * Boost) / 100;
+
+        // Reset the active worst quality to the baseline value for key frames.
+        if (cpi->pass < 2)
+            cpi->active_worst_quality = cpi->worst_quality;
+    }
+}
+
+
+
+void vp8_calc_pframe_target_size(VP8_COMP *cpi)
+{
+    int min_frame_target;
+    int Adjustment;
+
+    // Set the min frame bandwidth.
+    //min_frame_target = estimate_min_frame_size( cpi );
+    min_frame_target = 0;
+
+    if (cpi->pass == 2)
+    {
+        min_frame_target = cpi->min_frame_bandwidth;
+
+        if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5))
+            min_frame_target = cpi->av_per_frame_bandwidth >> 5;
+    }
+    else if (min_frame_target < cpi->per_frame_bandwidth / 4)
+        min_frame_target = cpi->per_frame_bandwidth / 4;
+
+
+    // Special alt reference frame case
+    if (cpi->common.refresh_alt_ref_frame)
+    {
+        if (cpi->pass == 2)
+        {
+            cpi->per_frame_bandwidth = cpi->gf_bits;                       // Per frame bit target for the alt ref frame
+            cpi->this_frame_target = cpi->per_frame_bandwidth;
+        }
+
+        /* One Pass ??? TBD */
+        /*else
+        {
+            int frames_in_section;
+            int allocation_chunks;
+            int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+            int alt_boost;
+            int max_arf_rate;
+
+            alt_boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
+            alt_boost += (cpi->frames_till_gf_update_due * 50);
+
+            // If alt ref is not currently active then we have a pottential double hit with GF and ARF so reduce the boost a bit.
+            // A similar thing is done on GFs that preceed a arf update.
+            if ( !cpi->source_alt_ref_active )
+                alt_boost = alt_boost * 3 / 4;
+
+            frames_in_section = cpi->frames_till_gf_update_due+1;                                   // Standard frames + GF
+            allocation_chunks = (frames_in_section * 100) + alt_boost;
+
+            // Normalize Altboost and allocations chunck down to prevent overflow
+            while ( alt_boost > 1000 )
+            {
+                alt_boost /= 2;
+                allocation_chunks /= 2;
+            }
+
+            else
+            {
+                int bits_in_section;
+
+                if ( cpi->kf_overspend_bits > 0 )
+                {
+                    Adjustment = (cpi->kf_bitrate_adjustment <= cpi->kf_overspend_bits) ? cpi->kf_bitrate_adjustment : cpi->kf_overspend_bits;
+
+                    if ( Adjustment > (cpi->per_frame_bandwidth - min_frame_target) )
+                        Adjustment = (cpi->per_frame_bandwidth - min_frame_target);
+
+                    cpi->kf_overspend_bits -= Adjustment;
+
+                    // Calculate an inter frame bandwidth target for the next few frames designed to recover
+                    // any extra bits spent on the key frame.
+                    cpi->inter_frame_target = cpi->per_frame_bandwidth - Adjustment;
+                    if ( cpi->inter_frame_target < min_frame_target )
+                        cpi->inter_frame_target = min_frame_target;
+                }
+                else
+                    cpi->inter_frame_target = cpi->per_frame_bandwidth;
+
+                bits_in_section = cpi->inter_frame_target * frames_in_section;
+
+                // Avoid loss of precision but avoid overflow
+                if ( (bits_in_section>>7) > allocation_chunks )
+                    cpi->this_frame_target = alt_boost * (bits_in_section / allocation_chunks);
+                else
+                    cpi->this_frame_target = (alt_boost * bits_in_section) / allocation_chunks;
+            }
+        }
+        */
+    }
+
+    // Normal frames (gf,and inter)
+    else
+    {
+        // 2 pass
+        if (cpi->pass == 2)
+        {
+            cpi->this_frame_target = cpi->per_frame_bandwidth;
+        }
+        // 1 pass
+        else
+        {
+            // Make rate adjustment to recover bits spent in key frame
+            // Test to see if the key frame inter data rate correction should still be in force
+            if (cpi->kf_overspend_bits > 0)
+            {
+                Adjustment = (cpi->kf_bitrate_adjustment <= cpi->kf_overspend_bits) ? cpi->kf_bitrate_adjustment : cpi->kf_overspend_bits;
+
+                if (Adjustment > (cpi->per_frame_bandwidth - min_frame_target))
+                    Adjustment = (cpi->per_frame_bandwidth - min_frame_target);
+
+                cpi->kf_overspend_bits -= Adjustment;
+
+                // Calculate an inter frame bandwidth target for the next few frames designed to recover
+                // any extra bits spent on the key frame.
+                cpi->this_frame_target = cpi->per_frame_bandwidth - Adjustment;
+
+                if (cpi->this_frame_target < min_frame_target)
+                    cpi->this_frame_target = min_frame_target;
+            }
+            else
+                cpi->this_frame_target = cpi->per_frame_bandwidth;
+
+            // If appropriate make an adjustment to recover bits spent on a recent GF
+            if ((cpi->gf_overspend_bits > 0) && (cpi->this_frame_target > min_frame_target))
+            {
+                int Adjustment = (cpi->non_gf_bitrate_adjustment <= cpi->gf_overspend_bits) ? cpi->non_gf_bitrate_adjustment : cpi->gf_overspend_bits;
+
+                if (Adjustment > (cpi->this_frame_target - min_frame_target))
+                    Adjustment = (cpi->this_frame_target - min_frame_target);
+
+                cpi->gf_overspend_bits -= Adjustment;
+                cpi->this_frame_target -= Adjustment;
+            }
+
+            // Apply small + and - boosts for non gf frames
+            if ((cpi->last_boost > 150) && (cpi->frames_till_gf_update_due > 0) &&
+                (cpi->current_gf_interval >= (MIN_GF_INTERVAL << 1)))
+            {
+                // % Adjustment limited to the range 1% to 10%
+                Adjustment = (cpi->last_boost - 100) >> 5;
+
+                if (Adjustment < 1)
+                    Adjustment = 1;
+                else if (Adjustment > 10)
+                    Adjustment = 10;
+
+                // Convert to bits
+                Adjustment = (cpi->this_frame_target * Adjustment) / 100;
+
+                if (Adjustment > (cpi->this_frame_target - min_frame_target))
+                    Adjustment = (cpi->this_frame_target - min_frame_target);
+
+                if (cpi->common.frames_since_golden == (cpi->current_gf_interval >> 1))
+                    cpi->this_frame_target += ((cpi->current_gf_interval - 1) * Adjustment);
+                else
+                    cpi->this_frame_target -= Adjustment;
+            }
+        }
+    }
+
+    // Set a reduced data rate target for our initial Q calculation.
+    // This should help to save bits during earier sections.
+    if ((cpi->oxcf.under_shoot_pct > 0) && (cpi->oxcf.under_shoot_pct <= 100))
+        cpi->this_frame_target = (cpi->this_frame_target * cpi->oxcf.under_shoot_pct) / 100;
+
+    // Sanity check that the total sum of adjustments is not above the maximum allowed
+    // That is that having allowed for KF and GF penalties we have not pushed the
+    // current interframe target to low. If the adjustment we apply here is not capable of recovering
+    // all the extra bits we have spent in the KF or GF then the remainder will have to be recovered over
+    // a longer time span via other buffer / rate control mechanisms.
+    if (cpi->this_frame_target < min_frame_target)
+        cpi->this_frame_target = min_frame_target;
+
+    if (!cpi->common.refresh_alt_ref_frame)
+        // Note the baseline target data rate for this inter frame.
+        cpi->inter_frame_target = cpi->this_frame_target;
+
+    // One Pass specific code
+    if (cpi->pass == 0)
+    {
+        // Adapt target frame size with respect to any buffering constraints:
+        if (cpi->buffered_mode)
+        {
+            int one_percent_bits = 1 + cpi->oxcf.optimal_buffer_level / 100;
+
+            if ((cpi->buffer_level < cpi->oxcf.optimal_buffer_level) || (cpi->bits_off_target < cpi->oxcf.optimal_buffer_level))
+            {
+                int percent_low = 0;
+
+                // Decide whether or not we need to adjust the frame data rate target.
+                //
+                // If we are are below the optimal buffer fullness level and adherence
+                // to buffering contraints is important to the end useage then adjust
+                // the per frame target.
+                if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) && (cpi->buffer_level < cpi->oxcf.optimal_buffer_level))
+                {
+                    percent_low = (cpi->oxcf.optimal_buffer_level - cpi->buffer_level) / one_percent_bits;
+
+                    if (percent_low > 100)
+                        percent_low = 100;
+                    else if (percent_low < 0)
+                        percent_low = 0;
+                }
+                // Are we overshooting the long term clip data rate...
+                else if (cpi->bits_off_target < 0)
+                {
+                    // Adjust per frame data target downwards to compensate.
+                    percent_low = (int)(100 * -cpi->bits_off_target / (cpi->total_byte_count * 8));
+
+                    if (percent_low > 100)
+                        percent_low = 100;
+                    else if (percent_low < 0)
+                        percent_low = 0;
+                }
+
+                // lower the target bandwidth for this frame.
+                cpi->this_frame_target = (cpi->this_frame_target * (100 - (percent_low / 2))) / 100;
+
+                // Are we using allowing control of active_worst_allowed_q according to buffer level.
+                if (cpi->auto_worst_q)
+                {
+                    int critical_buffer_level;
+
+                    // For streaming applications the most important factor is cpi->buffer_level as this takes
+                    // into account the specified short term buffering constraints. However, hitting the long
+                    // term clip data rate target is also important.
+                    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+                    {
+                        // Take the smaller of cpi->buffer_level and cpi->bits_off_target
+                        critical_buffer_level = (cpi->buffer_level < cpi->bits_off_target) ? cpi->buffer_level : cpi->bits_off_target;
+                    }
+                    // For local file playback short term buffering contraints are less of an issue
+                    else
+                    {
+                        // Consider only how we are doing for the clip as a whole
+                        critical_buffer_level = cpi->bits_off_target;
+                    }
+
+                    // Set the active worst quality based upon the selected buffer fullness number.
+                    if (critical_buffer_level < cpi->oxcf.optimal_buffer_level)
+                    {
+                        if (critical_buffer_level > (cpi->oxcf.optimal_buffer_level / 4))
+                        {
+                            int qadjustment_range = cpi->worst_quality - cpi->ni_av_qi;
+                            int above_base = (critical_buffer_level - (cpi->oxcf.optimal_buffer_level / 4));
+
+                            // Step active worst quality down from cpi->ni_av_qi when (critical_buffer_level == cpi->optimal_buffer_level)
+                            // to cpi->oxcf.worst_allowed_q when (critical_buffer_level == cpi->optimal_buffer_level/4)
+                            cpi->active_worst_quality = cpi->worst_quality - ((qadjustment_range * above_base) / (cpi->oxcf.optimal_buffer_level * 3 / 4));
+                        }
+                        else
+                        {
+                            cpi->active_worst_quality = cpi->worst_quality;
+                        }
+                    }
+                    else
+                    {
+                        cpi->active_worst_quality = cpi->ni_av_qi;
+                    }
+                }
+                else
+                {
+                    cpi->active_worst_quality = cpi->worst_quality;
+                }
+            }
+            else
+            {
+                int percent_high;
+
+                if (cpi->bits_off_target > cpi->oxcf.optimal_buffer_level)
+                {
+                    percent_high = (int)(100 * (cpi->bits_off_target - cpi->oxcf.optimal_buffer_level) / (cpi->total_byte_count * 8));
+
+                    if (percent_high > 100)
+                        percent_high = 100;
+                    else if (percent_high < 0)
+                        percent_high = 0;
+
+                    cpi->this_frame_target = (cpi->this_frame_target * (100 + (percent_high / 2))) / 100;
+
+                }
+
+                // Are we allowing control of active_worst_allowed_q according to bufferl level.
+                if (cpi->auto_worst_q)
+                {
+                    // When using the relaxed buffer model stick to the user specified value
+                    cpi->active_worst_quality = cpi->ni_av_qi;
+                }
+                else
+                {
+                    cpi->active_worst_quality = cpi->worst_quality;
+                }
+            }
+
+            // Set active_best_quality to prevent quality rising too high
+            cpi->active_best_quality = cpi->best_quality;
+
+            // Worst quality obviously must not be better than best quality
+            if (cpi->active_worst_quality <= cpi->active_best_quality)
+                cpi->active_worst_quality = cpi->active_best_quality + 1;
+
+        }
+        // Unbuffered mode (eg. video conferencing)
+        else
+        {
+            // Set the active worst quality
+            cpi->active_worst_quality = cpi->worst_quality;
+        }
+    }
+
+    // Test to see if we have to drop a frame
+    // The auto-drop frame code is only used in buffered mode.
+    // In unbufferd mode (eg vide conferencing) the descision to
+    // code or drop a frame is made outside the codec in response to real
+    // world comms or buffer considerations.
+    if (cpi->drop_frames_allowed && cpi->buffered_mode &&
+        (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+        ((cpi->common.frame_type != KEY_FRAME))) //|| !cpi->oxcf.allow_spatial_resampling) )
+    {
+        // Check for a buffer underun-crisis in which case we have to drop a frame
+        if ((cpi->buffer_level < 0))
+        {
+#if 0
+            FILE *f = fopen("dec.stt", "a");
+            fprintf(f, "%10d %10d %10d %10d ***** BUFFER EMPTY\n",
+                    (int) cpi->common.current_video_frame,
+                    cpi->decimation_factor, cpi->common.horiz_scale,
+                    (cpi->buffer_level * 100) / cpi->oxcf.optimal_buffer_level);
+            fclose(f);
+#endif
+            //vpx_log("Decoder: Drop frame due to bandwidth: %d \n",cpi->buffer_level, cpi->av_per_frame_bandwidth);
+
+            cpi->drop_frame = TRUE;
+        }
+
+#if 0
+        // Check for other drop frame crtieria (Note 2 pass cbr uses decimation on whole KF sections)
+        else if ((cpi->buffer_level < cpi->oxcf.drop_frames_water_mark * cpi->oxcf.optimal_buffer_level / 100) &&
+                 (cpi->drop_count < cpi->max_drop_count) && (cpi->pass == 0))
+        {
+            cpi->drop_frame = TRUE;
+        }
+
+#endif
+
+        if (cpi->drop_frame)
+        {
+            // Update the buffer level variable.
+            cpi->bits_off_target += cpi->av_per_frame_bandwidth;
+            cpi->buffer_level = cpi->bits_off_target;
+        }
+        else
+            cpi->drop_count = 0;
+    }
+
+    // Adjust target frame size for Golden Frames:
+    if (cpi->oxcf.error_resilient_mode == 0 &&
+        (cpi->frames_till_gf_update_due == 0) && !cpi->drop_frame)
+    {
+        //int Boost = 0;
+        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+
+        int gf_frame_useage = 0;      // Golden frame useage since last GF
+        int tot_mbs = cpi->recent_ref_frame_usage[INTRA_FRAME]  +
+                      cpi->recent_ref_frame_usage[LAST_FRAME]   +
+                      cpi->recent_ref_frame_usage[GOLDEN_FRAME] +
+                      cpi->recent_ref_frame_usage[ALTREF_FRAME];
+
+        int pct_gf_active = (100 * cpi->common.gf_active_count) / (cpi->common.mb_rows * cpi->common.mb_cols);
+
+        // Reset the last boost indicator
+        //cpi->last_boost = 100;
+
+        if (tot_mbs)
+            gf_frame_useage = (cpi->recent_ref_frame_usage[GOLDEN_FRAME] + cpi->recent_ref_frame_usage[ALTREF_FRAME]) * 100 / tot_mbs;
+
+        if (pct_gf_active > gf_frame_useage)
+            gf_frame_useage = pct_gf_active;
+
+        // Is a fixed manual GF frequency being used
+        if (!cpi->auto_gold)
+            cpi->common.refresh_golden_frame = TRUE;
+        else
+        {
+            // For one pass throw a GF if recent frame intra useage is low or the GF useage is high
+            if ((cpi->pass == 0) && (cpi->this_frame_percent_intra < 15 || gf_frame_useage >= 5))
+                cpi->common.refresh_golden_frame = TRUE;
+
+            // Two pass GF descision
+            else if (cpi->pass == 2)
+                cpi->common.refresh_golden_frame = TRUE;
+        }
+
+#if 0
+
+        // Debug stats
+        if (0)
+        {
+            FILE *f;
+
+            f = fopen("gf_useaget.stt", "a");
+            fprintf(f, " %8ld %10ld %10ld %10ld %10ld\n",
+                    cpi->common.current_video_frame,  cpi->gfu_boost, GFQ_ADJUSTMENT, cpi->gfu_boost, gf_frame_useage);
+            fclose(f);
+        }
+
+#endif
+
+        if (cpi->common.refresh_golden_frame == TRUE)
+        {
+            int isize_adjustment = 0;
+#if 0
+
+            if (0)   // p_gw
+            {
+                FILE *f;
+
+                f = fopen("GFexit.stt", "a");
+                fprintf(f, "%8ld GF coded\n", cpi->common.current_video_frame);
+                fclose(f);
+            }
+
+#endif
+            cpi->initial_gf_use = 0;
+
+            if (cpi->auto_adjust_gold_quantizer)
+            {
+                calc_gf_params(cpi);
+            }
+
+            // If we are using alternate ref instead of gf then do not apply the boost
+            // It will instead be applied to the altref update
+            // Jims modified boost
+            if (!cpi->source_alt_ref_active)
+            {
+                if (cpi->oxcf.fixed_q < 0)
+                {
+                    if (cpi->pass == 2)
+                    {
+                        cpi->this_frame_target = cpi->per_frame_bandwidth;          // The spend on the GF is defined in the two pass code for two pass encodes
+                    }
+                    else
+                    {
+                        int Boost = cpi->last_boost;
+                        int frames_in_section = cpi->frames_till_gf_update_due + 1;
+                        int allocation_chunks = (frames_in_section * 100) + (Boost - 100);
+                        int bits_in_section = cpi->inter_frame_target * frames_in_section;
+
+                        // Normalize Altboost and allocations chunck down to prevent overflow
+                        while (Boost > 1000)
+                        {
+                            Boost /= 2;
+                            allocation_chunks /= 2;
+                        }
+
+                        // Avoid loss of precision but avoid overflow
+                        if ((bits_in_section >> 7) > allocation_chunks)
+                            cpi->this_frame_target = Boost * (bits_in_section / allocation_chunks);
+                        else
+                            cpi->this_frame_target = (Boost * bits_in_section) / allocation_chunks;
+                    }
+                }
+                else
+                    cpi->this_frame_target = (baseline_bits_at_q(1, Q, cpi->common.MBs) * cpi->last_boost) / 100;
+
+            }
+            // If there is an active ARF at this location use the minimum bits on this frame
+            else
+            {
+                cpi->this_frame_target = 0;           // Minimial spend on gf that is replacing an arf
+            }
+
+            cpi->current_gf_interval = cpi->frames_till_gf_update_due;
+
+        }
+    }
+}
+
+
+void vp8_update_rate_correction_factors(VP8_COMP *cpi, int damp_var)
+{
+    int    Q = cpi->common.base_qindex;
+    int    correction_factor = 100;
+    double rate_correction_factor;
+    double adjustment_limit;
+
+    int    projected_size_based_on_q = 0;
+
+    // Clear down mmx registers to allow floating point in what follows
+    vp8_clear_system_state();  //__asm emms;
+
+    if (cpi->common.frame_type == KEY_FRAME)
+    {
+        rate_correction_factor = cpi->key_frame_rate_correction_factor;
+    }
+    else
+    {
+        if (cpi->common.refresh_alt_ref_frame || cpi->common.refresh_golden_frame)
+            rate_correction_factor = cpi->gf_rate_correction_factor;
+        else
+            rate_correction_factor = cpi->rate_correction_factor;
+    }
+
+    // Work out how big we would have expected the frame to be at this Q given the current correction factor.
+    // Stay in double to avoid int overflow when values are large
+    //projected_size_based_on_q = ((int)(.5 + rate_correction_factor * vp8_bits_per_mb[cpi->common.frame_type][Q]) * cpi->common.MBs) >> BPER_MB_NORMBITS;
+    projected_size_based_on_q = (int)(((.5 + rate_correction_factor * vp8_bits_per_mb[cpi->common.frame_type][Q]) * cpi->common.MBs) / (1 << BPER_MB_NORMBITS));
+
+    // Make some allowance for cpi->zbin_over_quant
+    if (cpi->zbin_over_quant > 0)
+    {
+        int Z = cpi->zbin_over_quant;
+        double Factor = 0.99;
+        double factor_adjustment = 0.01 / 256.0; //(double)ZBIN_OQ_MAX;
+
+        while (Z > 0)
+        {
+            Z --;
+            projected_size_based_on_q *= (int)Factor;
+            Factor += factor_adjustment;
+
+            if (Factor  >= 0.999)
+                Factor = 0.999;
+        }
+    }
+
+    // Work out a size correction factor.
+    //if ( cpi->this_frame_target > 0 )
+    //  correction_factor = (100 * cpi->projected_frame_size) / cpi->this_frame_target;
+    if (projected_size_based_on_q > 0)
+        correction_factor = (100 * cpi->projected_frame_size) / projected_size_based_on_q;
+
+    // More heavily damped adjustment used if we have been oscillating either side of target
+    switch (damp_var)
+    {
+    case 0:
+        adjustment_limit = 0.75;
+        break;
+    case 1:
+        adjustment_limit = 0.375;
+        break;
+    case 2:
+    default:
+        adjustment_limit = 0.25;
+        break;
+    }
+
+    //if ( (correction_factor > 102) && (Q < cpi->active_worst_quality) )
+    if (correction_factor > 102)
+    {
+        // We are not already at the worst allowable quality
+        correction_factor = (int)(100.5 + ((correction_factor - 100) * adjustment_limit));
+        rate_correction_factor = ((rate_correction_factor * correction_factor) / 100);
+
+        // Keep rate_correction_factor within limits
+        if (rate_correction_factor > MAX_BPB_FACTOR)
+            rate_correction_factor = MAX_BPB_FACTOR;
+    }
+    //else if ( (correction_factor < 99) && (Q > cpi->active_best_quality) )
+    else if (correction_factor < 99)
+    {
+        // We are not already at the best allowable quality
+        correction_factor = (int)(100.5 - ((100 - correction_factor) * adjustment_limit));
+        rate_correction_factor = ((rate_correction_factor * correction_factor) / 100);
+
+        // Keep rate_correction_factor within limits
+        if (rate_correction_factor < MIN_BPB_FACTOR)
+            rate_correction_factor = MIN_BPB_FACTOR;
+    }
+
+    if (cpi->common.frame_type == KEY_FRAME)
+        cpi->key_frame_rate_correction_factor = rate_correction_factor;
+    else
+    {
+        if (cpi->common.refresh_alt_ref_frame || cpi->common.refresh_golden_frame)
+            cpi->gf_rate_correction_factor = rate_correction_factor;
+        else
+            cpi->rate_correction_factor = rate_correction_factor;
+    }
+}
+
+static int estimate_bits_at_q(VP8_COMP *cpi, int Q)
+{
+    int Bpm = (int)(.5 + cpi->rate_correction_factor * vp8_bits_per_mb[INTER_FRAME][Q]);
+
+    /* Attempt to retain reasonable accuracy without overflow. The cutoff is
+     * chosen such that the maximum product of Bpm and MBs fits 31 bits. The
+     * largest Bpm takes 20 bits.
+     */
+    if (cpi->common.MBs > (1 << 11))
+        return (Bpm >> BPER_MB_NORMBITS) * cpi->common.MBs;
+    else
+        return (Bpm * cpi->common.MBs) >> BPER_MB_NORMBITS;
+
+}
+
+
+int vp8_regulate_q(VP8_COMP *cpi, int target_bits_per_frame)
+{
+    int Q = cpi->active_worst_quality;
+
+    // Reset Zbin OQ value
+    cpi->zbin_over_quant = 0;
+
+    if (cpi->oxcf.fixed_q >= 0)
+    {
+        Q = cpi->oxcf.fixed_q;
+
+        if (cpi->common.frame_type == KEY_FRAME)
+        {
+            Q = cpi->oxcf.key_q;
+        }
+        else if (cpi->common.refresh_alt_ref_frame)
+        {
+            Q = cpi->oxcf.alt_q;
+        }
+        else if (cpi->common.refresh_golden_frame)
+        {
+            Q = cpi->oxcf.gold_q;
+        }
+
+    }
+    else
+    {
+        int i;
+        int last_error = INT_MAX;
+        int target_bits_per_mb;
+        int bits_per_mb_at_this_q;
+        double correction_factor;
+
+        // Select the appropriate correction factor based upon type of frame.
+        if (cpi->common.frame_type == KEY_FRAME)
+            correction_factor = cpi->key_frame_rate_correction_factor;
+        else
+        {
+            if (cpi->common.refresh_alt_ref_frame || cpi->common.refresh_golden_frame)
+                correction_factor = cpi->gf_rate_correction_factor;
+            else
+                correction_factor = cpi->rate_correction_factor;
+        }
+
+        // Calculate required scaling factor based on target frame size and size of frame produced using previous Q
+        if (target_bits_per_frame >= (INT_MAX >> BPER_MB_NORMBITS))
+            target_bits_per_mb = (target_bits_per_frame / cpi->common.MBs) << BPER_MB_NORMBITS;       // Case where we would overflow int
+        else
+            target_bits_per_mb = (target_bits_per_frame << BPER_MB_NORMBITS) / cpi->common.MBs;
+
+        i = cpi->active_best_quality;
+
+        do
+        {
+            bits_per_mb_at_this_q = (int)(.5 + correction_factor * vp8_bits_per_mb[cpi->common.frame_type][i]);
+
+            if (bits_per_mb_at_this_q <= target_bits_per_mb)
+            {
+                if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error)
+                    Q = i;
+                else
+                    Q = i - 1;
+
+                break;
+            }
+            else
+                last_error = bits_per_mb_at_this_q - target_bits_per_mb;
+        }
+        while (++i <= cpi->active_worst_quality);
+
+
+        // If we are at MAXQ then enable Q over-run which seeks to claw back additional bits through things like
+        // the RD multiplier and zero bin size.
+        if (Q >= MAXQ)
+        {
+            int zbin_oqmax;
+
+            double Factor = 0.99;
+            double factor_adjustment = 0.01 / 256.0; //(double)ZBIN_OQ_MAX;
+
+            if (cpi->common.frame_type == KEY_FRAME)
+                zbin_oqmax = 0; //ZBIN_OQ_MAX/16
+            else if (cpi->common.refresh_alt_ref_frame || (cpi->common.refresh_golden_frame && !cpi->source_alt_ref_active))
+                zbin_oqmax = 16;
+            else
+                zbin_oqmax = ZBIN_OQ_MAX;
+
+            /*{
+                double Factor = (double)target_bits_per_mb/(double)bits_per_mb_at_this_q;
+                double Oq;
+
+                Factor = Factor/1.2683;
+
+                Oq = pow( Factor, (1.0/-0.165) );
+
+                if ( Oq > zbin_oqmax )
+                    Oq = zbin_oqmax;
+
+                cpi->zbin_over_quant = (int)Oq;
+            }*/
+
+            // Each incrment in the zbin is assumed to have a fixed effect on bitrate. This is not of course true.
+            // The effect will be highly clip dependent and may well have sudden steps.
+            // The idea here is to acheive higher effective quantizers than the normal maximum by expanding the zero
+            // bin and hence decreasing the number of low magnitude non zero coefficients.
+            while (cpi->zbin_over_quant < zbin_oqmax)
+            {
+                cpi->zbin_over_quant ++;
+
+                if (cpi->zbin_over_quant > zbin_oqmax)
+                    cpi->zbin_over_quant = zbin_oqmax;
+
+                bits_per_mb_at_this_q *= (int)Factor;                   // Each over-ruin step is assumed to equate to approximately 3% reduction in bitrate
+                Factor += factor_adjustment;
+
+                if (Factor  >= 0.999)
+                    Factor = 0.999;
+
+                if (bits_per_mb_at_this_q <= target_bits_per_mb)    // Break out if we get down to the target rate
+                    break;
+            }
+
+        }
+    }
+
+    return Q;
+}
+
+static int estimate_min_frame_size(VP8_COMP *cpi)
+{
+    double correction_factor;
+    int bits_per_mb_at_max_q;
+
+    // This funtion returns a default value for the first few frames untill the correction factor has had time to adapt.
+    if (cpi->common.current_video_frame < 10)
+    {
+        if (cpi->pass == 2)
+            return (cpi->min_frame_bandwidth);
+        else
+            return cpi->per_frame_bandwidth / 3;
+    }
+
+    /*  // Select the appropriate correction factor based upon type of frame.
+        if ( cpi->common.frame_type == KEY_FRAME )
+            correction_factor = cpi->key_frame_rate_correction_factor;
+        else
+        {
+            if ( cpi->common.refresh_alt_ref_frame || cpi->common.refresh_golden_frame )
+                correction_factor = cpi->gf_rate_correction_factor;
+            else
+                correction_factor = cpi->rate_correction_factor;
+        }*/
+
+    // We estimate at half the value we get from vp8_bits_per_mb
+    correction_factor = cpi->rate_correction_factor / 2.0;
+
+    bits_per_mb_at_max_q = (int)(.5 + correction_factor * vp8_bits_per_mb[cpi->common.frame_type][MAXQ]);
+
+    return (bits_per_mb_at_max_q * cpi->common.MBs) >> BPER_MB_NORMBITS;
+}
+
+void vp8_adjust_key_frame_context(VP8_COMP *cpi)
+{
+    int i;
+    int av_key_frames_per_second;
+
+    // Average key frame frequency and size
+    unsigned int total_weight = 0;
+    unsigned int av_key_frame_frequency = 0;
+    unsigned int av_key_frame_bits = 0;
+
+    unsigned int output_frame_rate = (unsigned int)(100 * cpi->output_frame_rate);
+    unsigned int target_bandwidth = (unsigned int)(100 * cpi->target_bandwidth);
+
+    // Clear down mmx registers to allow floating point in what follows
+    vp8_clear_system_state();  //__asm emms;
+
+    // Update the count of total key frame bits
+    cpi->tot_key_frame_bits += cpi->projected_frame_size;
+
+    // First key frame at start of sequence is a special case. We have no frequency data.
+    if (cpi->key_frame_count == 1)
+    {
+        av_key_frame_frequency = (int)cpi->output_frame_rate * 2;            // Assume a default of 1 kf every 2 seconds
+        av_key_frame_bits = cpi->projected_frame_size;
+        av_key_frames_per_second  = output_frame_rate / av_key_frame_frequency;  // Note output_frame_rate not cpi->output_frame_rate
+    }
+    else
+    {
+        // reset keyframe context and calculate weighted average of last KEY_FRAME_CONTEXT keyframes
+        for (i = 0; i < KEY_FRAME_CONTEXT; i++)
+        {
+            if (i < KEY_FRAME_CONTEXT - 1)
+            {
+                cpi->prior_key_frame_size[i]     = cpi->prior_key_frame_size[i+1];
+                cpi->prior_key_frame_distance[i] = cpi->prior_key_frame_distance[i+1];
+            }
+            else
+            {
+                cpi->prior_key_frame_size[KEY_FRAME_CONTEXT - 1]     = cpi->projected_frame_size;
+                cpi->prior_key_frame_distance[KEY_FRAME_CONTEXT - 1] = cpi->frames_since_key;
+            }
+
+            av_key_frame_bits      += prior_key_frame_weight[i] * cpi->prior_key_frame_size[i];
+            av_key_frame_frequency += prior_key_frame_weight[i] * cpi->prior_key_frame_distance[i];
+            total_weight         += prior_key_frame_weight[i];
+        }
+
+        av_key_frame_bits       /= total_weight;
+        av_key_frame_frequency  /= total_weight;
+        av_key_frames_per_second  = output_frame_rate / av_key_frame_frequency;
+
+    }
+
+    // Do we have any key frame overspend to recover?
+    if ((cpi->pass != 2) && (cpi->projected_frame_size > cpi->per_frame_bandwidth))
+    {
+        // Update the count of key frame overspend to be recovered in subsequent frames
+        // A portion of the KF overspend is treated as gf overspend (and hence recovered more quickly)
+        // as the kf is also a gf. Otherwise the few frames following each kf tend to get more bits
+        // allocated than those following other gfs.
+        cpi->kf_overspend_bits += (cpi->projected_frame_size - cpi->per_frame_bandwidth) * 7 / 8;
+        cpi->gf_overspend_bits += (cpi->projected_frame_size - cpi->per_frame_bandwidth) * 1 / 8;
+
+        // Work out how much to try and recover per frame.
+        // For one pass we estimate the number of frames to spread it over based upon past history.
+        // For two pass we know how many frames there will be till the next kf.
+        if (cpi->pass == 2)
+        {
+            if (cpi->frames_to_key > 16)
+                cpi->kf_bitrate_adjustment = cpi->kf_overspend_bits / (int)cpi->frames_to_key;
+            else
+                cpi->kf_bitrate_adjustment = cpi->kf_overspend_bits / 16;
+        }
+        else
+            cpi->kf_bitrate_adjustment = cpi->kf_overspend_bits / (int)av_key_frame_frequency;
+    }
+
+    cpi->frames_since_key = 0;
+    cpi->last_key_frame_size = cpi->projected_frame_size;
+    cpi->key_frame_count++;
+}
+
+void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit, int *frame_over_shoot_limit)
+{
+    // Set-up bounds on acceptable frame size:
+    if (cpi->oxcf.fixed_q >= 0)
+    {
+        // Fixed Q scenario: frame size never outranges target (there is no target!)
+        *frame_under_shoot_limit = 0;
+        *frame_over_shoot_limit  = INT_MAX;
+    }
+    else
+    {
+        if (cpi->common.frame_type == KEY_FRAME)
+        {
+            *frame_over_shoot_limit  = cpi->this_frame_target * 9 / 8;
+            *frame_under_shoot_limit = cpi->this_frame_target * 7 / 8;
+        }
+        else
+        {
+            if (cpi->common.refresh_alt_ref_frame || cpi->common.refresh_golden_frame)
+            {
+                *frame_over_shoot_limit  = cpi->this_frame_target * 9 / 8;
+                *frame_under_shoot_limit = cpi->this_frame_target * 7 / 8;
+            }
+            else
+            {
+                // For CBR take buffer fullness into account
+                if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+                {
+                    if (cpi->buffer_level >= ((cpi->oxcf.optimal_buffer_level + cpi->oxcf.maximum_buffer_size) >> 1))
+                    {
+                        // Buffer is too full so relax overshoot and tighten undershoot
+                        *frame_over_shoot_limit  = cpi->this_frame_target * 12 / 8;
+                        *frame_under_shoot_limit = cpi->this_frame_target * 6 / 8;
+                    }
+                    else if (cpi->buffer_level <= (cpi->oxcf.optimal_buffer_level >> 1))
+                    {
+                        // Buffer is too low so relax undershoot and tighten overshoot
+                        *frame_over_shoot_limit  = cpi->this_frame_target * 10 / 8;
+                        *frame_under_shoot_limit = cpi->this_frame_target * 4 / 8;
+                    }
+                    else
+                    {
+                        *frame_over_shoot_limit  = cpi->this_frame_target * 11 / 8;
+                        *frame_under_shoot_limit = cpi->this_frame_target * 5 / 8;
+                    }
+                }
+                // VBR
+                // Note that tighter restrictions here can help quality but hurt encode speed
+                else
+                {
+                    *frame_over_shoot_limit  = cpi->this_frame_target * 11 / 8;
+                    *frame_under_shoot_limit = cpi->this_frame_target * 5 / 8;
+                }
+            }
+        }
+    }
+}
diff --git a/vp8/encoder/ratectrl.h b/vp8/encoder/ratectrl.h
new file mode 100644 (file)
index 0000000..588c7a8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if !defined __INC_RATECTRL_H
+
+#include "onyx_int.h"
+
+extern void vp8_save_coding_context(VP8_COMP *cpi);
+extern void vp8_restore_coding_context(VP8_COMP *cpi);
+
+extern void vp8_setup_key_frame(VP8_COMP *cpi);
+extern void vp8_calc_iframe_target_size(VP8_COMP *cpi);
+extern void vp8_calc_pframe_target_size(VP8_COMP *cpi);
+extern void vp8_update_rate_correction_factors(VP8_COMP *cpi, int damp_var);
+extern int vp8_regulate_q(VP8_COMP *cpi, int target_bits_per_frame);
+extern void vp8_adjust_key_frame_context(VP8_COMP *cpi);
+extern void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit, int *frame_over_shoot_limit);
+
+#endif
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
new file mode 100644 (file)
index 0000000..0846996
--- /dev/null
@@ -0,0 +1,2212 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+#include "pragmas.h"
+
+#include "tokenize.h"
+#include "treewriter.h"
+#include "onyx_int.h"
+#include "modecosts.h"
+#include "encodeintra.h"
+#include "entropymode.h"
+#include "reconinter.h"
+#include "reconintra.h"
+#include "reconintra4x4.h"
+#include "findnearmv.h"
+#include "encodemb.h"
+#include "quantize.h"
+#include "idct.h"
+#include "g_common.h"
+#include "variance.h"
+#include "mcomp.h"
+
+#include "vpx_mem/vpx_mem.h"
+#include "dct.h"
+#include "systemdependent.h"
+
+#define DIAMONDSEARCH 1
+#if CONFIG_RUNTIME_CPU_DETECT
+#define IF_RTCD(x)  (x)
+#else
+#define IF_RTCD(x)  NULL
+#endif
+
+
+void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);
+
+
+#define RDFUNC(RM,DM,R,D,target_rd) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
+/*int  RDFUNC( int RM,int DM, int R, int D, int target_r )
+{
+    int rd_value;
+
+    rd_value =  ( ((128+(R)*(RM)) >> 8) + (DM)*(D) );
+
+    return rd_value;
+}*/
+
+#define UVRDFUNC(RM,DM,R,D,target_r)  RDFUNC(RM,DM,R,D,target_r)
+
+#define RDCOST(RM,DM,R,D) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
+
+#define MAXF(a,b)            (((a) > (b)) ? (a) : (b))
+
+
+extern const TOKENEXTRA vp8_dct_value_tokens[DCT_MAX_VALUE*2];
+extern const TOKENEXTRA *vp8_dct_value_tokens_ptr;
+extern int vp8_dct_value_cost[DCT_MAX_VALUE*2];
+extern int *vp8_dct_value_cost_ptr;
+
+
+const int vp8_auto_speed_thresh[17] =
+{
+    1000,
+    200,
+    150,
+    130,
+    150,
+    125,
+    120,
+    115,
+    115,
+    115,
+    115,
+    115,
+    115,
+    115,
+    115,
+    115,
+    105
+};
+
+const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES] =
+{
+    ZEROMV,
+    DC_PRED,
+
+    NEARESTMV,
+    NEARMV,
+
+    ZEROMV,
+    NEARESTMV,
+
+    ZEROMV,
+    NEARESTMV,
+
+    NEARMV,
+    NEARMV,
+
+    V_PRED,
+    H_PRED,
+    TM_PRED,
+
+    NEWMV,
+    NEWMV,
+    NEWMV,
+
+    SPLITMV,
+    SPLITMV,
+    SPLITMV,
+
+    B_PRED,
+};
+
+const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES] =
+{
+    LAST_FRAME,
+    INTRA_FRAME,
+
+    LAST_FRAME,
+    LAST_FRAME,
+
+    GOLDEN_FRAME,
+    GOLDEN_FRAME,
+
+    ALTREF_FRAME,
+    ALTREF_FRAME,
+
+    GOLDEN_FRAME,
+    ALTREF_FRAME,
+
+    INTRA_FRAME,
+    INTRA_FRAME,
+    INTRA_FRAME,
+
+    LAST_FRAME,
+    GOLDEN_FRAME,
+    ALTREF_FRAME,
+
+    LAST_FRAME,
+    GOLDEN_FRAME,
+    ALTREF_FRAME,
+
+    INTRA_FRAME,
+};
+
+static void fill_token_costs(
+    unsigned int c      [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens],
+    const vp8_prob p    [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1]
+)
+{
+    int i, j, k;
+
+
+    for (i = 0; i < BLOCK_TYPES; i++)
+        for (j = 0; j < COEF_BANDS; j++)
+            for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+
+                vp8_cost_tokens((int *)(c [i][j][k]), p [i][j][k], vp8_coef_tree);
+
+}
+
+static int rd_iifactor [ 32 ] =  {    16,  16,  16,  12,   8,   4,   2,   0,
+                                      0,   0,   0,   0,   0,   0,   0,   0,
+                                      0,   0,   0,   0,   0,   0,   0,   0,
+                                      0,   0,   0,   0,   0,   0,   0,   0,
+                                 };
+
+
+
+
+// The values in this table should be reviewed
+static int sad_per_bit16lut[128] =
+{
+    4,  4, 4, 4,  4, 4, 4, 4,   // 4
+    4,  4, 4, 4,  4, 4, 4, 4,   // 1
+    4,  4, 4, 4,  4, 4, 4, 4,   // 2
+    4,  4, 4, 4,  4, 4, 4, 4,   // 3
+    4,  4, 4, 4,  4, 4, 4, 4,   // 4
+    4,  4, 12, 12, 13, 13, 14, 14, // 5
+    14, 14, 14, 15, 15, 15, 15, 15, // 6
+    15, 15, 15, 15, 15, 15, 15, 15, // 7
+    15, 15, 15, 15, 15, 16, 16, 16, // 8
+    16, 16, 18, 18, 18, 18, 19, 19, // 9
+    19, 19, 19, 19, 19, 19, 19, 19, // 10
+    20, 20, 22, 22, 22, 22, 21, 21, // 11
+    22, 22, 22, 22, 22, 22, 22, 22, // 12
+    22, 22, 22, 22, 22, 22, 22, 22, // 13
+    22, 22, 22, 22, 22, 22, 22, 22, // 14
+    22, 22, 22, 22, 22, 22, 22, 22, // 15
+};
+
+static int sad_per_bit4lut[128] =
+{
+    4,  4, 4, 4,  4, 4, 4, 4,   // 4
+    4,  4, 4, 4,  4, 4, 4, 4,   // 1
+    4,  4, 4, 4,  4, 4, 4, 4,   // 2
+    4,  4, 4, 4,  4, 4, 4, 4,   // 3
+    4,  4, 4, 4,  4, 4, 4, 4,   // 4
+    4,  4, 15, 15, 15, 15, 16, 16, // 5
+    16, 17, 17, 17, 17, 17, 17, 17, // 6
+    17, 17, 19, 19, 22, 22, 21, 21, // 7
+    23, 23, 23, 23, 23, 24, 24, 24, // 8
+    25, 25, 27, 27, 27, 27, 28, 28, // 9
+    28, 28, 29, 29, 29, 29, 29, 29, // 10
+    30, 30, 31, 31, 31, 31, 32, 32, // 11
+    34, 34, 34, 34, 34, 34, 34, 34, // 12
+    34, 34, 34, 34, 34, 34, 34, 34, // 13
+    34, 34, 34, 34, 34, 34, 34, 34, // 14
+    34, 34, 34, 34, 34, 34, 34, 34, // 15
+};
+
+void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex)
+{
+    cpi->mb.sadperbit16 =  sad_per_bit16lut[QIndex];
+    cpi->mb.sadperbit4  =  sad_per_bit4lut[QIndex];
+}
+
+void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
+{
+    int q;
+    int i;
+    int *thresh;
+    int threshmult;
+
+    int capped_q = (Qvalue < 160) ? Qvalue : 160;
+
+    vp8_clear_system_state();  //__asm emms;
+
+    cpi->RDMULT = (int)((0.00007 * (capped_q * capped_q * capped_q * capped_q)) - (0.0125 * (capped_q * capped_q * capped_q)) +
+                        (2.25 * (capped_q * capped_q)) - (12.5 * capped_q) + 25.0);
+
+    if (cpi->RDMULT < 25)
+        cpi->RDMULT = 25;
+
+    if (cpi->pass == 2)
+    {
+        if (cpi->common.frame_type == KEY_FRAME)
+            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[0]) / 16;
+        else if (cpi->next_iiratio > 31)
+            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) / 16;
+        else
+            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->next_iiratio]) / 16;
+    }
+
+
+    // Extend rate multiplier along side quantizer zbin increases
+    if (cpi->zbin_over_quant  > 0)
+    {
+        // Extend rate multiplier along side quantizer zbin increases
+        if (cpi->zbin_over_quant  > 0)
+        {
+            double oq_factor = pow(1.006,  cpi->zbin_over_quant);
+
+            if (oq_factor > (1.0 + ((double)cpi->zbin_over_quant / 64.0)))
+                oq_factor = (1.0 + (double)cpi->zbin_over_quant / 64.0);
+
+            cpi->RDMULT *= (int)oq_factor;
+        }
+    }
+
+    cpi->mb.errorperbit = (cpi->RDMULT / 100);
+
+    if (cpi->mb.errorperbit < 1)
+        cpi->mb.errorperbit = 1;
+
+    vp8_set_speed_features(cpi);
+
+    if (cpi->common.simpler_lpf)
+        cpi->common.filter_type = SIMPLE_LOOPFILTER;
+
+    q = (int)pow(Qvalue, 1.25);
+
+    if (q < 8)
+        q = 8;
+
+    if (cpi->ref_frame_flags == VP8_ALT_FLAG)
+    {
+        thresh      = &cpi->rd_threshes[THR_NEWA];
+        threshmult  = cpi->sf.thresh_mult[THR_NEWA];
+    }
+    else if (cpi->ref_frame_flags == VP8_GOLD_FLAG)
+    {
+        thresh      = &cpi->rd_threshes[THR_NEWG];
+        threshmult  = cpi->sf.thresh_mult[THR_NEWG];
+    }
+    else
+    {
+        thresh      = &cpi->rd_threshes[THR_NEWMV];
+        threshmult  = cpi->sf.thresh_mult[THR_NEWMV];
+    }
+
+    if (cpi->RDMULT > 1000)
+    {
+        cpi->RDDIV = 1;
+        cpi->RDMULT /= 100;
+
+        for (i = 0; i < MAX_MODES; i++)
+        {
+            if (cpi->sf.thresh_mult[i] < INT_MAX)
+            {
+                cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100;
+            }
+            else
+            {
+                cpi->rd_threshes[i] = INT_MAX;
+            }
+
+            cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
+        }
+    }
+    else
+    {
+        cpi->RDDIV = 100;
+
+        for (i = 0; i < MAX_MODES; i++)
+        {
+            if (cpi->sf.thresh_mult[i] < (INT_MAX / q))
+            {
+                cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q;
+            }
+            else
+            {
+                cpi->rd_threshes[i] = INT_MAX;
+            }
+
+            cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
+        }
+    }
+
+    fill_token_costs(
+        cpi->mb.token_costs,
+        (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs
+    );
+
+    vp8_init_mode_costs(cpi);
+
+}
+
+void vp8_auto_select_speed(VP8_COMP *cpi)
+{
+    int used = cpi->oxcf.cpu_used;
+
+    int milliseconds_for_compress = (int)(1000000 / cpi->oxcf.frame_rate);
+
+    milliseconds_for_compress = milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16;
+
+#if 0
+
+    if (0)
+    {
+        FILE *f;
+
+        f = fopen("speed.stt", "a");
+        fprintf(f, " %8ld %10ld %10ld %10ld\n",
+                cpi->common.current_video_frame, cpi->Speed, milliseconds_for_compress, cpi->avg_pick_mode_time);
+        fclose(f);
+    }
+
+#endif
+
+    /*
+    // this is done during parameter valid check
+    if( used > 16)
+        used = 16;
+    if( used < -16)
+        used = -16;
+    */
+
+    if (cpi->avg_pick_mode_time < milliseconds_for_compress && (cpi->avg_encode_time - cpi->avg_pick_mode_time) < milliseconds_for_compress)
+    {
+        if (cpi->avg_pick_mode_time == 0)
+        {
+            cpi->Speed = 4;
+        }
+        else
+        {
+            if (milliseconds_for_compress * 100 < cpi->avg_encode_time * 95)
+            {
+                cpi->Speed          += 2;
+                cpi->avg_pick_mode_time = 0;
+                cpi->avg_encode_time = 0;
+
+                if (cpi->Speed > 16)
+                {
+                    cpi->Speed = 16;
+                }
+            }
+
+            if (milliseconds_for_compress * 100 > cpi->avg_encode_time * vp8_auto_speed_thresh[cpi->Speed])
+            {
+                cpi->Speed          -= 1;
+                cpi->avg_pick_mode_time = 0;
+                cpi->avg_encode_time = 0;
+
+                // In real-time mode, cpi->speed is in [4, 16].
+                if (cpi->Speed < 4)        //if ( cpi->Speed < 0 )
+                {
+                    cpi->Speed = 4;        //cpi->Speed = 0;
+                }
+            }
+        }
+    }
+    else
+    {
+        cpi->Speed += 4;
+
+        if (cpi->Speed > 16)
+            cpi->Speed = 16;
+
+
+        cpi->avg_pick_mode_time = 0;
+        cpi->avg_encode_time = 0;
+    }
+}
+
+int vp8_block_error_c(short *coeff, short *dqcoeff)
+{
+    int i;
+    int error = 0;
+
+    for (i = 0; i < 16; i++)
+    {
+        int this_diff = coeff[i] - dqcoeff[i];
+        error += this_diff * this_diff;
+    }
+
+    return error;
+}
+
+int vp8_mbblock_error_c(MACROBLOCK *mb, int dc)
+{
+    BLOCK  *be;
+    BLOCKD *bd;
+    int i, j;
+    int berror, error = 0;
+
+    for (i = 0; i < 16; i++)
+    {
+        be = &mb->block[i];
+        bd = &mb->e_mbd.block[i];
+
+        berror = 0;
+
+        for (j = dc; j < 16; j++)
+        {
+            int this_diff = be->coeff[j] - bd->dqcoeff[j];
+            berror += this_diff * this_diff;
+        }
+
+        error += berror;
+    }
+
+    return error;
+}
+
+int vp8_mbuverror_c(MACROBLOCK *mb)
+{
+
+    BLOCK  *be;
+    BLOCKD *bd;
+
+
+    int i;
+    int error = 0;
+
+    for (i = 16; i < 24; i++)
+    {
+        be = &mb->block[i];
+        bd = &mb->e_mbd.block[i];
+
+        error += vp8_block_error_c(be->coeff, bd->dqcoeff);
+    }
+
+    return error;
+}
+
+#if !(CONFIG_REALTIME_ONLY)
+static int macro_block_max_error(MACROBLOCK *mb)
+{
+    int error = 0;
+    int dc = 0;
+    BLOCK  *be;
+    int i, j;
+    int berror;
+
+    dc = !(mb->e_mbd.mbmi.mode == B_PRED || mb->e_mbd.mbmi.mode == SPLITMV);
+
+    for (i = 0; i < 16; i++)
+    {
+        be = &mb->block[i];
+
+        berror = 0;
+
+        for (j = dc; j < 16; j++)
+        {
+            int this_diff = be->coeff[j];
+            berror += this_diff * this_diff;
+        }
+
+        error += berror;
+    }
+
+    for (i = 16; i < 24; i++)
+    {
+        be = &mb->block[i];
+        berror = 0;
+
+        for (j = 0; j < 16; j++)
+        {
+            int this_diff = be->coeff[j];
+            berror += this_diff * this_diff;
+        }
+
+        error += berror;
+    }
+
+    error <<= 2;
+
+    if (dc)
+    {
+        be = &mb->block[24];
+        berror = 0;
+
+        for (j = 0; j < 16; j++)
+        {
+            int this_diff = be->coeff[j];
+            berror += this_diff * this_diff;
+        }
+
+        error += berror;
+    }
+
+    error >>= 4;
+    return error;
+}
+#endif
+
+int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd)
+{
+    unsigned char *uptr, *vptr;
+    unsigned char *upred_ptr = (*(x->block[16].base_src) + x->block[16].src);
+    unsigned char *vpred_ptr = (*(x->block[20].base_src) + x->block[20].src);
+    int uv_stride = x->block[16].src_stride;
+
+    unsigned int sse1 = 0;
+    unsigned int sse2 = 0;
+    int mv_row;
+    int mv_col;
+    int offset;
+    int pre_stride = x->e_mbd.block[16].pre_stride;
+
+    vp8_build_uvmvs(&x->e_mbd, 0);
+    mv_row = x->e_mbd.block[16].bmi.mv.as_mv.row;
+    mv_col = x->e_mbd.block[16].bmi.mv.as_mv.col;
+
+    offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
+    uptr = x->e_mbd.pre.u_buffer + offset;
+    vptr = x->e_mbd.pre.v_buffer + offset;
+
+    if ((mv_row | mv_col) & 7)
+    {
+        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2);
+        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1);
+        sse2 += sse1;
+    }
+    else
+    {
+        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2);
+        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1);
+        sse2 += sse1;
+    }
+
+    return sse2;
+
+}
+
+#if !(CONFIG_REALTIME_ONLY)
+static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
+{
+    int c = !type;              /* start at coef 0, unless Y with Y2 */
+    int eob = b->eob;
+    int pt ;    /* surrounding block/prev coef predictor */
+    int cost = 0;
+    short *qcoeff_ptr = b->qcoeff;
+
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+
+# define QC( I)  ( qcoeff_ptr [vp8_default_zig_zag1d[I]] )
+
+    for (; c < eob; c++)
+    {
+        int v = QC(c);
+        int t = vp8_dct_value_tokens_ptr[v].Token;
+        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [t];
+        cost += vp8_dct_value_cost_ptr[v];
+        pt = vp8_prev_token_class[t];
+    }
+
+# undef QC
+
+    if (c < 16)
+        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [DCT_EOB_TOKEN];
+
+    pt = (c != !type); // is eob first coefficient;
+    *a = *l = pt;
+
+    return cost;
+}
+
+int vp8_rdcost_mby(MACROBLOCK *mb)
+{
+    int cost = 0;
+    int b;
+    TEMP_CONTEXT t, t2;
+    int type = 0;
+
+    MACROBLOCKD *x = &mb->e_mbd;
+
+    vp8_setup_temp_context(&t, x->above_context[Y1CONTEXT], x->left_context[Y1CONTEXT], 4);
+    vp8_setup_temp_context(&t2, x->above_context[Y2CONTEXT], x->left_context[Y2CONTEXT], 1);
+
+    if (x->mbmi.mode == SPLITMV)
+        type = 3;
+
+    for (b = 0; b < 16; b++)
+        cost += cost_coeffs(mb, x->block + b, type,
+                            t.a + vp8_block2above[b], t.l + vp8_block2left[b]);
+
+    if (x->mbmi.mode != SPLITMV)
+        cost += cost_coeffs(mb, x->block + 24, 1,
+                            t2.a + vp8_block2above[24], t2.l + vp8_block2left[24]);
+
+    return cost;
+}
+
+
+static void rd_pick_intra4x4block(
+    VP8_COMP *cpi,
+    MACROBLOCK *x,
+    BLOCK *be,
+    BLOCKD *b,
+    B_PREDICTION_MODE *best_mode,
+    B_PREDICTION_MODE above,
+    B_PREDICTION_MODE left,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+
+    int *bestrate,
+    int *bestratey,
+    int *bestdistortion)
+{
+    B_PREDICTION_MODE mode;
+    int best_rd = INT_MAX;       // 1<<30
+    int rate = 0;
+    int distortion;
+    unsigned int *mode_costs;
+
+    ENTROPY_CONTEXT ta = *a, tempa = *a;
+    ENTROPY_CONTEXT tl = *l, templ = *l;
+
+
+    if (x->e_mbd.frame_type == KEY_FRAME)
+    {
+        mode_costs  = x->bmode_costs[above][left];
+    }
+    else
+    {
+        mode_costs = x->inter_bmode_costs;
+    }
+
+    for (mode = B_DC_PRED; mode <= B_HU_PRED; mode++)
+    {
+        int this_rd;
+        int ratey;
+
+        rate = mode_costs[mode];
+        vp8_encode_intra4x4block_rd(IF_RTCD(&cpi->rtcd), x, be, b, mode);
+
+        tempa = ta;
+        templ = tl;
+
+        ratey = cost_coeffs(x, b, 3, &tempa, &templ);
+        rate += ratey;
+        distortion = ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)(be->coeff, b->dqcoeff) >> 2;
+
+        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
+
+        if (this_rd < best_rd)
+        {
+            *bestrate = rate;
+            *bestratey = ratey;
+            *bestdistortion = distortion;
+            best_rd = this_rd;
+            *best_mode = mode;
+            *a = tempa;
+            *l = templ;
+        }
+    }
+
+    b->bmi.mode = (B_PREDICTION_MODE)(*best_mode);
+    vp8_encode_intra4x4block_rd(IF_RTCD(&cpi->rtcd), x, be, b, b->bmi.mode);
+
+}
+
+
+int vp8_rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rate, int *rate_y, int *Distortion)
+{
+    MACROBLOCKD *const xd = &mb->e_mbd;
+    int i;
+    TEMP_CONTEXT t;
+    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
+    int distortion = 0;
+    int tot_rate_y = 0;
+
+    vp8_intra_prediction_down_copy(xd);
+    vp8_setup_temp_context(&t, xd->above_context[Y1CONTEXT], xd->left_context[Y1CONTEXT], 4);
+
+    for (i = 0; i < 16; i++)
+    {
+        MODE_INFO *const mic = xd->mode_info_context;
+        const int mis = xd->mode_info_stride;
+        const B_PREDICTION_MODE A = vp8_above_bmi(mic, i, mis)->mode;
+        const B_PREDICTION_MODE L = vp8_left_bmi(mic, i)->mode;
+        B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
+        int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(ry), UNINITIALIZED_IS_SAFE(d);
+
+        rd_pick_intra4x4block(
+            cpi, mb, mb->block + i, xd->block + i, &best_mode, A, L,
+            t.a + vp8_block2above[i],
+            t.l + vp8_block2left[i], &r, &ry, &d);
+
+        cost += r;
+        distortion += d;
+        tot_rate_y += ry;
+        mic->bmi[i].mode = xd->block[i].bmi.mode = best_mode;
+    }
+
+    *Rate = cost;
+    *rate_y += tot_rate_y;
+    *Distortion = distortion;
+
+    return RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
+}
+
+int vp8_rd_pick_intra16x16mby_mode(VP8_COMP *cpi, MACROBLOCK *x, int *Rate, int *rate_y, int *Distortion)
+{
+
+    MB_PREDICTION_MODE mode;
+    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
+    int rate, ratey;
+    unsigned int distortion;
+    int best_rd = INT_MAX;
+
+    //Y Search for 16x16 intra prediction mode
+    for (mode = DC_PRED; mode <= TM_PRED; mode++)
+    {
+        int this_rd;
+        int dummy;
+        rate = 0;
+
+        x->e_mbd.mbmi.mode = mode;
+
+        rate += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.mode];
+
+        vp8_encode_intra16x16mbyrd(IF_RTCD(&cpi->rtcd), x);
+
+        ratey = vp8_rdcost_mby(x);
+
+        rate += ratey;
+
+        VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16var)(x->src.y_buffer, x->src.y_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride, &distortion, &dummy);
+
+        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
+
+        if (this_rd < best_rd)
+        {
+            mode_selected = mode;
+            best_rd = this_rd;
+            *Rate = rate;
+            *rate_y = ratey;
+            *Distortion = (int)distortion;
+        }
+    }
+
+    x->e_mbd.mbmi.mode = mode_selected;
+    return best_rd;
+}
+
+
+static int rd_cost_mbuv(MACROBLOCK *mb)
+{
+    TEMP_CONTEXT t, t2;
+    int b;
+    int cost = 0;
+    MACROBLOCKD *x = &mb->e_mbd;
+
+    vp8_setup_temp_context(&t, x->above_context[UCONTEXT], x->left_context[UCONTEXT], 2);
+    vp8_setup_temp_context(&t2, x->above_context[VCONTEXT], x->left_context[VCONTEXT], 2);
+
+    for (b = 16; b < 20; b++)
+        cost += cost_coeffs(mb, x->block + b, vp8_block2type[b],
+                            t.a + vp8_block2above[b], t.l + vp8_block2left[b]);
+
+    for (b = 20; b < 24; b++)
+        cost += cost_coeffs(mb, x->block + b, vp8_block2type[b],
+                            t2.a + vp8_block2above[b], t2.l + vp8_block2left[b]);
+
+    return cost;
+}
+
+
+unsigned int vp8_get_mbuvrecon_error(const vp8_variance_rtcd_vtable_t *rtcd, const MACROBLOCK *x) // sum of squares
+{
+    unsigned int sse0, sse1;
+    int sum0, sum1;
+    VARIANCE_INVOKE(rtcd, get8x8var)(x->src.u_buffer, x->src.uv_stride, x->e_mbd.dst.u_buffer, x->e_mbd.dst.uv_stride, &sse0, &sum0);
+    VARIANCE_INVOKE(rtcd, get8x8var)(x->src.v_buffer, x->src.uv_stride, x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride, &sse1, &sum1);
+    return (sse0 + sse1);
+}
+
+static int vp8_rd_inter_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *distortion, int fullpixel)
+{
+    vp8_build_uvmvs(&x->e_mbd, fullpixel);
+    vp8_encode_inter16x16uvrd(IF_RTCD(&cpi->rtcd), x);
+
+
+    *rate       = rd_cost_mbuv(x);
+    *distortion = ENCODEMB_INVOKE(&cpi->rtcd.encodemb, mbuverr)(x) / 4;
+
+    return UVRDFUNC(x->rdmult, x->rddiv, *rate, *distortion, cpi->target_bits_per_mb);
+}
+
+int vp8_rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly, int *distortion)
+{
+    MB_PREDICTION_MODE mode;
+    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
+    int best_rd = INT_MAX;
+    int UNINITIALIZED_IS_SAFE(d), UNINITIALIZED_IS_SAFE(r);
+    int rate_to;
+
+    for (mode = DC_PRED; mode <= TM_PRED; mode++)
+    {
+        int rate;
+        int distortion;
+        int this_rd;
+
+        x->e_mbd.mbmi.uv_mode = mode;
+        vp8_encode_intra16x16mbuvrd(IF_RTCD(&cpi->rtcd), x);
+
+        rate_to = rd_cost_mbuv(x);
+        rate = rate_to + x->intra_uv_mode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.uv_mode];
+
+        distortion = vp8_get_mbuvrecon_error(IF_RTCD(&cpi->rtcd.variance), x);
+
+        this_rd = UVRDFUNC(x->rdmult, x->rddiv, rate, distortion, cpi->target_bits_per_mb);
+
+        if (this_rd < best_rd)
+        {
+            best_rd = this_rd;
+            d = distortion;
+            r = rate;
+            *rate_tokenonly = rate_to;
+            mode_selected = mode;
+        }
+    }
+
+    *rate = r;
+    *distortion = d;
+
+    x->e_mbd.mbmi.uv_mode = mode_selected;
+    return best_rd;
+}
+#endif
+
+int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4])
+{
+    vp8_prob p [VP8_MVREFS-1];
+    assert(NEARESTMV <= m  &&  m <= SPLITMV);
+    vp8_mv_ref_probs(p, near_mv_ref_ct);
+    return vp8_cost_token(vp8_mv_ref_tree, p, VP8_MVREFENCODINGS + m);
+}
+
+void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, MV *mv)
+{
+    int i;
+
+    x->e_mbd.mbmi.mode = mb;
+    x->e_mbd.mbmi.mv.as_mv.row = mv->row;
+    x->e_mbd.mbmi.mv.as_mv.col = mv->col;
+
+    for (i = 0; i < 16; i++)
+    {
+        B_MODE_INFO *bmi = &x->e_mbd.block[i].bmi;
+        bmi->mode = (B_PREDICTION_MODE) mb;
+        bmi->mv.as_mv.row = mv->row;
+        bmi->mv.as_mv.col = mv->col;
+    }
+}
+
+#if !(CONFIG_REALTIME_ONLY)
+int vp8_count_labels(int const *labelings)
+{
+    int i;
+    int count = 0;
+
+    for (i = 0; i < 16; i++)
+    {
+        if (labelings[i] > count)
+            count = labelings[i];
+    }
+
+    return count + 1;
+}
+
+
+static int labels2mode(
+    MACROBLOCK *x,
+    int const *labelings, int which_label,
+    B_PREDICTION_MODE this_mode,
+    MV *this_mv, MV *best_ref_mv,
+    int *mvcost[2]
+)
+{
+    MACROBLOCKD *const xd = & x->e_mbd;
+    MODE_INFO *const mic = xd->mode_info_context;
+    const int mis = xd->mode_info_stride;
+
+    int cost = 0;
+    int thismvcost = 0;
+
+    /* We have to be careful retrieving previously-encoded motion vectors.
+       Ones from this macroblock have to be pulled from the BLOCKD array
+       as they have not yet made it to the bmi array in our MB_MODE_INFO. */
+
+    int i = 0;
+
+    do
+    {
+        BLOCKD *const d = xd->block + i;
+        const int row = i >> 2,  col = i & 3;
+
+        B_PREDICTION_MODE m;
+
+        if (labelings[i] != which_label)
+            continue;
+
+        if (col  &&  labelings[i] == labelings[i-1])
+            m = LEFT4X4;
+        else if (row  &&  labelings[i] == labelings[i-4])
+            m = ABOVE4X4;
+        else
+        {
+            // the only time we should do costing for new motion vector or mode
+            // is when we are on a new label  (jbb May 08, 2007)
+            switch (m = this_mode)
+            {
+            case NEW4X4 :
+                thismvcost  = vp8_mv_bit_cost(this_mv, best_ref_mv, mvcost, 102);
+                break;
+            case LEFT4X4:
+                *this_mv = col ? d[-1].bmi.mv.as_mv : vp8_left_bmi(mic, i)->mv.as_mv;
+                break;
+            case ABOVE4X4:
+                *this_mv = row ? d[-4].bmi.mv.as_mv : vp8_above_bmi(mic, i, mis)->mv.as_mv;
+                break;
+            case ZERO4X4:
+                this_mv->row = this_mv->col = 0;
+                break;
+            default:
+                break;
+            }
+
+            if (m == ABOVE4X4)  // replace above with left if same
+            {
+                const MV mv = col ? d[-1].bmi.mv.as_mv : vp8_left_bmi(mic, i)->mv.as_mv;
+
+                if (mv.row == this_mv->row  &&  mv.col == this_mv->col)
+                    m = LEFT4X4;
+            }
+
+            cost = x->inter_bmode_costs[ m];
+        }
+
+        d->bmi.mode = m;
+        d->bmi.mv.as_mv = *this_mv;
+
+    }
+    while (++i < 16);
+
+    cost += thismvcost ;
+    return cost;
+}
+
+static int rdcost_mbsegment_y(MACROBLOCK *mb, const int *labels, int which_label, TEMP_CONTEXT *t)
+{
+    int cost = 0;
+    int b;
+    MACROBLOCKD *x = &mb->e_mbd;
+
+
+    for (b = 0; b < 16; b++)
+        if (labels[ b] == which_label)
+            cost += cost_coeffs(mb, x->block + b, 3,
+                                t->a + vp8_block2above[b],
+                                t->l + vp8_block2left[b]);
+
+    return cost;
+
+}
+static unsigned int vp8_encode_inter_mb_segment(MACROBLOCK *x, int const *labels, int which_label, const vp8_encodemb_rtcd_vtable_t *rtcd)
+{
+    int i;
+    unsigned int distortion = 0;
+
+    for (i = 0; i < 16; i++)
+    {
+        if (labels[i] == which_label)
+        {
+            BLOCKD *bd = &x->e_mbd.block[i];
+            BLOCK *be = &x->block[i];
+
+
+            vp8_build_inter_predictors_b(bd, 16, x->e_mbd.subpixel_predict);
+            ENCODEMB_INVOKE(rtcd, subb)(be, bd, 16);
+            x->short_fdct4x4rd(be->src_diff, be->coeff, 32);
+
+            // set to 0 no way to account for 2nd order DC so discount
+            //be->coeff[0] = 0;
+            x->quantize_brd(be, bd);
+
+            distortion += ENCODEMB_INVOKE(rtcd, berr)(be->coeff, bd->dqcoeff);
+        }
+    }
+
+    return distortion;
+}
+
+static void macro_block_yrd(MACROBLOCK *mb, int *Rate, int *Distortion, const vp8_encodemb_rtcd_vtable_t *rtcd)
+{
+    int b;
+    MACROBLOCKD *const x = &mb->e_mbd;
+    BLOCK   *const mb_y2 = mb->block + 24;
+    BLOCKD *const x_y2  = x->block + 24;
+    short *Y2DCPtr = mb_y2->src_diff;
+    BLOCK *beptr;
+    int d;
+
+    ENCODEMB_INVOKE(rtcd, submby)(mb->src_diff, mb->src.y_buffer, mb->e_mbd.predictor, mb->src.y_stride);
+
+    // Fdct and building the 2nd order block
+    for (beptr = mb->block; beptr < mb->block + 16; beptr += 2)
+    {
+        mb->short_fdct8x4rd(beptr->src_diff, beptr->coeff, 32);
+        *Y2DCPtr++ = beptr->coeff[0];
+        *Y2DCPtr++ = beptr->coeff[16];
+    }
+
+    // 2nd order fdct
+    if (x->mbmi.mode != SPLITMV)
+    {
+        mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8);
+    }
+
+    // Quantization
+    for (b = 0; b < 16; b++)
+    {
+        mb->quantize_brd(&mb->block[b], &mb->e_mbd.block[b]);
+    }
+
+    // DC predication and Quantization of 2nd Order block
+    if (x->mbmi.mode != SPLITMV)
+    {
+
+        {
+            mb->quantize_brd(mb_y2, x_y2);
+        }
+    }
+
+    // Distortion
+    if (x->mbmi.mode == SPLITMV)
+        d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 0) << 2;
+    else
+    {
+        d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
+        d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
+    }
+
+    *Distortion = (d >> 4);
+
+    // rate
+    *Rate = vp8_rdcost_mby(mb);
+}
+
+static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *best_ref_mv, int best_rd, int *mdcounts, int *returntotrate, int *returnyrate, int *returndistortion, int compressor_speed, int *mvcost[2], int mvthresh, int fullpixel)
+{
+    int i, segmentation;
+    B_PREDICTION_MODE this_mode;
+    MACROBLOCKD *xc = &x->e_mbd;
+    BLOCK *b = &x->block[0];
+    BLOCKD *d = &x->e_mbd.block[0];
+    BLOCK *c = &x->block[0];
+    BLOCKD *e = &x->e_mbd.block[0];
+    int const *labels;
+    int best_segment_rd = INT_MAX;
+    int best_seg = 0;
+    int br = 0;
+    int bd = 0;
+    int bsr = 0;
+    int bsd = 0;
+    int bestsegmentyrate = 0;
+
+    // FIX TO Rd error outrange bug PGW 9 june 2004
+    B_PREDICTION_MODE bmodes[16] = {ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
+                                    ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
+                                    ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
+                                    ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4
+                                   };
+
+    MV bmvs[16];
+    int beobs[16];
+
+    for (segmentation = 0; segmentation < VP8_NUMMBSPLITS; segmentation++)
+    {
+        int label_count;
+        int this_segment_rd = 0;
+        int label_mv_thresh;
+        int rate = 0;
+        int sbr = 0;
+        int sbd = 0;
+        int UNINITIALIZED_IS_SAFE(sseshift);
+        int segmentyrate = 0;
+
+        vp8_variance_fn_ptr_t v_fn_ptr;
+
+        TEMP_CONTEXT t;
+        TEMP_CONTEXT tb;
+        vp8_setup_temp_context(&t, xc->above_context[Y1CONTEXT], xc->left_context[Y1CONTEXT], 4);
+
+        br = 0;
+        bd = 0;
+
+        switch (segmentation)
+        {
+        case 0:
+            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x8);
+            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar16x8);
+            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x8);
+            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x8x3);
+            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x8x4d);
+            sseshift = 3;
+            break;
+        case 1:
+            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var8x16);
+            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar8x16);
+            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x16);
+            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x16x3);
+            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x16x4d);
+            sseshift = 3;
+            break;
+        case 2:
+            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var8x8);
+            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar8x8);
+            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x8);
+            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x8x3);
+            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x8x4d);
+            sseshift = 2;
+            break;
+        case 3:
+            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var4x4);
+            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar4x4);
+            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad4x4);
+            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad4x4x3);
+            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad4x4x4d);
+            sseshift = 0;
+            break;
+        }
+
+        labels = vp8_mbsplits[segmentation];
+        label_count = vp8_count_labels(labels);
+
+        // 64 makes this threshold really big effectively
+        // making it so that we very rarely check mvs on
+        // segments.   setting this to 1 would make mv thresh
+        // roughly equal to what it is for macroblocks
+        label_mv_thresh = 1 * mvthresh / label_count ;
+
+        // Segmentation method overheads
+        rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation);
+
+        rate += vp8_cost_mv_ref(SPLITMV, mdcounts);
+
+        this_segment_rd += RDFUNC(x->rdmult, x->rddiv, rate, 0, cpi->target_bits_per_mb);
+        br += rate;
+
+        for (i = 0; i < label_count; i++)
+        {
+            MV mode_mv[B_MODE_COUNT];
+            int best_label_rd = INT_MAX;
+            B_PREDICTION_MODE mode_selected = ZERO4X4;
+            int j;
+            int bestlabelyrate = 0;
+
+            b = &x->block[0];
+            d = &x->e_mbd.block[0];
+
+
+            // find first label
+            for (j = 0; j < 16; j++)
+                if (labels[j] == i)
+                    break;
+
+            c = &x->block[j];
+            e = &x->e_mbd.block[j];
+
+            // search for the best motion vector on this segment
+            for (this_mode = LEFT4X4; this_mode <= NEW4X4 ; this_mode ++)
+            {
+                int distortion;
+                int this_rd;
+                int num00;
+                int labelyrate;
+
+                TEMP_CONTEXT ts;
+                vp8_setup_temp_context(&ts, &t.a[0], &t.l[0], 4);
+
+                if (this_mode == NEW4X4)
+                {
+                    int step_param = 0;
+                    int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
+                    int n;
+                    int thissme;
+                    int bestsme = INT_MAX;
+                    MV  temp_mv;
+
+                    // Is the best so far sufficiently good that we cant justify doing and new motion search.
+                    if (best_label_rd < label_mv_thresh)
+                        break;
+
+                    {
+                        int sadpb = x->sadperbit4;
+
+                        if (cpi->sf.search_method == HEX)
+                            bestsme = vp8_hex_search(x, c, e, best_ref_mv, &mode_mv[NEW4X4], step_param, sadpb/*x->errorperbit*/, &num00, v_fn_ptr.vf, v_fn_ptr.sdf, x->mvsadcost, mvcost);
+                        else
+                        {
+                            bestsme = cpi->diamond_search_sad(x, c, e, best_ref_mv, &mode_mv[NEW4X4], step_param, sadpb / 2/*x->errorperbit*/, &num00, &v_fn_ptr, x->mvsadcost, mvcost);
+
+                            n = num00;
+                            num00 = 0;
+
+                            while (n < further_steps)
+                            {
+                                n++;
+
+                                if (num00)
+                                    num00--;
+                                else
+                                {
+                                    thissme = cpi->diamond_search_sad(x, c, e, best_ref_mv, &temp_mv, step_param + n, sadpb / 2/*x->errorperbit*/, &num00, &v_fn_ptr, x->mvsadcost, mvcost);
+
+                                    if (thissme < bestsme)
+                                    {
+                                        bestsme = thissme;
+                                        mode_mv[NEW4X4].row = temp_mv.row;
+                                        mode_mv[NEW4X4].col = temp_mv.col;
+                                    }
+                                }
+                            }
+                        }
+
+                        // Should we do a full search (best quality only)
+                        if ((compressor_speed == 0) && (bestsme >> sseshift) > 4000)
+                        {
+                            thissme = cpi->full_search_sad(x, c, e, best_ref_mv, sadpb / 4, 16, &v_fn_ptr, x->mvcost, x->mvsadcost);
+
+                            if (thissme < bestsme)
+                            {
+                                bestsme = thissme;
+                                mode_mv[NEW4X4] = e->bmi.mv.as_mv;
+                            }
+                            else
+                            {
+                                // The full search result is actually worse so re-instate the previous best vector
+                                e->bmi.mv.as_mv = mode_mv[NEW4X4];
+                            }
+                        }
+                    }
+
+                    if (bestsme < INT_MAX)
+                    {
+                        if (!fullpixel)
+                            cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], best_ref_mv, x->errorperbit / 2, v_fn_ptr.svf, v_fn_ptr.vf, mvcost);
+                        else
+                            vp8_skip_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], best_ref_mv, x->errorperbit, v_fn_ptr.svf, v_fn_ptr.vf, mvcost);
+                    }
+                }
+
+                rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode], best_ref_mv, mvcost);
+
+                // Trap vectors that reach beyond the UMV borders
+                if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) ||
+                    ((mode_mv[this_mode].col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].col >> 3) > x->mv_col_max))
+                {
+                    continue;
+                }
+
+                distortion = vp8_encode_inter_mb_segment(x, labels, i, IF_RTCD(&cpi->rtcd.encodemb)) / 4;
+
+                labelyrate = rdcost_mbsegment_y(x, labels, i, &ts);
+                rate += labelyrate;
+
+                this_rd = RDFUNC(x->rdmult, x->rddiv, rate, distortion, cpi->target_bits_per_mb);
+
+                if (this_rd < best_label_rd)
+                {
+                    sbr = rate;
+                    sbd = distortion;
+                    bestlabelyrate = labelyrate;
+                    mode_selected = this_mode;
+                    best_label_rd = this_rd;
+                    vp8_setup_temp_context(&tb, &ts.a[0], &ts.l[0], 4);
+
+                }
+            }
+
+            vp8_setup_temp_context(&t, &tb.a[0], &tb.l[0], 4);
+
+            labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected], best_ref_mv, mvcost);
+
+            br += sbr;
+            bd += sbd;
+            segmentyrate += bestlabelyrate;
+            this_segment_rd += best_label_rd;
+
+            if ((this_segment_rd > best_rd) || (this_segment_rd > best_segment_rd))
+                break;
+        }
+
+        if ((this_segment_rd <= best_rd) && (this_segment_rd < best_segment_rd))
+        {
+            bsr = br;
+            bsd = bd;
+            bestsegmentyrate = segmentyrate;
+            best_segment_rd = this_segment_rd;
+            best_seg = segmentation;
+
+            // store everything needed to come back to this!!
+            for (i = 0; i < 16; i++)
+            {
+                BLOCKD *bd = &x->e_mbd.block[i];
+
+                bmvs[i] = bd->bmi.mv.as_mv;
+                bmodes[i] = bd->bmi.mode;
+                beobs[i] = bd->eob;
+            }
+        }
+    }
+
+    // set it to the best
+    for (i = 0; i < 16; i++)
+    {
+        BLOCKD *bd = &x->e_mbd.block[i];
+
+        bd->bmi.mv.as_mv = bmvs[i];
+        bd->bmi.mode = bmodes[i];
+        bd->eob = beobs[i];
+    }
+
+    // Trap cases where the best split mode has all vectors coded 0,0 (or all the same)
+    if (FALSE)
+    {
+        int allsame = 1;
+
+        for (i = 1; i < 16; i++)
+        {
+            if ((bmvs[i].col != bmvs[i-1].col) || (bmvs[i].row != bmvs[i-1].row))
+            {
+                allsame = 0;
+                break;
+            }
+        }
+
+        if (allsame)
+        {
+            best_segment_rd = INT_MAX;
+        }
+    }
+
+    *returntotrate = bsr;
+    *returndistortion = bsd;
+    *returnyrate = bestsegmentyrate;
+
+
+
+    // save partitions
+    labels = vp8_mbsplits[best_seg];
+    x->e_mbd.mbmi.partitioning = best_seg;
+    x->e_mbd.mbmi.partition_count = vp8_count_labels(labels);
+
+    for (i = 0; i < x->e_mbd.mbmi.partition_count; i++)
+    {
+        int j;
+
+        for (j = 0; j < 16; j++)
+        {
+            if (labels[j] == i)
+                break;
+        }
+
+        x->e_mbd.mbmi.partition_bmi[i].mode = x->e_mbd.block[j].bmi.mode;
+        x->e_mbd.mbmi.partition_bmi[i].mv.as_mv = x->e_mbd.block[j].bmi.mv.as_mv;
+    }
+
+    return best_segment_rd;
+}
+
+
+int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra)
+{
+    BLOCK *b = &x->block[0];
+    BLOCKD *d = &x->e_mbd.block[0];
+    MACROBLOCKD *xd = &x->e_mbd;
+    B_MODE_INFO best_bmodes[16];
+    MB_MODE_INFO best_mbmode;
+    MV best_ref_mv;
+    MV mode_mv[MB_MODE_COUNT];
+    MB_PREDICTION_MODE this_mode;
+    int num00;
+    int best_mode_index = 0;
+
+    int i;
+    int mode_index;
+    int mdcounts[4];
+    int rate;
+    int distortion;
+    int best_rd = INT_MAX; // 1 << 30;
+    int ref_frame_cost[MAX_REF_FRAMES];
+    int rate2, distortion2;
+    int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly;
+    int rate_y, UNINITIALIZED_IS_SAFE(rate_uv);
+
+    //int all_rds[MAX_MODES];        // Experimental debug code.
+    //int all_rates[MAX_MODES];
+    //int all_dist[MAX_MODES];
+    //int intermodecost[MAX_MODES];
+
+    MB_PREDICTION_MODE uv_intra_mode;
+    int sse;
+    int sum;
+    int uvintra_eob = 0;
+    int tteob = 0;
+    int force_no_skip = 0;
+
+    *returnintra = INT_MAX;
+
+    cpi->mbs_tested_so_far++;          // Count of the number of MBs tested so far this frame
+
+    x->skip = 0;
+
+    ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(cpi->prob_intra_coded);
+
+    // Experimental code
+    // Adjust the RD multiplier based on the best case distortion we saw in the most recently coded mb
+    //if ( (cpi->last_mb_distortion) > 0 && (cpi->target_bits_per_mb > 0) )
+    /*{
+        int tmprdmult;
+
+        //tmprdmult = (cpi->last_mb_distortion * 256) / ((cpi->av_per_frame_bandwidth*256)/cpi->common.MBs);
+        tmprdmult = (cpi->last_mb_distortion * 256) / cpi->target_bits_per_mb;
+        //tmprdmult = tmprdmult;
+
+        //if ( tmprdmult > cpi->RDMULT * 2 )
+        //  tmprdmult = cpi->RDMULT * 2;
+        //else if ( tmprdmult < cpi->RDMULT / 2 )
+        //  tmprdmult = cpi->RDMULT / 2;
+
+        //tmprdmult = (tmprdmult < 25) ? 25 : tmprdmult;
+
+        //x->rdmult = tmprdmult;
+
+    }*/
+
+    // Special case treatment when GF and ARF are not sensible options for reference
+    if (cpi->ref_frame_flags == VP8_LAST_FLAG)
+    {
+        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_zero(255);
+        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(255)
+                                        + vp8_cost_zero(128);
+        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(255)
+                                        + vp8_cost_one(128);
+    }
+    else
+    {
+        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_zero(cpi->prob_last_coded);
+        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(cpi->prob_last_coded)
+                                        + vp8_cost_zero(cpi->prob_gf_coded);
+        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
+                                        + vp8_cost_one(cpi->prob_last_coded)
+                                        + vp8_cost_one(cpi->prob_gf_coded);
+    }
+
+    vpx_memset(mode_mv, 0, sizeof(mode_mv));
+
+    x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
+    vp8_rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion);
+    uv_intra_mode = x->e_mbd.mbmi.uv_mode;
+    {
+        uvintra_eob = 0;
+
+        for (i = 16; i < 24; i++)
+            uvintra_eob += x->e_mbd.block[i].eob;
+    }
+
+    for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
+    {
+        int frame_cost;
+        int this_rd = INT_MAX;
+        int lf_or_gf = 0;           // Lat Frame (01) or gf/arf (1)
+        int disable_skip = 0;
+
+        force_no_skip = 0;
+
+        // Experimental debug code.
+        // Record of rd values recorded for this MB. -1 indicates not measured
+        //all_rds[mode_index] = -1;
+        //all_rates[mode_index] = -1;
+        //all_dist[mode_index] = -1;
+        //intermodecost[mode_index] = -1;  
+
+        // Test best rd so far against threshold for trying this mode.
+        if (best_rd <= cpi->rd_threshes[mode_index])
+            continue;
+
+
+
+        // These variables hold are rolling total cost and distortion for this mode
+        rate2 = 0;
+        distortion2 = 0;
+
+        // Where skip is allowable add in the default per mb cost for the no skip case.
+        // where we then decide to skip we have to delete this and replace it with the
+        // cost of signallying a skip
+        if (cpi->common.mb_no_coeff_skip)
+        {
+            rate2 += vp8_cost_bit(cpi->prob_skip_false, 0);
+        }
+
+        this_mode = vp8_mode_order[mode_index];
+
+        x->e_mbd.mbmi.mode = this_mode;
+        x->e_mbd.mbmi.uv_mode = DC_PRED;
+        x->e_mbd.mbmi.ref_frame = vp8_ref_frame_order[mode_index];
+
+        //Only consider ZEROMV/ALTREF_FRAME for alt ref frame.
+        if (cpi->is_src_frame_alt_ref)
+        {
+            if (this_mode != ZEROMV || x->e_mbd.mbmi.ref_frame != ALTREF_FRAME)
+                continue;
+        }
+
+        if (x->e_mbd.mbmi.ref_frame == LAST_FRAME)
+        {
+            if (!(cpi->ref_frame_flags & VP8_LAST_FLAG))
+                continue;
+
+            lf_or_gf = 0;  // Local last frame vs Golden frame flag
+
+            // Set up pointers for this macro block into the previous frame recon buffer
+            x->e_mbd.pre.y_buffer = cpi->common.last_frame.y_buffer + recon_yoffset;
+            x->e_mbd.pre.u_buffer = cpi->common.last_frame.u_buffer + recon_uvoffset;
+            x->e_mbd.pre.v_buffer = cpi->common.last_frame.v_buffer + recon_uvoffset;
+        }
+        else if (x->e_mbd.mbmi.ref_frame == GOLDEN_FRAME)
+        {
+
+            // not supposed to reference gold frame
+            if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG))
+                continue;
+
+            lf_or_gf = 1;  // Local last frame vs Golden frame flag
+
+            // Set up pointers for this macro block into the previous frame recon buffer
+            x->e_mbd.pre.y_buffer = cpi->common.golden_frame.y_buffer + recon_yoffset;
+            x->e_mbd.pre.u_buffer = cpi->common.golden_frame.u_buffer + recon_uvoffset;
+            x->e_mbd.pre.v_buffer = cpi->common.golden_frame.v_buffer + recon_uvoffset;
+        }
+        else if (x->e_mbd.mbmi.ref_frame == ALTREF_FRAME)
+        {
+            // not supposed to reference alt ref frame
+            if (!(cpi->ref_frame_flags & VP8_ALT_FLAG))
+                continue;
+
+            //if ( !cpi->source_alt_ref_active )
+            //  continue;
+
+            lf_or_gf = 1;  // Local last frame vs Golden frame flag
+
+            // Set up pointers for this macro block into the previous frame recon buffer
+            x->e_mbd.pre.y_buffer = cpi->common.alt_ref_frame.y_buffer + recon_yoffset;
+            x->e_mbd.pre.u_buffer = cpi->common.alt_ref_frame.u_buffer + recon_uvoffset;
+            x->e_mbd.pre.v_buffer = cpi->common.alt_ref_frame.v_buffer + recon_uvoffset;
+        }
+
+        vp8_find_near_mvs(&x->e_mbd,
+                          x->e_mbd.mode_info_context,
+                          &mode_mv[NEARESTMV], &mode_mv[NEARMV], &best_ref_mv,
+                          mdcounts, x->e_mbd.mbmi.ref_frame, cpi->common.ref_frame_sign_bias);
+
+
+        // Estimate the reference frame signaling cost and add it to the rolling cost variable.
+        frame_cost = ref_frame_cost[x->e_mbd.mbmi.ref_frame];
+        rate2 += frame_cost;
+
+        if (this_mode <= B_PRED)
+        {
+            for (i = 0; i < 16; i++)
+            {
+                vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
+            }
+        }
+
+        // Check to see if the testing frequency for this mode is at its max
+        // If so then prevent it from being tested and increase the threshold for its testing
+        if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
+        {
+            if (cpi->mbs_tested_so_far  <= cpi->mode_check_freq[mode_index] * cpi->mode_test_hit_counts[mode_index])
+            {
+                // Increase the threshold for coding this mode to make it less likely to be chosen
+                cpi->rd_thresh_mult[mode_index] += 4;
+
+                if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
+                    cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
+
+                cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+
+                continue;
+            }
+        }
+
+        // We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
+        cpi->mode_test_hit_counts[mode_index] ++;
+
+        // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
+        if (cpi->zbin_mode_boost_enabled)
+        {
+            if ((vp8_mode_order[mode_index] == ZEROMV) && (vp8_ref_frame_order[mode_index] != LAST_FRAME))
+                cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
+            else
+                cpi->zbin_mode_boost = 0;
+
+            vp8cx_mb_init_quantizer(cpi, x);
+        }
+
+        switch (this_mode)
+        {
+        case B_PRED:
+
+            // Note the rate value returned here includes the cost of coding the BPRED mode : x->mbmode_cost[x->e_mbd.frame_type][BPRED];
+            vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y, &distortion);
+            rate2 += rate;
+            //rate_y = rate;
+            distortion2 += distortion;
+            rate2 += uv_intra_rate;
+            rate_uv = uv_intra_rate_tokenonly;
+            distortion2 += uv_intra_distortion;
+            break;
+
+        case SPLITMV:
+        {
+            int frame_cost_rd = RDFUNC(x->rdmult, x->rddiv, frame_cost, 0, cpi->target_bits_per_mb);
+            int saved_rate = rate2;
+
+            // vp8_rd_pick_best_mbsegmentation looks only at Y and does not account for frame_cost.
+            // (best_rd - frame_cost_rd) is thus a conservative breakout number.
+            int breakout_rd = best_rd - frame_cost_rd;
+            int tmp_rd;
+
+            if (x->e_mbd.mbmi.ref_frame == LAST_FRAME)
+                tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWMV], cpi->common.full_pixel) ;
+            else if (x->e_mbd.mbmi.ref_frame == GOLDEN_FRAME)
+                tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWG], cpi->common.full_pixel) ;
+            else
+                tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWA], cpi->common.full_pixel) ;
+
+            rate2 += rate;
+            distortion2 += distortion;
+
+            // If even the 'Y' rd value of split is higher than best so far then dont bother looking at UV
+            if (tmp_rd < breakout_rd)
+            {
+                // Now work out UV cost and add it in
+                vp8_rd_inter_uv(cpi, x, &rate, &distortion, cpi->common.full_pixel);
+                rate2 += rate;
+                rate_uv = rate;
+                distortion2 += distortion;
+
+            }
+            else
+            {
+                this_rd = INT_MAX;
+                disable_skip = 1;
+            }
+
+            // Trap cases where the best split mode has all vectors coded 0,0 (or all the same)
+            if (0)
+            {
+                int allsame = 1;
+
+                for (i = 1; i < 16; i++)
+                {
+                    BLOCKD *bd = &x->e_mbd.block[i];
+
+                    if (bd->bmi.mv.as_int != x->e_mbd.block[0].bmi.mv.as_int)   //(bmvs[i].col != bmvs[i-1].col) || (bmvs[i].row != bmvs[i-1].row ) )
+                    {
+                        allsame = 0;
+                        break;
+                    }
+                }
+
+                if (allsame)
+                {
+                    // reset mode and mv and jump to newmv
+                    this_mode = NEWMV;
+                    distortion2 = 0;
+                    rate2 = saved_rate;
+                    mode_mv[NEWMV].row = x->e_mbd.block[0].bmi.mv.as_mv.row;
+                    mode_mv[NEWMV].col = x->e_mbd.block[0].bmi.mv.as_mv.col;
+                    rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96);
+                    goto mv_selected;
+                }
+            }
+
+            // trap cases where the 8x8s can be promoted to 8x16s or 16x8s
+            if (0)//x->e_mbd.mbmi.partition_count == 4)
+            {
+
+                if (x->e_mbd.mbmi.partition_bmi[0].mv.as_int == x->e_mbd.mbmi.partition_bmi[1].mv.as_int
+                    && x->e_mbd.mbmi.partition_bmi[2].mv.as_int == x->e_mbd.mbmi.partition_bmi[3].mv.as_int)
+                {
+                    const int *labels = vp8_mbsplits[2];
+                    x->e_mbd.mbmi.partitioning = 0;
+                    rate -= vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + 2);
+                    rate += vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings);
+                    //rate -=  x->inter_bmode_costs[  x->e_mbd.mbmi.partition_bmi[1]];
+                    //rate -=  x->inter_bmode_costs[  x->e_mbd.mbmi.partition_bmi[3]];
+                    x->e_mbd.mbmi.partition_bmi[1] = x->e_mbd.mbmi.partition_bmi[2];
+                }
+            }
+
+        }
+        break;
+        case DC_PRED:
+        case V_PRED:
+        case H_PRED:
+        case TM_PRED:
+            x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
+            vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
+            {
+                macro_block_yrd(x, &rate, &distortion, IF_RTCD(&cpi->rtcd.encodemb)) ;
+                rate2 += rate;
+                rate_y = rate;
+                distortion2 += distortion;
+                rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.mode];
+                rate2 += uv_intra_rate;
+                rate_uv = uv_intra_rate_tokenonly;
+                distortion2 += uv_intra_distortion;
+            }
+            break;
+
+        case NEWMV:
+
+            // Decrement full search counter
+            if (cpi->check_freq[lf_or_gf] > 0)
+                cpi->check_freq[lf_or_gf] --;
+
+            {
+                int thissme;
+                int bestsme = INT_MAX;
+                int step_param = cpi->sf.first_step;
+                int search_range;
+                int further_steps;
+                int n;
+
+                // Work out how long a search we should do
+                search_range = MAXF(abs(best_ref_mv.col), abs(best_ref_mv.row)) >> 3;
+
+                if (search_range >= x->vector_range)
+                    x->vector_range = search_range;
+                else if (x->vector_range > cpi->sf.min_fs_radius)
+                    x->vector_range--;
+
+                // Initial step/diamond search
+                {
+                    int sadpb = x->sadperbit16;
+
+                    if (cpi->sf.search_method == HEX)
+                    {
+                        bestsme = vp8_hex_search(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param, sadpb/*x->errorperbit*/, &num00, cpi->fn_ptr.vf, cpi->fn_ptr.sdf, x->mvsadcost, x->mvcost);
+                        mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                        mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+                    }
+                    else
+                    {
+                        bestsme = cpi->diamond_search_sad(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param, sadpb / 2/*x->errorperbit*/, &num00, &cpi->fn_ptr, x->mvsadcost, x->mvcost); //sadpb < 9
+                        mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                        mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+
+                        // Further step/diamond searches as necessary
+                        n = 0;
+                        further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+
+                        n = num00;
+                        num00 = 0;
+
+                        while (n < further_steps)
+                        {
+                            n++;
+
+                            if (num00)
+                                num00--;
+                            else
+                            {
+                                thissme = cpi->diamond_search_sad(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param + n, sadpb / 4/*x->errorperbit*/, &num00, &cpi->fn_ptr, x->mvsadcost, x->mvcost); //sadpb = 9
+
+                                if (thissme < bestsme)
+                                {
+                                    bestsme = thissme;
+                                    mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                                    mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+                                }
+                                else
+                                {
+                                    d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
+                                    d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+                                }
+                            }
+                        }
+                    }
+
+                }
+
+                // Should we do a full search
+                if (!cpi->check_freq[lf_or_gf] || cpi->do_full[lf_or_gf])
+                {
+                    int thissme;
+                    int full_flag_thresh = 0;
+
+                    // Update x->vector_range based on best vector found in step search
+                    search_range = MAXF(abs(d->bmi.mv.as_mv.row), abs(d->bmi.mv.as_mv.col));
+
+                    if (search_range > x->vector_range)
+                        x->vector_range = search_range;
+                    else
+                        search_range = x->vector_range;
+
+                    // Apply limits
+                    search_range = (search_range > cpi->sf.max_fs_radius) ? cpi->sf.max_fs_radius : search_range;
+                    {
+                        int sadpb = x->sadperbit16 >> 2;
+                        thissme = cpi->full_search_sad(x, b, d, &best_ref_mv, sadpb, search_range, &cpi->fn_ptr, x->mvcost, x->mvsadcost);
+                    }
+
+                    // Barrier threshold to initiating full search
+                    // full_flag_thresh = 10 + (thissme >> 7);
+                    if ((thissme + full_flag_thresh) < bestsme)
+                    {
+                        cpi->do_full[lf_or_gf] ++;
+                        bestsme = thissme;
+                    }
+                    else if (thissme < bestsme)
+                        bestsme = thissme;
+                    else
+                    {
+                        cpi->do_full[lf_or_gf] = cpi->do_full[lf_or_gf] >> 1;
+                        cpi->check_freq[lf_or_gf] = cpi->sf.full_freq[lf_or_gf];
+
+                        // The full search result is actually worse so re-instate the previous best vector
+                        d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
+                        d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+                    }
+                }
+
+                if (bestsme < INT_MAX)
+                    // cpi->find_fractional_mv_step(x,b,d,&d->bmi.mv.as_mv,&best_ref_mv,x->errorperbit/2,cpi->fn_ptr.svf,cpi->fn_ptr.vf,x->mvcost);  // normal mvc=11
+                    cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv, x->errorperbit / 4, cpi->fn_ptr.svf, cpi->fn_ptr.vf, x->mvcost);
+
+                mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+                mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+
+                // Add the new motion vector cost to our rolling cost variable
+                rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96);
+
+            }
+
+        case NEARESTMV:
+        case NEARMV:
+
+            // Clip "next_nearest" so that it does not extend to far out of image
+            if (mode_mv[this_mode].col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
+                mode_mv[this_mode].col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
+            else if (mode_mv[this_mode].col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
+                mode_mv[this_mode].col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
+
+            if (mode_mv[this_mode].row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
+                mode_mv[this_mode].row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
+            else if (mode_mv[this_mode].row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
+                mode_mv[this_mode].row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
+
+            // Do not bother proceeding if the vector (from newmv,nearest or near) is 0,0 as this should then be coded using the zeromv mode.
+            if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) &&
+                ((mode_mv[this_mode].row == 0) && (mode_mv[this_mode].col == 0)))
+                continue;
+
+        case ZEROMV:
+
+        mv_selected:
+
+            // Trap vectors that reach beyond the UMV borders
+            // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
+            // because of the lack of break statements in the previous two cases.
+            if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) ||
+                ((mode_mv[this_mode].col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].col >> 3) > x->mv_col_max))
+                continue;
+
+            vp8_set_mbmode_and_mvs(x, this_mode, &mode_mv[this_mode]);
+            vp8_build_inter_predictors_mby(&x->e_mbd);
+            VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16var)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, (unsigned int *)(&sse), &sum);
+
+            if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+            {
+                x->skip = 1;
+            }
+            else if (sse < x->encode_breakout)
+            {
+                // Check u and v to make sure skip is ok
+                int sse2 = 0;
+
+                sse2 = VP8_UVSSE(x, IF_RTCD(&cpi->rtcd.variance));
+
+                if (sse2 * 2 < x->encode_breakout)
+                {
+                    x->skip = 1;
+                    distortion2 = sse;
+                    rate2 = 500;
+
+                    disable_skip = 1;    // We have no real rate data so trying to adjust for rate_y and rate_uv below will cause problems.
+                    this_rd = RDFUNC(x->rdmult, x->rddiv, rate2, distortion2, cpi->target_bits_per_mb);
+
+                    break;              // (PGW) Move break here from below - for now at least
+                }
+                else
+                    x->skip = 0;
+            }
+
+            //intermodecost[mode_index] = vp8_cost_mv_ref(this_mode, mdcounts);   // Experimental debug code
+
+            // Add in the Mv/mode cost
+            rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
+
+            // Y cost and distortion
+            macro_block_yrd(x, &rate, &distortion, IF_RTCD(&cpi->rtcd.encodemb));
+            rate2 += rate;
+            rate_y = rate;
+            distortion2 += distortion;
+
+            // UV cost and distortion
+            vp8_rd_inter_uv(cpi, x, &rate, &distortion, cpi->common.full_pixel);
+            rate2 += rate;
+            rate_uv = rate;
+            distortion2 += distortion;
+            break;
+
+        default:
+            break;
+        }
+
+        if (!disable_skip)
+        {
+            // Test for the condition where skip block will be activated because there are no non zero coefficients and make any necessary adjustment for rate
+            if (cpi->common.mb_no_coeff_skip)
+            {
+                tteob = 0;
+
+                for (i = 0; i <= 24; i++)
+                {
+                    tteob += x->e_mbd.block[i].eob;
+                }
+
+                if (tteob == 0)
+                {
+#if 1
+                    rate2 -= (rate_y + rate_uv);
+
+                    // Back out no skip flag costing and add in skip flag costing
+                    if (cpi->prob_skip_false)
+                    {
+                        rate2 += vp8_cost_bit(cpi->prob_skip_false, 1);
+                        rate2 -= vp8_cost_bit(cpi->prob_skip_false, 0);
+                    }
+
+#else
+                    int rateuseskip;
+                    int ratenotuseskip;
+
+
+
+                    ratenotuseskip = rate_y + rate_uv + vp8_cost_bit(cpi->prob_skip_false, 0);
+                    rateuseskip    = vp8_cost_bit(cpi->prob_skip_false, 1);
+
+                    if (1) // rateuseskip<ratenotuseskip)
+                    {
+                        rate2 -= ratenotuseskip;
+                        rate2 += rateuseskip;
+                        force_no_skip = 0;
+                    }
+                    else
+                    {
+                        force_no_skip = 1;
+                    }
+
+#endif
+                }
+
+#if             0
+                else
+                {
+                    int rateuseskip;
+                    int ratenotuseskip;
+                    int maxdistortion;
+                    int minrate;
+                    int skip_rd;
+
+                    // distortion when no coeff is encoded
+                    maxdistortion = macro_block_max_error(x);
+
+                    ratenotuseskip = rate_y + rate_uv + vp8_cost_bit(cpi->prob_skip_false, 0);
+                    rateuseskip    = vp8_cost_bit(cpi->prob_skip_false, 1);
+
+                    minrate         = rateuseskip - ratenotuseskip;
+
+                    skip_rd = RDFUNC(x->rdmult, x->rddiv, minrate, maxdistortion - distortion2, cpi->target_bits_per_mb);
+
+                    if (skip_rd + 50 < 0 && x->e_mbd.mbmi.ref_frame != INTRA_FRAME && rate_y + rate_uv < 4000)
+                    {
+                        force_no_skip = 1;
+                        rate2       = rate2 + rateuseskip - ratenotuseskip;
+                        distortion2 =  maxdistortion;
+                    }
+                    else
+                    {
+                        force_no_skip = 0;
+                    }
+
+                }
+
+#endif
+
+            }
+
+            // Calculate the final RD estimate for this mode
+            this_rd = RDFUNC(x->rdmult, x->rddiv, rate2, distortion2, cpi->target_bits_per_mb);
+        }
+
+        // Experimental debug code.
+        //all_rds[mode_index] = this_rd;
+        //all_rates[mode_index] = rate2;
+        //all_dist[mode_index] = distortion2;
+
+        if ((x->e_mbd.mbmi.ref_frame == INTRA_FRAME)  && (this_rd < *returnintra))
+        {
+            *returnintra = this_rd ;
+        }
+
+        // Did this mode help.. i.i is it the new best mode
+        if (this_rd < best_rd || x->skip)
+        {
+            // Note index of best mode so far
+            best_mode_index = mode_index;
+            x->e_mbd.mbmi.force_no_skip = force_no_skip;
+
+            if (this_mode <= B_PRED)
+            {
+                x->e_mbd.mbmi.uv_mode = uv_intra_mode;
+            }
+
+            *returnrate = rate2;
+            *returndistortion = distortion2;
+            best_rd = this_rd;
+            vpx_memcpy(&best_mbmode, &x->e_mbd.mbmi, sizeof(MB_MODE_INFO));
+
+            for (i = 0; i < 16; i++)
+            {
+                vpx_memcpy(&best_bmodes[i], &x->e_mbd.block[i].bmi, sizeof(B_MODE_INFO));
+            }
+
+            // Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
+            cpi->rd_thresh_mult[mode_index] = (cpi->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) ? cpi->rd_thresh_mult[mode_index] - 2 : MIN_THRESHMULT;
+            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+        }
+
+        // If the mode did not help improve the best error case then raise the threshold for testing that mode next time around.
+        else
+        {
+            cpi->rd_thresh_mult[mode_index] += 4;
+
+            if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
+                cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
+
+            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
+        }
+
+        if (x->skip)
+            break;
+    }
+
+    // Reduce the activation RD thresholds for the best choice mode
+    if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2)))
+    {
+        int best_adjustment = (cpi->rd_thresh_mult[best_mode_index] >> 2);
+
+        cpi->rd_thresh_mult[best_mode_index] = (cpi->rd_thresh_mult[best_mode_index] >= (MIN_THRESHMULT + best_adjustment)) ? cpi->rd_thresh_mult[best_mode_index] - best_adjustment : MIN_THRESHMULT;
+        cpi->rd_threshes[best_mode_index] = (cpi->rd_baseline_thresh[best_mode_index] >> 7) * cpi->rd_thresh_mult[best_mode_index];
+
+        // If we chose a split mode then reset the new MV thresholds as well
+        /*if ( vp8_mode_order[best_mode_index] == SPLITMV )
+        {
+            best_adjustment = 4; //(cpi->rd_thresh_mult[THR_NEWMV] >> 4);
+            cpi->rd_thresh_mult[THR_NEWMV] = (cpi->rd_thresh_mult[THR_NEWMV] >= (MIN_THRESHMULT+best_adjustment)) ? cpi->rd_thresh_mult[THR_NEWMV]-best_adjustment: MIN_THRESHMULT;
+            cpi->rd_threshes[THR_NEWMV] = (cpi->rd_baseline_thresh[THR_NEWMV] >> 7) * cpi->rd_thresh_mult[THR_NEWMV];
+
+            best_adjustment = 4; //(cpi->rd_thresh_mult[THR_NEWG] >> 4);
+            cpi->rd_thresh_mult[THR_NEWG] = (cpi->rd_thresh_mult[THR_NEWG] >= (MIN_THRESHMULT+best_adjustment)) ? cpi->rd_thresh_mult[THR_NEWG]-best_adjustment: MIN_THRESHMULT;
+            cpi->rd_threshes[THR_NEWG] = (cpi->rd_baseline_thresh[THR_NEWG] >> 7) * cpi->rd_thresh_mult[THR_NEWG];
+
+            best_adjustment = 4; //(cpi->rd_thresh_mult[THR_NEWA] >> 4);
+            cpi->rd_thresh_mult[THR_NEWA] = (cpi->rd_thresh_mult[THR_NEWA] >= (MIN_THRESHMULT+best_adjustment)) ? cpi->rd_thresh_mult[THR_NEWA]-best_adjustment: MIN_THRESHMULT;
+            cpi->rd_threshes[THR_NEWA] = (cpi->rd_baseline_thresh[THR_NEWA] >> 7) * cpi->rd_thresh_mult[THR_NEWA];
+        }*/
+
+    }
+
+    // If we have chosen new mv or split then decay the full search check count more quickly.
+    if ((vp8_mode_order[best_mode_index] == NEWMV) || (vp8_mode_order[best_mode_index] == SPLITMV))
+    {
+        int lf_or_gf = (vp8_ref_frame_order[best_mode_index] == LAST_FRAME) ? 0 : 1;
+
+        if (cpi->check_freq[lf_or_gf] && !cpi->do_full[lf_or_gf])
+        {
+            cpi->check_freq[lf_or_gf] --;
+        }
+    }
+
+    // Keep a record of best mode index that we chose
+    cpi->last_best_mode_index = best_mode_index;
+
+    // Note how often each mode chosen as best
+    cpi->mode_chosen_counts[best_mode_index] ++;
+
+
+    if (cpi->is_src_frame_alt_ref && (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME))
+    {
+        best_mbmode.mode = ZEROMV;
+        best_mbmode.ref_frame = ALTREF_FRAME;
+        best_mbmode.mv.as_int = 0;
+        best_mbmode.uv_mode = 0;
+        best_mbmode.mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+        best_mbmode.partitioning = 0;
+        best_mbmode.dc_diff = 0;
+
+        vpx_memcpy(&x->e_mbd.mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
+
+        for (i = 0; i < 16; i++)
+        {
+            vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
+        }
+
+        x->e_mbd.mbmi.mv.as_int = 0;
+
+        return best_rd;
+    }
+
+
+    // macroblock modes
+    vpx_memcpy(&x->e_mbd.mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
+
+    for (i = 0; i < 16; i++)
+    {
+        vpx_memcpy(&x->e_mbd.block[i].bmi, &best_bmodes[i], sizeof(B_MODE_INFO));
+    }
+
+    x->e_mbd.mbmi.mv.as_mv = x->e_mbd.block[15].bmi.mv.as_mv;
+
+    return best_rd;
+}
+#endif
+
diff --git a/vp8/encoder/rdopt.h b/vp8/encoder/rdopt.h
new file mode 100644 (file)
index 0000000..c6eae4b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_RDOPT_H
+#define __INC_RDOPT_H
+void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue);
+int vp8_rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *rate, int *rate_to, int *distortion);
+int vp8_rd_pick_intra16x16mby_mode(VP8_COMP *cpi, MACROBLOCK *x, int *returnrate, int *rate_to, int *returndistortion);
+int vp8_rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *rate_to, int *distortion);
+extern int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra);
+
+
+#endif
diff --git a/vp8/encoder/sad_c.c b/vp8/encoder/sad_c.c
new file mode 100644 (file)
index 0000000..74c6bd7
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+
+unsigned int vp8_sad16x16_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    int max_sad)
+{
+
+    int r, c;
+    unsigned int sad = 0;
+
+    for (r = 0; r < 16; r++)
+    {
+        for (c = 0; c < 16; c++)
+        {
+            sad += abs(src_ptr[c] - ref_ptr[c]);
+        }
+
+        src_ptr += src_stride;
+        ref_ptr += ref_stride;
+    }
+
+    return sad;
+}
+
+
+static __inline
+unsigned int sad_mx_n_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    int m,
+    int n)
+{
+
+    int r, c;
+    unsigned int sad = 0;
+
+    for (r = 0; r < n; r++)
+    {
+        for (c = 0; c < m; c++)
+        {
+            sad += abs(src_ptr[c] - ref_ptr[c]);
+        }
+
+        src_ptr += src_stride;
+        ref_ptr += ref_stride;
+    }
+
+    return sad;
+}
+
+
+unsigned int vp8_sad8x8_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    int max_sad)
+{
+
+    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 8, 8);
+}
+
+
+unsigned int vp8_sad16x8_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    int max_sad)
+{
+
+    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 16, 8);
+
+}
+
+
+unsigned int vp8_sad8x16_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    int max_sad)
+{
+
+    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 8, 16);
+}
+
+
+unsigned int vp8_sad4x4_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    int max_sad)
+{
+
+    return sad_mx_n_c(src_ptr, src_stride, ref_ptr, ref_stride, 4, 4);
+}
+
+void vp8_sad16x16x3_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr  , ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, 0x7fffffff);
+}
+
+void vp8_sad16x8x3_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr  , ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, 0x7fffffff);
+}
+
+void vp8_sad8x8x3_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr  , ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, 0x7fffffff);
+}
+
+void vp8_sad8x16x3_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr  , ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, 0x7fffffff);
+}
+
+void vp8_sad4x4x3_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr,
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr  , ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 1, ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr + 2, ref_stride, 0x7fffffff);
+}
+
+void vp8_sad16x16x4d_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr[],
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[0], ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[1], ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[2], ref_stride, 0x7fffffff);
+    sad_array[3] = vp8_sad16x16_c(src_ptr, src_stride, ref_ptr[3], ref_stride, 0x7fffffff);
+}
+
+void vp8_sad16x8x4d_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr[],
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[0], ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[1], ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[2], ref_stride, 0x7fffffff);
+    sad_array[3] = vp8_sad16x8_c(src_ptr, src_stride, ref_ptr[3], ref_stride, 0x7fffffff);
+}
+
+void vp8_sad8x8x4d_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr[],
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[0], ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[1], ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[2], ref_stride, 0x7fffffff);
+    sad_array[3] = vp8_sad8x8_c(src_ptr, src_stride, ref_ptr[3], ref_stride, 0x7fffffff);
+}
+
+void vp8_sad8x16x4d_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr[],
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[0], ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[1], ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[2], ref_stride, 0x7fffffff);
+    sad_array[3] = vp8_sad8x16_c(src_ptr, src_stride, ref_ptr[3], ref_stride, 0x7fffffff);
+}
+
+void vp8_sad4x4x4d_c(
+    unsigned char *src_ptr,
+    int  src_stride,
+    unsigned char *ref_ptr[],
+    int  ref_stride,
+    unsigned int *sad_array
+)
+{
+    sad_array[0] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[0], ref_stride, 0x7fffffff);
+    sad_array[1] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[1], ref_stride, 0x7fffffff);
+    sad_array[2] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[2], ref_stride, 0x7fffffff);
+    sad_array[3] = vp8_sad4x4_c(src_ptr, src_stride, ref_ptr[3], ref_stride, 0x7fffffff);
+}
diff --git a/vp8/encoder/ssim.c b/vp8/encoder/ssim.c
new file mode 100644 (file)
index 0000000..df214a8
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/yv12config.h"
+#include "math.h"
+
+#define C1 (float)(64 * 64 * 0.01*255*0.01*255)
+#define C2 (float)(64 * 64 * 0.03*255*0.03*255)
+
+static int width_y;
+static int height_y;
+static int height_uv;
+static int width_uv;
+static int stride_uv;
+static int stride;
+static int lumimask;
+static int luminance;
+static double plane_summed_weights = 0;
+
+static short img12_sum_block[8*4096*4096*2] ;
+
+static short img1_sum[8*4096*2];
+static short img2_sum[8*4096*2];
+static int   img1_sq_sum[8*4096*2];
+static int   img2_sq_sum[8*4096*2];
+static int   img12_mul_sum[8*4096*2];
+
+
+double vp8_similarity
+(
+    int mu_x,
+    int mu_y,
+    int pre_mu_x2,
+    int pre_mu_y2,
+    int pre_mu_xy2
+)
+{
+    int mu_x2, mu_y2, mu_xy, theta_x2, theta_y2, theta_xy;
+
+    mu_x2 = mu_x * mu_x;
+    mu_y2 = mu_y * mu_y;
+    mu_xy = mu_x * mu_y;
+
+    theta_x2 = 64 * pre_mu_x2 - mu_x2;
+    theta_y2 = 64 * pre_mu_y2 - mu_y2;
+    theta_xy = 64 * pre_mu_xy2 - mu_xy;
+
+    return (2 * mu_xy + C1) * (2 * theta_xy + C2) / ((mu_x2 + mu_y2 + C1) * (theta_x2 + theta_y2 + C2));
+}
+
+double vp8_ssim
+(
+    const unsigned char *img1,
+    const unsigned char *img2,
+    int stride_img1,
+    int stride_img2,
+    int width,
+    int height
+)
+{
+    int x, y, x2, y2, img1_block, img2_block, img1_sq_block, img2_sq_block, img12_mul_block, temp;
+
+    double plane_quality, weight, mean;
+
+    short *img1_sum_ptr1, *img1_sum_ptr2;
+    short *img2_sum_ptr1, *img2_sum_ptr2;
+    int *img1_sq_sum_ptr1, *img1_sq_sum_ptr2;
+    int *img2_sq_sum_ptr1, *img2_sq_sum_ptr2;
+    int *img12_mul_sum_ptr1, *img12_mul_sum_ptr2;
+
+    plane_quality = 0;
+
+    if (lumimask)
+        plane_summed_weights = 0.0f;
+    else
+        plane_summed_weights = (height - 7) * (width - 7);
+
+    //some prologue for the main loop
+    temp = 8 * width;
+
+    img1_sum_ptr1      = img1_sum + temp;
+    img2_sum_ptr1      = img2_sum + temp;
+    img1_sq_sum_ptr1   = img1_sq_sum + temp;
+    img2_sq_sum_ptr1   = img2_sq_sum + temp;
+    img12_mul_sum_ptr1 = img12_mul_sum + temp;
+
+    for (x = 0; x < width; x++)
+    {
+        img1_sum[x]      = img1[x];
+        img2_sum[x]      = img2[x];
+        img1_sq_sum[x]   = img1[x] * img1[x];
+        img2_sq_sum[x]   = img2[x] * img2[x];
+        img12_mul_sum[x] = img1[x] * img2[x];
+
+        img1_sum_ptr1[x]      = 0;
+        img2_sum_ptr1[x]      = 0;
+        img1_sq_sum_ptr1[x]   = 0;
+        img2_sq_sum_ptr1[x]   = 0;
+        img12_mul_sum_ptr1[x] = 0;
+    }
+
+    //the main loop
+    for (y = 1; y < height; y++)
+    {
+        img1 += stride_img1;
+        img2 += stride_img2;
+
+        temp = (y - 1) % 9 * width;
+
+        img1_sum_ptr1      = img1_sum + temp;
+        img2_sum_ptr1      = img2_sum + temp;
+        img1_sq_sum_ptr1   = img1_sq_sum + temp;
+        img2_sq_sum_ptr1   = img2_sq_sum + temp;
+        img12_mul_sum_ptr1 = img12_mul_sum + temp;
+
+        temp = y % 9 * width;
+
+        img1_sum_ptr2      = img1_sum + temp;
+        img2_sum_ptr2      = img2_sum + temp;
+        img1_sq_sum_ptr2   = img1_sq_sum + temp;
+        img2_sq_sum_ptr2   = img2_sq_sum + temp;
+        img12_mul_sum_ptr2 = img12_mul_sum + temp;
+
+        for (x = 0; x < width; x++)
+        {
+            img1_sum_ptr2[x]      = img1_sum_ptr1[x] + img1[x];
+            img2_sum_ptr2[x]      = img2_sum_ptr1[x] + img2[x];
+            img1_sq_sum_ptr2[x]   = img1_sq_sum_ptr1[x] + img1[x] * img1[x];
+            img2_sq_sum_ptr2[x]   = img2_sq_sum_ptr1[x] + img2[x] * img2[x];
+            img12_mul_sum_ptr2[x] = img12_mul_sum_ptr1[x] + img1[x] * img2[x];
+        }
+
+        if (y > 6)
+        {
+            //calculate the sum of the last 8 lines by subtracting the total sum of 8 lines back from the present sum
+            temp = (y + 1) % 9 * width;
+
+            img1_sum_ptr1      = img1_sum + temp;
+            img2_sum_ptr1      = img2_sum + temp;
+            img1_sq_sum_ptr1   = img1_sq_sum + temp;
+            img2_sq_sum_ptr1   = img2_sq_sum + temp;
+            img12_mul_sum_ptr1 = img12_mul_sum + temp;
+
+            for (x = 0; x < width; x++)
+            {
+                img1_sum_ptr1[x]      = img1_sum_ptr2[x] - img1_sum_ptr1[x];
+                img2_sum_ptr1[x]      = img2_sum_ptr2[x] - img2_sum_ptr1[x];
+                img1_sq_sum_ptr1[x]   = img1_sq_sum_ptr2[x] - img1_sq_sum_ptr1[x];
+                img2_sq_sum_ptr1[x]   = img2_sq_sum_ptr2[x] - img2_sq_sum_ptr1[x];
+                img12_mul_sum_ptr1[x] = img12_mul_sum_ptr2[x] - img12_mul_sum_ptr1[x];
+            }
+
+            //here we calculate the sum over the 8x8 block of pixels
+            //this is done by sliding a window across the column sums for the last 8 lines
+            //each time adding the new column sum, and subtracting the one which fell out of the window
+            img1_block      = 0;
+            img2_block      = 0;
+            img1_sq_block   = 0;
+            img2_sq_block   = 0;
+            img12_mul_block = 0;
+
+            //prologue, and calculation of simularity measure from the first 8 column sums
+            for (x = 0; x < 8; x++)
+            {
+                img1_block      += img1_sum_ptr1[x];
+                img2_block      += img2_sum_ptr1[x];
+                img1_sq_block   += img1_sq_sum_ptr1[x];
+                img2_sq_block   += img2_sq_sum_ptr1[x];
+                img12_mul_block += img12_mul_sum_ptr1[x];
+            }
+
+            if (lumimask)
+            {
+                y2 = y - 7;
+                x2 = 0;
+
+                if (luminance)
+                {
+                    mean = (img2_block + img1_block) / 128.0f;
+
+                    if (!(y2 % 2 || x2 % 2))
+                        *(img12_sum_block + y2 / 2 * width_uv + x2 / 2) = img2_block + img1_block;
+                }
+                else
+                {
+                    mean = *(img12_sum_block + y2 * width_uv + x2);
+                    mean += *(img12_sum_block + y2 * width_uv + x2 + 4);
+                    mean += *(img12_sum_block + (y2 + 4) * width_uv + x2);
+                    mean += *(img12_sum_block + (y2 + 4) * width_uv + x2 + 4);
+
+                    mean /= 512.0f;
+                }
+
+                weight = mean < 40 ? 0.0f :
+                         (mean < 50 ? (mean - 40.0f) / 10.0f : 1.0f);
+                plane_summed_weights += weight;
+
+                plane_quality += weight * vp8_similarity(img1_block, img2_block, img1_sq_block, img2_sq_block, img12_mul_block);
+            }
+            else
+                plane_quality += vp8_similarity(img1_block, img2_block, img1_sq_block, img2_sq_block, img12_mul_block);
+
+            //and for the rest
+            for (x = 8; x < width; x++)
+            {
+                img1_block      = img1_block + img1_sum_ptr1[x] - img1_sum_ptr1[x - 8];
+                img2_block      = img2_block + img2_sum_ptr1[x] - img2_sum_ptr1[x - 8];
+                img1_sq_block   = img1_sq_block + img1_sq_sum_ptr1[x] - img1_sq_sum_ptr1[x - 8];
+                img2_sq_block   = img2_sq_block + img2_sq_sum_ptr1[x] - img2_sq_sum_ptr1[x - 8];
+                img12_mul_block = img12_mul_block + img12_mul_sum_ptr1[x] - img12_mul_sum_ptr1[x - 8];
+
+                if (lumimask)
+                {
+                    y2 = y - 7;
+                    x2 = x - 7;
+
+                    if (luminance)
+                    {
+                        mean = (img2_block + img1_block) / 128.0f;
+
+                        if (!(y2 % 2 || x2 % 2))
+                            *(img12_sum_block + y2 / 2 * width_uv + x2 / 2) = img2_block + img1_block;
+                    }
+                    else
+                    {
+                        mean = *(img12_sum_block + y2 * width_uv + x2);
+                        mean += *(img12_sum_block + y2 * width_uv + x2 + 4);
+                        mean += *(img12_sum_block + (y2 + 4) * width_uv + x2);
+                        mean += *(img12_sum_block + (y2 + 4) * width_uv + x2 + 4);
+
+                        mean /= 512.0f;
+                    }
+
+                    weight = mean < 40 ? 0.0f :
+                             (mean < 50 ? (mean - 40.0f) / 10.0f : 1.0f);
+                    plane_summed_weights += weight;
+
+                    plane_quality += weight * vp8_similarity(img1_block, img2_block, img1_sq_block, img2_sq_block, img12_mul_block);
+                }
+                else
+                    plane_quality += vp8_similarity(img1_block, img2_block, img1_sq_block, img2_sq_block, img12_mul_block);
+            }
+        }
+    }
+
+    if (plane_summed_weights == 0)
+        return 1.0f;
+    else
+        return plane_quality / plane_summed_weights;
+}
+
+double vp8_calc_ssim
+(
+    YV12_BUFFER_CONFIG *source,
+    YV12_BUFFER_CONFIG *dest,
+    int lumamask,
+    double *weight
+)
+{
+    double a, b, c;
+    double frame_weight;
+    double ssimv;
+
+    width_y = source->y_width;
+    height_y = source->y_height;
+    height_uv = source->uv_height;
+    width_uv = source->uv_width;
+    stride_uv = dest->uv_stride;
+    stride = dest->y_stride;
+
+    lumimask = lumamask;
+
+    luminance = 1;
+    a = vp8_ssim(source->y_buffer, dest->y_buffer,
+                 source->y_stride, dest->y_stride, source->y_width, source->y_height);
+    luminance = 0;
+
+    frame_weight = plane_summed_weights / ((width_y - 7) * (height_y - 7));
+
+    if (frame_weight == 0)
+        a = b = c = 1.0f;
+    else
+    {
+        b = vp8_ssim(source->u_buffer, dest->u_buffer,
+                     source->uv_stride, dest->uv_stride, source->uv_width, source->uv_height);
+
+        c = vp8_ssim(source->v_buffer, dest->v_buffer,
+                     source->uv_stride, dest->uv_stride, source->uv_width, source->uv_height);
+    }
+
+    ssimv = a * .8 + .1 * (b + c);
+
+    *weight = frame_weight;
+
+    return ssimv;
+}
+
+// Google version of SSIM
+// SSIM
+#define KERNEL 3
+#define KERNEL_SIZE  (2 * KERNEL + 1)
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+static const int K[KERNEL_SIZE] =
+{
+    1, 4, 11, 16, 11, 4, 1    // 16 * exp(-0.3 * i * i)
+};
+static const double ki_w = 1. / 2304.;  // 1 / sum(i:0..6, j..6) K[i]*K[j]
+double get_ssimg(const uint8 *org, const uint8 *rec,
+                 int xo, int yo, int W, int H,
+                 const int stride1, const int stride2
+                )
+{
+    // TODO(skal): use summed tables
+    int y, x;
+
+    const int ymin = (yo - KERNEL < 0) ? 0 : yo - KERNEL;
+    const int ymax = (yo + KERNEL > H - 1) ? H - 1 : yo + KERNEL;
+    const int xmin = (xo - KERNEL < 0) ? 0 : xo - KERNEL;
+    const int xmax = (xo + KERNEL > W - 1) ? W - 1 : xo + KERNEL;
+    // worst case of accumulation is a weight of 48 = 16 + 2 * (11 + 4 + 1)
+    // with a diff of 255, squares. That would a max error of 0x8ee0900,
+    // which fits into 32 bits integers.
+    uint32 w = 0, xm = 0, ym = 0, xxm = 0, xym = 0, yym = 0;
+    org += ymin * stride1;
+    rec += ymin * stride2;
+
+    for (y = ymin; y <= ymax; ++y, org += stride1, rec += stride2)
+    {
+        const int Wy = K[KERNEL + y - yo];
+
+        for (x = xmin; x <= xmax; ++x)
+        {
+            const  int Wxy = Wy * K[KERNEL + x - xo];
+            // TODO(skal): inlined assembly
+            w   += Wxy;
+            xm  += Wxy * org[x];
+            ym  += Wxy * rec[x];
+            xxm += Wxy * org[x] * org[x];
+            xym += Wxy * org[x] * rec[x];
+            yym += Wxy * rec[x] * rec[x];
+        }
+    }
+
+    {
+        const double iw = 1. / w;
+        const double iwx = xm * iw;
+        const double iwy = ym * iw;
+        double sxx = xxm * iw - iwx * iwx;
+        double syy = yym * iw - iwy * iwy;
+
+        // small errors are possible, due to rounding. Clamp to zero.
+        if (sxx < 0.) sxx = 0.;
+
+        if (syy < 0.) syy = 0.;
+
+        {
+            const double sxsy = sqrt(sxx * syy);
+            const double sxy = xym * iw - iwx * iwy;
+            static const double C11 = (0.01 * 0.01) * (255 * 255);
+            static const double C22 = (0.03 * 0.03) * (255 * 255);
+            static const double C33 = (0.015 * 0.015) * (255 * 255);
+            const double l = (2. * iwx * iwy + C11) / (iwx * iwx + iwy * iwy + C11);
+            const double c = (2. * sxsy      + C22) / (sxx + syy + C22);
+
+            const double s = (sxy + C33) / (sxsy + C33);
+            return l * c * s;
+
+        }
+    }
+
+}
+
+double get_ssimfull_kernelg(const uint8 *org, const uint8 *rec,
+                            int xo, int yo, int W, int H,
+                            const int stride1, const int stride2)
+{
+    // TODO(skal): use summed tables
+    // worst case of accumulation is a weight of 48 = 16 + 2 * (11 + 4 + 1)
+    // with a diff of 255, squares. That would a max error of 0x8ee0900,
+    // which fits into 32 bits integers.
+    int y_, x_;
+    uint32 xm = 0, ym = 0, xxm = 0, xym = 0, yym = 0;
+    org += (yo - KERNEL) * stride1;
+    org += (xo - KERNEL);
+    rec += (yo - KERNEL) * stride2;
+    rec += (xo - KERNEL);
+
+    for (y_ = 0; y_ < KERNEL_SIZE; ++y_, org += stride1, rec += stride2)
+    {
+        const int Wy = K[y_];
+
+        for (x_ = 0; x_ < KERNEL_SIZE; ++x_)
+        {
+            const int Wxy = Wy * K[x_];
+            // TODO(skal): inlined assembly
+            const int org_x = org[x_];
+            const int rec_x = rec[x_];
+            xm  += Wxy * org_x;
+            ym  += Wxy * rec_x;
+            xxm += Wxy * org_x * org_x;
+            xym += Wxy * org_x * rec_x;
+            yym += Wxy * rec_x * rec_x;
+        }
+    }
+
+    {
+        const double iw = ki_w;
+        const double iwx = xm * iw;
+        const double iwy = ym * iw;
+        double sxx = xxm * iw - iwx * iwx;
+        double syy = yym * iw - iwy * iwy;
+
+        // small errors are possible, due to rounding. Clamp to zero.
+        if (sxx < 0.) sxx = 0.;
+
+        if (syy < 0.) syy = 0.;
+
+        {
+            const double sxsy = sqrt(sxx * syy);
+            const double sxy = xym * iw - iwx * iwy;
+            static const double C11 = (0.01 * 0.01) * (255 * 255);
+            static const double C22 = (0.03 * 0.03) * (255 * 255);
+            static const double C33 = (0.015 * 0.015) * (255 * 255);
+            const double l = (2. * iwx * iwy + C11) / (iwx * iwx + iwy * iwy + C11);
+            const double c = (2. * sxsy      + C22) / (sxx + syy + C22);
+            const double s = (sxy + C33) / (sxsy + C33);
+            return l * c * s;
+        }
+    }
+}
+
+double calc_ssimg(const uint8 *org, const uint8 *rec,
+                  const int image_width, const int image_height,
+                  const int stride1, const int stride2
+                 )
+{
+    int j, i;
+    double SSIM = 0.;
+
+    for (j = 0; j < KERNEL; ++j)
+    {
+        for (i = 0; i < image_width; ++i)
+        {
+            SSIM += get_ssimg(org, rec, i, j, image_width, image_height, stride1, stride2);
+        }
+    }
+
+    for (j = KERNEL; j < image_height - KERNEL; ++j)
+    {
+        for (i = 0; i < KERNEL; ++i)
+        {
+            SSIM += get_ssimg(org, rec, i, j, image_width, image_height, stride1, stride2);
+        }
+
+        for (i = KERNEL; i < image_width - KERNEL; ++i)
+        {
+            SSIM += get_ssimfull_kernelg(org, rec, i, j,
+                                         image_width, image_height, stride1, stride2);
+        }
+
+        for (i = image_width - KERNEL; i < image_width; ++i)
+        {
+            SSIM += get_ssimg(org, rec, i, j, image_width, image_height, stride1, stride2);
+        }
+    }
+
+    for (j = image_height - KERNEL; j < image_height; ++j)
+    {
+        for (i = 0; i < image_width; ++i)
+        {
+            SSIM += get_ssimg(org, rec, i, j, image_width, image_height, stride1, stride2);
+        }
+    }
+
+    return SSIM;
+}
+
+
+double vp8_calc_ssimg
+(
+    YV12_BUFFER_CONFIG *source,
+    YV12_BUFFER_CONFIG *dest,
+    double *ssim_y,
+    double *ssim_u,
+    double *ssim_v
+)
+{
+    double ssim_all = 0;
+    int ysize  = source->y_width * source->y_height;
+    int uvsize = ysize / 4;
+
+    *ssim_y = calc_ssimg(source->y_buffer, dest->y_buffer,
+                         source->y_width, source->y_height,
+                         source->y_stride, dest->y_stride);
+
+
+    *ssim_u = calc_ssimg(source->u_buffer, dest->u_buffer,
+                         source->uv_width, source->uv_height,
+                         source->uv_stride, dest->uv_stride);
+
+
+    *ssim_v = calc_ssimg(source->v_buffer, dest->v_buffer,
+                         source->uv_width, source->uv_height,
+                         source->uv_stride, dest->uv_stride);
+
+    ssim_all = (*ssim_y + *ssim_u + *ssim_v) / (ysize + uvsize + uvsize);
+    *ssim_y /= ysize;
+    *ssim_u /= uvsize;
+    *ssim_v /= uvsize;
+    return ssim_all;
+}
diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c
new file mode 100644 (file)
index 0000000..33ddd64
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "onyx_int.h"
+#include "tokenize.h"
+#include "vpx_mem/vpx_mem.h"
+
+/* Global event counters used for accumulating statistics across several
+   compressions, then generating context.c = initial stats. */
+
+#ifdef ENTROPY_STATS
+_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
+#endif
+void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
+void vp8_fix_contexts(VP8_COMP *cpi, MACROBLOCKD *x);
+
+TOKENEXTRA vp8_dct_value_tokens[DCT_MAX_VALUE*2];
+TOKENEXTRA *vp8_dct_value_tokens_ptr;
+int vp8_dct_value_cost[DCT_MAX_VALUE*2];
+int *vp8_dct_value_cost_ptr;
+#if 0
+int skip_true_count = 0;
+int skip_false_count = 0;
+#endif
+static void fill_value_tokens()
+{
+
+    TOKENEXTRA *const t = vp8_dct_value_tokens + DCT_MAX_VALUE;
+    vp8_extra_bit_struct *const e = vp8_extra_bits;
+
+    int i = -DCT_MAX_VALUE;
+    int sign = 1;
+
+    do
+    {
+        if (!i)
+            sign = 0;
+
+        {
+            const int a = sign ? -i : i;
+            int eb = sign;
+
+            if (a > 4)
+            {
+                int j = 4;
+
+                while (++j < 11  &&  e[j].base_val <= a) {}
+
+                t[i].Token = --j;
+                eb |= (a - e[j].base_val) << 1;
+            }
+            else
+                t[i].Token = a;
+
+            t[i].Extra = eb;
+        }
+
+        // initialize the cost for extra bits for all possible coefficient value.
+        {
+            int cost = 0;
+            vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token;
+
+            if (p->base_val)
+            {
+                const int extra = t[i].Extra;
+                const int Length = p->Len;
+
+                if (Length)
+                    cost += vp8_treed_cost(p->tree, p->prob, extra >> 1, Length);
+
+                cost += vp8_cost_bit(vp8_prob_half, extra & 1); /* sign */
+                vp8_dct_value_cost[i + DCT_MAX_VALUE] = cost;
+            }
+
+        }
+
+    }
+    while (++i < DCT_MAX_VALUE);
+
+    vp8_dct_value_tokens_ptr = vp8_dct_value_tokens + DCT_MAX_VALUE;
+    vp8_dct_value_cost_ptr   = vp8_dct_value_cost + DCT_MAX_VALUE;
+}
+
+static void tokenize2nd_order_b
+(
+    const BLOCKD *const b,
+    TOKENEXTRA **tp,
+    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
+    const FRAME_TYPE frametype,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+    VP8_COMP *cpi
+)
+{
+    int pt; /* near block/prev token context index */
+    int c = 0;          /* start at DC */
+    const int eob = b->eob;     /* one beyond last nonzero coeff */
+    TOKENEXTRA *t = *tp;        /* store tokens starting here */
+    int x;
+    const short *qcoeff_ptr = b->qcoeff;
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+
+    do
+    {
+        const int band = vp8_coef_bands[c];
+
+        if (c < eob)
+        {
+            int rc = vp8_default_zig_zag1d[c];
+            const int v = qcoeff_ptr[rc];
+
+            assert(-DCT_MAX_VALUE <= v  &&  v < (DCT_MAX_VALUE));
+
+            t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
+            x        = vp8_dct_value_tokens_ptr[v].Token;
+        }
+        else
+            x = DCT_EOB_TOKEN;
+
+        t->Token = x;
+        t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];
+
+        t->section = frametype * BLOCK_TYPES * 2 + 2 * type + (c == 0);
+
+        t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0));
+
+        ++cpi->coef_counts       [type] [band] [pt] [x];
+    }
+    while (pt = vp8_prev_token_class[x], ++t, c < eob  &&  ++c < 16);
+
+    *tp = t;
+    pt = (c != !type); /* 0 <-> all coeff data is zero */
+    *a = *l = pt;
+
+}
+
+static void tokenize1st_order_b
+(
+    const BLOCKD *const b,
+    TOKENEXTRA **tp,
+    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
+    const FRAME_TYPE frametype,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+    VP8_COMP *cpi
+)
+{
+    int pt; /* near block/prev token context index */
+    int c = type ? 0 : 1;       /* start at DC unless type 0 */
+    const int eob = b->eob;     /* one beyond last nonzero coeff */
+    TOKENEXTRA *t = *tp;        /* store tokens starting here */
+    int x;
+    const short *qcoeff_ptr = b->qcoeff;
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+
+    do
+    {
+        const int band = vp8_coef_bands[c];
+
+        x = DCT_EOB_TOKEN;
+
+        if (c < eob)
+        {
+            int rc = vp8_default_zig_zag1d[c];
+            const int v = qcoeff_ptr[rc];
+
+            assert(-DCT_MAX_VALUE <= v  &&  v < (DCT_MAX_VALUE));
+
+            t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
+            x        = vp8_dct_value_tokens_ptr[v].Token;
+        }
+
+        t->Token = x;
+        t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];
+
+        t->section = frametype * BLOCK_TYPES * 2 + 2 * type + (c == 0);
+        t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0));
+
+        ++cpi->coef_counts       [type] [band] [pt] [x];
+    }
+    while (pt = vp8_prev_token_class[x], ++t, c < eob  &&  ++c < 16);
+
+    *tp = t;
+    pt = (c != !type); /* 0 <-> all coeff data is zero */
+    *a = *l = pt;
+
+}
+#if 0
+void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
+{
+    //int i;
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+    int plane_type;
+    int b;
+
+    TOKENEXTRA *start = *t;
+    TOKENEXTRA *tp = *t;
+
+    x->mbmi.dc_diff = 1;
+
+    vpx_memcpy(cpi->coef_counts_backup, cpi->coef_counts, sizeof(cpi->coef_counts));
+
+    if (x->mbmi.mode == B_PRED || x->mbmi.mode == SPLITMV)
+    {
+        plane_type = 3;
+    }
+    else
+    {
+        tokenize2nd_order_b(x->block + 24, t, 1, x->frame_type,
+                            A[Y2CONTEXT] + vp8_block2above[24], L[Y2CONTEXT] + vp8_block2left[24], cpi);
+        plane_type = 0;
+
+    }
+
+    for (b = 0; b < 16; b++)
+        tokenize1st_order_b(x->block + b, t, plane_type, x->frame_type,
+                            A[vp8_block2context[b]] + vp8_block2above[b],
+                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);
+
+    for (b = 16; b < 24; b++)
+        tokenize1st_order_b(x->block + b, t, 2, x->frame_type,
+                            A[vp8_block2context[b]] + vp8_block2above[b],
+                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);
+
+    if (cpi->common.mb_no_coeff_skip)
+    {
+        x->mbmi.mb_skip_coeff = 1;
+
+        while ((tp != *t) && x->mbmi.mb_skip_coeff)
+        {
+            x->mbmi.mb_skip_coeff = (x->mbmi.mb_skip_coeff && (tp->Token == DCT_EOB_TOKEN));
+            tp ++;
+        }
+
+        if (x->mbmi.mb_skip_coeff == 1)
+        {
+            x->mbmi.dc_diff = 0;
+            //redo the coutnts
+            vpx_memcpy(cpi->coef_counts, cpi->coef_counts_backup, sizeof(cpi->coef_counts));
+
+            *t = start;
+            cpi->skip_true_count++;
+
+            //skip_true_count++;
+        }
+        else
+        {
+
+            cpi->skip_false_count++;
+            //skip_false_count++;
+        }
+    }
+}
+#else
+void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
+{
+    //int i;
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+    int plane_type;
+    int b;
+
+    TOKENEXTRA *start = *t;
+    TOKENEXTRA *tp = *t;
+
+    x->mbmi.dc_diff = 1;
+
+#if 0
+
+    if (x->mbmi.force_no_skip)
+    {
+        x->mbmi.mb_skip_coeff = 1;
+        //reset for next_mb.
+        x->mbmi.force_no_skip = 0;
+    }
+
+#endif
+
+#if 1
+
+    if (x->mbmi.mb_skip_coeff)
+    {
+
+        cpi->skip_true_count++;
+
+        if (!cpi->common.mb_no_coeff_skip)
+            vp8_stuff_mb(cpi, x, t) ;
+        else
+        {
+            vp8_fix_contexts(cpi, x);
+        }
+
+        if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+            x->mbmi.dc_diff = 0;
+        else
+            x->mbmi.dc_diff = 1;
+
+
+        return;
+    }
+
+    cpi->skip_false_count++;
+#endif
+#if 0
+
+    if (x->mbmi.mode == B_PRED || x->mbmi.mode == SPLITMV)
+    {
+        int i, skip = 1;
+
+        for (i = 0; i < 24; i++)
+            skip &= (!x->block[i].eob);
+
+        if (skip != x->mbmi.mb_skip_coeff)
+            skip += 0;
+
+        x->mbmi.mb_skip_coeff = skip;
+    }
+    else
+    {
+        int i, skip = 1;
+
+        for (i = 0; i < 16; i++)
+            skip &= (x->block[i].eob < 2);
+
+        for (i = 16; i < 25; i++)
+            skip &= (!x->block[i].eob);
+
+        if (skip != x->mbmi.mb_skip_coeff)
+            skip += 0;
+
+        x->mbmi.mb_skip_coeff = skip;
+    }
+
+    vpx_memcpy(cpi->coef_counts_backup, cpi->coef_counts, sizeof(cpi->coef_counts));
+#endif
+
+    if (x->mbmi.mode == B_PRED || x->mbmi.mode == SPLITMV)
+    {
+        plane_type = 3;
+    }
+    else
+    {
+        tokenize2nd_order_b(x->block + 24, t, 1, x->frame_type,
+                            A[Y2CONTEXT] + vp8_block2above[24], L[Y2CONTEXT] + vp8_block2left[24], cpi);
+        plane_type = 0;
+
+    }
+
+    for (b = 0; b < 16; b++)
+        tokenize1st_order_b(x->block + b, t, plane_type, x->frame_type,
+                            A[vp8_block2context[b]] + vp8_block2above[b],
+                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);
+
+    for (b = 16; b < 24; b++)
+        tokenize1st_order_b(x->block + b, t, 2, x->frame_type,
+                            A[vp8_block2context[b]] + vp8_block2above[b],
+                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);
+
+#if 0
+
+    if (cpi->common.mb_no_coeff_skip)
+    {
+        int skip = 1;
+
+        while ((tp != *t) && skip)
+        {
+            skip = (skip && (tp->Token == DCT_EOB_TOKEN));
+            tp ++;
+        }
+
+        if (skip != x->mbmi.mb_skip_coeff)
+            skip += 0;
+
+        x->mbmi.mb_skip_coeff = skip;
+
+        if (x->mbmi.mb_skip_coeff == 1)
+        {
+            x->mbmi.dc_diff = 0;
+            //redo the coutnts
+            vpx_memcpy(cpi->coef_counts, cpi->coef_counts_backup, sizeof(cpi->coef_counts));
+
+            *t = start;
+            cpi->skip_true_count++;
+            //skip_true_count++;
+        }
+        else
+        {
+
+            cpi->skip_false_count++;
+            //skip_false_count++;
+        }
+    }
+
+#endif
+}
+#endif
+
+#ifdef ENTROPY_STATS
+
+void init_context_counters(void)
+{
+    vpx_memset(context_counters, 0, sizeof(context_counters));
+}
+
+void print_context_counters()
+{
+
+    int type, band, pt, t;
+
+    FILE *const f = fopen("context.c", "w");
+
+    fprintf(f, "#include \"entropy.h\"\n");
+
+    fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
+
+    fprintf(f, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];\n\n");
+
+    fprintf(f, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] = {");
+
+# define Comma( X) (X? ",":"")
+
+    type = 0;
+
+    do
+    {
+        fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
+
+        band = 0;
+
+        do
+        {
+            fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
+
+            pt = 0;
+
+            do
+            {
+                fprintf(f, "%s\n      {", Comma(pt));
+
+                t = 0;
+
+                do
+                {
+                    const _int64 x = context_counters [type] [band] [pt] [t];
+                    const int y = (int) x;
+
+                    assert(x == (_int64) y);  /* no overflow handling yet */
+                    fprintf(f, "%s %d", Comma(t), y);
+
+                }
+                while (++t < vp8_coef_tokens);
+
+                fprintf(f, "}");
+            }
+            while (++pt < PREV_COEF_CONTEXTS);
+
+            fprintf(f, "\n    }");
+
+        }
+        while (++band < COEF_BANDS);
+
+        fprintf(f, "\n  }");
+    }
+    while (++type < BLOCK_TYPES);
+
+    fprintf(f, "\n};\n");
+    fclose(f);
+}
+#endif
+
+
+void vp8_tokenize_initialize()
+{
+    fill_value_tokens();
+}
+
+
+static __inline void stuff2nd_order_b
+(
+    const BLOCKD *const b,
+    TOKENEXTRA **tp,
+    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
+    const FRAME_TYPE frametype,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+    VP8_COMP *cpi
+)
+{
+    int pt; /* near block/prev token context index */
+    TOKENEXTRA *t = *tp;        /* store tokens starting here */
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+    (void) frametype;
+    (void) type;
+    (void) b;
+
+    t->Token = DCT_EOB_TOKEN;
+    t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt];
+    t->section = 11;
+    t->skip_eob_node = 0;
+    ++cpi->coef_counts       [1] [0] [pt] [DCT_EOB_TOKEN];
+    ++t;
+
+    *tp = t;
+    pt = 0;
+    *a = *l = pt;
+
+}
+
+static __inline void stuff1st_order_b
+(
+    const BLOCKD *const b,
+    TOKENEXTRA **tp,
+    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
+    const FRAME_TYPE frametype,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+    VP8_COMP *cpi
+)
+{
+    int pt; /* near block/prev token context index */
+    TOKENEXTRA *t = *tp;        /* store tokens starting here */
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+    (void) frametype;
+    (void) type;
+    (void) b;
+
+    t->Token = DCT_EOB_TOKEN;
+    t->context_tree = cpi->common.fc.coef_probs [0] [1] [pt];
+    t->section = 8;
+    t->skip_eob_node = 0;
+    ++cpi->coef_counts       [0] [1] [pt] [DCT_EOB_TOKEN];
+    ++t;
+    *tp = t;
+    pt = 0; /* 0 <-> all coeff data is zero */
+    *a = *l = pt;
+
+}
+static __inline
+void stuff1st_order_buv
+(
+    const BLOCKD *const b,
+    TOKENEXTRA **tp,
+    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
+    const FRAME_TYPE frametype,
+    ENTROPY_CONTEXT *a,
+    ENTROPY_CONTEXT *l,
+    VP8_COMP *cpi
+)
+{
+    int pt; /* near block/prev token context index */
+    TOKENEXTRA *t = *tp;        /* store tokens starting here */
+    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+    (void) frametype;
+    (void) type;
+    (void) b;
+
+    t->Token = DCT_EOB_TOKEN;
+    t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt];
+    t->section = 13;
+    t->skip_eob_node = 0;
+    ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN];
+    ++t;
+    *tp = t;
+    pt = 0; /* 0 <-> all coeff data is zero */
+    *a = *l = pt;
+
+}
+
+void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
+{
+    //int i;
+    ENTROPY_CONTEXT **const A = x->above_context;
+    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
+    int plane_type;
+    int b;
+
+    stuff2nd_order_b(x->block + 24, t, 1, x->frame_type,
+                     A[Y2CONTEXT] + vp8_block2above[24], L[Y2CONTEXT] + vp8_block2left[24], cpi);
+    plane_type = 0;
+
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+        x->mbmi.dc_diff = 0;
+    else
+        x->mbmi.dc_diff = 1;
+
+
+    for (b = 0; b < 16; b++)
+        stuff1st_order_b(x->block + b, t, plane_type, x->frame_type,
+                         A[vp8_block2context[b]] + vp8_block2above[b],
+                         L[vp8_block2context[b]] + vp8_block2left[b], cpi);
+
+    for (b = 16; b < 24; b++)
+        stuff1st_order_buv(x->block + b, t, 2, x->frame_type,
+                           A[vp8_block2context[b]] + vp8_block2above[b],
+                           L[vp8_block2context[b]] + vp8_block2left[b], cpi);
+
+}
+void vp8_fix_contexts(VP8_COMP *cpi, MACROBLOCKD *x)
+{
+    x->left_context[Y1CONTEXT][0] = 0;
+    x->left_context[Y1CONTEXT][1] = 0;
+    x->left_context[Y1CONTEXT][2] = 0;
+    x->left_context[Y1CONTEXT][3] = 0;
+    x->left_context[UCONTEXT][0]  = 0;
+    x->left_context[VCONTEXT][0]  = 0;
+    x->left_context[UCONTEXT][1]  = 0;
+    x->left_context[VCONTEXT][1]  = 0;
+
+    x->above_context[Y1CONTEXT][0] = 0;
+    x->above_context[Y1CONTEXT][1] = 0;
+    x->above_context[Y1CONTEXT][2] = 0;
+    x->above_context[Y1CONTEXT][3] = 0;
+    x->above_context[UCONTEXT][0]  = 0;
+    x->above_context[VCONTEXT][0]  = 0;
+    x->above_context[UCONTEXT][1]  = 0;
+    x->above_context[VCONTEXT][1]  = 0;
+
+    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
+    {
+        x->left_context[Y2CONTEXT][0] = 0;
+        x->above_context[Y2CONTEXT][0] = 0;
+    }
+}
diff --git a/vp8/encoder/tokenize.h b/vp8/encoder/tokenize.h
new file mode 100644 (file)
index 0000000..02aacc2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef tokenize_h
+#define tokenize_h
+
+#include "entropy.h"
+#include "block.h"
+
+void vp8_tokenize_initialize();
+
+typedef struct
+{
+    int Token;
+    int Extra;
+    const vp8_prob *context_tree;
+    int skip_eob_node;
+    int section;
+} TOKENEXTRA;
+
+int rd_cost_mby(MACROBLOCKD *);
+
+#ifdef ENTROPY_STATS
+void init_context_counters();
+void print_context_counters();
+
+extern _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
+#endif
+
+
+#endif  /* tokenize_h */
diff --git a/vp8/encoder/treewriter.c b/vp8/encoder/treewriter.c
new file mode 100644 (file)
index 0000000..e398044
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "treewriter.h"
+
+static void cost(
+    int *const C,
+    vp8_tree T,
+    const vp8_prob *const P,
+    int i,
+    int c
+)
+{
+    const vp8_prob p = P [i>>1];
+
+    do
+    {
+        const vp8_tree_index j = T[i];
+        const int d = c + vp8_cost_bit(p, i & 1);
+
+        if (j <= 0)
+            C[-j] = d;
+        else
+            cost(C, T, P, j, d);
+    }
+    while (++i & 1);
+}
+void vp8_cost_tokens(int *c, const vp8_prob *p, vp8_tree t)
+{
+    cost(c, t, p, 0, 0);
+}
diff --git a/vp8/encoder/treewriter.h b/vp8/encoder/treewriter.h
new file mode 100644 (file)
index 0000000..05ac74c
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __INC_TREEWRITER_H
+#define __INC_TREEWRITER_H
+
+/* Trees map alphabets into huffman-like codes suitable for an arithmetic
+   bit coder.  Timothy S Murphy  11 October 2004 */
+
+#include "treecoder.h"
+
+#include "boolhuff.h"       /* for now */
+
+typedef BOOL_CODER vp8_writer;
+
+#define vp8_write vp8_encode_bool
+#define vp8_write_literal vp8_encode_value
+#define vp8_write_bit( W, V) vp8_write( W, V, vp8_prob_half)
+
+#define vp8bc_write vp8bc_write_bool
+#define vp8bc_write_literal vp8bc_write_bits
+#define vp8bc_write_bit( W, V) vp8bc_write_bits( W, V, 1)
+
+
+/* Approximate length of an encoded bool in 256ths of a bit at given prob */
+
+#define vp8_cost_zero( x) ( vp8_prob_cost[x])
+#define vp8_cost_one( x)  vp8_cost_zero( vp8_complement(x))
+
+#define vp8_cost_bit( x, b) vp8_cost_zero( (b)?  vp8_complement(x) : (x) )
+
+/* VP8BC version is scaled by 2^20 rather than 2^8; see bool_coder.h */
+
+
+/* Both of these return bits, not scaled bits. */
+
+static __inline unsigned int vp8_cost_branch(const unsigned int ct[2], vp8_prob p)
+{
+    /* Imitate existing calculation */
+
+    return ((ct[0] * vp8_cost_zero(p))
+            + (ct[1] * vp8_cost_one(p))) >> 8;
+}
+
+/* Small functions to write explicit values and tokens, as well as
+   estimate their lengths. */
+
+static __inline void vp8_treed_write
+(
+    vp8_writer *const w,
+    vp8_tree t,
+    const vp8_prob *const p,
+    int v,
+    int n               /* number of bits in v, assumed nonzero */
+)
+{
+    vp8_tree_index i = 0;
+
+    do
+    {
+        const int b = (v >> --n) & 1;
+        vp8_write(w, b, p[i>>1]);
+        i = t[i+b];
+    }
+    while (n);
+}
+static __inline void vp8_write_token
+(
+    vp8_writer *const w,
+    vp8_tree t,
+    const vp8_prob *const p,
+    vp8_token *const x
+)
+{
+    vp8_treed_write(w, t, p, x->value, x->Len);
+}
+
+static __inline int vp8_treed_cost(
+    vp8_tree t,
+    const vp8_prob *const p,
+    int v,
+    int n               /* number of bits in v, assumed nonzero */
+)
+{
+    int c = 0;
+    vp8_tree_index i = 0;
+
+    do
+    {
+        const int b = (v >> --n) & 1;
+        c += vp8_cost_bit(p[i>>1], b);
+        i = t[i+b];
+    }
+    while (n);
+
+    return c;
+}
+static __inline int vp8_cost_token
+(
+    vp8_tree t,
+    const vp8_prob *const p,
+    vp8_token *const x
+)
+{
+    return vp8_treed_cost(t, p, x->value, x->Len);
+}
+
+/* Fill array of costs for all possible token values. */
+
+void vp8_cost_tokens(
+    int *Costs, const vp8_prob *, vp8_tree
+);
+
+#endif
diff --git a/vp8/encoder/variance.h b/vp8/encoder/variance.h
new file mode 100644 (file)
index 0000000..b3b55c3
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VARIANCE_H
+#define VARIANCE_H
+
+#define prototype_sad(sym)\
+    unsigned int (sym)\
+    (\
+     unsigned char *src_ptr, \
+     int source_stride, \
+     unsigned char *ref_ptr, \
+     int  ref_stride, \
+     int max_sad\
+    )
+
+#define prototype_sad_multi_same_address(sym)\
+    void (sym)\
+    (\
+     unsigned char *src_ptr, \
+     int source_stride, \
+     unsigned char *ref_ptr, \
+     int  ref_stride, \
+     unsigned int *sad_array\
+    )
+
+#define prototype_sad_multi_dif_address(sym)\
+    void (sym)\
+    (\
+     unsigned char *src_ptr, \
+     int source_stride, \
+     unsigned char *ref_ptr[4], \
+     int  ref_stride, \
+     unsigned int *sad_array\
+    )
+
+#define prototype_variance(sym) \
+    unsigned int (sym) \
+    (\
+     unsigned char *src_ptr, \
+     int source_stride, \
+     unsigned char *ref_ptr, \
+     int  ref_stride, \
+     unsigned int *sse\
+    )
+
+#define prototype_variance2(sym) \
+    unsigned int (sym) \
+    (\
+     unsigned char *src_ptr, \
+     int source_stride, \
+     unsigned char *ref_ptr, \
+     int  ref_stride, \
+     unsigned int *sse,\
+     int *sum\
+    )
+
+#define prototype_subpixvariance(sym) \
+    unsigned int (sym) \
+    ( \
+      unsigned char  *src_ptr, \
+      int  source_stride, \
+      int  xoffset, \
+      int  yoffset, \
+      unsigned char *ref_ptr, \
+      int Refstride, \
+      unsigned int *sse \
+    );
+
+
+#define prototype_getmbss(sym) unsigned int (sym)(short *)
+
+#if ARCH_X86 || ARCH_X86_64
+#include "x86/variance_x86.h"
+#endif
+
+#if ARCH_ARM
+#include "arm/variance_arm.h"
+#endif
+
+#ifndef vp8_variance_sad4x4
+#define vp8_variance_sad4x4 vp8_sad4x4_c
+#endif
+extern prototype_sad(vp8_variance_sad4x4);
+
+#ifndef vp8_variance_sad8x8
+#define vp8_variance_sad8x8 vp8_sad8x8_c
+#endif
+extern prototype_sad(vp8_variance_sad8x8);
+
+#ifndef vp8_variance_sad8x16
+#define vp8_variance_sad8x16 vp8_sad8x16_c
+#endif
+extern prototype_sad(vp8_variance_sad8x16);
+
+#ifndef vp8_variance_sad16x8
+#define vp8_variance_sad16x8 vp8_sad16x8_c
+#endif
+extern prototype_sad(vp8_variance_sad16x8);
+
+#ifndef vp8_variance_sad16x16
+#define vp8_variance_sad16x16 vp8_sad16x16_c
+#endif
+extern prototype_sad(vp8_variance_sad16x16);
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+#ifndef vp8_variance_sad16x16x3
+#define vp8_variance_sad16x16x3 vp8_sad16x16x3_c
+#endif
+extern prototype_sad_multi_same_address(vp8_variance_sad16x16x3);
+
+#ifndef vp8_variance_sad16x8x3
+#define vp8_variance_sad16x8x3 vp8_sad16x8x3_c
+#endif
+extern prototype_sad_multi_same_address(vp8_variance_sad16x8x3);
+
+#ifndef vp8_variance_sad8x8x3
+#define vp8_variance_sad8x8x3 vp8_sad8x8x3_c
+#endif
+extern prototype_sad_multi_same_address(vp8_variance_sad8x8x3);
+
+#ifndef vp8_variance_sad8x16x3
+#define vp8_variance_sad8x16x3 vp8_sad8x16x3_c
+#endif
+extern prototype_sad_multi_same_address(vp8_variance_sad8x16x3);
+
+#ifndef vp8_variance_sad4x4x3
+#define vp8_variance_sad4x4x3 vp8_sad4x4x3_c
+#endif
+extern prototype_sad_multi_same_address(vp8_variance_sad4x4x3);
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+#ifndef vp8_variance_sad16x16x4d
+#define vp8_variance_sad16x16x4d vp8_sad16x16x4d_c
+#endif
+extern prototype_sad_multi_dif_address(vp8_variance_sad16x16x4d);
+
+#ifndef vp8_variance_sad16x8x4d
+#define vp8_variance_sad16x8x4d vp8_sad16x8x4d_c
+#endif
+extern prototype_sad_multi_dif_address(vp8_variance_sad16x8x4d);
+
+#ifndef vp8_variance_sad8x8x4d
+#define vp8_variance_sad8x8x4d vp8_sad8x8x4d_c
+#endif
+extern prototype_sad_multi_dif_address(vp8_variance_sad8x8x4d);
+
+#ifndef vp8_variance_sad8x16x4d
+#define vp8_variance_sad8x16x4d vp8_sad8x16x4d_c
+#endif
+extern prototype_sad_multi_dif_address(vp8_variance_sad8x16x4d);
+
+#ifndef vp8_variance_sad4x4x4d
+#define vp8_variance_sad4x4x4d vp8_sad4x4x4d_c
+#endif
+extern prototype_sad_multi_dif_address(vp8_variance_sad4x4x4d);
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+#ifndef vp8_variance_var4x4
+#define vp8_variance_var4x4 vp8_variance4x4_c
+#endif
+extern prototype_variance(vp8_variance_var4x4);
+
+#ifndef vp8_variance_var8x8
+#define vp8_variance_var8x8 vp8_variance8x8_c
+#endif
+extern prototype_variance(vp8_variance_var8x8);
+
+#ifndef vp8_variance_var8x16
+#define vp8_variance_var8x16 vp8_variance8x16_c
+#endif
+extern prototype_variance(vp8_variance_var8x16);
+
+#ifndef vp8_variance_var16x8
+#define vp8_variance_var16x8 vp8_variance16x8_c
+#endif
+extern prototype_variance(vp8_variance_var16x8);
+
+#ifndef vp8_variance_var16x16
+#define vp8_variance_var16x16 vp8_variance16x16_c
+#endif
+extern prototype_variance(vp8_variance_var16x16);
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+#ifndef vp8_variance_subpixvar4x4
+#define vp8_variance_subpixvar4x4 vp8_sub_pixel_variance4x4_c
+#endif
+extern prototype_subpixvariance(vp8_variance_subpixvar4x4);
+
+#ifndef vp8_variance_subpixvar8x8
+#define vp8_variance_subpixvar8x8 vp8_sub_pixel_variance8x8_c
+#endif
+extern prototype_subpixvariance(vp8_variance_subpixvar8x8);
+
+#ifndef vp8_variance_subpixvar8x16
+#define vp8_variance_subpixvar8x16 vp8_sub_pixel_variance8x16_c
+#endif
+extern prototype_subpixvariance(vp8_variance_subpixvar8x16);
+
+#ifndef vp8_variance_subpixvar16x8
+#define vp8_variance_subpixvar16x8 vp8_sub_pixel_variance16x8_c
+#endif
+extern prototype_subpixvariance(vp8_variance_subpixvar16x8);
+
+#ifndef vp8_variance_subpixvar16x16
+#define vp8_variance_subpixvar16x16 vp8_sub_pixel_variance16x16_c
+#endif
+extern prototype_subpixvariance(vp8_variance_subpixvar16x16);
+
+#ifndef vp8_variance_subpixmse16x16
+#define vp8_variance_subpixmse16x16 vp8_sub_pixel_mse16x16_c
+#endif
+extern prototype_subpixvariance(vp8_variance_subpixmse16x16);
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+#ifndef vp8_variance_getmbss
+#define vp8_variance_getmbss vp8_get_mb_ss_c
+#endif
+extern prototype_getmbss(vp8_variance_getmbss);
+
+#ifndef vp8_variance_mse16x16
+#define vp8_variance_mse16x16 vp8_mse16x16_c
+#endif
+extern prototype_variance(vp8_variance_mse16x16);
+
+#ifndef vp8_variance_get16x16prederror
+#define vp8_variance_get16x16prederror vp8_get16x16pred_error_c
+#endif
+extern prototype_sad(vp8_variance_get16x16prederror);
+
+#ifndef vp8_variance_get8x8var
+#define vp8_variance_get8x8var vp8_get8x8var_c
+#endif
+extern prototype_variance2(vp8_variance_get8x8var);
+
+#ifndef vp8_variance_get16x16var
+#define vp8_variance_get16x16var vp8_get16x16var_c
+#endif
+extern prototype_variance2(vp8_variance_get16x16var);
+
+#ifndef vp8_variance_get4x4sse_cs
+#define vp8_variance_get4x4sse_cs vp8_get4x4sse_cs_c
+#endif
+extern prototype_sad(vp8_variance_get4x4sse_cs);
+
+
+typedef prototype_sad(*vp8_sad_fn_t);
+typedef prototype_sad_multi_same_address(*vp8_sad_multi_fn_t);
+typedef prototype_sad_multi_dif_address(*vp8_sad_multi_d_fn_t);
+typedef prototype_variance(*vp8_variance_fn_t);
+typedef prototype_variance2(*vp8_variance2_fn_t);
+typedef prototype_subpixvariance(*vp8_subpixvariance_fn_t);
+typedef prototype_getmbss(*vp8_getmbss_fn_t);
+typedef struct
+{
+    vp8_sad_fn_t             sad4x4;
+    vp8_sad_fn_t             sad8x8;
+    vp8_sad_fn_t             sad8x16;
+    vp8_sad_fn_t             sad16x8;
+    vp8_sad_fn_t             sad16x16;
+
+    vp8_variance_fn_t        var4x4;
+    vp8_variance_fn_t        var8x8;
+    vp8_variance_fn_t        var8x16;
+    vp8_variance_fn_t        var16x8;
+    vp8_variance_fn_t        var16x16;
+
+    vp8_subpixvariance_fn_t  subpixvar4x4;
+    vp8_subpixvariance_fn_t  subpixvar8x8;
+    vp8_subpixvariance_fn_t  subpixvar8x16;
+    vp8_subpixvariance_fn_t  subpixvar16x8;
+    vp8_subpixvariance_fn_t  subpixvar16x16;
+    vp8_subpixvariance_fn_t  subpixmse16x16;
+
+    vp8_getmbss_fn_t         getmbss;
+    vp8_variance_fn_t        mse16x16;
+
+    vp8_sad_fn_t             get16x16prederror;
+    vp8_variance2_fn_t       get8x8var;
+    vp8_variance2_fn_t       get16x16var;
+    vp8_sad_fn_t             get4x4sse_cs;
+
+    vp8_sad_multi_fn_t       sad16x16x3;
+    vp8_sad_multi_fn_t       sad16x8x3;
+    vp8_sad_multi_fn_t       sad8x16x3;
+    vp8_sad_multi_fn_t       sad8x8x3;
+    vp8_sad_multi_fn_t       sad4x4x3;
+
+    vp8_sad_multi_d_fn_t     sad16x16x4d;
+    vp8_sad_multi_d_fn_t     sad16x8x4d;
+    vp8_sad_multi_d_fn_t     sad8x16x4d;
+    vp8_sad_multi_d_fn_t     sad8x8x4d;
+    vp8_sad_multi_d_fn_t     sad4x4x4d;
+
+} vp8_variance_rtcd_vtable_t;
+
+typedef struct
+{
+    vp8_sad_fn_t  sdf;
+    vp8_sad_multi_fn_t sdx3f;
+    vp8_sad_multi_d_fn_t sdx4df;
+    vp8_variance_fn_t vf;
+    vp8_subpixvariance_fn_t svf;
+} vp8_variance_fn_ptr_t;
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#define VARIANCE_INVOKE(ctx,fn) (ctx)->fn
+#else
+#define VARIANCE_INVOKE(ctx,fn) vp8_variance_##fn
+#endif
+
+/* TODO: Determine if this USEBILINEAR flag is necessary. */
+#define USEBILINEAR
+
+#endif
diff --git a/vp8/encoder/variance_c.c b/vp8/encoder/variance_c.c
new file mode 100644 (file)
index 0000000..85269b9
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "variance.h"
+
+const int vp8_six_tap[8][6] =
+{
+    { 0,  0,  128,    0,   0,  0 },         // note that 1/8 pel positions are just as per alpha -0.5 bicubic
+    { 0, -6,  123,   12,  -1,  0 },
+    { 2, -11, 108,   36,  -8,  1 },         // New 1/4 pel 6 tap filter
+    { 0, -9,   93,   50,  -6,  0 },
+    { 3, -16,  77,   77, -16,  3 },         // New 1/2 pel 6 tap filter
+    { 0, -6,   50,   93,  -9,  0 },
+    { 1, -8,   36,  108, -11,  2 },         // New 1/4 pel 6 tap filter
+    { 0, -1,   12,  123,  -6,  0 }
+};
+
+
+#ifdef USEBILINEAR
+const int VP8_FILTER_WEIGHT = 128;
+const int VP8_FILTER_SHIFT  =   7;
+const int vp8_bilinear_taps[8][2] =
+{
+    { 128,   0 },
+    { 112,  16 },
+    {  96,  32 },
+    {  80,  48 },
+    {  64,  64 },
+    {  48,  80 },
+    {  32,  96 },
+    {  16, 112 }
+};
+
+unsigned int vp8_get_mb_ss_c
+(
+    short *src_ptr
+)
+{
+    unsigned int i = 0, sum = 0;
+
+    do
+    {
+        sum += (src_ptr[i] * src_ptr[i]);
+        i++;
+    }
+    while (i < 256);
+
+    return sum;
+}
+
+
+void  vp8_variance(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    int  w,
+    int  h,
+    unsigned int *sse,
+    int *sum)
+{
+    int i, j;
+    int diff;
+
+    *sum = 0;
+    *sse = 0;
+
+    for (i = 0; i < h; i++)
+    {
+        for (j = 0; j < w; j++)
+        {
+            diff = src_ptr[j] - ref_ptr[j];
+            *sum += diff;
+            *sse += diff * diff;
+        }
+
+        src_ptr += source_stride;
+        ref_ptr += recon_stride;
+    }
+}
+
+unsigned int
+vp8_get8x8var_c
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *SSE,
+    int *Sum
+)
+{
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 8, 8, SSE, Sum);
+    return (*SSE - (((*Sum) * (*Sum)) >> 6));
+}
+
+unsigned int
+vp8_get16x16var_c
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *SSE,
+    int *Sum
+)
+{
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, SSE, Sum);
+    return (*SSE - (((*Sum) * (*Sum)) >> 8));
+
+}
+
+
+
+unsigned int vp8_variance16x16_c(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, &var, &avg);
+    *sse = var;
+    return (var - ((avg * avg) >> 8));
+}
+
+unsigned int vp8_variance8x16_c(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 8, 16, &var, &avg);
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+}
+
+unsigned int vp8_variance16x8_c(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 8, &var, &avg);
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+}
+
+
+unsigned int vp8_variance8x8_c(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 8, 8, &var, &avg);
+    *sse = var;
+    return (var - ((avg * avg) >> 6));
+}
+
+unsigned int vp8_variance4x4_c(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 4, 4, &var, &avg);
+    *sse = var;
+    return (var - ((avg * avg) >> 4));
+}
+
+
+unsigned int vp8_mse16x16_c(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+    vp8_variance(src_ptr, source_stride, ref_ptr, recon_stride, 16, 16, &var, &avg);
+    *sse = var;
+    return var;
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : filter_block2d_bil_first_pass
+ *
+ *  INPUTS        : UINT8  *src_ptr          : Pointer to source block.
+ *                  UINT32 src_pixels_per_line : Stride of input block.
+ *                  UINT32 pixel_step        : Offset between filter input samples (see notes).
+ *                  UINT32 output_height     : Input block height.
+ *                  UINT32 output_width      : Input block width.
+ *                  INT32  *vp8_filter          : Array of 2 bi-linear filter taps.
+ *
+ *  OUTPUTS       : INT32 *output_ptr        : Pointer to filtered block.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
+ *                  either horizontal or vertical direction to produce the
+ *                  filtered output block. Used to implement first-pass
+ *                  of 2-D separable filter.
+ *
+ *  SPECIAL NOTES : Produces INT32 output to retain precision for next pass.
+ *                  Two filter taps should sum to VP8_FILTER_WEIGHT.
+ *                  pixel_step defines whether the filter is applied
+ *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
+ *                  It defines the offset required to move from one input
+ *                  to the next.
+ *
+ ****************************************************************************/
+void vp8e_filter_block2d_bil_first_pass
+(
+    unsigned char *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int src_pixels_per_line,
+    int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    const int *vp8_filter
+)
+{
+    unsigned int i, j;
+
+    for (i = 0; i < output_height; i++)
+    {
+        for (j = 0; j < output_width; j++)
+        {
+            // Apply bilinear filter
+            output_ptr[j] = (((int)src_ptr[0]          * vp8_filter[0]) +
+                             ((int)src_ptr[pixel_step] * vp8_filter[1]) +
+                             (VP8_FILTER_WEIGHT / 2)) >> VP8_FILTER_SHIFT;
+            src_ptr++;
+        }
+
+        // Next row...
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_width;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : filter_block2d_bil_second_pass
+ *
+ *  INPUTS        : INT32  *src_ptr          : Pointer to source block.
+ *                  UINT32 src_pixels_per_line : Stride of input block.
+ *                  UINT32 pixel_step        : Offset between filter input samples (see notes).
+ *                  UINT32 output_height     : Input block height.
+ *                  UINT32 output_width      : Input block width.
+ *                  INT32  *vp8_filter          : Array of 2 bi-linear filter taps.
+ *
+ *  OUTPUTS       : UINT16 *output_ptr       : Pointer to filtered block.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
+ *                  either horizontal or vertical direction to produce the
+ *                  filtered output block. Used to implement second-pass
+ *                  of 2-D separable filter.
+ *
+ *  SPECIAL NOTES : Requires 32-bit input as produced by filter_block2d_bil_first_pass.
+ *                  Two filter taps should sum to VP8_FILTER_WEIGHT.
+ *                  pixel_step defines whether the filter is applied
+ *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
+ *                  It defines the offset required to move from one input
+ *                  to the next.
+ *
+ ****************************************************************************/
+void vp8e_filter_block2d_bil_second_pass
+(
+    unsigned short *src_ptr,
+    unsigned char  *output_ptr,
+    unsigned int  src_pixels_per_line,
+    unsigned int  pixel_step,
+    unsigned int  output_height,
+    unsigned int  output_width,
+    const int *vp8_filter
+)
+{
+    unsigned int  i, j;
+    int  Temp;
+
+    for (i = 0; i < output_height; i++)
+    {
+        for (j = 0; j < output_width; j++)
+        {
+            // Apply filter
+            Temp = ((int)src_ptr[0]         * vp8_filter[0]) +
+                   ((int)src_ptr[pixel_step] * vp8_filter[1]) +
+                   (VP8_FILTER_WEIGHT / 2);
+            output_ptr[j] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);
+            src_ptr++;
+        }
+
+        // Next row...
+        src_ptr    += src_pixels_per_line - output_width;
+        output_ptr += output_width;
+    }
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : filter_block2d_bil
+ *
+ *  INPUTS        : UINT8  *src_ptr          : Pointer to source block.
+ *                  UINT32 src_pixels_per_line : Stride of input block.
+ *                  INT32  *HFilter         : Array of 2 horizontal filter taps.
+ *                  INT32  *VFilter         : Array of 2 vertical filter taps.
+ *
+ *  OUTPUTS       : UINT16 *output_ptr       : Pointer to filtered block.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 2-D filters an 8x8 input block by applying a 2-tap
+ *                  bi-linear filter horizontally followed by a 2-tap
+ *                  bi-linear filter vertically on the result.
+ *
+ *  SPECIAL NOTES : The intermediate horizontally filtered block must produce
+ *                  1 more point than the input block in each column. This
+ *                  is to ensure that the 2-tap filter has one extra data-point
+ *                  at the top of each column so filter taps do not extend
+ *                  beyond data. Thus the output of the first stage filter
+ *                  is an 8x9 (hx_v) block.
+ *
+ ****************************************************************************/
+void vp8e_filter_block2d_bil
+(
+    unsigned char  *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int src_pixels_per_line,
+    int  *HFilter,
+    int  *VFilter
+)
+{
+
+    unsigned short FData[20*16];    // Temp data bufffer used in filtering
+
+    // First filter 1-D horizontally...
+    vp8e_filter_block2d_bil_first_pass(src_ptr, FData, src_pixels_per_line, 1, 9, 8, HFilter);
+
+    // then 1-D vertically...
+    vp8e_filter_block2d_bil_second_pass(FData, output_ptr, 8, 8, 8, 8, VFilter);
+}
+
+
+
+unsigned int vp8_sub_pixel_variance4x4_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    unsigned char  temp2[20*16];
+    const int *HFilter, *VFilter;
+    unsigned short FData3[5*4]; // Temp data bufffer used in filtering
+
+    HFilter = vp8_bilinear_taps[xoffset];
+    VFilter = vp8_bilinear_taps[yoffset];
+
+    // First filter 1d Horizontal
+    vp8e_filter_block2d_bil_first_pass(src_ptr, FData3, src_pixels_per_line, 1, 5, 4, HFilter);
+
+    // Now filter Verticaly
+    vp8e_filter_block2d_bil_second_pass(FData3, temp2, 4,  4,  4,  4, VFilter);
+
+    return vp8_variance4x4_c(temp2, 4, dst_ptr, dst_pixels_per_line, sse);
+}
+
+
+unsigned int vp8_sub_pixel_variance8x8_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    unsigned short FData3[9*8]; // Temp data bufffer used in filtering
+    unsigned char  temp2[20*16];
+    const int *HFilter, *VFilter;
+
+    HFilter = vp8_bilinear_taps[xoffset];
+    VFilter = vp8_bilinear_taps[yoffset];
+
+    vp8e_filter_block2d_bil_first_pass(src_ptr, FData3, src_pixels_per_line, 1, 9, 8, HFilter);
+    vp8e_filter_block2d_bil_second_pass(FData3, temp2, 8, 8, 8, 8, VFilter);
+
+    return vp8_variance8x8_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse);
+}
+
+unsigned int vp8_sub_pixel_variance16x16_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    unsigned short FData3[17*16];   // Temp data bufffer used in filtering
+    unsigned char  temp2[20*16];
+    const int *HFilter, *VFilter;
+
+    HFilter = vp8_bilinear_taps[xoffset];
+    VFilter = vp8_bilinear_taps[yoffset];
+
+    vp8e_filter_block2d_bil_first_pass(src_ptr, FData3, src_pixels_per_line, 1, 17, 16, HFilter);
+    vp8e_filter_block2d_bil_second_pass(FData3, temp2, 16, 16, 16, 16, VFilter);
+
+    return vp8_variance16x16_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse);
+}
+
+unsigned int vp8_sub_pixel_mse16x16_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    vp8_sub_pixel_variance16x16_c(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
+    return *sse;
+}
+
+unsigned int vp8_sub_pixel_variance16x8_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    unsigned short FData3[16*9];    // Temp data bufffer used in filtering
+    unsigned char  temp2[20*16];
+    const int *HFilter, *VFilter;
+
+    HFilter = vp8_bilinear_taps[xoffset];
+    VFilter = vp8_bilinear_taps[yoffset];
+
+    vp8e_filter_block2d_bil_first_pass(src_ptr, FData3, src_pixels_per_line, 1, 9, 16, HFilter);
+    vp8e_filter_block2d_bil_second_pass(FData3, temp2, 16, 16, 8, 16, VFilter);
+
+    return vp8_variance16x8_c(temp2, 16, dst_ptr, dst_pixels_per_line, sse);
+}
+
+unsigned int vp8_sub_pixel_variance8x16_c
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    unsigned short FData3[9*16];    // Temp data bufffer used in filtering
+    unsigned char  temp2[20*16];
+    const int *HFilter, *VFilter;
+
+
+    HFilter = vp8_bilinear_taps[xoffset];
+    VFilter = vp8_bilinear_taps[yoffset];
+
+
+    vp8e_filter_block2d_bil_first_pass(src_ptr, FData3, src_pixels_per_line, 1, 17, 8, HFilter);
+    vp8e_filter_block2d_bil_second_pass(FData3, temp2, 8, 8, 16, 8, VFilter);
+
+    return vp8_variance8x16_c(temp2, 8, dst_ptr, dst_pixels_per_line, sse);
+}
+#endif
diff --git a/vp8/encoder/x86/csystemdependent.c b/vp8/encoder/x86/csystemdependent.c
new file mode 100644 (file)
index 0000000..186ee68
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "variance.h"
+#include "onyx_int.h"
+
+SADFunction *vp8_sad16x16;
+SADFunction *vp8_sad16x8;
+SADFunction *vp8_sad8x16;
+SADFunction *vp8_sad8x8;
+SADFunction *vp8_sad4x4;
+
+variance_function *vp8_variance4x4;
+variance_function *vp8_variance8x8;
+variance_function *vp8_variance8x16;
+variance_function *vp8_variance16x8;
+variance_function *vp8_variance16x16;
+
+
+variance_function *vp8_mse16x16;
+
+sub_pixel_variance_function *vp8_sub_pixel_variance4x4;
+sub_pixel_variance_function *vp8_sub_pixel_variance8x8;
+sub_pixel_variance_function *vp8_sub_pixel_variance8x16;
+sub_pixel_variance_function *vp8_sub_pixel_variance16x8;
+sub_pixel_variance_function *vp8_sub_pixel_variance16x16;
+
+int (*vp8_block_error)(short *, short *);
+int (*vp8_mbblock_error)(MACROBLOCK *mb, int dc);
+void (*vp8_subtract_mby)(short *diff, unsigned char *src, unsigned char *pred, int stride);
+
+extern void vp8_subtract_mby_c(short *diff, unsigned char *src, unsigned char *pred, int stride);
+extern void vp8_subtract_mby_mmx(short *diff, unsigned char *src, unsigned char *pred, int stride);
+
+extern int vp8_block_error_c(short *, short *);
+extern int vp8_mbblock_error_c(MACROBLOCK *x, int dc);
+
+extern int vp8_block_error_mmx(short *, short *);
+extern int vp8_mbblock_error_mmx(MACROBLOCK *x, int dc);
+
+extern int vp8_block_error_xmm(short *, short *);
+extern int vp8_mbblock_error_xmm(MACROBLOCK *x, int dc);
+
+
+
+int (*vp8_mbuverror)(MACROBLOCK *mb);
+unsigned int (*vp8_get_mb_ss)(short *);
+void (*vp8_short_fdct4x4)(short *input, short *output, int pitch);
+void (*vp8_short_fdct8x4)(short *input, short *output, int pitch);
+void (*vp8_fast_fdct4x4)(short *input, short *output, int pitch);
+void (*vp8_fast_fdct8x4)(short *input, short *output, int pitch);
+
+void (*vp8_subtract_b)(BLOCK *be, BLOCKD *bd, int pitch);
+void (*vp8_subtract_mbuv)(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride);
+void (*vp8_fast_quantize_b)(BLOCK *b, BLOCKD *d);
+unsigned int (*vp8_get16x16pred_error)(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+unsigned int (*vp8_get8x8var)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+unsigned int (*vp8_get16x16var)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+unsigned int (*vp8_get4x4sse_cs)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
+
+// c imports
+extern int vp8_mbuverror_c(MACROBLOCK *mb);
+extern unsigned int vp8_get8x8var_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern void vp8_short_fdct4x4_c(short *input, short *output, int pitch);
+extern void vp8_short_fdct8x4_c(short *input, short *output, int pitch);
+extern void vp8_fast_fdct4x4_c(short *input, short *output, int pitch);
+extern void vp8_fast_fdct8x4_c(short *input, short *output, int pitch);
+
+
+extern void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch);
+extern void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride);
+extern void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d);
+
+extern SADFunction vp8_sad16x16_c;
+extern SADFunction vp8_sad16x8_c;
+extern SADFunction vp8_sad8x16_c;
+extern SADFunction vp8_sad8x8_c;
+extern SADFunction vp8_sad4x4_c;
+
+extern SADFunction vp8_sad16x16_wmt;
+extern SADFunction vp8_sad16x8_wmt;
+extern SADFunction vp8_sad8x16_wmt;
+extern SADFunction vp8_sad8x8_wmt;
+extern SADFunction vp8_sad4x4_wmt;
+
+extern SADFunction vp8_sad16x16_mmx;
+extern SADFunction vp8_sad16x8_mmx;
+extern SADFunction vp8_sad8x16_mmx;
+extern SADFunction vp8_sad8x8_mmx;
+extern SADFunction vp8_sad4x4_mmx;
+
+extern variance_function vp8_variance16x16_c;
+extern variance_function vp8_variance8x16_c;
+extern variance_function vp8_variance16x8_c;
+extern variance_function vp8_variance8x8_c;
+extern variance_function vp8_variance4x4_c;
+extern variance_function vp8_mse16x16_c;
+
+extern sub_pixel_variance_function vp8_sub_pixel_variance4x4_c;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x8_c;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x16_c;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x8_c;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x16_c;
+
+extern unsigned int vp8_get_mb_ss_c(short *);
+extern unsigned int vp8_get16x16pred_error_c(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+extern unsigned int vp8_get8x8var_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get16x16var_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get4x4sse_cs_c(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
+
+// mmx imports
+extern int vp8_mbuverror_mmx(MACROBLOCK *mb);
+extern void vp8_fast_quantize_b_mmx(BLOCK *b, BLOCKD *d);
+extern void vp8_subtract_b_mmx(BLOCK *be, BLOCKD *bd, int pitch);
+extern void vp8_subtract_mbuv_mmx(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride);
+extern void vp8_short_fdct4x4_mmx(short *input, short *output, int pitch);
+extern void vp8_short_fdct8x4_mmx(short *input, short *output, int pitch);
+extern void vp8_fast_fdct8x4_mmx(short *input, short *output, int pitch);
+extern void vp8_fast_fdct4x4_mmx(short *input, short *output, int pitch);
+extern variance_function vp8_variance4x4_mmx;
+extern variance_function vp8_variance8x8_mmx;
+extern variance_function vp8_variance8x16_mmx;
+extern variance_function vp8_variance16x8_mmx;
+extern variance_function vp8_variance16x16_mmx;
+
+extern variance_function vp8_mse16x16_mmx;
+extern sub_pixel_variance_function vp8_sub_pixel_variance4x4_mmx;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x8_mmx;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x16_mmx;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x8_mmx;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x16_mmx;
+
+extern unsigned int vp8_get16x16pred_error_mmx(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+extern unsigned int vp8_get_mb_ss_mmx(short *);
+extern unsigned int vp8_get8x8var_mmx(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get16x16var_mmx(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get4x4sse_cs_mmx(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
+
+
+// wmt imports
+extern int vp8_mbuverror_xmm(MACROBLOCK *mb);
+extern void vp8_fast_quantize_b_sse(BLOCK *b, BLOCKD *d);
+extern void vp8_fast_fdct8x4_wmt(short *input, short *output, int pitch);
+extern variance_function vp8_variance4x4_wmt;
+extern variance_function vp8_variance8x8_wmt;
+extern variance_function vp8_variance8x16_wmt;
+extern variance_function vp8_variance16x8_wmt;
+extern variance_function vp8_variance16x16_wmt;
+
+extern variance_function vp8_mse16x16_wmt;
+extern sub_pixel_variance_function vp8_sub_pixel_variance4x4_wmt;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x8_wmt;
+extern sub_pixel_variance_function vp8_sub_pixel_variance8x16_wmt;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x8_wmt;
+extern sub_pixel_variance_function vp8_sub_pixel_variance16x16_wmt;
+extern unsigned int vp8_get16x16pred_error_sse2(unsigned char *src_ptr, int src_stride, unsigned char *ref_ptr, int ref_stride);
+extern unsigned int vp8_get_mb_ss_sse2(short *src_ptr);
+extern unsigned int vp8_get8x8var_sse2(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+extern unsigned int vp8_get16x16var_sse2(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride, unsigned int *SSE, int *Sum);
+
+extern void vpx_get_processor_flags(int *mmx_enabled, int *xmm_enabled, int *wmt_enabled);
+
+void vp8_cmachine_specific_config(void)
+{
+    int mmx_enabled;
+    int xmm_enabled;
+    int wmt_enabled;
+
+    vpx_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled);
+
+    if (wmt_enabled)         // Willamette
+    {
+        // Willamette instruction set available:
+        vp8_mbuverror                = vp8_mbuverror_xmm;
+        vp8_fast_quantize_b            = vp8_fast_quantize_b_sse;
+        vp8_short_fdct4x4             = vp8_short_fdct4x4_mmx;
+        vp8_short_fdct8x4             = vp8_short_fdct8x4_mmx;
+        vp8_fast_fdct4x4              = vp8_fast_fdct4x4_mmx;
+        vp8_fast_fdct8x4              = vp8_fast_fdct8x4_wmt;
+        vp8_subtract_b                = vp8_subtract_b_mmx;
+        vp8_subtract_mbuv             = vp8_subtract_mbuv_mmx;
+        vp8_variance4x4              = vp8_variance4x4_mmx;
+        vp8_variance8x8              = vp8_variance8x8_mmx;
+        vp8_variance8x16             = vp8_variance8x16_wmt;
+        vp8_variance16x8             = vp8_variance16x8_wmt;
+        vp8_variance16x16            = vp8_variance16x16_wmt;
+        vp8_mse16x16                 = vp8_mse16x16_wmt;
+        vp8_sub_pixel_variance4x4      = vp8_sub_pixel_variance4x4_wmt;
+        vp8_sub_pixel_variance8x8      = vp8_sub_pixel_variance8x8_wmt;
+        vp8_sub_pixel_variance8x16     = vp8_sub_pixel_variance8x16_wmt;
+        vp8_sub_pixel_variance16x8     = vp8_sub_pixel_variance16x8_wmt;
+        vp8_sub_pixel_variance16x16    = vp8_sub_pixel_variance16x16_wmt;
+        vp8_get_mb_ss                  = vp8_get_mb_ss_sse2;
+        vp8_get16x16pred_error        = vp8_get16x16pred_error_sse2;
+        vp8_get8x8var                = vp8_get8x8var_sse2;
+        vp8_get16x16var              = vp8_get16x16var_sse2;
+        vp8_get4x4sse_cs             = vp8_get4x4sse_cs_mmx;
+        vp8_sad16x16                 = vp8_sad16x16_wmt;
+        vp8_sad16x8                  = vp8_sad16x8_wmt;
+        vp8_sad8x16                  = vp8_sad8x16_wmt;
+        vp8_sad8x8                   = vp8_sad8x8_wmt;
+        vp8_sad4x4                   = vp8_sad4x4_wmt;
+        vp8_block_error               = vp8_block_error_xmm;
+        vp8_mbblock_error             = vp8_mbblock_error_xmm;
+        vp8_subtract_mby              = vp8_subtract_mby_mmx;
+
+    }
+    else if (mmx_enabled)
+    {
+        // MMX instruction set available:
+        vp8_mbuverror                = vp8_mbuverror_mmx;
+        vp8_fast_quantize_b            = vp8_fast_quantize_b_mmx;
+        vp8_short_fdct4x4             = vp8_short_fdct4x4_mmx;
+        vp8_short_fdct8x4             = vp8_short_fdct8x4_mmx;
+        vp8_fast_fdct4x4              = vp8_fast_fdct4x4_mmx;
+        vp8_fast_fdct8x4              = vp8_fast_fdct8x4_mmx;
+        vp8_subtract_b                = vp8_subtract_b_mmx;
+        vp8_subtract_mbuv             = vp8_subtract_mbuv_mmx;
+        vp8_variance4x4              = vp8_variance4x4_mmx;
+        vp8_variance8x8              = vp8_variance8x8_mmx;
+        vp8_variance8x16             = vp8_variance8x16_mmx;
+        vp8_variance16x8             = vp8_variance16x8_mmx;
+        vp8_variance16x16            = vp8_variance16x16_mmx;
+        vp8_mse16x16                 = vp8_mse16x16_mmx;
+        vp8_sub_pixel_variance4x4      = vp8_sub_pixel_variance4x4_mmx;
+        vp8_sub_pixel_variance8x8      = vp8_sub_pixel_variance8x8_mmx;
+        vp8_sub_pixel_variance8x16     = vp8_sub_pixel_variance8x16_mmx;
+        vp8_sub_pixel_variance16x8     = vp8_sub_pixel_variance16x8_mmx;
+        vp8_sub_pixel_variance16x16    = vp8_sub_pixel_variance16x16_mmx;
+        vp8_get_mb_ss                  = vp8_get_mb_ss_mmx;
+        vp8_get16x16pred_error        = vp8_get16x16pred_error_mmx;
+        vp8_get8x8var                = vp8_get8x8var_mmx;
+        vp8_get16x16var              = vp8_get16x16var_mmx;
+        vp8_get4x4sse_cs             = vp8_get4x4sse_cs_mmx;
+        vp8_sad16x16                 = vp8_sad16x16_mmx;
+        vp8_sad16x8                  = vp8_sad16x8_mmx;
+        vp8_sad8x16                  = vp8_sad8x16_mmx;
+        vp8_sad8x8                   = vp8_sad8x8_mmx;
+        vp8_sad4x4                   = vp8_sad4x4_mmx;
+        vp8_block_error               = vp8_block_error_mmx;
+        vp8_mbblock_error             = vp8_mbblock_error_mmx;
+        vp8_subtract_mby              = vp8_subtract_mby_mmx;
+
+    }
+    else
+    {
+        // Pure C:
+        vp8_mbuverror                = vp8_mbuverror_c;
+        vp8_fast_quantize_b            = vp8_fast_quantize_b_c;
+        vp8_short_fdct4x4             = vp8_short_fdct4x4_c;
+        vp8_short_fdct8x4             = vp8_short_fdct8x4_c;
+        vp8_fast_fdct4x4              = vp8_fast_fdct4x4_c;
+        vp8_fast_fdct8x4              = vp8_fast_fdct8x4_c;
+        vp8_subtract_b                = vp8_subtract_b_c;
+        vp8_subtract_mbuv             = vp8_subtract_mbuv_c;
+        vp8_variance4x4              = vp8_variance4x4_c;
+        vp8_variance8x8              = vp8_variance8x8_c;
+        vp8_variance8x16             = vp8_variance8x16_c;
+        vp8_variance16x8             = vp8_variance16x8_c;
+        vp8_variance16x16            = vp8_variance16x16_c;
+        vp8_mse16x16                 = vp8_mse16x16_c;
+        vp8_sub_pixel_variance4x4      = vp8_sub_pixel_variance4x4_c;
+        vp8_sub_pixel_variance8x8      = vp8_sub_pixel_variance8x8_c;
+        vp8_sub_pixel_variance8x16     = vp8_sub_pixel_variance8x16_c;
+        vp8_sub_pixel_variance16x8     = vp8_sub_pixel_variance16x8_c;
+        vp8_sub_pixel_variance16x16    = vp8_sub_pixel_variance16x16_c;
+        vp8_get_mb_ss                  = vp8_get_mb_ss_c;
+        vp8_get16x16pred_error        = vp8_get16x16pred_error_c;
+        vp8_get8x8var                = vp8_get8x8var_c;
+        vp8_get16x16var              = vp8_get16x16var_c;
+        vp8_get4x4sse_cs             = vp8_get4x4sse_cs_c;
+        vp8_sad16x16                 = vp8_sad16x16_c;
+        vp8_sad16x8                  = vp8_sad16x8_c;
+        vp8_sad8x16                  = vp8_sad8x16_c;
+        vp8_sad8x8                   = vp8_sad8x8_c;
+        vp8_sad4x4                   = vp8_sad4x4_c;
+        vp8_block_error               = vp8_block_error_c;
+        vp8_mbblock_error             = vp8_mbblock_error_c;
+        vp8_subtract_mby              = vp8_subtract_mby_c;
+    }
+
+}
diff --git a/vp8/encoder/x86/dct_mmx.asm b/vp8/encoder/x86/dct_mmx.asm
new file mode 100644 (file)
index 0000000..e134237
--- /dev/null
@@ -0,0 +1,846 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+section .text
+    global sym(vp8_short_fdct4x4_mmx)
+    global sym(vp8_fast_fdct4x4_mmx)
+    global sym(vp8_fast_fdct8x4_wmt)
+
+
+%define         DCTCONSTANTSBITS         (16)
+%define         DCTROUNDINGVALUE         (1<< (DCTCONSTANTSBITS-1))
+%define         x_c1                      (60547)          ; cos(pi  /8) * (1<<15)
+%define         x_c2                      (46341)          ; cos(pi*2/8) * (1<<15)
+%define         x_c3                      (25080)          ; cos(pi*3/8) * (1<<15)
+
+
+%define _1STSTAGESHIFT           14
+%define _2NDSTAGESHIFT           16
+
+; using matrix multiply with source and destbuffer has a pitch
+;void vp8_short_fdct4x4_mmx(short *input, short *output, int pitch)
+sym(vp8_short_fdct4x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    ; end prolog
+
+        mov         rsi,    arg(0) ;input
+        mov         rdi,    arg(1) ;output
+
+        movsxd      rax,    dword ptr arg(2) ;pitch
+        lea         rdx,    [dct_matrix GLOBAL]
+
+        movq        mm0,    [rsi   ]
+        movq        mm1,    [rsi + rax]
+
+        movq        mm2,    [rsi + rax*2]
+        lea         rsi,    [rsi + rax*2]
+
+        movq        mm3,    [rsi + rax]
+
+        ; first column
+        movq        mm4,    mm0
+        movq        mm7,    [rdx]
+
+        pmaddwd     mm4,    mm7
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    mm7
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+
+        pmaddwd     mm5,    mm7
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    mm7
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct1st_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _1STSTAGESHIFT
+        psrad       mm5,    _1STSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi],  mm4
+
+        ;second column
+        movq        mm4,    mm0
+
+        pmaddwd     mm4,    [rdx+8]
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    [rdx+8]
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+        pmaddwd     mm5,    [rdx+8]
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    [rdx+8]
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct1st_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _1STSTAGESHIFT
+        psrad       mm5,    _1STSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi+8],  mm4
+
+
+        ;third column
+        movq        mm4,    mm0
+
+        pmaddwd     mm4,    [rdx+16]
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    [rdx+16]
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+        pmaddwd     mm5,    [rdx+16]
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    [rdx+16]
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct1st_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _1STSTAGESHIFT
+        psrad       mm5,    _1STSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi+16],  mm4
+
+        ;fourth column (this is the last column, so we do not have save the source any more)
+
+        pmaddwd     mm0,    [rdx+24]
+
+        pmaddwd     mm1,    [rdx+24]
+        movq        mm6,    mm0
+
+        punpckldq   mm0,    mm1
+        punpckhdq   mm6,    mm1
+
+        paddd       mm0,    mm6
+
+        pmaddwd     mm2,    [rdx+24]
+
+        pmaddwd     mm3,    [rdx+24]
+        movq        mm7,    mm2
+
+        punpckldq   mm2,    mm3
+        punpckhdq   mm7,    mm3
+
+        paddd       mm2,    mm7
+        movq        mm6,    [dct1st_stage_rounding_mmx GLOBAL]
+
+        paddd       mm0,    mm6
+        paddd       mm2,    mm6
+
+        psrad       mm0,    _1STSTAGESHIFT
+        psrad       mm2,    _1STSTAGESHIFT
+
+        packssdw    mm0,    mm2
+
+        movq        mm3,    mm0
+
+        ; done with one pass
+        ; now start second pass
+        movq        mm0,    [rdi   ]
+        movq        mm1,    [rdi+ 8]
+        movq        mm2,    [rdi+ 16]
+
+        movq        mm4,    mm0
+
+        pmaddwd     mm4,    [rdx]
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    [rdx]
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+        pmaddwd     mm5,    [rdx]
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    [rdx]
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct2nd_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _2NDSTAGESHIFT
+        psrad       mm5,    _2NDSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi],  mm4
+
+        ;second column
+        movq        mm4,    mm0
+
+        pmaddwd     mm4,    [rdx+8]
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    [rdx+8]
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+        pmaddwd     mm5,    [rdx+8]
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    [rdx+8]
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct2nd_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _2NDSTAGESHIFT
+        psrad       mm5,    _2NDSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi+8],  mm4
+
+
+        ;third column
+        movq        mm4,    mm0
+
+        pmaddwd     mm4,    [rdx+16]
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    [rdx+16]
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+        pmaddwd     mm5,    [rdx+16]
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    [rdx+16]
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct2nd_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _2NDSTAGESHIFT
+        psrad       mm5,    _2NDSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi+16],  mm4
+
+        ;fourth column
+        movq        mm4,    mm0
+
+        pmaddwd     mm4,    [rdx+24]
+        movq        mm5,    mm1
+
+        pmaddwd     mm5,    [rdx+24]
+        movq        mm6,    mm4
+
+        punpckldq   mm4,    mm5
+        punpckhdq   mm6,    mm5
+
+        paddd       mm4,    mm6
+        movq        mm5,    mm2
+
+        pmaddwd     mm5,    [rdx+24]
+        movq        mm6,    mm3
+
+        pmaddwd     mm6,    [rdx+24]
+        movq        mm7,    mm5
+
+        punpckldq   mm5,    mm6
+        punpckhdq   mm7,    mm6
+
+        paddd       mm5,    mm7
+        movq        mm6,    [dct2nd_stage_rounding_mmx GLOBAL]
+
+        paddd       mm4,    mm6
+        paddd       mm5,    mm6
+
+        psrad       mm4,    _2NDSTAGESHIFT
+        psrad       mm5,    _2NDSTAGESHIFT
+
+        packssdw    mm4,    mm5
+        movq        [rdi+24],  mm4
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_fast_fdct4x4_mmx(short *input, short *output, int pitch)
+sym(vp8_fast_fdct4x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    ; end prolog
+        mov     rsi,    arg(0) ;input
+        mov     rdi,    arg(1) ;output
+
+        lea     rdx,    [dct_const_mmx GLOBAL]
+        movsxd  rax,    dword ptr arg(2) ;pitch
+
+        lea     rcx,    [rsi + rax*2]
+        ; read the input data
+        movq    mm0,    [rsi]
+        movq    mm1,    [rsi + rax    ]
+
+        movq    mm2,    [rcx]
+        movq    mm3,    [rcx + rax]
+        ; get the constants
+        ;shift to left by 1 for prescision
+        paddw   mm0,    mm0
+        paddw   mm1,    mm1
+
+        psllw   mm2,    1
+        psllw   mm3,    1
+
+        ; transpose for the second stage
+        movq    mm4,    mm0         ; 00 01 02 03
+        movq    mm5,    mm2         ; 10 11 12 03
+
+        punpcklwd   mm0,    mm1     ; 00 10 01 11
+        punpckhwd   mm4,    mm1     ; 02 12 03 13
+
+        punpcklwd   mm2,    mm3     ; 20 30 21 31
+        punpckhwd   mm5,    mm3     ; 22 32 23 33
+
+
+        movq        mm1,    mm0     ; 00 10 01 11
+        punpckldq   mm0,    mm2     ; 00 10 20 30
+
+        punpckhdq   mm1,    mm2     ; 01 11 21 31
+
+        movq        mm2,    mm4     ; 02 12 03 13
+        punpckldq   mm2,    mm5     ; 02 12 22 32
+
+        punpckhdq   mm4,    mm5     ; 03 13 23 33
+        movq        mm3,    mm4
+
+
+        ; first stage
+        movq    mm5,    mm0
+        movq    mm4,    mm1
+
+        paddw   mm0,    mm3         ; a = 0 + 3
+        paddw   mm1,    mm2         ; b = 1 + 2
+
+        psubw   mm4,    mm2         ; c = 1 - 2
+        psubw   mm5,    mm3         ; d = 0 - 3
+
+
+        ; output 0 and 2
+        movq    mm6,    [rdx +  16] ; c2
+        movq    mm2,    mm0         ; a
+
+        paddw   mm0,    mm1         ; a + b
+        psubw   mm2,    mm1         ; a - b
+
+        movq    mm1,    mm0         ; a + b
+        pmulhw  mm0,    mm6         ; 00 01 02 03
+
+        paddw   mm0,    mm1         ; output 00 01 02 03
+        pmulhw  mm6,    mm2         ; 20 21 22 23
+
+        paddw   mm2,    mm6         ; output 20 21 22 23
+
+        ; output 1 and 3
+        movq    mm6,    [rdx +  8]  ; c1
+        movq    mm7,    [rdx + 24]  ; c3
+
+        movq    mm1,    mm4         ; c
+        movq    mm3,    mm5         ; d
+
+        pmulhw  mm1,    mm7         ; c * c3
+        pmulhw  mm3,    mm6         ; d * c1
+
+        paddw   mm3,    mm5         ; d * c1 rounded
+        paddw   mm1,    mm3         ; output 10 11 12 13
+
+        movq    mm3,    mm4         ; c
+        pmulhw  mm5,    mm7         ; d * c3
+
+        pmulhw  mm4,    mm6         ; c * c1
+        paddw   mm3,    mm4         ; round c* c1
+
+        psubw   mm5,    mm3         ; output 30 31 32 33
+        movq    mm3,    mm5
+
+
+        ; done with vertical
+        ; transpose for the second stage
+        movq    mm4,    mm0         ; 00 01 02 03
+        movq    mm5,    mm2         ; 10 11 12 03
+
+        punpcklwd   mm0,    mm1     ; 00 10 01 11
+        punpckhwd   mm4,    mm1     ; 02 12 03 13
+
+        punpcklwd   mm2,    mm3     ; 20 30 21 31
+        punpckhwd   mm5,    mm3     ; 22 32 23 33
+
+
+        movq        mm1,    mm0     ; 00 10 01 11
+        punpckldq   mm0,    mm2     ; 00 10 20 30
+
+        punpckhdq   mm1,    mm2     ; 01 11 21 31
+
+        movq        mm2,    mm4     ; 02 12 03 13
+        punpckldq   mm2,    mm5     ; 02 12 22 32
+
+        punpckhdq   mm4,    mm5     ; 03 13 23 33
+        movq        mm3,    mm4
+
+
+        ; first stage
+        movq    mm5,    mm0
+        movq    mm4,    mm1
+
+        paddw   mm0,    mm3         ; a = 0 + 3
+        paddw   mm1,    mm2         ; b = 1 + 2
+
+        psubw   mm4,    mm2         ; c = 1 - 2
+        psubw   mm5,    mm3         ; d = 0 - 3
+
+
+        ; output 0 and 2
+        movq    mm6,    [rdx +  16] ; c2
+        movq    mm2,    mm0         ; a
+        paddw   mm0,    mm1         ; a + b
+
+        psubw   mm2,    mm1         ; a - b
+
+        movq    mm1,    mm0         ; a + b
+        pmulhw  mm0,    mm6         ; 00 01 02 03
+
+        paddw   mm0,    mm1         ; output 00 01 02 03
+        pmulhw  mm6,    mm2         ; 20 21 22 23
+
+        paddw   mm2,    mm6         ; output 20 21 22 23
+
+
+        ; output 1 and 3
+        movq    mm6,    [rdx +  8]  ; c1
+        movq    mm7,    [rdx + 24]  ; c3
+
+        movq    mm1,    mm4         ; c
+        movq    mm3,    mm5         ; d
+
+        pmulhw  mm1,    mm7         ; c * c3
+        pmulhw  mm3,    mm6         ; d * c1
+
+        paddw   mm3,    mm5         ; d * c1 rounded
+        paddw   mm1,    mm3         ; output 10 11 12 13
+
+        movq    mm3,    mm4         ; c
+        pmulhw  mm5,    mm7         ; d * c3
+
+        pmulhw  mm4,    mm6         ; c * c1
+        paddw   mm3,    mm4         ; round c* c1
+
+        psubw   mm5,    mm3         ; output 30 31 32 33
+        movq    mm3,    mm5
+        ; done with vertical
+
+               pcmpeqw mm4,    mm4
+               pcmpeqw mm5,    mm5
+               psrlw   mm4,    15
+               psrlw   mm5,    15
+
+        paddw   mm0,    mm4
+        paddw   mm1,    mm5
+        paddw   mm2,    mm4
+        paddw   mm3,    mm5
+
+        psraw   mm0, 1
+        psraw   mm1, 1
+        psraw   mm2, 1
+        psraw   mm3, 1
+
+        movq        [rdi   ],   mm0
+        movq        [rdi+ 8],   mm1
+        movq        [rdi+16],   mm2
+        movq        [rdi+24],   mm3
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_fast_fdct8x4_wmt(short *input, short *output, int pitch)
+sym(vp8_fast_fdct8x4_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    ; end prolog
+        mov         rsi,    arg(0) ;input
+        mov         rdi,    arg(1) ;output
+
+        lea         rdx,    [dct_const_xmm GLOBAL]
+        movsxd      rax,    dword ptr arg(2) ;pitch
+
+        lea         rcx,    [rsi + rax*2]
+        ; read the input data
+        movdqa      xmm0,       [rsi]
+        movdqa      xmm2,       [rsi + rax]
+
+        movdqa      xmm4,       [rcx]
+        movdqa      xmm3,       [rcx + rax]
+        ; get the constants
+        ;shift to left by 1 for prescision
+        psllw       xmm0,        1
+        psllw       xmm2,        1
+
+        psllw       xmm4,        1
+        psllw       xmm3,        1
+
+        ; transpose for the second stage
+        movdqa      xmm1,       xmm0         ; 00 01 02 03 04 05 06 07
+        movdqa      xmm5,       xmm4         ; 20 21 22 23 24 25 26 27
+
+        punpcklwd   xmm0,       xmm2         ; 00 10 01 11 02 12 03 13
+        punpckhwd   xmm1,       xmm2         ; 04 14 05 15 06 16 07 17
+
+        punpcklwd   xmm4,       xmm3         ; 20 30 21 31 22 32 23 33
+        punpckhwd   xmm5,       xmm3         ; 24 34 25 35 26 36 27 37
+
+        movdqa      xmm2,       xmm0         ; 00 10 01 11 02 12 03 13
+        punpckldq   xmm0,       xmm4         ; 00 10 20 30 01 11 21 31
+
+        punpckhdq   xmm2,       xmm4         ; 02 12 22 32 03 13 23 33
+
+
+        movdqa      xmm4,       xmm1         ; 04 14 05 15 06 16 07 17
+        punpckldq   xmm4,       xmm5         ; 04 14 24 34 05 15 25 35
+
+        punpckhdq   xmm1,       xmm5         ; 06 16 26 36 07 17 27 37
+        movdqa      xmm3,       xmm2         ; 02 12 22 32 03 13 23 33
+
+        punpckhqdq  xmm3,       xmm1         ; 03 13 23 33 07 17 27 37
+        punpcklqdq  xmm2,       xmm1         ; 02 12 22 32 06 16 26 36
+
+        movdqa      xmm1,       xmm0         ; 00 10 20 30 01 11 21 31
+        punpcklqdq  xmm0,       xmm4         ; 00 10 20 30 04 14 24 34
+
+        punpckhqdq  xmm1,       xmm4         ; 01 11 21 32 05 15 25 35
+
+        ; xmm0 0
+        ; xmm1 1
+        ; xmm2 2
+        ; xmm3 3
+
+        ; first stage
+        movdqa      xmm5,       xmm0
+        movdqa      xmm4,       xmm1
+
+        paddw       xmm0,       xmm3         ; a = 0 + 3
+        paddw       xmm1,       xmm2         ; b = 1 + 2
+
+        psubw       xmm4,       xmm2         ; c = 1 - 2
+        psubw       xmm5,       xmm3         ; d = 0 - 3
+
+
+        ; output 0 and 2
+        movdqa      xmm6,       [rdx +  32] ; c2
+        movdqa      xmm2,       xmm0         ; a
+
+        paddw       xmm0,       xmm1         ; a + b
+        psubw       xmm2,       xmm1         ; a - b
+
+        movdqa      xmm1,       xmm0         ; a + b
+        pmulhw      xmm0,       xmm6         ; 00 01 02 03
+
+        paddw       xmm0,       xmm1         ; output 00 01 02 03
+        pmulhw      xmm6,       xmm2         ; 20 21 22 23
+
+        paddw       xmm2,       xmm6         ; output 20 21 22 23
+
+        ; output 1 and 3
+        movdqa      xmm6,       [rdx + 16]  ; c1
+        movdqa      xmm7,       [rdx + 48]  ; c3
+
+        movdqa      xmm1,       xmm4         ; c
+        movdqa      xmm3,       xmm5         ; d
+
+        pmulhw      xmm1,       xmm7         ; c * c3
+        pmulhw      xmm3,       xmm6         ; d * c1
+
+        paddw       xmm3,       xmm5         ; d * c1 rounded
+        paddw       xmm1,       xmm3         ; output 10 11 12 13
+
+        movdqa      xmm3,       xmm4         ; c
+        pmulhw      xmm5,       xmm7         ; d * c3
+
+        pmulhw      xmm4,       xmm6         ; c * c1
+        paddw       xmm3,       xmm4         ; round c* c1
+
+        psubw       xmm5,       xmm3         ; output 30 31 32 33
+        movdqa      xmm3,       xmm5
+
+
+        ; done with vertical
+        ; transpose for the second stage
+        movdqa      xmm4,       xmm2         ; 02 12 22 32 06 16 26 36
+        movdqa      xmm2,       xmm1         ; 01 11 21 31 05 15 25 35
+
+        movdqa      xmm1,       xmm0         ; 00 10 20 30 04 14 24 34
+        movdqa      xmm5,       xmm4         ; 02 12 22 32 06 16 26 36
+
+        punpcklwd   xmm0,       xmm2         ; 00 01 10 11 20 21 30 31
+        punpckhwd   xmm1,       xmm2         ; 04 05 14 15 24 25 34 35
+
+        punpcklwd   xmm4,       xmm3         ; 02 03 12 13 22 23 32 33
+        punpckhwd   xmm5,       xmm3         ; 06 07 16 17 26 27 36 37
+
+        movdqa      xmm2,       xmm0         ; 00 01 10 11 20 21 30 31
+        punpckldq   xmm0,       xmm4         ; 00 01 02 03 10 11 12 13
+
+        punpckhdq   xmm2,       xmm4         ; 20 21 22 23 30 31 32 33
+
+
+        movdqa      xmm4,       xmm1         ; 04 05 14 15 24 25 34 35
+        punpckldq   xmm4,       xmm5         ; 04 05 06 07 14 15 16 17
+
+        punpckhdq   xmm1,       xmm5         ; 24 25 26 27 34 35 36 37
+        movdqa      xmm3,       xmm2         ; 20 21 22 23 30 31 32 33
+
+        punpckhqdq  xmm3,       xmm1         ; 30 31 32 33 34 35 36 37
+        punpcklqdq  xmm2,       xmm1         ; 20 21 22 23 24 25 26 27
+
+        movdqa      xmm1,       xmm0         ; 00 01 02 03 10 11 12 13
+        punpcklqdq  xmm0,       xmm4         ; 00 01 02 03 04 05 06 07
+
+        punpckhqdq  xmm1,       xmm4         ; 10 11 12 13 14 15 16 17
+
+        ; first stage
+        movdqa      xmm5,       xmm0
+        movdqa      xmm4,       xmm1
+
+        paddw       xmm0,       xmm3         ; a = 0 + 3
+        paddw       xmm1,       xmm2         ; b = 1 + 2
+
+        psubw       xmm4,       xmm2         ; c = 1 - 2
+        psubw       xmm5,       xmm3         ; d = 0 - 3
+
+
+        ; output 0 and 2
+        movdqa      xmm6,       [rdx +  32] ; c2
+        movdqa      xmm2,       xmm0         ; a
+
+        paddw       xmm0,       xmm1         ; a + b
+        psubw       xmm2,       xmm1         ; a - b
+
+        movdqa      xmm1,       xmm0         ; a + b
+        pmulhw      xmm0,       xmm6         ; 00 01 02 03
+
+        paddw       xmm0,       xmm1         ; output 00 01 02 03
+        pmulhw      xmm6,       xmm2         ; 20 21 22 23
+
+        paddw       xmm2,       xmm6         ; output 20 21 22 23
+
+        ; output 1 and 3
+        movdqa      xmm6,       [rdx + 16]  ; c1
+        movdqa      xmm7,       [rdx + 48]  ; c3
+
+        movdqa      xmm1,       xmm4         ; c
+        movdqa      xmm3,       xmm5         ; d
+
+        pmulhw      xmm1,       xmm7         ; c * c3
+        pmulhw      xmm3,       xmm6         ; d * c1
+
+        paddw       xmm3,       xmm5         ; d * c1 rounded
+        paddw       xmm1,       xmm3         ; output 10 11 12 13
+
+        movdqa      xmm3,       xmm4         ; c
+        pmulhw      xmm5,       xmm7         ; d * c3
+
+        pmulhw      xmm4,       xmm6         ; c * c1
+        paddw       xmm3,       xmm4         ; round c* c1
+
+        psubw       xmm5,       xmm3         ; output 30 31 32 33
+        movdqa      xmm3,       xmm5
+        ; done with vertical
+
+
+        pcmpeqw                xmm4,           xmm4
+        pcmpeqw                xmm5,           xmm5;
+        psrlw          xmm4,           15
+        psrlw          xmm5,           15
+
+        paddw       xmm0,       xmm4
+        paddw       xmm1,       xmm5
+        paddw       xmm2,       xmm4
+        paddw       xmm3,       xmm5
+
+        psraw       xmm0,       1
+        psraw       xmm1,       1
+        psraw       xmm2,       1
+        psraw       xmm3,       1
+
+        movq        QWORD PTR[rdi   ],   xmm0
+        movq        QWORD PTR[rdi+ 8],   xmm1
+        movq        QWORD PTR[rdi+16],   xmm2
+        movq        QWORD PTR[rdi+24],   xmm3
+
+        psrldq      xmm0,       8
+        psrldq      xmm1,       8
+        psrldq      xmm2,       8
+        psrldq      xmm3,       8
+
+        movq        QWORD PTR[rdi+32],   xmm0
+        movq        QWORD PTR[rdi+40],   xmm1
+        movq        QWORD PTR[rdi+48],   xmm2
+        movq        QWORD PTR[rdi+56],   xmm3
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+;static const unsigned int dct1st_stage_rounding_mmx[2] =
+align 16
+dct1st_stage_rounding_mmx:
+    times 2 dd 8192
+
+
+;static const unsigned int dct2nd_stage_rounding_mmx[2] =
+align 16
+dct2nd_stage_rounding_mmx:
+    times 2 dd 32768
+
+
+;static const short dct_matrix[4][4]=
+align 16
+dct_matrix:
+    times 4 dw 23170
+
+    dw  30274
+    dw  12540
+    dw -12540
+    dw -30274
+
+    dw 23170
+    times 2 dw -23170
+    dw 23170
+
+    dw  12540
+    dw -30274
+    dw  30274
+    dw -12540
+
+
+;static const unsigned short dct_const_mmx[4 * 4]=
+align 16
+dct_const_mmx:
+    times 4 dw 0
+    times 4 dw 60547
+    times 4 dw 46341
+    times 4 dw 25080
+
+
+;static const unsigned short dct_const_xmm[8 * 4]=
+align 16
+dct_const_xmm:
+    times 8 dw 0
+    times 8 dw 60547
+    times 8 dw 46341
+    times 8 dw 25080
diff --git a/vp8/encoder/x86/dct_sse2.asm b/vp8/encoder/x86/dct_sse2.asm
new file mode 100644 (file)
index 0000000..3e5e9a7
--- /dev/null
@@ -0,0 +1,260 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+global sym(vp8_short_fdct4x4_wmt)
+
+%define         DCTCONSTANTSBITS         (16)
+%define         DCTROUNDINGVALUE         (1<< (DCTCONSTANTSBITS-1))
+%define         x_c1                      (60547)          ; cos(pi  /8) * (1<<15)
+%define         x_c2                      (46341)          ; cos(pi*2/8) * (1<<15)
+%define         x_c3                      (25080)          ; cos(pi*3/8) * (1<<15)
+
+%define _1STSTAGESHIFT           14
+%define _2NDSTAGESHIFT           16
+
+
+;; using matrix multiply
+;void vp8_short_fdct4x4_wmt(short *input, short *output)
+sym(vp8_short_fdct4x4_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    GET_GOT     rbx
+    ; end prolog
+
+        mov         rax,        arg(0) ;input
+        mov         rcx,        arg(1) ;output
+
+        lea         rdx,        [dct_matrix_sse2 GLOBAL]
+
+        movdqu      xmm0,       [rax   ]
+        movdqu      xmm1,       [rax+16]
+
+        ; first column
+        movdqa      xmm2,       xmm0
+        movdqa      xmm7,       [rdx]
+
+        pmaddwd     xmm2,       xmm7
+        movdqa      xmm3,       xmm1
+
+        pmaddwd     xmm3,       xmm7
+        movdqa      xmm4,       xmm2
+
+        punpckldq   xmm2,       xmm3
+        punpckhdq   xmm4,       xmm3
+
+        movdqa      xmm3,       xmm2
+        punpckldq   xmm2,       xmm4
+
+        punpckhdq   xmm3,       xmm4
+        paddd       xmm2,       xmm3
+
+
+        paddd       xmm2,       XMMWORD PTR [dct1st_stage_rounding_sse2 GLOBAL]
+        psrad       xmm2,       _1STSTAGESHIFT
+        ;second column
+        movdqa      xmm3,       xmm0
+        pmaddwd     xmm3,       [rdx+16]
+
+        movdqa      xmm4,       xmm1
+        pmaddwd     xmm4,       [rdx+16]
+
+        movdqa      xmm5,       xmm3
+        punpckldq   xmm3,       xmm4
+
+        punpckhdq   xmm5,       xmm4
+        movdqa      xmm4,       xmm3
+
+        punpckldq   xmm3,       xmm5
+        punpckhdq   xmm4,       xmm5
+
+        paddd       xmm3,       xmm4
+        paddd       xmm3,       XMMWORD PTR [dct1st_stage_rounding_sse2 GLOBAL]
+
+
+        psrad       xmm3,       _1STSTAGESHIFT
+        packssdw    xmm2,       xmm3
+
+        ;third column
+        movdqa      xmm3,       xmm0
+        pmaddwd     xmm3,       [rdx+32]
+
+        movdqa      xmm4,       xmm1
+        pmaddwd     xmm4,       [rdx+32]
+
+        movdqa      xmm5,       xmm3
+        punpckldq   xmm3,       xmm4
+
+        punpckhdq   xmm5,       xmm4
+        movdqa      xmm4,       xmm3
+
+        punpckldq   xmm3,       xmm5
+        punpckhdq   xmm4,       xmm5
+
+        paddd       xmm3,       xmm4
+        paddd       xmm3,       XMMWORD PTR [dct1st_stage_rounding_sse2 GLOBAL]
+
+        psrad       xmm3,       _1STSTAGESHIFT
+
+        ;fourth column (this is the last column, so we do not have save the source any more)
+        pmaddwd     xmm0,       [rdx+48]
+        pmaddwd     xmm1,       [rdx+48]
+
+        movdqa      xmm4,       xmm0
+        punpckldq   xmm0,       xmm1
+
+        punpckhdq   xmm4,       xmm1
+        movdqa      xmm1,       xmm0
+
+        punpckldq   xmm0,       xmm4
+        punpckhdq   xmm1,       xmm4
+
+        paddd       xmm0,       xmm1
+        paddd       xmm0,       XMMWORD PTR [dct1st_stage_rounding_sse2 GLOBAL]
+
+
+        psrad       xmm0,       _1STSTAGESHIFT
+        packssdw    xmm3,       xmm0
+        ; done with one pass
+        ; now start second pass
+        movdqa      xmm0,       xmm2
+        movdqa      xmm1,       xmm3
+
+        pmaddwd     xmm2,       xmm7
+        pmaddwd     xmm3,       xmm7
+
+        movdqa      xmm4,       xmm2
+        punpckldq   xmm2,       xmm3
+
+        punpckhdq   xmm4,       xmm3
+        movdqa      xmm3,       xmm2
+
+        punpckldq   xmm2,       xmm4
+        punpckhdq   xmm3,       xmm4
+
+        paddd       xmm2,       xmm3
+        paddd       xmm2,       XMMWORD PTR [dct2nd_stage_rounding_sse2 GLOBAL]
+
+        psrad       xmm2,       _2NDSTAGESHIFT
+
+        ;second column
+        movdqa      xmm3,       xmm0
+        pmaddwd     xmm3,       [rdx+16]
+
+        movdqa      xmm4,       xmm1
+        pmaddwd     xmm4,       [rdx+16]
+
+        movdqa      xmm5,       xmm3
+        punpckldq   xmm3,       xmm4
+
+        punpckhdq   xmm5,       xmm4
+        movdqa      xmm4,       xmm3
+
+        punpckldq   xmm3,       xmm5
+        punpckhdq   xmm4,       xmm5
+
+        paddd       xmm3,       xmm4
+        paddd       xmm3,       XMMWORD PTR [dct2nd_stage_rounding_sse2 GLOBAL]
+
+        psrad       xmm3,       _2NDSTAGESHIFT
+        packssdw    xmm2,       xmm3
+
+        movdqu      [rcx],      xmm2
+        ;third column
+        movdqa      xmm3,       xmm0
+        pmaddwd     xmm3,       [rdx+32]
+
+        movdqa      xmm4,       xmm1
+        pmaddwd     xmm4,       [rdx+32]
+
+        movdqa      xmm5,       xmm3
+        punpckldq   xmm3,       xmm4
+
+        punpckhdq   xmm5,       xmm4
+        movdqa      xmm4,       xmm3
+
+        punpckldq   xmm3,       xmm5
+        punpckhdq   xmm4,       xmm5
+
+        paddd       xmm3,       xmm4
+        paddd       xmm3,       XMMWORD PTR [dct2nd_stage_rounding_sse2 GLOBAL]
+
+        psrad       xmm3,       _2NDSTAGESHIFT
+        ;fourth column
+        pmaddwd     xmm0,       [rdx+48]
+        pmaddwd     xmm1,       [rdx+48]
+
+        movdqa      xmm4,       xmm0
+        punpckldq   xmm0,       xmm1
+
+        punpckhdq   xmm4,       xmm1
+        movdqa      xmm1,       xmm0
+
+        punpckldq   xmm0,       xmm4
+        punpckhdq   xmm1,       xmm4
+
+        paddd       xmm0,       xmm1
+        paddd       xmm0,       XMMWORD PTR [dct2nd_stage_rounding_sse2 GLOBAL]
+
+        psrad       xmm0,       _2NDSTAGESHIFT
+        packssdw    xmm3,       xmm0
+
+        movdqu     [rcx+16],   xmm3
+
+    mov rsp, rbp
+    ; begin epilog
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+;static unsigned int dct1st_stage_rounding_sse2[4] =
+align 16
+dct1st_stage_rounding_sse2:
+    times 4 dd 8192
+
+
+;static unsigned int dct2nd_stage_rounding_sse2[4] =
+align 16
+dct2nd_stage_rounding_sse2:
+    times 4 dd 32768
+
+;static short dct_matrix_sse2[4][8]=
+align 16
+dct_matrix_sse2:
+    times 8 dw 23170
+
+    dw  30274
+    dw  12540
+    dw -12540
+    dw -30274
+    dw  30274
+    dw  12540
+    dw -12540
+    dw -30274
+
+    dw  23170
+    times 2 dw -23170
+    times 2 dw  23170
+    times 2 dw -23170
+    dw  23170
+
+    dw  12540
+    dw -30274
+    dw  30274
+    dw -12540
+    dw  12540
+    dw -30274
+    dw  30274
+    dw -12540
diff --git a/vp8/encoder/x86/dct_x86.h b/vp8/encoder/x86/dct_x86.h
new file mode 100644 (file)
index 0000000..bc80e64
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef DCT_X86_H
+#define DCT_X86_H
+
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+#if HAVE_MMX
+extern prototype_fdct(vp8_short_fdct4x4_mmx);
+extern prototype_fdct(vp8_short_fdct8x4_mmx);
+extern prototype_fdct(vp8_fast_fdct4x4_mmx);
+extern prototype_fdct(vp8_fast_fdct8x4_mmx);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_fdct_short4x4
+#define vp8_fdct_short4x4 vp8_short_fdct4x4_mmx
+
+#undef  vp8_fdct_short8x4
+#define vp8_fdct_short8x4 vp8_short_fdct8x4_mmx
+
+#undef  vp8_fdct_fast4x4
+#define vp8_fdct_fast4x4 vp8_fast_fdct4x4_mmx
+
+#undef  vp8_fdct_fast8x4
+#define vp8_fdct_fast8x4 vp8_fast_fdct8x4_mmx
+
+#endif
+#endif
+
+
+#if HAVE_SSE2
+extern prototype_fdct(vp8_short_fdct4x4_wmt);
+extern prototype_fdct(vp8_short_fdct8x4_wmt);
+extern prototype_fdct(vp8_fast_fdct8x4_wmt);
+
+extern prototype_fdct(vp8_short_walsh4x4_sse2);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+
+#if 0
+/* short SSE2 DCT currently disabled, does not match the MMX version */
+#undef  vp8_fdct_short4x4
+#define vp8_fdct_short4x4 vp8_short_fdct4x4_wmt
+
+#undef  vp8_fdct_short8x4
+#define vp8_fdct_short8x4 vp8_short_fdct8x4_wmt
+#endif
+
+#undef  vp8_fdct_fast8x4
+#define vp8_fdct_fast8x4 vp8_fast_fdct8x4_wmt
+
+#undef vp8_fdct_walsh_short4x4
+#define vp8_fdct_walsh_short4x4  vp8_short_walsh4x4_sse2
+
+#endif
+
+
+#endif
+
+#endif
diff --git a/vp8/encoder/x86/encodemb_x86.h b/vp8/encoder/x86/encodemb_x86.h
new file mode 100644 (file)
index 0000000..9397a6c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef ENCODEMB_X86_H
+#define ENCODEMB_X86_H
+
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+#if HAVE_MMX
+extern prototype_berr(vp8_block_error_mmx);
+extern prototype_mberr(vp8_mbblock_error_mmx);
+extern prototype_mbuverr(vp8_mbuverror_mmx);
+extern prototype_subb(vp8_subtract_b_mmx);
+extern prototype_submby(vp8_subtract_mby_mmx);
+extern prototype_submbuv(vp8_subtract_mbuv_mmx);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_encodemb_berr
+#define vp8_encodemb_berr vp8_block_error_mmx
+
+#undef  vp8_encodemb_mberr
+#define vp8_encodemb_mberr vp8_mbblock_error_mmx
+
+#undef  vp8_encodemb_mbuverr
+#define vp8_encodemb_mbuverr vp8_mbuverror_mmx
+
+#undef  vp8_encodemb_subb
+#define vp8_encodemb_subb vp8_subtract_b_mmx
+
+#undef  vp8_encodemb_submby
+#define vp8_encodemb_submby vp8_subtract_mby_mmx
+
+#undef  vp8_encodemb_submbuv
+#define vp8_encodemb_submbuv vp8_subtract_mbuv_mmx
+
+#endif
+#endif
+
+
+#if HAVE_SSE2
+extern prototype_berr(vp8_block_error_xmm);
+extern prototype_mberr(vp8_mbblock_error_xmm);
+extern prototype_mbuverr(vp8_mbuverror_xmm);
+
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_encodemb_berr
+#define vp8_encodemb_berr vp8_block_error_xmm
+
+#undef  vp8_encodemb_mberr
+#define vp8_encodemb_mberr vp8_mbblock_error_xmm
+
+#undef  vp8_encodemb_mbuverr
+#define vp8_encodemb_mbuverr vp8_mbuverror_xmm
+
+#endif
+#endif
+
+
+#endif
diff --git a/vp8/encoder/x86/encodeopt.asm b/vp8/encoder/x86/encodeopt.asm
new file mode 100644 (file)
index 0000000..1940471
--- /dev/null
@@ -0,0 +1,393 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+
+;int vp8_block_error_xmm(short *coeff_ptr,  short *dcoef_ptr)
+global sym(vp8_block_error_xmm)
+sym(vp8_block_error_xmm):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov         rsi,        arg(0) ;coeff_ptr
+        pxor        xmm7,       xmm7
+
+        mov         rdi,        arg(1) ;dcoef_ptr
+        movdqa      xmm3,       [rsi]
+
+        movdqa      xmm4,       [rdi]
+        movdqa      xmm5,       [rsi+16]
+
+        movdqa      xmm6,       [rdi+16]
+        pxor        xmm1,       xmm1    ; from movd xmm1, dc; dc=0
+
+        movdqa      xmm2,       xmm7
+        psubw       xmm5,       xmm6
+
+        por         xmm1,       xmm2
+        pmaddwd     xmm5,       xmm5
+
+        pcmpeqw     xmm1,       xmm7
+        psubw       xmm3,       xmm4
+
+        pand        xmm1,       xmm3
+        pmaddwd     xmm1,       xmm1
+
+        paddd       xmm1,       xmm5
+        movdqa      xmm0,       xmm1
+
+        punpckldq   xmm0,       xmm7
+        punpckhdq   xmm1,       xmm7
+
+        paddd       xmm0,       xmm1
+        movdqa      xmm1,       xmm0
+
+        psrldq      xmm0,       8
+        paddd       xmm0,       xmm1
+
+        movd        rax,        xmm0
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;int vp8_block_error_mmx(short *coeff_ptr,  short *dcoef_ptr)
+global sym(vp8_block_error_mmx)
+sym(vp8_block_error_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov         rsi,        arg(0) ;coeff_ptr
+        pxor        mm7,        mm7
+
+        mov         rdi,        arg(1) ;dcoef_ptr
+        movq        mm3,        [rsi]
+
+        movq        mm4,        [rdi]
+        movq        mm5,        [rsi+8]
+
+        movq        mm6,        [rdi+8]
+        pxor        mm1,        mm1 ; from movd mm1, dc ; dc =0
+
+        movq        mm2,        mm7
+        psubw       mm5,        mm6
+
+        por         mm1,        mm2
+        pmaddwd     mm5,        mm5
+
+        pcmpeqw     mm1,        mm7
+        psubw       mm3,        mm4
+
+        pand        mm1,        mm3
+        pmaddwd     mm1,        mm1
+
+        paddd       mm1,        mm5
+        movq        mm3,        [rsi+16]
+
+        movq        mm4,        [rdi+16]
+        movq        mm5,        [rsi+24]
+
+        movq        mm6,        [rdi+24]
+        psubw       mm5,        mm6
+
+        pmaddwd     mm5,        mm5
+        psubw       mm3,        mm4
+
+        pmaddwd     mm3,        mm3
+        paddd       mm3,        mm5
+
+        paddd       mm1,        mm3
+        movq        mm0,        mm1
+
+        psrlq       mm1,        32
+        paddd       mm0,        mm1
+
+        movd        rax,        mm0
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;int vp8_mbblock_error_mmx_impl(short *coeff_ptr, short *dcoef_ptr, int dc);
+global sym(vp8_mbblock_error_mmx_impl)
+sym(vp8_mbblock_error_mmx_impl):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov         rsi,        arg(0) ;coeff_ptr
+        pxor        mm7,        mm7
+
+        mov         rdi,        arg(1) ;dcoef_ptr
+        pxor        mm2,        mm2
+
+        movd        mm1,        dword ptr arg(2) ;dc
+        por         mm1,        mm2
+
+        pcmpeqw     mm1,        mm7
+        mov         rcx,        16
+
+mberror_loop_mmx:
+        movq        mm3,       [rsi]
+        movq        mm4,       [rdi]
+
+        movq        mm5,       [rsi+8]
+        movq        mm6,       [rdi+8]
+
+
+        psubw       mm5,        mm6
+        pmaddwd     mm5,        mm5
+
+        psubw       mm3,        mm4
+        pand        mm3,        mm1
+
+        pmaddwd     mm3,        mm3
+        paddd       mm2,        mm5
+
+        paddd       mm2,        mm3
+        movq        mm3,       [rsi+16]
+
+        movq        mm4,       [rdi+16]
+        movq        mm5,       [rsi+24]
+
+        movq        mm6,       [rdi+24]
+        psubw       mm5,        mm6
+
+        pmaddwd     mm5,        mm5
+        psubw       mm3,        mm4
+
+        pmaddwd     mm3,        mm3
+        paddd       mm2,        mm5
+
+        paddd       mm2,        mm3
+        add         rsi,        32
+
+        add         rdi,        32
+        sub         rcx,        1
+
+        jnz         mberror_loop_mmx
+
+        movq        mm0,        mm2
+        psrlq       mm2,        32
+
+        paddd       mm0,        mm2
+        movd        rax,        mm0
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;int vp8_mbblock_error_xmm_impl(short *coeff_ptr, short *dcoef_ptr, int dc);
+global sym(vp8_mbblock_error_xmm_impl)
+sym(vp8_mbblock_error_xmm_impl):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov         rsi,        arg(0) ;coeff_ptr
+        pxor        xmm7,       xmm7
+
+        mov         rdi,        arg(1) ;dcoef_ptr
+        pxor        xmm2,       xmm2
+
+        movd        xmm1,       dword ptr arg(2) ;dc
+        por         xmm1,       xmm2
+
+        pcmpeqw     xmm1,       xmm7
+        mov         rcx,        16
+
+mberror_loop:
+        movdqa      xmm3,       [rsi]
+        movdqa      xmm4,       [rdi]
+
+        movdqa      xmm5,       [rsi+16]
+        movdqa      xmm6,       [rdi+16]
+
+
+        psubw       xmm5,       xmm6
+        pmaddwd     xmm5,       xmm5
+
+        psubw       xmm3,       xmm4
+        pand        xmm3,       xmm1
+
+        pmaddwd     xmm3,       xmm3
+        add         rsi,        32
+
+        add         rdi,        32
+
+        sub         rcx,        1
+        paddd       xmm2,       xmm5
+
+        paddd       xmm2,       xmm3
+        jnz         mberror_loop
+
+        movdqa      xmm0,       xmm2
+        punpckldq   xmm0,       xmm7
+
+        punpckhdq   xmm2,       xmm7
+        paddd       xmm0,       xmm2
+
+        movdqa      xmm1,       xmm0
+        psrldq      xmm0,       8
+
+        paddd       xmm0,       xmm1
+        movd        rax,        xmm0
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;int vp8_mbuverror_mmx_impl(short *s_ptr, short *d_ptr);
+global sym(vp8_mbuverror_mmx_impl)
+sym(vp8_mbuverror_mmx_impl):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov             rsi,        arg(0) ;s_ptr
+        mov             rdi,        arg(1) ;d_ptr
+
+        mov             rcx,        16
+        pxor            mm7,        mm7
+
+mbuverror_loop_mmx:
+
+        movq            mm1,        [rsi]
+        movq            mm2,        [rdi]
+
+        psubw           mm1,        mm2
+        pmaddwd         mm1,        mm1
+
+
+        movq            mm3,        [rsi+8]
+        movq            mm4,        [rdi+8]
+
+        psubw           mm3,        mm4
+        pmaddwd         mm3,        mm3
+
+
+        paddd           mm7,        mm1
+        paddd           mm7,        mm3
+
+
+        add             rsi,        16
+        add             rdi,        16
+
+        dec             rcx
+        jnz             mbuverror_loop_mmx
+
+        movq            mm0,        mm7
+        psrlq           mm7,        32
+
+        paddd           mm0,        mm7
+        movd            rax,        mm0
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;int vp8_mbuverror_xmm_impl(short *s_ptr, short *d_ptr);
+global sym(vp8_mbuverror_xmm_impl)
+sym(vp8_mbuverror_xmm_impl):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 2
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov             rsi,        arg(0) ;s_ptr
+        mov             rdi,        arg(1) ;d_ptr
+
+        mov             rcx,        16
+        pxor            xmm7,       xmm7
+
+mbuverror_loop:
+
+        movdqa          xmm1,       [rsi]
+        movdqa          xmm2,       [rdi]
+
+        psubw           xmm1,       xmm2
+        pmaddwd         xmm1,       xmm1
+
+        paddd           xmm7,       xmm1
+
+        add             rsi,        16
+        add             rdi,        16
+
+        dec             rcx
+        jnz             mbuverror_loop
+
+        pxor        xmm0,           xmm0
+        movdqa      xmm1,           xmm7
+
+        movdqa      xmm2,           xmm1
+        punpckldq   xmm1,           xmm0
+
+        punpckhdq   xmm2,           xmm0
+        paddd       xmm1,           xmm2
+
+        movdqa      xmm2,           xmm1
+
+        psrldq      xmm1,           8
+        paddd       xmm1,           xmm2
+
+        movd            rax,            xmm1
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/fwalsh_sse2.asm b/vp8/encoder/x86/fwalsh_sse2.asm
new file mode 100644 (file)
index 0000000..7d86201
--- /dev/null
@@ -0,0 +1,117 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;void vp8_short_walsh4x4_sse2(short *input, short *output, int pitch)
+global sym(vp8_short_walsh4x4_sse2)
+sym(vp8_short_walsh4x4_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 3
+    push        rsi
+    push        rdi
+    ; end prolog
+
+    mov     rsi, arg(0)
+    mov     rdi, arg(1)
+
+    movdqu    xmm4, [rsi + 0]       ;ip[4] ip[0]
+    movdqu    xmm0, [rsi + 16]      ;ip[12] ip[8]
+
+    pxor  xmm7, xmm7
+    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ; 13 12 11 10 03 02 01 00
+    ;
+    ; 33 32 31 30 23 22 21 20
+    ;
+    movdqa    xmm3, xmm4          ; 13 12 11 10 03 02 01 00
+    punpcklwd xmm4, xmm0          ; 23 03 22 02 21 01 20 00
+    punpckhwd xmm3, xmm0          ; 33 13 32 12 31 11 30 10
+    movdqa    xmm1, xmm4          ; 23 03 22 02 21 01 20 00
+    punpcklwd xmm4, xmm3          ; 31 21 11 01 30 20 10 00
+    punpckhwd xmm1, xmm3          ; 33 23 13 03 32 22 12 02
+    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    pshufd    xmm2, xmm1, 4eh       ;ip[8] ip[12]
+    movdqa    xmm3, xmm4          ;ip[4] ip[0]
+
+    paddw   xmm4, xmm2          ;ip[4]+ip[8] ip[0]+ip[12] aka b1 a1
+    psubw   xmm3, xmm2          ;ip[4]-ip[8] ip[0]-ip[12] aka c1 d1
+
+    movdqa    xmm5, xmm4
+    punpcklqdq  xmm4, xmm3          ;d1 a1
+    punpckhqdq  xmm5, xmm3          ;c1 b1
+
+    movdqa    xmm1, xmm5          ;c1 b1
+    paddw   xmm5, xmm4          ;dl+cl a1+b1 aka op[4] op[0]
+    psubw   xmm4, xmm1          ;d1-c1 a1-b1 aka op[12] op[8]
+    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ; 13 12 11 10 03 02 01 00
+    ;
+    ; 33 32 31 30 23 22 21 20
+    ;
+    movdqa    xmm0, xmm5          ; 13 12 11 10 03 02 01 00
+    punpcklwd xmm5, xmm4          ; 23 03 22 02 21 01 20 00
+    punpckhwd xmm0, xmm4          ; 33 13 32 12 31 11 30 10
+    movdqa    xmm1, xmm5          ; 23 03 22 02 21 01 20 00
+    punpcklwd xmm5, xmm0          ; 31 21 11 01 30 20 10 00
+    punpckhwd xmm1, xmm0          ; 33 23 13 03 32 22 12 02
+    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    pshufd    xmm2, xmm1, 4eh       ;ip[8] ip[12]
+    movdqa    xmm3, xmm5          ;ip[4] ip[0]
+
+    paddw   xmm5, xmm2          ;ip[4]+ip[8] ip[0]+ip[12] aka b1 a1
+    psubw   xmm3, xmm2          ;ip[4]-ip[8] ip[0]-ip[12] aka c1 d1
+
+    movdqa    xmm6, xmm5
+    punpcklqdq  xmm5, xmm3          ;d1 a1
+    punpckhqdq  xmm6, xmm3          ;c1 b1
+
+    movdqa    xmm1, xmm6          ;c1 b1
+    paddw   xmm6, xmm5          ;dl+cl a1+b1 aka op[4] op[0]
+    psubw   xmm5, xmm1          ;d1-c1 a1-b1 aka op[12] op[8]
+
+    movdqa    xmm0, xmm6          ;aka b2 a2
+    movdqa    xmm1, xmm5          ;aka d2 c2
+
+    pcmpgtw   xmm0, xmm7
+    pcmpgtw   xmm1, xmm7
+
+    psrlw   xmm0, 15
+    psrlw   xmm1, 15
+
+    paddw   xmm6, xmm0
+    paddw   xmm5, xmm1
+
+    psraw   xmm6, 1
+    psraw   xmm5, 1
+
+    ;   a2 = a1 + b1;
+    ;   b2 = c1 + d1;
+    ;   c2 = a1 - b1;
+    ;   d2 = d1 - c1;
+    ;        a2 += (a2>0);
+    ;        b2 += (b2>0);
+    ;        c2 += (c2>0);
+    ;        d2 += (d2>0);
+    ;   op[0] = (a2)>>1;
+    ;   op[4] = (b2)>>1;
+    ;   op[8] = (c2)>>1;
+    ;   op[12]= (d2)>>1;
+
+    movdqu  [rdi + 0], xmm6
+    movdqu  [rdi + 16], xmm5
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/mcomp_x86.h b/vp8/encoder/x86/mcomp_x86.h
new file mode 100644 (file)
index 0000000..5661491
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef MCOMP_X86_H
+#define MCOMP_X86_H
+
+#if HAVE_SSE3
+#if !CONFIG_RUNTIME_CPU_DETECT
+
+#undef  vp8_search_full_search
+#define vp8_search_full_search vp8_full_search_sadx3
+
+#undef  vp8_search_diamond_search
+#define vp8_search_diamond_search vp8_diamond_search_sadx4
+
+#endif
+#endif
+
+#endif
+
diff --git a/vp8/encoder/x86/preproc_mmx.c b/vp8/encoder/x86/preproc_mmx.c
new file mode 100644 (file)
index 0000000..69617ca
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "memory.h"
+#include "preproc.h"
+#include "pragmas.h"
+
+/****************************************************************************
+*  Macros
+****************************************************************************/
+#define FRAMECOUNT 7
+#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
+
+/****************************************************************************
+*  Imports
+****************************************************************************/
+extern void vpx_get_processor_flags(int *mmx_enabled, int *xmm_enabled, int *wmt_enabled);
+
+/****************************************************************************
+*  Exported Global Variables
+****************************************************************************/
+void (*temp_filter)(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int bytes, int strength);
+
+/****************************************************************************
+ *
+ *  ROUTINE       : temp_filter_wmt
+ *
+ *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
+ *                  unsigned char *s     : Pointer to source frame.
+ *                  unsigned char *d     : Pointer to destination frame.
+ *                  int bytes            : Number of bytes to filter.
+ *                  int strength         : Strength of filter to apply.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs a closesness adjusted temporarl blur
+ *
+ *  SPECIAL NOTES : Destination frame can be same as source frame.
+ *
+ ****************************************************************************/
+void temp_filter_wmt
+(
+    pre_proc_instance *ppi,
+    unsigned char *s,
+    unsigned char *d,
+    int bytes,
+    int strength
+)
+{
+    int byte = 0;
+    unsigned char *frameptr = ppi->frame_buffer;
+
+    __declspec(align(16)) unsigned short threes[]  = { 3, 3, 3, 3, 3, 3, 3, 3};
+    __declspec(align(16)) unsigned short sixteens[] = {16, 16, 16, 16, 16, 16, 16, 16};
+
+    if (ppi->frame == 0)
+    {
+        do
+        {
+            int i;
+            int frame = 0;
+
+            do
+            {
+                for (i = 0; i < 8; i++)
+                {
+                    *frameptr = s[byte+i];
+                    ++frameptr;
+                }
+
+                ++frame;
+            }
+            while (frame < FRAMECOUNT);
+
+            for (i = 0; i < 8; i++)
+                d[byte+i] = s[byte+i];
+
+            byte += 8;
+
+        }
+        while (byte < bytes);
+    }
+    else
+    {
+        int i;
+        int offset2 = (ppi->frame % FRAMECOUNT);
+
+        do
+        {
+            __declspec(align(16)) unsigned short counts[8];
+            __declspec(align(16)) unsigned short sums[8];
+            __asm
+            {
+                mov         eax, offset2
+                mov         edi, s                  // source pixels
+                pxor        xmm1, xmm1              // accumulator
+
+                pxor        xmm7, xmm7
+
+                mov         esi, frameptr           // accumulator
+                pxor        xmm2, xmm2              // count
+
+                movq        xmm3, QWORD PTR [edi]
+
+                movq        QWORD PTR [esi+8*eax], xmm3
+
+                punpcklbw   xmm3, xmm2              // xmm3 source pixels
+                mov         ecx,  FRAMECOUNT
+
+                next_frame:
+                movq        xmm4, QWORD PTR [esi]   // get frame buffer values
+                punpcklbw   xmm4, xmm7              // xmm4 frame buffer pixels
+                movdqa      xmm6, xmm4              // save the pixel values
+                psubsw      xmm4, xmm3              // subtracted pixel values
+                pmullw      xmm4, xmm4              // square xmm4
+                movd        xmm5, strength
+                psrlw       xmm4, xmm5              // should be strength
+                pmullw      xmm4, threes            // 3 * modifier
+                movdqa      xmm5, sixteens          // 16s
+                psubusw     xmm5, xmm4              // 16 - modifiers
+                movdqa      xmm4, xmm5              // save the modifiers
+                pmullw      xmm4, xmm6              // multiplier values
+                paddusw     xmm1, xmm4              // accumulator
+                paddusw     xmm2, xmm5              // count
+                add         esi, 8                  // next frame
+                dec         ecx                     // next set of eight pixels
+                jnz         next_frame
+
+                movdqa      counts, xmm2
+                psrlw       xmm2, 1                 // divide count by 2 for rounding
+                paddusw     xmm1, xmm2              // rounding added in
+
+                mov         frameptr, esi
+
+                movdqa      sums, xmm1
+            }
+
+            for (i = 0; i < 8; i++)
+            {
+                int blurvalue = sums[i] * ppi->fixed_divide[counts[i]];
+                blurvalue >>= 16;
+                d[i] = blurvalue;
+            }
+
+            s += 8;
+            d += 8;
+            byte += 8;
+        }
+        while (byte < bytes);
+    }
+
+    ++ppi->frame;
+    __asm emms
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : temp_filter_mmx
+ *
+ *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
+ *                  unsigned char *s     : Pointer to source frame.
+ *                  unsigned char *d     : Pointer to destination frame.
+ *                  int bytes            : Number of bytes to filter.
+ *                  int strength         : Strength of filter to apply.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs a closesness adjusted temporarl blur
+ *
+ *  SPECIAL NOTES : Destination frame can be same as source frame.
+ *
+ ****************************************************************************/
+void temp_filter_mmx
+(
+    pre_proc_instance *ppi,
+    unsigned char *s,
+    unsigned char *d,
+    int bytes,
+    int strength
+)
+{
+    int byte = 0;
+    unsigned char *frameptr = ppi->frame_buffer;
+
+    __declspec(align(16)) unsigned short threes[]  = { 3, 3, 3, 3};
+    __declspec(align(16)) unsigned short sixteens[] = {16, 16, 16, 16};
+
+    if (ppi->frame == 0)
+    {
+        do
+        {
+            int i;
+            int frame = 0;
+
+            do
+            {
+                for (i = 0; i < 4; i++)
+                {
+                    *frameptr = s[byte+i];
+                    ++frameptr;
+                }
+
+                ++frame;
+            }
+            while (frame < FRAMECOUNT);
+
+            for (i = 0; i < 4; i++)
+                d[byte+i] = s[byte+i];
+
+            byte += 4;
+
+        }
+        while (byte < bytes);
+    }
+    else
+    {
+        int i;
+        int offset2 = (ppi->frame % FRAMECOUNT);
+
+        do
+        {
+            __declspec(align(16)) unsigned short counts[8];
+            __declspec(align(16)) unsigned short sums[8];
+            __asm
+            {
+
+                mov         eax, offset2
+                mov         edi, s                  // source pixels
+                pxor        mm1, mm1                // accumulator
+                pxor        mm7, mm7
+
+                mov         esi, frameptr           // accumulator
+                pxor        mm2, mm2                // count
+
+                movd        mm3, DWORD PTR [edi]
+                movd        DWORD PTR [esi+4*eax], mm3
+
+                punpcklbw   mm3, mm2                // mm3 source pixels
+                mov         ecx,  FRAMECOUNT
+
+                next_frame:
+                movd        mm4, DWORD PTR [esi]    // get frame buffer values
+                punpcklbw   mm4, mm7                // mm4 frame buffer pixels
+                movq        mm6, mm4                // save the pixel values
+                psubsw      mm4, mm3                // subtracted pixel values
+                pmullw      mm4, mm4                // square mm4
+                movd        mm5, strength
+                psrlw       mm4, mm5                // should be strength
+                pmullw      mm4, threes             // 3 * modifier
+                movq        mm5, sixteens           // 16s
+                psubusw     mm5, mm4                // 16 - modifiers
+                movq        mm4, mm5                // save the modifiers
+                pmullw      mm4, mm6                // multiplier values
+                paddusw     mm1, mm4                // accumulator
+                paddusw     mm2, mm5                // count
+                add         esi, 4                  // next frame
+                dec         ecx                     // next set of eight pixels
+                jnz         next_frame
+
+                movq        counts, mm2
+                psrlw       mm2, 1                  // divide count by 2 for rounding
+                paddusw     mm1, mm2                // rounding added in
+
+                mov         frameptr, esi
+
+                movq        sums, mm1
+
+            }
+
+            for (i = 0; i < 4; i++)
+            {
+                int blurvalue = sums[i] * ppi->fixed_divide[counts[i]];
+                blurvalue >>= 16;
+                d[i] = blurvalue;
+            }
+
+            s += 4;
+            d += 4;
+            byte += 4;
+        }
+        while (byte < bytes);
+    }
+
+    ++ppi->frame;
+    __asm emms
+}
diff --git a/vp8/encoder/x86/quantize_mmx.asm b/vp8/encoder/x86/quantize_mmx.asm
new file mode 100644 (file)
index 0000000..847fc6e
--- /dev/null
@@ -0,0 +1,438 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;int vp8_fast_quantize_b_impl_mmx(short *coeff_ptr, short *zbin_ptr,
+;                           short *qcoeff_ptr,short *dequant_ptr,
+;                           short *scan_mask, short *round_ptr,
+;                           short *quant_ptr, short *dqcoeff_ptr);
+global sym(vp8_fast_quantize_b_impl_mmx)
+sym(vp8_fast_quantize_b_impl_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov             rsi,        arg(0) ;coeff_ptr
+        movq            mm0,        [rsi]
+
+        mov             rax,        arg(1) ;zbin_ptr
+        movq            mm1,        [rax]
+
+        movq            mm3,        mm0
+        psraw           mm0,        15
+
+        pxor            mm3,        mm0
+        psubw           mm3,        mm0         ; abs
+
+        movq            mm2,        mm3
+        pcmpgtw         mm1,        mm2
+
+        pandn           mm1,        mm2
+        movq            mm3,        mm1
+
+        mov             rdx,        arg(6) ;quant_ptr
+        movq            mm1,        [rdx]
+
+        mov             rcx,        arg(5) ;round_ptr
+        movq            mm2,        [rcx]
+
+        paddw           mm3,        mm2
+        pmulhuw         mm3,        mm1
+
+        pxor            mm3,        mm0
+        psubw           mm3,        mm0     ;gain the sign back
+
+        mov             rdi,        arg(2) ;qcoeff_ptr
+        movq            mm0,        mm3
+
+        movq            [rdi],      mm3
+
+        mov             rax,        arg(3) ;dequant_ptr
+        movq            mm2,        [rax]
+
+        pmullw          mm3,        mm2
+        mov             rax,        arg(7) ;dqcoeff_ptr
+
+        movq            [rax],      mm3
+
+        ; next 8
+        movq            mm4,        [rsi+8]
+
+        mov             rax,        arg(1) ;zbin_ptr
+        movq            mm5,        [rax+8]
+
+        movq            mm7,        mm4
+        psraw           mm4,        15
+
+        pxor            mm7,        mm4
+        psubw           mm7,        mm4         ; abs
+
+        movq            mm6,        mm7
+        pcmpgtw         mm5,        mm6
+
+        pandn           mm5,        mm6
+        movq            mm7,        mm5
+
+        movq            mm5,        [rdx+8]
+        movq            mm6,        [rcx+8]
+
+        paddw           mm7,        mm6
+        pmulhuw         mm7,        mm5
+
+        pxor            mm7,        mm4
+        psubw           mm7,        mm4;gain the sign back
+
+        mov             rdi,        arg(2) ;qcoeff_ptr
+
+        movq            mm1,        mm7
+        movq            [rdi+8],    mm7
+
+        mov             rax,        arg(3) ;dequant_ptr
+        movq            mm6,        [rax+8]
+
+        pmullw          mm7,        mm6
+        mov             rax,        arg(7) ;dqcoeff_ptr
+
+        movq            [rax+8],    mm7
+
+
+                ; next 8
+        movq            mm4,        [rsi+16]
+
+        mov             rax,        arg(1) ;zbin_ptr
+        movq            mm5,        [rax+16]
+
+        movq            mm7,        mm4
+        psraw           mm4,        15
+
+        pxor            mm7,        mm4
+        psubw           mm7,        mm4         ; abs
+
+        movq            mm6,        mm7
+        pcmpgtw         mm5,        mm6
+
+        pandn           mm5,        mm6
+        movq            mm7,        mm5
+
+        movq            mm5,        [rdx+16]
+        movq            mm6,        [rcx+16]
+
+        paddw           mm7,        mm6
+        pmulhuw         mm7,        mm5
+
+        pxor            mm7,        mm4
+        psubw           mm7,        mm4;gain the sign back
+
+        mov             rdi,        arg(2) ;qcoeff_ptr
+
+        movq            mm1,        mm7
+        movq            [rdi+16],   mm7
+
+        mov             rax,        arg(3) ;dequant_ptr
+        movq            mm6,        [rax+16]
+
+        pmullw          mm7,        mm6
+        mov             rax,        arg(7) ;dqcoeff_ptr
+
+        movq            [rax+16],   mm7
+
+
+                ; next 8
+        movq            mm4,        [rsi+24]
+
+        mov             rax,        arg(1) ;zbin_ptr
+        movq            mm5,        [rax+24]
+
+        movq            mm7,        mm4
+        psraw           mm4,        15
+
+        pxor            mm7,        mm4
+        psubw           mm7,        mm4         ; abs
+
+        movq            mm6,        mm7
+        pcmpgtw         mm5,        mm6
+
+        pandn           mm5,        mm6
+        movq            mm7,        mm5
+
+        movq            mm5,        [rdx+24]
+        movq            mm6,        [rcx+24]
+
+        paddw           mm7,        mm6
+        pmulhuw         mm7,        mm5
+
+        pxor            mm7,        mm4
+        psubw           mm7,        mm4;gain the sign back
+
+        mov             rdi,        arg(2) ;qcoeff_ptr
+
+        movq            mm1,        mm7
+        movq            [rdi+24],   mm7
+
+        mov             rax,        arg(3) ;dequant_ptr
+        movq            mm6,        [rax+24]
+
+        pmullw          mm7,        mm6
+        mov             rax,        arg(7) ;dqcoeff_ptr
+
+        movq            [rax+24],   mm7
+
+
+
+        mov             rdi,        arg(4) ;scan_mask
+        mov             rsi,        arg(2) ;qcoeff_ptr
+
+        pxor            mm5,        mm5
+        pxor            mm7,        mm7
+
+        movq            mm0,        [rsi]
+        movq            mm1,        [rsi+8]
+
+        movq            mm2,        [rdi]
+        movq            mm3,        [rdi+8];
+
+        pcmpeqw         mm0,        mm7
+        pcmpeqw         mm1,        mm7
+
+        pcmpeqw         mm6,        mm6
+        pxor            mm0,        mm6
+
+        pxor            mm1,        mm6
+        psrlw           mm0,        15
+
+        psrlw           mm1,        15
+        pmaddwd         mm0,        mm2
+
+        pmaddwd         mm1,        mm3
+        movq            mm5,        mm0
+
+        paddd           mm5,        mm1
+
+        movq            mm0,        [rsi+16]
+        movq            mm1,        [rsi+24]
+
+        movq            mm2,        [rdi+16]
+        movq            mm3,        [rdi+24];
+
+        pcmpeqw         mm0,        mm7
+        pcmpeqw         mm1,        mm7
+
+        pcmpeqw         mm6,        mm6
+        pxor            mm0,        mm6
+
+        pxor            mm1,        mm6
+        psrlw           mm0,        15
+
+        psrlw           mm1,        15
+        pmaddwd         mm0,        mm2
+
+        pmaddwd         mm1,        mm3
+        paddd           mm5,        mm0
+
+        paddd           mm5,        mm1
+        movq            mm0,        mm5
+
+        psrlq           mm5,        32
+        paddd           mm0,        mm5
+
+        ; eob adjustment begins here
+        movd            rcx,        mm0
+        and             rcx,        0xffff
+
+        xor             rdx,        rdx
+        sub             rdx,        rcx ; rdx=-rcx
+
+        bsr             rax,        rcx
+        inc             rax
+
+        sar             rdx,        31
+        and             rax,        rdx
+        ; Substitute the sse assembly for the old mmx mixed assembly/C. The
+        ; following is kept as reference
+        ;    movd            rcx,        mm0
+        ;    bsr             rax,        rcx
+        ;
+        ;    mov             eob,        rax
+        ;    mov             eee,        rcx
+        ;
+        ;if(eee==0)
+        ;{
+        ;    eob=-1;
+        ;}
+        ;else if(eee<0)
+        ;{
+        ;    eob=15;
+        ;}
+        ;d->eob = eob+1;
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;int vp8_fast_quantize_b_impl_sse(short *coeff_ptr, short *zbin_ptr,
+;                           short *qcoeff_ptr,short *dequant_ptr,
+;                           short *scan_mask, short *round_ptr,
+;                           short *quant_ptr, short *dqcoeff_ptr);
+global sym(vp8_fast_quantize_b_impl_sse)
+sym(vp8_fast_quantize_b_impl_sse):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov             rsi,        arg(0) ;coeff_ptr
+        movdqa          xmm0,       [rsi]
+
+        mov             rax,        arg(1) ;zbin_ptr
+        movdqa          xmm1,       [rax]
+
+        movdqa          xmm3,       xmm0
+        psraw           xmm0,       15
+
+        pxor            xmm3,       xmm0
+        psubw           xmm3,       xmm0            ; abs
+
+        movdqa          xmm2,       xmm3
+        pcmpgtw         xmm1,       xmm2
+
+        pandn           xmm1,       xmm2
+        movdqa          xmm3,       xmm1
+
+        mov             rdx,        arg(6) ; quant_ptr
+        movdqa          xmm1,       [rdx]
+
+        mov             rcx,        arg(5) ; round_ptr
+        movdqa          xmm2,       [rcx]
+
+        paddw           xmm3,       xmm2
+        pmulhuw         xmm3,       xmm1
+
+        pxor            xmm3,       xmm0
+        psubw           xmm3,       xmm0        ;gain the sign back
+
+        mov             rdi,        arg(2) ;qcoeff_ptr
+        movdqa          xmm0,       xmm3
+
+        movdqa          [rdi],      xmm3
+
+        mov             rax,        arg(3) ;dequant_ptr
+        movdqa          xmm2,       [rax]
+
+        pmullw          xmm3,       xmm2
+        mov             rax,        arg(7) ;dqcoeff_ptr
+
+        movdqa          [rax],      xmm3
+
+        ; next 8
+        movdqa          xmm4,       [rsi+16]
+
+        mov             rax,        arg(1) ;zbin_ptr
+        movdqa          xmm5,       [rax+16]
+
+        movdqa          xmm7,       xmm4
+        psraw           xmm4,       15
+
+        pxor            xmm7,       xmm4
+        psubw           xmm7,       xmm4            ; abs
+
+        movdqa          xmm6,       xmm7
+        pcmpgtw         xmm5,       xmm6
+
+        pandn           xmm5,       xmm6
+        movdqa          xmm7,       xmm5
+
+        movdqa          xmm5,       [rdx+16]
+        movdqa          xmm6,       [rcx+16]
+
+
+        paddw           xmm7,       xmm6
+        pmulhuw         xmm7,       xmm5
+
+        pxor            xmm7,       xmm4
+        psubw           xmm7,       xmm4;gain the sign back
+
+        mov             rdi,        arg(2) ;qcoeff_ptr
+
+        movdqa          xmm1,       xmm7
+        movdqa          [rdi+16],   xmm7
+
+        mov             rax,        arg(3) ;dequant_ptr
+        movdqa          xmm6,       [rax+16]
+
+        pmullw          xmm7,       xmm6
+        mov             rax,        arg(7) ;dqcoeff_ptr
+
+        movdqa          [rax+16],   xmm7
+        mov             rdi,        arg(4) ;scan_mask
+
+        pxor            xmm7,       xmm7
+        movdqa          xmm2,       [rdi]
+
+        movdqa          xmm3,       [rdi+16];
+        pcmpeqw         xmm0,       xmm7
+
+        pcmpeqw         xmm1,       xmm7
+        pcmpeqw         xmm6,       xmm6
+
+        pxor            xmm0,       xmm6
+        pxor            xmm1,       xmm6
+
+        psrlw           xmm0,       15
+        psrlw           xmm1,       15
+
+        pmaddwd         xmm0,       xmm2
+        pmaddwd         xmm1,       xmm3
+
+        movq            xmm2,       xmm0
+        movq            xmm3,       xmm1
+
+        psrldq          xmm0,       8
+        psrldq          xmm1,       8
+
+        paddd           xmm0,       xmm1
+        paddd           xmm2,       xmm3
+
+        paddd           xmm0,       xmm2
+        movq            xmm1,       xmm0
+
+        psrldq          xmm0,       4
+        paddd           xmm1,       xmm0
+
+        movd            rcx,        xmm1
+        and             rcx,        0xffff
+
+        xor             rdx,        rdx
+        sub             rdx,        rcx
+
+        bsr             rax,        rcx
+        inc             rax
+
+        sar             rdx,        31
+        and             rax,        rdx
+
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/sad_mmx.asm b/vp8/encoder/x86/sad_mmx.asm
new file mode 100644 (file)
index 0000000..a825698
--- /dev/null
@@ -0,0 +1,428 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+global sym(vp8_sad16x16_mmx)
+global sym(vp8_sad8x16_mmx)
+global sym(vp8_sad8x8_mmx)
+global sym(vp8_sad4x4_mmx)
+global sym(vp8_sad16x8_mmx)
+
+%idefine QWORD
+
+;unsigned int vp8_sad16x16_mmx(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+sym(vp8_sad16x16_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rax*8]
+
+        lea             rcx,        [rcx+rax*8]
+        pxor            mm7,        mm7
+
+        pxor            mm6,        mm6
+
+x16x16sad_mmx_loop:
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm2,        QWORD PTR [rsi+8]
+
+        movq            mm1,        QWORD PTR [rdi]
+        movq            mm3,        QWORD PTR [rdi+8]
+
+        movq            mm4,        mm0
+        movq            mm5,        mm2
+
+        psubusb         mm0,        mm1
+        psubusb         mm1,        mm4
+
+        psubusb         mm2,        mm3
+        psubusb         mm3,        mm5
+
+        por             mm0,        mm1
+        por             mm2,        mm3
+
+        movq            mm1,        mm0
+        movq            mm3,        mm2
+
+        punpcklbw       mm0,        mm6
+        punpcklbw       mm2,        mm6
+
+        punpckhbw       mm1,        mm6
+        punpckhbw       mm3,        mm6
+
+        paddw           mm0,        mm2
+        paddw           mm1,        mm3
+
+
+        lea             rsi,        [rsi+rax]
+        add             rdi,        rdx
+
+        paddw           mm7,        mm0
+        paddw           mm7,        mm1
+
+        cmp             rsi,        rcx
+        jne             x16x16sad_mmx_loop
+
+
+        movq            mm0,        mm7
+
+        punpcklwd       mm0,        mm6
+        punpckhwd       mm7,        mm6
+
+        paddw           mm0,        mm7
+        movq            mm7,        mm0
+
+
+        psrlq           mm0,        32
+        paddw           mm7,        mm0
+
+        movd            rax,        mm7
+
+    pop rdi
+    pop rsi
+    mov rsp, rbp
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_sad8x16_mmx(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+sym(vp8_sad8x16_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rax*8]
+
+        lea             rcx,        [rcx+rax*8]
+        pxor            mm7,        mm7
+
+        pxor            mm6,        mm6
+
+x8x16sad_mmx_loop:
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm1,        QWORD PTR [rdi]
+
+        movq            mm2,        mm0
+        psubusb         mm0,        mm1
+
+        psubusb         mm1,        mm2
+        por             mm0,        mm1
+
+        movq            mm2,        mm0
+        punpcklbw       mm0,        mm6
+
+        punpckhbw       mm2,        mm6
+        lea             rsi,        [rsi+rax]
+
+        add             rdi,        rdx
+        paddw           mm7,        mm0
+
+        paddw           mm7,        mm2
+        cmp             rsi,        rcx
+
+        jne             x8x16sad_mmx_loop
+
+        movq            mm0,        mm7
+        punpcklwd       mm0,        mm6
+
+        punpckhwd       mm7,        mm6
+        paddw           mm0,        mm7
+
+        movq            mm7,        mm0
+        psrlq           mm0,        32
+
+        paddw           mm7,        mm0
+        movd            rax,        mm7
+
+    pop rdi
+    pop rsi
+    mov rsp, rbp
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_sad8x8_mmx(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+sym(vp8_sad8x8_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rax*8]
+        pxor            mm7,        mm7
+
+        pxor            mm6,        mm6
+
+x8x8sad_mmx_loop:
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm1,        QWORD PTR [rdi]
+
+        movq            mm2,        mm0
+        psubusb         mm0,        mm1
+
+        psubusb         mm1,        mm2
+        por             mm0,        mm1
+
+        movq            mm2,        mm0
+        punpcklbw       mm0,        mm6
+
+        punpckhbw       mm2,        mm6
+        paddw           mm0,        mm2
+
+        lea             rsi,       [rsi+rax]
+        add             rdi,        rdx
+
+        paddw           mm7,       mm0
+        cmp             rsi,        rcx
+
+        jne             x8x8sad_mmx_loop
+
+        movq            mm0,        mm7
+        punpcklwd       mm0,        mm6
+
+        punpckhwd       mm7,        mm6
+        paddw           mm0,        mm7
+
+        movq            mm7,        mm0
+        psrlq           mm0,        32
+
+        paddw           mm7,        mm0
+        movd            rax,        mm7
+
+    pop rdi
+    pop rsi
+    mov rsp, rbp
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_sad4x4_mmx(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+sym(vp8_sad4x4_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        movd            mm0,       QWORD PTR [rsi]
+        movd            mm1,       QWORD PTR [rdi]
+
+        movd            mm2,       QWORD PTR [rsi+rax]
+        movd            mm3,       QWORD PTR [rdi+rdx]
+
+        punpcklbw       mm0,        mm2
+        punpcklbw       mm1,        mm3
+
+        movq            mm2,        mm0
+        psubusb         mm0,        mm1
+
+        psubusb         mm1,        mm2
+        por             mm0,        mm1
+
+        movq            mm2,        mm0
+        pxor            mm3,        mm3
+
+        punpcklbw       mm0,        mm3
+        punpckhbw       mm2,        mm3
+
+        paddw           mm0,        mm2
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        movd            mm4,       QWORD PTR [rsi]
+        movd            mm5,       QWORD PTR [rdi]
+
+        movd            mm6,       QWORD PTR [rsi+rax]
+        movd            mm7,       QWORD PTR [rdi+rdx]
+
+        punpcklbw       mm4,        mm6
+        punpcklbw       mm5,        mm7
+
+        movq            mm6,        mm4
+        psubusb         mm4,        mm5
+
+        psubusb         mm5,        mm6
+        por             mm4,        mm5
+
+        movq            mm5,        mm4
+        punpcklbw       mm4,        mm3
+
+        punpckhbw       mm5,        mm3
+        paddw           mm4,        mm5
+
+        paddw           mm0,        mm4
+        movq            mm1,        mm0
+
+        punpcklwd       mm0,        mm3
+        punpckhwd       mm1,        mm3
+
+        paddw           mm0,        mm1
+        movq            mm1,        mm0
+
+        psrlq           mm0,        32
+        paddw           mm0,        mm1
+
+        movd            rax,        mm0
+
+    pop rdi
+    pop rsi
+    mov rsp, rbp
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_sad16x8_mmx(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+sym(vp8_sad16x8_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rax*8]
+        pxor            mm7,        mm7
+
+        pxor            mm6,        mm6
+
+x16x8sad_mmx_loop:
+
+        movq            mm0,       [rsi]
+        movq            mm1,       [rdi]
+
+        movq            mm2,        [rsi+8]
+        movq            mm3,        [rdi+8]
+
+        movq            mm4,        mm0
+        movq            mm5,        mm2
+
+        psubusb         mm0,        mm1
+        psubusb         mm1,        mm4
+
+        psubusb         mm2,        mm3
+        psubusb         mm3,        mm5
+
+        por             mm0,        mm1
+        por             mm2,        mm3
+
+        movq            mm1,        mm0
+        movq            mm3,        mm2
+
+        punpcklbw       mm0,        mm6
+        punpckhbw       mm1,        mm6
+
+        punpcklbw       mm2,        mm6
+        punpckhbw       mm3,        mm6
+
+
+        paddw           mm0,        mm2
+        paddw           mm1,        mm3
+
+        paddw           mm0,        mm1
+        lea             rsi,        [rsi+rax]
+
+        add             rdi,        rdx
+        paddw           mm7,        mm0
+
+        cmp             rsi,        rcx
+        jne             x16x8sad_mmx_loop
+
+        movq            mm0,        mm7
+        punpcklwd       mm0,        mm6
+
+        punpckhwd       mm7,        mm6
+        paddw           mm0,        mm7
+
+        movq            mm7,        mm0
+        psrlq           mm0,        32
+
+        paddw           mm7,        mm0
+        movd            rax,        mm7
+
+    pop rdi
+    pop rsi
+    mov rsp, rbp
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/sad_sse2.asm b/vp8/encoder/x86/sad_sse2.asm
new file mode 100644 (file)
index 0000000..53240bb
--- /dev/null
@@ -0,0 +1,329 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%idefine QWORD
+
+;unsigned int vp8_sad16x16_wmt(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+global sym(vp8_sad16x16_wmt)
+sym(vp8_sad16x16_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rax*8]
+
+        lea             rcx,        [rcx+rax*8]
+        pxor            xmm7,       xmm7
+
+x16x16sad_wmt_loop:
+
+        movq            xmm0,       QWORD PTR [rsi]
+        movq            xmm2,       QWORD PTR [rsi+8]
+
+        movq            xmm1,       QWORD PTR [rdi]
+        movq            xmm3,       QWORD PTR [rdi+8]
+
+        movq            xmm4,       QWORD PTR [rsi+rax]
+        movq            xmm5,       QWORD PTR [rdi+rdx]
+
+
+        punpcklbw       xmm0,       xmm2
+        punpcklbw       xmm1,       xmm3
+
+        psadbw          xmm0,       xmm1
+        movq            xmm6,       QWORD PTR [rsi+rax+8]
+
+        movq            xmm3,       QWORD PTR [rdi+rdx+8]
+        lea             rsi,        [rsi+rax*2]
+
+        lea             rdi,        [rdi+rdx*2]
+        punpcklbw       xmm4,       xmm6
+
+        punpcklbw       xmm5,       xmm3
+        psadbw          xmm4,       xmm5
+
+        paddw           xmm7,       xmm0
+        paddw           xmm7,       xmm4
+
+        cmp             rsi,        rcx
+        jne             x16x16sad_wmt_loop
+
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            rax,        xmm0
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;unsigned int vp8_sad8x16_wmt(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  max_err)
+global sym(vp8_sad8x16_wmt)
+sym(vp8_sad8x16_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rbx*8]
+
+        lea             rcx,        [rcx+rbx*8]
+        pxor            mm7,        mm7
+
+x8x16sad_wmt_loop:
+
+        movd            rax,        mm7
+        cmp             rax,        arg(4)
+        jg              x8x16sad_wmt_early_exit
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm1,        QWORD PTR [rdi]
+
+        movq            mm2,        QWORD PTR [rsi+rbx]
+        movq            mm3,        QWORD PTR [rdi+rdx]
+
+        psadbw          mm0,        mm1
+        psadbw          mm2,        mm3
+
+        lea             rsi,        [rsi+rbx*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        paddw           mm7,        mm0
+        paddw           mm7,        mm2
+
+        cmp             rsi,        rcx
+        jne             x8x16sad_wmt_loop
+
+        movd            rax,        mm7
+
+x8x16sad_wmt_early_exit:
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    pop         rbx
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_sad8x8_wmt(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+global sym(vp8_sad8x8_wmt)
+sym(vp8_sad8x8_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rbx*8]
+        pxor            mm7,        mm7
+
+x8x8sad_wmt_loop:
+
+        movd            rax,        mm7
+        cmp             rax,        arg(4)
+        jg              x8x8sad_wmt_early_exit
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm1,        QWORD PTR [rdi]
+
+        psadbw          mm0,        mm1
+        lea             rsi,        [rsi+rbx]
+
+        add             rdi,        rdx
+        paddw           mm7,        mm0
+
+        cmp             rsi,        rcx
+        jne             x8x8sad_wmt_loop
+
+        movd            rax,        mm7
+x8x8sad_wmt_early_exit:
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    pop         rbx
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;unsigned int vp8_sad4x4_wmt(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+global sym(vp8_sad4x4_wmt)
+sym(vp8_sad4x4_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        movd            mm0,       QWORD PTR [rsi]
+        movd            mm1,       QWORD PTR [rdi]
+
+        movd            mm2,       QWORD PTR [rsi+rax]
+        movd            mm3,       QWORD PTR [rdi+rdx]
+
+        punpcklbw       mm0,        mm2
+        punpcklbw       mm1,        mm3
+
+        psadbw          mm0,        mm1
+        lea             rsi,        [rsi+rax*2]
+
+        lea             rdi,        [rdi+rdx*2]
+        movd            mm4,       QWORD PTR [rsi]
+
+        movd            mm5,       QWORD PTR [rdi]
+        movd            mm6,       QWORD PTR [rsi+rax]
+
+        movd            mm7,       QWORD PTR [rdi+rdx]
+        punpcklbw       mm4,        mm6
+
+        punpcklbw       mm5,        mm7
+        psadbw          mm4,        mm5
+
+        paddw           mm0,        mm4
+        movd            rax,        mm0
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_sad16x8_wmt(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride)
+global sym(vp8_sad16x8_wmt)
+sym(vp8_sad16x8_wmt):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rbx*8]
+        pxor            mm7,        mm7
+
+x16x8sad_wmt_loop:
+
+        movd            rax,        mm7
+        cmp             rax,        arg(4)
+        jg              x16x8sad_wmt_early_exit
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm2,        QWORD PTR [rsi+8]
+
+        movq            mm1,        QWORD PTR [rdi]
+        movq            mm3,        QWORD PTR [rdi+8]
+
+        movq            mm4,        QWORD PTR [rsi+rbx]
+        movq            mm5,        QWORD PTR [rdi+rdx]
+
+        psadbw          mm0,        mm1
+        psadbw          mm2,        mm3
+
+        movq            mm1,        QWORD PTR [rsi+rbx+8]
+        movq            mm3,        QWORD PTR [rdi+rdx+8]
+
+        psadbw          mm4,        mm5
+        psadbw          mm1,        mm3
+
+        lea             rsi,        [rsi+rbx*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        paddw           mm0,        mm2
+        paddw           mm4,        mm1
+
+        paddw           mm7,        mm0
+        paddw           mm7,        mm4
+
+        cmp             rsi,        rcx
+        jne             x16x8sad_wmt_loop
+
+        movd            rax,        mm7
+
+x16x8sad_wmt_early_exit:
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    pop         rbx
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/sad_sse3.asm b/vp8/encoder/x86/sad_sse3.asm
new file mode 100644 (file)
index 0000000..38cc029
--- /dev/null
@@ -0,0 +1,939 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%idefine QWORD
+
+%macro PROCESS_16X2X3 1
+%if %1
+        movdqa          xmm0,       [rsi]
+        lddqu           xmm5,       [rdi]
+        lddqu           xmm6,       [rdi+1]
+        lddqu           xmm7,       [rdi+2]
+
+        psadbw          xmm5,       xmm0
+        psadbw          xmm6,       xmm0
+        psadbw          xmm7,       xmm0
+%else
+        movdqa          xmm0,       [rsi]
+        lddqu           xmm1,       [rdi]
+        lddqu           xmm2,       [rdi+1]
+        lddqu           xmm3,       [rdi+2]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm5,       xmm1
+        paddw           xmm6,       xmm2
+        paddw           xmm7,       xmm3
+%endif
+        movdqa          xmm0,       QWORD PTR [rsi+rax]
+        lddqu           xmm1,       QWORD PTR [rdi+rdx]
+        lddqu           xmm2,       QWORD PTR [rdi+rdx+1]
+        lddqu           xmm3,       QWORD PTR [rdi+rdx+2]
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm5,       xmm1
+        paddw           xmm6,       xmm2
+        paddw           xmm7,       xmm3
+%endmacro
+
+%macro PROCESS_8X2X3 1
+%if %1
+        movq            mm0,       [rsi]
+        movq            mm5,       [rdi]
+        movq            mm6,       [rdi+1]
+        movq            mm7,       [rdi+2]
+
+        psadbw          mm5,       mm0
+        psadbw          mm6,       mm0
+        psadbw          mm7,       mm0
+%else
+        movq            mm0,       [rsi]
+        movq            mm1,       [rdi]
+        movq            mm2,       [rdi+1]
+        movq            mm3,       [rdi+2]
+
+        psadbw          mm1,       mm0
+        psadbw          mm2,       mm0
+        psadbw          mm3,       mm0
+
+        paddw           mm5,       mm1
+        paddw           mm6,       mm2
+        paddw           mm7,       mm3
+%endif
+        movq            mm0,       QWORD PTR [rsi+rax]
+        movq            mm1,       QWORD PTR [rdi+rdx]
+        movq            mm2,       QWORD PTR [rdi+rdx+1]
+        movq            mm3,       QWORD PTR [rdi+rdx+2]
+
+        lea             rsi,       [rsi+rax*2]
+        lea             rdi,       [rdi+rdx*2]
+
+        psadbw          mm1,       mm0
+        psadbw          mm2,       mm0
+        psadbw          mm3,       mm0
+
+        paddw           mm5,       mm1
+        paddw           mm6,       mm2
+        paddw           mm7,       mm3
+%endmacro
+
+%macro LOAD_X4_ADDRESSES 5
+        mov             %2,         [%1+REG_SZ_BYTES*0]
+        mov             %3,         [%1+REG_SZ_BYTES*1]
+
+        mov             %4,         [%1+REG_SZ_BYTES*2]
+        mov             %5,         [%1+REG_SZ_BYTES*3]
+%endmacro
+
+%macro PROCESS_16X2X4 1
+%if %1
+        movdqa          xmm0,       [rsi]
+        lddqu           xmm4,       [rcx]
+        lddqu           xmm5,       [rdx]
+        lddqu           xmm6,       [rbx]
+        lddqu           xmm7,       [rdi]
+
+        psadbw          xmm4,       xmm0
+        psadbw          xmm5,       xmm0
+        psadbw          xmm6,       xmm0
+        psadbw          xmm7,       xmm0
+%else
+        movdqa          xmm0,       [rsi]
+        lddqu           xmm1,       [rcx]
+        lddqu           xmm2,       [rdx]
+        lddqu           xmm3,       [rbx]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm4,       xmm1
+        lddqu           xmm1,       [rdi]
+        paddw           xmm5,       xmm2
+        paddw           xmm6,       xmm3
+
+        psadbw          xmm1,       xmm0
+        paddw           xmm7,       xmm1
+%endif
+        movdqa          xmm0,       QWORD PTR [rsi+rax]
+        lddqu           xmm1,       QWORD PTR [rcx+rbp]
+        lddqu           xmm2,       QWORD PTR [rdx+rbp]
+        lddqu           xmm3,       QWORD PTR [rbx+rbp]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm4,       xmm1
+        lddqu           xmm1,       QWORD PTR [rdi+rbp]
+        paddw           xmm5,       xmm2
+        paddw           xmm6,       xmm3
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rcx,        [rcx+rbp*2]
+
+        lea             rdx,        [rdx+rbp*2]
+        lea             rbx,        [rbx+rbp*2]
+
+        lea             rdi,        [rdi+rbp*2]
+
+        psadbw          xmm1,       xmm0
+        paddw           xmm7,       xmm1
+
+%endmacro
+
+%macro PROCESS_8X2X4 1
+%if %1
+        movq            mm0,        [rsi]
+        movq            mm4,        [rcx]
+        movq            mm5,        [rdx]
+        movq            mm6,        [rbx]
+        movq            mm7,        [rdi]
+
+        psadbw          mm4,        mm0
+        psadbw          mm5,        mm0
+        psadbw          mm6,        mm0
+        psadbw          mm7,        mm0
+%else
+        movq            mm0,        [rsi]
+        movq            mm1,        [rcx]
+        movq            mm2,        [rdx]
+        movq            mm3,        [rbx]
+
+        psadbw          mm1,        mm0
+        psadbw          mm2,        mm0
+        psadbw          mm3,        mm0
+
+        paddw           mm4,        mm1
+        movq            mm1,        [rdi]
+        paddw           mm5,        mm2
+        paddw           mm6,        mm3
+
+        psadbw          mm1,        mm0
+        paddw           mm7,        mm1
+%endif
+        movq            mm0,        QWORD PTR [rsi+rax]
+        movq            mm1,        QWORD PTR [rcx+rbp]
+        movq            mm2,        QWORD PTR [rdx+rbp]
+        movq            mm3,        QWORD PTR [rbx+rbp]
+
+        psadbw          mm1,        mm0
+        psadbw          mm2,        mm0
+        psadbw          mm3,        mm0
+
+        paddw           mm4,        mm1
+        movq            mm1,        QWORD PTR [rdi+rbp]
+        paddw           mm5,        mm2
+        paddw           mm6,        mm3
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rcx,        [rcx+rbp*2]
+
+        lea             rdx,        [rdx+rbp*2]
+        lea             rbx,        [rbx+rbp*2]
+
+        lea             rdi,        [rdi+rbp*2]
+
+        psadbw          mm1,        mm0
+        paddw           mm7,        mm1
+
+%endmacro
+
+;void int vp8_sad16x16x3_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad16x16x3_sse3)
+sym(vp8_sad16x16x3_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        PROCESS_16X2X3 1
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+
+        mov             rdi,        arg(4) ;Results
+
+        movq            xmm0,       xmm5
+        psrldq          xmm5,       8
+
+        paddw           xmm0,       xmm5
+        movd            [rdi],      xmm0
+;-
+        movq            xmm0,       xmm6
+        psrldq          xmm6,       8
+
+        paddw           xmm0,       xmm6
+        movd            [rdi+4],    xmm0
+;-
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            [rdi+8],    xmm0
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad16x8x3_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad16x8x3_sse3)
+sym(vp8_sad16x8x3_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        PROCESS_16X2X3 1
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+
+        mov             rdi,        arg(4) ;Results
+
+        movq            xmm0,       xmm5
+        psrldq          xmm5,       8
+
+        paddw           xmm0,       xmm5
+        movd            [rdi],      xmm0
+;-
+        movq            xmm0,       xmm6
+        psrldq          xmm6,       8
+
+        paddw           xmm0,       xmm6
+        movd            [rdi+4],    xmm0
+;-
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            [rdi+8],    xmm0
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad8x16x3_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad8x16x3_sse3)
+sym(vp8_sad8x16x3_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        PROCESS_8X2X3 1
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+
+        mov             rdi,        arg(4) ;Results
+
+        movd            [rdi],      mm5
+        movd            [rdi+4],    mm6
+        movd            [rdi+8],    mm7
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad8x8x3_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad8x8x3_sse3)
+sym(vp8_sad8x8x3_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        PROCESS_8X2X3 1
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+        PROCESS_8X2X3 0
+
+        mov             rdi,        arg(4) ;Results
+
+        movd            [rdi],      mm5
+        movd            [rdi+4],    mm6
+        movd            [rdi+8],    mm7
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad4x4x3_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad4x4x3_sse3)
+sym(vp8_sad4x4x3_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        movd            mm0,        QWORD PTR [rsi]
+        movd            mm1,        QWORD PTR [rdi]
+
+        movd            mm2,        QWORD PTR [rsi+rax]
+        movd            mm3,        QWORD PTR [rdi+rdx]
+
+        punpcklbw       mm0,        mm2
+        punpcklbw       mm1,        mm3
+
+        movd            mm4,        QWORD PTR [rdi+1]
+        movd            mm5,        QWORD PTR [rdi+2]
+
+        movd            mm2,        QWORD PTR [rdi+rdx+1]
+        movd            mm3,        QWORD PTR [rdi+rdx+2]
+
+        psadbw          mm1,        mm0
+
+        punpcklbw       mm4,        mm2
+        punpcklbw       mm5,        mm3
+
+        psadbw          mm4,        mm0
+        psadbw          mm5,        mm0
+
+
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        movd            mm0,        QWORD PTR [rsi]
+        movd            mm2,        QWORD PTR [rdi]
+
+        movd            mm3,        QWORD PTR [rsi+rax]
+        movd            mm6,        QWORD PTR [rdi+rdx]
+
+        punpcklbw       mm0,        mm3
+        punpcklbw       mm2,        mm6
+
+        movd            mm3,        QWORD PTR [rdi+1]
+        movd            mm7,        QWORD PTR [rdi+2]
+
+        psadbw          mm2,        mm0
+
+        paddw           mm1,        mm2
+
+        movd            mm2,        QWORD PTR [rdi+rdx+1]
+        movd            mm6,        QWORD PTR [rdi+rdx+2]
+
+        punpcklbw       mm3,        mm2
+        punpcklbw       mm7,        mm6
+
+        psadbw          mm3,        mm0
+        psadbw          mm7,        mm0
+
+        paddw           mm3,        mm4
+        paddw           mm7,        mm5
+
+        mov             rdi,        arg(4) ;Results
+        movd            [rdi],      mm1
+
+        movd            [rdi+4],    mm3
+        movd            [rdi+8],    mm7
+
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;unsigned int vp8_sad16x16_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  max_err)
+;%define lddqu movdqu
+global sym(vp8_sad16x16_sse3)
+sym(vp8_sad16x16_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rbx
+    push        rsi
+    push        rdi
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        lea             rcx,        [rsi+rbx*8]
+
+        lea             rcx,        [rcx+rbx*8]
+        pxor            mm7,        mm7
+
+vp8_sad16x16_sse3_loop:
+
+        movd            rax,        mm7
+        cmp             rax,        arg(4)
+        jg              vp8_sad16x16_early_exit
+
+        movq            mm0,        QWORD PTR [rsi]
+        movq            mm2,        QWORD PTR [rsi+8]
+
+        movq            mm1,        QWORD PTR [rdi]
+        movq            mm3,        QWORD PTR [rdi+8]
+
+        movq            mm4,        QWORD PTR [rsi+rbx]
+        movq            mm5,        QWORD PTR [rdi+rdx]
+
+        psadbw          mm0,        mm1
+        psadbw          mm2,        mm3
+
+        movq            mm1,        QWORD PTR [rsi+rbx+8]
+        movq            mm3,        QWORD PTR [rdi+rdx+8]
+
+        psadbw          mm4,        mm5
+        psadbw          mm1,        mm3
+
+        lea             rsi,        [rsi+rbx*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        paddw           mm0,        mm2
+        paddw           mm4,        mm1
+
+        paddw           mm7,        mm0
+        paddw           mm7,        mm4
+
+        cmp             rsi,        rcx
+        jne             vp8_sad16x16_sse3_loop
+
+        movd            rax,        mm7
+
+vp8_sad16x16_early_exit:
+
+    ; begin epilog
+    pop         rdi
+    pop         rsi
+    pop         rbx
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void vp8_sad16x16x4d_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr_base,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad16x16x4d_sse3)
+sym(vp8_sad16x16x4d_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rbx
+    ; end prolog
+
+        push            rbp
+        mov             rdi,        arg(2) ; ref_ptr_base
+
+        LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+
+        mov             rsi,        arg(0) ;src_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rbp,        dword ptr arg(3) ;ref_stride
+
+        xchg            rbx,        rax
+
+        PROCESS_16X2X4 1
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+
+        pop             rbp
+        mov             rdi,        arg(4) ;Results
+
+        movq            xmm0,       xmm4
+        psrldq          xmm4,       8
+
+        paddw           xmm0,       xmm4
+        movd            [rdi],      xmm0
+;-
+        movq            xmm0,       xmm5
+        psrldq          xmm5,       8
+
+        paddw           xmm0,       xmm5
+        movd            [rdi+4],    xmm0
+;-
+        movq            xmm0,       xmm6
+        psrldq          xmm6,       8
+
+        paddw           xmm0,       xmm6
+        movd            [rdi+8],    xmm0
+;-
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            [rdi+12],   xmm0
+
+    ; begin epilog
+    pop         rbx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void vp8_sad16x8x4d_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr_base,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad16x8x4d_sse3)
+sym(vp8_sad16x8x4d_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rbx
+    ; end prolog
+
+        push            rbp
+        mov             rdi,        arg(2) ; ref_ptr_base
+
+        LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+
+        mov             rsi,        arg(0) ;src_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rbp,        dword ptr arg(3) ;ref_stride
+
+        xchg            rbx,        rax
+
+        PROCESS_16X2X4 1
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+        PROCESS_16X2X4 0
+
+        pop             rbp
+        mov             rdi,        arg(4) ;Results
+
+        movq            xmm0,       xmm4
+        psrldq          xmm4,       8
+
+        paddw           xmm0,       xmm4
+        movd            [rdi],      xmm0
+;-
+        movq            xmm0,       xmm5
+        psrldq          xmm5,       8
+
+        paddw           xmm0,       xmm5
+        movd            [rdi+4],    xmm0
+;-
+        movq            xmm0,       xmm6
+        psrldq          xmm6,       8
+
+        paddw           xmm0,       xmm6
+        movd            [rdi+8],    xmm0
+;-
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            [rdi+12],   xmm0
+
+    ; begin epilog
+    pop         rbx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad8x16x4d_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad8x16x4d_sse3)
+sym(vp8_sad8x16x4d_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rbx
+    ; end prolog
+
+        push            rbp
+        mov             rdi,        arg(2) ; ref_ptr_base
+
+        LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+
+        mov             rsi,        arg(0) ;src_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rbp,        dword ptr arg(3) ;ref_stride
+
+        xchg            rbx,        rax
+
+        PROCESS_8X2X4 1
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+
+        pop             rbp
+        mov             rdi,        arg(4) ;Results
+
+        movd            [rdi],      mm4
+        movd            [rdi+4],    mm5
+        movd            [rdi+8],    mm6
+        movd            [rdi+12],   mm7
+
+    ; begin epilog
+    pop         rbx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad8x8x4d_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad8x8x4d_sse3)
+sym(vp8_sad8x8x4d_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rbx
+    ; end prolog
+
+        push            rbp
+        mov             rdi,        arg(2) ; ref_ptr_base
+
+        LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+
+        mov             rsi,        arg(0) ;src_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rbp,        dword ptr arg(3) ;ref_stride
+
+        xchg            rbx,        rax
+
+        PROCESS_8X2X4 1
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+        PROCESS_8X2X4 0
+
+        pop             rbp
+        mov             rdi,        arg(4) ;Results
+
+        movd            [rdi],      mm4
+        movd            [rdi+4],    mm5
+        movd            [rdi+8],    mm6
+        movd            [rdi+12],   mm7
+
+    ; begin epilog
+    pop         rbx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad4x4x4d_sse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad4x4x4d_sse3)
+sym(vp8_sad4x4x4d_sse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rbx
+    ; end prolog
+
+        push            rbp
+        mov             rdi,        arg(2) ; ref_ptr_base
+
+        LOAD_X4_ADDRESSES rdi, rcx, rdx, rax, rdi
+
+        mov             rsi,        arg(0) ;src_ptr
+
+        movsxd          rbx,        dword ptr arg(1) ;src_stride
+        movsxd          rbp,        dword ptr arg(3) ;ref_stride
+
+        xchg            rbx,        rax
+
+        movd            mm0,        QWORD PTR [rsi]
+        movd            mm1,        QWORD PTR [rcx]
+
+        movd            mm2,        QWORD PTR [rsi+rax]
+        movd            mm3,        QWORD PTR [rcx+rbp]
+
+        punpcklbw       mm0,        mm2
+        punpcklbw       mm1,        mm3
+
+        movd            mm4,        QWORD PTR [rdx]
+        movd            mm5,        QWORD PTR [rbx]
+
+        movd            mm6,        QWORD PTR [rdi]
+        movd            mm2,        QWORD PTR [rdx+rbp]
+
+        movd            mm3,        QWORD PTR [rbx+rbp]
+        movd            mm7,        QWORD PTR [rdi+rbp]
+
+        psadbw          mm1,        mm0
+
+        punpcklbw       mm4,        mm2
+        punpcklbw       mm5,        mm3
+
+        punpcklbw       mm6,        mm7
+        psadbw          mm4,        mm0
+
+        psadbw          mm5,        mm0
+        psadbw          mm6,        mm0
+
+
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rcx,        [rcx+rbp*2]
+
+        lea             rdx,        [rdx+rbp*2]
+        lea             rbx,        [rbx+rbp*2]
+
+        lea             rdi,        [rdi+rbp*2]
+
+        movd            mm0,        QWORD PTR [rsi]
+        movd            mm2,        QWORD PTR [rcx]
+
+        movd            mm3,        QWORD PTR [rsi+rax]
+        movd            mm7,        QWORD PTR [rcx+rbp]
+
+        punpcklbw       mm0,        mm3
+        punpcklbw       mm2,        mm7
+
+        movd            mm3,        QWORD PTR [rdx]
+        movd            mm7,        QWORD PTR [rbx]
+
+        psadbw          mm2,        mm0
+        mov             rax,        rbp
+
+        pop             rbp
+        mov             rsi,        arg(4) ;Results
+
+        paddw           mm1,        mm2
+        movd            [rsi],      mm1
+
+        movd            mm2,        QWORD PTR [rdx+rax]
+        movd            mm1,        QWORD PTR [rbx+rax]
+
+        punpcklbw       mm3,        mm2
+        punpcklbw       mm7,        mm1
+
+        psadbw          mm3,        mm0
+        psadbw          mm7,        mm0
+
+        movd            mm2,        QWORD PTR [rdi]
+        movd            mm1,        QWORD PTR [rdi+rax]
+
+        paddw           mm3,        mm4
+        paddw           mm7,        mm5
+
+        movd            [rsi+4],    mm3
+        punpcklbw       mm2,        mm1
+
+        movd            [rsi+8],    mm7
+        psadbw          mm2,        mm0
+
+        paddw           mm2,        mm6
+        movd            [rsi+12],   mm2
+
+
+    ; begin epilog
+    pop         rbx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/sad_ssse3.asm b/vp8/encoder/x86/sad_ssse3.asm
new file mode 100644 (file)
index 0000000..1bb9561
--- /dev/null
@@ -0,0 +1,367 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%idefine QWORD
+
+%macro PROCESS_16X2X3 1
+%if %1
+        movdqa          xmm0,       [rsi]
+        lddqu           xmm5,       [rdi]
+        lddqu           xmm6,       [rdi+1]
+        lddqu           xmm7,       [rdi+2]
+
+        psadbw          xmm5,       xmm0
+        psadbw          xmm6,       xmm0
+        psadbw          xmm7,       xmm0
+%else
+        movdqa          xmm0,       [rsi]
+        lddqu           xmm1,       [rdi]
+        lddqu           xmm2,       [rdi+1]
+        lddqu           xmm3,       [rdi+2]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm5,       xmm1
+        paddw           xmm6,       xmm2
+        paddw           xmm7,       xmm3
+%endif
+        movdqa          xmm0,       QWORD PTR [rsi+rax]
+        lddqu           xmm1,       QWORD PTR [rdi+rdx]
+        lddqu           xmm2,       QWORD PTR [rdi+rdx+1]
+        lddqu           xmm3,       QWORD PTR [rdi+rdx+2]
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm5,       xmm1
+        paddw           xmm6,       xmm2
+        paddw           xmm7,       xmm3
+%endmacro
+
+%macro PROCESS_16X2X3_OFFSET 2
+%if %1
+        movdqa          xmm0,       [rsi]
+        movdqa          xmm4,       [rdi]
+        movdqa          xmm7,       [rdi+16]
+
+        movdqa          xmm5,       xmm7
+        palignr         xmm5,       xmm4,       %2
+
+        movdqa          xmm6,       xmm7
+        palignr         xmm6,       xmm4,       (%2+1)
+
+        palignr         xmm7,       xmm4,       (%2+2)
+
+        psadbw          xmm5,       xmm0
+        psadbw          xmm6,       xmm0
+        psadbw          xmm7,       xmm0
+%else
+        movdqa          xmm0,       [rsi]
+        movdqa          xmm4,       [rdi]
+        movdqa          xmm3,       [rdi+16]
+
+        movdqa          xmm1,       xmm3
+        palignr         xmm1,       xmm4,       %2
+
+        movdqa          xmm2,       xmm3
+        palignr         xmm2,       xmm4,       (%2+1)
+
+        palignr         xmm3,       xmm4,       (%2+2)
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm5,       xmm1
+        paddw           xmm6,       xmm2
+        paddw           xmm7,       xmm3
+%endif
+        movdqa          xmm0,       QWORD PTR [rsi+rax]
+        movdqa          xmm4,       QWORD PTR [rdi+rdx]
+        movdqa          xmm3,       QWORD PTR [rdi+rdx+16]
+
+        movdqa          xmm1,       xmm3
+        palignr         xmm1,       xmm4,       %2
+
+        movdqa          xmm2,       xmm3
+        palignr         xmm2,       xmm4,       (%2+1)
+
+        palignr         xmm3,       xmm4,       (%2+2)
+
+        lea             rsi,        [rsi+rax*2]
+        lea             rdi,        [rdi+rdx*2]
+
+        psadbw          xmm1,       xmm0
+        psadbw          xmm2,       xmm0
+        psadbw          xmm3,       xmm0
+
+        paddw           xmm5,       xmm1
+        paddw           xmm6,       xmm2
+        paddw           xmm7,       xmm3
+%endmacro
+
+%macro PROCESS_16X16X3_OFFSET 2
+%2_aligned_by_%1:
+
+        sub             rdi,        %1
+
+        PROCESS_16X2X3_OFFSET 1, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+
+        jmp             %2_store_off
+
+%endmacro
+
+%macro PROCESS_16X8X3_OFFSET 2
+%2_aligned_by_%1:
+
+        sub             rdi,        %1
+
+        PROCESS_16X2X3_OFFSET 1, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+        PROCESS_16X2X3_OFFSET 0, %1
+
+        jmp             %2_store_off
+
+%endmacro
+
+;void int vp8_sad16x16x3_ssse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad16x16x3_ssse3)
+sym(vp8_sad16x16x3_ssse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rcx
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        mov             rdx,        0xf
+        and             rdx,        rdi
+
+        jmp vp8_sad16x16x3_ssse3_skiptable
+vp8_sad16x16x3_ssse3_jumptable:
+        dd vp8_sad16x16x3_ssse3_aligned_by_0  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_1  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_2  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_3  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_4  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_5  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_6  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_7  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_8  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_9  - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_10 - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_11 - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_12 - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_13 - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_14 - vp8_sad16x16x3_ssse3_do_jump
+        dd vp8_sad16x16x3_ssse3_aligned_by_15 - vp8_sad16x16x3_ssse3_do_jump
+vp8_sad16x16x3_ssse3_skiptable:
+
+        call vp8_sad16x16x3_ssse3_do_jump
+vp8_sad16x16x3_ssse3_do_jump:
+        pop             rcx                         ; get the address of do_jump
+        mov             rax,  vp8_sad16x16x3_ssse3_jumptable - vp8_sad16x16x3_ssse3_do_jump
+        add             rax,  rcx  ; get the absolute address of vp8_sad16x16x3_ssse3_jumptable
+
+        movsxd          rax,  dword [rax + 4*rdx]   ; get the 32 bit offset from the jumptable
+        add             rcx,        rax
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        jmp             rcx
+
+        PROCESS_16X16X3_OFFSET 0,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 1,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 2,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 3,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 4,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 5,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 6,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 7,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 8,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 9,  vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 10, vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 11, vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 12, vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 13, vp8_sad16x16x3_ssse3
+        PROCESS_16X16X3_OFFSET 14, vp8_sad16x16x3_ssse3
+
+vp8_sad16x16x3_ssse3_aligned_by_15:
+        PROCESS_16X2X3 1
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+
+vp8_sad16x16x3_ssse3_store_off:
+        mov             rdi,        arg(4) ;Results
+
+        movq            xmm0,       xmm5
+        psrldq          xmm5,       8
+
+        paddw           xmm0,       xmm5
+        movd            [rdi],      xmm0
+;-
+        movq            xmm0,       xmm6
+        psrldq          xmm6,       8
+
+        paddw           xmm0,       xmm6
+        movd            [rdi+4],    xmm0
+;-
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            [rdi+8],    xmm0
+
+    ; begin epilog
+    pop         rcx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void int vp8_sad16x8x3_ssse3(
+;    unsigned char *src_ptr,
+;    int  src_stride,
+;    unsigned char *ref_ptr,
+;    int  ref_stride,
+;    int  *results)
+global sym(vp8_sad16x8x3_ssse3)
+sym(vp8_sad16x8x3_ssse3):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push        rsi
+    push        rdi
+    push        rcx
+    ; end prolog
+
+        mov             rsi,        arg(0) ;src_ptr
+        mov             rdi,        arg(2) ;ref_ptr
+
+        mov             rdx,        0xf
+        and             rdx,        rdi
+
+        jmp vp8_sad16x8x3_ssse3_skiptable
+vp8_sad16x8x3_ssse3_jumptable:
+        dd vp8_sad16x8x3_ssse3_aligned_by_0  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_1  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_2  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_3  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_4  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_5  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_6  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_7  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_8  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_9  - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_10 - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_11 - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_12 - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_13 - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_14 - vp8_sad16x8x3_ssse3_do_jump
+        dd vp8_sad16x8x3_ssse3_aligned_by_15 - vp8_sad16x8x3_ssse3_do_jump
+vp8_sad16x8x3_ssse3_skiptable:
+
+        call vp8_sad16x8x3_ssse3_do_jump
+vp8_sad16x8x3_ssse3_do_jump:
+        pop             rcx                         ; get the address of do_jump
+        mov             rax,  vp8_sad16x8x3_ssse3_jumptable - vp8_sad16x8x3_ssse3_do_jump
+        add             rax,  rcx  ; get the absolute address of vp8_sad16x8x3_ssse3_jumptable
+
+        movsxd          rax,  dword [rax + 4*rdx]   ; get the 32 bit offset from the jumptable
+        add             rcx,        rax
+
+        movsxd          rax,        dword ptr arg(1) ;src_stride
+        movsxd          rdx,        dword ptr arg(3) ;ref_stride
+
+        jmp             rcx
+
+        PROCESS_16X8X3_OFFSET 0,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 1,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 2,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 3,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 4,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 5,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 6,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 7,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 8,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 9,  vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 10, vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 11, vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 12, vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 13, vp8_sad16x8x3_ssse3
+        PROCESS_16X8X3_OFFSET 14, vp8_sad16x8x3_ssse3
+
+vp8_sad16x8x3_ssse3_aligned_by_15:
+
+        PROCESS_16X2X3 1
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+        PROCESS_16X2X3 0
+
+vp8_sad16x8x3_ssse3_store_off:
+        mov             rdi,        arg(4) ;Results
+
+        movq            xmm0,       xmm5
+        psrldq          xmm5,       8
+
+        paddw           xmm0,       xmm5
+        movd            [rdi],      xmm0
+;-
+        movq            xmm0,       xmm6
+        psrldq          xmm6,       8
+
+        paddw           xmm0,       xmm6
+        movd            [rdi+4],    xmm0
+;-
+        movq            xmm0,       xmm7
+        psrldq          xmm7,       8
+
+        paddw           xmm0,       xmm7
+        movd            [rdi+8],    xmm0
+
+    ; begin epilog
+    pop         rcx
+    pop         rdi
+    pop         rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/subtract_mmx.asm b/vp8/encoder/x86/subtract_mmx.asm
new file mode 100644 (file)
index 0000000..ce3e610
--- /dev/null
@@ -0,0 +1,431 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;void vp8_subtract_b_mmx_impl(unsigned char *z,  int src_stride,
+;                            unsigned short *diff, unsigned char *Predictor,
+;                            int pitch);
+global sym(vp8_subtract_b_mmx_impl)
+sym(vp8_subtract_b_mmx_impl)
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push rsi
+    push rdi
+    ; end prolog
+
+
+        mov     rdi,        arg(2) ;diff
+        mov     rax,        arg(3) ;Predictor
+        mov     rsi,        arg(0) ;z
+        movsxd  rdx,        dword ptr arg(1);src_stride;
+        movsxd  rcx,        dword ptr arg(4);pitch
+        pxor    mm7,        mm7
+
+        movd    mm0,        [rsi]
+        movd    mm1,        [rax]
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+        psubw   mm0,        mm1
+        movq    [rdi],      mm0
+
+
+        movd    mm0,        [rsi+rdx]
+        movd    mm1,        [rax+rcx]
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+        psubw   mm0,        mm1
+        movq    [rdi+rcx*2],mm0
+
+
+        movd    mm0,        [rsi+rdx*2]
+        movd    mm1,        [rax+rcx*2]
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+        psubw   mm0,        mm1
+        movq    [rdi+rcx*4],        mm0
+
+        lea     rsi,        [rsi+rdx*2]
+        lea     rcx,        [rcx+rcx*2]
+
+
+
+        movd    mm0,        [rsi+rdx]
+        movd    mm1,        [rax+rcx]
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+        psubw   mm0,        mm1
+        movq    [rdi+rcx*2],        mm0
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void vp8_subtract_mby_mmx(short *diff, unsigned char *src, unsigned char *pred, int stride)
+global sym(vp8_subtract_mby_mmx)
+sym(vp8_subtract_mby_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    ; end prolog
+
+
+            mov         rsi,            arg(1) ;src
+            mov         rdi,            arg(0) ;diff
+
+            mov         rax,            arg(2) ;pred
+            movsxd      rdx,            dword ptr arg(3) ;stride
+
+            mov         rcx,            16
+            pxor        mm0,            mm0
+
+submby_loop:
+
+            movq        mm1,            [rsi]
+            movq        mm3,            [rax]
+
+            movq        mm2,            mm1
+            movq        mm4,            mm3
+
+            punpcklbw   mm1,            mm0
+            punpcklbw   mm3,            mm0
+
+            punpckhbw   mm2,            mm0
+            punpckhbw   mm4,            mm0
+
+            psubw       mm1,            mm3
+            psubw       mm2,            mm4
+
+            movq        [rdi],          mm1
+            movq        [rdi+8],        mm2
+
+
+            movq        mm1,            [rsi+8]
+            movq        mm3,            [rax+8]
+
+            movq        mm2,            mm1
+            movq        mm4,            mm3
+
+            punpcklbw   mm1,            mm0
+            punpcklbw   mm3,            mm0
+
+            punpckhbw   mm2,            mm0
+            punpckhbw   mm4,            mm0
+
+            psubw       mm1,            mm3
+            psubw       mm2,            mm4
+
+            movq        [rdi+16],       mm1
+            movq        [rdi+24],       mm2
+
+
+            add         rdi,            32
+            add         rax,            16
+
+            lea         rsi,            [rsi+rdx]
+
+            sub         rcx,            1
+            jnz         submby_loop
+
+    pop rdi
+    pop rsi
+    ; begin epilog
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_subtract_mbuv_mmx(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride)
+global sym(vp8_subtract_mbuv_mmx)
+sym(vp8_subtract_mbuv_mmx)
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 5
+    push rsi
+    push rdi
+    ; end prolog
+
+    ;short *udiff = diff + 256;
+    ;short *vdiff = diff + 320;
+    ;unsigned char *upred = pred + 256;
+    ;unsigned char *vpred = pred + 320;
+
+        ;unsigned char  *z    = usrc;
+        ;unsigned short *diff = udiff;
+        ;unsigned char  *Predictor= upred;
+
+            mov     rdi,        arg(0) ;diff
+            mov     rax,        arg(3) ;pred
+            mov     rsi,        arg(1) ;z = usrc
+            add     rdi,        256*2  ;diff = diff + 256 (shorts)
+            add     rax,        256    ;Predictor = pred + 256
+            movsxd  rdx,        dword ptr arg(4) ;stride;
+            pxor    mm7,        mm7
+
+            movq    mm0,        [rsi]
+            movq    mm1,        [rax]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi],      mm0
+            movq    [rdi+8],    mm3
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+8]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+16],   mm0
+            movq    [rdi+24],   mm3
+
+            movq    mm0,        [rsi+rdx*2]
+            movq    mm1,        [rax+16]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+32],   mm0
+            movq    [rdi+40],   mm3
+            lea     rsi,        [rsi+rdx*2]
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+24]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+
+            movq    [rdi+48],   mm0
+            movq    [rdi+56],   mm3
+
+
+            add     rdi,        64
+            add     rax,        32
+            lea     rsi,        [rsi+rdx*2]
+
+
+            movq    mm0,        [rsi]
+            movq    mm1,        [rax]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi],      mm0
+            movq    [rdi+8],    mm3
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+8]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+16],   mm0
+            movq    [rdi+24],   mm3
+
+            movq    mm0,        [rsi+rdx*2]
+            movq    mm1,        [rax+16]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+32],   mm0
+            movq    [rdi+40],   mm3
+            lea     rsi,        [rsi+rdx*2]
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+24]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+
+            movq    [rdi+48],   mm0
+            movq    [rdi+56],   mm3
+
+        ;unsigned char  *z    = vsrc;
+        ;unsigned short *diff = vdiff;
+        ;unsigned char  *Predictor= vpred;
+
+            mov     rdi,        arg(0) ;diff
+            mov     rax,        arg(3) ;pred
+            mov     rsi,        arg(2) ;z = usrc
+            add     rdi,        320*2  ;diff = diff + 320 (shorts)
+            add     rax,        320    ;Predictor = pred + 320
+            movsxd  rdx,        dword ptr arg(4) ;stride;
+            pxor    mm7,        mm7
+
+            movq    mm0,        [rsi]
+            movq    mm1,        [rax]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi],      mm0
+            movq    [rdi+8],    mm3
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+8]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+16],   mm0
+            movq    [rdi+24],   mm3
+
+            movq    mm0,        [rsi+rdx*2]
+            movq    mm1,        [rax+16]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+32],   mm0
+            movq    [rdi+40],   mm3
+            lea     rsi,        [rsi+rdx*2]
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+24]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+
+            movq    [rdi+48],   mm0
+            movq    [rdi+56],   mm3
+
+
+            add     rdi,        64
+            add     rax,        32
+            lea     rsi,        [rsi+rdx*2]
+
+
+            movq    mm0,        [rsi]
+            movq    mm1,        [rax]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi],      mm0
+            movq    [rdi+8],    mm3
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+8]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+16],   mm0
+            movq    [rdi+24],   mm3
+
+            movq    mm0,        [rsi+rdx*2]
+            movq    mm1,        [rax+16]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+            movq    [rdi+32],   mm0
+            movq    [rdi+40],   mm3
+            lea     rsi,        [rsi+rdx*2]
+
+
+            movq    mm0,        [rsi+rdx]
+            movq    mm1,        [rax+24]
+            movq    mm3,        mm0
+            movq    mm4,        mm1
+            punpcklbw   mm0,    mm7
+            punpcklbw   mm1,    mm7
+            punpckhbw   mm3,    mm7
+            punpckhbw   mm4,    mm7
+            psubw   mm0,        mm1
+            psubw   mm3,        mm4
+
+            movq    [rdi+48],   mm0
+            movq    [rdi+56],   mm3
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
diff --git a/vp8/encoder/x86/variance_impl_mmx.asm b/vp8/encoder/x86/variance_impl_mmx.asm
new file mode 100644 (file)
index 0000000..d0da82a
--- /dev/null
@@ -0,0 +1,980 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+;unsigned int vp8_get_mb_ss_mmx( short *src_ptr )
+global sym(vp8_get_mb_ss_mmx)
+sym(vp8_get_mb_ss_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 8
+    ; end prolog
+
+        mov         rax, arg(0) ;src_ptr
+        mov         rcx, 16
+        pxor        mm4, mm4
+
+NEXTROW:
+        movq        mm0, [rax]
+        movq        mm1, [rax+8]
+        movq        mm2, [rax+16]
+        movq        mm3, [rax+24]
+        pmaddwd     mm0, mm0
+        pmaddwd     mm1, mm1
+        pmaddwd     mm2, mm2
+        pmaddwd     mm3, mm3
+
+        paddd       mm4, mm0
+        paddd       mm4, mm1
+        paddd       mm4, mm2
+        paddd       mm4, mm3
+
+        add         rax, 32
+        dec         rcx
+        ja          NEXTROW
+        movq        QWORD PTR [rsp], mm4
+
+        ;return sum[0]+sum[1];
+        movsxd      rax, dword ptr [rsp]
+        movsxd      rcx, dword ptr [rsp+4]
+        add         rax, rcx
+
+
+    ; begin epilog
+    add rsp, 8
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_get8x8var_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  source_stride,
+;    unsigned char *ref_ptr,
+;    int  recon_stride,
+;    unsigned int *SSE,
+;    int *Sum
+;)
+global sym(vp8_get8x8var_mmx)
+sym(vp8_get8x8var_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    push rsi
+    push rdi
+    push rbx
+    sub         rsp, 16
+    ; end prolog
+
+
+        pxor        mm5, mm5                    ; Blank mmx6
+        pxor        mm6, mm6                    ; Blank mmx7
+        pxor        mm7, mm7                    ; Blank mmx7
+
+        mov         rax, arg(0) ;[src_ptr]  ; Load base addresses
+        mov         rbx, arg(2) ;[ref_ptr]
+        movsxd      rcx, dword ptr arg(1) ;[source_stride]
+        movsxd      rdx, dword ptr arg(3) ;[recon_stride]
+
+        ; Row 1
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+
+        ; Row 2
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Row 3
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Row 4
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Row 5
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        ;              movq        mm4, [rbx + rdx]
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Row 6
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Row 7
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Row 8
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm2, mm0                    ; Take copies
+        movq        mm3, mm1                    ; Take copies
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        punpckhbw   mm2, mm6                    ; unpack to higher prrcision
+        punpckhbw   mm3, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        psubsw      mm2, mm3                    ; A-B (high order) to MM2
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        paddw       mm5, mm2                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        pmaddwd     mm2, mm2                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        paddd       mm7, mm0                    ; accumulate in mm7
+        paddd       mm7, mm2                    ; accumulate in mm7
+
+        ; Now accumulate the final results.
+        movq        QWORD PTR [rsp+8], mm5      ; copy back accumulated results into normal memory
+        movq        QWORD PTR [rsp], mm7        ; copy back accumulated results into normal memory
+        movsx       rdx, WORD PTR [rsp+8]
+        movsx       rcx, WORD PTR [rsp+10]
+        movsx       rbx, WORD PTR [rsp+12]
+        movsx       rax, WORD PTR [rsp+14]
+        add         rdx, rcx
+        add         rbx, rax
+        add         rdx, rbx    ;XSum
+        movsxd      rax, DWORD PTR [rsp]
+        movsxd      rcx, DWORD PTR [rsp+4]
+        add         rax, rcx    ;XXSum
+        mov         rsi, arg(4) ;SSE
+        mov         rdi, arg(5) ;Sum
+        mov         dword ptr [rsi], eax
+        mov         dword ptr [rdi], edx
+        xor         rax, rax    ; return 0
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rbx
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+;unsigned int
+;vp8_get4x4var_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  source_stride,
+;    unsigned char *ref_ptr,
+;    int  recon_stride,
+;    unsigned int *SSE,
+;    int *Sum
+;)
+global sym(vp8_get4x4var_mmx)
+sym(vp8_get4x4var_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    push rsi
+    push rdi
+    push rbx
+    sub         rsp, 16
+    ; end prolog
+
+
+        pxor        mm5, mm5                    ; Blank mmx6
+        pxor        mm6, mm6                    ; Blank mmx7
+        pxor        mm7, mm7                    ; Blank mmx7
+
+        mov         rax, arg(0) ;[src_ptr]  ; Load base addresses
+        mov         rbx, arg(2) ;[ref_ptr]
+        movsxd      rcx, dword ptr arg(1) ;[source_stride]
+        movsxd      rdx, dword ptr arg(3) ;[recon_stride]
+
+        ; Row 1
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+
+        ; Row 2
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+        ; Row 3
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movq        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+        ; Row 4
+        movq        mm0, [rax]                  ; Copy eight bytes to mm0
+
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+
+        paddw       mm5, mm0                    ; accumulate differences in mm5
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+
+        ; Now accumulate the final results.
+        movq        QWORD PTR [rsp+8], mm5      ; copy back accumulated results into normal memory
+        movq        QWORD PTR [rsp], mm7        ; copy back accumulated results into normal memory
+        movsx       rdx, WORD PTR [rsp+8]
+        movsx       rcx, WORD PTR [rsp+10]
+        movsx       rbx, WORD PTR [rsp+12]
+        movsx       rax, WORD PTR [rsp+14]
+        add         rdx, rcx
+        add         rbx, rax
+        add         rdx, rbx    ;XSum
+        movsxd      rax, DWORD PTR [rsp]
+        movsxd      rcx, DWORD PTR [rsp+4]
+        add         rax, rcx    ;XXSum
+        mov         rsi, arg(4) ;SSE
+        mov         rdi, arg(5) ;Sum
+        mov         dword ptr [rsi], eax
+        mov         dword ptr [rdi], edx
+        xor         rax, rax    ; return 0
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rbx
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+;unsigned int
+;vp8_get4x4sse_cs_mmx
+;(
+;    unsigned char *src_ptr,
+;    int  source_stride,
+;    unsigned char *ref_ptr,
+;    int  recon_stride
+;)
+global sym(vp8_get4x4sse_cs_mmx)
+sym(vp8_get4x4sse_cs_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    push rsi
+    push rdi
+    push rbx
+    ; end prolog
+
+
+        pxor        mm6, mm6                    ; Blank mmx7
+        pxor        mm7, mm7                    ; Blank mmx7
+
+        mov         rax, arg(0) ;[src_ptr]  ; Load base addresses
+        mov         rbx, arg(2) ;[ref_ptr]
+        movsxd      rcx, dword ptr arg(1) ;[source_stride]
+        movsxd      rdx, dword ptr arg(3) ;[recon_stride]
+        ; Row 1
+        movd        mm0, [rax]                  ; Copy eight bytes to mm0
+        movd        mm1, [rbx]                  ; Copy eight bytes to mm1
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movd        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+        ; Row 2
+        movd        mm0, [rax]                  ; Copy eight bytes to mm0
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movd        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+        ; Row 3
+        movd        mm0, [rax]                  ; Copy eight bytes to mm0
+        punpcklbw   mm1, mm6
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        add         rbx,rdx                     ; Inc pointer into ref data
+        add         rax,rcx                     ; Inc pointer into the new data
+        movd        mm1, [rbx]                  ; Copy eight bytes to mm1
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+        ; Row 4
+        movd        mm0, [rax]                  ; Copy eight bytes to mm0
+        punpcklbw   mm0, mm6                    ; unpack to higher prrcision
+        punpcklbw   mm1, mm6
+        psubsw      mm0, mm1                    ; A-B (low order) to MM0
+        pmaddwd     mm0, mm0                    ; square and accumulate
+        paddd       mm7, mm0                    ; accumulate in mm7
+
+        movq        mm0,    mm7                 ;
+        psrlq       mm7,    32
+
+        paddd       mm0,    mm7
+        movd        rax,    mm0
+
+
+    ; begin epilog
+    pop rbx
+    pop rdi
+    pop rsi
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+%define mmx_filter_shift            7
+
+;void vp8_filter_block2d_bil4x4_var_mmx
+;(
+;    unsigned char *ref_ptr,
+;    int ref_pixels_per_line,
+;    unsigned char *src_ptr,
+;    int src_pixels_per_line,
+;    unsigned short *HFilter,
+;    unsigned short *VFilter,
+;    int *sum,
+;    unsigned int *sumsquared
+;)
+global sym(vp8_filter_block2d_bil4x4_var_mmx)
+sym(vp8_filter_block2d_bil4x4_var_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 8
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+
+        pxor            mm6,            mm6                 ;
+        pxor            mm7,            mm7                 ;
+
+        mov             rax,            arg(4) ;HFilter             ;
+        mov             rdx,            arg(5) ;VFilter             ;
+
+        mov             rsi,            arg(0) ;ref_ptr              ;
+        mov             rdi,            arg(2) ;src_ptr              ;
+
+        mov             rcx,            4                   ;
+        pxor            mm0,            mm0                 ;
+
+        movd            mm1,            [rsi]               ;
+        movd            mm3,            [rsi+1]             ;
+
+        punpcklbw       mm1,            mm0                 ;
+        pmullw          mm1,            [rax]               ;
+
+        punpcklbw       mm3,            mm0                 ;
+        pmullw          mm3,            [rax+8]             ;
+
+        paddw           mm1,            mm3                 ;
+        paddw           mm1,            [mmx_bi_rd GLOBAL]  ;
+
+        psraw           mm1,            mmx_filter_shift    ;
+        movq            mm5,            mm1
+
+%if ABI_IS_32BIT
+        add             rsi, dword ptr  arg(1) ;ref_pixels_per_line    ;
+%else
+        movsxd          r8, dword ptr  arg(1) ;ref_pixels_per_line    ;
+        add             rsi, r8
+%endif
+
+filter_block2d_bil4x4_var_mmx_loop:
+
+        movd            mm1,            [rsi]               ;
+        movd            mm3,            [rsi+1]             ;
+
+        punpcklbw       mm1,            mm0                 ;
+        pmullw          mm1,            [rax]               ;
+
+        punpcklbw       mm3,            mm0                 ;
+        pmullw          mm3,            [rax+8]             ;
+
+        paddw           mm1,            mm3                 ;
+        paddw           mm1,            [mmx_bi_rd GLOBAL]  ;
+
+        psraw           mm1,            mmx_filter_shift    ;
+        movq            mm3,            mm5                 ;
+
+        movq            mm5,            mm1                 ;
+        pmullw          mm3,            [rdx]               ;
+
+        pmullw          mm1,            [rdx+8]             ;
+        paddw           mm1,            mm3                 ;
+
+
+        paddw           mm1,            [mmx_bi_rd GLOBAL]  ;
+        psraw           mm1,            mmx_filter_shift    ;
+
+        movd            mm3,            [rdi]               ;
+        punpcklbw       mm3,            mm0                 ;
+
+        psubw           mm1,            mm3                 ;
+        paddw           mm6,            mm1                 ;
+
+        pmaddwd         mm1,            mm1                 ;
+        paddd           mm7,            mm1                 ;
+
+%if ABI_IS_32BIT
+        add             rsi,            dword ptr arg(1) ;ref_pixels_per_line    ;
+        add             rdi,            dword ptr arg(3) ;src_pixels_per_line    ;
+%else
+        movsxd          r8,             dword ptr arg(1) ;ref_pixels_per_line
+        movsxd          r9,             dword ptr arg(3) ;src_pixels_per_line
+        add             rsi,            r8
+        add             rdi,            r9
+%endif
+        sub             rcx,            1                   ;
+        jnz             filter_block2d_bil4x4_var_mmx_loop       ;
+
+
+        pxor            mm3,            mm3                 ;
+        pxor            mm2,            mm2                 ;
+
+        punpcklwd       mm2,            mm6                 ;
+        punpckhwd       mm3,            mm6                 ;
+
+        paddd           mm2,            mm3                 ;
+        movq            mm6,            mm2                 ;
+
+        psrlq           mm6,            32                  ;
+        paddd           mm2,            mm6                 ;
+
+        psrad           mm2,            16                  ;
+        movq            mm4,            mm7                 ;
+
+        psrlq           mm4,            32                  ;
+        paddd           mm4,            mm7                 ;
+
+        mov             rdi,            arg(6) ;sum
+        mov             rsi,            arg(7) ;sumsquared
+
+        movd            dword ptr [rdi],          mm2                 ;
+        movd            dword ptr [rsi],          mm4                 ;
+
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+
+;void vp8_filter_block2d_bil_var_mmx
+;(
+;    unsigned char *ref_ptr,
+;    int ref_pixels_per_line,
+;    unsigned char *src_ptr,
+;    int src_pixels_per_line,
+;    unsigned int Height,
+;    unsigned short *HFilter,
+;    unsigned short *VFilter,
+;    int *sum,
+;    unsigned int *sumsquared
+;)
+global sym(vp8_filter_block2d_bil_var_mmx)
+sym(vp8_filter_block2d_bil_var_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 9
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+        pxor            mm6,            mm6                 ;
+        pxor            mm7,            mm7                 ;
+        mov             rax,            arg(5) ;HFilter             ;
+
+        mov             rdx,            arg(6) ;VFilter             ;
+        mov             rsi,            arg(0) ;ref_ptr              ;
+
+        mov             rdi,            arg(2) ;src_ptr              ;
+        movsxd          rcx,            dword ptr arg(4) ;Height              ;
+
+        pxor            mm0,            mm0                 ;
+        movq            mm1,            [rsi]               ;
+
+        movq            mm3,            [rsi+1]             ;
+        movq            mm2,            mm1                 ;
+
+        movq            mm4,            mm3                 ;
+        punpcklbw       mm1,            mm0                 ;
+
+        punpckhbw       mm2,            mm0                 ;
+        pmullw          mm1,            [rax]               ;
+
+        pmullw          mm2,            [rax]               ;
+        punpcklbw       mm3,            mm0                 ;
+
+        punpckhbw       mm4,            mm0                 ;
+        pmullw          mm3,            [rax+8]             ;
+
+        pmullw          mm4,            [rax+8]             ;
+        paddw           mm1,            mm3                 ;
+
+        paddw           mm2,            mm4                 ;
+        paddw           mm1,            [mmx_bi_rd GLOBAL]  ;
+
+        psraw           mm1,            mmx_filter_shift    ;
+        paddw           mm2,            [mmx_bi_rd GLOBAL]  ;
+
+        psraw           mm2,            mmx_filter_shift    ;
+        movq            mm5,            mm1
+
+        packuswb        mm5,            mm2                 ;
+%if ABI_IS_32BIT
+        add             rsi,            dword ptr arg(1) ;ref_pixels_per_line
+%else
+        movsxd          r8,             dword ptr arg(1) ;ref_pixels_per_line
+        add             rsi,            r8
+%endif
+
+filter_block2d_bil_var_mmx_loop:
+
+        movq            mm1,            [rsi]               ;
+        movq            mm3,            [rsi+1]             ;
+
+        movq            mm2,            mm1                 ;
+        movq            mm4,            mm3                 ;
+
+        punpcklbw       mm1,            mm0                 ;
+        punpckhbw       mm2,            mm0                 ;
+
+        pmullw          mm1,            [rax]               ;
+        pmullw          mm2,            [rax]               ;
+
+        punpcklbw       mm3,            mm0                 ;
+        punpckhbw       mm4,            mm0                 ;
+
+        pmullw          mm3,            [rax+8]             ;
+        pmullw          mm4,            [rax+8]             ;
+
+        paddw           mm1,            mm3                 ;
+        paddw           mm2,            mm4                 ;
+
+        paddw           mm1,            [mmx_bi_rd GLOBAL]  ;
+        psraw           mm1,            mmx_filter_shift    ;
+
+        paddw           mm2,            [mmx_bi_rd GLOBAL]  ;
+        psraw           mm2,            mmx_filter_shift    ;
+
+        movq            mm3,            mm5                 ;
+        movq            mm4,            mm5                 ;
+
+        punpcklbw       mm3,            mm0                 ;
+        punpckhbw       mm4,            mm0                 ;
+
+        movq            mm5,            mm1                 ;
+        packuswb        mm5,            mm2                 ;
+
+        pmullw          mm3,            [rdx]               ;
+        pmullw          mm4,            [rdx]               ;
+
+        pmullw          mm1,            [rdx+8]             ;
+        pmullw          mm2,            [rdx+8]             ;
+
+        paddw           mm1,            mm3                 ;
+        paddw           mm2,            mm4                 ;
+
+        paddw           mm1,            [mmx_bi_rd GLOBAL]  ;
+        paddw           mm2,            [mmx_bi_rd GLOBAL]  ;
+
+        psraw           mm1,            mmx_filter_shift    ;
+        psraw           mm2,            mmx_filter_shift    ;
+
+        movq            mm3,            [rdi]               ;
+        movq            mm4,            mm3                 ;
+
+        punpcklbw       mm3,            mm0                 ;
+        punpckhbw       mm4,            mm0                 ;
+
+        psubw           mm1,            mm3                 ;
+        psubw           mm2,            mm4                 ;
+
+        paddw           mm6,            mm1                 ;
+        pmaddwd         mm1,            mm1                 ;
+
+        paddw           mm6,            mm2                 ;
+        pmaddwd         mm2,            mm2                 ;
+
+        paddd           mm7,            mm1                 ;
+        paddd           mm7,            mm2                 ;
+
+%if ABI_IS_32BIT
+        add             rsi,            dword ptr arg(1) ;ref_pixels_per_line    ;
+        add             rdi,            dword ptr arg(3) ;src_pixels_per_line    ;
+%else
+        movsxd          r8,             dword ptr arg(1) ;ref_pixels_per_line    ;
+        movsxd          r9,             dword ptr arg(3) ;src_pixels_per_line    ;
+        add             rsi,            r8
+        add             rdi,            r9
+%endif
+        sub             rcx,            1                   ;
+        jnz             filter_block2d_bil_var_mmx_loop       ;
+
+
+        pxor            mm3,            mm3                 ;
+        pxor            mm2,            mm2                 ;
+
+        punpcklwd       mm2,            mm6                 ;
+        punpckhwd       mm3,            mm6                 ;
+
+        paddd           mm2,            mm3                 ;
+        movq            mm6,            mm2                 ;
+
+        psrlq           mm6,            32                  ;
+        paddd           mm2,            mm6                 ;
+
+        psrad           mm2,            16                  ;
+        movq            mm4,            mm7                 ;
+
+        psrlq           mm4,            32                  ;
+        paddd           mm4,            mm7                 ;
+
+        mov             rdi,            arg(7) ;sum
+        mov             rsi,            arg(8) ;sumsquared
+
+        movd            dword ptr [rdi],          mm2                 ;
+        movd            dword ptr [rsi],          mm4                 ;
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;unsigned int vp8_get16x16pred_error_mmx
+;(
+;    unsigned char *src_ptr,
+;    int src_stride,
+;    unsigned char *ref_ptr,
+;    int ref_stride
+;)
+global sym(vp8_get16x16pred_error_mmx)
+sym(vp8_get16x16pred_error_mmx):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+        mov         rsi,            arg(0) ;DWORD PTR [src_ptr]
+        mov         rdi,            arg(2) ;DWORD PTR [ref_ptr]
+
+        movsxd      rax,            DWORD PTR arg(1) ;[src_stride]
+        movsxd      rdx,            DWORD PTR arg(3) ;[ref_stride]
+
+        pxor        mm0,            mm0                     ; clear xmm0 for unpack
+        pxor        mm7,            mm7                     ; clear xmm7 for accumulating diffs
+
+        pxor        mm6,            mm6                     ; clear xmm6 for accumulating sse
+        mov         rcx,            16
+
+var16loop:
+
+        movq        mm1,            [rsi]
+        movq        mm2,            [rdi]
+
+        movq        mm3,            mm1
+        movq        mm4,            mm2
+
+        punpcklbw   mm1,            mm0
+        punpckhbw   mm3,            mm0
+
+        punpcklbw   mm2,            mm0
+        punpckhbw   mm4,            mm0
+
+        psubw       mm1,            mm2
+        psubw       mm3,            mm4
+
+        paddw       mm7,            mm1
+        pmaddwd     mm1,            mm1
+
+        paddw       mm7,            mm3
+        pmaddwd     mm3,            mm3
+
+        paddd       mm6,            mm1
+        paddd       mm6,            mm3
+
+
+        movq        mm1,            [rsi+8]
+        movq        mm2,            [rdi+8]
+
+        movq        mm3,            mm1
+        movq        mm4,            mm2
+
+        punpcklbw   mm1,            mm0
+        punpckhbw   mm3,            mm0
+
+        punpcklbw   mm2,            mm0
+        punpckhbw   mm4,            mm0
+
+        psubw       mm1,            mm2
+        psubw       mm3,            mm4
+
+        paddw       mm7,            mm1
+        pmaddwd     mm1,            mm1
+
+        paddw       mm7,            mm3
+        pmaddwd     mm3,            mm3
+
+        paddd       mm6,            mm1
+        paddd       mm6,            mm3
+
+        add         rsi,            rax
+        add         rdi,            rdx
+
+        sub         rcx,            1
+        jnz         var16loop
+
+
+        movq        mm1,            mm6
+        pxor        mm6,            mm6
+
+        pxor        mm5,            mm5
+        punpcklwd   mm6,            mm7
+
+        punpckhwd   mm5,            mm7
+        psrad       mm5,            16
+
+        psrad       mm6,            16
+        paddd       mm6,            mm5
+
+        movq        mm2,            mm1
+        psrlq       mm1,            32
+
+        paddd       mm2,            mm1
+        movq        mm7,            mm6
+
+        psrlq       mm6,            32
+        paddd       mm6,            mm7
+
+        movd DWORD PTR [rsp],       mm6  ;Sum
+        movd DWORD PTR [rsp+4],     mm2  ;SSE
+
+        ; return (SSE-((Sum*Sum)>>8));
+        movsxd      rdx, dword ptr [rsp]
+        imul        rdx, rdx
+        sar         rdx, 8
+        movsxd      rax, dword ptr [rsp + 4]
+        sub         rax, rdx
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+SECTION_RODATA
+;short mmx_bi_rd[4] = { 64, 64, 64, 64};
+align 16
+mmx_bi_rd:
+    times 4 dw 64
diff --git a/vp8/encoder/x86/variance_impl_sse2.asm b/vp8/encoder/x86/variance_impl_sse2.asm
new file mode 100644 (file)
index 0000000..7e5ee28
--- /dev/null
@@ -0,0 +1,975 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_ports/x86_abi_support.asm"
+
+%define xmm_filter_shift            7
+
+;unsigned int vp8_get_mb_ss_sse2
+;(
+;    short *src_ptr
+;)
+global sym(vp8_get_mb_ss_sse2)
+sym(vp8_get_mb_ss_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 1
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+
+        mov         rax, arg(0) ;[src_ptr]
+        mov         rcx, 8
+        pxor        xmm4, xmm4
+
+NEXTROW:
+        movdqa      xmm0, [rax]
+        movdqa      xmm1, [rax+16]
+        movdqa      xmm2, [rax+32]
+        movdqa      xmm3, [rax+48]
+        pmaddwd     xmm0, xmm0
+        pmaddwd     xmm1, xmm1
+        pmaddwd     xmm2, xmm2
+        pmaddwd     xmm3, xmm3
+
+        paddd       xmm0, xmm1
+        paddd       xmm2, xmm3
+        paddd       xmm4, xmm0
+        paddd       xmm4, xmm2
+
+        add         rax, 0x40
+        dec         rcx
+        ja          NEXTROW
+
+        movdqa      xmm3,xmm4
+        psrldq      xmm4,8
+        paddd       xmm4,xmm3
+        movdqa      xmm3,xmm4
+        psrldq      xmm4,4
+        paddd       xmm4,xmm3
+        movd        rax,xmm4
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_get16x16var_sse2
+;(
+;    unsigned char   *  src_ptr,
+;    int             source_stride,
+;    unsigned char   *  ref_ptr,
+;    int             recon_stride,
+;    unsigned int    *  SSE,
+;    int             *  Sum
+;)
+global sym(vp8_get16x16var_sse2)
+sym(vp8_get16x16var_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+        mov         rsi,            arg(0) ;[src_ptr]
+        mov         rdi,            arg(2) ;[ref_ptr]
+
+        movsxd      rax,            DWORD PTR arg(1) ;[source_stride]
+        movsxd      rdx,            DWORD PTR arg(3) ;[recon_stride]
+
+        pxor        xmm0,           xmm0                        ; clear xmm0 for unpack
+        pxor        xmm7,           xmm7                        ; clear xmm7 for accumulating diffs
+
+        pxor        xmm6,           xmm6                        ; clear xmm6 for accumulating sse
+        mov         rcx,            16
+
+var16loop:
+        movdqu      xmm1,           XMMWORD PTR [rsi]
+        movdqu      xmm2,           XMMWORD PTR [rdi]
+
+        movdqa      xmm3,           xmm1
+        movdqa      xmm4,           xmm2
+
+
+        punpcklbw   xmm1,           xmm0
+        punpckhbw   xmm3,           xmm0
+
+        punpcklbw   xmm2,           xmm0
+        punpckhbw   xmm4,           xmm0
+
+
+        psubw       xmm1,           xmm2
+        psubw       xmm3,           xmm4
+
+        paddw       xmm7,           xmm1
+        pmaddwd     xmm1,           xmm1
+
+        paddw       xmm7,           xmm3
+        pmaddwd     xmm3,           xmm3
+
+        paddd       xmm6,           xmm1
+        paddd       xmm6,           xmm3
+
+        add         rsi,            rax
+        add         rdi,            rdx
+
+        sub         rcx,            1
+        jnz         var16loop
+
+
+        movdqa      xmm1,           xmm6
+        pxor        xmm6,           xmm6
+
+        pxor        xmm5,           xmm5
+        punpcklwd   xmm6,           xmm7
+
+        punpckhwd   xmm5,           xmm7
+        psrad       xmm5,           16
+
+        psrad       xmm6,           16
+        paddd       xmm6,           xmm5
+
+        movdqa      xmm2,           xmm1
+        punpckldq   xmm1,           xmm0
+
+        punpckhdq   xmm2,           xmm0
+        movdqa      xmm7,           xmm6
+
+        paddd       xmm1,           xmm2
+        punpckldq   xmm6,           xmm0
+
+        punpckhdq   xmm7,           xmm0
+        paddd       xmm6,           xmm7
+
+        movdqa      xmm2,           xmm1
+        movdqa      xmm7,           xmm6
+
+        psrldq      xmm1,           8
+        psrldq      xmm6,           8
+
+        paddd       xmm7,           xmm6
+        paddd       xmm1,           xmm2
+
+        mov         rax,            arg(5) ;[Sum]
+        mov         rdi,            arg(4) ;[SSE]
+
+        movd DWORD PTR [rax],       xmm7
+        movd DWORD PTR [rdi],       xmm1
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;unsigned int vp8_get16x16pred_error_sse2
+;(
+;   unsigned char *src_ptr,
+;    int src_stride,
+;    unsigned char *ref_ptr,
+;    int ref_stride
+;)
+global sym(vp8_get16x16pred_error_sse2)
+sym(vp8_get16x16pred_error_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 4
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+        mov         rsi,            arg(0) ;[src_ptr]
+        mov         rdi,            arg(2) ;[ref_ptr]
+
+        movsxd      rax,            DWORD PTR arg(1) ;[src_stride]
+        movsxd      rdx,            DWORD PTR arg(3) ;[ref_stride]
+
+        pxor        xmm0,           xmm0                        ; clear xmm0 for unpack
+        pxor        xmm7,           xmm7                        ; clear xmm7 for accumulating diffs
+
+        pxor        xmm6,           xmm6                        ; clear xmm6 for accumulating sse
+        mov         rcx,            16
+
+var16peloop:
+        movdqu      xmm1,           XMMWORD PTR [rsi]
+        movdqu      xmm2,           XMMWORD PTR [rdi]
+
+        movdqa      xmm3,           xmm1
+        movdqa      xmm4,           xmm2
+
+        punpcklbw   xmm1,           xmm0
+        punpckhbw   xmm3,           xmm0
+
+        punpcklbw   xmm2,           xmm0
+        punpckhbw   xmm4,           xmm0
+
+        psubw       xmm1,           xmm2
+        psubw       xmm3,           xmm4
+
+        paddw       xmm7,           xmm1
+        pmaddwd     xmm1,           xmm1
+
+        paddw       xmm7,           xmm3
+        pmaddwd     xmm3,           xmm3
+
+        paddd       xmm6,           xmm1
+        paddd       xmm6,           xmm3
+
+        add         rsi,            rax
+        add         rdi,            rdx
+
+        sub         rcx,            1
+        jnz         var16peloop
+
+
+        movdqa      xmm1,           xmm6
+        pxor        xmm6,           xmm6
+
+        pxor        xmm5,           xmm5
+        punpcklwd   xmm6,           xmm7
+
+        punpckhwd   xmm5,           xmm7
+        psrad       xmm5,           16
+
+        psrad       xmm6,           16
+        paddd       xmm6,           xmm5
+
+        movdqa      xmm2,           xmm1
+        punpckldq   xmm1,           xmm0
+
+        punpckhdq   xmm2,           xmm0
+        movdqa      xmm7,           xmm6
+
+        paddd       xmm1,           xmm2
+        punpckldq   xmm6,           xmm0
+
+        punpckhdq   xmm7,           xmm0
+        paddd       xmm6,           xmm7
+
+        movdqa      xmm2,           xmm1
+        movdqa      xmm7,           xmm6
+
+        psrldq      xmm1,           8
+        psrldq      xmm6,           8
+
+        paddd       xmm7,           xmm6
+        paddd       xmm1,           xmm2
+
+        movd DWORD PTR [rsp],       xmm7  ;Sum
+        movd DWORD PTR [rsp+4],     xmm1  ;SSE
+
+        ; return (SSE-((Sum*Sum)>>8));
+        movsxd      rdx, dword ptr [rsp]
+        imul        rdx, rdx
+        sar         rdx, 8
+        movsxd      rax, dword ptr [rsp + 4]
+        sub         rax, rdx
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+
+;unsigned int vp8_get8x8var_sse2
+;(
+;    unsigned char   *  src_ptr,
+;    int             source_stride,
+;    unsigned char   *  ref_ptr,
+;    int             recon_stride,
+;    unsigned int    *  SSE,
+;    int             *  Sum
+;)
+global sym(vp8_get8x8var_sse2)
+sym(vp8_get8x8var_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 6
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+        mov         rsi,            arg(0) ;[src_ptr]
+        mov         rdi,            arg(2) ;[ref_ptr]
+
+        movsxd      rax,            DWORD PTR arg(1) ;[source_stride]
+        movsxd      rdx,            DWORD PTR arg(3) ;[recon_stride]
+
+        pxor        xmm0,           xmm0                        ; clear xmm0 for unpack
+        pxor        xmm7,           xmm7                        ; clear xmm7 for accumulating diffs
+
+        movq        xmm1,           QWORD PTR [rsi]
+        movq        xmm2,           QWORD PTR [rdi]
+
+        punpcklbw   xmm1,           xmm0
+        punpcklbw   xmm2,           xmm0
+
+        psubsw      xmm1,           xmm2
+        paddw       xmm7,           xmm1
+
+        pmaddwd     xmm1,           xmm1
+
+        movq        xmm2,           QWORD PTR[rsi + rax]
+        movq        xmm3,           QWORD PTR[rdi + rdx]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+
+        movq        xmm2,           QWORD PTR[rsi + rax * 2]
+        movq        xmm3,           QWORD PTR[rdi + rdx * 2]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+
+        lea         rsi,            [rsi + rax * 2]
+        lea         rdi,            [rdi + rdx * 2]
+        movq        xmm2,           QWORD PTR[rsi + rax]
+        movq        xmm3,           QWORD PTR[rdi + rdx]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+        movq        xmm2,           QWORD PTR[rsi + rax *2]
+        movq        xmm3,           QWORD PTR[rdi + rdx *2]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+
+        lea         rsi,            [rsi + rax * 2]
+        lea         rdi,            [rdi + rdx * 2]
+
+
+        movq        xmm2,           QWORD PTR[rsi + rax]
+        movq        xmm3,           QWORD PTR[rdi + rdx]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+        movq        xmm2,           QWORD PTR[rsi + rax *2]
+        movq        xmm3,           QWORD PTR[rdi + rdx *2]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+
+        lea         rsi,            [rsi + rax * 2]
+        lea         rdi,            [rdi + rdx * 2]
+
+        movq        xmm2,           QWORD PTR[rsi + rax]
+        movq        xmm3,           QWORD PTR[rdi + rdx]
+
+        punpcklbw   xmm2,           xmm0
+        punpcklbw   xmm3,           xmm0
+
+        psubsw      xmm2,           xmm3
+        paddw       xmm7,           xmm2
+
+        pmaddwd     xmm2,           xmm2
+        paddd       xmm1,           xmm2
+
+
+        movdqa      xmm6,           xmm7
+        punpcklwd   xmm6,           xmm0
+
+        punpckhwd   xmm7,           xmm0
+        movdqa      xmm2,           xmm1
+
+        paddw       xmm6,           xmm7
+        punpckldq   xmm1,           xmm0
+
+        punpckhdq   xmm2,           xmm0
+        movdqa      xmm7,           xmm6
+
+        paddd       xmm1,           xmm2
+        punpckldq   xmm6,           xmm0
+
+        punpckhdq   xmm7,           xmm0
+        paddw       xmm6,           xmm7
+
+        movdqa      xmm2,           xmm1
+        movdqa      xmm7,           xmm6
+
+        psrldq      xmm1,           8
+        psrldq      xmm6,           8
+
+        paddw       xmm7,           xmm6
+        paddd       xmm1,           xmm2
+
+        mov         rax,            arg(5) ;[Sum]
+        mov         rdi,            arg(4) ;[SSE]
+
+        movd        rdx,            xmm7
+        movsx       rcx,            dx
+
+        mov  dword ptr [rax],       ecx
+        movd DWORD PTR [rdi],       xmm1
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+;void vp8_filter_block2d_bil_var_sse2
+;(
+;    unsigned char *ref_ptr,
+;    int ref_pixels_per_line,
+;    unsigned char *src_ptr,
+;    int src_pixels_per_line,
+;    unsigned int Height,
+;    unsigned short *HFilter,
+;    unsigned short *VFilter,
+;    int *sum,
+;    unsigned int *sumsquared;;
+;
+;)
+global sym(vp8_filter_block2d_bil_var_sse2)
+sym(vp8_filter_block2d_bil_var_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 9
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    sub         rsp, 16
+    ; end prolog
+
+        pxor            xmm6,           xmm6                 ;
+        pxor            xmm7,           xmm7                 ;
+        mov             rax,            arg(5) ;HFilter             ;
+
+        mov             rdx,            arg(6) ;VFilter             ;
+        mov             rsi,            arg(0) ;ref_ptr              ;
+
+        mov             rdi,            arg(2) ;src_ptr              ;
+        movsxd          rcx,            dword ptr arg(4) ;Height              ;
+
+        pxor            xmm0,           xmm0                 ;
+        movq            xmm1,           QWORD PTR [rsi]               ;
+
+        movq            xmm3,           QWORD PTR [rsi+1]        ;
+        punpcklbw       xmm1,           xmm0                 ;
+
+        pmullw          xmm1,           [rax]               ;
+        punpcklbw       xmm3,           xmm0
+            ;
+        pmullw          xmm3,           [rax+16]             ;
+        paddw           xmm1,           xmm3                 ;
+
+        paddw           xmm1,           [xmm_bi_rd GLOBAL]   ;
+        psraw           xmm1,           xmm_filter_shift    ;
+
+        movdqa          xmm5,           xmm1
+%if ABI_IS_32BIT
+        add             rsi,            dword ptr arg(1) ;ref_pixels_per_line    ;
+%else
+        movsxd          r8,             dword ptr arg(1) ;ref_pixels_per_line    ;
+        add             rsi,            r8
+%endif
+filter_block2d_bil_var_sse2_loop:
+
+        movq            xmm1,           QWORD PTR [rsi]               ;
+        movq            xmm3,           QWORD PTR [rsi+1]             ;
+
+        punpcklbw       xmm1,           xmm0                 ;
+        pmullw          xmm1,           [rax]               ;
+
+        punpcklbw       xmm3,           xmm0                 ;
+        pmullw          xmm3,           [rax+16]             ;
+
+        paddw           xmm1,           xmm3                 ;
+        paddw           xmm1,           [xmm_bi_rd GLOBAL]   ;
+
+        psraw           xmm1,           xmm_filter_shift    ;
+        movdqa          xmm3,           xmm5                 ;
+
+        movdqa          xmm5,           xmm1                 ;
+        pmullw          xmm3,           [rdx]               ;
+
+        pmullw          xmm1,           [rdx+16]             ;
+        paddw           xmm1,           xmm3                 ;
+
+        paddw           xmm1,           [xmm_bi_rd GLOBAL]   ;
+        psraw           xmm1,           xmm_filter_shift    ;
+
+        movq            xmm3,           QWORD PTR [rdi]               ;
+        punpcklbw       xmm3,           xmm0                 ;
+
+        psubw           xmm1,           xmm3                 ;
+        paddw           xmm6,           xmm1                 ;
+
+        pmaddwd         xmm1,           xmm1                 ;
+        paddd           xmm7,           xmm1                 ;
+
+%if ABI_IS_32BIT
+        add             rsi,            dword ptr arg(1) ;ref_pixels_per_line    ;
+        add             rdi,            dword ptr arg(3) ;src_pixels_per_line    ;
+%else
+        movsxd          r8,             dword ptr arg(1) ;ref_pixels_per_line    ;
+        movsxd          r9,             dword ptr arg(3) ;src_pixels_per_line    ;
+        add             rsi,            r8
+        add             rdi,            r9
+%endif
+
+        sub             rcx,            1                   ;
+        jnz             filter_block2d_bil_var_sse2_loop       ;
+
+
+        movdq2q         mm6,            xmm6                ;
+        movdq2q         mm7,            xmm7                ;
+
+        psrldq          xmm6,           8
+        psrldq          xmm7,           8
+
+        movdq2q         mm2,            xmm6
+        movdq2q         mm3,            xmm7
+
+        paddw           mm6,            mm2
+        paddd           mm7,            mm3
+
+        pxor            mm3,            mm3                 ;
+        pxor            mm2,            mm2                 ;
+
+        punpcklwd       mm2,            mm6                 ;
+        punpckhwd       mm3,            mm6                 ;
+
+        paddd           mm2,            mm3                 ;
+        movq            mm6,            mm2                 ;
+
+        psrlq           mm6,            32                  ;
+        paddd           mm2,            mm6                 ;
+
+        psrad           mm2,            16                  ;
+        movq            mm4,            mm7                 ;
+
+        psrlq           mm4,            32                  ;
+        paddd           mm4,            mm7                 ;
+
+        mov             rsi,            arg(7) ; sum
+        mov             rdi,            arg(8) ; sumsquared
+
+        movd            [rsi],          mm2    ; xsum
+        movd            [rdi],          mm4    ; xxsum
+
+
+    ; begin epilog
+    add rsp, 16
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_half_horiz_vert_variance16x_h_sse2
+;(
+;    unsigned char *ref_ptr,
+;    int ref_pixels_per_line,
+;    unsigned char *src_ptr,
+;    int src_pixels_per_line,
+;    unsigned int Height,
+;    int *sum,
+;    unsigned int *sumsquared
+;)
+global sym(vp8_half_horiz_vert_variance16x_h_sse2)
+sym(vp8_half_horiz_vert_variance16x_h_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    ; end prolog
+
+%if ABI_IS_32BIT=0
+    movsxd          r8, dword ptr arg(1) ;ref_pixels_per_line
+    movsxd          r9, dword ptr arg(3) ;src_pixels_per_line
+%endif
+
+        pxor            xmm6,           xmm6                ;  error accumulator
+        pxor            xmm7,           xmm7                ;  sse eaccumulator
+        mov             rsi,            arg(0) ;ref_ptr              ;
+
+        mov             rdi,            arg(2) ;src_ptr              ;
+        movsxd          rcx,            dword ptr arg(4) ;Height              ;
+        movsxd          rax,            dword ptr arg(1) ;ref_pixels_per_line
+
+        pxor            xmm0,           xmm0                ;
+
+        movq            xmm5,           QWORD PTR [rsi]     ;  xmm5 = s0,s1,s2..s8
+        movq            xmm3,           QWORD PTR [rsi+1]   ;  xmm3 = s1,s2,s3..s9
+        pavgb           xmm5,           xmm3                ;  xmm5 = avg(xmm1,xmm3) horizontal line 1
+
+%if ABI_IS_32BIT
+        add             rsi,            dword ptr arg(1) ;ref_pixels_per_line    ;  next source
+%else
+        add             rsi, r8
+%endif
+
+vp8_half_horiz_vert_variance16x_h_1:
+
+        movq            xmm1,           QWORD PTR [rsi]     ;
+        movq            xmm2,           QWORD PTR [rsi+1]   ;
+        pavgb           xmm1,           xmm2                ;  xmm1 = avg(xmm1,xmm3) horizontal line i+1
+
+        pavgb           xmm5,           xmm1                ;  xmm = vertical average of the above
+        punpcklbw       xmm5,           xmm0                ;  xmm5 = words of above
+
+        movq            xmm3,           QWORD PTR [rdi]     ;  xmm3 = d0,d1,d2..d8
+        punpcklbw       xmm3,           xmm0                ;  xmm3 = words of above
+
+        psubw           xmm5,           xmm3                ;  xmm5 -= xmm3
+        paddw           xmm6,           xmm5                ;  xmm6 += accumulated column differences
+        pmaddwd         xmm5,           xmm5                ;  xmm5 *= xmm5
+        paddd           xmm7,           xmm5                ;  xmm7 += accumulated square column differences
+
+        movdqa          xmm5,           xmm1                ;  save xmm1 for use on the next row
+
+%if ABI_IS_32BIT
+        add             esi,            dword ptr arg(1) ;ref_pixels_per_line    ;  next source
+        add             edi,            dword ptr arg(3) ;src_pixels_per_line    ;  next destination
+%else
+        add             rsi, r8
+        add             rdi, r9
+%endif
+
+        sub             rcx,            1                   ;
+        jnz             vp8_half_horiz_vert_variance16x_h_1     ;
+
+        movdq2q         mm6,            xmm6                ;
+        movdq2q         mm7,            xmm7                ;
+
+        psrldq          xmm6,           8
+        psrldq          xmm7,           8
+
+        movdq2q         mm2,            xmm6
+        movdq2q         mm3,            xmm7
+
+        paddw           mm6,            mm2
+        paddd           mm7,            mm3
+
+        pxor            mm3,            mm3                 ;
+        pxor            mm2,            mm2                 ;
+
+        punpcklwd       mm2,            mm6                 ;
+        punpckhwd       mm3,            mm6                 ;
+
+        paddd           mm2,            mm3                 ;
+        movq            mm6,            mm2                 ;
+
+        psrlq           mm6,            32                  ;
+        paddd           mm2,            mm6                 ;
+
+        psrad           mm2,            16                  ;
+        movq            mm4,            mm7                 ;
+
+        psrlq           mm4,            32                  ;
+        paddd           mm4,            mm7                 ;
+
+        mov             rsi,            arg(5) ; sum
+        mov             rdi,            arg(6) ; sumsquared
+
+        movd            [rsi],          mm2                 ;
+        movd            [rdi],          mm4                 ;
+
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_half_vert_variance16x_h_sse2
+;(
+;    unsigned char *ref_ptr,
+;    int ref_pixels_per_line,
+;    unsigned char *src_ptr,
+;    int src_pixels_per_line,
+;    unsigned int Height,
+;    int *sum,
+;    unsigned int *sumsquared
+;)
+global sym(vp8_half_vert_variance16x_h_sse2)
+sym(vp8_half_vert_variance16x_h_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    ; end prolog
+
+%if ABI_IS_32BIT=0
+    movsxd          r8, dword ptr arg(1) ;ref_pixels_per_line
+    movsxd          r9, dword ptr arg(3) ;src_pixels_per_line
+%endif
+
+        pxor            xmm6,           xmm6                ;  error accumulator
+        pxor            xmm7,           xmm7                ;  sse eaccumulator
+        mov             rsi,            arg(0) ;ref_ptr              ;
+
+        mov             rdi,            arg(2) ;src_ptr              ;
+        movsxd          rcx,            dword ptr arg(4) ;Height              ;
+        movsxd          rax,            dword ptr arg(1) ;ref_pixels_per_line
+
+        pxor            xmm0,           xmm0                ;
+vp8_half_vert_variance16x_h_1:
+        movq            xmm5,           QWORD PTR [rsi]     ;  xmm5 = s0,s1,s2..s8
+        movq            xmm3,           QWORD PTR [rsi+rax] ;  xmm3 = s1,s2,s3..s9
+
+        pavgb           xmm5,           xmm3                ;  xmm5 = avg(xmm1,xmm3)
+        punpcklbw       xmm5,           xmm0                ;  xmm5 = words of above
+
+        movq            xmm3,           QWORD PTR [rdi]     ;  xmm3 = d0,d1,d2..d8
+        punpcklbw       xmm3,           xmm0                ;  xmm3 = words of above
+
+        psubw           xmm5,           xmm3                ;  xmm5 -= xmm3
+        paddw           xmm6,           xmm5                ;  xmm6 += accumulated column differences
+        pmaddwd         xmm5,           xmm5                ;  xmm5 *= xmm5
+        paddd           xmm7,           xmm5                ;  xmm7 += accumulated square column differences
+
+%if ABI_IS_32BIT
+        add             esi,            dword ptr arg(1) ;ref_pixels_per_line    ;  next source
+        add             edi,            dword ptr arg(3) ;src_pixels_per_line    ;  next destination
+%else
+        add             rsi, r8
+        add             rdi, r9
+%endif
+
+        sub             rcx,            1                   ;
+        jnz             vp8_half_vert_variance16x_h_1          ;
+
+        movdq2q         mm6,            xmm6                ;
+        movdq2q         mm7,            xmm7                ;
+
+        psrldq          xmm6,           8
+        psrldq          xmm7,           8
+
+        movdq2q         mm2,            xmm6
+        movdq2q         mm3,            xmm7
+
+        paddw           mm6,            mm2
+        paddd           mm7,            mm3
+
+        pxor            mm3,            mm3                 ;
+        pxor            mm2,            mm2                 ;
+
+        punpcklwd       mm2,            mm6                 ;
+        punpckhwd       mm3,            mm6                 ;
+
+        paddd           mm2,            mm3                 ;
+        movq            mm6,            mm2                 ;
+
+        psrlq           mm6,            32                  ;
+        paddd           mm2,            mm6                 ;
+
+        psrad           mm2,            16                  ;
+        movq            mm4,            mm7                 ;
+
+        psrlq           mm4,            32                  ;
+        paddd           mm4,            mm7                 ;
+
+        mov             rsi,            arg(5) ; sum
+        mov             rdi,            arg(6) ; sumsquared
+
+        movd            [rsi],          mm2                 ;
+        movd            [rdi],          mm4                 ;
+
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+;void vp8_half_horiz_variance16x_h_sse2
+;(
+;    unsigned char *ref_ptr,
+;    int ref_pixels_per_line,
+;    unsigned char *src_ptr,
+;    int src_pixels_per_line,
+;    unsigned int Height,
+;    int *sum,
+;    unsigned int *sumsquared
+;)
+global sym(vp8_half_horiz_variance16x_h_sse2)
+sym(vp8_half_horiz_variance16x_h_sse2):
+    push        rbp
+    mov         rbp, rsp
+    SHADOW_ARGS_TO_STACK 7
+    GET_GOT     rbx
+    push rsi
+    push rdi
+    ; end prolog
+
+%if ABI_IS_32BIT=0
+    movsxd          r8, dword ptr arg(1) ;ref_pixels_per_line
+    movsxd          r9, dword ptr arg(3) ;src_pixels_per_line
+%endif
+
+        pxor            xmm6,           xmm6                ;  error accumulator
+        pxor            xmm7,           xmm7                ;  sse eaccumulator
+        mov             rsi,            arg(0) ;ref_ptr              ;
+
+        mov             rdi,            arg(2) ;src_ptr              ;
+        movsxd          rcx,            dword ptr arg(4) ;Height              ;
+
+        pxor            xmm0,           xmm0                ;
+vp8_half_horiz_variance16x16_1:
+        movq            xmm5,           QWORD PTR [rsi]     ;  xmm5 = s0,s1,s2..s8
+        movq            xmm3,           QWORD PTR [rsi+1]   ;  xmm3 = s1,s2,s3..s9
+
+        pavgb           xmm5,           xmm3                ;  xmm5 = avg(xmm1,xmm3)
+        punpcklbw       xmm5,           xmm0                ;  xmm5 = words of above
+
+        movq            xmm3,           QWORD PTR [rdi]     ;  xmm3 = d0,d1,d2..d8
+        punpcklbw       xmm3,           xmm0                ;  xmm3 = words of above
+
+        psubw           xmm5,           xmm3                ;  xmm5 -= xmm3
+        paddw           xmm6,           xmm5                ;  xmm6 += accumulated column differences
+        pmaddwd         xmm5,           xmm5                ;  xmm5 *= xmm5
+        paddd           xmm7,           xmm5                ;  xmm7 += accumulated square column differences
+
+%if ABI_IS_32BIT
+        add             esi,            dword ptr arg(1) ;ref_pixels_per_line    ;  next source
+        add             edi,            dword ptr arg(3) ;src_pixels_per_line    ;  next destination
+%else
+        add             rsi, r8
+        add             rdi, r9
+%endif
+        sub             rcx,            1                   ;
+        jnz             vp8_half_horiz_variance16x16_1        ;
+
+        movdq2q         mm6,            xmm6                ;
+        movdq2q         mm7,            xmm7                ;
+
+        psrldq          xmm6,           8
+        psrldq          xmm7,           8
+
+        movdq2q         mm2,            xmm6
+        movdq2q         mm3,            xmm7
+
+        paddw           mm6,            mm2
+        paddd           mm7,            mm3
+
+        pxor            mm3,            mm3                 ;
+        pxor            mm2,            mm2                 ;
+
+        punpcklwd       mm2,            mm6                 ;
+        punpckhwd       mm3,            mm6                 ;
+
+        paddd           mm2,            mm3                 ;
+        movq            mm6,            mm2                 ;
+
+        psrlq           mm6,            32                  ;
+        paddd           mm2,            mm6                 ;
+
+        psrad           mm2,            16                  ;
+        movq            mm4,            mm7                 ;
+
+        psrlq           mm4,            32                  ;
+        paddd           mm4,            mm7                 ;
+
+        mov             rsi,            arg(5) ; sum
+        mov             rdi,            arg(6) ; sumsquared
+
+        movd            [rsi],          mm2                 ;
+        movd            [rdi],          mm4                 ;
+
+
+    ; begin epilog
+    pop rdi
+    pop rsi
+    RESTORE_GOT
+    UNSHADOW_ARGS
+    pop         rbp
+    ret
+
+
+SECTION_RODATA
+;    short xmm_bi_rd[8] = { 64, 64, 64, 64,64, 64, 64, 64};
+align 16
+xmm_bi_rd:
+    times 8 dw 64
diff --git a/vp8/encoder/x86/variance_mmx.c b/vp8/encoder/x86/variance_mmx.c
new file mode 100644 (file)
index 0000000..4a5b25b
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "variance.h"
+#include "pragmas.h"
+#include "vpx_ports/mem.h"
+
+extern void filter_block1d_h6_mmx
+(
+    unsigned char *src_ptr,
+    unsigned short *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    short *vp7_filter
+);
+extern void filter_block1d_v6_mmx
+(
+    short *src_ptr,
+    unsigned char *output_ptr,
+    unsigned int pixels_per_line,
+    unsigned int pixel_step,
+    unsigned int output_height,
+    unsigned int output_width,
+    short *vp7_filter
+);
+
+extern unsigned int vp8_get_mb_ss_mmx(short *src_ptr);
+extern unsigned int vp8_get8x8var_mmx
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *SSE,
+    int *Sum
+);
+extern unsigned int vp8_get4x4var_mmx
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *SSE,
+    int *Sum
+);
+extern unsigned int vp8_get4x4sse_cs_mmx
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride
+);
+extern void vp8_filter_block2d_bil4x4_var_mmx
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    const short *HFilter,
+    const short *VFilter,
+    int *sum,
+    unsigned int *sumsquared
+);
+extern void vp8_filter_block2d_bil_var_mmx
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    unsigned int Height,
+    const short *HFilter,
+    const short *VFilter,
+    int *sum,
+    unsigned int *sumsquared
+);
+extern unsigned int vp8_get16x16pred_error_mmx
+(
+    unsigned char *src_ptr,
+    int src_stride,
+    unsigned char *ref_ptr,
+    int ref_stride
+);
+
+
+void vp8_test_get_mb_ss(void)
+{
+    short zz[] =
+    {
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -2, -2, -2, -2, 2, 2, 2, 2, -2, -2, -2, -2, 2, 2, 2, 2,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -3, -3, -3, -3, 3, 3, 3, 3, -3, -3, -3, -3, 3, 3, 3, 3,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+        -4, -4, -4, -4, 4, 4, 4, 4, -4, -4, -4, -4, 4, 4, 4, 4,
+    };
+    int s = 0, x = vp8_get_mb_ss_mmx(zz);
+    {
+        int y;
+
+        for (y = 0; y < 256; y++)
+            s += (zz[y] * zz[y]);
+    }
+
+    x += 0;
+}
+
+
+unsigned int vp8_get16x16var_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned *SSE,
+    unsigned *SUM
+)
+{
+    unsigned int sse0, sse1, sse2, sse3, var;
+    int sum0, sum1, sum2, sum3, avg;
+
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
+
+    var = sse0 + sse1 + sse2 + sse3;
+    avg = sum0 + sum1 + sum2 + sum3;
+
+    *SSE = var;
+    *SUM = avg;
+    return (var - ((avg * avg) >> 8));
+
+}
+
+
+
+
+
+unsigned int vp8_variance4x4_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+    vp8_get4x4var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
+    *sse = var;
+    return (var - ((avg * avg) >> 4));
+
+}
+
+unsigned int vp8_variance8x8_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int var;
+    int avg;
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
+    *sse = var;
+
+    return (var - ((avg * avg) >> 6));
+
+}
+
+unsigned int vp8_mse16x16_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, sse2, sse3, var;
+    int sum0, sum1, sum2, sum3;
+
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
+
+    var = sse0 + sse1 + sse2 + sse3;
+    *sse = var;
+    return var;
+}
+
+
+unsigned int vp8_variance16x16_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    int *sse)
+{
+    unsigned int sse0, sse1, sse2, sse3, var;
+    int sum0, sum1, sum2, sum3, avg;
+
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse2, &sum2) ;
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride + 8, source_stride, ref_ptr + 8 * recon_stride + 8, recon_stride, &sse3, &sum3);
+
+    var = sse0 + sse1 + sse2 + sse3;
+    avg = sum0 + sum1 + sum2 + sum3;
+    *sse = var;
+    return (var - ((avg * avg) >> 8));
+}
+
+unsigned int vp8_variance16x8_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, var;
+    int sum0, sum1, avg;
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+
+    var = sse0 + sse1;
+    avg = sum0 + sum1;
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+
+}
+
+
+unsigned int vp8_variance8x16_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, var;
+    int sum0, sum1, avg;
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse1, &sum1) ;
+
+    var = sse0 + sse1;
+    avg = sum0 + sum1;
+    *sse = var;
+
+    return (var - ((avg * avg) >> 7));
+
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////
+// the mmx function that does the bilinear filtering and var calculation //
+// int one pass                                                          //
+///////////////////////////////////////////////////////////////////////////
+DECLARE_ALIGNED(16, const short, vp8_vp7_bilinear_filters_mmx[8][8]) =
+{
+    { 128, 128, 128, 128,  0,  0,  0,  0 },
+    { 112, 112, 112, 112, 16, 16, 16, 16 },
+    {  96, 96, 96, 96, 32, 32, 32, 32 },
+    {  80, 80, 80, 80, 48, 48, 48, 48 },
+    {  64, 64, 64, 64, 64, 64, 64, 64 },
+    {  48, 48, 48, 48, 80, 80, 80, 80 },
+    {  32, 32, 32, 32, 96, 96, 96, 96 },
+    {  16, 16, 16, 16, 112, 112, 112, 112 }
+};
+
+unsigned int vp8_sub_pixel_variance4x4_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse)
+
+{
+    int xsum;
+    unsigned int xxsum;
+    vp8_filter_block2d_bil4x4_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum, &xxsum
+    );
+    *sse = xxsum;
+    return (xxsum - ((xsum * xsum) >> 4));
+}
+
+
+unsigned int vp8_sub_pixel_variance8x8_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+
+    int xsum;
+    unsigned int xxsum;
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum, &xxsum
+    );
+    *sse = xxsum;
+    return (xxsum - ((xsum * xsum) >> 6));
+}
+
+unsigned int vp8_sub_pixel_variance16x16_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+
+    int xsum0, xsum1;
+    unsigned int xxsum0, xxsum1;
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 16,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum0, &xxsum0
+    );
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr + 8, src_pixels_per_line,
+        dst_ptr + 8, dst_pixels_per_line, 16,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+
+    *sse = xxsum0;
+    return (xxsum0 - ((xsum0 * xsum0) >> 8));
+
+
+}
+
+unsigned int vp8_sub_pixel_mse16x16_mmx(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    vp8_sub_pixel_variance16x16_mmx(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
+    return *sse;
+}
+
+unsigned int vp8_sub_pixel_variance16x8_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    int xsum0, xsum1;
+    unsigned int xxsum0, xxsum1;
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum0, &xxsum0
+    );
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr + 8, src_pixels_per_line,
+        dst_ptr + 8, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+
+    *sse = xxsum0;
+    return (xxsum0 - ((xsum0 * xsum0) >> 7));
+}
+
+unsigned int vp8_sub_pixel_variance8x16_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    int *sse
+)
+{
+    int xsum;
+    unsigned int xxsum;
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 16,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum, &xxsum
+    );
+    *sse = xxsum;
+    return (xxsum - ((xsum * xsum) >> 7));
+}
+
+unsigned int vp8_i_variance16x16_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, sse2, sse3, var;
+    int sum0, sum1, sum2, sum3, avg;
+
+
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+    vp8_get8x8var_mmx(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse2, &sum2) ;
+    vp8_get8x8var_mmx(src_ptr + (source_stride >> 1) + 8, source_stride, ref_ptr + (recon_stride >> 1) + 8, recon_stride, &sse3, &sum3);
+
+    var = sse0 + sse1 + sse2 + sse3;
+    avg = sum0 + sum1 + sum2 + sum3;
+    *sse = var;
+    return (var - ((avg * avg) >> 8));
+
+}
+
+unsigned int vp8_i_variance8x16_mmx(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, var;
+    int sum0, sum1, avg;
+    vp8_get8x8var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_mmx(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse1, &sum1) ;
+
+    var = sse0 + sse1;
+    avg = sum0 + sum1;
+
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+
+}
+
+unsigned int vp8_i_sub_pixel_variance16x16_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    int xsum0, xsum1;
+    unsigned int xxsum0, xxsum1;
+    int f2soffset = (src_pixels_per_line >> 1);
+    int f2doffset = (dst_pixels_per_line >> 1);
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum0, &xxsum0
+    );
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr + 8, src_pixels_per_line,
+        dst_ptr + 8, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr + f2soffset, src_pixels_per_line,
+        dst_ptr + f2doffset, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr + f2soffset + 8, src_pixels_per_line,
+        dst_ptr + f2doffset + 8, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+    *sse = xxsum0;
+    return (xxsum0 - ((xsum0 * xsum0) >> 8));
+}
+
+
+unsigned int vp8_i_sub_pixel_variance8x16_mmx
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    int xsum0, xsum1;
+    unsigned int xxsum0, xxsum1;
+    int f2soffset = (src_pixels_per_line >> 1);
+    int f2doffset = (dst_pixels_per_line >> 1);
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum0, &xxsum0
+    );
+
+
+    vp8_filter_block2d_bil_var_mmx(
+        src_ptr + f2soffset, src_pixels_per_line,
+        dst_ptr + f2doffset, dst_pixels_per_line, 8,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+    *sse = xxsum0;
+    return (xxsum0 - ((xsum0 * xsum0) >> 7));
+}
diff --git a/vp8/encoder/x86/variance_sse2.c b/vp8/encoder/x86/variance_sse2.c
new file mode 100644 (file)
index 0000000..ea80753
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "variance.h"
+#include "pragmas.h"
+#include "vpx_ports/mem.h"
+
+extern void filter_block1d_h6_mmx(unsigned char *src_ptr, unsigned short *output_ptr, unsigned int src_pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
+extern void filter_block1d_v6_mmx(short *src_ptr, unsigned char *output_ptr, unsigned int pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
+extern void filter_block1d8_h6_sse2(unsigned char *src_ptr, unsigned short *output_ptr, unsigned int src_pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
+extern void filter_block1d8_v6_sse2(short *src_ptr, unsigned char *output_ptr, unsigned int pixels_per_line, unsigned int pixel_step, unsigned int output_height, unsigned int output_width, short *vp7_filter);
+
+extern void vp8_filter_block2d_bil4x4_var_mmx
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    const short *HFilter,
+    const short *VFilter,
+    int *sum,
+    unsigned int *sumsquared
+);
+
+extern unsigned int vp8_get4x4var_mmx
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *SSE,
+    int *Sum
+);
+
+unsigned int vp8_get_mb_ss_sse2
+(
+    short *src_ptr
+);
+unsigned int vp8_get16x16var_sse2
+(
+    unsigned char     *src_ptr,
+    int             source_stride,
+    unsigned char     *ref_ptr,
+    int             recon_stride,
+    unsigned int      *SSE,
+    int               *Sum
+);
+unsigned int vp8_get16x16pred_error_sse2
+(
+    unsigned char *src_ptr,
+    int src_stride,
+    unsigned char *ref_ptr,
+    int ref_stride
+);
+unsigned int vp8_get8x8var_sse2
+(
+    unsigned char     *src_ptr,
+    int             source_stride,
+    unsigned char     *ref_ptr,
+    int             recon_stride,
+    unsigned int      *SSE,
+    int               *Sum
+);
+void vp8_filter_block2d_bil_var_sse2
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    unsigned int Height,
+    const short *HFilter,
+    const short *VFilter,
+    int *sum,
+    unsigned int *sumsquared
+);
+void vp8_half_horiz_vert_variance16x_h_sse2
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    unsigned int Height,
+    int *sum,
+    unsigned int *sumsquared
+);
+void vp8_half_horiz_variance16x_h_sse2
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    unsigned int Height,
+    int *sum,
+    unsigned int *sumsquared
+);
+void vp8_half_vert_variance16x_h_sse2
+(
+    unsigned char *ref_ptr,
+    int ref_pixels_per_line,
+    unsigned char *src_ptr,
+    int src_pixels_per_line,
+    unsigned int Height,
+    int *sum,
+    unsigned int *sumsquared
+);
+
+DECLARE_ALIGNED(16, extern short, vp8_vp7_bilinear_filters_mmx[8][8]);
+
+unsigned int vp8_variance4x4_wmt(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride)
+{
+    unsigned int var;
+    int avg;
+
+    vp8_get4x4var_mmx(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
+    return (var - ((avg * avg) >> 4));
+
+}
+
+
+
+unsigned int vp8_variance8x8_wmt
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride)
+{
+    unsigned int var;
+    int avg;
+
+    vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &var, &avg) ;
+
+    return (var - ((avg * avg) >> 6));
+
+}
+
+
+unsigned int vp8_variance16x16_wmt
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0;
+    int sum0;
+
+
+    vp8_get16x16var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    *sse = sse0;
+    return (sse0 - ((sum0 * sum0) >> 8));
+}
+unsigned int vp8_mse16x16_wmt(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+
+    unsigned int sse0;
+    int sum0;
+    vp8_get16x16var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    *sse = sse0;
+    return sse0;
+
+}
+
+
+unsigned int vp8_variance16x8_wmt
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, var;
+    int sum0, sum1, avg;
+
+    vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_sse2(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+
+    var = sse0 + sse1;
+    avg = sum0 + sum1;
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+
+}
+
+unsigned int vp8_variance8x16_wmt
+(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, var;
+    int sum0, sum1, avg;
+
+    vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_sse2(src_ptr + 8 * source_stride, source_stride, ref_ptr + 8 * recon_stride, recon_stride, &sse1, &sum1) ;
+
+    var = sse0 + sse1;
+    avg = sum0 + sum1;
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+// the mmx function that does the bilinear filtering and var calculation //
+// int one pass                                                          //
+///////////////////////////////////////////////////////////////////////////
+DECLARE_ALIGNED(16, const short, vp8_bilinear_filters_xmm[8][16]) =
+{
+    { 128, 128, 128, 128, 128, 128, 128, 128,  0,  0,  0,  0,  0,  0,  0,  0 },
+    { 112, 112, 112, 112, 112, 112, 112, 112, 16, 16, 16, 16, 16, 16, 16, 16 },
+    {  96, 96, 96, 96, 96, 96, 96, 96, 32, 32, 32, 32, 32, 32, 32, 32 },
+    {  80, 80, 80, 80, 80, 80, 80, 80, 48, 48, 48, 48, 48, 48, 48, 48 },
+    {  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
+    {  48, 48, 48, 48, 48, 48, 48, 48, 80, 80, 80, 80, 80, 80, 80, 80 },
+    {  32, 32, 32, 32, 32, 32, 32, 32, 96, 96, 96, 96, 96, 96, 96, 96 },
+    {  16, 16, 16, 16, 16, 16, 16, 16, 112, 112, 112, 112, 112, 112, 112, 112 }
+};
+unsigned int vp8_sub_pixel_variance4x4_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    int xsum;
+    unsigned int xxsum;
+    vp8_filter_block2d_bil4x4_var_mmx(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line,
+        vp8_vp7_bilinear_filters_mmx[xoffset], vp8_vp7_bilinear_filters_mmx[yoffset],
+        &xsum, &xxsum
+    );
+    *sse = xxsum;
+    return (xxsum - ((xsum * xsum) >> 4));
+}
+
+
+unsigned int vp8_sub_pixel_variance8x8_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+
+    int xsum;
+    unsigned int xxsum;
+    vp8_filter_block2d_bil_var_sse2(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 8,
+        vp8_bilinear_filters_xmm[xoffset], vp8_bilinear_filters_xmm[yoffset],
+        &xsum, &xxsum
+    );
+
+    *sse = xxsum;
+    return (xxsum - ((xsum * xsum) >> 6));
+}
+
+unsigned int vp8_sub_pixel_variance16x16_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    int xsum0, xsum1;
+    unsigned int xxsum0, xxsum1;
+
+
+    // note we could avoid these if statements if the calling function
+    // just called the appropriate functions inside.
+    if (xoffset == 4 && yoffset == 0)
+    {
+        vp8_half_horiz_variance16x_h_sse2(
+            src_ptr, src_pixels_per_line,
+            dst_ptr, dst_pixels_per_line, 16,
+            &xsum0, &xxsum0);
+
+        vp8_half_horiz_variance16x_h_sse2(
+            src_ptr + 8, src_pixels_per_line,
+            dst_ptr + 8, dst_pixels_per_line, 16,
+            &xsum1, &xxsum1);
+    }
+    else if (xoffset == 0 && yoffset == 4)
+    {
+        vp8_half_vert_variance16x_h_sse2(
+            src_ptr, src_pixels_per_line,
+            dst_ptr, dst_pixels_per_line, 16,
+            &xsum0, &xxsum0);
+
+        vp8_half_vert_variance16x_h_sse2(
+            src_ptr + 8, src_pixels_per_line,
+            dst_ptr + 8, dst_pixels_per_line, 16,
+            &xsum1, &xxsum1);
+    }
+    else if (xoffset == 4 && yoffset == 4)
+    {
+        vp8_half_horiz_vert_variance16x_h_sse2(
+            src_ptr, src_pixels_per_line,
+            dst_ptr, dst_pixels_per_line, 16,
+            &xsum0, &xxsum0);
+
+        vp8_half_horiz_vert_variance16x_h_sse2(
+            src_ptr + 8, src_pixels_per_line,
+            dst_ptr + 8, dst_pixels_per_line, 16,
+            &xsum1, &xxsum1);
+    }
+    else
+    {
+        vp8_filter_block2d_bil_var_sse2(
+            src_ptr, src_pixels_per_line,
+            dst_ptr, dst_pixels_per_line, 16,
+            vp8_bilinear_filters_xmm[xoffset], vp8_bilinear_filters_xmm[yoffset],
+            &xsum0, &xxsum0
+        );
+
+
+        vp8_filter_block2d_bil_var_sse2(
+            src_ptr + 8, src_pixels_per_line,
+            dst_ptr + 8, dst_pixels_per_line, 16,
+            vp8_bilinear_filters_xmm[xoffset], vp8_bilinear_filters_xmm[yoffset],
+            &xsum1, &xxsum1
+        );
+    }
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+    *sse = xxsum0;
+    return (xxsum0 - ((xsum0 * xsum0) >> 8));
+}
+
+unsigned int vp8_sub_pixel_mse16x16_wmt(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    vp8_sub_pixel_variance16x16_wmt(src_ptr, src_pixels_per_line, xoffset, yoffset, dst_ptr, dst_pixels_per_line, sse);
+    return *sse;
+}
+
+unsigned int vp8_sub_pixel_variance16x8_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+
+)
+{
+    int xsum0, xsum1;
+    unsigned int xxsum0, xxsum1;
+
+
+    vp8_filter_block2d_bil_var_sse2(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 8,
+        vp8_bilinear_filters_xmm[xoffset], vp8_bilinear_filters_xmm[yoffset],
+        &xsum0, &xxsum0
+    );
+
+
+    vp8_filter_block2d_bil_var_sse2(
+        src_ptr + 8, src_pixels_per_line,
+        dst_ptr + 8, dst_pixels_per_line, 8,
+        vp8_bilinear_filters_xmm[xoffset], vp8_bilinear_filters_xmm[yoffset],
+        &xsum1, &xxsum1
+    );
+
+    xsum0 += xsum1;
+    xxsum0 += xxsum1;
+
+    *sse = xxsum0;
+    return (xxsum0 - ((xsum0 * xsum0) >> 7));
+}
+
+unsigned int vp8_sub_pixel_variance8x16_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    int xsum;
+    unsigned int xxsum;
+    vp8_filter_block2d_bil_var_sse2(
+        src_ptr, src_pixels_per_line,
+        dst_ptr, dst_pixels_per_line, 16,
+        vp8_bilinear_filters_xmm[xoffset], vp8_bilinear_filters_xmm[yoffset],
+        &xsum, &xxsum
+    );
+
+    *sse = xxsum;
+    return (xxsum - ((xsum * xsum) >> 7));
+}
+
+unsigned int vp8_i_variance16x16_wmt(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, sse2, sse3, var;
+    int sum0, sum1, sum2, sum3, avg;
+
+
+    vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_sse2(src_ptr + 8, source_stride, ref_ptr + 8, recon_stride, &sse1, &sum1);
+    vp8_get8x8var_sse2(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse2, &sum2) ;
+    vp8_get8x8var_sse2(src_ptr + (source_stride >> 1) + 8, source_stride, ref_ptr + (recon_stride >> 1) + 8, recon_stride, &sse3, &sum3);
+
+    var = sse0 + sse1 + sse2 + sse3;
+    avg = sum0 + sum1 + sum2 + sum3;
+
+    *sse = var;
+    return (var - ((avg * avg) >> 8));
+
+}
+
+unsigned int vp8_i_variance8x16_wmt(
+    unsigned char *src_ptr,
+    int  source_stride,
+    unsigned char *ref_ptr,
+    int  recon_stride,
+    unsigned int *sse)
+{
+    unsigned int sse0, sse1, var;
+    int sum0, sum1, avg;
+    vp8_get8x8var_sse2(src_ptr, source_stride, ref_ptr, recon_stride, &sse0, &sum0) ;
+    vp8_get8x8var_sse2(src_ptr + (source_stride >> 1), source_stride, ref_ptr + (recon_stride >> 1), recon_stride, &sse1, &sum1) ;
+
+    var = sse0 + sse1;
+    avg = sum0 + sum1;
+
+    *sse = var;
+    return (var - ((avg * avg) >> 7));
+
+}
+
+
+unsigned int vp8_i_sub_pixel_variance16x16_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+    return vp8_sub_pixel_variance16x16_wmt(src_ptr, (src_pixels_per_line >> 1), xoffset, yoffset, dst_ptr, (dst_pixels_per_line >> 1), sse);
+}
+
+
+unsigned int vp8_i_sub_pixel_variance8x16_wmt
+(
+    unsigned char  *src_ptr,
+    int  src_pixels_per_line,
+    int  xoffset,
+    int  yoffset,
+    unsigned char *dst_ptr,
+    int dst_pixels_per_line,
+    unsigned int *sse
+)
+{
+
+    return vp8_sub_pixel_variance8x16_wmt(src_ptr, (src_pixels_per_line >> 1), xoffset, yoffset, dst_ptr, (dst_pixels_per_line >> 1), sse);
+}
diff --git a/vp8/encoder/x86/variance_x86.h b/vp8/encoder/x86/variance_x86.h
new file mode 100644 (file)
index 0000000..35fc90c
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VARIANCE_X86_H
+#define VARIANCE_X86_H
+
+
+/* Note:
+ *
+ * This platform is commonly built for runtime CPU detection. If you modify
+ * any of the function mappings present in this file, be sure to also update
+ * them in the function pointer initialization code
+ */
+#if HAVE_MMX
+extern prototype_sad(vp8_sad4x4_mmx);
+extern prototype_sad(vp8_sad8x8_mmx);
+extern prototype_sad(vp8_sad8x16_mmx);
+extern prototype_sad(vp8_sad16x8_mmx);
+extern prototype_sad(vp8_sad16x16_mmx);
+extern prototype_variance(vp8_variance4x4_mmx);
+extern prototype_variance(vp8_variance8x8_mmx);
+extern prototype_variance(vp8_variance8x16_mmx);
+extern prototype_variance(vp8_variance16x8_mmx);
+extern prototype_variance(vp8_variance16x16_mmx);
+extern prototype_subpixvariance(vp8_sub_pixel_variance4x4_mmx);
+extern prototype_subpixvariance(vp8_sub_pixel_variance8x8_mmx);
+extern prototype_subpixvariance(vp8_sub_pixel_variance8x16_mmx);
+extern prototype_subpixvariance(vp8_sub_pixel_variance16x8_mmx);
+extern prototype_subpixvariance(vp8_sub_pixel_variance16x16_mmx);
+extern prototype_subpixvariance(vp8_sub_pixel_mse16x16_mmx);
+extern prototype_getmbss(vp8_get_mb_ss_mmx);
+extern prototype_variance(vp8_mse16x16_mmx);
+extern prototype_sad(vp8_get16x16pred_error_mmx);
+extern prototype_variance2(vp8_get8x8var_mmx);
+extern prototype_variance2(vp8_get16x16var_mmx);
+extern prototype_sad(vp8_get4x4sse_cs_mmx);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_variance_sad4x4
+#define vp8_variance_sad4x4 vp8_sad4x4_mmx
+
+#undef  vp8_variance_sad8x8
+#define vp8_variance_sad8x8 vp8_sad8x8_mmx
+
+#undef  vp8_variance_sad8x16
+#define vp8_variance_sad8x16 vp8_sad8x16_mmx
+
+#undef  vp8_variance_sad16x8
+#define vp8_variance_sad16x8 vp8_sad16x8_mmx
+
+#undef  vp8_variance_sad16x16
+#define vp8_variance_sad16x16 vp8_sad16x16_mmx
+
+#undef  vp8_variance_var4x4
+#define vp8_variance_var4x4 vp8_variance4x4_mmx
+
+#undef  vp8_variance_var8x8
+#define vp8_variance_var8x8 vp8_variance8x8_mmx
+
+#undef  vp8_variance_var8x16
+#define vp8_variance_var8x16 vp8_variance8x16_mmx
+
+#undef  vp8_variance_var16x8
+#define vp8_variance_var16x8 vp8_variance16x8_mmx
+
+#undef  vp8_variance_var16x16
+#define vp8_variance_var16x16 vp8_variance16x16_mmx
+
+#undef  vp8_variance_subpixvar4x4
+#define vp8_variance_subpixvar4x4 vp8_sub_pixel_variance4x4_mmx
+
+#undef  vp8_variance_subpixvar8x8
+#define vp8_variance_subpixvar8x8 vp8_sub_pixel_variance8x8_mmx
+
+#undef  vp8_variance_subpixvar8x16
+#define vp8_variance_subpixvar8x16 vp8_sub_pixel_variance8x16_mmx
+
+#undef  vp8_variance_subpixvar16x8
+#define vp8_variance_subpixvar16x8 vp8_sub_pixel_variance16x8_mmx
+
+#undef  vp8_variance_subpixvar16x16
+#define vp8_variance_subpixvar16x16 vp8_sub_pixel_variance16x16_mmx
+
+#undef  vp8_variance_subpixmse16x16
+#define vp8_variance_subpixmse16x16 vp8_sub_pixel_mse16x16_mmx
+
+#undef  vp8_variance_getmbss
+#define vp8_variance_getmbss vp8_get_mb_ss_mmx
+
+#undef  vp8_variance_mse16x16
+#define vp8_variance_mse16x16 vp8_mse16x16_mmx
+
+#undef  vp8_variance_get16x16prederror
+#define vp8_variance_get16x16prederror vp8_get16x16pred_error_mmx
+
+#undef  vp8_variance_get8x8var
+#define vp8_variance_get8x8var vp8_get8x8var_mmx
+
+#undef  vp8_variance_get16x16var
+#define vp8_variance_get16x16var vp8_get16x16var_mmx
+
+#undef  vp8_variance_get4x4sse_cs
+#define vp8_variance_get4x4sse_cs vp8_get4x4sse_cs_mmx
+
+#endif
+#endif
+
+
+#if HAVE_SSE2
+extern prototype_sad(vp8_sad4x4_wmt);
+extern prototype_sad(vp8_sad8x8_wmt);
+extern prototype_sad(vp8_sad8x16_wmt);
+extern prototype_sad(vp8_sad16x8_wmt);
+extern prototype_sad(vp8_sad16x16_wmt);
+extern prototype_variance(vp8_variance4x4_wmt);
+extern prototype_variance(vp8_variance8x8_wmt);
+extern prototype_variance(vp8_variance8x16_wmt);
+extern prototype_variance(vp8_variance16x8_wmt);
+extern prototype_variance(vp8_variance16x16_wmt);
+extern prototype_subpixvariance(vp8_sub_pixel_variance4x4_wmt);
+extern prototype_subpixvariance(vp8_sub_pixel_variance8x8_wmt);
+extern prototype_subpixvariance(vp8_sub_pixel_variance8x16_wmt);
+extern prototype_subpixvariance(vp8_sub_pixel_variance16x8_wmt);
+extern prototype_subpixvariance(vp8_sub_pixel_variance16x16_wmt);
+extern prototype_subpixvariance(vp8_sub_pixel_mse16x16_wmt);
+extern prototype_getmbss(vp8_get_mb_ss_sse2);
+extern prototype_variance(vp8_mse16x16_wmt);
+extern prototype_sad(vp8_get16x16pred_error_sse2);
+extern prototype_variance2(vp8_get8x8var_sse2);
+extern prototype_variance2(vp8_get16x16var_sse2);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_variance_sad4x4
+#define vp8_variance_sad4x4 vp8_sad4x4_wmt
+
+#undef  vp8_variance_sad8x8
+#define vp8_variance_sad8x8 vp8_sad8x8_wmt
+
+#undef  vp8_variance_sad8x16
+#define vp8_variance_sad8x16 vp8_sad8x16_wmt
+
+#undef  vp8_variance_sad16x8
+#define vp8_variance_sad16x8 vp8_sad16x8_wmt
+
+#undef  vp8_variance_sad16x16
+#define vp8_variance_sad16x16 vp8_sad16x16_wmt
+
+#undef  vp8_variance_var4x4
+#define vp8_variance_var4x4 vp8_variance4x4_wmt
+
+#undef  vp8_variance_var8x8
+#define vp8_variance_var8x8 vp8_variance8x8_wmt
+
+#undef  vp8_variance_var8x16
+#define vp8_variance_var8x16 vp8_variance8x16_wmt
+
+#undef  vp8_variance_var16x8
+#define vp8_variance_var16x8 vp8_variance16x8_wmt
+
+#undef  vp8_variance_var16x16
+#define vp8_variance_var16x16 vp8_variance16x16_wmt
+
+#undef  vp8_variance_subpixvar4x4
+#define vp8_variance_subpixvar4x4 vp8_sub_pixel_variance4x4_wmt
+
+#undef  vp8_variance_subpixvar8x8
+#define vp8_variance_subpixvar8x8 vp8_sub_pixel_variance8x8_wmt
+
+#undef  vp8_variance_subpixvar8x16
+#define vp8_variance_subpixvar8x16 vp8_sub_pixel_variance8x16_wmt
+
+#undef  vp8_variance_subpixvar16x8
+#define vp8_variance_subpixvar16x8 vp8_sub_pixel_variance16x8_wmt
+
+#undef  vp8_variance_subpixvar16x16
+#define vp8_variance_subpixvar16x16 vp8_sub_pixel_variance16x16_wmt
+
+#undef  vp8_variance_subpixmse16x16
+#define vp8_variance_subpixmse16x16 vp8_sub_pixel_mse16x16_wmt
+
+#undef  vp8_variance_getmbss
+#define vp8_variance_getmbss vp8_get_mb_ss_sse2
+
+#undef  vp8_variance_mse16x16
+#define vp8_variance_mse16x16 vp8_mse16x16_wmt
+
+#undef  vp8_variance_get16x16prederror
+#define vp8_variance_get16x16prederror vp8_get16x16pred_error_sse2
+
+#undef  vp8_variance_get8x8var
+#define vp8_variance_get8x8var vp8_get8x8var_sse2
+
+#undef  vp8_variance_get16x16var
+#define vp8_variance_get16x16var vp8_get16x16var_sse2
+
+#endif
+#endif
+
+
+#if HAVE_SSE3
+extern prototype_sad(vp8_sad16x16_sse3);
+extern prototype_sad(vp8_sad16x8_sse3);
+extern prototype_sad_multi_same_address(vp8_sad16x16x3_sse3);
+extern prototype_sad_multi_same_address(vp8_sad16x8x3_sse3);
+extern prototype_sad_multi_same_address(vp8_sad8x16x3_sse3);
+extern prototype_sad_multi_same_address(vp8_sad8x8x3_sse3);
+extern prototype_sad_multi_same_address(vp8_sad4x4x3_sse3);
+
+extern prototype_sad_multi_dif_address(vp8_sad16x16x4d_sse3);
+extern prototype_sad_multi_dif_address(vp8_sad16x8x4d_sse3);
+extern prototype_sad_multi_dif_address(vp8_sad8x16x4d_sse3);
+extern prototype_sad_multi_dif_address(vp8_sad8x8x4d_sse3);
+extern prototype_sad_multi_dif_address(vp8_sad4x4x4d_sse3);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+
+#undef  vp8_variance_sad16x16
+#define vp8_variance_sad16x16 vp8_sad16x16_sse3
+
+#undef  vp8_variance_sad16x16x3
+#define vp8_variance_sad16x16x3 vp8_sad16x16x3_sse3
+
+#undef  vp8_variance_sad16x8x3
+#define vp8_variance_sad16x8x3 vp8_sad16x8x3_sse3
+
+#undef  vp8_variance_sad8x16x3
+#define vp8_variance_sad8x16x3 vp8_sad8x16x3_sse3
+
+#undef  vp8_variance_sad8x8x3
+#define vp8_variance_sad8x8x3 vp8_sad8x8x3_sse3
+
+#undef  vp8_variance_sad4x4x3
+#define vp8_variance_sad4x4x3 vp8_sad4x4x3_sse3
+
+#undef  vp8_variance_sad16x16x4d
+#define vp8_variance_sad16x16x4 vp8_sad16x16x4d_sse3
+
+#undef  vp8_variance_sad16x8x4d
+#define vp8_variance_sad16x8x4d vp8_sad16x8x4d_sse3
+
+#undef  vp8_variance_sad8x16x4d
+#define vp8_variance_sad8x16x4d vp8_sad8x16x4d_sse3
+
+#undef  vp8_variance_sad8x8x4d
+#define vp8_variance_sad8x8x4d vp8_sad8x8x4d_sse3
+
+#undef  vp8_variance_sad4x4x4d
+#define vp8_variance_sad4x4x4d vp8_sad4x4x4d_sse3
+
+#endif
+#endif
+
+
+#if HAVE_SSSE3
+extern prototype_sad_multi_same_address(vp8_sad16x16x3_ssse3);
+extern prototype_sad_multi_same_address(vp8_sad16x8x3_ssse3);
+
+#if !CONFIG_RUNTIME_CPU_DETECT
+#undef  vp8_variance_sad16x16x3
+#define vp8_variance_sad16x16x3 vp8_sad16x16x3_ssse3
+
+#undef  vp8_variance_sad16x8x3
+#define vp8_variance_sad16x8x3 vp8_sad16x8x3_ssse3
+
+#endif
+#endif
+
+#endif
diff --git a/vp8/encoder/x86/x86_csystemdependent.c b/vp8/encoder/x86/x86_csystemdependent.c
new file mode 100644 (file)
index 0000000..f1391ba
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_ports/config.h"
+#include "vpx_ports/x86.h"
+#include "variance.h"
+#include "onyx_int.h"
+
+
+#if HAVE_MMX
+void vp8_short_fdct8x4_mmx(short *input, short *output, int pitch)
+{
+    vp8_short_fdct4x4_mmx(input,   output,    pitch);
+    vp8_short_fdct4x4_mmx(input + 4, output + 16, pitch);
+}
+
+void vp8_fast_fdct8x4_mmx(short *input, short *output, int pitch)
+{
+    vp8_fast_fdct4x4_mmx(input,   output   , pitch);
+    vp8_fast_fdct4x4_mmx(input + 4, output + 16, pitch);
+}
+
+int vp8_fast_quantize_b_impl_mmx(short *coeff_ptr, short *zbin_ptr,
+                                 short *qcoeff_ptr, short *dequant_ptr,
+                                 short *scan_mask, short *round_ptr,
+                                 short *quant_ptr, short *dqcoeff_ptr);
+void vp8_fast_quantize_b_mmx(BLOCK *b, BLOCKD *d)
+{
+    short *scan_mask    = vp8_default_zig_zag_mask;//d->scan_order_mask_ptr;
+    short *coeff_ptr  = &b->coeff[0];
+    short *zbin_ptr   = &b->zbin[0][0];
+    short *round_ptr  = &b->round[0][0];
+    short *quant_ptr  = &b->quant[0][0];
+    short *qcoeff_ptr = d->qcoeff;
+    short *dqcoeff_ptr = d->dqcoeff;
+    short *dequant_ptr = &d->dequant[0][0];
+
+    d->eob = vp8_fast_quantize_b_impl_mmx(
+                 coeff_ptr,
+                 zbin_ptr,
+                 qcoeff_ptr,
+                 dequant_ptr,
+                 scan_mask,
+
+                 round_ptr,
+                 quant_ptr,
+                 dqcoeff_ptr
+             );
+}
+
+int vp8_mbblock_error_mmx_impl(short *coeff_ptr, short *dcoef_ptr, int dc);
+int vp8_mbblock_error_mmx(MACROBLOCK *mb, int dc)
+{
+    short *coeff_ptr =  mb->block[0].coeff;
+    short *dcoef_ptr =  mb->e_mbd.block[0].dqcoeff;
+    return vp8_mbblock_error_mmx_impl(coeff_ptr, dcoef_ptr, dc);
+}
+
+int vp8_mbuverror_mmx_impl(short *s_ptr, short *d_ptr);
+int vp8_mbuverror_mmx(MACROBLOCK *mb)
+{
+    short *s_ptr = &mb->coeff[256];
+    short *d_ptr = &mb->e_mbd.dqcoeff[256];
+    return vp8_mbuverror_mmx_impl(s_ptr, d_ptr);
+}
+
+void vp8_subtract_b_mmx_impl(unsigned char *z,  int src_stride,
+                             short *diff, unsigned char *predictor,
+                             int pitch);
+void vp8_subtract_b_mmx(BLOCK *be, BLOCKD *bd, int pitch)
+{
+    unsigned char *z = *(be->base_src) + be->src;
+    unsigned int  src_stride = be->src_stride;
+    short *diff = &be->src_diff[0];
+    unsigned char *predictor = &bd->predictor[0];
+    vp8_subtract_b_mmx_impl(z, src_stride, diff, predictor, pitch);
+}
+
+#endif
+
+#if HAVE_SSE2
+void vp8_short_fdct8x4_wmt(short *input, short *output, int pitch)
+{
+    vp8_short_fdct4x4_wmt(input,   output,    pitch);
+    vp8_short_fdct4x4_wmt(input + 4, output + 16, pitch);
+}
+
+int vp8_fast_quantize_b_impl_sse(short *coeff_ptr, short *zbin_ptr,
+                                 short *qcoeff_ptr, short *dequant_ptr,
+                                 short *scan_mask, short *round_ptr,
+                                 short *quant_ptr, short *dqcoeff_ptr);
+void vp8_fast_quantize_b_sse(BLOCK *b, BLOCKD *d)
+{
+    short *scan_mask    = vp8_default_zig_zag_mask;//d->scan_order_mask_ptr;
+    short *coeff_ptr  = &b->coeff[0];
+    short *zbin_ptr   = &b->zbin[0][0];
+    short *round_ptr  = &b->round[0][0];
+    short *quant_ptr  = &b->quant[0][0];
+    short *qcoeff_ptr = d->qcoeff;
+    short *dqcoeff_ptr = d->dqcoeff;
+    short *dequant_ptr = &d->dequant[0][0];
+
+    d->eob = vp8_fast_quantize_b_impl_sse(
+                 coeff_ptr,
+                 zbin_ptr,
+                 qcoeff_ptr,
+                 dequant_ptr,
+                 scan_mask,
+
+                 round_ptr,
+                 quant_ptr,
+                 dqcoeff_ptr
+             );
+}
+
+int vp8_mbblock_error_xmm_impl(short *coeff_ptr, short *dcoef_ptr, int dc);
+int vp8_mbblock_error_xmm(MACROBLOCK *mb, int dc)
+{
+    short *coeff_ptr =  mb->block[0].coeff;
+    short *dcoef_ptr =  mb->e_mbd.block[0].dqcoeff;
+    return vp8_mbblock_error_xmm_impl(coeff_ptr, dcoef_ptr, dc);
+}
+
+int vp8_mbuverror_xmm_impl(short *s_ptr, short *d_ptr);
+int vp8_mbuverror_xmm(MACROBLOCK *mb)
+{
+    short *s_ptr = &mb->coeff[256];
+    short *d_ptr = &mb->e_mbd.dqcoeff[256];
+    return vp8_mbuverror_xmm_impl(s_ptr, d_ptr);
+}
+
+#endif
+
+void vp8_arch_x86_encoder_init(VP8_COMP *cpi)
+{
+#if CONFIG_RUNTIME_CPU_DETECT
+    int flags = x86_simd_caps();
+    int mmx_enabled = flags & HAS_MMX;
+    int xmm_enabled = flags & HAS_SSE;
+    int wmt_enabled = flags & HAS_SSE2;
+    int SSE3Enabled = flags & HAS_SSE3;
+    int SSSE3Enabled = flags & HAS_SSSE3;
+
+    /* Note:
+     *
+     * This platform can be built without runtime CPU detection as well. If
+     * you modify any of the function mappings present in this file, be sure
+     * to also update them in static mapings (<arch>/filename_<arch>.h)
+     */
+
+    /* Override default functions with fastest ones for this CPU. */
+#if HAVE_MMX
+
+    if (mmx_enabled)
+    {
+        cpi->rtcd.variance.sad16x16              = vp8_sad16x16_mmx;
+        cpi->rtcd.variance.sad16x8               = vp8_sad16x8_mmx;
+        cpi->rtcd.variance.sad8x16               = vp8_sad8x16_mmx;
+        cpi->rtcd.variance.sad8x8                = vp8_sad8x8_mmx;
+        cpi->rtcd.variance.sad4x4                = vp8_sad4x4_mmx;
+
+        cpi->rtcd.variance.var4x4                = vp8_variance4x4_mmx;
+        cpi->rtcd.variance.var8x8                = vp8_variance8x8_mmx;
+        cpi->rtcd.variance.var8x16               = vp8_variance8x16_mmx;
+        cpi->rtcd.variance.var16x8               = vp8_variance16x8_mmx;
+        cpi->rtcd.variance.var16x16              = vp8_variance16x16_mmx;
+
+        cpi->rtcd.variance.subpixvar4x4          = vp8_sub_pixel_variance4x4_mmx;
+        cpi->rtcd.variance.subpixvar8x8          = vp8_sub_pixel_variance8x8_mmx;
+        cpi->rtcd.variance.subpixvar8x16         = vp8_sub_pixel_variance8x16_mmx;
+        cpi->rtcd.variance.subpixvar16x8         = vp8_sub_pixel_variance16x8_mmx;
+        cpi->rtcd.variance.subpixvar16x16        = vp8_sub_pixel_variance16x16_mmx;
+        cpi->rtcd.variance.subpixmse16x16        = vp8_sub_pixel_mse16x16_mmx;
+
+        cpi->rtcd.variance.mse16x16              = vp8_mse16x16_mmx;
+        cpi->rtcd.variance.getmbss               = vp8_get_mb_ss_mmx;
+
+        cpi->rtcd.variance.get16x16prederror     = vp8_get16x16pred_error_mmx;
+        cpi->rtcd.variance.get8x8var             = vp8_get8x8var_mmx;
+        cpi->rtcd.variance.get16x16var           = vp8_get16x16var_mmx;
+        cpi->rtcd.variance.get4x4sse_cs          = vp8_get4x4sse_cs_mmx;
+
+        cpi->rtcd.fdct.short4x4                  = vp8_short_fdct4x4_mmx;
+        cpi->rtcd.fdct.short8x4                  = vp8_short_fdct8x4_mmx;
+        cpi->rtcd.fdct.fast4x4                   = vp8_fast_fdct4x4_mmx;
+        cpi->rtcd.fdct.fast8x4                   = vp8_fast_fdct8x4_mmx;
+        cpi->rtcd.fdct.walsh_short4x4            = vp8_short_walsh4x4_c;
+
+        cpi->rtcd.encodemb.berr                  = vp8_block_error_mmx;
+        cpi->rtcd.encodemb.mberr                 = vp8_mbblock_error_mmx;
+        cpi->rtcd.encodemb.mbuverr               = vp8_mbuverror_mmx;
+        cpi->rtcd.encodemb.subb                  = vp8_subtract_b_mmx;
+        cpi->rtcd.encodemb.submby                = vp8_subtract_mby_mmx;
+        cpi->rtcd.encodemb.submbuv               = vp8_subtract_mbuv_mmx;
+
+        cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_mmx;
+    }
+
+#endif
+#if HAVE_SSE2
+
+    if (wmt_enabled)
+    {
+        cpi->rtcd.variance.sad16x16              = vp8_sad16x16_wmt;
+        cpi->rtcd.variance.sad16x8               = vp8_sad16x8_wmt;
+        cpi->rtcd.variance.sad8x16               = vp8_sad8x16_wmt;
+        cpi->rtcd.variance.sad8x8                = vp8_sad8x8_wmt;
+        cpi->rtcd.variance.sad4x4                = vp8_sad4x4_wmt;
+
+        cpi->rtcd.variance.var4x4                = vp8_variance4x4_wmt;
+        cpi->rtcd.variance.var8x8                = vp8_variance8x8_wmt;
+        cpi->rtcd.variance.var8x16               = vp8_variance8x16_wmt;
+        cpi->rtcd.variance.var16x8               = vp8_variance16x8_wmt;
+        cpi->rtcd.variance.var16x16              = vp8_variance16x16_wmt;
+
+        cpi->rtcd.variance.subpixvar4x4          = vp8_sub_pixel_variance4x4_wmt;
+        cpi->rtcd.variance.subpixvar8x8          = vp8_sub_pixel_variance8x8_wmt;
+        cpi->rtcd.variance.subpixvar8x16         = vp8_sub_pixel_variance8x16_wmt;
+        cpi->rtcd.variance.subpixvar16x8         = vp8_sub_pixel_variance16x8_wmt;
+        cpi->rtcd.variance.subpixvar16x16        = vp8_sub_pixel_variance16x16_wmt;
+        cpi->rtcd.variance.subpixmse16x16        = vp8_sub_pixel_mse16x16_wmt;
+
+        cpi->rtcd.variance.mse16x16              = vp8_mse16x16_wmt;
+        cpi->rtcd.variance.getmbss               = vp8_get_mb_ss_sse2;
+
+        cpi->rtcd.variance.get16x16prederror     = vp8_get16x16pred_error_sse2;
+        cpi->rtcd.variance.get8x8var             = vp8_get8x8var_sse2;
+        cpi->rtcd.variance.get16x16var           = vp8_get16x16var_sse2;
+        /* cpi->rtcd.variance.get4x4sse_cs  not implemented for wmt */;
+
+#if 0
+        /* short SSE2 DCT currently disabled, does not match the MMX version */
+        cpi->rtcd.fdct.short4x4                  = vp8_short_fdct4x4_wmt;
+        cpi->rtcd.fdct.short8x4                  = vp8_short_fdct8x4_wmt;
+#endif
+        /* cpi->rtcd.fdct.fast4x4  not implemented for wmt */;
+        cpi->rtcd.fdct.fast8x4                   = vp8_fast_fdct8x4_wmt;
+        cpi->rtcd.fdct.walsh_short4x4            = vp8_short_walsh4x4_sse2;
+
+        cpi->rtcd.encodemb.berr                  = vp8_block_error_xmm;
+        cpi->rtcd.encodemb.mberr                 = vp8_mbblock_error_xmm;
+        cpi->rtcd.encodemb.mbuverr               = vp8_mbuverror_xmm;
+        /* cpi->rtcd.encodemb.sub* not implemented for wmt */
+
+        cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_sse;
+    }
+
+#endif
+#if HAVE_SSE3
+
+    if (SSE3Enabled)
+    {
+        cpi->rtcd.variance.sad16x16              = vp8_sad16x16_sse3;
+        cpi->rtcd.variance.sad16x16x3            = vp8_sad16x16x3_sse3;
+        cpi->rtcd.variance.sad16x8x3             = vp8_sad16x8x3_sse3;
+        cpi->rtcd.variance.sad8x16x3             = vp8_sad8x16x3_sse3;
+        cpi->rtcd.variance.sad8x8x3              = vp8_sad8x8x3_sse3;
+        cpi->rtcd.variance.sad4x4x3              = vp8_sad4x4x3_sse3;
+        cpi->rtcd.search.full_search             = vp8_full_search_sadx3;
+
+        cpi->rtcd.variance.sad16x16x4d           = vp8_sad16x16x4d_sse3;
+        cpi->rtcd.variance.sad16x8x4d            = vp8_sad16x8x4d_sse3;
+        cpi->rtcd.variance.sad8x16x4d            = vp8_sad8x16x4d_sse3;
+        cpi->rtcd.variance.sad8x8x4d             = vp8_sad8x8x4d_sse3;
+        cpi->rtcd.variance.sad4x4x4d             = vp8_sad4x4x4d_sse3;
+        cpi->rtcd.search.diamond_search          = vp8_diamond_search_sadx4;
+    }
+
+#endif
+#if HAVE_SSSE3
+
+    if (SSSE3Enabled)
+    {
+        cpi->rtcd.variance.sad16x16x3            = vp8_sad16x16x3_ssse3;
+        cpi->rtcd.variance.sad16x8x3             = vp8_sad16x8x3_ssse3;
+    }
+
+#endif
+#endif
+}
diff --git a/vp8/vp8.h b/vp8/vp8.h
new file mode 100644 (file)
index 0000000..87ca217
--- /dev/null
+++ b/vp8/vp8.h
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\defgroup vp8 VP8
+ * \ingroup codecs
+ * VP8 is vpx's newest video compression algorithm that uses motion
+ * compensated prediction, Discrete Cosine Transform (DCT) coding of the
+ * prediction error signal and context dependent entropy coding techniques
+ * based on arithmatic principles. It features:
+ *  - YUV 4:2:0 image format
+ *  - Macro-block based coding (16x16 luma plus two 8x8 chroma)
+ *  - 1/4 (1/8) pixel accuracy motion compensated prediction
+ *  - 4x4 DCT transform
+ *  - 128 level linear quantizer
+ *  - In loop deblocking filter
+ *  - Context-based entropy coding
+ *
+ * @{
+ */
+/*!\file vp8.h
+ * \brief Provides controls common to both the VP8 encoder and decoder.
+ */
+#ifndef VP8_H
+#define VP8_H
+#include "vpx_codec_impl_top.h"
+
+/*!\brief Control functions
+ *
+ * The set of macros define the control functions of VP8 interface
+ */
+enum vp8_dec_control_id
+{
+    VP8_SET_REFERENCE       = 1,    /**< pass in an external frame into decoder to be used as reference frame */
+    VP8_COPY_REFERENCE      = 2,    /**< get a copy of reference frame from the decoder */
+    VP8_SET_POSTPROC        = 3,    /**< set decoder's the post processing settings  */
+    VP8_COMMON_CTRL_ID_MAX
+};
+
+/*!\brief post process flags
+ *
+ * The set of macros define VP8 decoder post processing flags
+ */
+enum vp8_postproc_level
+{
+    VP8_NOFILTERING    = 0,
+    VP8_DEBLOCK        = 1,
+    VP8_DEMACROBLOCK   = 2,
+    VP8_ADDNOISE       = 4,
+};
+
+/*!\brief post process flags
+ *
+ * This define a structure that describe the post processing settings. For
+ * the best objective measure (using thet PSNR metric) set post_proc_flag
+ * to VP8_DEBLOCK and deblocking_level to 1.
+ */
+
+typedef struct vp8_postproc_cfg
+{
+    int post_proc_flag;           /**< the types of post processing to be done, should be combination of "vp8_postproc_level" */
+    int deblocking_level;        /**< the strength of deblocking, valid range [0, 16] */
+    int noise_level;             /**< the strength of additive noise, valid range [0, 16] */
+} vp8_postproc_cfg_t;
+
+/*!\brief reference frame type
+ *
+ * The set of macros define the type of VP8 reference frames
+ */
+typedef enum vpx_ref_frame_type
+{
+    VP8_LAST_FRAME = 1,
+    VP8_GOLD_FRAME = 2,
+    VP8_ALTR_FRAME = 4
+} vpx_ref_frame_type_t;
+
+/*!\brief reference frame data struct
+ *
+ * define the data struct to access vp8 reference frames
+ */
+
+typedef struct vpx_ref_frame
+{
+    vpx_ref_frame_type_t  frame_type;   /**< which reference frame */
+    vpx_image_t           img;          /**< reference frame data in image format */
+} vpx_ref_frame_t;
+
+
+/*!\brief vp8 decoder control funciton parameter type
+ *
+ * defines the data type for each of VP8 decoder control funciton requires
+ */
+
+VPX_CTRL_USE_TYPE(VP8_SET_REFERENCE,           vpx_ref_frame_t *)
+VPX_CTRL_USE_TYPE(VP8_COPY_REFERENCE,          vpx_ref_frame_t *)
+VPX_CTRL_USE_TYPE(VP8_SET_POSTPROC,            vp8_postproc_cfg_t *)
+
+
+/*! @} - end defgroup vp8 */
+
+#if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT
+/* The following definitions are provided for backward compatibility with
+ * the VP8 1.0.x SDK. USE IN PRODUCTION CODE IS NOT RECOMMENDED.
+ */
+
+DECLSPEC_DEPRECATED extern vpx_codec_iface_t vpx_codec_vp8_algo DEPRECATED;
+#endif
+
+#include "vpx_codec_impl_bottom.h"
+#endif
diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk
new file mode 100644 (file)
index 0000000..ec467c5
--- /dev/null
@@ -0,0 +1,190 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+#add this file to the installed sources list
+VP8_COMMON_SRCS-yes += vp8_common.mk
+
+#common interface
+VP8_COMMON_SRCS-yes += vp8.h
+
+CFLAGS+=-I$(SRC_PATH_BARE)/$(VP8_PREFIX)common
+VP8_COMMON_SRCS-yes += common/type_aliases.h
+VP8_COMMON_SRCS-yes += common/pragmas.h
+
+CFLAGS+=-I$(SRC_PATH_BARE)/$(VP8_PREFIX)common
+VP8_COMMON_SRCS-yes += common/preproc.h
+VP8_COMMON_SRCS-yes += common/vpxerrors.h
+
+CFLAGS+=-I$(SRC_PATH_BARE)/$(VP8_PREFIX)common
+VP8_COMMON_SRCS-yes += common/ppflags.h
+VP8_COMMON_SRCS-yes += common/onyx.h
+VP8_COMMON_SRCS-yes += common/onyxd.h
+
+CFLAGS+=-I$(SRC_PATH_BARE)/$(VP8_PREFIX)common
+
+VP8_COMMON_SRCS-yes += common/segmentation_common.c
+VP8_COMMON_SRCS-yes += common/alloccommon.c
+VP8_COMMON_SRCS-yes += common/blockd.c
+VP8_COMMON_SRCS-yes += common/coefupdateprobs.h
+VP8_COMMON_SRCS-yes += common/debugmodes.c
+VP8_COMMON_SRCS-yes += common/defaultcoefcounts.h
+VP8_COMMON_SRCS-yes += common/entropy.c
+VP8_COMMON_SRCS-yes += common/entropymode.c
+VP8_COMMON_SRCS-yes += common/entropymv.c
+VP8_COMMON_SRCS-yes += common/extend.c
+VP8_COMMON_SRCS-yes += common/filter_c.c
+VP8_COMMON_SRCS-yes += common/findnearmv.c
+VP8_COMMON_SRCS-yes += common/generic/systemdependent.c
+VP8_COMMON_SRCS-yes += common/idctllm.c
+VP8_COMMON_SRCS-yes += common/alloccommon.h
+VP8_COMMON_SRCS-yes += common/blockd.h
+VP8_COMMON_SRCS-yes += common/common.h
+VP8_COMMON_SRCS-yes += common/common_types.h
+VP8_COMMON_SRCS-yes += common/entropy.h
+VP8_COMMON_SRCS-yes += common/entropymode.h
+VP8_COMMON_SRCS-yes += common/entropymv.h
+VP8_COMMON_SRCS-yes += common/extend.h
+VP8_COMMON_SRCS-yes += common/findnearmv.h
+VP8_COMMON_SRCS-yes += common/g_common.h
+VP8_COMMON_SRCS-yes += common/header.h
+VP8_COMMON_SRCS-yes += common/idct.h
+VP8_COMMON_SRCS-yes += common/invtrans.h
+VP8_COMMON_SRCS-yes += common/loopfilter.h
+VP8_COMMON_SRCS-yes += common/modecont.h
+VP8_COMMON_SRCS-yes += common/mv.h
+VP8_COMMON_SRCS-yes += common/onyxc_int.h
+VP8_COMMON_SRCS-yes += common/predictdc.h
+VP8_COMMON_SRCS-yes += common/quant_common.h
+VP8_COMMON_SRCS-yes += common/recon.h
+VP8_COMMON_SRCS-yes += common/reconinter.h
+VP8_COMMON_SRCS-yes += common/reconintra.h
+VP8_COMMON_SRCS-yes += common/reconintra4x4.h
+VP8_COMMON_SRCS-yes += common/segmentation_common.h
+VP8_COMMON_SRCS-yes += common/setupintrarecon.h
+VP8_COMMON_SRCS-yes += common/subpixel.h
+VP8_COMMON_SRCS-yes += common/swapyv12buffer.h
+VP8_COMMON_SRCS-yes += common/systemdependent.h
+VP8_COMMON_SRCS-yes += common/threading.h
+VP8_COMMON_SRCS-yes += common/treecoder.h
+VP8_COMMON_SRCS-yes += common/invtrans.c
+VP8_COMMON_SRCS-yes += common/loopfilter.c
+VP8_COMMON_SRCS-yes += common/loopfilter_filters.c
+VP8_COMMON_SRCS-yes += common/mbpitch.c
+VP8_COMMON_SRCS-yes += common/modecont.c
+VP8_COMMON_SRCS-yes += common/modecontext.c
+VP8_COMMON_SRCS-yes += common/predictdc.c
+VP8_COMMON_SRCS-yes += common/quant_common.c
+VP8_COMMON_SRCS-yes += common/recon.c
+VP8_COMMON_SRCS-yes += common/reconinter.c
+VP8_COMMON_SRCS-yes += common/reconintra.c
+VP8_COMMON_SRCS-yes += common/reconintra4x4.c
+VP8_COMMON_SRCS-yes += common/setupintrarecon.c
+VP8_COMMON_SRCS-yes += common/swapyv12buffer.c
+VP8_COMMON_SRCS-yes += common/textblit.c
+VP8_COMMON_SRCS-yes += common/treecoder.c
+
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/idct_x86.h
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/subpixel_x86.h
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/recon_x86.h
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/loopfilter_x86.h
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/postproc_x86.h
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/x86_systemdependent.c
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/vp8_asm_stubs.c
+VP8_COMMON_SRCS-$(ARCH_X86)$(ARCH_X86_64) += common/x86/loopfilter_x86.c
+VP8_COMMON_SRCS-$(CONFIG_POSTPROC) += common/postproc.h
+VP8_COMMON_SRCS-$(CONFIG_POSTPROC) += common/postproc.c
+VP8_COMMON_SRCS-$(CONFIG_VP8_ENCODER) += common/postproc.h
+VP8_COMMON_SRCS-$(CONFIG_VP8_ENCODER) += common/postproc.c
+VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/idctllm_mmx.asm
+VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/iwalsh_mmx.asm
+VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/recon_mmx.asm
+VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/subpixel_mmx.asm
+VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/loopfilter_mmx.asm
+VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/recon_sse2.asm
+VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/subpixel_sse2.asm
+VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/loopfilter_sse2.asm
+VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/iwalsh_sse2.asm
+ifeq ($(CONFIG_POSTPROC),yes)
+VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/postproc_mmx.asm
+VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/postproc_sse2.asm
+endif
+
+# common (c)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/bilinearfilter_arm.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/filter_arm.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/loopfilter_arm.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/recon_arm.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/reconintra4x4_arm.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/reconintra_arm.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/systemdependent.c
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/vpx_asm_offsets.c
+
+VP8_COMMON_SRCS_REMOVE-$(HAVE_ARMV6)  += common/filter_c.c
+VP8_COMMON_SRCS_REMOVE-$(HAVE_ARMV6)  += common/recon.c
+VP8_COMMON_SRCS_REMOVE-$(HAVE_ARMV6)  += common/reconintra4x4.c
+VP8_COMMON_SRCS_REMOVE-$(HAVE_ARMV6)  += common/generic/systemdependent.c
+
+# common (armv6)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/bilinearfilter_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/copymem8x4_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/copymem8x8_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/copymem16x16_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/iwalsh_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/filter_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/idct_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/loopfilter_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/recon_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/simpleloopfilter_v6$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/sixtappredict8x4_v6$(ASM)
+
+# common (neon)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/bilinearpredict4x4_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/bilinearpredict8x4_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/bilinearpredict8x8_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/bilinearpredict16x16_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/copymem8x4_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/copymem8x8_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/copymem16x16_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/iwalsh_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/loopfiltersimplehorizontaledge_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/loopfiltersimpleverticaledge_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/loopfilterhorizontaledge_uv_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/loopfilterhorizontaledge_y_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/loopfilterverticaledge_uv_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/loopfilterverticaledge_y_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/mbloopfilterhorizontaledge_uv_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/mbloopfilterhorizontaledge_y_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/mbloopfilterverticaledge_uv_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/mbloopfilterverticaledge_y_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/recon2b_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/recon4b_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/reconb_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/shortidct4x4llm_1_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/shortidct4x4llm_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/sixtappredict4x4_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/sixtappredict8x4_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/sixtappredict8x8_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/sixtappredict16x16_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/recon16x16mb_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/buildintrapredictorsmby_neon$(ASM)
+VP8_COMMON_SRCS-$(HAVE_ARMV7)  += common/arm/neon/save_neon_reg$(ASM)
+
+
+#
+# Rule to extract assembly constants from C sources
+#
+ifeq ($(ARCH_ARM),yes)
+vpx_asm_offsets.asm: obj_int_extract
+vpx_asm_offsets.asm: $(VP8_PREFIX)common/arm/vpx_asm_offsets.c.o
+       ./obj_int_extract rvds $< $(ADS2GAS) > $@
+OBJS-yes += $(VP8_PREFIX)common/arm/vpx_asm_offsets.c.o
+CLEAN-OBJS += vpx_asm_offsets.asm
+$(filter %$(ASM).o,$(OBJS-yes)): vpx_asm_offsets.asm
+endif
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
new file mode 100644 (file)
index 0000000..e129ec9
--- /dev/null
@@ -0,0 +1,1177 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_codec/vpx_codec.h"
+#include "vpx_codec/internal/vpx_codec_internal.h"
+#include "vpx_version.h"
+#include "onyx_int.h"
+#include "vp8e.h"
+#include "onyx.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* This value is a sentinel for determining whether the user has set a mode
+ * directly through the deprecated VP8E_SET_ENCODING_MODE control.
+ */
+#define NO_MODE_SET 255
+
+struct vp8_extracfg
+{
+    struct vpx_codec_pkt_list *pkt_list;
+    vp8e_encoding_mode      encoding_mode;               /** best, good, realtime            */
+    int                         cpu_used;                    /** available cpu percentage in 1/16*/
+    unsigned int                enable_auto_alt_ref;           /** if encoder decides to uses alternate reference frame */
+    unsigned int                noise_sensitivity;
+    unsigned int                Sharpness;
+    unsigned int                static_thresh;
+    unsigned int                token_partitions;
+    unsigned int                arnr_max_frames;    /* alt_ref Noise Reduction Max Frame Count */
+    unsigned int                arnr_strength;    /* alt_ref Noise Reduction Strength */
+    unsigned int                arnr_type;        /* alt_ref filter type */
+
+};
+
+struct extraconfig_map
+{
+    int                 usage;
+    struct vp8_extracfg cfg;
+};
+
+static const struct extraconfig_map extracfg_map[] =
+{
+    {
+        0,
+        {
+            NULL,
+#if !(CONFIG_REALTIME_ONLY)
+            VP8_BEST_QUALITY_ENCODING,  /* Encoding Mode */
+            -4,                         /* cpu_used      */
+#else
+            VP8_REAL_TIME_ENCODING,     /* Encoding Mode */
+            -8,                         /* cpu_used      */
+#endif
+            0,                          /* enable_auto_alt_ref */
+            0,                          /* noise_sensitivity */
+            0,                          /* Sharpness */
+            800,                        /* static_thresh */
+            VP8_ONE_TOKENPARTITION,     /* token_partitions */
+            0, /* arnr_max_frames */
+            0, /* arnr_strength */
+            0, /* arnr_type*/
+        }
+    }
+};
+
+struct vpx_codec_alg_priv
+{
+    vpx_codec_priv_t        base;
+    vpx_codec_enc_cfg_t     cfg;
+    struct vp8_extracfg     vp8_cfg;
+    VP8_CONFIG              oxcf;
+    VP8_PTR             cpi;
+    unsigned char          *cx_data;
+    unsigned int            cx_data_sz;
+    vpx_image_t             preview_img;
+    unsigned int            next_frame_flag;
+    vp8_postproc_cfg_t      preview_ppcfg;
+    vpx_codec_pkt_list_decl(26) pkt_list;              // changed to accomendate the maximum number of lagged frames allowed
+    int                         deprecated_mode;
+    unsigned int                fixed_kf_cntr;
+};
+
+
+static vpx_codec_err_t
+update_error_state(vpx_codec_alg_priv_t                 *ctx,
+                   const struct vpx_internal_error_info *error)
+{
+    vpx_codec_err_t res;
+
+    if ((res = error->error_code))
+        ctx->base.err_detail = error->has_detail
+                               ? error->detail
+                               : NULL;
+
+    return res;
+}
+
+
+#define ERROR(str) do {\
+        ctx->base.err_detail = str;\
+        return VPX_CODEC_INVALID_PARAM;\
+    } while(0)
+
+#define RANGE_CHECK(p,memb,lo,hi) do {\
+        if(!((p)->memb >= (lo) && (p)->memb <= hi)) \
+            ERROR(#memb " out of range ["#lo".."#hi"]");\
+    } while(0)
+
+#define RANGE_CHECK_LO(p,memb,lo) do {\
+        if(!((p)->memb >= (lo))) \
+            ERROR(#memb " out of range ["#lo"..]");\
+    } while(0)
+
+#define RANGE_CHECK_BOOL(p,memb) do {\
+        if(!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
+    } while(0)
+
+static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t      *ctx,
+                                       const vpx_codec_enc_cfg_t *cfg,
+                                       const struct vp8_extracfg *vp8_cfg)
+{
+    RANGE_CHECK(cfg, g_w,                   2, 16384);
+    RANGE_CHECK(cfg, g_h,                   2, 16384);
+    RANGE_CHECK(cfg, g_timebase.den,        1, 1000000000);
+    RANGE_CHECK(cfg, g_timebase.num,        1, cfg->g_timebase.den);
+    RANGE_CHECK(cfg, g_profile,             0, 3);
+    RANGE_CHECK(cfg, rc_min_quantizer,      0, 63);
+    RANGE_CHECK(cfg, rc_max_quantizer,      0, 63);
+    RANGE_CHECK(cfg, g_threads,             0, 64);
+#if !(CONFIG_REALTIME_ONLY)
+    RANGE_CHECK(cfg, g_lag_in_frames,       0, 25);
+#else
+    RANGE_CHECK(cfg, g_lag_in_frames,       0, 0);
+#endif
+    RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_CBR);
+    RANGE_CHECK(cfg, rc_undershoot_pct,     0, 100);
+    RANGE_CHECK(cfg, rc_2pass_vbr_bias_pct, 0, 100);
+    RANGE_CHECK(cfg, kf_mode,               VPX_KF_DISABLED, VPX_KF_AUTO);
+    //RANGE_CHECK_BOOL(cfg,                 g_delete_firstpassfile);
+    RANGE_CHECK_BOOL(cfg,                   rc_resize_allowed);
+    RANGE_CHECK(cfg, rc_dropframe_thresh,   0, 100);
+    RANGE_CHECK(cfg, rc_resize_up_thresh,   0, 100);
+    RANGE_CHECK(cfg, rc_resize_down_thresh, 0, 100);
+#if !(CONFIG_REALTIME_ONLY)
+    RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);
+#else
+    RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_ONE_PASS);
+#endif
+
+    /* VP8 does not support a lower bound on the keyframe interval in
+     * automatic keyframe placement mode.
+     */
+    if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist
+        && cfg->kf_min_dist > 0)
+        ERROR("kf_min_dist not supported in auto mode, use 0 "
+              "or kf_max_dist instead.");
+
+    RANGE_CHECK_BOOL(vp8_cfg,               enable_auto_alt_ref);
+#if !(CONFIG_REALTIME_ONLY)
+    RANGE_CHECK(vp8_cfg, encoding_mode,      VP8_BEST_QUALITY_ENCODING, VP8_REAL_TIME_ENCODING);
+    RANGE_CHECK(vp8_cfg, cpu_used,           -16, 16);
+    RANGE_CHECK(vp8_cfg, noise_sensitivity,  0, 6);
+#else
+    RANGE_CHECK(vp8_cfg, encoding_mode,      VP8_REAL_TIME_ENCODING, VP8_REAL_TIME_ENCODING);
+
+    if (!((vp8_cfg->cpu_used >= -16 && vp8_cfg->cpu_used <= -4) || (vp8_cfg->cpu_used >= 4 && vp8_cfg->cpu_used <= 16)))
+        ERROR("cpu_used out of range [-16..-4] or [4..16]");
+
+    RANGE_CHECK(vp8_cfg, noise_sensitivity,  0, 0);
+#endif
+
+    RANGE_CHECK(vp8_cfg, token_partitions,   VP8_ONE_TOKENPARTITION, VP8_EIGHT_TOKENPARTITION);
+    RANGE_CHECK(vp8_cfg, Sharpness,         0, 7);
+    RANGE_CHECK(vp8_cfg, arnr_max_frames,    0, 25);
+    RANGE_CHECK(vp8_cfg, arnr_strength,     0, 6);
+    RANGE_CHECK(vp8_cfg, arnr_type,         0, 0xffffffff);
+
+    if (cfg->g_pass == VPX_RC_LAST_PASS)
+    {
+        int n_doubles = cfg->rc_twopass_stats_in.sz / sizeof(double);
+        int n_packets = cfg->rc_twopass_stats_in.sz / sizeof(FIRSTPASS_STATS);
+        double frames;
+
+        if (!cfg->rc_twopass_stats_in.buf)
+            ERROR("rc_twopass_stats_in.buf not set.");
+
+        if (cfg->rc_twopass_stats_in.sz % sizeof(FIRSTPASS_STATS))
+            ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
+
+        if (cfg->rc_twopass_stats_in.sz < 2 * sizeof(FIRSTPASS_STATS))
+            ERROR("rc_twopass_stats_in requires at least two packets.");
+
+        frames = ((double *)cfg->rc_twopass_stats_in.buf)[n_doubles - 1];
+
+        if ((int)(frames + 0.5) != n_packets - 1)
+            ERROR("rc_twopass_stats_in missing EOS stats packet");
+    }
+
+    return VPX_CODEC_OK;
+}
+
+
+static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
+                                    const vpx_image_t    *img)
+{
+    switch (img->fmt)
+    {
+    case IMG_FMT_YV12:
+    case IMG_FMT_I420:
+    case IMG_FMT_VPXI420:
+    case IMG_FMT_VPXYV12:
+        break;
+    default:
+        ERROR("Invalid image format. Only YV12 and I420 images are supported");
+    }
+
+    if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h))
+        ERROR("Image size must match encoder init configuration size");
+
+    return VPX_CODEC_OK;
+}
+
+
+static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
+                                       vpx_codec_enc_cfg_t cfg,
+                                       struct vp8_extracfg vp8_cfg)
+{
+    oxcf->multi_threaded         = cfg.g_threads;
+    oxcf->Version               = cfg.g_profile;
+
+    oxcf->Width                 = cfg.g_w;
+    oxcf->Height                = cfg.g_h;
+    /* guess a frame rate if out of whack, use 30 */
+    oxcf->frame_rate             = (double)(cfg.g_timebase.den) / (double)(cfg.g_timebase.num);
+
+    if (oxcf->frame_rate > 180)
+    {
+        oxcf->frame_rate = 30;
+    }
+
+    oxcf->error_resilient_mode    = cfg.g_error_resilient;
+
+    switch (cfg.g_pass)
+    {
+    case VPX_RC_ONE_PASS:
+        oxcf->Mode = MODE_BESTQUALITY;
+        break;
+    case VPX_RC_FIRST_PASS:
+        oxcf->Mode = MODE_FIRSTPASS;
+        break;
+    case VPX_RC_LAST_PASS:
+        oxcf->Mode = MODE_SECONDPASS_BEST;
+        break;
+    }
+
+    if (cfg.g_pass == VPX_RC_FIRST_PASS)
+    {
+        oxcf->allow_lag              = 0;
+        oxcf->lag_in_frames           = 0;
+    }
+    else
+    {
+        oxcf->allow_lag              = (cfg.g_lag_in_frames) > 0;
+        oxcf->lag_in_frames           = cfg.g_lag_in_frames;
+    }
+
+    oxcf->allow_df               = (cfg.rc_dropframe_thresh > 0);
+    oxcf->drop_frames_water_mark   = cfg.rc_dropframe_thresh;
+
+    oxcf->allow_spatial_resampling = cfg.rc_resize_allowed;
+    oxcf->resample_up_water_mark   = cfg.rc_resize_up_thresh;
+    oxcf->resample_down_water_mark = cfg.rc_resize_down_thresh;
+
+    if (cfg.rc_end_usage == VPX_VBR)
+    {
+        oxcf->end_usage          = USAGE_LOCAL_FILE_PLAYBACK;
+    }
+    else if (cfg.rc_end_usage == VPX_CBR)
+    {
+        oxcf->end_usage          = USAGE_STREAM_FROM_SERVER;
+    }
+
+    oxcf->target_bandwidth       = cfg.rc_target_bitrate;
+
+    oxcf->best_allowed_q          = cfg.rc_min_quantizer;
+    oxcf->worst_allowed_q         = cfg.rc_max_quantizer;
+    oxcf->fixed_q = -1;
+
+    oxcf->under_shoot_pct         = cfg.rc_undershoot_pct;
+    //oxcf->over_shoot_pct        = cfg.rc_overshoot_pct;
+
+    oxcf->maximum_buffer_size     = cfg.rc_buf_sz / 1000;
+    oxcf->starting_buffer_level   = cfg.rc_buf_initial_sz / 1000;
+    oxcf->optimal_buffer_level    = cfg.rc_buf_optimal_sz / 1000;
+
+    oxcf->two_pass_vbrbias        = cfg.rc_2pass_vbr_bias_pct;
+    oxcf->two_pass_vbrmin_section  = cfg.rc_2pass_vbr_minsection_pct;
+    oxcf->two_pass_vbrmax_section  = cfg.rc_2pass_vbr_maxsection_pct;
+
+    oxcf->auto_key               = cfg.kf_mode == VPX_KF_AUTO
+                                   && cfg.kf_min_dist != cfg.kf_max_dist;
+    //oxcf->kf_min_dist         = cfg.kf_min_dis;
+    oxcf->key_freq               = cfg.kf_max_dist;
+
+    //oxcf->delete_first_pass_file = cfg.g_delete_firstpassfile;
+    //strcpy(oxcf->first_pass_file, cfg.g_firstpass_file);
+
+    oxcf->cpu_used               =  vp8_cfg.cpu_used;
+    oxcf->encode_breakout        =  vp8_cfg.static_thresh;
+    oxcf->play_alternate         =  vp8_cfg.enable_auto_alt_ref;
+    oxcf->noise_sensitivity      =  vp8_cfg.noise_sensitivity;
+    oxcf->Sharpness             =  vp8_cfg.Sharpness;
+    oxcf->token_partitions       =  vp8_cfg.token_partitions;
+
+    oxcf->two_pass_stats_in        =  cfg.rc_twopass_stats_in;
+    oxcf->output_pkt_list         =  vp8_cfg.pkt_list;
+
+    oxcf->arnr_max_frames = vp8_cfg.arnr_max_frames;
+    oxcf->arnr_strength =  vp8_cfg.arnr_strength;
+    oxcf->arnr_type =      vp8_cfg.arnr_type;
+
+
+    /*
+        printf("Current VP8 Settings: \n");
+        printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
+        printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
+        printf("Sharpness: %d\n",    oxcf->Sharpness);
+        printf("cpu_used: %d\n",  oxcf->cpu_used);
+        printf("Mode: %d\n",     oxcf->Mode);
+        printf("delete_first_pass_file: %d\n",  oxcf->delete_first_pass_file);
+        printf("auto_key: %d\n",  oxcf->auto_key);
+        printf("key_freq: %d\n", oxcf->key_freq);
+        printf("end_usage: %d\n", oxcf->end_usage);
+        printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
+        printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
+        printf("optimal_buffer_level: %d\n",  oxcf->optimal_buffer_level);
+        printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
+        printf("fixed_q: %d\n",  oxcf->fixed_q);
+        printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
+        printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
+        printf("allow_spatial_resampling: %d\n",  oxcf->allow_spatial_resampling);
+        printf("resample_down_water_mark: %d\n", oxcf->resample_down_water_mark);
+        printf("resample_up_water_mark: %d\n", oxcf->resample_up_water_mark);
+        printf("allow_df: %d\n", oxcf->allow_df);
+        printf("drop_frames_water_mark: %d\n", oxcf->drop_frames_water_mark);
+        printf("two_pass_vbrbias: %d\n",  oxcf->two_pass_vbrbias);
+        printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
+        printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
+        printf("allow_lag: %d\n", oxcf->allow_lag);
+        printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
+        printf("play_alternate: %d\n", oxcf->play_alternate);
+        printf("Version: %d\n", oxcf->Version);
+        printf("multi_threaded: %d\n",   oxcf->multi_threaded);
+        printf("encode_breakout: %d\n", oxcf->encode_breakout);
+    */
+    return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t vp8e_set_config(vpx_codec_alg_priv_t       *ctx,
+                                       const vpx_codec_enc_cfg_t  *cfg)
+{
+    vpx_codec_err_t res;
+
+    if ((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h))
+        ERROR("Cannot change width or height after initialization");
+
+    /* Prevent increasing lag_in_frames. This check is stricter than it needs
+     * to be -- the limit is not increasing past the first lag_in_frames
+     * value, but we don't track the initial config, only the last successful
+     * config.
+     */
+    if ((cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames))
+        ERROR("Cannot increase lag_in_frames");
+
+    res = validate_config(ctx, cfg, &ctx->vp8_cfg);
+
+    if (!res)
+    {
+        ctx->cfg = *cfg;
+        set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
+        vp8_change_config(ctx->cpi, &ctx->oxcf);
+    }
+
+    return res;
+}
+
+
+int vp8_reverse_trans(int);
+
+
+static vpx_codec_err_t get_param(vpx_codec_alg_priv_t *ctx,
+                                 int                   ctrl_id,
+                                 va_list               args)
+{
+    void *arg = va_arg(args, void *);
+
+#define MAP(id, var) case id: *(RECAST(id, arg)) = var; break
+
+    if (!arg)
+        return VPX_CODEC_INVALID_PARAM;
+
+    switch (ctrl_id)
+    {
+        MAP(VP8E_GET_LAST_QUANTIZER, vp8_get_quantizer(ctx->cpi));
+        MAP(VP8E_GET_LAST_QUANTIZER_64, vp8_reverse_trans(vp8_get_quantizer(ctx->cpi)));
+    }
+
+    return VPX_CODEC_OK;
+#undef MAP
+}
+
+
+static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
+                                 int                   ctrl_id,
+                                 va_list               args)
+{
+    vpx_codec_err_t     res  = VPX_CODEC_OK;
+    struct vp8_extracfg xcfg = ctx->vp8_cfg;
+
+#define MAP(id, var) case id: var = CAST(id, args); break;
+
+    switch (ctrl_id)
+    {
+        MAP(VP8E_SET_ENCODING_MODE,         ctx->deprecated_mode);
+        MAP(VP8E_SET_CPUUSED,               xcfg.cpu_used);
+        MAP(VP8E_SET_ENABLEAUTOALTREF,      xcfg.enable_auto_alt_ref);
+        MAP(VP8E_SET_NOISE_SENSITIVITY,     xcfg.noise_sensitivity);
+        MAP(VP8E_SET_SHARPNESS,             xcfg.Sharpness);
+        MAP(VP8E_SET_STATIC_THRESHOLD,      xcfg.static_thresh);
+        MAP(VP8E_SET_TOKEN_PARTITIONS,      xcfg.token_partitions);
+
+        MAP(VP8E_SET_ARNR_MAXFRAMES,        xcfg.arnr_max_frames);
+        MAP(VP8E_SET_ARNR_STRENGTH ,        xcfg.arnr_strength);
+        MAP(VP8E_SET_ARNR_TYPE     ,        xcfg.arnr_type);
+
+    }
+
+    res = validate_config(ctx, &ctx->cfg, &xcfg);
+
+    if (!res)
+    {
+        ctx->vp8_cfg = xcfg;
+        set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
+        vp8_change_config(ctx->cpi, &ctx->oxcf);
+    }
+
+    return res;
+#undef MAP
+}
+static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx)
+{
+    vpx_codec_err_t        res = VPX_DEC_OK;
+    struct vpx_codec_alg_priv *priv;
+    vpx_codec_enc_cfg_t       *cfg;
+    unsigned int               i;
+
+    VP8_PTR optr;
+
+    if (!ctx->priv)
+    {
+        priv = calloc(1, sizeof(struct vpx_codec_alg_priv));
+
+        if (priv)
+        {
+            ctx->priv = &priv->base;
+            ctx->priv->sz = sizeof(*ctx->priv);
+            ctx->priv->iface = ctx->iface;
+            ctx->priv->alg_priv = priv;
+            ctx->priv->init_flags = ctx->init_flags;
+
+            if (ctx->config.enc)
+            {
+                /* Update the reference to the config structure to an
+                 * internal copy.
+                 */
+                ctx->priv->alg_priv->cfg = *ctx->config.enc;
+                ctx->config.enc = &ctx->priv->alg_priv->cfg;
+            }
+
+            cfg =  &ctx->priv->alg_priv->cfg;
+
+            /* Select the extra vp6 configuration table based on the current
+             * usage value. If the current usage value isn't found, use the
+             * values for usage case 0.
+             */
+            for (i = 0;
+                 extracfg_map[i].usage && extracfg_map[i].usage != cfg->g_usage;
+                 i++);
+
+            priv->vp8_cfg = extracfg_map[i].cfg;
+            priv->vp8_cfg.pkt_list = &priv->pkt_list.head;
+
+            priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2;
+
+            if (priv->cx_data_sz < 4096) priv->cx_data_sz = 4096;
+
+            priv->cx_data = malloc(priv->cx_data_sz);
+            priv->deprecated_mode = NO_MODE_SET;
+
+            vp8_initialize();
+
+            res = validate_config(priv, &priv->cfg, &priv->vp8_cfg);
+
+            if (!res)
+            {
+                set_vp8e_config(&ctx->priv->alg_priv->oxcf, ctx->priv->alg_priv->cfg, ctx->priv->alg_priv->vp8_cfg);
+                optr = vp8_create_compressor(&ctx->priv->alg_priv->oxcf);
+
+                if (!optr)
+                    res = VPX_CODEC_MEM_ERROR;
+                else
+                    ctx->priv->alg_priv->cpi = optr;
+            }
+        }
+    }
+
+    return res;
+}
+
+static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx)
+{
+
+    free(ctx->cx_data);
+    vp8_remove_compressor(&ctx->cpi);
+    free(ctx);
+    return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t image2yuvconfig(const vpx_image_t   *img,
+                                       YV12_BUFFER_CONFIG  *yv12)
+{
+    vpx_codec_err_t        res = VPX_CODEC_OK;
+    yv12->y_buffer = img->planes[PLANE_Y];
+    yv12->u_buffer = img->planes[PLANE_U];
+    yv12->v_buffer = img->planes[PLANE_V];
+
+    yv12->y_width  = img->d_w;
+    yv12->y_height = img->d_h;
+    yv12->uv_width = (1 + yv12->y_width) / 2;
+    yv12->uv_height = (1 + yv12->y_height) / 2;
+
+    yv12->y_stride = img->stride[PLANE_Y];
+    yv12->uv_stride = img->stride[PLANE_U];
+
+    yv12->border  = (img->stride[PLANE_Y] - img->w) / 2;
+    yv12->clrtype = (img->fmt == IMG_FMT_VPXI420 || img->fmt == IMG_FMT_VPXYV12); //REG_YUV = 0
+    return res;
+}
+
+static void pick_quickcompress_mode(vpx_codec_alg_priv_t  *ctx,
+                                    unsigned long          duration,
+                                    unsigned long          deadline)
+{
+    unsigned int new_qc;
+
+#if !(CONFIG_REALTIME_ONLY)
+    /* Use best quality mode if no deadline is given. */
+    new_qc = MODE_BESTQUALITY;
+
+    if (deadline)
+    {
+        uint64_t     duration_us;
+
+        /* Convert duration parameter from stream timebase to microseconds */
+        duration_us = (uint64_t)duration * 1000000
+                      * (uint64_t)ctx->cfg.g_timebase.num
+                      / (uint64_t)ctx->cfg.g_timebase.den;
+
+        /* If the deadline is more that the duration this frame is to be shown,
+         * use good quality mode. Otherwise use realtime mode.
+         */
+        new_qc = (deadline > duration_us) ? MODE_GOODQUALITY : MODE_REALTIME;
+    }
+
+#else
+    new_qc = MODE_REALTIME;
+#endif
+
+    switch (ctx->deprecated_mode)
+    {
+    case VP8_BEST_QUALITY_ENCODING:
+        new_qc = MODE_BESTQUALITY;
+        break;
+    case VP8_GOOD_QUALITY_ENCODING:
+        new_qc = MODE_GOODQUALITY;
+        break;
+    case VP8_REAL_TIME_ENCODING:
+        new_qc = MODE_REALTIME;
+        break;
+    }
+
+    if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
+        new_qc = MODE_FIRSTPASS;
+    else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
+        new_qc = (new_qc == MODE_BESTQUALITY)
+                 ? MODE_SECONDPASS_BEST
+                 : MODE_SECONDPASS;
+
+    if (ctx->oxcf.Mode != new_qc)
+    {
+        ctx->oxcf.Mode = new_qc;
+        vp8_change_config(ctx->cpi, &ctx->oxcf);
+    }
+}
+
+
+static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
+                                   const vpx_image_t     *img,
+                                   vpx_codec_pts_t        pts,
+                                   unsigned long          duration,
+                                   vpx_enc_frame_flags_t  flags,
+                                   unsigned long          deadline)
+{
+    vpx_codec_err_t res = VPX_CODEC_OK;
+
+    if (img)
+        res = validate_img(ctx, img);
+
+    pick_quickcompress_mode(ctx, duration, deadline);
+    vpx_codec_pkt_list_init(&ctx->pkt_list);
+
+    /* Handle Flags */
+    if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF))
+        || ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF)))
+    {
+        ctx->base.err_detail = "Conflicting flags.";
+        return VPX_CODEC_INVALID_PARAM;
+    }
+
+    if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF
+                 | VP8_EFLAG_NO_REF_ARF))
+    {
+        int ref = 7;
+
+        if (flags & VP8_EFLAG_NO_REF_LAST)
+            ref ^= VP8_LAST_FLAG;
+
+        if (flags & VP8_EFLAG_NO_REF_GF)
+            ref ^= VP8_GOLD_FLAG;
+
+        if (flags & VP8_EFLAG_NO_REF_ARF)
+            ref ^= VP8_ALT_FLAG;
+
+        vp8_use_as_reference(ctx->cpi, ref);
+    }
+
+    if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF
+                 | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF
+                 | VP8_EFLAG_FORCE_ARF))
+    {
+        int upd = 7;
+
+        if (flags & VP8_EFLAG_NO_UPD_LAST)
+            upd ^= VP8_LAST_FLAG;
+
+        if (flags & VP8_EFLAG_NO_UPD_GF)
+            upd ^= VP8_GOLD_FLAG;
+
+        if (flags & VP8_EFLAG_NO_UPD_ARF)
+            upd ^= VP8_ALT_FLAG;
+
+        vp8_update_reference(ctx->cpi, upd);
+    }
+
+    if (flags & VP8_EFLAG_NO_UPD_ENTROPY)
+    {
+        vp8_update_entropy(ctx->cpi, 0);
+    }
+
+    /* Handle fixed keyframe intervals */
+    if (ctx->cfg.kf_mode == VPX_KF_AUTO
+        && ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist)
+    {
+        if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist)
+        {
+            flags |= VPX_EFLAG_FORCE_KF;
+            ctx->fixed_kf_cntr = 0;
+        }
+    }
+
+    /* Initialize the encoder instance on the first frame*/
+    if (!res && ctx->cpi)
+    {
+        unsigned int lib_flags;
+        YV12_BUFFER_CONFIG sd;
+        INT64 dst_time_stamp, dst_end_time_stamp;
+        unsigned long size, cx_data_sz;
+        unsigned char *cx_data;
+
+        /* Set up internal flags */
+        if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
+            ((VP8_COMP *)ctx->cpi)->b_calculate_psnr = 1;
+
+        /* Convert API flags to internal codec lib flags */
+        lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
+
+        /* vp8 use 10,000,000 ticks/second as time stamp */
+        dst_time_stamp    = pts * 10000000 * ctx->cfg.g_timebase.num / ctx->cfg.g_timebase.den;
+        dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / ctx->cfg.g_timebase.den;
+
+        if (img != NULL)
+        {
+            res = image2yuvconfig(img, &sd);
+
+            if (vp8_receive_raw_frame(ctx->cpi, ctx->next_frame_flag | lib_flags,
+                                      &sd, dst_time_stamp, dst_end_time_stamp))
+            {
+                VP8_COMP *cpi = (VP8_COMP *)ctx->cpi;
+                res = update_error_state(ctx, &cpi->common.error);
+            }
+
+            /* reset for next frame */
+            ctx->next_frame_flag = 0;
+        }
+
+        cx_data = ctx->cx_data;
+        cx_data_sz = ctx->cx_data_sz;
+        lib_flags = 0;
+
+        while (cx_data_sz >= ctx->cx_data_sz / 2
+               && -1 != vp8_get_compressed_data(ctx->cpi, &lib_flags, &size, cx_data, &dst_time_stamp, &dst_end_time_stamp, !img))
+        {
+            if (size)
+            {
+                vpx_codec_pts_t    round, delta;
+                vpx_codec_cx_pkt_t pkt;
+                VP8_COMP *cpi = (VP8_COMP *)ctx->cpi;
+
+                /* Add the frame packet to the list of returned packets. */
+                round = 1000000 * ctx->cfg.g_timebase.num / 2 - 1;
+                delta = (dst_end_time_stamp - dst_time_stamp);
+                pkt.kind = VPX_CODEC_CX_FRAME_PKT;
+                pkt.data.frame.buf = cx_data;
+                pkt.data.frame.sz  = size;
+                pkt.data.frame.pts =
+                    (dst_time_stamp * ctx->cfg.g_timebase.den + round)
+                    / ctx->cfg.g_timebase.num / 10000000;
+                pkt.data.frame.duration =
+                    (delta * ctx->cfg.g_timebase.den + round)
+                    / ctx->cfg.g_timebase.num / 10000000;
+                pkt.data.frame.flags = lib_flags << 16;
+
+                if (lib_flags & FRAMEFLAGS_KEY)
+                    pkt.data.frame.flags |= VPX_FRAME_IS_KEY;
+
+                if (!cpi->common.show_frame)
+                {
+                    pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE;
+
+                    // TODO: ideally this timestamp should be as close as
+                    // possible to the prior PTS so that if a decoder uses
+                    // pts to schedule when to do this, we start right after
+                    // last frame was decoded.  Maybe should be set to
+                    // last time stamp. Invisible frames have no duration..
+                    pkt.data.frame.pts --;
+                    pkt.data.frame.duration = 0;
+                }
+
+                vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
+
+                //printf("timestamp: %lld, duration: %d\n", pkt->data.frame.pts, pkt->data.frame.duration);
+                cx_data += size;
+                cx_data_sz -= size;
+            }
+        }
+    }
+
+    return res;
+}
+
+
+static const vpx_codec_cx_pkt_t *vp8e_get_cxdata(vpx_codec_alg_priv_t  *ctx,
+        vpx_codec_iter_t      *iter)
+{
+    return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
+}
+
+static vpx_codec_err_t vp8e_set_reference(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+    vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
+
+    if (data)
+    {
+        vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
+        YV12_BUFFER_CONFIG sd;
+
+        image2yuvconfig(&frame->img, &sd);
+        vp8_set_reference(ctx->cpi, frame->frame_type, &sd);
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+
+}
+
+static vpx_codec_err_t vp8e_get_reference(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+
+    vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
+
+    if (data)
+    {
+        vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
+        YV12_BUFFER_CONFIG sd;
+
+        image2yuvconfig(&frame->img, &sd);
+        vp8_get_reference(ctx->cpi, frame->frame_type, &sd);
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+}
+
+static vpx_codec_err_t vp8e_set_previewpp(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+    vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
+
+    if (data)
+    {
+        ctx->preview_ppcfg = *((vp8_postproc_cfg_t *)data);
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+}
+
+
+static vpx_image_t *vp8e_get_preview(vpx_codec_alg_priv_t *ctx)
+{
+
+    YV12_BUFFER_CONFIG sd;
+
+    if (0 == vp8_get_preview_raw_frame(ctx->cpi, &sd, ctx->preview_ppcfg.deblocking_level, ctx->preview_ppcfg.noise_level, ctx->preview_ppcfg.post_proc_flag))
+    {
+
+        /*
+        vpx_img_wrap(&ctx->preview_img, IMG_FMT_YV12,
+            sd.y_width + 2*VP8BORDERINPIXELS,
+            sd.y_height + 2*VP8BORDERINPIXELS,
+            1,
+            sd.buffer_alloc);
+        vpx_img_set_rect(&ctx->preview_img,
+            VP8BORDERINPIXELS, VP8BORDERINPIXELS,
+            sd.y_width, sd.y_height);
+            */
+
+        ctx->preview_img.bps = 12;
+        ctx->preview_img.planes[PLANE_Y] = sd.y_buffer;
+        ctx->preview_img.planes[PLANE_U] = sd.u_buffer;
+        ctx->preview_img.planes[PLANE_V] = sd.v_buffer;
+
+        if (sd.clrtype == REG_YUV)
+            ctx->preview_img.fmt = IMG_FMT_I420;
+        else
+            ctx->preview_img.fmt = IMG_FMT_VPXI420;
+
+        ctx->preview_img.x_chroma_shift = 1;
+        ctx->preview_img.y_chroma_shift = 1;
+
+        ctx->preview_img.d_w = ctx->cfg.g_w;
+        ctx->preview_img.d_h = ctx->cfg.g_h;
+        ctx->preview_img.stride[PLANE_Y] = sd.y_stride;
+        ctx->preview_img.stride[PLANE_U] = sd.uv_stride;
+        ctx->preview_img.stride[PLANE_V] = sd.uv_stride;
+        ctx->preview_img.w   = sd.y_width;
+        ctx->preview_img.h   = sd.y_height;
+
+        return &ctx->preview_img;
+    }
+    else
+        return NULL;
+}
+
+static vpx_codec_err_t vp8e_update_entropy(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+    int update = va_arg(args, int);
+    vp8_update_entropy(ctx->cpi, update);
+    return VPX_CODEC_OK;
+
+}
+
+static vpx_codec_err_t vp8e_update_reference(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+    int update = va_arg(args, int);
+    vp8_update_reference(ctx->cpi, update);
+    return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t vp8e_use_reference(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+    int reference_flag = va_arg(args, int);
+    vp8_use_as_reference(ctx->cpi, reference_flag);
+    return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t vp8e_set_roi_map(vpx_codec_alg_priv_t *ctx,
+                                        int ctr_id,
+                                        va_list args)
+{
+    vpx_roi_map_t *data = va_arg(args, vpx_roi_map_t *);
+
+    if (data)
+    {
+        vpx_roi_map_t *roi = (vpx_roi_map_t *)data;
+
+        if (!vp8_set_roimap(ctx->cpi, roi->roi_map, roi->rows, roi->cols, roi->delta_q, roi->delta_lf, roi->static_threshold))
+            return VPX_CODEC_OK;
+        else
+            return VPX_CODEC_INVALID_PARAM;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+}
+
+
+static vpx_codec_err_t vp8e_set_activemap(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+    vpx_active_map_t *data = va_arg(args, vpx_active_map_t *);
+
+    if (data)
+    {
+
+        vpx_active_map_t *map = (vpx_active_map_t *)data;
+
+        if (!vp8_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols))
+            return VPX_CODEC_OK;
+        else
+            return VPX_CODEC_INVALID_PARAM;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+}
+
+static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+
+    vpx_scaling_mode_t *data =  va_arg(args, vpx_scaling_mode_t *);
+
+    if (data)
+    {
+        int res;
+        vpx_scaling_mode_t scalemode = *(vpx_scaling_mode_t *)data ;
+        res = vp8_set_internal_size(ctx->cpi, scalemode.h_scaling_mode, scalemode.v_scaling_mode);
+
+        if (!res)
+        {
+            /*force next frame a key frame to effect scaling mode */
+            ctx->next_frame_flag |= FRAMEFLAGS_KEY;
+            return VPX_CODEC_OK;
+        }
+        else
+            return VPX_CODEC_INVALID_PARAM;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+}
+
+
+static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] =
+{
+    {VP8_SET_REFERENCE,                 vp8e_set_reference},
+    {VP8_COPY_REFERENCE,                vp8e_get_reference},
+    {VP8_SET_POSTPROC,                  vp8e_set_previewpp},
+    {VP8E_UPD_ENTROPY,                  vp8e_update_entropy},
+    {VP8E_UPD_REFERENCE,                vp8e_update_reference},
+    {VP8E_USE_REFERENCE,                vp8e_use_reference},
+    {VP8E_SET_ROI_MAP,                  vp8e_set_roi_map},
+    {VP8E_SET_ACTIVEMAP,                vp8e_set_activemap},
+    {VP8E_SET_SCALEMODE,                vp8e_set_scalemode},
+    {VP8E_SET_ENCODING_MODE,            set_param},
+    {VP8E_SET_CPUUSED,                  set_param},
+    {VP8E_SET_NOISE_SENSITIVITY,        set_param},
+    {VP8E_SET_ENABLEAUTOALTREF,         set_param},
+    {VP8E_SET_SHARPNESS,                set_param},
+    {VP8E_SET_STATIC_THRESHOLD,         set_param},
+    {VP8E_SET_TOKEN_PARTITIONS,         set_param},
+    {VP8E_GET_LAST_QUANTIZER,           get_param},
+    {VP8E_GET_LAST_QUANTIZER_64,        get_param},
+    {VP8E_SET_ARNR_MAXFRAMES,           set_param},
+    {VP8E_SET_ARNR_STRENGTH ,           set_param},
+    {VP8E_SET_ARNR_TYPE     ,           set_param},
+    { -1, NULL},
+};
+
+static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
+{
+    {
+    0,
+    {
+        0,                  /* g_usage */
+        0,                  /* g_threads */
+        0,                  /* g_profile */
+
+        320,                /* g_width */
+        240,                /* g_height */
+        {1, 30},            /* g_timebase */
+
+        0,                  /* g_error_resilient */
+
+        VPX_RC_ONE_PASS,    /* g_pass */
+
+        0,                  /* g_lag_in_frames */
+
+        70,                 /* rc_dropframe_thresh */
+        0,                  /* rc_resize_allowed */
+        60,                 /* rc_resize_down_thresold */
+        30,                 /* rc_resize_up_thresold */
+
+        VPX_VBR,            /* rc_end_usage */
+#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
+        {0},                /* rc_twopass_stats_in */
+#endif
+        256,                /* rc_target_bandwidth */
+
+        4,                  /* rc_min_quantizer */
+        63,                 /* rc_max_quantizer */
+
+        95,                 /* rc_undershoot_pct */
+        200,                /* rc_overshoot_pct */
+
+        6000,               /* rc_max_buffer_size */
+        4000,               /* rc_buffer_initial_size; */
+        5000,               /* rc_buffer_optimal_size; */
+
+        50,                 /* rc_two_pass_vbrbias  */
+        0,                  /* rc_two_pass_vbrmin_section */
+        400,                /* rc_two_pass_vbrmax_section */
+
+        /* keyframing settings (kf) */
+        VPX_KF_AUTO,        /* g_kfmode*/
+        0,                  /* kf_min_dist */
+        9999,               /* kf_max_dist */
+
+#if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
+        1,                  /* g_delete_first_pass_file */
+        "vp8.fpf"           /* first pass filename */
+#endif
+    }},
+    { -1, {NOT_IMPLEMENTED}}
+};
+
+
+#ifndef VERSION_STRING
+#define VERSION_STRING
+#endif
+vpx_codec_iface_t vpx_codec_vp8_cx_algo =
+{
+    "vpx Technologies VP8 Encoder" VERSION_STRING,
+    VPX_CODEC_INTERNAL_ABI_VERSION,
+    VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
+    /* vpx_codec_caps_t          caps; */
+    vp8e_init,          /* vpx_codec_init_fn_t       init; */
+    vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
+    vp8e_ctf_maps,      /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
+    NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
+    NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
+    {
+        NOT_IMPLEMENTED,    /* vpx_codec_peek_si_fn_t    peek_si; */
+        NOT_IMPLEMENTED,    /* vpx_codec_get_si_fn_t     get_si; */
+        NOT_IMPLEMENTED,    /* vpx_codec_decode_fn_t     decode; */
+        NOT_IMPLEMENTED,    /* vpx_codec_frame_get_fn_t  frame_get; */
+    },
+    {
+        vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
+        vp8e_encode,        /* vpx_codec_encode_fn_t      encode; */
+        vp8e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
+        vp8e_set_config,
+        NOT_IMPLEMENTED,
+        vp8e_get_preview,
+    } /* encoder functions */
+};
+
+
+/*
+ * BEGIN BACKWARDS COMPATIBILITY SHIM.
+ */
+#define FORCE_KEY   2
+static vpx_codec_err_t api1_control(vpx_codec_alg_priv_t *ctx,
+                                    int                   ctrl_id,
+                                    va_list               args)
+{
+    vpx_codec_ctrl_fn_map_t *entry;
+
+    switch (ctrl_id)
+    {
+    case VP8E_SET_FLUSHFLAG:
+        /* VP8 sample code did VP8E_SET_FLUSHFLAG followed by
+         * vpx_codec_get_cx_data() rather than vpx_codec_encode().
+         */
+        return vp8e_encode(ctx, NULL, 0, 0, 0, 0);
+    case VP8E_SET_FRAMETYPE:
+        ctx->base.enc.tbd |= FORCE_KEY;
+        return VPX_CODEC_OK;
+    }
+
+    for (entry = vp8e_ctf_maps; entry && entry->fn; entry++)
+    {
+        if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
+        {
+            return entry->fn(ctx, ctrl_id, args);
+        }
+    }
+
+    return VPX_CODEC_ERROR;
+}
+
+
+static vpx_codec_ctrl_fn_map_t api1_ctrl_maps[] =
+{
+    {0, api1_control},
+    { -1, NULL}
+};
+
+
+static vpx_codec_err_t api1_encode(vpx_codec_alg_priv_t  *ctx,
+                                   const vpx_image_t     *img,
+                                   vpx_codec_pts_t        pts,
+                                   unsigned long          duration,
+                                   vpx_enc_frame_flags_t  flags,
+                                   unsigned long          deadline)
+{
+    int force = ctx->base.enc.tbd;
+
+    ctx->base.enc.tbd = 0;
+    return vp8e_encode
+           (ctx,
+            img,
+            pts,
+            duration,
+            flags | ((force & FORCE_KEY) ? VPX_EFLAG_FORCE_KF : 0),
+            deadline);
+}
+
+
+vpx_codec_iface_t vpx_enc_vp8_algo =
+{
+    "vpx Technologies VP8 Encoder (Deprecated API)" VERSION_STRING,
+    VPX_CODEC_INTERNAL_ABI_VERSION,
+    VPX_CODEC_CAP_ENCODER,
+    /* vpx_codec_caps_t          caps; */
+    vp8e_init,          /* vpx_codec_init_fn_t       init; */
+    vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
+    api1_ctrl_maps,     /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
+    NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
+    NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
+    {NOT_IMPLEMENTED},  /* decoder functions */
+    {
+        vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
+        api1_encode,        /* vpx_codec_encode_fn_t      encode; */
+        vp8e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
+        vp8e_set_config,
+        NOT_IMPLEMENTED,
+        vp8e_get_preview,
+    } /* encoder functions */
+};
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
new file mode 100644 (file)
index 0000000..3e6cdf4
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include "vpx_codec/vpx_decoder.h"
+#include "vp8dx.h"
+#include "vpx_codec/internal/vpx_codec_internal.h"
+#include "vpx_version.h"
+#include "onyxd.h"
+#include "onyxd_int.h"
+
+#define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
+
+#if CONFIG_BIG_ENDIAN
+# define swap4(d)\
+    ((d&0x000000ff)<<24) |  \
+    ((d&0x0000ff00)<<8)  |  \
+    ((d&0x00ff0000)>>8)  |  \
+    ((d&0xff000000)>>24)
+# define swap2(d)\
+    ((d&0x000000ff)<<8) |  \
+    ((d&0x0000ff00)>>8)
+#else
+# define swap4(d) d
+# define swap2(d) d
+#endif
+typedef vpx_codec_stream_info_t  vp8_stream_info_t;
+
+/* Structures for handling memory allocations */
+typedef enum
+{
+    VP8_SEG_ALG_PRIV     = 256,
+    VP8_SEG_MAX
+} mem_seg_id_t;
+#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
+
+static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_t);
+
+typedef struct
+{
+    unsigned int   id;
+    unsigned long  sz;
+    unsigned int   align;
+    unsigned int   flags;
+    unsigned long(*calc_sz)(const vpx_codec_dec_cfg_t *, vpx_codec_flags_t);
+} mem_req_t;
+
+static const mem_req_t vp8_mem_req_segs[] =
+{
+    {VP8_SEG_ALG_PRIV,    0, 8, VPX_CODEC_MEM_ZERO, vp8_priv_sz},
+    {VP8_SEG_MAX, 0, 0, 0, NULL}
+};
+
+struct vpx_codec_alg_priv
+{
+    vpx_codec_priv_t        base;
+    vpx_codec_mmap_t        mmaps[NELEMENTS(vp8_mem_req_segs)-1];
+    vpx_codec_dec_cfg_t     cfg;
+    vp8_stream_info_t   si;
+    int                     defer_alloc;
+    int                     decoder_init;
+    VP8D_PTR                pbi;
+    int                     postproc_cfg_set;
+    vp8_postproc_cfg_t      postproc_cfg;
+    vpx_image_t             img;
+    int                     img_setup;
+    int                     img_avail;
+};
+
+static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_t flags)
+{
+    /* Although this declaration is constant, we can't use it in the requested
+     * segments list because we want to define the requested segments list
+     * before defining the private type (so that the number of memory maps is
+     * known)
+     */
+    (void)si;
+    return sizeof(vpx_codec_alg_priv_t);
+}
+
+
+static void vp8_mmap_dtor(vpx_codec_mmap_t *mmap)
+{
+    free(mmap->priv);
+}
+
+static vpx_codec_err_t vp8_mmap_alloc(vpx_codec_mmap_t *mmap)
+{
+    vpx_codec_err_t  res;
+    unsigned int   align;
+
+    align = mmap->align ? mmap->align - 1 : 0;
+
+    if (mmap->flags & VPX_CODEC_MEM_ZERO)
+        mmap->priv = calloc(1, mmap->sz + align);
+    else
+        mmap->priv = malloc(mmap->sz + align);
+
+    res = (mmap->priv) ? VPX_CODEC_OK : VPX_CODEC_MEM_ERROR;
+    mmap->base = (void *)((((uintptr_t)mmap->priv) + align) & ~(uintptr_t)align);
+    mmap->dtor = vp8_mmap_dtor;
+    return res;
+}
+
+static vpx_codec_err_t vp8_validate_mmaps(const vp8_stream_info_t *si,
+        const vpx_codec_mmap_t        *mmaps,
+        vpx_codec_flags_t              init_flags)
+{
+    int i;
+    vpx_codec_err_t res = VPX_CODEC_OK;
+
+    for (i = 0; i < NELEMENTS(vp8_mem_req_segs) - 1; i++)
+    {
+        /* Ensure the segment has been allocated */
+        if (!mmaps[i].base)
+        {
+            res = VPX_CODEC_MEM_ERROR;
+            break;
+        }
+
+        /* Verify variable size segment is big enough for the current si. */
+        if (vp8_mem_req_segs[i].calc_sz)
+        {
+            vpx_codec_dec_cfg_t cfg;
+
+            cfg.w = si->w;
+            cfg.h = si->h;
+
+            if (mmaps[i].sz < vp8_mem_req_segs[i].calc_sz(&cfg, init_flags))
+            {
+                res = VPX_CODEC_MEM_ERROR;
+                break;
+            }
+        }
+    }
+
+    return res;
+}
+
+static void vp8_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap)
+{
+    int i;
+
+    ctx->priv = mmap->base;
+    ctx->priv->sz = sizeof(*ctx->priv);
+    ctx->priv->iface = ctx->iface;
+    ctx->priv->alg_priv = mmap->base;
+
+    for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++)
+        ctx->priv->alg_priv->mmaps[i].id = vp8_mem_req_segs[i].id;
+
+    ctx->priv->alg_priv->mmaps[0] = *mmap;
+    ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
+    ctx->priv->init_flags = ctx->init_flags;
+
+    if (ctx->config.dec)
+    {
+        /* Update the reference to the config structure to an internal copy. */
+        ctx->priv->alg_priv->cfg = *ctx->config.dec;
+        ctx->config.dec = &ctx->priv->alg_priv->cfg;
+    }
+}
+
+static void *mmap_lkup(vpx_codec_alg_priv_t *ctx, int id)
+{
+    int i;
+
+    for (i = 0; i < NELEMENTS(vp8_mem_req_segs); i++)
+        if (ctx->mmaps[i].id == id)
+            return ctx->mmaps[i].base;
+
+    return NULL;
+}
+static void vp8_finalize_mmaps(vpx_codec_alg_priv_t *ctx)
+{
+    /*
+    ctx->pbi = mmap_lkup(ctx, VP6_SEG_PB_INSTANCE);
+    ctx->pbi->mbi.block_dx_info[0].idct_output_ptr = mmap_lkup(ctx, VP6_SEG_IDCT_BUFFER);
+    ctx->pbi->loop_filtered_block = mmap_lkup(ctx, VP6_SEG_LF_BLOCK);
+    ctx->pbi->huff = mmap_lkup(ctx, VP6_SEG_HUFF);
+    ctx->pbi->mbi.coeffs_base_ptr = mmap_lkup(ctx, VP6_SEG_COEFFS);
+    ctx->pbi->fc.above_y = mmap_lkup(ctx, VP6_SEG_ABOVEY);
+    ctx->pbi->fc.above_u = mmap_lkup(ctx, VP6_SEG_ABOVEU);
+    ctx->pbi->fc.above_v = mmap_lkup(ctx, VP6_SEG_ABOVEV);
+    ctx->pbi->prediction_mode = mmap_lkup(ctx, VP6_SEG_PRED_MODES);
+    ctx->pbi->mbmotion_vector = mmap_lkup(ctx, VP6_SEG_MV_FIELD);
+    ctx->pbi->fb_storage_ptr[0] = mmap_lkup(ctx, VP6_SEG_IMG0_STRG);
+    ctx->pbi->fb_storage_ptr[1] = mmap_lkup(ctx, VP6_SEG_IMG1_STRG);
+    ctx->pbi->fb_storage_ptr[2] = mmap_lkup(ctx, VP6_SEG_IMG2_STRG);
+    #if CONFIG_NEW_TOKENS
+    ctx->pbi->token_graph = mmap_lkup(ctx, VP6_SEG_TOKEN_GRAPH);
+    #endif
+    #if CONFIG_POSTPROC
+    ctx->pbi->postproc.deblock.fragment_variances = mmap_lkup(ctx, VP6_SEG_DEBLOCKER);
+    ctx->pbi->fb_storage_ptr[3] = mmap_lkup(ctx, VP6_SEG_PP_IMG_STRG);
+    #endif
+    */
+}
+
+static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx)
+{
+    vpx_codec_err_t        res = VPX_CODEC_OK;
+
+    /* This function only allocates space for the vpx_codec_alg_priv_t
+     * structure. More memory may be required at the time the stream
+     * information becomes known.
+     */
+    if (!ctx->priv)
+    {
+        vpx_codec_mmap_t mmap;
+
+        mmap.id = vp8_mem_req_segs[0].id;
+        mmap.sz = sizeof(vpx_codec_alg_priv_t);
+        mmap.align = vp8_mem_req_segs[0].align;
+        mmap.flags = vp8_mem_req_segs[0].flags;
+
+        res = vp8_mmap_alloc(&mmap);
+
+        if (!res)
+            vp8_init_ctx(ctx, &mmap);
+
+        ctx->priv->alg_priv->defer_alloc = 1;
+        /*post processing level initialized to do nothing */
+
+    }
+
+    return res;
+}
+
+static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t *ctx)
+{
+    int i;
+
+    vp8dx_remove_decompressor(ctx->pbi);
+
+    for (i = NELEMENTS(ctx->mmaps) - 1; i >= 0; i--)
+    {
+        if (ctx->mmaps[i].dtor)
+            ctx->mmaps[i].dtor(&ctx->mmaps[i]);
+    }
+
+    return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t vp8_peek_si(const uint8_t         *data,
+                                   unsigned int           data_sz,
+                                   vpx_codec_stream_info_t *si)
+{
+
+    vpx_codec_err_t res = VPX_CODEC_OK;
+    {
+        /*Parse from VP8 compressed data, the implies knowledge of the
+         *VP8 bitsteam.
+         * First 3 byte header including version, frame type and an offset
+         * Next 3 bytes are image sizewith 12 bit each for width and height
+         */
+
+        si->is_kf = 0;
+
+        if (data_sz >= 10 && !(data[0] & 0x01))  /* I-Frame */
+        {
+            const uint8_t *c = data + 3;
+            si->is_kf = 1;
+
+            // vet via sync code
+            if (c[0] != 0x9d || c[1] != 0x01 || c[2] != 0x2a)
+                res = VPX_CODEC_UNSUP_BITSTREAM;
+
+            si->w = swap2(*(const unsigned short *)(c + 3)) & 0x3fff;
+            si->h = swap2(*(const unsigned short *)(c + 5)) & 0x3fff;
+
+            //printf("w=%d, h=%d\n", si->w, si->h);
+            if (!(si->h | si->w))
+                res = VPX_CODEC_UNSUP_BITSTREAM;
+        }
+        else
+            res = VPX_CODEC_UNSUP_BITSTREAM;
+    }
+
+    return res;
+
+}
+
+static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t    *ctx,
+                                  vpx_codec_stream_info_t *si)
+{
+
+    unsigned int sz;
+
+    if (si->sz >= sizeof(vp8_stream_info_t))
+        sz = sizeof(vp8_stream_info_t);
+    else
+        sz = sizeof(vpx_codec_stream_info_t);
+
+    memcpy(si, &ctx->si, sz);
+    si->sz = sz;
+
+    return VPX_CODEC_OK;
+}
+
+
+static vpx_codec_err_t
+update_error_state(vpx_codec_alg_priv_t                 *ctx,
+                   const struct vpx_internal_error_info *error)
+{
+    vpx_codec_err_t res;
+
+    if ((res = error->error_code))
+        ctx->base.err_detail = error->has_detail
+                               ? error->detail
+                               : NULL;
+
+    return res;
+}
+
+
+static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t  *ctx,
+                                  const uint8_t         *data,
+                                  unsigned int            data_sz,
+                                  void                    *user_priv,
+                                  long                    deadline)
+{
+    vpx_codec_err_t res = VPX_CODEC_OK;
+
+    ctx->img_avail = 0;
+
+    /* Determine the stream parameters */
+    if (!ctx->si.h)
+        res = ctx->base.iface->dec.peek_si(data, data_sz, &ctx->si);
+
+
+    /* Perform deferred allocations, if required */
+    if (!res && ctx->defer_alloc)
+    {
+        int i;
+
+        for (i = 1; !res && i < NELEMENTS(ctx->mmaps); i++)
+        {
+            vpx_codec_dec_cfg_t cfg;
+
+            cfg.w = ctx->si.w;
+            cfg.h = ctx->si.h;
+            ctx->mmaps[i].id = vp8_mem_req_segs[i].id;
+            ctx->mmaps[i].sz = vp8_mem_req_segs[i].sz;
+            ctx->mmaps[i].align = vp8_mem_req_segs[i].align;
+            ctx->mmaps[i].flags = vp8_mem_req_segs[i].flags;
+
+            if (!ctx->mmaps[i].sz)
+                ctx->mmaps[i].sz = vp8_mem_req_segs[i].calc_sz(&cfg,
+                                   ctx->base.init_flags);
+
+            res = vp8_mmap_alloc(&ctx->mmaps[i]);
+        }
+
+        if (!res)
+            vp8_finalize_mmaps(ctx);
+
+        ctx->defer_alloc = 0;
+    }
+
+    /* Initialize the decoder instance on the first frame*/
+    if (!res && !ctx->decoder_init)
+    {
+        res = vp8_validate_mmaps(&ctx->si, ctx->mmaps, ctx->base.init_flags);
+
+        if (!res)
+        {
+            VP8D_CONFIG oxcf;
+            VP8D_PTR optr;
+
+            vp8dx_initialize();
+
+            oxcf.Width = ctx->si.w;
+            oxcf.Height = ctx->si.h;
+            oxcf.Version = 9;
+            oxcf.postprocess = 0;
+            oxcf.max_threads = ctx->cfg.threads;
+
+            optr = vp8dx_create_decompressor(&oxcf);
+
+            /* If postprocessing was enabled by the application and a
+             * configuration has not been provided, default it.
+             */
+            if (!ctx->postproc_cfg_set
+                && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC))
+            {
+                ctx->postproc_cfg.post_proc_flag =
+                    VP8_DEBLOCK | VP8_DEMACROBLOCK;
+                ctx->postproc_cfg.deblocking_level = 4;
+                ctx->postproc_cfg.noise_level = 0;
+            }
+
+            if (!optr)
+                res = VPX_CODEC_ERROR;
+            else
+                ctx->pbi = optr;
+        }
+
+        ctx->decoder_init = 1;
+    }
+
+    if (!res && ctx->pbi)
+    {
+        YV12_BUFFER_CONFIG sd;
+        INT64 time_stamp = 0, time_end_stamp = 0;
+        int ppflag       = 0;
+        int ppdeblocking = 0;
+        int ppnoise      = 0;
+
+        if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)
+        {
+            ppflag      = ctx->postproc_cfg.post_proc_flag;
+            ppdeblocking = ctx->postproc_cfg.deblocking_level;
+            ppnoise     = ctx->postproc_cfg.noise_level;
+        }
+
+        if (vp8dx_receive_compressed_data(ctx->pbi, data_sz, data, deadline))
+        {
+            VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi;
+            res = update_error_state(ctx, &pbi->common.error);
+        }
+
+        if (!res && 0 == vp8dx_get_raw_frame(ctx->pbi, &sd, &time_stamp, &time_end_stamp, ppdeblocking, ppnoise, ppflag))
+        {
+            /* Align width/height */
+            unsigned int a_w = (sd.y_width + 15) & ~15;
+            unsigned int a_h = (sd.y_height + 15) & ~15;
+
+            vpx_img_wrap(&ctx->img, IMG_FMT_I420,
+                         a_w + 2 * VP8BORDERINPIXELS,
+                         a_h + 2 * VP8BORDERINPIXELS,
+                         1,
+                         sd.buffer_alloc);
+            vpx_img_set_rect(&ctx->img,
+                             VP8BORDERINPIXELS, VP8BORDERINPIXELS,
+                             sd.y_width, sd.y_height);
+            ctx->img_avail = 1;
+
+        }
+    }
+
+    return res;
+}
+
+static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t  *ctx,
+                                  vpx_codec_iter_t      *iter)
+{
+    vpx_image_t *img = NULL;
+
+    if (ctx->img_avail)
+    {
+        /* iter acts as a flip flop, so an image is only returned on the first
+         * call to get_frame.
+         */
+        if (!(*iter))
+        {
+            img = &ctx->img;
+            *iter = img;
+        }
+    }
+
+    return img;
+}
+
+
+static
+vpx_codec_err_t vp8_xma_get_mmap(const vpx_codec_ctx_t      *ctx,
+                                 vpx_codec_mmap_t           *mmap,
+                                 vpx_codec_iter_t           *iter)
+{
+    vpx_codec_err_t     res;
+    const mem_req_t  *seg_iter = *iter;
+
+    /* Get address of next segment request */
+    do
+    {
+        if (!seg_iter)
+            seg_iter = vp8_mem_req_segs;
+        else if (seg_iter->id != VP8_SEG_MAX)
+            seg_iter++;
+
+        *iter = (vpx_codec_iter_t)seg_iter;
+
+        if (seg_iter->id != VP8_SEG_MAX)
+        {
+            mmap->id = seg_iter->id;
+            mmap->sz = seg_iter->sz;
+            mmap->align = seg_iter->align;
+            mmap->flags = seg_iter->flags;
+
+            if (!seg_iter->sz)
+                mmap->sz = seg_iter->calc_sz(ctx->config.dec, ctx->init_flags);
+
+            res = VPX_CODEC_OK;
+        }
+        else
+            res = VPX_CODEC_LIST_END;
+    }
+    while (!mmap->sz && res != VPX_CODEC_LIST_END);
+
+    return res;
+}
+
+static vpx_codec_err_t vp8_xma_set_mmap(vpx_codec_ctx_t         *ctx,
+                                        const vpx_codec_mmap_t  *mmap)
+{
+    vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
+    int i, done;
+
+    if (!ctx->priv)
+    {
+        if (mmap->id == VP8_SEG_ALG_PRIV)
+        {
+            if (!ctx->priv)
+            {
+                vp8_init_ctx(ctx, mmap);
+                res = VPX_CODEC_OK;
+            }
+        }
+    }
+
+    done = 1;
+
+    if (ctx->priv->alg_priv)
+    {
+        for (i = 0; i < NELEMENTS(vp8_mem_req_segs); i++)
+        {
+            if (ctx->priv->alg_priv->mmaps[i].id == mmap->id)
+                if (!ctx->priv->alg_priv->mmaps[i].base)
+                {
+                    ctx->priv->alg_priv->mmaps[i] = *mmap;
+                    res = VPX_CODEC_OK;
+                }
+
+            done &= (ctx->priv->alg_priv->mmaps[i].base != NULL);
+        }
+    }
+
+    if (done && !res)
+    {
+        vp8_finalize_mmaps(ctx->priv->alg_priv);
+        res = ctx->iface->init(ctx);
+    }
+
+    return res;
+}
+
+static vpx_codec_err_t image2yuvconfig(const vpx_image_t   *img,
+                                       YV12_BUFFER_CONFIG  *yv12)
+{
+    vpx_codec_err_t        res = VPX_CODEC_OK;
+    yv12->y_buffer = img->planes[PLANE_Y];
+    yv12->u_buffer = img->planes[PLANE_U];
+    yv12->v_buffer = img->planes[PLANE_V];
+
+    yv12->y_width  = img->d_w;
+    yv12->y_height = img->d_h;
+    yv12->uv_width = yv12->y_width / 2;
+    yv12->uv_height = yv12->y_height / 2;
+
+    yv12->y_stride = img->stride[PLANE_Y];
+    yv12->uv_stride = img->stride[PLANE_U];
+
+    yv12->border  = (img->stride[PLANE_Y] - img->d_w) / 2;
+    yv12->clrtype = (img->fmt == IMG_FMT_VPXI420 || img->fmt == IMG_FMT_VPXYV12);
+
+    return res;
+}
+
+
+static vpx_codec_err_t vp8_set_reference(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+
+    vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
+
+    if (data)
+    {
+        vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
+        YV12_BUFFER_CONFIG sd;
+
+        image2yuvconfig(&frame->img, &sd);
+
+        vp8dx_set_reference(ctx->pbi, frame->frame_type, &sd);
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+
+}
+
+static vpx_codec_err_t vp8_get_reference(vpx_codec_alg_priv_t *ctx,
+        int ctr_id,
+        va_list args)
+{
+
+    vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
+
+    if (data)
+    {
+        vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
+        YV12_BUFFER_CONFIG sd;
+
+        image2yuvconfig(&frame->img, &sd);
+
+        vp8dx_get_reference(ctx->pbi, frame->frame_type, &sd);
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+
+}
+
+static vpx_codec_err_t vp8_set_postproc(vpx_codec_alg_priv_t *ctx,
+                                        int ctr_id,
+                                        va_list args)
+{
+    vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
+#if CONFIG_POSTPROC
+
+    if (data)
+    {
+        ctx->postproc_cfg_set = 1;
+        ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data);
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+
+#else
+    return VPX_CODEC_INCAPABLE;
+#endif
+}
+
+
+vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
+{
+    {VP8_SET_REFERENCE,  vp8_set_reference},
+    {VP8_COPY_REFERENCE, vp8_get_reference},
+    {VP8_SET_POSTPROC,   vp8_set_postproc},
+    { -1, NULL},
+};
+
+
+#ifndef VERSION_STRING
+#define VERSION_STRING
+#endif
+vpx_codec_iface_t vpx_codec_vp8_dx_algo =
+{
+    "vpx Technologies VP8 Decoder" VERSION_STRING,
+    VPX_CODEC_INTERNAL_ABI_VERSION,
+    VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC,
+    /* vpx_codec_caps_t          caps; */
+    vp8_init,         /* vpx_codec_init_fn_t       init; */
+    vp8_destroy,      /* vpx_codec_destroy_fn_t    destroy; */
+    vp8_ctf_maps,     /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
+    vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t   get_mmap; */
+    vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t   set_mmap; */
+    {
+        vp8_peek_si,      /* vpx_codec_peek_si_fn_t    peek_si; */
+        vp8_get_si,       /* vpx_codec_get_si_fn_t     get_si; */
+        vp8_decode,       /* vpx_codec_decode_fn_t     decode; */
+        vp8_get_frame,    /* vpx_codec_frame_get_fn_t  frame_get; */
+    },
+    {NOT_IMPLEMENTED} /* encoder functions */
+};
+
+/*
+ * BEGIN BACKWARDS COMPATIBILITY SHIM.
+ */
+vpx_codec_iface_t vpx_codec_vp8_algo =
+{
+    "vpx Technologies VP8 Decoder (Deprecated API)" VERSION_STRING,
+    VPX_CODEC_INTERNAL_ABI_VERSION,
+    VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC,
+    /* vpx_codec_caps_t          caps; */
+    vp8_init,         /* vpx_codec_init_fn_t       init; */
+    vp8_destroy,      /* vpx_codec_destroy_fn_t    destroy; */
+    vp8_ctf_maps,     /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
+    vp8_xma_get_mmap, /* vpx_codec_get_mmap_fn_t   get_mmap; */
+    vp8_xma_set_mmap, /* vpx_codec_set_mmap_fn_t   set_mmap; */
+    {
+        vp8_peek_si,      /* vpx_codec_peek_si_fn_t    peek_si; */
+        vp8_get_si,       /* vpx_codec_get_si_fn_t     get_si; */
+        vp8_decode,       /* vpx_codec_decode_fn_t     decode; */
+        vp8_get_frame,    /* vpx_codec_frame_get_fn_t  frame_get; */
+    },
+    {NOT_IMPLEMENTED} /* encoder functions */
+};
diff --git a/vp8/vp8cx.h b/vp8/vp8cx.h
new file mode 100644 (file)
index 0000000..dd48c07
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\defgroup vp8_encoder WebM VP8 Encoder
+ * \ingroup vp8
+ *
+ * @{
+ */
+#include "vp8.h"
+
+/*!\file vp8cx.h
+ * \brief Provides definitions for using the VP8 encoder algorithm within the
+ *        vpx Codec Interface.
+ */
+#ifndef VP8CX_H
+#define VP8CX_H
+#include "vpx_codec_impl_top.h"
+
+/*!\brief Algorithm interface for VP8
+ *
+ * This interface provides the capability to encode raw VP8 streams, as would
+ * be found in AVI files.
+ */
+extern vpx_codec_iface_t vpx_codec_vp8_cx_algo;
+
+
+/*
+ * Algorithm Flags
+ */
+
+/*!\brief Don't reference the last frame
+ *
+ * When this flag is set, the encoder will not use the last frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * last frame or not automatically.
+ */
+#define VP8_EFLAG_NO_REF_LAST      (1<<16)
+
+
+/*!\brief Don't reference the golden frame
+ *
+ * When this flag is set, the encoder will not use the golden frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * golden frame or not automatically.
+ */
+#define VP8_EFLAG_NO_REF_GF        (1<<17)
+
+
+/*!\brief Don't reference the alternate reference frame
+ *
+ * When this flag is set, the encoder will not use the alt ref frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * alt ref frame or not automatically.
+ */
+#define VP8_EFLAG_NO_REF_ARF       (1<<21)
+
+
+/*!\brief Don't update the last frame
+ *
+ * When this flag is set, the encoder will not update the last frame with
+ * the contents of the current frame.
+ */
+#define VP8_EFLAG_NO_UPD_LAST      (1<<18)
+
+
+/*!\brief Don't update the golden frame
+ *
+ * When this flag is set, the encoder will not update the golden frame with
+ * the contents of the current frame.
+ */
+#define VP8_EFLAG_NO_UPD_GF        (1<<22)
+
+
+/*!\brief Don't update the alternate reference frame
+ *
+ * When this flag is set, the encoder will not update the alt ref frame with
+ * the contents of the current frame.
+ */
+#define VP8_EFLAG_NO_UPD_ARF       (1<<23)
+
+
+/*!\brief Force golden frame update
+ *
+ * When this flag is set, the encoder copy the contents of the current frame
+ * to the golden frame buffer.
+ */
+#define VP8_EFLAG_FORCE_GF         (1<<19)
+
+
+/*!\brief Force alternate reference frame update
+ *
+ * When this flag is set, the encoder copy the contents of the current frame
+ * to the alternate reference frame buffer.
+ */
+#define VP8_EFLAG_FORCE_ARF        (1<<24)
+
+
+/*!\brief Disable entropy update
+ *
+ * When this flag is set, the encoder will not update its internal entropy
+ * model based on the entropy of this frame.
+ */
+#define VP8_EFLAG_NO_UPD_ENTROPY   (1<<20)
+
+
+/*!\brief VP8 encoder control functions
+ *
+ * The set of macros define the control functions of VP8 encoder interface
+ */
+enum vp8e_enc_control_id
+{
+    VP8E_UPD_ENTROPY           = 5,  /**< control function to set mode of entropy update in encoder */
+    VP8E_UPD_REFERENCE,              /**< control function to set reference update mode in encoder */
+    VP8E_USE_REFERENCE,              /**< control function to set which reference frame encoder can use */
+    VP8E_SET_ROI_MAP,                /**< control function to pass an ROI map to encoder */
+    VP8E_SET_ACTIVEMAP,              /**< control function to pass an Active map to encoder */
+    VP8E_SET_SCALEMODE         = 11, /**< control function to set encoder scaling mode */
+    VP8E_SET_CPUUSED           = 13, /**< control function to set vp8 encoder cpuused  */
+    VP8E_SET_ENABLEAUTOALTREF,       /**< control function to enable vp8 to automatic set and use altref frame */
+    VP8E_SET_NOISE_SENSITIVITY,      /**< control function to set noise sensitivity */
+    VP8E_SET_SHARPNESS,              /**< control function to set sharpness */
+    VP8E_SET_STATIC_THRESHOLD,       /**< control function to set the threshold for macroblocks treated static */
+    VP8E_SET_TOKEN_PARTITIONS,       /**< control function to set the number of token partitions  */
+    VP8E_GET_LAST_QUANTIZER,         /**< return the quantizer chosen by the
+                                          encoder for the last frame using the internal
+                                          scale */
+    VP8E_GET_LAST_QUANTIZER_64,      /**< return the quantizer chosen by the
+                                          encoder for the last frame, using the 0..63
+                                          scale as used by the rc_*_quantizer config
+                                          parameters */
+    VP8E_SET_ARNR_MAXFRAMES,         /**< control function to set the max number of frames blurred creating arf*/
+    VP8E_SET_ARNR_STRENGTH ,         /**< control function to set the filter strength for the arf */
+    VP8E_SET_ARNR_TYPE     ,         /**< control function to set the type of filter to use for the arf*/
+} ;
+
+/*!\brief vpx 1-D scaling mode
+ *
+ * This set of constants define 1-D vpx scaling modes
+ */
+typedef enum vpx_scaling_mode_1d
+{
+    VP8E_NORMAL      = 0,
+    VP8E_FOURFIVE    = 1,
+    VP8E_THREEFIVE   = 2,
+    VP8E_ONETWO      = 3
+} VPX_SCALING_MODE;
+
+
+/*!\brief  vpx region of interest map
+ *
+ * These defines the data structures for the region of interest map
+ *
+ */
+
+typedef struct vpx_roi_map
+{
+    unsigned char *roi_map;      /**< specify an id between 0 and 3 for each 16x16 region within a frame */
+    unsigned int   rows;         /**< number of rows */
+    unsigned int   cols;         /**< number of cols */
+    int     delta_q[4];          /**< quantizer delta [-64, 64] off baseline for regions with id between 0 and 3*/
+    int     delta_lf[4];         /**< loop filter strength delta [-32, 32] for regions with id between 0 and 3 */
+    unsigned int   static_threshold[4];/**< threshold for region to be treated as static */
+} vpx_roi_map_t;
+
+/*!\brief  vpx active region map
+ *
+ * These defines the data structures for active region map
+ *
+ */
+
+
+typedef struct vpx_active_map
+{
+    unsigned char  *active_map; /**< specify an on (1) or off (0) each 16x16 region within a frame */
+    unsigned int    rows;       /**< number of rows */
+    unsigned int    cols;       /**< number of cols */
+} vpx_active_map_t;
+
+/*!\brief  vpx image scaling mode
+ *
+ * This defines the data structure for image scaling mode
+ *
+ */
+typedef struct vpx_scaling_mode
+{
+    VPX_SCALING_MODE    h_scaling_mode;  /**< horizontal scaling mode */
+    VPX_SCALING_MODE    v_scaling_mode;  /**< vertical scaling mode   */
+} vpx_scaling_mode_t;
+
+/*!\brief VP8 encoding mode
+ *
+ * This defines VP8 encoding mode
+ *
+ */
+typedef enum
+{
+    VP8_BEST_QUALITY_ENCODING,
+    VP8_GOOD_QUALITY_ENCODING,
+    VP8_REAL_TIME_ENCODING
+} vp8e_encoding_mode;
+
+/*!\brief VP8 token partition mode
+ *
+ * This defines VP8 partitioning mode for compressed data, i.e., the number of
+ * sub-streams in the bitstream. Used for parallelized decoding.
+ *
+ */
+
+typedef enum
+{
+    VP8_ONE_TOKENPARTITION   = 0,
+    VP8_TWO_TOKENPARTITION   = 1,
+    VP8_FOUR_TOKENPARTITION  = 2,
+    VP8_EIGHT_TOKENPARTITION = 3,
+} vp8e_token_partitions;
+
+
+/*!\brief VP8 encoder control function parameter type
+ *
+ * Defines the data types that VP8E control functions take. Note that
+ * additional common controls are defined in vp8.h
+ *
+ */
+
+
+/* These controls have been deprecated in favor of the flags parameter to
+ * vpx_codec_encode(). See the definition of VP8_EFLAG_* above.
+ */
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_UPD_ENTROPY,            int)
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_UPD_REFERENCE,          int)
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_USE_REFERENCE,          int)
+
+VPX_CTRL_USE_TYPE(VP8E_SET_ROI_MAP,            vpx_roi_map_t *)
+VPX_CTRL_USE_TYPE(VP8E_SET_ACTIVEMAP,          vpx_active_map_t *)
+VPX_CTRL_USE_TYPE(VP8E_SET_SCALEMODE,          vpx_scaling_mode_t *)
+
+VPX_CTRL_USE_TYPE(VP8E_SET_CPUUSED,            int)
+VPX_CTRL_USE_TYPE(VP8E_SET_ENABLEAUTOALTREF,   unsigned int)
+VPX_CTRL_USE_TYPE(VP8E_SET_NOISE_SENSITIVITY,  unsigned int)
+VPX_CTRL_USE_TYPE(VP8E_SET_SHARPNESS,          unsigned int)
+VPX_CTRL_USE_TYPE(VP8E_SET_STATIC_THRESHOLD,   unsigned int)
+VPX_CTRL_USE_TYPE(VP8E_SET_TOKEN_PARTITIONS,   vp8e_token_partitions)
+
+VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_MAXFRAMES,     unsigned int)
+VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_STRENGTH ,     unsigned int)
+VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_TYPE     ,     unsigned int)
+
+
+VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER,     int *)
+VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64,  int *)
+
+/*! @} - end defgroup vp8_encoder */
+#include "vpx_codec_impl_bottom.h"
+#endif
diff --git a/vp8/vp8cx.mk b/vp8/vp8cx.mk
new file mode 100644 (file)
index 0000000..e7e7663
--- /dev/null
@@ -0,0 +1,104 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk
+VP8_CX_SRCS-yes += $(VP8_COMMON_SRCS-yes)
+VP8_CX_SRCS-no  += $(VP8_COMMON_SRCS-no)
+VP8_CX_SRCS_REMOVE-yes += $(VP8_COMMON_SRCS_REMOVE-yes)
+VP8_CX_SRCS_REMOVE-no  += $(VP8_COMMON_SRCS_REMOVE-no)
+
+ifeq ($(ARCH_ARM),yes)
+  include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8cx_arm.mk
+endif
+
+VP8_CX_SRCS-yes += vp8cx.h vp8e.h vp8_cx_iface.c
+
+# encoder
+#INCLUDES += algo/vpx_common/vpx_mem/include
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += algo/vpx_ref/cpu_id/include
+#INCLUDES += common
+#INCLUDES += encoder
+
+CFLAGS+=-I$(SRC_PATH_BARE)/$(VP8_PREFIX)encoder
+
+VP8_CX_SRCS-yes += encoder/bitstream.c
+VP8_CX_SRCS-yes += encoder/boolhuff.c
+VP8_CX_SRCS-yes += encoder/dct.c
+VP8_CX_SRCS-yes += encoder/encodeframe.c
+VP8_CX_SRCS-yes += encoder/encodeintra.c
+VP8_CX_SRCS-yes += encoder/encodemb.c
+VP8_CX_SRCS-yes += encoder/encodemv.c
+VP8_CX_SRCS-yes += encoder/ethreading.c
+VP8_CX_SRCS-yes += encoder/firstpass.c
+VP8_CX_SRCS-yes += encoder/generic/csystemdependent.c
+VP8_CX_SRCS-yes += encoder/block.h
+VP8_CX_SRCS-yes += encoder/boolhuff.h
+VP8_CX_SRCS-yes += encoder/bitstream.h
+VP8_CX_SRCS-yes += encoder/dct.h
+VP8_CX_SRCS-yes += encoder/encodeintra.h
+VP8_CX_SRCS-yes += encoder/encodemb.h
+VP8_CX_SRCS-yes += encoder/encodemv.h
+VP8_CX_SRCS-yes += encoder/firstpass.h
+VP8_CX_SRCS-yes += encoder/mcomp.h
+VP8_CX_SRCS-yes += encoder/modecosts.h
+VP8_CX_SRCS-yes += encoder/onyx_int.h
+VP8_CX_SRCS-yes += encoder/pickinter.h
+VP8_CX_SRCS-yes += encoder/psnr.h
+VP8_CX_SRCS-yes += encoder/quantize.h
+VP8_CX_SRCS-yes += encoder/ratectrl.h
+VP8_CX_SRCS-yes += encoder/rdopt.h
+VP8_CX_SRCS-yes += encoder/tokenize.h
+VP8_CX_SRCS-yes += encoder/treewriter.h
+VP8_CX_SRCS-yes += encoder/variance.h
+VP8_CX_SRCS-yes += encoder/mcomp.c
+VP8_CX_SRCS-yes += encoder/modecosts.c
+VP8_CX_SRCS-yes += encoder/onyx_if.c
+VP8_CX_SRCS-yes += encoder/pickinter.c
+VP8_CX_SRCS-yes += encoder/picklpf.c
+VP8_CX_SRCS-yes += encoder/psnr.c
+VP8_CX_SRCS-yes += encoder/quantize.c
+VP8_CX_SRCS-yes += encoder/ratectrl.c
+VP8_CX_SRCS-yes += encoder/rdopt.c
+VP8_CX_SRCS-yes += encoder/sad_c.c
+VP8_CX_SRCS-yes += encoder/ssim.c
+VP8_CX_SRCS-yes += encoder/tokenize.c
+VP8_CX_SRCS-yes += encoder/treewriter.c
+VP8_CX_SRCS-yes += encoder/variance_c.c
+
+ifeq ($(CONFIG_REALTIME_ONLY),yes)
+VP8_CX_SRCS_REMOVE-yes += encoder/firstpass.c
+endif
+
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/encodemb_x86.h
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/dct_x86.h
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/mcomp_x86.h
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/variance_x86.h
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/x86_csystemdependent.c
+VP8_CX_SRCS-$(HAVE_MMX) += encoder/x86/variance_mmx.c
+VP8_CX_SRCS-$(HAVE_MMX) += encoder/x86/variance_impl_mmx.asm
+VP8_CX_SRCS-$(HAVE_MMX) += encoder/x86/sad_mmx.asm
+VP8_CX_SRCS-$(HAVE_MMX) += encoder/x86/dct_mmx.asm
+VP8_CX_SRCS-$(HAVE_MMX) += encoder/x86/subtract_mmx.asm
+VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/variance_sse2.c
+VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/variance_impl_sse2.asm
+VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/sad_sse2.asm
+VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/dct_sse2.asm
+VP8_CX_SRCS-$(HAVE_SSE2) += encoder/x86/fwalsh_sse2.asm
+VP8_CX_SRCS-$(HAVE_SSE3) += encoder/x86/sad_sse3.asm
+VP8_CX_SRCS-$(HAVE_SSSE3) += encoder/x86/sad_ssse3.asm
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/quantize_mmx.asm
+VP8_CX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += encoder/x86/encodeopt.asm
+
+VP8_CX_SRCS-yes := $(filter-out $(VP8_CX_SRCS_REMOVE-yes),$(VP8_CX_SRCS-yes))
+
+INSTALL-LIBS-yes += include/vp8.h include/vp8e.h include/vp8cx.h
diff --git a/vp8/vp8cx_arm.mk b/vp8/vp8cx_arm.mk
new file mode 100644 (file)
index 0000000..f0753d9
--- /dev/null
@@ -0,0 +1,64 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+#VP8_CX_SRCS list is modified according to different platforms.
+
+#File list for arm
+# encoder
+VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/csystemdependent.c
+
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/encodemb_arm.c
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/quantize_arm.c
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/picklpf_arm.c
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/boolhuff_arm.c
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/mcomp_arm.c
+
+VP8_CX_SRCS_REMOVE-$(HAVE_ARMV6)  += encoder/generic/csystemdependent.c
+VP8_CX_SRCS_REMOVE-$(HAVE_ARMV7)  += encoder/boolhuff.c
+VP8_CX_SRCS_REMOVE-$(HAVE_ARMV7)  += encoder/mcomp.c
+
+#File list for armv6
+# encoder
+VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/armv6/walsh_v6$(ASM)
+
+#File list for neon
+# encoder
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/fastfdct4x4_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/fastfdct8x4_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/fastquantizeb_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/sad8_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/sad16_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/shortfdct_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/subtract_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/variance_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_mse16x16_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_subpixelvariance8x8_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_subpixelvariance16x16_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_subpixelvariance16x16s_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_memcpy_neon$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_packtokens_armv7$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_packtokens_mbrow_armv7$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_packtokens_partitions_armv7$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/boolhuff_armv7$(ASM)
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/neon/vp8_shortwalsh4x4_neon$(ASM)
+
+VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/vpx_vp8_enc_asm_offsets.c
+
+#
+# Rule to extract assembly constants from C sources
+#
+ifeq ($(ARCH_ARM),yes)
+vpx_vp8_enc_asm_offsets.asm: obj_int_extract
+vpx_vp8_enc_asm_offsets.asm: $(VP8_PREFIX)encoder/arm/vpx_vp8_enc_asm_offsets.c.o
+       ./obj_int_extract rvds $< $(ADS2GAS) > $@
+OBJS-yes += $(VP8_PREFIX)encoder/arm/vpx_vp7_enc_asm_offsets.c.o
+CLEAN-OBJS += vpx_vp8_enc_asm_offsets.asm
+$(filter %$(ASM).o,$(OBJS-yes)): vpx_vp8_enc_asm_offsets.asm
+endif
diff --git a/vp8/vp8dx.h b/vp8/vp8dx.h
new file mode 100644 (file)
index 0000000..7310b3b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vp8.h"
+
+/*!\defgroup vp8_decoder WebM VP8 Decoder
+ * \ingroup vp8
+ *
+ * @{
+ */
+/*!\file vp8dx.h
+ * \brief Provides definitions for using the VP8 algorithm within the vpx Decoder
+ *        interface.
+ */
+#ifndef VP8DX_H
+#define VP8DX_H
+#include "vpx_codec_impl_top.h"
+
+/*!\brief Algorithm interface for VP8
+ *
+ * This interface provides the capability to decode raw VP8 streams, as would
+ * be found in AVI files and other non-Flash uses.
+ */
+extern vpx_codec_iface_t vpx_codec_vp8_dx_algo;
+
+/* Include controls common to both the encoder and decoder */
+#include "vp8.h"
+
+
+/*! @} - end defgroup vp8_decoder */
+
+
+#include "vpx_codec_impl_bottom.h"
+#endif
diff --git a/vp8/vp8dx.mk b/vp8/vp8dx.mk
new file mode 100644 (file)
index 0000000..e6af543
--- /dev/null
@@ -0,0 +1,76 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk
+VP8_DX_SRCS-yes += $(VP8_COMMON_SRCS-yes)
+VP8_DX_SRCS-no  += $(VP8_COMMON_SRCS-no)
+VP8_DX_SRCS_REMOVE-yes += $(VP8_COMMON_SRCS_REMOVE-yes)
+VP8_DX_SRCS_REMOVE-no  += $(VP8_COMMON_SRCS_REMOVE-no)
+
+ifeq ($(ARCH_ARM),yes)
+  include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8dx_arm.mk
+endif
+
+VP8_DX_SRCS-yes += vp8dx.h vp8_dx_iface.c
+
+CFLAGS+=-I$(SRC_PATH_BARE)/$(VP8_PREFIX)decoder
+
+
+# common
+#define ARM
+#define DISABLE_THREAD
+#define INLINE=__forceinline
+
+#INCLUDES += algo/vpx_common/vpx_mem/include
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += decoder
+
+
+
+# decoder
+#define ARM
+#define DISABLE_THREAD
+#define INLINE=__forceinline
+
+#INCLUDES += algo/vpx_common/vpx_mem/include
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += common
+#INCLUDES += decoder
+
+VP8_DX_SRCS-yes += decoder/dboolhuff.c
+VP8_DX_SRCS-yes += decoder/decodemv.c
+VP8_DX_SRCS-yes += decoder/decodframe.c
+VP8_DX_SRCS-yes += decoder/demode.c
+VP8_DX_SRCS-yes += decoder/dequantize.c
+VP8_DX_SRCS-yes += decoder/detokenize.c
+VP8_DX_SRCS-yes += decoder/generic/dsystemdependent.c
+VP8_DX_SRCS-yes += decoder/dboolhuff.h
+VP8_DX_SRCS-yes += decoder/decodemv.h
+VP8_DX_SRCS-yes += decoder/decoderthreading.h
+VP8_DX_SRCS-yes += decoder/demode.h
+VP8_DX_SRCS-yes += decoder/dequantize.h
+VP8_DX_SRCS-yes += decoder/detokenize.h
+VP8_DX_SRCS-yes += decoder/onyxd_int.h
+VP8_DX_SRCS-yes += decoder/treereader.h
+VP8_DX_SRCS-yes += decoder/onyxd_if.c
+VP8_DX_SRCS-yes += decoder/threading.c
+
+VP8_DX_SRCS-yes := $(filter-out $(VP8_DX_SRCS_REMOVE-yes),$(VP8_DX_SRCS-yes))
+
+INSTALL-LIBS-yes += include/vp8.h include/vp8dx.h
+
+VP8_DX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += decoder/x86/dequantize_x86.h
+VP8_DX_SRCS-$(ARCH_X86)$(ARCH_X86_64) += decoder/x86/x86_dsystemdependent.c
+VP8_DX_SRCS-$(HAVE_MMX) += decoder/x86/dequantize_mmx.asm
diff --git a/vp8/vp8dx_arm.mk b/vp8/vp8dx_arm.mk
new file mode 100644 (file)
index 0000000..1b4a7ec
--- /dev/null
@@ -0,0 +1,44 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+#VP8_DX_SRCS list is modified according to different platforms.
+
+#File list for arm
+# decoder
+#VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/decodframe_arm.c
+VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/dequantize_arm.c
+VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/dsystemdependent.c
+
+#VP8_DX_SRCS_REMOVE-$(HAVE_ARMV6)  += decoder/decodframe.c
+VP8_DX_SRCS_REMOVE-$(HAVE_ARMV6)  += decoder/dequantize.c
+VP8_DX_SRCS_REMOVE-$(HAVE_ARMV6)  += decoder/generic/dsystemdependent.c
+
+#File list for armv6
+# decoder
+VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/armv6/dequantdcidct_v6$(ASM)
+VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/armv6/dequantidct_v6$(ASM)
+VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/armv6/dequantize_v6$(ASM)
+
+#File list for neon
+# decoder
+VP8_DX_SRCS-$(HAVE_ARMV7)  += decoder/arm/neon/dequantdcidct_neon$(ASM)
+VP8_DX_SRCS-$(HAVE_ARMV7)  += decoder/arm/neon/dequantidct_neon$(ASM)
+VP8_DX_SRCS-$(HAVE_ARMV7)  += decoder/arm/neon/dequantizeb_neon$(ASM)
+
+
+#for new token test
+ifeq ($(ARCH_ARM),yes)
+VP8_DX_SRCS-$(CONFIG_NEW_TOKENS)  += decoder/arm/detokenize_arm_sjl.c
+VP8_DX_SRCS-$(CONFIG_NEW_TOKENS)  += decoder/arm/detokenize_arm_v6$(ASM)
+VP8_DX_SRCS-$(CONFIG_NEW_TOKENS)  += decoder/onyxd_if_sjl.c
+
+VP8_DX_SRCS_REMOVE-$(CONFIG_NEW_TOKENS)  += decoder/arm/detokenize_arm.c
+VP8_DX_SRCS_REMOVE-$(CONFIG_NEW_TOKENS)  += decoder/onyxd_if.c
+endif
diff --git a/vp8/vp8e.h b/vp8/vp8e.h
new file mode 100644 (file)
index 0000000..a90aa2a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This file contains backwards compatibility stubs for applications using
+ * the VP8 version 1.0 API.
+ */
+#ifndef VP8E_H
+#define VP8E_H
+#include "vpx_codec_impl_top.h"
+
+#if defined(VPX_CODEC_DISABLE_COMPAT) && VPX_CODEC_DISABLE_COMPAT
+#error "Backwards compatibility disabled: don't include vp8e.h"
+#endif
+
+#include "vp8cx.h"
+DECLSPEC_DEPRECATED extern vpx_codec_iface_t vpx_enc_vp8_algo DEPRECATED;
+
+
+enum
+{
+    VP8E_SET_REFERENCE     = VP8_SET_REFERENCE,
+    VP8E_COPY_REFERENCE    = VP8_COPY_REFERENCE,
+    VP8E_SET_PREVIEWPP     = VP8_SET_POSTPROC,
+    VP8E_SET_FLUSHFLAG     = 4,
+    VP8E_SET_FRAMETYPE     = 10,
+    VP8E_SET_ENCODING_MODE = 12
+};
+
+#define NORMAL_FRAME   (0)
+#define KEY_FRAME      (1)
+
+/* Change VP8E to VP8 to get the undeprecated version of these (defined in
+ * vp8.h)
+ */
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_REFERENCE,   vpx_ref_frame_t *)
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_COPY_REFERENCE,  vpx_ref_frame_t *)
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_PREVIEWPP,   vp8_postproc_cfg_t *)
+
+
+/* Flush is done by calling vpx_codec_encode with a NULL input image. */
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_FLUSHFLAG,          int)
+
+
+/* Frame type is set with a flag to vpx_codec_control. See VPX_EFLAG_FORCE_KF
+ */
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_FRAMETYPE,          int)
+
+
+/* This control has been deprecated in favor of the duration parameter to
+ * vpx_codec_encode(). Use the #VPX_DL_REALTIME, #VPX_DL_GOOD_QUALITY,
+ * #VPX_DL_BEST_QUALITY constants to that parameter instead.
+ */
+VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_ENCODING_MODE, vp8e_encoding_mode)
+#include "vpx_codec_impl_bottom.h"
+#endif
diff --git a/vp8_api1_migration.txt b/vp8_api1_migration.txt
new file mode 100644 (file)
index 0000000..47b7981
--- /dev/null
@@ -0,0 +1,198 @@
+Version 2.x of this library has deprecated or removed a number of interfaces to
+the VP8 codec. Where possible, the old interfaces have been left in place in a
+deprecated state, and will generate compiler warnings when they are referenced.
+All users are encouraged to update their code to the new interfaces as soon as
+possible. To assist in this effort, the `VPX_CODEC_DISABLE_COMPAT` symbol can
+be #defined to 1 prior to including vpx headers. This will disable the
+backwards compatability workarounds and ensure that you are using only the
+latest API.
+
+The *TWO-PASS STATISTICS* sections detail the one section of code which is not
+backwards compatable and will require code changes.
+
+
+HEADER FILES
+============
+The following header files were renamed:
+
+    vp8.h  -> vp8dx.h
+    vp8e.h -> vp8cx.h
+
+
+INTERFACE SYMBOLS
+=================
+The following interface symbols were renamed:
+
+    vpx_codec_vp8_algo -> vpx_codec_vp8_dx_algo
+    vpx_enc_vp8_algo   -> vpx_codec_vp8_cx_algo
+
+
+TWO-PASS STATISTICS
+===================
+Two-pass statistics are handled significantly differently. The version 1 API
+stored statistics in a file, and the application passed the name of that file
+in the `vpx_codec_enc_cfg` structure. In this version, statistics are returned
+though the application though the `vpx_codec_get_cx_data()` interface. The
+application must concatenate these packets into a contiguous buffer and then
+pass that buffer to the encoder through the `vpx_codec_enc_cfg` structure on
+the second pass initialization. The application may choose to keep these packets
+in memory or write them to disk. Statistics packets are approximately 112 bytes
+per frame. See the example code for more detailed examples.
+
+
+ENCODER CONTROLS
+================
+
+Renames
+-------
+The following controls are duplicated between the encoder and the decoder, but
+the encoder unnecessarily introduced unique identifiers for them. These
+identifiers were removed in favor of the ones used by the decoder:
+
+    VP8E_SET_REFERENCE  -> VP8_SET_REFERENCE
+    VP8E_COPY_REFERENCE -> VP8_COPY_REFERENCE
+    VP8E_SET_PREVIEWPP  -> VP8_SET_POSTPROC
+
+
+VP8E_SET_FRAMETYPE
+------------------
+This control was removed in favor of the `flags` parameter to
+`vpx_codec_encode()`. Existing code such as:
+
+~~~
+    vpx_codec_control(&encoder, VP8E_SET_FRAMETYPE, KEY_FRAME);
+    ...
+    vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
+~~~
+
+becomes:
+
+~~~
+    vpx_codec_encode(&encoder, img, pts, 1, VPX_EFLAG_FORCE_KF,
+    VPX_DL_REALTIME);
+~~~
+
+
+
+VP8E_SET_FLUSHFLAG
+------------------
+Flush is handled by passing `NULL` to the `img` parameter of
+`vpx_codec_encode()`. You must do this at least once, regardless of your encoder
+configuration. i.e. it's not specific to g_lag_in_frames. This control was
+removed.
+
+~~~
+    while(...) {
+       ...
+       vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
+       while( (pkt = vpx_codec_get_cx_data(&encoder, &iter)) ) {
+          ...
+       }
+    }
+    vpx_codec_control(&encoder, VP8E_SET_FLUSHFLAG, 1);
+    while( (pkt = vpx_codec_get_cx_data(&encoder, &iter)) ) {
+       ...
+    }
+    vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
+~~~
+
+becomes
+
+~~~
+    while(new_image && ...) {
+       ...
+       vpx_codec_encode(&encoder, new_image?img:NULL, pts, 1, 0, 0);
+       while( (pkt = vpx_codec_get_cx_data(&encoder, &iter)) ) {
+          ...
+       }
+    }
+~~~
+
+
+
+VP8E_SET_ENCODING_MODE
+----------------------
+This control was removed in favor of the `deadline` parameter to
+`vpx_codec_encode()`. There are three macros that can be used to get the
+equivalent behavior: VPX_DL_REALTIME, VPX_DL_GOOD_QUALITY,
+VPX_DL_BEST_QUALITY. Existing code such as:
+
+~~~
+    vpx_codec_control(&encoder, VP8E_SET_ENCODING_MODE, VP8_REAL_TIME_ENCODING);
+    ...
+    vpx_codec_encode(&encoder, img, pts, 1, 0, 0);
+~~~
+
+becomes:
+
+~~~
+    vpx_codec_encode(&encoder, img, pts, 1, 0, VPX_DL_REALTIME);
+~~~
+
+
+VP8E_UPD_ENTROPY
+------------------
+This control was deprecated in favor of the `flags` parameter to
+`vpx_codec_encode()`. Existing code such as:
+
+~~~
+    vpx_codec_control(&encoder, VP8E_UPD_ENTROPY, 0);
+~~~
+
+becomes:
+
+~~~
+    vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_NO_UPD_ENTROPY,
+                     VPX_DL_REALTIME);
+~~~
+
+
+VP8E_UPD_REFERENCE
+------------------
+This control was deprecated in favor of the `flags` parameter to
+`vpx_codec_encode()`. A set bit on the VP8E_UPD_REFERENCE bitfield is
+analogous to setting the VP8_EFLAG_FORCE_* flag. A cleared bit is analogous
+to setting the VP8_EFLAG_NO_UPD_* flag. If neither the FORCE or NO_UPD bit
+is set, the encoder will make its decision automatically, as usual. Setting
+both bits will result in an error being returned. Existing code such as:
+
+~~~
+    vpx_codec_control(&encoder, VP8E_UPD_REFERENCE,
+                      VP8_LAST_FRAME | VP8_GOLD_FRAME);
+    vpx_codec_control(&encoder, VP8E_UPD_REFERENCE, 0);
+    ...
+    vpx_codec_encode(&encoder, img, pts, 1, 0, VPX_DL_REALTIME);
+~~~
+
+becomes:
+
+~~~
+    vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_FORCE_GF,
+                     VPX_DL_REALTIME);
+    vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_NO_UPD_LAST
+                     | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF,
+                     VPX_DL_REALTIME);
+~~~
+
+
+VP8E_USE_REFERENCE
+------------------
+This control was deprecated in favor of the `flags` parameter to
+`vpx_codec_encode()`. A cleared bit on the VP8E_USE_REFERENCE bitfield is
+analogous to setting the VP8_EFLAG_NO_REF* flag. A set bit indicates that
+the encoder will make its decision automatically, as usual.
+Existing code such as:
+
+~~~
+    vpx_codec_control(&encoder, VP8E_USE_REFERENCE,
+                      VP8_ALTR_FRAME | VP8_GOLD_FRAME);
+    ...
+    vpx_codec_encode(&encoder, img, pts, 1, 0, VPX_DL_REALTIME);
+~~~
+
+becomes
+
+~~~
+    vpx_codec_encode(&encoder, img, pts, 1, VP8_EFLAG_NO_REF_LAST,
+                     VPX_DL_REALTIME);
+~~~
diff --git a/vpx_codec/exports b/vpx_codec/exports
new file mode 100644 (file)
index 0000000..f5e7473
--- /dev/null
@@ -0,0 +1,17 @@
+text vpx_dec_control
+text vpx_dec_decode
+text vpx_dec_destroy
+text vpx_dec_err_to_string
+text vpx_dec_error
+text vpx_dec_error_detail
+text vpx_dec_get_caps
+text vpx_dec_get_frame
+text vpx_dec_get_mem_map
+text vpx_dec_get_stream_info
+text vpx_dec_iface_name
+text vpx_dec_init_ver
+text vpx_dec_peek_stream_info
+text vpx_dec_register_put_frame_cb
+text vpx_dec_register_put_slice_cb
+text vpx_dec_set_mem_map
+text vpx_dec_xma_init_ver
diff --git a/vpx_codec/internal/vpx_codec_internal.h b/vpx_codec/internal/vpx_codec_internal.h
new file mode 100644 (file)
index 0000000..0867552
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\file decoder_impl.h
+ * \brief Describes the decoder algorithm interface for algorithm
+ *        implementations.
+ *
+ * This file defines the private structures and data types that are only
+ * relevant to implementing an algorithm, as opposed to using it.
+ *
+ * To create a decoder algorithm class, an interface structure is put
+ * into the global namespace:
+ *     <pre>
+ *     my_codec.c:
+ *       vpx_codec_iface_t my_codec = {
+ *           "My Codec v1.0",
+ *           VPX_CODEC_ALG_ABI_VERSION,
+ *           ...
+ *       };
+ *     </pre>
+ *
+ * An application instantiates a specific decoder instance by using
+ * vpx_codec_init() and a pointer to the algorithm's interface structure:
+ *     <pre>
+ *     my_app.c:
+ *       extern vpx_codec_iface_t my_codec;
+ *       {
+ *           vpx_codec_ctx_t algo;
+ *           res = vpx_codec_init(&algo, &my_codec);
+ *       }
+ *     </pre>
+ *
+ * Once initialized, the instance is manged using other functions from
+ * the vpx_codec_* family.
+ */
+#ifndef VPX_CODEC_INTERNAL_H
+#define VPX_CODEC_INTERNAL_H
+#include "../vpx_decoder.h"
+#include "../vpx_encoder.h"
+#include <stdarg.h>
+
+
+/*!\brief Current ABI version number
+ *
+ * \internal
+ * If this file is altered in any way that changes the ABI, this value
+ * must be bumped.  Examples include, but are not limited to, changing
+ * types, removing or reassigning enums, adding/removing/rearranging
+ * fields to structures
+ */
+#define VPX_CODEC_INTERNAL_ABI_VERSION (2) /**<\hideinitializer*/
+
+typedef struct vpx_codec_alg_priv  vpx_codec_alg_priv_t;
+
+/*!\brief init function pointer prototype
+ *
+ * Performs algorithm-specific initialization of the decoder context. This
+ * function is called by the generic vpx_codec_init() wrapper function, so
+ * plugins implementing this interface may trust the input parameters to be
+ * properly initialized.
+ *
+ * \param[in] ctx   Pointer to this instance's context
+ * \retval #VPX_CODEC_OK
+ *     The input stream was recognized and decoder initialized.
+ * \retval #VPX_CODEC_MEM_ERROR
+ *     Memory operation failed.
+ */
+typedef vpx_codec_err_t (*vpx_codec_init_fn_t)(vpx_codec_ctx_t *ctx);
+
+/*!\brief destroy function pointer prototype
+ *
+ * Performs algorithm-specific destruction of the decoder context. This
+ * function is called by the generic vpx_codec_destroy() wrapper function,
+ * so plugins implementing this interface may trust the input parameters
+ * to be properly initialized.
+ *
+ * \param[in] ctx   Pointer to this instance's context
+ * \retval #VPX_CODEC_OK
+ *     The input stream was recognized and decoder initialized.
+ * \retval #VPX_CODEC_MEM_ERROR
+ *     Memory operation failed.
+ */
+typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)(vpx_codec_alg_priv_t *ctx);
+
+/*!\brief parse stream info function pointer prototype
+ *
+ * Performs high level parsing of the bitstream. This function is called by
+ * the generic vpx_codec_parse_stream() wrapper function, so plugins implementing
+ * this interface may trust the input parameters to be properly initialized.
+ *
+ * \param[in]      data    Pointer to a block of data to parse
+ * \param[in]      data_sz Size of the data buffer
+ * \param[in,out]  si      Pointer to stream info to update. The size member
+ *                         \ref MUST be properly initialized, but \ref MAY be
+ *                         clobbered by the algorithm. This parameter \ref MAY
+ *                         be NULL.
+ *
+ * \retval #VPX_CODEC_OK
+ *     Bitstream is parsable and stream information updated
+ */
+typedef vpx_codec_err_t (*vpx_codec_peek_si_fn_t)(const uint8_t         *data,
+        unsigned int           data_sz,
+        vpx_codec_stream_info_t *si);
+
+/*!\brief Return information about the current stream.
+ *
+ * Returns information about the stream that has been parsed during decoding.
+ *
+ * \param[in]      ctx     Pointer to this instance's context
+ * \param[in,out]  si      Pointer to stream info to update. The size member
+ *                         \ref MUST be properly initialized, but \ref MAY be
+ *                         clobbered by the algorithm. This parameter \ref MAY
+ *                         be NULL.
+ *
+ * \retval #VPX_CODEC_OK
+ *     Bitstream is parsable and stream information updated
+ */
+typedef vpx_codec_err_t (*vpx_codec_get_si_fn_t)(vpx_codec_alg_priv_t    *ctx,
+        vpx_codec_stream_info_t *si);
+
+/*!\brief control function pointer prototype
+ *
+ * This function is used to exchange algorithm specific data with the decoder
+ * instance. This can be used to implement features specific to a particular
+ * algorithm.
+ *
+ * This function is called by the generic vpx_codec_control() wrapper
+ * function, so plugins implementing this interface may trust the input
+ * parameters to be properly initialized. However,  this interface does not
+ * provide type safety for the exchanged data or assign meanings to the
+ * control codes. Those details should be specified in the algorithm's
+ * header file. In particular, the ctrl_id parameter is guaranteed to exist
+ * in the algorithm's control mapping table, and the data paramter may be NULL.
+ *
+ *
+ * \param[in]     ctx              Pointer to this instance's context
+ * \param[in]     ctrl_id          Algorithm specific control identifier
+ * \param[in,out] data             Data to exchange with algorithm instance.
+ *
+ * \retval #VPX_CODEC_OK
+ *     The internal state data was deserialized.
+ */
+typedef vpx_codec_err_t (*vpx_codec_control_fn_t)(vpx_codec_alg_priv_t  *ctx,
+        int                  ctrl_id,
+        va_list              ap);
+
+/*!\brief control function pointer mapping
+ *
+ * This structure stores the mapping between control identifiers and
+ * implementing functions. Each algorithm provides a list of these
+ * mappings. This list is searched by the vpx_codec_control() wrapper
+ * function to determine which function to invoke. The special
+ * value {0, NULL} is used to indicate end-of-list, and must be
+ * present. The special value {0, <non-null>} can be used as a catch-all
+ * mapping. This implies that ctrl_id values chosen by the algorithm
+ * \ref MUST be non-zero.
+ */
+typedef const struct
+{
+    int                    ctrl_id;
+    vpx_codec_control_fn_t   fn;
+} vpx_codec_ctrl_fn_map_t;
+
+/*!\brief decode data function pointer prototype
+ *
+ * Processes a buffer of coded data. If the processing results in a new
+ * decoded frame becoming available, #VPX_CODEC_CB_PUT_SLICE and
+ * #VPX_CODEC_CB_PUT_FRAME events are generated as appropriate. This
+ * function is called by the generic vpx_codec_decode() wrapper function,
+ * so plugins implementing this interface may trust the input parameters
+ * to be properly initialized.
+ *
+ * \param[in] ctx          Pointer to this instance's context
+ * \param[in] data         Pointer to this block of new coded data. If
+ *                         NULL, a #VPX_CODEC_CB_PUT_FRAME event is posted
+ *                         for the previously decoded frame.
+ * \param[in] data_sz      Size of the coded data, in bytes.
+ *
+ * \return Returns #VPX_CODEC_OK if the coded data was processed completely
+ *         and future pictures can be decoded without error. Otherwise,
+ *         see the descriptions of the other error codes in ::vpx_codec_err_t
+ *         for recoverability capabilities.
+ */
+typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t  *ctx,
+        const uint8_t         *data,
+        unsigned int     data_sz,
+        void        *user_priv,
+        long         deadline);
+
+/*!\brief Decoded frames iterator
+ *
+ * Iterates over a list of the frames available for display. The iterator
+ * storage should be initialized to NULL to start the iteration. Iteration is
+ * complete when this function returns NULL.
+ *
+ * The list of available frames becomes valid upon completion of the
+ * vpx_codec_decode call, and remains valid until the next call to vpx_codec_decode.
+ *
+ * \param[in]     ctx      Pointer to this instance's context
+ * \param[in out] iter     Iterator storage, initialized to NULL
+ *
+ * \return Returns a pointer to an image, if one is ready for display. Frames
+ *         produced will always be in PTS (presentation time stamp) order.
+ */
+typedef vpx_image_t*(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx,
+        vpx_codec_iter_t     *iter);
+
+
+/*\brief e_xternal Memory Allocation memory map get iterator
+ *
+ * Iterates over a list of the memory maps requested by the decoder. The
+ * iterator storage should be initialized to NULL to start the iteration.
+ * Iteration is complete when this function returns NULL.
+ *
+ * \param[in out] iter     Iterator storage, initialized to NULL
+ *
+ * \return Returns a pointer to an memory segment descriptor, or NULL to
+ *         indicate end-of-list.
+ */
+typedef vpx_codec_err_t (*vpx_codec_get_mmap_fn_t)(const vpx_codec_ctx_t      *ctx,
+        vpx_codec_mmap_t           *mmap,
+        vpx_codec_iter_t           *iter);
+
+
+/*\brief e_xternal Memory Allocation memory map set iterator
+ *
+ * Sets a memory descriptor inside the decoder instance.
+ *
+ * \param[in] ctx      Pointer to this instance's context
+ * \param[in] mmap     Memory map to store.
+ *
+ * \retval #VPX_CODEC_OK
+ *     The memory map was accepted and stored.
+ * \retval #VPX_CODEC_MEM_ERROR
+ *     The memory map was rejected.
+ */
+typedef vpx_codec_err_t (*vpx_codec_set_mmap_fn_t)(vpx_codec_ctx_t         *ctx,
+        const vpx_codec_mmap_t  *mmap);
+
+
+typedef vpx_codec_err_t (*vpx_codec_encode_fn_t)(vpx_codec_alg_priv_t  *ctx,
+        const vpx_image_t     *img,
+        vpx_codec_pts_t        pts,
+        unsigned long          duration,
+        vpx_enc_frame_flags_t  flags,
+        unsigned long          deadline);
+typedef const vpx_codec_cx_pkt_t*(*vpx_codec_get_cx_data_fn_t)(vpx_codec_alg_priv_t *ctx,
+        vpx_codec_iter_t     *iter);
+
+typedef vpx_codec_err_t
+(*vpx_codec_enc_config_set_fn_t)(vpx_codec_alg_priv_t       *ctx,
+                                 const vpx_codec_enc_cfg_t  *cfg);
+typedef vpx_fixed_buf_t *
+(*vpx_codec_get_global_headers_fn_t)(vpx_codec_alg_priv_t   *ctx);
+
+typedef vpx_image_t *
+(*vpx_codec_get_preview_frame_fn_t)(vpx_codec_alg_priv_t   *ctx);
+
+/*!\brief usage configuration mapping
+ *
+ * This structure stores the mapping between usage identifiers and
+ * configuration structures. Each algorithm provides a list of these
+ * mappings. This list is searched by the vpx_codec_enc_config_default()
+ * wrapper function to determine which config to return. The special value
+ * {-1, {0}} is used to indicate end-of-list, and must be present. At least
+ * one mapping must be present, in addition to the end-of-list.
+ *
+ */
+typedef const struct
+{
+    int                 usage;
+    vpx_codec_enc_cfg_t cfg;
+} vpx_codec_enc_cfg_map_t;
+
+#define NOT_IMPLEMENTED 0
+
+/*!\brief Decoder algorithm interface interface
+ *
+ * All decoders \ref MUST expose a variable of this type.
+ */
+struct vpx_codec_iface
+{
+    const char               *name;        /**< Identification String  */
+    int                       abi_version; /**< Implemented ABI version */
+    vpx_codec_caps_t          caps;    /**< Decoder capabilities */
+    vpx_codec_init_fn_t       init;    /**< \copydoc ::vpx_codec_init_fn_t */
+    vpx_codec_destroy_fn_t    destroy;     /**< \copydoc ::vpx_codec_destroy_fn_t */
+    vpx_codec_ctrl_fn_map_t  *ctrl_maps;   /**< \copydoc ::vpx_codec_ctrl_fn_map_t */
+    vpx_codec_get_mmap_fn_t   get_mmap;    /**< \copydoc ::vpx_codec_get_mmap_fn_t */
+    vpx_codec_set_mmap_fn_t   set_mmap;    /**< \copydoc ::vpx_codec_set_mmap_fn_t */
+    struct
+    {
+        vpx_codec_peek_si_fn_t    peek_si;     /**< \copydoc ::vpx_codec_peek_si_fn_t */
+        vpx_codec_get_si_fn_t     get_si;      /**< \copydoc ::vpx_codec_peek_si_fn_t */
+        vpx_codec_decode_fn_t     decode;      /**< \copydoc ::vpx_codec_decode_fn_t */
+        vpx_codec_get_frame_fn_t  get_frame;   /**< \copydoc ::vpx_codec_get_frame_fn_t */
+    } dec;
+    struct
+    {
+        vpx_codec_enc_cfg_map_t           *cfg_maps;      /**< \copydoc ::vpx_codec_enc_cfg_map_t */
+        vpx_codec_encode_fn_t              encode;        /**< \copydoc ::vpx_codec_encode_fn_t */
+        vpx_codec_get_cx_data_fn_t         get_cx_data;   /**< \copydoc ::vpx_codec_get_cx_data_fn_t */
+        vpx_codec_enc_config_set_fn_t      cfg_set;       /**< \copydoc ::vpx_codec_enc_config_set_fn_t */
+        vpx_codec_get_global_headers_fn_t  get_glob_hdrs; /**< \copydoc ::vpx_codec_enc_config_set_fn_t */
+        vpx_codec_get_preview_frame_fn_t   get_preview;   /**< \copydoc ::vpx_codec_get_preview_frame_fn_t */
+    } enc;
+};
+
+/*!\brief Callback function pointer / user data pair storage */
+typedef struct
+{
+    union
+    {
+        vpx_codec_put_frame_cb_fn_t    put_frame;
+        vpx_codec_put_slice_cb_fn_t    put_slice;
+    };
+    void                            *user_priv;
+} vpx_codec_priv_cb_pair_t;
+
+
+/*!\brief Instance private storage
+ *
+ * This structure is allocated by the algorithm's init function. It can be
+ * extended in one of two ways. First, a second, algorithm specific structure
+ * can be allocated and the priv member pointed to it. Alternatively, this
+ * structure can be made the first member of the algorithm specific structure,
+ * and the pointer casted to the proper type.
+ */
+struct vpx_codec_priv
+{
+    unsigned int                    sz;
+    vpx_codec_iface_t              *iface;
+    struct vpx_codec_alg_priv      *alg_priv;
+    const char                     *err_detail;
+    unsigned int                    eval_counter;
+    vpx_codec_flags_t               init_flags;
+    struct
+    {
+        vpx_codec_priv_cb_pair_t    put_frame_cb;
+        vpx_codec_priv_cb_pair_t    put_slice_cb;
+    } dec;
+    struct
+    {
+        int                         tbd;
+        struct vpx_fixed_buf        cx_data_dst_buf;
+        unsigned int                cx_data_pad_before;
+        unsigned int                cx_data_pad_after;
+        vpx_codec_cx_pkt_t          cx_data_pkt;
+    } enc;
+};
+
+#undef VPX_CTRL_USE_TYPE
+#define VPX_CTRL_USE_TYPE(id, typ) \
+    static typ id##__value(va_list args) {return va_arg(args, typ);} \
+    static typ id##__convert(void *x)\
+    {\
+        union\
+        {\
+            void *x;\
+            typ   d;\
+        } u;\
+        u.x = x;\
+        return u.d;\
+    }
+
+
+#undef VPX_CTRL_USE_TYPE_DEPRECATED
+#define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \
+    static typ id##__value(va_list args) {return va_arg(args, typ);} \
+    static typ id##__convert(void *x)\
+    {\
+        union\
+        {\
+            void *x;\
+            typ   d;\
+        } u;\
+        u.x = x;\
+        return u.d;\
+    }
+
+#define CAST(id, arg) id##__value(arg)
+#define RECAST(id, x) id##__convert(x)
+
+
+/* Internal Utility Functions
+ *
+ * The following functions are indended to be used inside algorithms as
+ * utilities for manipulating vpx_codec_* data structures.
+ */
+struct vpx_codec_pkt_list
+{
+    unsigned int            cnt;
+    unsigned int            max;
+    struct vpx_codec_cx_pkt pkts[1];
+};
+
+#define vpx_codec_pkt_list_decl(n)\
+    union {struct vpx_codec_pkt_list head;\
+        struct {struct vpx_codec_pkt_list head;\
+            struct vpx_codec_cx_pkt    pkts[n];} alloc;}
+
+#define vpx_codec_pkt_list_init(m)\
+    (m)->alloc.head.cnt = 0,\
+                          (m)->alloc.head.max = sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0])
+
+int
+vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *,
+                       const struct vpx_codec_cx_pkt *);
+
+const vpx_codec_cx_pkt_t*
+vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
+                       vpx_codec_iter_t           *iter);
+
+
+#include <stdio.h>
+#include <setjmp.h>
+struct vpx_internal_error_info
+{
+    vpx_codec_err_t  error_code;
+    int              has_detail;
+    char             detail[80];
+    int              setjmp;
+    jmp_buf          jmp;
+};
+
+static void vpx_internal_error(struct vpx_internal_error_info *info,
+                               vpx_codec_err_t                 error,
+                               const char                     *fmt,
+                               ...)
+{
+    va_list ap;
+
+    info->error_code = error;
+    info->has_detail = 0;
+
+    if (fmt)
+    {
+        size_t  sz = sizeof(info->detail);
+
+        info->has_detail = 1;
+        va_start(ap, fmt);
+        vsnprintf(info->detail, sz - 1, fmt, ap);
+        va_end(ap);
+        info->detail[sz-1] = '\0';
+    }
+
+    if (info->setjmp)
+        longjmp(info->jmp, info->error_code);
+}
+#endif
diff --git a/vpx_codec/src/vpx_codec.c b/vpx_codec/src/vpx_codec.c
new file mode 100644 (file)
index 0000000..6366416
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\file vpx_decoder.c
+ * \brief Provides the high level interface to wrap decoder algorithms.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "vpx_codec/internal/vpx_codec_internal.h"
+#include "vpx_version.h"
+
+#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
+
+int vpx_codec_version(void)
+{
+    return VERSION_PACKED;
+}
+
+
+const char *vpx_codec_version_str(void)
+{
+    return VERSION_STRING_NOSP;
+}
+
+
+const char *vpx_codec_version_extra_str(void)
+{
+    return VERSION_EXTRA;
+}
+
+
+const char *vpx_codec_iface_name(vpx_codec_iface_t *iface)
+{
+    return iface ? iface->name : "<invalid interface>";
+}
+
+const char *vpx_codec_err_to_string(vpx_codec_err_t  err)
+{
+    switch (err)
+    {
+    case VPX_CODEC_OK:
+        return "Success";
+    case VPX_CODEC_ERROR:
+        return "Unspecified internal error";
+    case VPX_CODEC_MEM_ERROR:
+        return "Memory allocation error";
+    case VPX_CODEC_ABI_MISMATCH:
+        return "ABI version mismatch";
+    case VPX_CODEC_INCAPABLE:
+        return "Codec does not implement requested capability";
+    case VPX_CODEC_UNSUP_BITSTREAM:
+        return "Bitstream not supported by this decoder";
+    case VPX_CODEC_UNSUP_FEATURE:
+        return "Bitstream required feature not supported by this decoder";
+    case VPX_CODEC_CORRUPT_FRAME:
+        return "Corrupt frame detected";
+    case  VPX_CODEC_INVALID_PARAM:
+        return "Invalid parameter";
+    case VPX_CODEC_LIST_END:
+        return "End of iterated list";
+    }
+
+    return "Unrecognized error code";
+}
+
+const char *vpx_codec_error(vpx_codec_ctx_t  *ctx)
+{
+    return (ctx) ? vpx_codec_err_to_string(ctx->err)
+           : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
+}
+
+const char *vpx_codec_error_detail(vpx_codec_ctx_t  *ctx)
+{
+    if (ctx && ctx->err)
+        return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;
+
+    return NULL;
+}
+
+
+vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
+                                       vpx_codec_iface_t    *iface,
+                                       vpx_codec_dec_cfg_t  *cfg,
+                                       vpx_codec_flags_t     flags,
+                                       int                   ver)
+{
+    vpx_codec_err_t res;
+
+    if (ver != VPX_DECODER_ABI_VERSION)
+        res = VPX_CODEC_ABI_MISMATCH;
+    else if (!ctx || !iface)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
+        res = VPX_CODEC_ABI_MISMATCH;
+    else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
+        res = VPX_CODEC_INCAPABLE;
+    else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
+        res = VPX_CODEC_INCAPABLE;
+    else
+    {
+        memset(ctx, 0, sizeof(*ctx));
+        ctx->iface = iface;
+        ctx->name = iface->name;
+        ctx->priv = NULL;
+        ctx->init_flags = flags;
+        ctx->config.dec = cfg;
+        res = VPX_CODEC_OK;
+
+        if (!(flags & VPX_CODEC_USE_XMA))
+        {
+            res = ctx->iface->init(ctx);
+
+            if (res)
+            {
+                ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
+                vpx_codec_destroy(ctx);
+            }
+
+            if (ctx->priv)
+                ctx->priv->iface = ctx->iface;
+        }
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv)
+        res = VPX_CODEC_ERROR;
+    else
+    {
+        if (ctx->priv->alg_priv)
+            ctx->iface->destroy(ctx->priv->alg_priv);
+
+        ctx->iface = NULL;
+        ctx->name = NULL;
+        ctx->priv = NULL;
+        res = VPX_CODEC_OK;
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface)
+{
+    return (iface) ? iface->caps : 0;
+}
+
+
+vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t  *ctx,
+                                   int               ctrl_id,
+                                   ...)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || !ctrl_id)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
+        res = VPX_CODEC_ERROR;
+    else
+    {
+        vpx_codec_ctrl_fn_map_t *entry;
+
+        res = VPX_CODEC_ERROR;
+
+        for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++)
+        {
+            if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
+            {
+                va_list  ap;
+
+                va_start(ap, ctrl_id);
+                res = entry->fn(ctx->priv->alg_priv, ctrl_id, ap);
+                va_end(ap);
+                break;
+            }
+        }
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
diff --git a/vpx_codec/src/vpx_decoder.c b/vpx_codec/src/vpx_decoder.c
new file mode 100644 (file)
index 0000000..7e8575f
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\file vpx_decoder.c
+ * \brief Provides the high level interface to wrap decoder algorithms.
+ *
+ */
+#include <stdlib.h>
+#include "vpx_codec/internal/vpx_codec_internal.h"
+
+#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
+
+vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t       *iface,
+        const uint8_t         *data,
+        unsigned int           data_sz,
+        vpx_codec_stream_info_t *si)
+{
+    vpx_codec_err_t res;
+
+    if (!iface || !data || !data_sz || !si
+        || si->sz < sizeof(vpx_codec_stream_info_t))
+        res = VPX_CODEC_INVALID_PARAM;
+    else
+    {
+        /* Set default/unknown values */
+        si->w = 0;
+        si->h = 0;
+
+        res = iface->dec.peek_si(data, data_sz, si);
+    }
+
+    return res;
+}
+
+
+vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t         *ctx,
+        vpx_codec_stream_info_t *si)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv)
+        res = VPX_CODEC_ERROR;
+    else
+    {
+        /* Set default/unknown values */
+        si->w = 0;
+        si->h = 0;
+
+        res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si);
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t    *ctx,
+                                 const uint8_t        *data,
+                                 unsigned int    data_sz,
+                                 void       *user_priv,
+                                 long        deadline)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || !data || !data_sz)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv)
+        res = VPX_CODEC_ERROR;
+
+#if CONFIG_EVAL_LIMIT
+    else if (ctx->priv->eval_counter >= 500)
+    {
+        ctx->priv->err_detail = "Evaluation limit exceeded.";
+        res = VPX_CODEC_ERROR;
+    }
+
+#endif
+    else
+    {
+        res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
+                                     user_priv, deadline);
+#if CONFIG_EVAL_LIMIT
+        ctx->priv->eval_counter++;
+#endif
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t  *ctx,
+                                 vpx_codec_iter_t *iter)
+{
+    vpx_image_t *img;
+
+    if (!ctx || !iter || !ctx->iface || !ctx->priv)
+        img = NULL;
+    else
+        img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
+
+    return img;
+}
+
+
+vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t             *ctx,
+        vpx_codec_put_frame_cb_fn_t  cb,
+        void                      *user_priv)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || !cb)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv
+             || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
+        res = VPX_CODEC_ERROR;
+    else
+    {
+        ctx->priv->dec.put_frame_cb.put_frame = cb;
+        ctx->priv->dec.put_frame_cb.user_priv = user_priv;
+        res = VPX_CODEC_OK;
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t             *ctx,
+        vpx_codec_put_slice_cb_fn_t  cb,
+        void                      *user_priv)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || !cb)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv
+             || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
+        res = VPX_CODEC_ERROR;
+    else
+    {
+        ctx->priv->dec.put_slice_cb.put_slice = cb;
+        ctx->priv->dec.put_slice_cb.user_priv = user_priv;
+        res = VPX_CODEC_OK;
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t                *ctx,
+                                      vpx_codec_mmap_t               *mmap,
+                                      vpx_codec_iter_t               *iter)
+{
+    vpx_codec_err_t res = VPX_CODEC_OK;
+
+    if (!ctx || !mmap || !iter || !ctx->iface)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
+        res = VPX_CODEC_ERROR;
+    else
+        res = ctx->iface->get_mmap(ctx, mmap, iter);
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t   *ctx,
+                                      vpx_codec_mmap_t  *mmap,
+                                      unsigned int     num_maps)
+{
+    vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
+
+    if (!ctx || !mmap || !ctx->iface)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
+        res = VPX_CODEC_ERROR;
+    else
+    {
+        unsigned int i;
+
+        for (i = 0; i < num_maps; i++, mmap++)
+        {
+            if (!mmap->base)
+                break;
+
+            /* Everything look ok, set the mmap in the decoder */
+            res = ctx->iface->set_mmap(ctx, mmap);
+
+            if (res)
+                break;
+        }
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
diff --git a/vpx_codec/src/vpx_decoder_compat.c b/vpx_codec/src/vpx_decoder_compat.c
new file mode 100644 (file)
index 0000000..d5b04ae
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\file vpx_decoder.c
+ * \brief Provides the high level interface to wrap decoder algorithms.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "vpx_codec/vpx_decoder.h"
+#include "vpx_codec/internal/vpx_codec_internal.h"
+
+#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
+
+const char *vpx_dec_iface_name(vpx_dec_iface_t *iface)
+{
+    return vpx_codec_iface_name((vpx_codec_iface_t *)iface);
+}
+
+const char *vpx_dec_err_to_string(vpx_dec_err_t  err)
+{
+    return vpx_codec_err_to_string(err);
+}
+
+const char *vpx_dec_error(vpx_dec_ctx_t  *ctx)
+{
+    return vpx_codec_error((vpx_codec_ctx_t *)ctx);
+}
+
+const char *vpx_dec_error_detail(vpx_dec_ctx_t  *ctx)
+{
+    return vpx_codec_error_detail((vpx_codec_ctx_t *)ctx);
+}
+
+
+vpx_dec_err_t vpx_dec_init_ver(vpx_dec_ctx_t    *ctx,
+                               vpx_dec_iface_t  *iface,
+                               int               ver)
+{
+    return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
+                                  (vpx_codec_iface_t *)iface,
+                                  NULL,
+                                  0,
+                                  ver);
+}
+
+
+vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx)
+{
+    return vpx_codec_destroy((vpx_codec_ctx_t *)ctx);
+}
+
+
+vpx_dec_caps_t vpx_dec_get_caps(vpx_dec_iface_t *iface)
+{
+    return vpx_codec_get_caps((vpx_codec_iface_t *)iface);
+}
+
+
+vpx_dec_err_t vpx_dec_peek_stream_info(vpx_dec_iface_t       *iface,
+                                       const uint8_t         *data,
+                                       unsigned int           data_sz,
+                                       vpx_dec_stream_info_t *si)
+{
+    return vpx_codec_peek_stream_info((vpx_codec_iface_t *)iface, data, data_sz,
+                                      (vpx_codec_stream_info_t *)si);
+}
+
+
+vpx_dec_err_t vpx_dec_get_stream_info(vpx_dec_ctx_t         *ctx,
+                                      vpx_dec_stream_info_t *si)
+{
+    return vpx_codec_get_stream_info((vpx_codec_ctx_t *)ctx,
+                                     (vpx_codec_stream_info_t *)si);
+}
+
+
+vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t  *ctx,
+                              int             ctrl_id,
+                              void           *data)
+{
+    return vpx_codec_control_((vpx_codec_ctx_t *)ctx, ctrl_id, data);
+}
+
+
+vpx_dec_err_t vpx_dec_decode(vpx_dec_ctx_t  *ctx,
+                             uint8_t        *data,
+                             unsigned int    data_sz,
+                             void       *user_priv,
+                             int         rel_pts)
+{
+    (void)rel_pts;
+    return vpx_codec_decode((vpx_codec_ctx_t *)ctx, data, data_sz, user_priv,
+                            0);
+}
+
+vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t  *ctx,
+                               vpx_dec_iter_t *iter)
+{
+    return vpx_codec_get_frame((vpx_codec_ctx_t *)ctx, iter);
+}
+
+
+vpx_dec_err_t vpx_dec_register_put_frame_cb(vpx_dec_ctx_t             *ctx,
+        vpx_dec_put_frame_cb_fn_t  cb,
+        void                      *user_priv)
+{
+    return vpx_codec_register_put_frame_cb((vpx_codec_ctx_t *)ctx, cb,
+                                           user_priv);
+}
+
+
+vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t             *ctx,
+        vpx_dec_put_slice_cb_fn_t  cb,
+        void                      *user_priv)
+{
+    return vpx_codec_register_put_slice_cb((vpx_codec_ctx_t *)ctx, cb,
+                                           user_priv);
+}
+
+
+vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t    *ctx,
+                                   vpx_dec_iface_t  *iface,
+                                   int               ver)
+{
+    return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
+                                  (vpx_codec_iface_t *)iface,
+                                  NULL,
+                                  VPX_CODEC_USE_XMA,
+                                  ver);
+}
+
+vpx_dec_err_t vpx_dec_get_mem_map(vpx_dec_ctx_t                *ctx_,
+                                  vpx_dec_mmap_t               *mmap,
+                                  const vpx_dec_stream_info_t  *si,
+                                  vpx_dec_iter_t               *iter)
+{
+    vpx_codec_ctx_t   *ctx = (vpx_codec_ctx_t *)ctx_;
+    vpx_dec_err_t      res = VPX_DEC_OK;
+
+    if (!ctx || !mmap || !si || !iter || !ctx->iface)
+        res = VPX_DEC_INVALID_PARAM;
+    else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
+        res = VPX_DEC_ERROR;
+    else
+    {
+        if (!ctx->config.dec)
+        {
+            ctx->config.dec = malloc(sizeof(vpx_codec_dec_cfg_t));
+            ctx->config.dec->w = si->w;
+            ctx->config.dec->h = si->h;
+        }
+
+        res = ctx->iface->get_mmap(ctx, mmap, iter);
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_dec_err_t vpx_dec_set_mem_map(vpx_dec_ctx_t   *ctx_,
+                                  vpx_dec_mmap_t  *mmap,
+                                  unsigned int     num_maps)
+{
+    vpx_codec_ctx_t   *ctx = (vpx_codec_ctx_t *)ctx_;
+    vpx_dec_err_t      res = VPX_DEC_MEM_ERROR;
+
+    if (!ctx || !mmap || !ctx->iface)
+        res = VPX_DEC_INVALID_PARAM;
+    else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
+        res = VPX_DEC_ERROR;
+    else
+    {
+        void         *save = (ctx->priv) ? NULL : ctx->config.dec;
+        unsigned int i;
+
+        for (i = 0; i < num_maps; i++, mmap++)
+        {
+            if (!mmap->base)
+                break;
+
+            /* Everything look ok, set the mmap in the decoder */
+            res = ctx->iface->set_mmap(ctx, mmap);
+
+            if (res)
+                break;
+        }
+
+        if (save) free(save);
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
diff --git a/vpx_codec/src/vpx_encoder.c b/vpx_codec/src/vpx_encoder.c
new file mode 100644 (file)
index 0000000..98ad8ba
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\file vpx_encoder.c
+ * \brief Provides the high level interface to wrap encoder algorithms.
+ *
+ */
+#include <limits.h>
+#include <string.h>
+#include "vpx_codec/internal/vpx_codec_internal.h"
+
+#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
+
+vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t      *ctx,
+                                       vpx_codec_iface_t    *iface,
+                                       vpx_codec_enc_cfg_t  *cfg,
+                                       vpx_codec_flags_t     flags,
+                                       int                   ver)
+{
+    vpx_codec_err_t res;
+
+    if (ver != VPX_ENCODER_ABI_VERSION)
+        res = VPX_CODEC_ABI_MISMATCH;
+    else if (!ctx || !iface || !cfg)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
+        res = VPX_CODEC_ABI_MISMATCH;
+    else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
+        res = VPX_CODEC_INCAPABLE;
+    else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
+        res = VPX_CODEC_INCAPABLE;
+    else if ((flags & VPX_CODEC_USE_PSNR)
+             && !(iface->caps & VPX_CODEC_CAP_PSNR))
+        res = VPX_CODEC_INCAPABLE;
+    else
+    {
+        ctx->iface = iface;
+        ctx->name = iface->name;
+        ctx->priv = NULL;
+        ctx->init_flags = flags;
+        ctx->config.enc = cfg;
+        res = ctx->iface->init(ctx);
+
+        if (res)
+        {
+            ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
+            vpx_codec_destroy(ctx);
+        }
+
+        if (ctx->priv)
+            ctx->priv->iface = ctx->iface;
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+
+vpx_codec_err_t  vpx_codec_enc_config_default(vpx_codec_iface_t    *iface,
+        vpx_codec_enc_cfg_t  *cfg,
+        unsigned int          usage)
+{
+    vpx_codec_err_t res;
+    vpx_codec_enc_cfg_map_t *map;
+
+    if (!iface || !cfg || usage > INT_MAX)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
+        res = VPX_CODEC_INCAPABLE;
+    else
+    {
+        res = VPX_CODEC_INVALID_PARAM;
+
+        for (map = iface->enc.cfg_maps; map->usage >= 0; map++)
+        {
+            if (map->usage == (int)usage)
+            {
+                *cfg = map->cfg;
+                cfg->g_usage = usage;
+                res = VPX_CODEC_OK;
+                break;
+            }
+        }
+    }
+
+    return res;
+}
+
+
+#if ARCH_X86 || ARCH_X86_64
+/* On X86, disable the x87 unit's internal 80 bit precision for better
+ * consistency with the SSE unit's 64 bit precision.
+ */
+#include "vpx_ports/x86.h"
+#define FLOATING_POINT_INIT() do {\
+        unsigned short x87_orig_mode = x87_set_double_precision();
+#define FLOATING_POINT_RESTORE() \
+    x87_set_control_word(x87_orig_mode); }while(0)
+
+
+#else
+static void FLOATING_POINT_INIT() {}
+static void FLOATING_POINT_RESTORE() {}
+#endif
+
+
+vpx_codec_err_t  vpx_codec_encode(vpx_codec_ctx_t            *ctx,
+                                  const vpx_image_t          *img,
+                                  vpx_codec_pts_t             pts,
+                                  unsigned long               duration,
+                                  vpx_enc_frame_flags_t       flags,
+                                  unsigned long               deadline)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || (img && !duration))
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!ctx->iface || !ctx->priv)
+        res = VPX_CODEC_ERROR;
+    else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
+        res = VPX_CODEC_INCAPABLE;
+
+#if CONFIG_EVAL_LIMIT
+    else if (ctx->priv->eval_counter >= 500)
+    {
+        ctx->priv->err_detail = "Evaluation limit exceeded.";
+        res = VPX_CODEC_ERROR;
+    }
+
+#endif
+    else
+    {
+        /* Execute in a normalized floating point environment, if the platform
+         * requires it.
+         */
+        FLOATING_POINT_INIT();
+        res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts,
+                                     duration, flags, deadline);
+        FLOATING_POINT_RESTORE();
+
+#if CONFIG_EVAL_LIMIT
+        ctx->priv->eval_counter++;
+#endif
+    }
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t   *ctx,
+        vpx_codec_iter_t  *iter)
+{
+    const vpx_codec_cx_pkt_t *pkt = NULL;
+
+    if (ctx)
+    {
+        if (!iter)
+            ctx->err = VPX_CODEC_INVALID_PARAM;
+        else if (!ctx->iface || !ctx->priv)
+            ctx->err = VPX_CODEC_ERROR;
+        else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
+            ctx->err = VPX_CODEC_INCAPABLE;
+        else
+            pkt = ctx->iface->enc.get_cx_data(ctx->priv->alg_priv, iter);
+    }
+
+    if (pkt && pkt->kind == VPX_CODEC_CX_FRAME_PKT)
+    {
+        /* If the application has specified a destination area for the
+         * compressed data, and the codec has not placed the data there,
+         * and it fits, copy it.
+         */
+        char *dst_buf = ctx->priv->enc.cx_data_dst_buf.buf;
+
+        if (dst_buf
+            && pkt->data.raw.buf != dst_buf
+            && pkt->data.raw.sz
+            + ctx->priv->enc.cx_data_pad_before
+            + ctx->priv->enc.cx_data_pad_after
+            <= ctx->priv->enc.cx_data_dst_buf.sz)
+        {
+            vpx_codec_cx_pkt_t *modified_pkt = &ctx->priv->enc.cx_data_pkt;
+
+            memcpy(dst_buf + ctx->priv->enc.cx_data_pad_before,
+                   pkt->data.raw.buf, pkt->data.raw.sz);
+            *modified_pkt = *pkt;
+            modified_pkt->data.raw.buf = dst_buf;
+            modified_pkt->data.raw.sz += ctx->priv->enc.cx_data_pad_before
+                                         + ctx->priv->enc.cx_data_pad_after;
+            pkt = modified_pkt;
+        }
+
+        if (dst_buf == pkt->data.raw.buf)
+        {
+            ctx->priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
+            ctx->priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
+        }
+    }
+
+    return pkt;
+}
+
+
+vpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t       *ctx,
+        const vpx_fixed_buf_t *buf,
+        unsigned int           pad_before,
+        unsigned int           pad_after)
+{
+    if (!ctx || !ctx->priv)
+        return VPX_CODEC_INVALID_PARAM;
+
+    if (buf)
+    {
+        ctx->priv->enc.cx_data_dst_buf = *buf;
+        ctx->priv->enc.cx_data_pad_before = pad_before;
+        ctx->priv->enc.cx_data_pad_after = pad_after;
+    }
+    else
+    {
+        ctx->priv->enc.cx_data_dst_buf.buf = NULL;
+        ctx->priv->enc.cx_data_dst_buf.sz = 0;
+        ctx->priv->enc.cx_data_pad_before = 0;
+        ctx->priv->enc.cx_data_pad_after = 0;
+    }
+
+    return VPX_CODEC_OK;
+}
+
+
+const vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t   *ctx)
+{
+    vpx_image_t *img = NULL;
+
+    if (ctx)
+    {
+        if (!ctx->iface || !ctx->priv)
+            ctx->err = VPX_CODEC_ERROR;
+        else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
+            ctx->err = VPX_CODEC_INCAPABLE;
+        else if (!ctx->iface->enc.get_preview)
+            ctx->err = VPX_CODEC_INCAPABLE;
+        else
+            img = ctx->iface->enc.get_preview(ctx->priv->alg_priv);
+    }
+
+    return img;
+}
+
+
+vpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t   *ctx)
+{
+    vpx_fixed_buf_t *buf = NULL;
+
+    if (ctx)
+    {
+        if (!ctx->iface || !ctx->priv)
+            ctx->err = VPX_CODEC_ERROR;
+        else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
+            ctx->err = VPX_CODEC_INCAPABLE;
+        else if (!ctx->iface->enc.get_glob_hdrs)
+            ctx->err = VPX_CODEC_INCAPABLE;
+        else
+            buf = ctx->iface->enc.get_glob_hdrs(ctx->priv->alg_priv);
+    }
+
+    return buf;
+}
+
+
+vpx_codec_err_t  vpx_codec_enc_config_set(vpx_codec_ctx_t            *ctx,
+        const vpx_codec_enc_cfg_t  *cfg)
+{
+    vpx_codec_err_t res;
+
+    if (!ctx || !ctx->iface || !ctx->priv || !cfg)
+        res = VPX_CODEC_INVALID_PARAM;
+    else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
+        res = VPX_CODEC_INCAPABLE;
+    else
+        res = ctx->iface->enc.cfg_set(ctx->priv->alg_priv, cfg);
+
+    return SAVE_STATUS(ctx, res);
+}
+
+
+int vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *list,
+                           const struct vpx_codec_cx_pkt *pkt)
+{
+    if (list->cnt < list->max)
+    {
+        list->pkts[list->cnt++] = *pkt;
+        return 0;
+    }
+
+    return 1;
+}
+
+
+const vpx_codec_cx_pkt_t *vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
+        vpx_codec_iter_t           *iter)
+{
+    const vpx_codec_cx_pkt_t *pkt;
+
+    if (!(*iter))
+    {
+        *iter = list->pkts;
+    }
+
+    pkt = (const void *) * iter;
+
+    if (pkt - list->pkts < list->cnt)
+        *iter = pkt + 1;
+    else
+        pkt = NULL;
+
+    return pkt;
+}
diff --git a/vpx_codec/src/vpx_image.c b/vpx_codec/src/vpx_image.c
new file mode 100644 (file)
index 0000000..8a16e58
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include "vpx_codec/vpx_image.h"
+
+static vpx_image_t *img_alloc_helper(vpx_image_t  *img,
+                                     img_fmt_t     fmt,
+                                     unsigned int  d_w,
+                                     unsigned int  d_h,
+                                     unsigned int  stride_align,
+                                     unsigned char      *img_data)
+{
+
+    unsigned int  h, w, s, xcs, ycs, bps;
+    int           align;
+
+    /* Treat align==0 like align==1 */
+    if (!stride_align)
+        stride_align = 1;
+
+    /* Validate alignment (must be power of 2) */
+    if (stride_align & (stride_align - 1))
+        goto fail;
+
+    /* Get sample size for this format */
+    switch (fmt)
+    {
+    case IMG_FMT_RGB32:
+    case IMG_FMT_RGB32_LE:
+    case IMG_FMT_ARGB:
+    case IMG_FMT_ARGB_LE:
+        bps = 32;
+        break;
+    case IMG_FMT_RGB24:
+    case IMG_FMT_BGR24:
+        bps = 24;
+        break;
+    case IMG_FMT_RGB565:
+    case IMG_FMT_RGB565_LE:
+    case IMG_FMT_RGB555:
+    case IMG_FMT_RGB555_LE:
+    case IMG_FMT_UYVY:
+    case IMG_FMT_YUY2:
+    case IMG_FMT_YVYU:
+        bps = 16;
+        break;
+    case IMG_FMT_I420:
+    case IMG_FMT_YV12:
+    case IMG_FMT_VPXI420:
+    case IMG_FMT_VPXYV12:
+        bps = 12;
+        break;
+    default:
+        bps = 16;
+        break;
+    }
+
+    /* Get chroma shift values for this format */
+    switch (fmt)
+    {
+    case IMG_FMT_I420:
+    case IMG_FMT_YV12:
+    case IMG_FMT_VPXI420:
+    case IMG_FMT_VPXYV12:
+        xcs = 1;
+        break;
+    default:
+        xcs = 0;
+        break;
+    }
+
+    switch (fmt)
+    {
+    case IMG_FMT_I420:
+    case IMG_FMT_YV12:
+    case IMG_FMT_VPXI420:
+    case IMG_FMT_VPXYV12:
+        ycs = 1;
+        break;
+    default:
+        ycs = 0;
+        break;
+    }
+
+    /* Calculate storage sizes given the chroma subsampling */
+    align = (1 << xcs) - 1;
+    w = (d_w + align) & ~align;
+    align = (1 << ycs) - 1;
+    h = (d_h + align) & ~align;
+    s = (fmt & IMG_FMT_PLANAR) ? w : bps * w / 8;
+    s = (s + stride_align - 1) & ~(stride_align - 1);
+
+    /* Allocate the new image */
+    if (!img)
+    {
+        img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t));
+
+        if (!img)
+            goto fail;
+
+        img->self_allocd = 1;
+    }
+    else
+    {
+        memset(img, 0, sizeof(vpx_image_t));
+    }
+
+    img->img_data = img_data;
+
+    if (!img_data)
+    {
+        img->img_data = malloc((fmt & IMG_FMT_PLANAR) ? h * w * bps / 8 : h * s);
+        img->img_data_owner = 1;
+    }
+
+    if (!img->img_data)
+        goto fail;
+
+    img->fmt = fmt;
+    img->w = w;
+    img->h = h;
+    img->x_chroma_shift = xcs;
+    img->y_chroma_shift = ycs;
+    img->bps = bps;
+
+    /* Calculate strides */
+    img->stride[PLANE_Y] = img->stride[PLANE_ALPHA] = s;
+    img->stride[PLANE_U] = img->stride[PLANE_V] = s >> xcs;
+
+    /* Default viewport to entire image */
+    if (!vpx_img_set_rect(img, 0, 0, d_w, d_h))
+        return img;
+
+fail:
+    vpx_img_free(img);
+    return NULL;
+}
+
+vpx_image_t *vpx_img_alloc(vpx_image_t  *img,
+                           img_fmt_t     fmt,
+                           unsigned int  d_w,
+                           unsigned int  d_h,
+                           unsigned int  stride_align)
+{
+    return img_alloc_helper(img, fmt, d_w, d_h, stride_align, NULL);
+}
+
+vpx_image_t *vpx_img_wrap(vpx_image_t  *img,
+                          img_fmt_t     fmt,
+                          unsigned int  d_w,
+                          unsigned int  d_h,
+                          unsigned int  stride_align,
+                          unsigned char       *img_data)
+{
+    return img_alloc_helper(img, fmt, d_w, d_h, stride_align, img_data);
+}
+
+int vpx_img_set_rect(vpx_image_t  *img,
+                     unsigned int  x,
+                     unsigned int  y,
+                     unsigned int  w,
+                     unsigned int  h)
+{
+    unsigned char      *data;
+
+    if (x + w <= img->w && y + h <= img->h)
+    {
+        img->d_w = w;
+        img->d_h = h;
+
+        /* Calculate plane pointers */
+        if (!(img->fmt & IMG_FMT_PLANAR))
+        {
+            img->planes[PLANE_PACKED] =
+                img->img_data + x * img->bps / 8 + y * img->stride[PLANE_PACKED];
+        }
+        else
+        {
+            data = img->img_data;
+
+            if (img->fmt & IMG_FMT_HAS_ALPHA)
+            {
+                img->planes[PLANE_ALPHA] =
+                    data + x + y * img->stride[PLANE_ALPHA];
+                data += img->h * img->stride[PLANE_ALPHA];
+            }
+
+            img->planes[PLANE_Y] = data + x + y * img->stride[PLANE_Y];
+            data += img->h * img->stride[PLANE_Y];
+
+            if (!(img->fmt & IMG_FMT_UV_FLIP))
+            {
+                img->planes[PLANE_U] = data
+                                       + (x >> img->x_chroma_shift)
+                                       + (y >> img->y_chroma_shift) * img->stride[PLANE_U];
+                data += (img->h >> img->y_chroma_shift) * img->stride[PLANE_U];
+                img->planes[PLANE_V] = data
+                                       + (x >> img->x_chroma_shift)
+                                       + (y >> img->y_chroma_shift) * img->stride[PLANE_V];
+            }
+            else
+            {
+                img->planes[PLANE_V] = data
+                                       + (x >> img->x_chroma_shift)
+                                       + (y >> img->y_chroma_shift) * img->stride[PLANE_V];
+                data += (img->h >> img->y_chroma_shift) * img->stride[PLANE_V];
+                img->planes[PLANE_U] = data
+                                       + (x >> img->x_chroma_shift)
+                                       + (y >> img->y_chroma_shift) * img->stride[PLANE_U];
+            }
+        }
+
+        return 0;
+    }
+
+    return -1;
+}
+
+void vpx_img_flip(vpx_image_t *img)
+{
+    /* Note: In the calculation pointer adjustment calculation, we want the
+     * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
+     * standard indicates that if the adjustment parameter is unsigned, the
+     * stride parameter will be promoted to unsigned, causing errors when
+     * the lhs is a larger type than the rhs.
+     */
+    img->planes[PLANE_Y] += (signed)(img->d_h - 1) * img->stride[PLANE_Y];
+    img->stride[PLANE_Y] = -img->stride[PLANE_Y];
+
+    img->planes[PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
+                            * img->stride[PLANE_U];
+    img->stride[PLANE_U] = -img->stride[PLANE_U];
+
+    img->planes[PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
+                            * img->stride[PLANE_V];
+    img->stride[PLANE_V] = -img->stride[PLANE_V];
+
+    img->planes[PLANE_ALPHA] += (signed)(img->d_h - 1) * img->stride[PLANE_ALPHA];
+    img->stride[PLANE_ALPHA] = -img->stride[PLANE_ALPHA];
+}
+
+void vpx_img_free(vpx_image_t *img)
+{
+    if (img)
+    {
+        if (img->img_data && img->img_data_owner)
+            free(img->img_data);
+
+        if (img->self_allocd)
+            free(img);
+    }
+}
diff --git a/vpx_codec/vpx_codec.h b/vpx_codec/vpx_codec.h
new file mode 100644 (file)
index 0000000..e2a79f9
--- /dev/null
@@ -0,0 +1,560 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\defgroup codec Common Algorithm Interface
+ * This abstraction allows applications to easily support multiple video
+ * formats with minimal code duplication. This section describes the interface
+ * common to all codecs (both encoders and decoders).
+ * @{
+ */
+
+/*!\file vpx_codec.h
+ * \brief Describes the codec algorithm interface to applications.
+ *
+ * This file describes the interface between an application and a
+ * video codec algorithm.
+ *
+ * An application instantiates a specific codec instance by using
+ * vpx_codec_init() and a pointer to the algorithm's interface structure:
+ *     <pre>
+ *     my_app.c:
+ *       extern vpx_codec_iface_t my_codec;
+ *       {
+ *           vpx_codec_ctx_t algo;
+ *           res = vpx_codec_init(&algo, &my_codec);
+ *       }
+ *     </pre>
+ *
+ * Once initialized, the instance is manged using other functions from
+ * the vpx_codec_* family.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef VPX_CODEC_H
+#define VPX_CODEC_H
+#ifdef HAVE_CONFIG_H
+#  include "vpx_config.h"
+#endif
+#if defined(HAVE_VPX_PORTS) && HAVE_VPX_PORTS
+#  include "vpx_ports/vpx_integer.h"
+#else
+#  include "vpx_integer.h"
+#endif
+#include "vpx_image.h"
+
+    /*!\brief Decorator indicating a function is deprecated */
+#ifndef DEPRECATED
+#if defined(__GNUC__) && __GNUC__
+#define DEPRECATED          __attribute__ ((deprecated))
+#define DECLSPEC_DEPRECATED /**< \copydoc #DEPRECATED */
+#elif defined(_MSC_VER)
+#define DEPRECATED
+#define DECLSPEC_DEPRECATED __declspec(deprecated) /**< \copydoc #DEPRECATED */
+#else
+#define DEPRECATED
+#define DECLSPEC_DEPRECATED /**< \copydoc #DEPRECATED */
+#endif
+#endif
+
+    /*!\brief Decorator indicating a function is potentially unused */
+#ifdef UNUSED
+#elif __GNUC__
+#define UNUSED __attribute__ ((unused));
+#else
+#define UNUSED
+#endif
+
+    /*!\brief Current ABI version number
+     *
+     * \internal
+     * If this file is altered in any way that changes the ABI, this value
+     * must be bumped.  Examples include, but are not limited to, changing
+     * types, removing or reassigning enums, adding/removing/rearranging
+     * fields to structures
+     */
+#define VPX_CODEC_ABI_VERSION (2 + VPX_IMAGE_ABI_VERSION) /**<\hideinitializer*/
+
+    /*!\brief Algorithm return codes */
+    typedef enum {
+        /*!\brief Operation completed without error */
+        VPX_CODEC_OK,
+
+        /*!\brief Unspecified error */
+        VPX_CODEC_ERROR,
+
+        /*!\brief Memory operation failed */
+        VPX_CODEC_MEM_ERROR,
+
+        /*!\brief ABI version mismatch */
+        VPX_CODEC_ABI_MISMATCH,
+
+        /*!\brief Algorithm does not have required capability */
+        VPX_CODEC_INCAPABLE,
+
+        /*!\brief The given bitstream is not supported.
+         *
+         * The bitstream was unable to be parsed at the highest level. The decoder
+         * is unable to proceed. This error \ref SHOULD be treated as fatal to the
+         * stream. */
+        VPX_CODEC_UNSUP_BITSTREAM,
+
+        /*!\brief Encoded bitstream uses an unsupported feature
+         *
+         * The decoder does not implement a feature required by the encoder. This
+         * return code should only be used for features that prevent future
+         * pictures from being properly decoded. This error \ref MAY be treated as
+         * fatal to the stream or \ref MAY be treated as fatal to the current GOP.
+         */
+        VPX_CODEC_UNSUP_FEATURE,
+
+        /*!\brief The coded data for this stream is corrupt or incomplete
+         *
+         * There was a problem decoding the current frame.  This return code
+         * should only be used for failures that prevent future pictures from
+         * being properly decoded. This error \ref MAY be treated as fatal to the
+         * stream or \ref MAY be treated as fatal to the current GOP. If decoding
+         * is continued for the current GOP, artifacts may be present.
+         */
+        VPX_CODEC_CORRUPT_FRAME,
+
+        /*!\brief An application-supplied parameter is not valid.
+         *
+         */
+        VPX_CODEC_INVALID_PARAM,
+
+        /*!\brief An iterator reached the end of list.
+         *
+         */
+        VPX_CODEC_LIST_END,
+
+    }
+    vpx_codec_err_t;
+
+
+    /*! \brief Codec capabilities bitfield
+     *
+     *  Each codec advertises the capabilities it supports as part of its
+     *  ::vpx_codec_iface_t interface structure. Capabilities are extra interfaces
+     *  or functionality, and are not required to be supported.
+     *
+     *  The available flags are specified by VPX_CODEC_CAP_* defines.
+     */
+    typedef long vpx_codec_caps_t;
+#define VPX_CODEC_CAP_DECODER 0x1 /**< Is a decoder */
+#define VPX_CODEC_CAP_ENCODER 0x2 /**< Is an encoder */
+#define VPX_CODEC_CAP_XMA     0x4 /**< Supports e_xternal Memory Allocation */
+
+
+    /*! \brief Initialization-time Feature Enabling
+     *
+     *  Certain codec features must be known at initialization time, to allow for
+     *  proper memory allocation.
+     *
+     *  The available flags are specified by VPX_CODEC_USE_* defines.
+     */
+    typedef long vpx_codec_flags_t;
+#define VPX_CODEC_USE_XMA 0x00000001    /**< Use e_xternal Memory Allocation mode */
+
+
+    /*!\brief Codec interface structure.
+     *
+     * Contains function pointers and other data private to the codec
+     * implementation. This structure is opaque to the application.
+     */
+    typedef const struct vpx_codec_iface vpx_codec_iface_t;
+
+
+    /*!\brief Codec private data structure.
+     *
+     * Contains data private to the codec implementation. This structure is opaque
+     * to the application.
+     */
+    typedef       struct vpx_codec_priv  vpx_codec_priv_t;
+
+
+    /*!\brief Iterator
+     *
+     * Opaque storage used for iterating over lists.
+     */
+    typedef const void *vpx_codec_iter_t;
+
+
+    /*!\brief Codec context structure
+     *
+     * All codecs \ref MUST support this context structure fully. In general,
+     * this data should be considered private to the codec algorithm, and
+     * not be manipulated or examined by the calling application. Applications
+     * may reference the 'name' member to get a printable description of the
+     * algorithm.
+     */
+    typedef struct
+    {
+        const char              *name;        /**< Printable interface name */
+        vpx_codec_iface_t       *iface;       /**< Interface pointers */
+        vpx_codec_err_t          err;         /**< Last returned error */
+        const char              *err_detail;  /**< Detailed info, if available */
+        vpx_codec_flags_t        init_flags;  /**< Flags passed at init time */
+        union
+        {
+            struct vpx_codec_dec_cfg  *dec;   /**< Decoder Configuration Pointer */
+            struct vpx_codec_enc_cfg  *enc;   /**< Encoder Configuration Pointer */
+            void                      *raw;
+        }                        config;      /**< Configuration pointer aliasing union */
+        vpx_codec_priv_t        *priv;        /**< Algorithm private storage */
+    } vpx_codec_ctx_t;
+
+
+    /*
+     * Library Version Number Interface
+     *
+     * For example, see the following sample return values:
+     *     vpx_codec_version()           (1<<16 | 2<<8 | 3)
+     *     vpx_codec_version_str()       "v1.2.3-rc1-16-gec6a1ba"
+     *     vpx_codec_version_extra_str() "rc1-16-gec6a1ba"
+     */
+
+    /*!\brief Return the version information (as an integer)
+     *
+     * Returns a packed encoding of the library version number. This will only include
+     * the major.minor.patch component of the version number. Note that this encoded
+     * value should be accessed through the macros provided, as the encoding may change
+     * in the future.
+     *
+     */
+    int vpx_codec_version(void);
+#define VPX_VERSION_MAJOR(v) ((v>>16)&0xff) /**< extract major from packed version */
+#define VPX_VERSION_MINOR(v) ((v>>8)&0xff)  /**< extract minor from packed version */
+#define VPX_VERSION_PATCH(v) ((v>>0)&0xff)  /**< extract patch from packed version */
+
+    /*!\brief Return the version major number */
+#define vpx_codec_version_major() ((vpx_codec_version()>>16)&0xff)
+
+    /*!\brief Return the version minr number */
+#define vpx_codec_version_minor() ((vpx_codec_version()>>8)&0xff)
+
+    /*!\brief Return the version patch number */
+#define vpx_codec_version_patch() ((vpx_codec_version()>>0)&0xff)
+
+
+    /*!\brief Return the version information (as a string)
+     *
+     * Returns a printable string containing the full library version number. This may
+     * contain additional text following the three digit version number, as to indicate
+     * release candidates, prerelease versions, etc.
+     *
+     */
+    const char *vpx_codec_version_str(void);
+
+
+    /*!\brief Return the version information (as a string)
+     *
+     * Returns a printable "extra string". This is the component of the string returned
+     * by vpx_codec_version_str() following the three digit version number.
+     *
+     */
+    const char *vpx_codec_version_extra_str(void);
+
+
+    /*!\brief Return the build configuration
+     *
+     * Returns a printable string containing an encoded version of the build
+     * configuration. This may be useful to vpx support.
+     *
+     */
+    const char *vpx_codec_build_config(void);
+
+
+    /*!\brief Return the name for a given interface
+     *
+     * Returns a human readable string for name of the given codec interface.
+     *
+     * \param[in]    iface     Interface pointer
+     *
+     */
+    const char *vpx_codec_iface_name(vpx_codec_iface_t *iface);
+
+
+    /*!\brief Convert error number to printable string
+     *
+     * Returns a human readable string for the last error returned by the
+     * algorithm. The returned error will be one line and will not contain
+     * any newline characters.
+     *
+     *
+     * \param[in]    err     Error number.
+     *
+     */
+    const char *vpx_codec_err_to_string(vpx_codec_err_t  err);
+
+
+    /*!\brief Retrieve error synopsis for codec context
+     *
+     * Returns a human readable string for the last error returned by the
+     * algorithm. The returned error will be one line and will not contain
+     * any newline characters.
+     *
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     *
+     */
+    const char *vpx_codec_error(vpx_codec_ctx_t  *ctx);
+
+
+    /*!\brief Retrieve detailed error information for codec context
+     *
+     * Returns a human readable string providing detailed information about
+     * the last error.
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     *
+     * \retval NULL
+     *     No detailed information is available.
+     */
+    const char *vpx_codec_error_detail(vpx_codec_ctx_t  *ctx);
+
+
+    /* REQUIRED FUNCTIONS
+     *
+     * The following functions are required to be implemented for all codecs.
+     * They represent the base case functionality expected of all codecs.
+     */
+
+    /*!\brief Destroy a codec instance
+     *
+     * Destroys a codec context, freeing any associated memory buffers.
+     *
+     * \param[in] ctx   Pointer to this instance's context
+     *
+     * \retval #VPX_CODEC_OK
+     *     The codec algorithm initialized.
+     * \retval #VPX_CODEC_MEM_ERROR
+     *     Memory allocation failed.
+     */
+    vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx);
+
+
+    /*!\brief Get the capabilities of an algorithm.
+     *
+     * Retrieves the capabliities bitfield from the algorithm's interface.
+     *
+     * \param[in] iface   Pointer to the alogrithm interface
+     *
+     */
+    vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface);
+
+
+    /*!\brief Control algorithm
+     *
+     * This function is used to exchange algorithm specific data with the codec
+     * instance. This can be used to implement features specific to a particular
+     * algorithm.
+     *
+     * This wrapper function dispatches the request to the helper function
+     * associated with the given ctrl_id. It tries to call this function
+     * transparantly, but will return #VPX_CODEC_ERROR if the request could not
+     * be dispatched.
+     *
+     * Note that this function should not be used directly. Call the
+     * #vpx_codec_control wrapper macro instead.
+     *
+     * \param[in]     ctx              Pointer to this instance's context
+     * \param[in]     ctrl_id          Algorithm specific control identifier
+     *
+     * \retval #VPX_CODEC_OK
+     *     The control request was processed.
+     * \retval #VPX_CODEC_ERROR
+     *     The control request was not processed.
+     * \retval #VPX_CODEC_INVALID_PARAM
+     *     The data was not valid.
+     */
+    vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t  *ctx,
+                                       int               ctrl_id,
+                                       ...);
+#if defined(VPX_DISABLE_CTRL_TYPECHECKS) && VPX_DISABLE_CTRL_TYPECHECKS
+#    define vpx_codec_control(ctx,id,data) vpx_codec_control_(ctx,id,data)
+#    define VPX_CTRL_USE_TYPE(id, typ)
+#    define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ)
+#    define VPX_CTRL_VOID(id, typ)
+
+#else
+    /*!\brief vpx_codec_control wrapper macro
+     *
+     * This macro allows for type safe conversions across the variadic parameter
+     * to vpx_codec_control_().
+     *
+     * \internal
+     * It works by dispatching the call to the control function through a wrapper
+     * function named with the id parameter.
+     */
+#    define vpx_codec_control(ctx,id,data) vpx_codec_control_##id(ctx,id,data)\
+    /**<\hideinitializer*/
+
+
+    /*!\brief vpx_codec_control type definition macro
+     *
+     * This macro allows for type safe conversions across the variadic parameter
+     * to vpx_codec_control_(). It defines the type of the argument for a given
+     * control identifier.
+     *
+     * \internal
+     * It defines a static function with
+     * the correctly typed arguments as a wrapper to the type-unsafe internal
+     * function.
+     */
+#    define VPX_CTRL_USE_TYPE(id, typ) \
+    static vpx_codec_err_t \
+    vpx_codec_control_##id(vpx_codec_ctx_t*, int, typ) UNUSED;\
+    \
+    static vpx_codec_err_t \
+    vpx_codec_control_##id(vpx_codec_ctx_t  *ctx, int ctrl_id, typ data) {\
+        return vpx_codec_control_(ctx, ctrl_id, data);\
+    } /**<\hideinitializer*/
+
+
+    /*!\brief vpx_codec_control deprecated type definition macro
+     *
+     * Like #VPX_CTRL_USE_TYPE, but indicates that the specified control is
+     * deprecated and should not be used. Consult the documentation for your
+     * codec for more information.
+     *
+     * \internal
+     * It defines a static function with the correctly typed arguments as a
+     * wrapper to the type-unsafe internal function.
+     */
+#    define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \
+    DECLSPEC_DEPRECATED static vpx_codec_err_t \
+    vpx_codec_control_##id(vpx_codec_ctx_t*, int, typ) DEPRECATED UNUSED;\
+    \
+    DECLSPEC_DEPRECATED static vpx_codec_err_t \
+    vpx_codec_control_##id(vpx_codec_ctx_t  *ctx, int ctrl_id, typ data) {\
+        return vpx_codec_control_(ctx, ctrl_id, data);\
+    } /**<\hideinitializer*/
+
+
+    /*!\brief vpx_codec_control void type definition macro
+     *
+     * This macro allows for type safe conversions across the variadic parameter
+     * to vpx_codec_control_(). It indicates that a given control identifier takes
+     * no argument.
+     *
+     * \internal
+     * It defines a static function without a data argument as a wrapper to the
+     * type-unsafe internal function.
+     */
+#    define VPX_CTRL_VOID(id) \
+    static vpx_codec_err_t \
+    vpx_codec_control_##id(vpx_codec_ctx_t*, int) UNUSED;\
+    \
+    static vpx_codec_err_t \
+    vpx_codec_control_##id(vpx_codec_ctx_t  *ctx, int ctrl_id) {\
+        return vpx_codec_control_(ctx, ctrl_id);\
+    } /**<\hideinitializer*/
+
+
+#endif
+
+
+    /*!\defgroup cap_xma External Memory Allocation Functions
+     *
+     * The following functions are required to be implemented for all codecs
+     * that advertise the VPX_CODEC_CAP_XMA capability. Calling these functions
+     * for codecs that don't advertise this capability will result in an error
+     * code being returned, usually VPX_CODEC_INCAPABLE
+     * @{
+     */
+
+
+    /*!\brief Memory Map Entry
+     *
+     * This structure is used to contain the properties of a memory segment. It
+     * is populated by the codec in the request phase, and by the calling
+     * application once the requested allocation has been performed.
+     */
+    typedef struct vpx_codec_mmap
+    {
+        /*
+         * The following members are set by the codec when requesting a segment
+         */
+        unsigned int   id;     /**< identifier for the segment's contents */
+        unsigned long  sz;     /**< size of the segment, in bytes */
+        unsigned int   align;  /**< required alignment of the segment, in bytes */
+        unsigned int   flags;  /**< bitfield containing segment properties */
+#define VPX_CODEC_MEM_ZERO     0x1  /**< Segment must be zeroed by allocation */
+#define VPX_CODEC_MEM_WRONLY   0x2  /**< Segment need not be readable */
+#define VPX_CODEC_MEM_FAST     0x4  /**< Place in fast memory, if available */
+
+        /* The following members are to be filled in by the allocation function */
+        void          *base;   /**< pointer to the allocated segment */
+        void (*dtor)(struct vpx_codec_mmap *map);         /**< destructor to call */
+        void          *priv;   /**< allocator private storage */
+    } vpx_codec_mmap_t; /**< alias for struct vpx_codec_mmap */
+
+
+    /*!\brief Iterate over the list of segments to allocate.
+     *
+     * Iterates over a list of the segments to allocate. The iterator storage
+     * should be initialized to NULL to start the iteration. Iteration is complete
+     * when this function returns VPX_CODEC_LIST_END. The amount of memory needed to
+     * allocate is dependant upon the size of the encoded stream. In cases where the
+     * stream is not available at allocation time, a fixed size must be requested.
+     * The codec will not be able to operate on streams larger than the size used at
+     * allocation time.
+     *
+     * \param[in]      ctx     Pointer to this instance's context.
+     * \param[out]     mmap    Pointer to the memory map entry to populate.
+     * \param[in,out]  iter    Iterator storage, initialized to NULL
+     *
+     * \retval #VPX_CODEC_OK
+     *     The memory map entry was populated.
+     * \retval #VPX_CODEC_ERROR
+     *     Codec does not support XMA mode.
+     * \retval #VPX_CODEC_MEM_ERROR
+     *     Unable to determine segment size from stream info.
+     */
+    vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t                *ctx,
+                                          vpx_codec_mmap_t               *mmap,
+                                          vpx_codec_iter_t               *iter);
+
+
+    /*!\brief Identify allocated segments to codec instance
+     *
+     * Stores a list of allocated segments in the codec. Segments \ref MUST be
+     * passed in the order they are read from vpx_codec_get_mem_map(), but may be
+     * passed in groups of any size. Segments \ref MUST be set only once. The
+     * allocation function \ref MUST ensure that the vpx_codec_mmap_t::base member
+     * is non-NULL. If the segment requires cleanup handling (eg, calling free()
+     * or close()) then the vpx_codec_mmap_t::dtor member \ref MUST be populated.
+     *
+     * \param[in]      ctx     Pointer to this instance's context.
+     * \param[in]      mmaps   Pointer to the first memory map entry in the list.
+     * \param[in]      num_maps  Number of entries being set at this time
+     *
+     * \retval #VPX_CODEC_OK
+     *     The segment was stored in the codec context.
+     * \retval #VPX_CODEC_INCAPABLE
+     *     Codec does not support XMA mode.
+     * \retval #VPX_CODEC_MEM_ERROR
+     *     Segment base address was not set, or segment was already stored.
+
+     */
+    vpx_codec_err_t  vpx_codec_set_mem_map(vpx_codec_ctx_t   *ctx,
+                                           vpx_codec_mmap_t  *mmaps,
+                                           unsigned int       num_maps);
+
+    /*!@} - end defgroup cap_xma*/
+    /*!@} - end defgroup codec*/
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
diff --git a/vpx_codec/vpx_codec.mk b/vpx_codec/vpx_codec.mk
new file mode 100644 (file)
index 0000000..75fbeea
--- /dev/null
@@ -0,0 +1,26 @@
+##
+##  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+##
+##  Use of this source code is governed by a BSD-style license and patent
+##  grant that can be found in the LICENSE file in the root of the source
+##  tree. All contributing project authors may be found in the AUTHORS
+##  file in the root of the source tree.
+##
+
+
+API_EXPORTS += exports
+
+API_SRCS-yes += internal/vpx_codec_internal.h
+API_SRCS-yes += vpx_codec.h
+API_SRCS-yes += vpx_codec.mk
+API_SRCS-yes += vpx_codec_impl_top.h
+API_SRCS-yes += vpx_codec_impl_bottom.h
+API_SRCS-yes += vpx_decoder.h
+API_SRCS-yes += vpx_decoder_compat.h
+API_SRCS-yes += vpx_encoder.h
+API_SRCS-yes += vpx_image.h
+API_SRCS-yes += src/vpx_codec.c
+API_SRCS-yes += src/vpx_decoder.c
+API_SRCS-yes += src/vpx_decoder_compat.c
+API_SRCS-yes += src/vpx_image.c
+API_SRCS-yes += src/vpx_encoder.c
diff --git a/vpx_codec/vpx_codec_impl_bottom.h b/vpx_codec/vpx_codec_impl_bottom.h
new file mode 100644 (file)
index 0000000..c52654c
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+ * This file is to be included at the bottom of the header files defining the
+ * interface to individual codecs and contains matching blocks to those defined
+ * in vpx_codec_impl_top.h
+ */
+#ifdef __cplusplus
+}
+#endif
diff --git a/vpx_codec/vpx_codec_impl_top.h b/vpx_codec/vpx_codec_impl_top.h
new file mode 100644 (file)
index 0000000..f73809a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+ * This file is to be included at the top of the header files defining the
+ * interface to individual codecs and contains various workarounds common
+ * to all codec implementations.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
diff --git a/vpx_codec/vpx_decoder.h b/vpx_codec/vpx_decoder.h
new file mode 100644 (file)
index 0000000..5e4968d
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\defgroup decoder Decoder Algorithm Interface
+ * \ingroup codec
+ * This abstraction allows applications using this decoder to easily support
+ * multiple video formats with minimal code duplication. This section describes
+ * the interface common to all decoders.
+ * @{
+ */
+
+/*!\file vpx_decoder.h
+ * \brief Describes the decoder algorithm interface to applications.
+ *
+ * This file describes the interface between an application and a
+ * video decoder algorithm.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef VPX_DECODER_H
+#define VPX_DECODER_H
+#include "vpx_codec.h"
+
+    /*!\brief Current ABI version number
+     *
+     * \internal
+     * If this file is altered in any way that changes the ABI, this value
+     * must be bumped.  Examples include, but are not limited to, changing
+     * types, removing or reassigning enums, adding/removing/rearranging
+     * fields to structures
+     */
+#define VPX_DECODER_ABI_VERSION (2 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
+
+    /*! \brief Decoder capabilities bitfield
+     *
+     *  Each decoder advertises the capabilities it supports as part of its
+     *  ::vpx_codec_iface_t interface structure. Capabilities are extra interfaces
+     *  or functionality, and are not required to be supported by a decoder.
+     *
+     *  The available flags are specifiedby VPX_CODEC_CAP_* defines.
+     */
+#define VPX_CODEC_CAP_PUT_SLICE  0x10000 /**< Will issue put_slice callbacks */
+#define VPX_CODEC_CAP_PUT_FRAME  0x20000 /**< Will issue put_frame callbacks */
+#define VPX_CODEC_CAP_POSTPROC   0x40000 /**< Can postprocess decoded frame */
+
+    /*! \brief Initialization-time Feature Enabling
+     *
+     *  Certain codec features must be known at initialization time, to allow for
+     *  proper memory allocation.
+     *
+     *  The available flags are specified by VPX_CODEC_USE_* defines.
+     */
+#define VPX_CODEC_USE_POSTPROC   0x10000 /**< Postprocess decoded frame */
+
+    /*!\brief Stream properties
+     *
+     * This structure is used to query or set properties of the decoded
+     * stream. Algorithms may extend this structure with data specific
+     * to their bitstream by setting the sz member appropriately.
+     */
+    typedef struct
+    {
+        unsigned int sz;     /**< Size of this structure */
+        unsigned int w;      /**< Width (or 0 for unknown/default) */
+        unsigned int h;      /**< Height (or 0 for unknown/default) */
+        unsigned int is_kf;  /**< Current frame is a keyframe */
+    } vpx_codec_stream_info_t;
+
+    /* REQUIRED FUNCTIONS
+     *
+     * The following functions are required to be implemented for all decoders.
+     * They represent the base case functionality expected of all decoders.
+     */
+
+
+    /*!\brief Initialization Configurations
+     *
+     * This structure is used to pass init time configuration options to the
+     * decoder.
+     */
+    typedef struct vpx_codec_dec_cfg
+    {
+        unsigned int threads; /**< Maximum number of threads to use, default 1 */
+        unsigned int w;      /**< Width */
+        unsigned int h;      /**< Height */
+    } vpx_codec_dec_cfg_t; /**< alias for struct vpx_codec_dec_cfg */
+
+
+    /*!\brief Initialize a decoder instance
+     *
+     * Initializes a decoder context using the given interface. Applications
+     * should call the vpx_codec_dec_init convenience macro instead of this
+     * function directly, to ensure that the ABI version number parameter
+     * is properly initialized.
+     *
+     * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the flags
+     * parameter), the storage pointed to by the cfg parameter must be
+     * kept readable and stable until all memory maps have been set.
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     * \param[in]    iface   Pointer to the alogrithm interface to use.
+     * \param[in]    cfg     Configuration to use, if known. May be NULL.
+     * \param[in]    flags   Bitfield of VPX_CODEC_USE_* flags
+     * \param[in]    ver     ABI version number. Must be set to
+     *                       VPX_DECODER_ABI_VERSION
+     * \retval #VPX_CODEC_OK
+     *     The decoder algorithm initialized.
+     * \retval #VPX_CODEC_MEM_ERROR
+     *     Memory allocation failed.
+     */
+    vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
+                                           vpx_codec_iface_t    *iface,
+                                           vpx_codec_dec_cfg_t  *cfg,
+                                           vpx_codec_flags_t     flags,
+                                           int                   ver);
+
+    /*!\brief Convenience macro for vpx_codec_dec_init_ver()
+     *
+     * Ensures the ABI version parameter is properly set.
+     */
+#define vpx_codec_dec_init(ctx, iface, cfg, flags) \
+    vpx_codec_dec_init_ver(ctx, iface, cfg, flags, VPX_DECODER_ABI_VERSION)
+
+
+    /*!\brief Parse stream info from a buffer
+     *
+     * Performs high level parsing of the bitstream. Construction of a decoder
+     * context is not necessary. Can be used to determine if the bitstream is
+     * of the proper format, and to extract information from the stream.
+     *
+     * \param[in]      iface   Pointer to the alogrithm interface
+     * \param[in]      data    Pointer to a block of data to parse
+     * \param[in]      data_sz Size of the data buffer
+     * \param[in,out]  si      Pointer to stream info to update. The size member
+     *                         \ref MUST be properly initialized, but \ref MAY be
+     *                         clobbered by the algorithm. This parameter \ref MAY
+     *                         be NULL.
+     *
+     * \retval #VPX_CODEC_OK
+     *     Bitstream is parsable and stream information updated
+     */
+    vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t       *iface,
+            const uint8_t           *data,
+            unsigned int             data_sz,
+            vpx_codec_stream_info_t *si);
+
+
+    /*!\brief Return information about the current stream.
+     *
+     * Returns information about the stream that has been parsed during decoding.
+     *
+     * \param[in]      ctx     Pointer to this instance's context
+     * \param[in,out]  si      Pointer to stream info to update. The size member
+     *                         \ref MUST be properly initialized, but \ref MAY be
+     *                         clobbered by the algorithm. This parameter \ref MAY
+     *                         be NULL.
+     *
+     * \retval #VPX_CODEC_OK
+     *     Bitstream is parsable and stream information updated
+     */
+    vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t         *ctx,
+            vpx_codec_stream_info_t *si);
+
+
+    /*!\brief Decode data
+     *
+     * Processes a buffer of coded data. If the processing results in a new
+     * decoded frame becoming available, PUT_SLICE and PUT_FRAME events may be
+     * generated, as appropriate. Encoded data \ref MUST be passed in DTS (decode
+     * time stamp) order. Frames produced will always be in PTS (presentation
+     * time stamp) order.
+     *
+     * \param[in] ctx          Pointer to this instance's context
+     * \param[in] data         Pointer to this block of new coded data. If
+     *                         NULL, a VPX_CODEC_CB_PUT_FRAME event is posted
+     *                         for the previously decoded frame.
+     * \param[in] data_sz      Size of the coded data, in bytes.
+     * \param[in] user_priv    Application specific data to associate with
+     *                         this frame.
+     * \param[in] deadline     Soft deadline the decoder should attempt to meet,
+     *                         in us. Set to zero for unlimited.
+     *
+     * \return Returns #VPX_CODEC_OK if the coded data was processed completely
+     *         and future pictures can be decoded without error. Otherwise,
+     *         see the descriptions of the other error codes in ::vpx_codec_err_t
+     *         for recoverability capabilities.
+     */
+    vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t    *ctx,
+                                     const uint8_t        *data,
+                                     unsigned int            data_sz,
+                                     void               *user_priv,
+                                     long                deadline);
+
+
+    /*!\brief Decoded frames iterator
+     *
+     * Iterates over a list of the frames available for display. The iterator
+     * storage should be initialized to NULL to start the iteration. Iteration is
+     * complete when this function returns NULL.
+     *
+     * The list of available frames becomes valid upon completion of the
+     * vpx_codec_decode call, and remains valid until the next call to vpx_codec_decode.
+     *
+     * \param[in]     ctx      Pointer to this instance's context
+     * \param[in,out] iter     Iterator storage, initialized to NULL
+     *
+     * \return Returns a pointer to an image, if one is ready for display. Frames
+     *         produced will always be in PTS (presentation time stamp) order.
+     */
+    vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t  *ctx,
+                                     vpx_codec_iter_t *iter);
+
+
+    /*!\defgroup cap_put_frame Frame-Based Decoding Functions
+     *
+     * The following functions are required to be implemented for all decoders
+     * that advertise the VPX_CODEC_CAP_PUT_FRAME capability. Calling these functions
+     * for codecs that don't advertise this capability will result in an error
+     * code being returned, usually VPX_CODEC_ERROR
+     * @{
+     */
+
+    /*!\brief put frame callback prototype
+     *
+     * This callback is invoked by the decoder to notify the application of
+     * the availability of decoded image data.
+     */
+    typedef void (*vpx_codec_put_frame_cb_fn_t)(void        *user_priv,
+            const vpx_image_t *img);
+
+
+    /*!\brief Register for notification of frame completion.
+     *
+     * Registers a given function to be called when a decoded frame is
+     * available.
+     *
+     * \param[in] ctx          Pointer to this instance's context
+     * \param[in] cb           Pointer to the callback function
+     * \param[in] user_priv    User's private data
+     *
+     * \retval #VPX_CODEC_OK
+     *     Callback successfully registered.
+     * \retval #VPX_CODEC_ERROR
+     *     Decoder context not initialized, or algorithm not capable of
+     *     posting slice completion.
+     */
+    vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t             *ctx,
+            vpx_codec_put_frame_cb_fn_t  cb,
+            void                        *user_priv);
+
+
+    /*!@} - end defgroup cap_put_frame */
+
+    /*!\defgroup cap_put_slice Slice-Based Decoding Functions
+     *
+     * The following functions are required to be implemented for all decoders
+     * that advertise the VPX_CODEC_CAP_PUT_SLICE capability. Calling these functions
+     * for codecs that don't advertise this capability will result in an error
+     * code being returned, usually VPX_CODEC_ERROR
+     * @{
+     */
+
+    /*!\brief put slice callback prototype
+     *
+     * This callback is invoked by the decoder to notify the application of
+     * the availability of partially decoded image data. The
+     */
+    typedef void (*vpx_codec_put_slice_cb_fn_t)(void         *user_priv,
+            const vpx_image_t      *img,
+            const vpx_image_rect_t *valid,
+            const vpx_image_rect_t *update);
+
+
+    /*!\brief Register for notification of slice completion.
+     *
+     * Registers a given function to be called when a decoded slice is
+     * available.
+     *
+     * \param[in] ctx          Pointer to this instance's context
+     * \param[in] cb           Pointer to the callback function
+     * \param[in] user_priv    User's private data
+     *
+     * \retval #VPX_CODEC_OK
+     *     Callback successfully registered.
+     * \retval #VPX_CODEC_ERROR
+     *     Decoder context not initialized, or algorithm not capable of
+     *     posting slice completion.
+     */
+    vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t             *ctx,
+            vpx_codec_put_slice_cb_fn_t  cb,
+            void                        *user_priv);
+
+
+    /*!@} - end defgroup cap_put_slice*/
+
+    /*!@} - end defgroup decoder*/
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT
+#include "vpx_decoder_compat.h"
+#endif
diff --git a/vpx_codec/vpx_decoder_compat.h b/vpx_codec/vpx_decoder_compat.h
new file mode 100644 (file)
index 0000000..25bb5eb
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\defgroup decoder Common Decoder Algorithm Interface
+ * This abstraction allows applications using this decoder to easily support
+ * multiple video formats with minimal code duplication. This section describes
+ * the interface common to all codecs.
+ * @{
+ */
+
+/*!\file vpx_decoder_compat.h
+ * \brief Provides a compatibility layer between version 1 and 2 of this API.
+ *
+ * This interface has been deprecated. Only existing code should make use
+ * of this interface, and therefore, it is only thinly documented. Existing
+ * code should be ported to the vpx_codec_* API.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef VPX_DECODER_COMPAT_H
+#define VPX_DECODER_COMPAT_H
+
+    /*!\brief Decoder algorithm return codes */
+    typedef enum {
+        /*!\brief Operation completed without error */
+        VPX_DEC_OK = VPX_CODEC_OK,
+
+        /*!\brief Unspecified error */
+        VPX_DEC_ERROR = VPX_CODEC_ERROR,
+
+        /*!\brief Memory operation failed */
+        VPX_DEC_MEM_ERROR = VPX_CODEC_MEM_ERROR,
+
+        /*!\brief ABI version mismatch */
+        VPX_DEC_ABI_MISMATCH = VPX_CODEC_ABI_MISMATCH,
+
+        /*!\brief The given bitstream is not supported.
+         *
+         * The bitstream was unable to be parsed at the highest level. The decoder
+         * is unable to proceed. This error \ref SHOULD be treated as fatal to the
+         * stream. */
+        VPX_DEC_UNSUP_BITSTREAM = VPX_CODEC_UNSUP_BITSTREAM,
+
+        /*!\brief Encoded bitstream uses an unsupported feature
+         *
+         * The decoder does not implement a feature required by the encoder. This
+         * return code should only be used for features that prevent future
+         * pictures from being properly decoded. This error \ref MAY be treated as
+         * fatal to the stream or \ref MAY be treated as fatal to the current GOP.
+         */
+        VPX_DEC_UNSUP_FEATURE = VPX_CODEC_UNSUP_FEATURE,
+
+        /*!\brief The coded data for this stream is corrupt or incomplete
+         *
+         * There was a problem decoding the current frame.  This return code
+         * should only be used for failures that prevent future pictures from
+         * being properly decoded. This error \ref MAY be treated as fatal to the
+         * stream or \ref MAY be treated as fatal to the current GOP. If decoding
+         * is continued for the current GOP, artifacts may be present.
+         */
+        VPX_DEC_CORRUPT_FRAME = VPX_CODEC_CORRUPT_FRAME,
+
+        /*!\brief An application-supplied parameter is not valid.
+         *
+         */
+        VPX_DEC_INVALID_PARAM = VPX_CODEC_INVALID_PARAM,
+
+        /*!\brief An iterator reached the end of list.
+         *
+         */
+        VPX_DEC_LIST_END = VPX_CODEC_LIST_END,
+
+    }
+    vpx_dec_err_t;
+
+    /*! \brief Decoder capabilities bitfield
+     *
+     *  Each decoder advertises the capabilities it supports as part of its
+     *  ::vpx_dec_iface_t interface structure. Capabilities are extra interfaces
+     *  or functionality, and are not required to be supported by a decoder.
+     *
+     *  The available flags are specifiedby VPX_DEC_CAP_* defines.
+     */
+    typedef int vpx_dec_caps_t;
+#define VPX_DEC_CAP_PUT_SLICE  0x0001 /**< Will issue put_slice callbacks */
+#define VPX_DEC_CAP_PUT_FRAME  0x0002 /**< Will issue put_frame callbacks */
+#define VPX_DEC_CAP_XMA        0x0004 /**< Supports e_xternal Memory Allocation */
+
+    /*!\brief Stream properties
+     *
+     * This structure is used to query or set properties of the decoded
+     * stream. Algorithms may extend this structure with data specific
+     * to their bitstream by setting the sz member appropriately.
+     */
+#if 1
+    typedef vpx_codec_stream_info_t vpx_dec_stream_info_t;
+#else
+    typedef struct
+    {
+        unsigned int sz;     /**< Size of this structure */
+        unsigned int w;      /**< Width (or 0 for unknown/default) */
+        unsigned int h;      /**< Height (or 0 for unknown/default) */
+        unsigned int is_kf;  /**< Current frame is a keyframe */
+    } vpx_dec_stream_info_t;
+#endif
+
+
+    /*!\brief Decoder interface structure.
+     *
+     * Contains function pointers and other data private to the decoder
+     * implementation. This structure is opaque to the application.
+     */
+    typedef const struct vpx_codec_iface vpx_dec_iface_t;
+    typedef       struct vpx_codec_priv  vpx_dec_priv_t;
+
+    /*!\brief Iterator
+     *
+     * Opaque storage used for iterating over lists.
+     */
+    typedef vpx_codec_iter_t vpx_dec_iter_t;
+
+    /*!\brief Decoder context structure
+     *
+     * All decoders \ref MUST support this context structure fully. In general,
+     * this data should be considered private to the decoder algorithm, and
+     * not be manipulated or examined by the calling application. Applications
+     * may reference the 'name' member to get a printable description of the
+     * algorithm.
+     */
+#if 1
+    typedef vpx_codec_ctx_t vpx_dec_ctx_t;
+#else
+    typedef struct
+    {
+        const char            *name;        /**< Printable interface name */
+        vpx_dec_iface_t       *iface;       /**< Interface pointers */
+        vpx_dec_err_t          err;         /**< Last returned error */
+        vpx_dec_priv_t        *priv;        /**< Algorithm private storage */
+    } vpx_dec_ctx_t;
+#endif
+
+
+    /*!\brief Return the build configuration
+     *
+     * Returns a printable string containing an encoded version of the build
+     * configuration. This may be useful to vpx support.
+     *
+     */
+    const char *vpx_dec_build_config(void) DEPRECATED;
+
+    /*!\brief Return the name for a given interface
+     *
+     * Returns a human readable string for name of the given decoder interface.
+     *
+     * \param[in]    iface     Interface pointer
+     *
+     */
+    const char *vpx_dec_iface_name(vpx_dec_iface_t *iface) DEPRECATED;
+
+
+    /*!\brief Convert error number to printable string
+     *
+     * Returns a human readable string for the last error returned by the
+     * algorithm. The returned error will be one line and will not contain
+     * any newline characters.
+     *
+     *
+     * \param[in]    err     Error number.
+     *
+     */
+    const char *vpx_dec_err_to_string(vpx_dec_err_t  err) DEPRECATED;
+
+
+    /*!\brief Retrieve error synopsis for decoder context
+     *
+     * Returns a human readable string for the last error returned by the
+     * algorithm. The returned error will be one line and will not contain
+     * any newline characters.
+     *
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     *
+     */
+    const char *vpx_dec_error(vpx_dec_ctx_t  *ctx) DEPRECATED;
+
+
+    /*!\brief Retrieve detailed error information for decoder context
+     *
+     * Returns a human readable string providing detailed information about
+     * the last error.
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     *
+     * \retval NULL
+     *     No detailed information is available.
+     */
+    const char *vpx_dec_error_detail(vpx_dec_ctx_t  *ctx) DEPRECATED;
+
+
+    /* REQUIRED FUNCTIONS
+     *
+     * The following functions are required to be implemented for all decoders.
+     * They represent the base case functionality expected of all decoders.
+     */
+
+
+    /*!\brief Initialize a decoder instance
+     *
+     * Initializes a decoder context using the given interface. Applications
+     * should call the vpx_dec_init convenience macro instead of this
+     * function directly, to ensure that the ABI version number parameter
+     * is properly initialized.
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     * \param[in]    iface   Pointer to the alogrithm interface to use.
+     * \param[in]    ver     ABI version number. Must be set to
+     *                       VPX_DECODER_ABI_VERSION
+     * \retval #VPX_DEC_OK
+     *     The decoder algorithm initialized.
+     * \retval #VPX_DEC_MEM_ERROR
+     *     Memory allocation failed.
+     */
+    vpx_dec_err_t vpx_dec_init_ver(vpx_dec_ctx_t    *ctx,
+                                   vpx_dec_iface_t  *iface,
+                                   int               ver) DEPRECATED;
+#define vpx_dec_init(ctx, iface) \
+    vpx_dec_init_ver(ctx, iface, VPX_DECODER_ABI_VERSION)
+
+
+    /*!\brief Destroy a decoder instance
+     *
+     * Destroys a decoder context, freeing any associated memory buffers.
+     *
+     * \param[in] ctx   Pointer to this instance's context
+     *
+     * \retval #VPX_DEC_OK
+     *     The decoder algorithm initialized.
+     * \retval #VPX_DEC_MEM_ERROR
+     *     Memory allocation failed.
+     */
+    vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx) DEPRECATED;
+
+
+    /*!\brief Get the capabilities of an algorithm.
+     *
+     * Retrieves the capabliities bitfield from the algorithm's interface.
+     *
+     * \param[in] iface   Pointer to the alogrithm interface
+     *
+     */
+    vpx_dec_caps_t vpx_dec_get_caps(vpx_dec_iface_t *iface) DEPRECATED;
+
+
+    /*!\brief Parse stream info from a buffer
+     *
+     * Performs high level parsing of the bitstream. Construction of a decoder
+     * context is not necessary. Can be used to determine if the bitstream is
+     * of the proper format, and to extract information from the stream.
+     *
+     * \param[in]      iface   Pointer to the alogrithm interface
+     * \param[in]      data    Pointer to a block of data to parse
+     * \param[in]      data_sz Size of the data buffer
+     * \param[in,out]  si      Pointer to stream info to update. The size member
+     *                         \ref MUST be properly initialized, but \ref MAY be
+     *                         clobbered by the algorithm. This parameter \ref MAY
+     *                         be NULL.
+     *
+     * \retval #VPX_DEC_OK
+     *     Bitstream is parsable and stream information updated
+     */
+    vpx_dec_err_t vpx_dec_peek_stream_info(vpx_dec_iface_t       *iface,
+                                           const uint8_t         *data,
+                                           unsigned int           data_sz,
+                                           vpx_dec_stream_info_t *si) DEPRECATED;
+
+
+    /*!\brief Return information about the current stream.
+     *
+     * Returns information about the stream that has been parsed during decoding.
+     *
+     * \param[in]      ctx     Pointer to this instance's context
+     * \param[in,out]  si      Pointer to stream info to update. The size member
+     *                         \ref MUST be properly initialized, but \ref MAY be
+     *                         clobbered by the algorithm. This parameter \ref MAY
+     *                         be NULL.
+     *
+     * \retval #VPX_DEC_OK
+     *     Bitstream is parsable and stream information updated
+     */
+    vpx_dec_err_t vpx_dec_get_stream_info(vpx_dec_ctx_t         *ctx,
+                                          vpx_dec_stream_info_t *si) DEPRECATED;
+
+
+    /*!\brief Control algorithm
+     *
+     * This function is used to exchange algorithm specific data with the decoder
+     * instance. This can be used to implement features specific to a particular
+     * algorithm.
+     *
+     * This wrapper function dispatches the request to the helper function
+     * associated with the given ctrl_id. It tries to call this function
+     * transparantly, but will return #VPX_DEC_ERROR if the request could not
+     * be dispatched.
+     *
+     * \param[in]     ctx              Pointer to this instance's context
+     * \param[in]     ctrl_id          Algorithm specific control identifier
+     * \param[in,out] data             Data to exchange with algorithm instance.
+     *
+     * \retval #VPX_DEC_OK
+     *     The control request was processed.
+     * \retval #VPX_DEC_ERROR
+     *     The control request was not processed.
+     * \retval #VPX_DEC_INVALID_PARAM
+     *     The data was not valid.
+     */
+    vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t  *ctx,
+                                  int             ctrl_id,
+                                  void           *data) DEPRECATED;
+
+    /*!\brief Decode data
+     *
+     * Processes a buffer of coded data. If the processing results in a new
+     * decoded frame becoming available, #VPX_DEC_CB_PUT_SLICE and
+     * #VPX_DEC_CB_PUT_FRAME events may be generated, as appropriate. Encoded data
+     * \ref MUST be passed in DTS (decode time stamp) order. Frames produced will
+     * always be in PTS (presentation time stamp) order.
+     *
+     * \param[in] ctx          Pointer to this instance's context
+     * \param[in] data         Pointer to this block of new coded data. If
+     *                         NULL, a VPX_DEC_CB_PUT_FRAME event is posted
+     *                         for the previously decoded frame.
+     * \param[in] data_sz      Size of the coded data, in bytes.
+     * \param[in] user_priv    Application specific data to associate with
+     *                         this frame.
+     * \param[in] rel_pts      PTS relative to the previous frame, in us. If
+     *                         unknown or unavailable, set to zero.
+     *
+     * \return Returns #VPX_DEC_OK if the coded data was processed completely
+     *         and future pictures can be decoded without error. Otherwise,
+     *         see the descriptions of the other error codes in ::vpx_dec_err_t
+     *         for recoverability capabilities.
+     */
+    vpx_dec_err_t vpx_dec_decode(vpx_dec_ctx_t  *ctx,
+                                 uint8_t        *data,
+                                 unsigned int    data_sz,
+                                 void       *user_priv,
+                                 int         rel_pts) DEPRECATED;
+
+
+    /*!\brief Decoded frames iterator
+     *
+     * Iterates over a list of the frames available for display. The iterator
+     * storage should be initialized to NULL to start the iteration. Iteration is
+     * complete when this function returns NULL.
+     *
+     * The list of available frames becomes valid upon completion of the
+     * vpx_dec_decode call, and remains valid until the next call to vpx_dec_decode.
+     *
+     * \param[in]     ctx      Pointer to this instance's context
+     * \param[in out] iter     Iterator storage, initialized to NULL
+     *
+     * \return Returns a pointer to an image, if one is ready for display. Frames
+     *         produced will always be in PTS (presentation time stamp) order.
+     */
+    vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t  *ctx,
+                                   vpx_dec_iter_t *iter) DEPRECATED;
+
+
+    /*!\defgroup cap_put_frame Frame-Based Decoding Functions
+     *
+     * The following functions are required to be implemented for all decoders
+     * that advertise the VPX_DEC_CAP_PUT_FRAME capability. Calling these functions
+     * for codecs that don't advertise this capability will result in an error
+     * code being returned, usually VPX_DEC_ERROR
+     * @{
+     */
+
+    /*!\brief put frame callback prototype
+     *
+     * This callback is invoked by the decoder to notify the application of
+     * the availability of decoded image data.
+     */
+    typedef void (*vpx_dec_put_frame_cb_fn_t)(void          *user_priv,
+            const vpx_image_t *img);
+
+
+    /*!\brief Register for notification of frame completion.
+     *
+     * Registers a given function to be called when a decoded frame is
+     * available.
+     *
+     * \param[in] ctx          Pointer to this instance's context
+     * \param[in] cb           Pointer to the callback function
+     * \param[in] user_priv    User's private data
+     *
+     * \retval #VPX_DEC_OK
+     *     Callback successfully registered.
+     * \retval #VPX_DEC_ERROR
+     *     Decoder context not initialized, or algorithm not capable of
+     *     posting slice completion.
+     */
+    vpx_dec_err_t vpx_dec_register_put_frame_cb(vpx_dec_ctx_t             *ctx,
+            vpx_dec_put_frame_cb_fn_t  cb,
+            void                      *user_priv) DEPRECATED;
+
+
+    /*!@} - end defgroup cap_put_frame */
+
+    /*!\defgroup cap_put_slice Slice-Based Decoding Functions
+     *
+     * The following functions are required to be implemented for all decoders
+     * that advertise the VPX_DEC_CAP_PUT_SLICE capability. Calling these functions
+     * for codecs that don't advertise this capability will result in an error
+     * code being returned, usually VPX_DEC_ERROR
+     * @{
+     */
+
+    /*!\brief put slice callback prototype
+     *
+     * This callback is invoked by the decoder to notify the application of
+     * the availability of partially decoded image data. The
+     */
+    typedef void (*vpx_dec_put_slice_cb_fn_t)(void           *user_priv,
+            const vpx_image_t      *img,
+            const vpx_image_rect_t *valid,
+            const vpx_image_rect_t *update);
+
+
+    /*!\brief Register for notification of slice completion.
+     *
+     * Registers a given function to be called when a decoded slice is
+     * available.
+     *
+     * \param[in] ctx          Pointer to this instance's context
+     * \param[in] cb           Pointer to the callback function
+     * \param[in] user_priv    User's private data
+     *
+     * \retval #VPX_DEC_OK
+     *     Callback successfully registered.
+     * \retval #VPX_DEC_ERROR
+     *     Decoder context not initialized, or algorithm not capable of
+     *     posting slice completion.
+     */
+    vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t             *ctx,
+            vpx_dec_put_slice_cb_fn_t  cb,
+            void                      *user_priv) DEPRECATED;
+
+
+    /*!@} - end defgroup cap_put_slice*/
+
+    /*!\defgroup cap_xma External Memory Allocation Functions
+     *
+     * The following functions are required to be implemented for all decoders
+     * that advertise the VPX_DEC_CAP_XMA capability. Calling these functions
+     * for codecs that don't advertise this capability will result in an error
+     * code being returned, usually VPX_DEC_ERROR
+     * @{
+     */
+
+    /*!\brief Memory Map Entry
+     *
+     * This structure is used to contain the properties of a memory segment. It
+     * is populated by the decoder in the request phase, and by the calling
+     * application once the requested allocation has been performed.
+     */
+#if 1
+#define VPX_DEC_MEM_ZERO     0x1  /**< Segment must be zeroed by allocation */
+#define VPX_DEC_MEM_WRONLY   0x2  /**< Segment need not be readable */
+#define VPX_DEC_MEM_FAST     0x4  /**< Place in fast memory, if available */
+    typedef struct vpx_codec_mmap vpx_dec_mmap_t;
+#else
+    typedef struct vpx_dec_mmap
+    {
+        /*
+         * The following members are set by the codec when requesting a segment
+         */
+        unsigned int   id;     /**< identifier for the segment's contents */
+        unsigned long  sz;     /**< size of the segment, in bytes */
+        unsigned int   align;  /**< required alignment of the segment, in bytes */
+        unsigned int   flags;  /**< bitfield containing segment properties */
+#define VPX_DEC_MEM_ZERO     0x1  /**< Segment must be zeroed by allocation */
+#define VPX_DEC_MEM_WRONLY   0x2  /**< Segment need not be readable */
+#define VPX_DEC_MEM_FAST     0x4  /**< Place in fast memory, if available */
+
+        /* The following members are to be filled in by the allocation function */
+        void          *base;   /**< pointer to the allocated segment */
+        void (*dtor)(struct vpx_dec_mmap *map);         /**< destructor to call */
+        void          *priv;   /**< allocator private storage */
+    } vpx_dec_mmap_t;
+#endif
+
+    /*!\brief Initialize a decoder instance in external allocation mode
+     *
+     * Initializes a decoder context using the given interface. Applications
+     * should call the vpx_dec_xma_init convenience macro instead of this
+     * function directly, to ensure that the ABI version number parameter
+     * is properly initialized.
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     * \param[in]    iface   Pointer to the alogrithm interface to use.
+     * \param[in]    ver     ABI version number. Must be set to
+     *                       VPX_DECODER_ABI_VERSION
+     * \retval #VPX_DEC_OK
+     *     The decoder algorithm initialized.
+     * \retval #VPX_DEC_ERROR
+     *     Decoder does not support XMA mode.
+     */
+    vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t    *ctx,
+                                       vpx_dec_iface_t  *iface,
+                                       int               ver) DEPRECATED;
+#define vpx_dec_xma_init(ctx, iface) \
+    vpx_dec_xma_init_ver(ctx, iface, VPX_DECODER_ABI_VERSION)
+
+
+    /*!\brief Iterate over the list of segments to allocate.
+     *
+     * Iterates over a list of the segments to allocate. The iterator storage
+     * should be initialized to NULL to start the iteration. Iteration is complete
+     * when this function returns VPX_DEC_LIST_END. The amount of memory needed to
+     * allocate is dependant upon the size of the encoded stream. This means that
+     * the stream info structure must be known at allocation time. It can be
+     * populated with the vpx_dec_peek_stream_info() function. In cases where the
+     * stream to be decoded is not available at allocation time, a fixed size must
+     * be requested. The decoder will not be able to decode streams larger than
+     * the size used at allocation time.
+     *
+     * \param[in]      ctx     Pointer to this instance's context.
+     * \param[out]     mmap    Pointer to the memory map entry to populate.
+     * \param[in]      si      Pointer to the stream info.
+     * \param[in out]  iter    Iterator storage, initialized to NULL
+     *
+     * \retval #VPX_DEC_OK
+     *     The memory map entry was populated.
+     * \retval #VPX_DEC_ERROR
+     *     Decoder does not support XMA mode.
+     * \retval #VPX_DEC_MEM_ERROR
+     *     Unable to determine segment size from stream info.
+     */
+    vpx_dec_err_t vpx_dec_get_mem_map(vpx_dec_ctx_t                *ctx,
+                                      vpx_dec_mmap_t               *mmap,
+                                      const vpx_dec_stream_info_t  *si,
+                                      vpx_dec_iter_t               *iter) DEPRECATED;
+
+
+    /*!\brief Identify allocated segments to decoder instance
+     *
+     * Stores a list of allocated segments in the decoder. Segments \ref MUST be
+     * passed in the order they are read from vpx_dec_get_mem_map(), but may be
+     * passed in groups of any size. Segments \ref MUST be set only once. The
+     * allocation function \ref MUST ensure that the vpx_dec_mmap_t::base member
+     * is non-NULL. If the segment requires cleanup handling (eg, calling free()
+     * or close()) then the vpx_dec_mmap_t::dtor member \ref MUST be populated.
+     *
+     * \param[in]      ctx     Pointer to this instance's context.
+     * \param[in]      mmaps   Pointer to the first memory map entry in the list.
+     * \param[in]      num_maps  Number of entries being set at this time
+     *
+     * \retval #VPX_DEC_OK
+     *     The segment was stored in the decoder context.
+     * \retval #VPX_DEC_ERROR
+     *     Decoder does not support XMA mode.
+     * \retval #VPX_DEC_MEM_ERROR
+     *     Segment base address was not set, or segment was already stored.
+
+     */
+    vpx_dec_err_t  vpx_dec_set_mem_map(vpx_dec_ctx_t   *ctx,
+                                       vpx_dec_mmap_t  *mmaps,
+                                       unsigned int     num_maps) DEPRECATED;
+
+    /*!@} - end defgroup cap_xma*/
+    /*!@} - end defgroup decoder*/
+
+
+#endif
+#ifdef __cplusplus
+}
+#endif
diff --git a/vpx_codec/vpx_encoder.h b/vpx_codec/vpx_encoder.h
new file mode 100644 (file)
index 0000000..67393be
--- /dev/null
@@ -0,0 +1,792 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\defgroup encoder Encoder Algorithm Interface
+ * \ingroup codec
+ * This abstraction allows applications using this encoder to easily support
+ * multiple video formats with minimal code duplication. This section describes
+ * the interface common to all encoders.
+ * @{
+ */
+
+/*!\file vpx_encoder.h
+ * \brief Describes the encoder algorithm interface to applications.
+ *
+ * This file describes the interface between an application and a
+ * video encoder algorithm.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef VPX_ENCODER_H
+#define VPX_ENCODER_H
+#include "vpx_codec.h"
+
+
+    /*!\brief Current ABI version number
+     *
+     * \internal
+     * If this file is altered in any way that changes the ABI, this value
+     * must be bumped.  Examples include, but are not limited to, changing
+     * types, removing or reassigning enums, adding/removing/rearranging
+     * fields to structures
+     */
+#define VPX_ENCODER_ABI_VERSION (2 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/
+
+
+    /*! \brief Encoder capabilities bitfield
+     *
+     *  Each encoder advertises the capabilities it supports as part of its
+     *  ::vpx_codec_iface_t interface structure. Capabilities are extra
+     *  interfaces or functionality, and are not required to be supported
+     *  by an encoder.
+     *
+     *  The available flags are specifiedby VPX_CODEC_CAP_* defines.
+     */
+#define VPX_CODEC_CAP_PSNR  0x10000 /**< Can issue PSNR packets */
+
+
+    /*! \brief Initialization-time Feature Enabling
+     *
+     *  Certain codec features must be known at initialization time, to allow
+     *  for proper memory allocation.
+     *
+     *  The available flags are specified by VPX_CODEC_USE_* defines.
+     */
+#define VPX_CODEC_USE_PSNR  0x10000 /**< Calculate PSNR on each frame */
+
+
+    /*!\brief Generic fixed size buffer structure
+     *
+     * This structure is able to hold a reference to any fixed size buffer.
+     */
+    typedef struct vpx_fixed_buf
+    {
+        void          *buf; /**< Pointer to the data */
+        size_t         sz;  /**< Length of the buffer, in chars */
+    } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */
+
+
+    /*!\brief Time Stamp Type
+     *
+     * An integer, which when multiplied by the stream's time base, provides
+     * the absolute time of a sample.
+     */
+    typedef int64_t vpx_codec_pts_t;
+
+
+    /*!\brief Compressed Frame Flags
+     *
+     * This type represents a bitfield containing information about a compressed
+     * frame that may be useful to an application. The most significant 16 bits
+     * can be used by an algorithm to provide additional detail, for example to
+     * support frame types that are codec specific (MPEG-1 D-frames for example)
+     */
+    typedef uint32_t vpx_codec_frame_flags_t;
+#define VPX_FRAME_IS_KEY       0x1 /**< frame is the start of a GOP */
+#define VPX_FRAME_IS_DROPPABLE 0x2 /**< frame can be dropped without affecting
+    the stream (no future frame depends on
+                this one) */
+#define VPX_FRAME_IS_INVISIBLE 0x4 /**< frame should be decoded but will not
+    be shown */
+
+
+    /*!\brief Encoder output packet variants
+     *
+     * This enumeration lists the different kinds of data packets that can be
+     * returned by calls to vpx_codec_get_cx_data(). Algorithms \ref MAY
+     * extend this list to provide additional functionality.
+     */
+    enum vpx_codec_cx_pkt_kind
+    {
+        VPX_CODEC_CX_FRAME_PKT,    /**< Compressed video frame */
+        VPX_CODEC_STATS_PKT,       /**< Two-pass statistics for this frame */
+        VPX_CODEC_PSNR_PKT,        /**< PSNR statistics for this frame */
+        VPX_CODEC_CUSTOM_PKT = 256 /**< Algorithm extensions  */
+    };
+
+
+    /*!\brief Encoder output packet
+     *
+     * This structure contains the different kinds of output data the encoder
+     * may produce while compressing a frame.
+     */
+    typedef struct vpx_codec_cx_pkt
+    {
+        enum vpx_codec_cx_pkt_kind  kind; /**< packet variant */
+        union
+        {
+            struct
+            {
+                void                    *buf;      /**< compressed data buffer */
+                size_t                   sz;       /**< length of compressed data */
+                vpx_codec_pts_t          pts;      /**< time stamp to show frame
+                                                    (in timebase units) */
+                unsigned long            duration; /**< duration to show frame
+                                                    (in timebase units) */
+                vpx_codec_frame_flags_t  flags;    /**< flags for this frame */
+            } frame;  /**< data for compressed frame packet */
+            struct vpx_fixed_buf twopass_stats;  /**< data for two-pass packet */
+            struct vpx_psnr_pkt
+            {
+                unsigned int samples[4];  /**< Number of samples, total/y/u/v */
+                uint64_t     sse[4];      /**< sum squared error, total/y/u/v */
+                double       psnr[4];     /**< PSNR, total/y/u/v */
+            } psnr;                       /**< data for PSNR packet */
+            struct vpx_fixed_buf raw;     /**< data for arbitrary packets */
+
+            /* This packet size is fixed to allow codecs to extend this
+             * interface without having to manage storage for raw packets,
+             * ie if it's smaller than 128 bytes, you can store in the
+             * packet list directly.
+             */
+            char pad[128 - sizeof(enum vpx_codec_cx_pkt_kind)]; /**< fixed sz */
+        } data; /**< packet data */
+    } vpx_codec_cx_pkt_t; /**< alias for struct vpx_codec_cx_pkt */
+
+
+    /*!\brief Rational Number
+     *
+     * This structure holds a fractional value.
+     */
+    typedef struct vpx_rational
+    {
+        int num; /**< fraction numerator */
+        int den; /**< fraction denominator */
+    } vpx_rational_t; /**< alias for struct vpx_rational */
+
+
+    /*!\brief Multi-pass Encoding Pass */
+    enum vpx_enc_pass
+    {
+        VPX_RC_ONE_PASS,   /**< Single pass mode */
+        VPX_RC_FIRST_PASS, /**< First pass of multi-pass mode */
+        VPX_RC_LAST_PASS,  /**< Final pass of multi-pass mode */
+    };
+
+
+    /*!\brief Rate control mode */
+    enum vpx_rc_mode
+    {
+        VPX_VBR, /**< Variable Bit Rate (VBR) mode */
+        VPX_CBR  /**< Constant Bit Rate (CBR) mode */
+    };
+
+
+    /*!\brief Keyframe placement mode.
+     *
+     * This enumeration determines whether keyframes are placed automatically by
+     * the encoder or whether this behavior is disabled. Older releases of this
+     * SDK were implemented such that VPX_KF_FIXED meant keyframes were disabled.
+     * This name is confusing for this behavior, so the new symbols to be used
+     * are VPX_KF_AUTO and VPX_KF_DISABLED.
+     */
+    enum vpx_kf_mode
+    {
+        VPX_KF_FIXED, /**< deprecated, implies VPX_KF_DISABLED */
+        VPX_KF_AUTO,  /**< Encoder determines optimal placement automatically */
+        VPX_KF_DISABLED = 0 /**< Encoder does not place keyframes. */
+    };
+
+
+    /*!\brief Encoded Frame Flags
+     *
+     * This type indicates a bitfield to be passed to vpx_codec_encode(), defining
+     * per-frame boolean values. By convention, bits common to all codecs will be
+     * named VPX_EFLAG_*, and bits specific to an algorithm will be named
+     * /algo/_eflag_*. The lower order 16 bits are reserved for common use.
+     */
+    typedef long vpx_enc_frame_flags_t;
+#define VPX_EFLAG_FORCE_KF (1<<0)  /**< Force this frame to be a keyframe */
+
+
+    /*!\brief Encoder configuration structure
+     *
+     * This structure contains the encoder settings that have common representations
+     * across all codecs. This doesn't imply that all codecs support all features,
+     * however.
+     */
+    typedef struct vpx_codec_enc_cfg
+    {
+        /*
+         * generic settings (g)
+         */
+
+        /*!\brief Algorithm specific "usage" value
+         *
+         * Algorithms may define multiple values for usage, which may convey the
+         * intent of how the application intends to use the stream. If this value
+         * is non-zero, consult the documentation for the codec to determine its
+         * meaning.
+         */
+        unsigned int           g_usage;
+
+
+        /*!\brief Maximum number of threads to use
+         *
+         * For multi-threaded implementations, use no more than this number of
+         * threads. The codec may use fewer threads than allowed. The value
+         * 0 is equivalent to the value 1.
+         */
+        unsigned int           g_threads;
+
+
+        /*!\brief Bitstream profile to use
+         *
+         * Some codecs support a notion of multiple bitstream profiles. Typically
+         * this maps to a set of features that are turned on or off. Often the
+         * profile to use is determined by the features of the intended decoder.
+         * Consult the documentation for the codec to determine the valid values
+         * for this parameter, or set to zero for a sane default.
+         */
+        unsigned int           g_profile;  /**< profile of bitstream to use */
+
+
+
+        /*!\brief Width of the frame
+         *
+         * This value identifies the presentation resolution of the frame,
+         * in pixels. Note that the frames passed as input to the encoder must
+         * have this resolution. Frames will be presented by the decoder in this
+         * resolution, independent of any spatial resampling the encoder may do.
+         */
+        unsigned int           g_w;
+
+
+        /*!\brief Height of the frame
+         *
+         * This value identifies the presentation resolution of the frame,
+         * in pixels. Note that the frames passed as input to the encoder must
+         * have this resolution. Frames will be presented by the decoder in this
+         * resolution, independent of any spatial resampling the encoder may do.
+         */
+        unsigned int           g_h;
+
+
+        /*!\brief Stream timebase units
+         *
+         * Indicates the smallest interval of time, in seconds, used by the stream.
+         * For fixed frame rate material, or variable frame rate material where
+         * frames are timed at a multiple of a given clock (ex: video capture),
+         * the \ref RECOMMENDED method is to set the timebase to the reciprocal
+         * of the frame rate (ex: 1001/30000 for 29.970 Hz NTSC). This allows the
+         * pts to correspond to the frame number, which can be handy. For
+         * re-encoding video from containers with absolute time timestamps, the
+         * \ref RECOMMENDED method is to set the timebase to that of the parent
+         * container or multimedia framework (ex: 1/1000 for ms, as in FLV).
+         */
+        struct vpx_rational    g_timebase;
+
+
+        /*!\brief Enable error resilient mode.
+         *
+         * Error resilient mode indicates to the encoder that it should take
+         * measures appropriate for streaming over lossy or noisy links, if
+         * possible. Set to 1 to enable this feature, 0 to disable it.
+         */
+        unsigned int           g_error_resilient;
+
+
+        /*!\brief Multi-pass Encoding Mode
+         *
+         * This value should be set to the current phase for multi-pass encoding.
+         * For single pass, set to #VPX_RC_ONE_PASS.
+         */
+        enum vpx_enc_pass      g_pass;
+
+
+        /*!\brief Allow lagged encoding
+         *
+         * If set, this value allows the encoder to consume a number of input
+         * frames before producing output frames. This allows the encoder to
+         * base decisions for the current frame on future frames. This does
+         * increase the latency of the encoding pipeline, so it is not appropriate
+         * in all situations (ex: realtime encoding).
+         *
+         * Note that this is a maximum value -- the encoder may produce frames
+         * sooner than the given limit. Set this value to 0 to disable this
+         * feature.
+         */
+        unsigned int           g_lag_in_frames;
+
+
+        /*
+         * rate control settings (rc)
+         */
+
+        /*!\brief Temporal resampling configuration, if supported by the codec.
+         *
+         * Temporal resampling allows the codec to "drop" frames as a strategy to
+         * meet its target data rate. This can cause temporal discontinuities in
+         * the encoded video, which may appear as stuttering during playback. This
+         * trade-off is often acceptable, but for many applications is not. It can
+         * be disabled in these cases.
+         *
+         * Note that not all codecs support this feature. All vpx VPx codecs do.
+         * For other codecs, consult the documentation for that algorithm.
+         *
+         * This threshold is described as a percentage of the target data buffer.
+         * When the data buffer falls below this percentage of fullness, a
+         * dropped frame is indicated. Set the threshold to zero (0) to disable
+         * this feature.
+         */
+        unsigned int           rc_dropframe_thresh;
+
+
+        /*!\brief Enable/disable spatial resampling, if supported by the codec.
+         *
+         * Spatial resampling allows the codec to compress a lower resolution
+         * version of the frame, which is then upscaled by the encoder to the
+         * correct presentation resolution. This increases visual quality at
+         * low data rates, at the expense of CPU time on the encoder/decoder.
+         */
+        unsigned int           rc_resize_allowed;
+
+
+        /*!\brief Spatial resampling up watermark.
+         *
+         * This threshold is described as a percentage of the target data buffer.
+         * When the data buffer rises above this percentage of fullness, the
+         * encoder will step up to a higher resolution version of the frame.
+         */
+        unsigned int           rc_resize_up_thresh;
+
+
+        /*!\brief Spatial resampling down watermark.
+         *
+         * This threshold is described as a percentage of the target data buffer.
+         * When the data buffer falls below this percentage of fullness, the
+         * encoder will step down to a lower resolution version of the frame.
+         */
+        unsigned int           rc_resize_down_thresh;
+
+
+        /*!\brief Rate control algorithm to use.
+         *
+         * Indicates whether the end usage of this stream is to be streamed over
+         * a bandwidth constrained link, indicating that Constant Bit Rate (CBR)
+         * mode should be used, or whether it will be played back on a high
+         * bandwidth link, as from a local disk, where higher variations in
+         * bitrate are acceptable.
+         */
+        enum vpx_rc_mode       rc_end_usage;
+
+
+        /*!\brief Two-pass stats buffer.
+         *
+         * A buffer containing all of the stats packets produced in the first
+         * pass, concatenated.
+         */
+        struct vpx_fixed_buf   rc_twopass_stats_in;
+
+
+        /*!\brief Target data rate
+         *
+         * Target bandwidth to use for this stream, in kilobits per second.
+         */
+        unsigned int           rc_target_bitrate;
+
+
+        /*
+         * quantizer settings
+         */
+
+
+        /*!\brief Minimum (Best Quality) Quantizer
+         *
+         * The quantizer is the most direct control over the quality of the
+         * encoded image. The range of valid values for the quantizer is codec
+         * specific. Consult the documentation for the codec to determine the
+         * values to use. To determine the range programmatically, call
+         * vpx_codec_enc_config_default() with a usage value of 0.
+         */
+        unsigned int           rc_min_quantizer;
+
+
+        /*!\brief Maximum (Worst Quality) Quantizer
+         *
+         * The quantizer is the most direct control over the quality of the
+         * encoded image. The range of valid values for the quantizer is codec
+         * specific. Consult the documentation for the codec to determine the
+         * values to use. To determine the range programmatically, call
+         * vpx_codec_enc_config_default() with a usage value of 0.
+         */
+        unsigned int           rc_max_quantizer;
+
+
+        /*
+         * bitrate tolerance
+         */
+
+
+        /*!\brief Rate control undershoot tolerance
+         *
+         * This value, expressed as a percentage of the target bitrate, describes
+         * the target bitrate for easier frames, allowing bits to be saved for
+         * harder frames. Set to zero to use the codec default.
+         */
+        unsigned int           rc_undershoot_pct;
+
+
+        /*!\brief Rate control overshoot tolerance
+         *
+         * This value, expressed as a percentage of the target bitrate, describes
+         * the maximum allowed bitrate for a given frame.  Set to zero to use the
+         * codec default.
+         */
+        unsigned int           rc_overshoot_pct;
+
+
+        /*
+         * decoder buffer model parameters
+         */
+
+
+        /*!\brief Decoder Buffer Size
+         *
+         * This value indicates the amount of data that may be buffered by the
+         * decoding application. Note that this value is expressed in units of
+         * time (milliseconds). For example, a value of 5000 indicates that the
+         * client will buffer (at least) 5000ms worth of encoded data. Use the
+         * target bitrate (#rc_target_bitrate) to convert to bits/bytes, if
+         * necessary.
+         */
+        unsigned int           rc_buf_sz;
+
+
+        /*!\brief Decoder Buffer Initial Size
+         *
+         * This value indicates the amount of data that will be buffered by the
+         * decoding application prior to beginning playback. This value is
+         * expressed in units of time (milliseconds). Use the target bitrate
+         * (#rc_target_bitrate) to convert to bits/bytes, if necessary.
+         */
+        unsigned int           rc_buf_initial_sz;
+
+
+        /*!\brief Decoder Buffer Optimal Size
+         *
+         * This value indicates the amount of data that the encoder should try
+         * to maintain in the decoder's buffer. This value is expressed in units
+         * of time (milliseconds). Use the target bitrate (#rc_target_bitrate)
+         * to convert to bits/bytes, if necessary.
+         */
+        unsigned int           rc_buf_optimal_sz;
+
+
+        /*
+         * 2 pass rate control parameters
+         */
+
+
+        /*!\brief Two-pass mode CBR/VBR bias
+         *
+         * Bias, expressed on a scale of 0 to 100, for determining target size
+         * for the current frame. The value 0 indicates the optimal CBR mode
+         * value should be used. The value 100 indicates the optimal VBR mode
+         * value should be used. Values in between indicate which way the
+         * encoder should "lean."
+         */
+        unsigned int           rc_2pass_vbr_bias_pct;       /**< RC mode bias between CBR and VBR(0-100: 0->CBR, 100->VBR)   */
+
+
+        /*!\brief Two-pass mode per-GOP minimum bitrate
+         *
+         * This value, expressed as a percentage of the target bitrate, indicates
+         * the minimum bitrate to be used for a single GOP (aka "section")
+         */
+        unsigned int           rc_2pass_vbr_minsection_pct;
+
+
+        /*!\brief Two-pass mode per-GOP maximum bitrate
+         *
+         * This value, expressed as a percentage of the target bitrate, indicates
+         * the maximum bitrate to be used for a single GOP (aka "section")
+         */
+        unsigned int           rc_2pass_vbr_maxsection_pct;
+
+
+        /*
+         * keyframing settings (kf)
+         */
+
+        /*!\brief Keyframe placement mode
+         *
+         * This value indicates whether the encoder should place keyframes at a
+         * fixed interval, or determine the optimal placement automatically
+         * (as governed by the #kf_min_dist and #kf_max_dist parameters)
+         */
+        enum vpx_kf_mode       kf_mode;
+
+
+        /*!\brief Keyframe minimum interval
+         *
+         * This value, expressed as a number of frames, prevents the encoder from
+         * placing a keyframe nearer than kf_min_dist to the previous keyframe. At
+         * least kf_min_dist frames non-keyframes will be coded before the next
+         * keyframe. Set kf_min_dist equal to kf_max_dist for a fixed interval.
+         */
+        unsigned int           kf_min_dist;
+
+
+        /*!\brief Keyframe maximum interval
+         *
+         * This value, expressed as a number of frames, forces the encoder to code
+         * a keyframe if one has not been coded in the last kf_max_dist frames.
+         * A value of 0 implies all frames will be keyframes. Set kf_min_dist
+         * equal to kf_max_dist for a fixed interval.
+         */
+        unsigned int           kf_max_dist;
+
+    } vpx_codec_enc_cfg_t; /**< alias for struct vpx_codec_enc_cfg */
+
+
+    /*!\brief Initialize an encoder instance
+     *
+     * Initializes a encoder context using the given interface. Applications
+     * should call the vpx_codec_enc_init convenience macro instead of this
+     * function directly, to ensure that the ABI version number parameter
+     * is properly initialized.
+     *
+     * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the flags
+     * parameter), the storage pointed to by the cfg parameter must be
+     * kept readable and stable until all memory maps have been set.
+     *
+     * \param[in]    ctx     Pointer to this instance's context.
+     * \param[in]    iface   Pointer to the algorithm interface to use.
+     * \param[in]    cfg     Configuration to use, if known. May be NULL.
+     * \param[in]    flags   Bitfield of VPX_CODEC_USE_* flags
+     * \param[in]    ver     ABI version number. Must be set to
+     *                       VPX_ENCODER_ABI_VERSION
+     * \retval #VPX_CODEC_OK
+     *     The decoder algorithm initialized.
+     * \retval #VPX_CODEC_MEM_ERROR
+     *     Memory allocation failed.
+     */
+    vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t      *ctx,
+                                           vpx_codec_iface_t    *iface,
+                                           vpx_codec_enc_cfg_t  *cfg,
+                                           vpx_codec_flags_t     flags,
+                                           int                   ver);
+
+
+    /*!\brief Convenience macro for vpx_codec_enc_init_ver()
+     *
+     * Ensures the ABI version parameter is properly set.
+     */
+#define vpx_codec_enc_init(ctx, iface, cfg, flags) \
+    vpx_codec_enc_init_ver(ctx, iface, cfg, flags, VPX_ENCODER_ABI_VERSION)
+
+
+    /*!\brief Get a default configuration
+     *
+     * Initializes a encoder configuration structure with default values. Supports
+     * the notion of "usages" so that an algorithm may offer different default
+     * settings depending on the user's intended goal. This function \ref SHOULD
+     * be called by all applications to initialize the configuration structure
+     * before specializing the configuration with application specific values.
+     *
+     * \param[in]    iface   Pointer to the algorithm interface to use.
+     * \param[out]   cfg     Configuration buffer to populate
+     * \param[in]    usage   End usage. Set to 0 or use codec specific values.
+     *
+     * \retval #VPX_CODEC_OK
+     *     The configuration was populated.
+     * \retval #VPX_CODEC_INCAPABLE
+     *     Interface is not an encoder interface.
+     * \retval #VPX_CODEC_INVALID_PARAM
+     *     A parameter was NULL, or the usage value was not recognized.
+     */
+    vpx_codec_err_t  vpx_codec_enc_config_default(vpx_codec_iface_t    *iface,
+            vpx_codec_enc_cfg_t  *cfg,
+            unsigned int          usage);
+
+
+    /*!\brief Set or change configuration
+     *
+     * Reconfigures an encoder instance according to the given configuration.
+     *
+     * \param[in]    ctx     Pointer to this instance's context
+     * \param[in]    cfg     Configuration buffer to use
+     *
+     * \retval #VPX_CODEC_OK
+     *     The configuration was populated.
+     * \retval #VPX_CODEC_INCAPABLE
+     *     Interface is not an encoder interface.
+     * \retval #VPX_CODEC_INVALID_PARAM
+     *     A parameter was NULL, or the usage value was not recognized.
+     */
+    vpx_codec_err_t  vpx_codec_enc_config_set(vpx_codec_ctx_t            *ctx,
+            const vpx_codec_enc_cfg_t  *cfg);
+
+
+    /*!\brief Get global stream headers
+     *
+     * Retrieves a stream level global header packet, if supported by the codec.
+     *
+     * \param[in]    ctx     Pointer to this instance's context
+     *
+     * \retval NULL
+     *     Encoder does not support global header
+     * \retval Non-NULL
+     *     Pointer to buffer containing global header packet
+     */
+    vpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t   *ctx);
+
+
+#define VPX_DL_REALTIME     (1)        /**< deadline parameter analogous to
+    *   VPx REALTIME mode. */
+#define VPX_DL_GOOD_QUALITY (1000000)  /**< deadline parameter analogous to
+    *   VPx GOOD QUALITY mode. */
+#define VPX_DL_BEST_QUALITY (0)        /**< deadline parameter analogous to
+    *   VPx BEST QUALITY mode. */
+    /*!\brief Encode a frame
+     *
+     * Encodes a video frame at the given "presentation time." The presentation
+     * time stamp (PTS) \ref MUST be strictly increasing.
+     *
+     * The encoder supports the notion of a soft real-time deadline. Given a
+     * non-zero value to the deadline parameter, the encoder will make a "best
+     * effort" guarantee to  return before the given time slice expires. It is
+     * implicit that limiting the available time to encode will degrade the
+     * output quality. The encoder can be given an unlimited time to produce the
+     * best possible frame by specifying a deadline of '0'. This deadline
+     * supercedes the VPx notion of "best quality, good quality, realtime".
+     * Applications that wish to map these former settings to the new deadline
+     * based system can use the symbols #VPX_DL_REALTIME, #VPX_DL_GOOD_QUALITY,
+     * and #VPX_DL_BEST_QUALITY.
+     *
+     * When the last frame has been passed to the encoder, this function should
+     * continue to be called, with the img parameter set to NULL. This will
+     * signal the end-of-stream condition to the encoder and allow it to encode
+     * any held buffers. Encoding is complete when vpx_codec_encode() is called
+     * and vpx_codec_get_cx_data() returns no data.
+     *
+     * \param[in]    ctx       Pointer to this instance's context
+     * \param[in]    img       Image data to encode, NULL to flush.
+     * \param[in]    pts       Presentation time stamp, in timebase units.
+     * \param[in]    duration  Duration to show frame, in timebase units.
+     * \param[in]    flags     Flags to use for encoding this frame.
+     * \param[in]    deadline  Time to spend encoding, in microseconds. (0=infinite)
+     *
+     * \retval #VPX_CODEC_OK
+     *     The configuration was populated.
+     * \retval #VPX_CODEC_INCAPABLE
+     *     Interface is not an encoder interface.
+     * \retval #VPX_CODEC_INVALID_PARAM
+     *     A parameter was NULL, the image format is unsupported, etc.
+     */
+    vpx_codec_err_t  vpx_codec_encode(vpx_codec_ctx_t            *ctx,
+                                      const vpx_image_t          *img,
+                                      vpx_codec_pts_t             pts,
+                                      unsigned long               duration,
+                                      vpx_enc_frame_flags_t       flags,
+                                      unsigned long               deadline);
+
+
+    /*!\brief Set compressed data output buffer
+     *
+     * Sets the buffer that the codec should output the compressed data
+     * into. This call effectively sets the buffer pointer returned in the
+     * next VPX_CODEC_CX_FRAME_PKT packet. Subsequent packets will be
+     * appended into this buffer. The buffer is preserved across frames,
+     * so applications must periodically call this function after flushing
+     * the accumulated compressed data to disk or to the network to reset
+     * the pointer to the buffer's head.
+     *
+     * `pad_before` bytes will be skipped before writing the compressed
+     * data, and `pad_after` bytes will be appended to the packet. The size
+     * of the packet will be the sum of the size of the actual compressed
+     * data, pad_before, and pad_after. The padding bytes will be preserved
+     * (not overwritten).
+     *
+     * Note that calling this function does not guarantee that the returned
+     * compressed data will be placed into the specified buffer. In the
+     * event that the encoded data will not fit into the buffer provided,
+     * the returned packet \ref MAY point to an internal buffer, as it would
+     * if this call were never used. In this event, the output packet will
+     * NOT have any padding, and the application must free space and copy it
+     * to the proper place. This is of particular note in configurations
+     * that may output multiple packets for a single encoded frame (e.g., lagged
+     * encoding) or if the application does not reset the buffer periodically.
+     *
+     * Applications may restore the default behavior of the codec providing
+     * the compressed data buffer by calling this function with a NULL
+     * buffer.
+     *
+     * Applications \ref MUSTNOT call this function during iteration of
+     * vpx_codec_get_cx_data().
+     *
+     * \param[in]    ctx         Pointer to this instance's context
+     * \param[in]    buf         Buffer to store compressed data into
+     * \param[in]    pad_before  Bytes to skip before writing compressed data
+     * \param[in]    pad_after   Bytes to skip after writing compressed data
+     *
+     * \retval #VPX_CODEC_OK
+     *     The buffer was set successfully.
+     * \retval #VPX_CODEC_INVALID_PARAM
+     *     A parameter was NULL, the image format is unsupported, etc.
+     */
+    vpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t       *ctx,
+            const vpx_fixed_buf_t *buf,
+            unsigned int           pad_before,
+            unsigned int           pad_after);
+
+
+    /*!\brief Encoded data iterator
+     *
+     * Iterates over a list of data packets to be passed from the encoder to the
+     * application. The different kinds of packets available are enumerated in
+     * #vpx_codec_cx_pkt_kind.
+     *
+     * #VPX_CODEC_CX_FRAME_PKT packets should be passed to the application's
+     * muxer. Multiple compressed frames may be in the list.
+     * #VPX_CODEC_STATS_PKT packets should be appended to a global buffer.
+     *
+     * The application \ref MUST silently ignore any packet kinds that it does
+     * not recognize or support.
+     *
+     * The data buffers returned from this function are only guaranteed to be
+     * valid until the application makes another call to any vpx_codec_* function.
+     *
+     * \param[in]     ctx      Pointer to this instance's context
+     * \param[in,out] iter     Iterator storage, initialized to NULL
+     *
+     * \return Returns a pointer to an output data packet (compressed frame data,
+     *         two-pass statistics, etc.) or NULL to signal end-of-list.
+     *
+     */
+    const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t   *ctx,
+            vpx_codec_iter_t  *iter);
+
+
+    /*!\brief Get Preview Frame
+     *
+     * Returns an image that can be used as a preview. Shows the image as it would
+     * exist at the decompressor. The application \ref MUST NOT write into this
+     * image buffer.
+     *
+     * \param[in]     ctx      Pointer to this instance's context
+     *
+     * \return Returns a pointer to a preview image, or NULL if no image is
+     *         available.
+     *
+     */
+    const vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t   *ctx);
+
+
+    /*!@} - end defgroup encoder*/
+
+#endif
+#ifdef __cplusplus
+}
+#endif
diff --git a/vpx_codec/vpx_image.h b/vpx_codec/vpx_image.h
new file mode 100644 (file)
index 0000000..a8a9416
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*!\file vpx_image.h
+ * \brief Describes the vpx image descriptor and associated operations
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef VPX_IMAGE_H
+#define VPX_IMAGE_H
+
+    /*!\brief Current ABI version number
+     *
+     * \internal
+     * If this file is altered in any way that changes the ABI, this value
+     * must be bumped.  Examples include, but are not limited to, changing
+     * types, removing or reassigning enums, adding/removing/rearranging
+     * fields to structures
+     */
+#define VPX_IMAGE_ABI_VERSION (1) /**<\hideinitializer*/
+
+
+#define IMG_FMT_PLANAR     0x100  /**< Image is a planar format */
+#define IMG_FMT_UV_FLIP    0x200  /**< V plane precedes U plane in memory */
+#define IMG_FMT_HAS_ALPHA  0x400  /**< Image has an alpha channel componnent */
+
+
+    /*!\brief List of supported image formats */
+    typedef enum img_fmt {
+        IMG_FMT_NONE,
+        IMG_FMT_RGB24,   /**< 24 bit per pixel packed RGB */
+        IMG_FMT_RGB32,   /**< 32 bit per pixel packed 0RGB */
+        IMG_FMT_RGB565,  /**< 16 bit per pixel, 565 */
+        IMG_FMT_RGB555,  /**< 16 bit per pixel, 555 */
+        IMG_FMT_UYVY,    /**< UYVY packed YUV */
+        IMG_FMT_YUY2,    /**< YUYV packed YUV */
+        IMG_FMT_YVYU,    /**< YVYU packed YUV */
+        IMG_FMT_BGR24,   /**< 24 bit per pixel packed BGR */
+        IMG_FMT_RGB32_LE, /**< 32 bit packed BGR0 */
+        IMG_FMT_ARGB,     /**< 32 bit packed ARGB, alpha=255 */
+        IMG_FMT_ARGB_LE,  /**< 32 bit packed BGRA, alpha=255 */
+        IMG_FMT_RGB565_LE,  /**< 16 bit per pixel, gggbbbbb rrrrrggg */
+        IMG_FMT_RGB555_LE,  /**< 16 bit per pixel, gggbbbbb 0rrrrrgg */
+        IMG_FMT_YV12    = IMG_FMT_PLANAR | IMG_FMT_UV_FLIP | 1, /**< planar YVU */
+        IMG_FMT_I420    = IMG_FMT_PLANAR | 2,
+        IMG_FMT_VPXYV12 = IMG_FMT_PLANAR | IMG_FMT_UV_FLIP | 3, /** < planar 4:2:0 format with vpx color space */
+        IMG_FMT_VPXI420 = IMG_FMT_PLANAR | 4,  /** < planar 4:2:0 format with vpx color space */
+    }
+    img_fmt_t; /**< alias for enum img_fmt */
+
+
+    /**\brief Image Descriptor */
+    typedef struct
+    {
+        img_fmt_t     fmt; /**< Image Format */
+
+        /* Image storage dimensions */
+        unsigned int  w;   /**< Stored image width */
+        unsigned int  h;   /**< Stored image height */
+
+        /* Image display dimensions */
+        unsigned int  d_w;   /**< Displayed image width */
+        unsigned int  d_h;   /**< Displayed image height */
+
+        /* Chroma subsampling info */
+        unsigned int  x_chroma_shift;   /**< subsampling order, X */
+        unsigned int  y_chroma_shift;   /**< subsampling order, Y */
+
+        /* Image data pointers. */
+#define PLANE_PACKED 0   /**< To be used for all packed formats */
+#define PLANE_Y   0      /**< Y (Luminance) plane */
+#define PLANE_U   1      /**< U (Chroma) plane */
+#define PLANE_V   2      /**< V (Chroma) plane */
+#define PLANE_ALPHA 3    /**< A (Transparancy) plane */
+        unsigned char *planes[4];  /**< pointer to the top left pixel for each plane */
+        int      stride[4];  /**< stride between rows for each plane */
+
+        int     bps; /**< bits per sample (for packed formats) */
+
+        /* The following member may be set by the application to associate data
+         * with this image.
+         */
+        void    *user_priv; /**< may be set by the application to associate data
+                         *   with this image. */
+
+        /* The following members should be treated as private. */
+        unsigned char *img_data;       /**< private */
+        int      img_data_owner; /**< private */
+        int      self_allocd;    /**< private */
+    } vpx_image_t; /**< alias for struct vpx_image */
+
+    /**\brief Representation of a rectangle on a surface */
+    typedef struct vpx_image_rect
+    {
+        unsigned int x; /**< leftmost column */
+        unsigned int y; /**< topmost row */
+        unsigned int w; /**< width */
+        unsigned int h; /**< height */
+    } vpx_image_rect_t; /**< alias for struct vpx_image_rect */
+
+    /*!\brief Open a descriptor, allocating storage for the underlying image
+     *
+     * Returns a descriptor for storing an image of the given format. The
+     * storage for the descriptor is allocated on the heap.
+     *
+     * \param[in]    img       Pointer to storage for descriptor. If this parameter
+     *                         is NULL, the storage for the descriptor will be
+     *                         allocated on the heap.
+     * \param[in]    fmt       Format for the image
+     * \param[in]    d_w       Width of the image
+     * \param[in]    d_h       Height of the image
+     * \param[in]    align     Alignment, in bytes, of each row in the image.
+     *
+     * \return Returns a pointer to the initialized image descriptor. If the img
+     *         parameter is non-null, the value of the img parameter will be
+     *         returned.
+     */
+    vpx_image_t *vpx_img_alloc(vpx_image_t  *img,
+                               img_fmt_t fmt,
+                               unsigned int d_w,
+                               unsigned int d_h,
+                               unsigned int align);
+
+    /*!\brief Open a descriptor, using existing storage for the underlying image
+     *
+     * Returns a descriptor for storing an image of the given format. The
+     * storage for descriptor has been allocated elsewhere, and a descriptor is
+     * desired to "wrap" that storage.
+     *
+     * \param[in]    img       Pointer to storage for descriptor. If this parameter
+     *                         is NULL, the storage for the descriptor will be
+     *                         allocated on the heap.
+     * \param[in]    fmt       Format for the image
+     * \param[in]    d_w       Width of the image
+     * \param[in]    d_h       Height of the image
+     * \param[in]    align     Alignment, in bytes, of each row in the image.
+     * \param[in]    img_data  Storage to use for the image
+     *
+     * \return Returns a pointer to the initialized image descriptor. If the img
+     *         parameter is non-null, the value of the img parameter will be
+     *         returned.
+     */
+    vpx_image_t *vpx_img_wrap(vpx_image_t  *img,
+                              img_fmt_t fmt,
+                              unsigned int d_w,
+                              unsigned int d_h,
+                              unsigned int align,
+                              unsigned char      *img_data);
+
+
+    /*!\brief Set the rectangle identifying the displayed portion of the image
+     *
+     * Updates the displayed rectangle (aka viewport) on the image surface to
+     * match the specified coordinates and size.
+     *
+     * \param[in]    img       Image descriptor
+     * \param[in]    x         leftmost column
+     * \param[in]    y         topmost row
+     * \param[in]    w         width
+     * \param[in]    h         height
+     *
+     * \return 0 if the requested rectangle is valid, nonzero otherwise.
+     */
+    int vpx_img_set_rect(vpx_image_t  *img,
+                         unsigned int  x,
+                         unsigned int  y,
+                         unsigned int  w,
+                         unsigned int  h);
+
+
+    /*!\brief Flip the image vertically (top for bottom)
+     *
+     * Adjusts the image descriptor's pointers and strides to make the image
+     * be referenced upside-down.
+     *
+     * \param[in]    img       Image descriptor
+     */
+    void vpx_img_flip(vpx_image_t *img);
+
+    /*!\brief Close an image descriptor
+     *
+     * Frees all allocated storage associated with an image descriptor.
+     *
+     * \param[in]    img       Image descriptor
+     */
+    void vpx_img_free(vpx_image_t *img);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
diff --git a/vpx_mem/include/nds/vpx_mem_nds.h b/vpx_mem/include/nds/vpx_mem_nds.h
new file mode 100644 (file)
index 0000000..c332403
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __VPX_MEM_NDS_H__
+#define __VPX_MEM_NDS_H__
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <nitro.h>
+#include <nitro/os.h>
+
+    void *vpx_mem_nds_alloc(osarena_id id, osheap_handle handle, size_t size, size_t align);
+    void vpx_mem_nds_free(osarena_id id, osheap_handle handle, void *mem);
+    int vpx_nds_alloc_heap(osarena_id id, u32 size);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /*__VPX_MEM_NDS_H__*/
diff --git a/vpx_mem/include/vpx_mem_intrnl.h b/vpx_mem/include/vpx_mem_intrnl.h
new file mode 100644 (file)
index 0000000..3b68d86
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __VPX_MEM_INTRNL_H__
+#define __VPX_MEM_INTRNL_H__
+#include "vpx_ports/config.h"
+
+#ifndef CONFIG_MEM_MANAGER
+# if defined(VXWORKS)
+#  define CONFIG_MEM_MANAGER  1 //include heap manager functionality,
+//default: enabled on vxworks
+# else
+#  define CONFIG_MEM_MANAGER  0 //include heap manager functionality
+# endif
+#endif /*CONFIG_MEM_MANAGER*/
+
+#ifndef CONFIG_MEM_TRACKER
+# define CONFIG_MEM_TRACKER     1 //include xvpx_* calls in the lib
+#endif
+
+#ifndef CONFIG_MEM_CHECKS
+# define CONFIG_MEM_CHECKS      0 //include some basic safety checks in
+//vpx_memcpy, _memset, and _memmove
+#endif
+
+#ifndef USE_GLOBAL_FUNCTION_POINTERS
+# define USE_GLOBAL_FUNCTION_POINTERS   0  //use function pointers instead of compiled functions.
+#endif
+
+#if CONFIG_MEM_TRACKER
+# include "vpx_mem_tracker.h"
+# if VPX_MEM_TRACKER_VERSION_CHIEF != 2 || VPX_MEM_TRACKER_VERSION_MAJOR != 5
+#  error "vpx_mem requires memory tracker version 2.5 to track memory usage"
+# endif
+#endif
+
+#define ADDRESS_STORAGE_SIZE      sizeof(size_t)
+
+#ifndef DEFAULT_ALIGNMENT
+# if defined(VXWORKS)
+#  define DEFAULT_ALIGNMENT        32        //default addr alignment to use in
+//calls to vpx_* functions other
+//than vpx_memalign
+# else
+#  define DEFAULT_ALIGNMENT        1
+# endif
+#endif
+
+#if DEFAULT_ALIGNMENT < 1
+# error "DEFAULT_ALIGNMENT must be >= 1!"
+#endif
+
+#if CONFIG_MEM_TRACKER
+# define TRY_BOUNDS_CHECK         1         //when set to 1 pads each allocation,
+//integrity can be checked using
+//vpx_memory_tracker_check_integrity
+//or on free by defining
+//TRY_BOUNDS_CHECK_ON_FREE
+#else
+# define TRY_BOUNDS_CHECK         0
+#endif /*CONFIG_MEM_TRACKER*/
+
+#if TRY_BOUNDS_CHECK
+# define TRY_BOUNDS_CHECK_ON_FREE 0          //checks mem integrity on every
+//free, very expensive
+# define BOUNDS_CHECK_VALUE       0xdeadbeef //value stored before/after ea.
+//mem addr for bounds checking
+# define BOUNDS_CHECK_PAD_SIZE    32         //size of the padding before and
+//after ea allocation to be filled
+//with BOUNDS_CHECK_VALUE.
+//this should be a multiple of 4
+#else
+# define BOUNDS_CHECK_VALUE       0
+# define BOUNDS_CHECK_PAD_SIZE    0
+#endif /*TRY_BOUNDS_CHECK*/
+
+#ifndef REMOVE_PRINTFS
+# define REMOVE_PRINTFS 0
+#endif
+
+/* Should probably use a vpx_mem logger function. */
+#if REMOVE_PRINTFS
+# define _P(x)
+#else
+# define _P(x) x
+#endif
+
+/*returns an addr aligned to the byte boundary specified by align*/
+#define align_addr(addr,align) (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align))
+
+#endif /*__VPX_MEM_INTRNL_H__*/
diff --git a/vpx_mem/include/vpx_mem_tracker.h b/vpx_mem/include/vpx_mem_tracker.h
new file mode 100644 (file)
index 0000000..ab85d19
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __VPX_MEM_TRACKER_H__
+#define __VPX_MEM_TRACKER_H__
+
+/* vpx_mem_tracker version info */
+#define vpx_mem_tracker_version "2.5.1.1"
+
+#define VPX_MEM_TRACKER_VERSION_CHIEF 2
+#define VPX_MEM_TRACKER_VERSION_MAJOR 5
+#define VPX_MEM_TRACKER_VERSION_MINOR 1
+#define VPX_MEM_TRACKER_VERSION_PATCH 1
+/* END - vpx_mem_tracker version info */
+
+#include <stdarg.h>
+
+struct mem_block
+{
+    size_t addr;
+    unsigned int size,
+             line;
+    char *file;
+    struct mem_block *prev,
+            * next;
+
+    int padded; // This mem_block has padding for integrity checks.
+    // As of right now, this should only be 0 if
+    // using vpx_mem_alloc to allocate cache memory.
+    // 2005-01-11 tjf
+};
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+    /*
+        vpx_memory_tracker_init(int padding_size, int pad_value)
+          padding_size - the size of the padding before and after each mem addr.
+                         Values > 0 indicate that integrity checks can be performed
+                         by inspecting these areas.
+          pad_value - the initial value within the padding area before and after
+                      each mem addr.
+
+        Initializes the memory tracker interface. Should be called before any
+        other calls to the memory tracker.
+    */
+    int vpx_memory_tracker_init(int padding_size, int pad_value);
+
+    /*
+        vpx_memory_tracker_destroy()
+        Deinitializes the memory tracker interface
+    */
+    void vpx_memory_tracker_destroy();
+
+    /*
+        vpx_memory_tracker_add(size_t addr, unsigned int size,
+                             char * file, unsigned int line)
+          addr - memory address to be added to list
+          size - size of addr
+          file - the file addr was referenced from
+          line - the line in file addr was referenced from
+        Adds memory address addr, it's size, file and line it came from
+        to the memory tracker allocation table
+    */
+    void vpx_memory_tracker_add(size_t addr, unsigned int size,
+                                char *file, unsigned int line,
+                                int padded);
+
+    /*
+        vpx_memory_tracker_add(size_t addr, unsigned int size, char * file, unsigned int line)
+          addr - memory address to be added to be removed
+          padded - if 0, disables bounds checking on this memory block even if bounds
+          checking is enabled. (for example, when allocating cache memory, we still want
+          to check for memory leaks, but we do not waste cache space for bounds check padding)
+        Removes the specified address from the memory tracker's allocation
+        table
+        Return:
+          0: on success
+          -1: if memory allocation table's mutex could not be locked
+          -2: if the addr was not found in the list
+    */
+    int vpx_memory_tracker_remove(size_t addr);
+
+    /*
+        vpx_memory_tracker_find(unsigned int addr)
+          addr - address to be found in the memory tracker's
+                 allocation table
+        Return:
+            If found, pointer to the memory block that matches addr
+            NULL otherwise
+    */
+    struct mem_block *vpx_memory_tracker_find(size_t addr);
+
+    /*
+        vpx_memory_tracker_dump()
+        Dumps the current contents of the memory
+        tracker allocation table
+    */
+    void vpx_memory_tracker_dump();
+
+    /*
+        vpx_memory_tracker_check_integrity()
+        If a padding_size was provided to vpx_memory_tracker_init()
+        This function will verify that the region before and after each
+        memory address contains the specified pad_value. Should the check
+        fail, the filename and line of the check will be printed out.
+    */
+    void vpx_memory_tracker_check_integrity(char *file, unsigned int line);
+
+    /*
+        vpx_memory_tracker_set_log_type
+          type - value representing the logging type to use
+          option - type specific option. This will be interpreted differently
+                   based on the type.
+        Sets the logging type for the memory tracker.
+        Values currently supported:
+          0: if option is NULL, log to stderr, otherwise interpret option as a
+             filename and attempt to open it.
+          1: Use output_debug_string (WIN32 only), option ignored
+        Return:
+          0: on success
+          -1: if the logging type could not be set, because the value was invalid
+              or because a file could not be opened
+    */
+    int vpx_memory_tracker_set_log_type(int type, char *option);
+
+    /*
+        vpx_memory_tracker_set_log_func
+          userdata - ptr to be passed to the supplied logfunc, can be NULL
+          logfunc - the logging function to be used to output data from
+                    vpx_memory_track_dump/check_integrity
+        Sets a logging function to be used by the memory tracker.
+        Return:
+          0: on success
+          -1: if the logging type could not be set because logfunc was NULL
+    */
+    int vpx_memory_tracker_set_log_func(void *userdata,
+                                        void(*logfunc)(void *userdata,
+                                                const char *fmt, va_list args));
+
+    /* Wrappers to standard library functions. */
+    typedef void*(* mem_track_malloc_func)(size_t);
+    typedef void*(* mem_track_calloc_func)(size_t, size_t);
+    typedef void*(* mem_track_realloc_func)(void *, size_t);
+    typedef void (* mem_track_free_func)(void *);
+    typedef void*(* mem_track_memcpy_func)(void *, const void *, size_t);
+    typedef void*(* mem_track_memset_func)(void *, int, size_t);
+    typedef void*(* mem_track_memmove_func)(void *, const void *, size_t);
+
+    /*
+        vpx_memory_tracker_set_functions
+
+        Sets the function pointers for the standard library functions.
+
+        Return:
+          0: on success
+          -1: if the use global function pointers is not set.
+    */
+    int vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l
+                                         , mem_track_calloc_func g_calloc_l
+                                         , mem_track_realloc_func g_realloc_l
+                                         , mem_track_free_func g_free_l
+                                         , mem_track_memcpy_func g_memcpy_l
+                                         , mem_track_memset_func g_memset_l
+                                         , mem_track_memmove_func g_memmove_l);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //__VPX_MEM_TRACKER_H__
diff --git a/vpx_mem/intel_linux/vpx_mem.c b/vpx_mem/intel_linux/vpx_mem.c
new file mode 100644 (file)
index 0000000..002e407
--- /dev/null
@@ -0,0 +1,950 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#define __VPX_MEM_C__
+
+#include "vpx_mem.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef CONFIG_MEM_MANAGER
+# if defined(VXWORKS)
+#  define CONFIG_MEM_MANAGER  1 //include heap manager functionality,
+//default: enabled on vxworks
+# else
+#  define CONFIG_MEM_MANAGER  0 //include heap manager functionality
+# endif
+#endif
+
+#ifndef CONFIG_MEM_TRACKER
+# define CONFIG_MEM_TRACKER     1 //include xvpx_* calls in the lib
+#endif
+
+#ifndef CONFIG_MEM_CHECKS
+# define CONFIG_MEM_CHECKS      0 //include some basic safety checks in
+//vpx_memcpy, _memset, and _memmove
+#endif
+
+#ifndef USE_GLOBAL_FUNCTION_POINTERS
+# define USE_GLOBAL_FUNCTION_POINTERS   0  //use function pointers instead of compiled functions.
+#endif
+
+#if CONFIG_MEM_TRACKER
+# include "vpx_mem_tracker.h"
+# if VPX_MEM_TRACKER_VERSION_CHIEF != 2 || VPX_MEM_TRACKER_VERSION_MAJOR != 5
+#  error "vpx_mem requires memory tracker version 2.5 to track memory usage"
+# endif
+#endif
+
+#define ADDRESS_STORAGE_SIZE      sizeof(size_t)
+
+#ifndef DEFAULT_ALIGNMENT
+# if defined(VXWORKS)
+#  define DEFAULT_ALIGNMENT        32        //default addr alignment to use in
+//calls to vpx_* functions other
+//than vpx_memalign
+# else
+#  define DEFAULT_ALIGNMENT        1
+# endif
+#endif
+
+#if DEFAULT_ALIGNMENT < 1
+# error "DEFAULT_ALIGNMENT must be >= 1!"
+#endif
+
+#if CONFIG_MEM_TRACKER
+# define TRY_BOUNDS_CHECK         1         //when set to 1 pads each allocation,
+//integrity can be checked using
+//vpx_memory_tracker_check_integrity
+//or on free by defining
+//TRY_BOUNDS_CHECK_ON_FREE
+static unsigned long g_alloc_count = 0;
+
+#else
+# define TRY_BOUNDS_CHECK         0
+#endif
+
+#if TRY_BOUNDS_CHECK
+# define TRY_BOUNDS_CHECK_ON_FREE 0          //checks mem integrity on every
+//free, very expensive
+# define BOUNDS_CHECK_VALUE       0xdeadbeef //value stored before/after ea.
+//mem addr for bounds checking
+# define BOUNDS_CHECK_PAD_SIZE    32         //size of the padding before and
+//after ea allocation to be filled
+//with BOUNDS_CHECK_VALUE.
+//this should be a multiple of 4
+#else
+# define BOUNDS_CHECK_VALUE       0
+# define BOUNDS_CHECK_PAD_SIZE    0
+#endif
+
+#if CONFIG_MEM_MANAGER
+# include "heapmm.h"
+# include "hmm_intrnl.h"
+
+# define SHIFT_HMM_ADDR_ALIGN_UNIT 5
+# define TOTAL_MEMORY_TO_ALLOCATE  20971520 // 20 * 1024 * 1024
+
+# define MM_DYNAMIC_MEMORY 1
+# if MM_DYNAMIC_MEMORY
+static unsigned char *g_p_mng_memory_raw = NULL;
+static unsigned char *g_p_mng_memory     = NULL;
+# else
+static unsigned char g_p_mng_memory[TOTAL_MEMORY_TO_ALLOCATE];
+# endif
+
+static size_t g_mm_memory_size = TOTAL_MEMORY_TO_ALLOCATE;
+
+static hmm_descriptor hmm_d;
+static int g_mng_memory_allocated = 0;
+
+static int vpx_mm_create_heap_memory();
+static void *vpx_mm_realloc(void *memblk, size_t size);
+#endif //CONFIG_MEM_MANAGER
+
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+struct GLOBAL_FUNC_POINTERS
+{
+    g_malloc_func g_malloc;
+    g_calloc_func g_calloc;
+    g_realloc_func g_realloc;
+    g_free_func g_free;
+    g_memcpy_func g_memcpy;
+    g_memset_func g_memset;
+    g_memmove_func g_memmove;
+};
+struct GLOBAL_FUNC_POINTERS *g_func = 0;
+
+# define VPX_MALLOC_L  g_func->g_malloc
+# define VPX_REALLOC_L g_func->g_realloc
+# define VPX_FREE_L    g_func->g_free
+# define VPX_MEMCPY_L  g_func->g_memcpy
+# define VPX_MEMSET_L  g_func->g_memset
+# define VPX_MEMMOVE_L g_func->g_memmove
+
+#else
+# define VPX_MALLOC_L  malloc
+# define VPX_REALLOC_L realloc
+# define VPX_FREE_L    free
+# define VPX_MEMCPY_L  memcpy
+# define VPX_MEMSET_L  memset
+# define VPX_MEMMOVE_L memmove
+#endif // USE_GLOBAL_FUNCTION_POINTERS
+
+/* Should probably use a vpx_mem logger function. */
+#define __REMOVE_PRINTFS
+#ifdef __REMOVE_PRINTFS
+#define _P(x)
+#else
+#define _P(x) x
+#endif
+
+/*returns an addr aligned to the byte boundary specified by align*/
+#define align_addr(addr,align) \
+    (void*)(((size_t)(addr) + ((align) - 1)) & (size_t)-(align))
+
+unsigned int vpx_mem_get_version()
+{
+    unsigned int ver = ((unsigned int)(unsigned char)VPX_MEM_VERSION_CHIEF << 24 |
+                        (unsigned int)(unsigned char)VPX_MEM_VERSION_MAJOR << 16 |
+                        (unsigned int)(unsigned char)VPX_MEM_VERSION_MINOR << 8  |
+                        (unsigned int)(unsigned char)VPX_MEM_VERSION_PATCH);
+    return ver;
+}
+
+int vpx_mem_set_heap_size(size_t size)
+{
+    int ret = -1;
+
+#if CONFIG_MEM_MANAGER
+#if MM_DYNAMIC_MEMORY
+
+    if (!g_mng_memory_allocated && size)
+    {
+        g_mm_memory_size = size;
+        ret = 0;
+    }
+    else
+        ret = -3;
+
+#else
+    ret = -2;
+#endif
+#else
+    (void)size;
+#endif
+
+    return ret;
+}
+
+void *vpx_memalign(size_t align, size_t size)
+{
+    void *addr,
+         * x = NULL;
+
+#if CONFIG_MEM_MANAGER
+    int number_aau;
+
+    if (vpx_mm_create_heap_memory() < 0)
+    {
+        _P(printf("[vpx][mm] ERROR vpx_memalign() Couldn't create memory for Heap.\n");)
+    }
+
+    number_aau = ((size + align - 1 + ADDRESS_STORAGE_SIZE) >>
+                  SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
+
+    addr = hmm_alloc(&hmm_d, number_aau);
+#else
+    addr = VPX_MALLOC_L(size + align - 1 + ADDRESS_STORAGE_SIZE);
+#endif //CONFIG_MEM_MANAGER
+
+    if (addr)
+    {
+        x = align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, (int)align);
+        /* save the actual malloc address */
+        ((size_t *)x)[-1] = (size_t)addr;
+    }
+
+    return x;
+}
+
+void *vpx_malloc(size_t size)
+{
+    return vpx_memalign(DEFAULT_ALIGNMENT, size);
+}
+
+void *vpx_calloc(size_t num, size_t size)
+{
+    void *x;
+
+    x = vpx_memalign(DEFAULT_ALIGNMENT, num * size);
+
+    if (x)
+        VPX_MEMSET_L(x, 0, num * size);
+
+    return x;
+}
+
+void *vpx_realloc(void *memblk, size_t size)
+{
+    void *addr,
+         * new_addr = NULL;
+    int align = DEFAULT_ALIGNMENT;
+
+    /*
+    The realloc() function changes the size of the object pointed to by
+    ptr to the size specified by size, and returns a pointer to the
+    possibly moved block. The contents are unchanged up to the lesser
+    of the new and old sizes. If ptr is null, realloc() behaves like
+    malloc() for the specified size. If size is zero (0) and ptr is
+    not a null pointer, the object pointed to is freed.
+    */
+    if (!memblk)
+        new_addr = vpx_malloc(size);
+    else if (!size)
+        vpx_free(memblk);
+    else
+    {
+        addr   = (void *)(((size_t *)memblk)[-1]);
+        memblk = NULL;
+
+#if CONFIG_MEM_MANAGER
+        new_addr = vpx_mm_realloc(addr, size + align + ADDRESS_STORAGE_SIZE);
+#else
+        new_addr = VPX_REALLOC_L(addr, size + align + ADDRESS_STORAGE_SIZE);
+#endif
+
+        if (new_addr)
+        {
+            addr = new_addr;
+            new_addr = (void *)(((size_t)
+                                 ((unsigned char *)new_addr + ADDRESS_STORAGE_SIZE) + (align - 1)) &
+                                (size_t) - align);
+            /* save the actual malloc address */
+            ((size_t *)new_addr)[-1] = (size_t)addr;
+        }
+    }
+
+    return new_addr;
+}
+
+void vpx_free(void *memblk)
+{
+    if (memblk)
+    {
+        void *addr = (void *)(((size_t *)memblk)[-1]);
+#if CONFIG_MEM_MANAGER
+        hmm_free(&hmm_d, addr);
+#else
+        VPX_FREE_L(addr);
+#endif
+    }
+}
+
+void *vpx_mem_alloc(int id, size_t size, size_t align)
+{
+#if defined CHIP_DM642 || defined __uClinux__
+    void *mem = (void *)mem_alloc(id, size, align);
+
+    if (!mem)
+    {
+        _P(fprintf(stderr,
+                   "\n"
+                   "*********************************************************\n"
+                   "WARNING: mem_alloc returned 0 for id=%p size=%u align=%u.\n"
+                   "*********************************************************\n",
+                   mem, size, align));
+        // should no longer need this.  Softier says it's fixed. 2005-01-21 tjf
+        //#if defined __uClinux__
+        //while(1)usleep(1000000);
+        //#endif
+    }
+
+#if defined __uClinux__
+    else if (mem == (void *)0xFFFFFFFF)
+    {
+        // out of memory/error
+        mem = (void *)0;
+
+        _P(fprintf(stderr,
+                   "\n"
+                   "******************************************************\n"
+                   "ERROR: mem_alloc id=%p size=%u align=%u OUT OF MEMORY.\n"
+                   "******************************************************\n",
+                   mem, size, align));
+    }
+
+#endif  // __uClinux__
+
+    return mem;
+#else
+    (void)id;
+    (void)size;
+    (void)align;
+    return (void *)0;
+#endif
+}
+
+void vpx_mem_free(int id, void *mem, size_t size)
+{
+#if defined CHIP_DM642 || defined __uClinux__
+
+    if (!mem)
+    {
+        _P(fprintf(stderr,
+                   "\n"
+                   "**************************************\n"
+                   "WARNING: 0 being free'd id=%p size=%u.\n"
+                   "**************************************\n",
+                   id, size));
+
+        // should no longer need this.  Softier says it's fixed. 2005-01-21 tjf
+        //#if defined __uClinux__
+        //while(1)usleep(1000000);
+        //#endif
+    }
+
+    mem_free(id, mem, size);
+#else
+    (void)id;
+    (void)mem;
+    (void)size;
+#endif
+}
+
+
+#if CONFIG_MEM_TRACKER
+
+void *xvpx_mem_alloc(int id, size_t size, size_t align, char *file, int line)
+{
+    void *mem = vpx_mem_alloc(id, size, align);
+
+    vpx_memory_tracker_add((size_t)mem, size, file, line, 0);
+
+    return mem;
+}
+
+void xvpx_mem_free(int id, void *mem, size_t size, char *file, int line)
+{
+    if (vpx_memory_tracker_remove((size_t)mem) == -2)
+    {
+#if REMOVE_PRINTFS
+        (void)file;
+        (void)line;
+#endif
+        _P(fprintf(stderr, "[vpx_mem][xvpx_mem_free] addr: %p (id=%p size=%u) "
+                   "not found in list; freed from file:%s"
+                   " line:%d\n", mem, id, size, file, line));
+    }
+
+    vpx_mem_free(id, mem, size);
+}
+
+void *xvpx_memalign(size_t align, size_t size, char *file, int line)
+{
+#if TRY_BOUNDS_CHECK
+    unsigned char *x_bounds;
+#endif
+
+    void *x;
+
+    if (g_alloc_count == 0)
+    {
+#if TRY_BOUNDS_CHECK
+        int i_rv = vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE);
+#else
+        int i_rv = vpx_memory_tracker_init(0, 0);
+#endif
+
+        if (i_rv < 0)
+        {
+            _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");)
+        }
+    }
+
+#if TRY_BOUNDS_CHECK
+    {
+        int i;
+        unsigned int tempme = BOUNDS_CHECK_VALUE;
+
+        x_bounds = vpx_memalign(align, size + (BOUNDS_CHECK_PAD_SIZE * 2));
+
+        if (x_bounds)
+        {
+            /*we're aligning the address twice here but to keep things
+              consistent we want to have the padding come before the stored
+              address so no matter what free function gets called we will
+              attempt to free the correct address*/
+            x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]);
+            x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE,
+                           (int)align);
+            /* save the actual malloc address */
+            ((size_t *)x)[-1] = (size_t)x_bounds;
+
+            for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int))
+            {
+                VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int));
+                VPX_MEMCPY_L((unsigned char *)x + size + i,
+                             &tempme, sizeof(unsigned int));
+            }
+        }
+        else
+            x = NULL;
+    }
+#else
+    x = vpx_memalign(align, size);
+#endif //TRY_BOUNDS_CHECK
+
+    g_alloc_count++;
+
+    vpx_memory_tracker_add((size_t)x, size, file, line, 1);
+
+    return x;
+}
+
+void *xvpx_malloc(size_t size, char *file, int line)
+{
+    return xvpx_memalign(DEFAULT_ALIGNMENT, size, file, line);
+}
+
+void *xvpx_calloc(size_t num, size_t size, char *file, int line)
+{
+    void *x = xvpx_memalign(DEFAULT_ALIGNMENT, num * size, file, line);
+
+    if (x)
+        VPX_MEMSET_L(x, 0, num * size);
+
+    return x;
+}
+
+void *xvpx_realloc(void *memblk, size_t size, char *file, int line)
+{
+    struct mem_block *p = NULL;
+    int orig_size = 0,
+        orig_line = 0;
+    char *orig_file = NULL;
+
+#if TRY_BOUNDS_CHECK
+    unsigned char *x_bounds = memblk ?
+                              (unsigned char *)(((size_t *)memblk)[-1]) :
+                              NULL;
+#endif
+
+    void *x;
+
+    if (g_alloc_count == 0)
+    {
+#if TRY_BOUNDS_CHECK
+
+        if (!vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE))
+#else
+        if (!vpx_memory_tracker_init(0, 0))
+#endif
+        {
+            _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");)
+        }
+    }
+
+    if (p = vpx_memory_tracker_find((size_t)memblk))
+    {
+        orig_size = p->size;
+        orig_file = p->file;
+        orig_line = p->line;
+    }
+
+#if TRY_BOUNDS_CHECK_ON_FREE
+    vpx_memory_tracker_check_integrity(file, line);
+#endif
+
+    //have to do this regardless of success, because
+    //the memory that does get realloc'd may change
+    //the bounds values of this block
+    vpx_memory_tracker_remove((size_t)memblk);
+
+#if TRY_BOUNDS_CHECK
+    {
+        int i;
+        unsigned int tempme = BOUNDS_CHECK_VALUE;
+
+        x_bounds = vpx_realloc(memblk, size + (BOUNDS_CHECK_PAD_SIZE * 2));
+
+        if (x_bounds)
+        {
+            x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]);
+            x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE,
+                           (int)DEFAULT_ALIGNMENT);
+            /* save the actual malloc address */
+            ((size_t *)x)[-1] = (size_t)x_bounds;
+
+            for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int))
+            {
+                VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int));
+                VPX_MEMCPY_L((unsigned char *)x + size + i,
+                             &tempme, sizeof(unsigned int));
+            }
+        }
+        else
+            x = NULL;
+    }
+#else
+    x = vpx_realloc(memblk, size);
+#endif //TRY_BOUNDS_CHECK
+
+    if (x)
+        vpx_memory_tracker_add((size_t)x, size, file, line, 1);
+    else
+        vpx_memory_tracker_add((size_t)memblk, orig_size, orig_file, orig_line, 1);
+
+    return x;
+}
+
+void xvpx_free(void *p_address, char *file, int line)
+{
+#if TRY_BOUNDS_CHECK
+    unsigned char *p_bounds_address = (unsigned char *)p_address;
+    //p_bounds_address -= BOUNDS_CHECK_PAD_SIZE;
+#endif
+
+#if !TRY_BOUNDS_CHECK_ON_FREE
+    (void)file;
+    (void)line;
+#endif
+
+    if (p_address)
+    {
+#if TRY_BOUNDS_CHECK_ON_FREE
+        vpx_memory_tracker_check_integrity(file, line);
+#endif
+
+        //if the addr isn't found in the list, assume it was allocated via
+        //vpx_ calls not xvpx_, therefore it does not contain any padding
+        if (vpx_memory_tracker_remove((size_t)p_address) == -2)
+        {
+            p_bounds_address = p_address;
+            _P(fprintf(stderr, "[vpx_mem][xvpx_free] addr: %p not found in"
+                       " list; freed from file:%s"
+                       " line:%d\n", p_address, file, line));
+        }
+        else
+            --g_alloc_count;
+
+#if TRY_BOUNDS_CHECK
+        vpx_free(p_bounds_address);
+#else
+        vpx_free(p_address);
+#endif
+
+        if (!g_alloc_count)
+            vpx_memory_tracker_destroy();
+    }
+}
+
+#endif /*CONFIG_MEM_TRACKER*/
+
+#if CONFIG_MEM_CHECKS
+#if defined(VXWORKS)
+#include <task_lib.h> //for task_delay()
+/* This function is only used to get a stack trace of the player
+object so we can se where we are having a problem. */
+static int get_my_tt(int task)
+{
+    tt(task);
+
+    return 0;
+}
+
+static void vx_sleep(int msec)
+{
+    int ticks_to_sleep = 0;
+
+    if (msec)
+    {
+        int msec_per_tick = 1000 / sys_clk_rate_get();
+
+        if (msec < msec_per_tick)
+            ticks_to_sleep++;
+        else
+            ticks_to_sleep = msec / msec_per_tick;
+    }
+
+    task_delay(ticks_to_sleep);
+}
+#endif
+#endif
+
+void *vpx_memcpy(void *dest, const void *source, size_t length)
+{
+#if CONFIG_MEM_CHECKS
+
+    if (((int)dest < 0x4000) || ((int)source < 0x4000))
+    {
+        _P(printf("WARNING: vpx_memcpy dest:0x%x source:0x%x len:%d\n", (int)dest, (int)source, length);)
+
+#if defined(VXWORKS)
+        sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
+
+        vx_sleep(10000);
+#endif
+    }
+
+#endif
+
+    return VPX_MEMCPY_L(dest, source, length);
+}
+
+void *vpx_memset(void *dest, int val, size_t length)
+{
+#if CONFIG_MEM_CHECKS
+
+    if ((int)dest < 0x4000)
+    {
+        _P(printf("WARNING: vpx_memset dest:0x%x val:%d len:%d\n", (int)dest, val, length);)
+
+#if defined(VXWORKS)
+        sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
+
+        vx_sleep(10000);
+#endif
+    }
+
+#endif
+
+    return VPX_MEMSET_L(dest, val, length);
+}
+
+void *vpx_memmove(void *dest, const void *src, size_t count)
+{
+#if CONFIG_MEM_CHECKS
+
+    if (((int)dest < 0x4000) || ((int)src < 0x4000))
+    {
+        _P(printf("WARNING: vpx_memmove dest:0x%x src:0x%x count:%d\n", (int)dest, (int)src, count);)
+
+#if defined(VXWORKS)
+        sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
+
+        vx_sleep(10000);
+#endif
+    }
+
+#endif
+
+    return VPX_MEMMOVE_L(dest, src, count);
+}
+
+#if CONFIG_MEM_MANAGER
+
+static int vpx_mm_create_heap_memory()
+{
+    int i_rv = 0;
+
+    if (!g_mng_memory_allocated)
+    {
+#if MM_DYNAMIC_MEMORY
+        g_p_mng_memory_raw =
+            (unsigned char *)malloc(g_mm_memory_size + HMM_ADDR_ALIGN_UNIT);
+
+        if (g_p_mng_memory_raw)
+        {
+            g_p_mng_memory = (unsigned char *)((((unsigned int)g_p_mng_memory_raw) +
+                                                HMM_ADDR_ALIGN_UNIT - 1) &
+                                               -(int)HMM_ADDR_ALIGN_UNIT);
+
+            _P(printf("[vpx][mm] total memory size:%d g_p_mng_memory_raw:0x%x g_p_mng_memory:0x%x\n"
+                      , g_mm_memory_size + HMM_ADDR_ALIGN_UNIT
+                      , (unsigned int)g_p_mng_memory_raw
+                      , (unsigned int)g_p_mng_memory);)
+        }
+        else
+        {
+            _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n"
+                      , g_mm_memory_size);)
+
+            i_rv = -1;
+        }
+
+        if (g_p_mng_memory)
+#endif
+        {
+            int chunk_size = 0;
+
+            g_mng_memory_allocated = 1;
+
+            hmm_init(&hmm_d);
+
+            chunk_size = g_mm_memory_size >> SHIFT_HMM_ADDR_ALIGN_UNIT;
+
+            chunk_size -= DUMMY_END_BLOCK_BAUS;
+
+            _P(printf("[vpx][mm] memory size:%d for vpx memory manager. g_p_mng_memory:0x%x  chunk_size:%d\n"
+                      , g_mm_memory_size
+                      , (unsigned int)g_p_mng_memory
+                      , chunk_size);)
+
+            hmm_new_chunk(&hmm_d, (void *)g_p_mng_memory, chunk_size);
+        }
+
+#if MM_DYNAMIC_MEMORY
+        else
+        {
+            _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n"
+                      , g_mm_memory_size);)
+
+            i_rv = -1;
+        }
+
+#endif
+    }
+
+    return i_rv;
+}
+
+static void *vpx_mm_realloc(void *memblk, size_t size)
+{
+    void *p_ret = NULL;
+
+    if (vpx_mm_create_heap_memory() < 0)
+    {
+        _P(printf("[vpx][mm] ERROR vpx_mm_realloc() Couldn't create memory for Heap.\n");)
+    }
+    else
+    {
+        int i_rv = 0;
+        int old_num_aaus;
+        int new_num_aaus;
+
+        old_num_aaus = hmm_true_size(memblk);
+        new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
+
+        if (old_num_aaus == new_num_aaus)
+        {
+            p_ret = memblk;
+        }
+        else
+        {
+            i_rv = hmm_resize(&hmm_d, memblk, new_num_aaus);
+
+            if (i_rv == 0)
+            {
+                p_ret = memblk;
+            }
+            else
+            {
+                /* Error. Try to malloc and then copy data. */
+                void *p_from_malloc;
+
+                new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
+                p_from_malloc  = hmm_alloc(&hmm_d, new_num_aaus);
+
+                if (p_from_malloc)
+                {
+                    vpx_memcpy(p_from_malloc, memblk, size);
+                    hmm_free(&hmm_d, memblk);
+
+                    p_ret = p_from_malloc;
+                }
+            }
+        }
+    }
+
+    return p_ret;
+}
+#endif //CONFIG_MEM_MANAGER
+
+#if USE_GLOBAL_FUNCTION_POINTERS
+# if CONFIG_MEM_TRACKER
+extern int vpx_memory_tracker_set_functions(g_malloc_func g_malloc_l
+        , g_calloc_func g_calloc_l
+        , g_realloc_func g_realloc_l
+        , g_free_func g_free_l
+        , g_memcpy_func g_memcpy_l
+        , g_memset_func g_memset_l
+        , g_memmove_func g_memmove_l);
+# endif
+#endif
+int vpx_mem_set_functions(g_malloc_func g_malloc_l
+                          , g_calloc_func g_calloc_l
+                          , g_realloc_func g_realloc_l
+                          , g_free_func g_free_l
+                          , g_memcpy_func g_memcpy_l
+                          , g_memset_func g_memset_l
+                          , g_memmove_func g_memmove_l)
+{
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+    /* If use global functions is turned on then the
+    application must set the global functions before
+    it does anything else or vpx_mem will have
+    unpredictable results. */
+    if (!g_func)
+    {
+        g_func = (struct GLOBAL_FUNC_POINTERS *)g_malloc_l(sizeof(struct GLOBAL_FUNC_POINTERS));
+
+        if (!g_func)
+        {
+            return -1;
+        }
+    }
+
+#if CONFIG_MEM_TRACKER
+    {
+        int rv = 0;
+        rv = vpx_memory_tracker_set_functions(g_malloc_l
+                                              , g_calloc_l
+                                              , g_realloc_l
+                                              , g_free_l
+                                              , g_memcpy_l
+                                              , g_memset_l
+                                              , g_memmove_l);
+
+        if (rv < 0)
+        {
+            return rv;
+        }
+    }
+#endif
+
+    if (g_malloc_l)
+        g_func->g_malloc = g_malloc_l;
+    else
+        g_func->g_malloc = 0;
+
+    if (g_calloc_l)
+        g_func->g_calloc = g_calloc_l;
+    else
+        g_func->g_calloc = 0;
+
+    if (g_realloc_l)
+        g_func->g_realloc = g_realloc_l;
+    else
+        g_func->g_realloc = 0;
+
+    if (g_free_l)
+        g_func->g_free = g_free_l;
+    else
+        g_func->g_free = 0;
+
+    if (g_memcpy_l)
+        g_func->g_memcpy = g_memcpy_l;
+    else
+        g_func->g_memcpy = 0;
+
+    if (g_memset_l)
+        g_func->g_memset = g_memset_l;
+    else
+        g_func->g_memset = 0;
+
+    if (g_memmove_l)
+        g_func->g_memmove = g_memmove_l;
+    else
+        g_func->g_memmove = 0;
+
+    return 0;
+#else
+    (void)g_malloc_l;
+    (void)g_calloc_l;
+    (void)g_realloc_l;
+    (void)g_free_l;
+    (void)g_memcpy_l;
+    (void)g_memset_l;
+    (void)g_memmove_l;
+    return -1;
+#endif
+}
+
+int vpx_mem_unset_functions()
+{
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+    if (g_func)
+    {
+        g_free_func temp_free;
+
+        temp_free = g_func->g_free;
+
+        temp_free(g_func);
+        g_func = 0;
+    }
+
+#endif
+    return 0;
+}
+
+#ifdef _INTEL_LINUX
+void *_intel_fast_memcpy(void *dest, const void *src, size_t count)
+{
+
+    //memcpy(dest, src, count);
+    char *dst8 = (char *)dest;
+    char *src8 = (char *)src;
+
+    while (count--)
+    {
+        *dst8++ = *src8++;
+    }
+
+    return dest;
+}
+
+void *_intel_fast_memset(void *dest, int c, size_t count)
+{
+    memset(dest, c, count);
+    return dest;
+}
+
+void *_VEC_memzero(void *dest, int c, size_t count)
+{
+    memset(dest, 0, count);
+    return dest;
+}
+
+#endif //_ICC
diff --git a/vpx_mem/intel_linux/vpx_mem_tracker.c b/vpx_mem/intel_linux/vpx_mem_tracker.c
new file mode 100644 (file)
index 0000000..fa023e3
--- /dev/null
@@ -0,0 +1,811 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+  vpx_mem_tracker.c
+
+  jwz 2003-09-30:
+   Stores a list of addreses, their size, and file and line they came from.
+   All exposed lib functions are prefaced by vpx_ and allow the global list
+   to be thread safe.
+   Current supported platforms are:
+    Linux, Win32, win_ce and vx_works
+   Further support can be added by defining the platform specific mutex
+   in the memory_tracker struct as well as calls to create/destroy/lock/unlock
+   the mutex in vpx_memory_tracker_init/Destroy and memory_tracker_lock_mutex/unlock_mutex
+*/
+
+#define NO_MUTEX
+
+#if defined(__uClinux__)
+# include <lddk.h>
+#endif
+
+#if defined(LINUX) || defined(__uClinux__)
+# include <pthread.h>
+#elif defined(WIN32) || defined(_WIN32_WCE)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <winbase.h>
+#elif defined(VXWORKS)
+# include <sem_lib.h>
+#elif defined(NDS_NITRO)
+# include <nitro.h>
+# include <nitro/os.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> //VXWORKS doesn't have a malloc/memory.h file,
+//this should pull in malloc,free,etc.
+#include <stdarg.h>
+
+#include "vpx_mem_tracker.h"
+
+#undef vpx_malloc   //undefine any vpx_mem macros that may affect calls to
+#undef vpx_free     //memory functions in this file
+#undef vpx_memcpy
+#undef vpx_memset
+
+
+#ifndef USE_GLOBAL_FUNCTION_POINTERS
+# define USE_GLOBAL_FUNCTION_POINTERS   0  //use function pointers instead of compiled functions.
+#endif
+
+#if USE_GLOBAL_FUNCTION_POINTERS
+static mem_track_malloc_func g_malloc   = malloc;
+static mem_track_calloc_func g_calloc   = calloc;
+static mem_track_realloc_func g_realloc = realloc;
+static mem_track_free_func g_free       = free;
+static mem_track_memcpy_func g_memcpy   = memcpy;
+static mem_track_memset_func g_memset   = memset;
+static mem_track_memmove_func g_memmove = memmove;
+# define MEM_TRACK_MALLOC g_malloc
+# define MEM_TRACK_FREE   g_free
+# define MEM_TRACK_MEMCPY g_memcpy
+# define MEM_TRACK_MEMSET g_memset
+#else
+# define MEM_TRACK_MALLOC vpx_malloc
+# define MEM_TRACK_FREE   vpx_free
+# define MEM_TRACK_MEMCPY vpx_memcpy
+# define MEM_TRACK_MEMSET vpx_memset
+#endif // USE_GLOBAL_FUNCTION_POINTERS
+
+
+struct memory_tracker
+{
+    struct mem_block *head,
+            * tail;
+    int len,
+        totalsize;
+    unsigned int current_allocated,
+             max_allocated;
+
+#if defined(LINUX) || defined(__uClinux__)
+    pthread_mutex_t mutex;
+#elif defined(WIN32) || defined(_WIN32_WCE)
+    HANDLE mutex;
+#elif defined(VXWORKS)
+    SEM_ID mutex;
+#elif defined(NDS_NITRO)
+    OSMutex mutex;
+#elif defined(NO_MUTEX)
+#else
+#error "No mutex type defined for this platform!"
+#endif
+
+    int padding_size,
+        pad_value;
+};
+
+/* prototypes for internal library functions */
+static void memtrack_log(const char *fmt, ...);
+static void memory_tracker_dump();
+static void memory_tracker_check_integrity(char *file, unsigned int line);
+static void memory_tracker_add(size_t addr, unsigned int size,
+                               char *file, unsigned int line,
+                               int padded);
+static int memory_tracker_remove(size_t addr);
+static struct mem_block *memory_tracker_find(size_t addr);
+
+#if defined(NO_MUTEX)
+# define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited)
+# define memory_tracker_unlock_mutex()
+#else
+static int memory_tracker_lock_mutex();
+static int memory_tracker_unlock_mutex();
+#endif
+
+static struct memory_tracker memtrack;   //our global memory allocation list
+static int g_b_mem_tracker_inited = 0;     //indicates whether the global list has
+//been initialized (1:yes/0:no)
+static struct
+{
+    FILE *file;
+    int type;
+    void (*func)(void *userdata, const char *fmt, va_list args);
+    void *userdata;
+} g_logging = {0};
+
+extern void *vpx_malloc(size_t size);
+extern void vpx_free(void *memblk);
+extern void *vpx_memcpy(void *dest, const void *src, size_t length);
+extern void *vpx_memset(void *dest, int val, size_t length);
+
+/*
+ *
+ * Exposed library functions
+ *
+*/
+
+/*
+    vpx_memory_tracker_init(int padding_size, int pad_value)
+      padding_size - the size of the padding before and after each mem addr.
+                     Values > 0 indicate that integrity checks can be performed
+                     by inspecting these areas.
+      pad_value - the initial value within the padding area before and after
+                  each mem addr.
+
+    Initializes global memory tracker structure
+    Allocates the head of the list
+*/
+int vpx_memory_tracker_init(int padding_size, int pad_value)
+{
+    if (!g_b_mem_tracker_inited)
+    {
+        if (memtrack.head = (struct mem_block *)MEM_TRACK_MALLOC(sizeof(struct mem_block)))
+        {
+            int ret;
+
+            MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block));
+
+            memtrack.tail = memtrack.head;
+
+            memtrack.current_allocated = 0;
+            memtrack.max_allocated     = 0;
+
+            memtrack.padding_size = padding_size;
+            memtrack.pad_value    = pad_value;
+
+#if defined(LINUX) || defined(__uClinux__)
+            ret = pthread_mutex_init(&memtrack.mutex,
+                                     NULL);            /*mutex attributes (NULL=default)*/
+#elif defined(WIN32) || defined(_WIN32_WCE)
+            memtrack.mutex = create_mutex(NULL,   /*security attributes*/
+                                          FALSE,  /*we don't want initial ownership*/
+                                          NULL);  /*mutex name*/
+            ret = !memtrack.mutex;
+#elif defined(VXWORKS)
+            memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based mutex*/
+                                         SEM_FULL);  /*SEM_FULL initial state is unlocked*/
+            ret = !memtrack.mutex;
+#elif defined(NDS_NITRO)
+            os_init_mutex(&memtrack.mutex);
+            ret = 0;
+#elif defined(NO_MUTEX)
+            ret = 0;
+#endif
+
+            if (ret)
+            {
+                memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n");
+
+                MEM_TRACK_FREE(memtrack.head);
+                memtrack.head = NULL;
+            }
+            else
+            {
+                memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version" pad_size:%d pad_val:0x%x %d\n"
+                             , padding_size
+                             , pad_value
+                             , pad_value);
+                g_b_mem_tracker_inited = 1;
+            }
+        }
+    }
+
+    return g_b_mem_tracker_inited;
+}
+
+/*
+    vpx_memory_tracker_destroy()
+    If our global struct was initialized zeros out all its members,
+    frees memory and destroys it's mutex
+*/
+void vpx_memory_tracker_destroy()
+{
+
+    if (!memory_tracker_lock_mutex())
+    {
+        struct mem_block *p  = memtrack.head,
+                                  * p2 = memtrack.head;
+
+        memory_tracker_dump();
+
+        while (p)
+    {
+            p2 = p;
+            p  = p->next;
+
+            MEM_TRACK_FREE(p2);
+        }
+
+        memtrack.head              = NULL;
+        memtrack.tail              = NULL;
+        memtrack.len               = 0;
+        memtrack.current_allocated = 0;
+        memtrack.max_allocated     = 0;
+
+        if ((g_logging.type == 0) && (g_logging.file != 0)) //&& (g_logging.file != stderr) )
+        {
+#if !defined(NDS_NITRO)
+            fclose(g_logging.file);
+#endif
+            g_logging.file = NULL;
+        }
+
+        memory_tracker_unlock_mutex();
+
+        g_b_mem_tracker_inited = 0;
+
+    }
+
+}
+
+/*
+    vpx_memory_tracker_add(size_t addr, unsigned int size,
+                         char * file, unsigned int line)
+      addr - memory address to be added to list
+      size - size of addr
+      file - the file addr was referenced from
+      line - the line in file addr was referenced from
+    Adds memory address addr, it's size, file and line it came from
+    to the global list via the thread safe internal library function
+*/
+void vpx_memory_tracker_add(size_t addr, unsigned int size,
+                            char *file, unsigned int line,
+                            int padded)
+{
+    memory_tracker_add(addr, size, file, line, padded);
+}
+
+/*
+    vpx_memory_tracker_remove(size_t addr)
+      addr - memory address to be removed from list
+    Removes addr from the global list via the thread safe
+    internal remove function
+    Return:
+      Same as described for memory_tracker_remove
+*/
+int vpx_memory_tracker_remove(size_t addr)
+{
+    return memory_tracker_remove(addr);
+}
+
+/*
+    vpx_memory_tracker_find(size_t addr)
+      addr - address to be found in list
+    Return:
+        If found, pointer to the memory block that matches addr
+        NULL otherwise
+*/
+struct mem_block *vpx_memory_tracker_find(size_t addr)
+{
+    struct mem_block *p = NULL;
+
+    if (!memory_tracker_lock_mutex())
+    {
+        p = memory_tracker_find(addr);
+        memory_tracker_unlock_mutex();
+    }
+
+    return p;
+}
+
+/*
+    vpx_memory_tracker_dump()
+    Locks the memory tracker's mutex and calls the internal
+    library function to dump the current contents of the
+    global memory allocation list
+*/
+void vpx_memory_tracker_dump()
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        memory_tracker_dump();
+        memory_tracker_unlock_mutex();
+    }
+}
+
+/*
+    vpx_memory_tracker_check_integrity(char* file, unsigned int line)
+      file - The file name where the check was placed
+      line - The line in file where the check was placed
+    Locks the memory tracker's mutex and calls the internal
+    integrity check function to inspect every address in the global
+    memory allocation list
+*/
+void vpx_memory_tracker_check_integrity(char *file, unsigned int line)
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        memory_tracker_check_integrity(file, line);
+        memory_tracker_unlock_mutex();
+    }
+}
+
+/*
+    vpx_memory_tracker_set_log_type
+    Sets the logging type for the memory tracker. Based on the value it will
+    direct its output to the appropriate place.
+    Return:
+      0: on success
+      -1: if the logging type could not be set, because the value was invalid
+          or because a file could not be opened
+*/
+int vpx_memory_tracker_set_log_type(int type, char *option)
+{
+    int ret = -1;
+
+
+    switch (type)
+    {
+    case 0:
+        g_logging.type = 0;
+
+        if (!option)
+        {
+            // g_logging.file = stderr;
+            ret = 0;
+        }
+
+#if !defined(NDS_NITRO)
+        else
+        {
+            if (g_logging.file = fopen((char *)option, "w"))
+                ret = 0;
+        }
+
+#endif
+        break;
+#if defined(WIN32) && !defined(_WIN32_WCE)
+    case 1:
+        g_logging.type = type;
+        ret = 0;
+        break;
+#endif
+    default:
+        break;
+    }
+
+    //output the version to the new logging destination
+    if (!ret)
+        memtrack_log("Memory Tracker logging initialized, "
+                     "Memory Tracker v."vpx_mem_tracker_version"\n");
+
+    return ret;
+}
+
+/*
+    vpx_memory_tracker_set_log_func
+    Sets a logging function to be used by the memory tracker.
+    Return:
+      0: on success
+      -1: if the logging type could not be set because logfunc was NULL
+*/
+int vpx_memory_tracker_set_log_func(void *userdata,
+                                    void(*logfunc)(void *userdata,
+                                            const char *fmt, va_list args))
+{
+    int ret = -1;
+
+    if (logfunc)
+    {
+        g_logging.type     = -1;
+        g_logging.userdata = userdata;
+        g_logging.func     = logfunc;
+        ret = 0;
+    }
+
+    //output the version to the new logging destination
+    if (!ret)
+        memtrack_log("Memory Tracker logging initialized, "
+                     "Memory Tracker v."vpx_mem_tracker_version"\n");
+
+    return ret;
+}
+
+/*
+ *
+ * END - Exposed library functions
+ *
+*/
+
+
+/*
+ *
+ * Internal library functions
+ *
+*/
+
+static void memtrack_log(const char *fmt, ...)
+{
+    va_list list;
+
+    va_start(list, fmt);
+
+    switch (g_logging.type)
+    {
+    case -1:
+
+        if (g_logging.func)
+            g_logging.func(g_logging.userdata, fmt, list);
+
+        break;
+    case 0:
+
+        if (g_logging.file)
+        {
+            vfprintf(g_logging.file, fmt, list);
+            fflush(g_logging.file);
+        }
+
+        break;
+#if defined(WIN32) && !defined(_WIN32_WCE)
+    case 1:
+    {
+        char temp[1024];
+        _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list);
+        output_debug_string(temp);
+    }
+    break;
+#endif
+    default:
+        break;
+    }
+
+    va_end(list);
+}
+
+/*
+    memory_tracker_dump()
+    Dumps the current contents of the global memory allocation list
+*/
+static void memory_tracker_dump()
+{
+    int i = 0;
+    struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL);
+
+    memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n",
+                 memtrack.current_allocated, memtrack.max_allocated);
+
+    while (p)
+    {
+#if defined(WIN32) && !defined(_WIN32_WCE)
+
+        /*when using outputdebugstring, output filenames so they
+          can be clicked to be opened in visual studio*/
+        if (g_logging.type == 1)
+            memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file:\n"
+                         "  %s(%d):\n", i,
+                         p->addr, i, p->size,
+                         p->file, p->line);
+        else
+#endif
+            memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s, line: %d\n", i,
+                         p->addr, i, p->size,
+                         p->file, p->line);
+
+        p = p->next;
+        ++i;
+    }
+
+    memtrack_log("\n");
+}
+
+/*
+    memory_tracker_check_integrity(char* file, unsigned int file)
+      file - the file name where the check was placed
+      line - the line in file where the check was placed
+    If a padding_size was supplied to vpx_memory_tracker_init()
+    this function will check ea. addr in the list verifying that
+    addr-padding_size and addr+padding_size is filled with pad_value
+*/
+static void memory_tracker_check_integrity(char *file, unsigned int line)
+{
+    if (memtrack.padding_size)
+    {
+        int i,
+            index = 0;
+        unsigned char *p_show_me,
+                 * p_show_me2;
+        unsigned int tempme = memtrack.pad_value,
+                     dead1,
+                     dead2;
+        unsigned char *x_bounds;
+        struct mem_block *p = memtrack.head->next;
+
+        while (p)
+        {
+            //x_bounds = (unsigned char*)p->addr;
+            //back up VPX_BYTE_ALIGNMENT
+            //x_bounds -= memtrack.padding_size;
+
+            if (p->padded)   // can the bounds be checked?
+            {
+                /*yes, move to the address that was actually allocated
+                by the vpx_* calls*/
+                x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]);
+
+                for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int))
+                {
+                    p_show_me = (x_bounds + i);
+                    p_show_me2 = (unsigned char *)(p->addr + p->size + i);
+
+                    MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int));
+                    MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int));
+
+                    if ((dead1 != tempme) || (dead2 != tempme))
+                    {
+                        memtrack_log("\n[vpx_mem integrity check failed]:\n"
+                                     "    index[%d] {%s:%d} addr=0x%x, size=%d,"
+                                     " file: %s, line: %d c0:0x%x c1:0x%x\n",
+                                     index, file, line, p->addr, p->size, p->file,
+                                     p->line, dead1, dead2);
+                    }
+                }
+            }
+
+            ++index;
+            p = p->next;
+        }
+    }
+}
+
+/*
+    memory_tracker_add(size_t addr, unsigned int size,
+                     char * file, unsigned int line)
+    Adds an address (addr), it's size, file and line number to our list.
+    Adjusts the total bytes allocated and max bytes allocated if necessary.
+    If memory cannot be allocated the list will be destroyed.
+*/
+void memory_tracker_add(size_t addr, unsigned int size,
+                        char *file, unsigned int line,
+                        int padded)
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        struct mem_block *p;
+
+        p = MEM_TRACK_MALLOC(sizeof(struct mem_block));
+
+        if (p)
+        {
+            p->prev       = memtrack.tail;
+            p->prev->next = p;
+            p->addr       = addr;
+            p->size       = size;
+            p->line       = line;
+            p->file       = file;
+            p->padded     = padded;
+            p->next       = NULL;
+
+            memtrack.tail = p;
+
+            memtrack.current_allocated += size;
+
+            if (memtrack.current_allocated > memtrack.max_allocated)
+                memtrack.max_allocated = memtrack.current_allocated;
+
+            //memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr);
+
+            memory_tracker_unlock_mutex();
+        }
+        else
+        {
+            memtrack_log("memory_tracker_add: error allocating memory!\n");
+            memory_tracker_unlock_mutex();
+            vpx_memory_tracker_destroy();
+        }
+    }
+}
+
+/*
+    memory_tracker_remove(size_t addr)
+    Removes an address and its corresponding size (if they exist)
+    from the memory tracker list and adjusts the current number
+    of bytes allocated.
+    Return:
+      0: on success
+      -1: if the mutex could not be locked
+      -2: if the addr was not found in the list
+*/
+int memory_tracker_remove(size_t addr)
+{
+    int ret = -1;
+
+    if (!memory_tracker_lock_mutex())
+    {
+        struct mem_block *p;
+
+        if (p = memory_tracker_find(addr))
+        {
+            memtrack.current_allocated -= p->size;
+
+            p->prev->next = p->next;
+
+            if (p->next)
+                p->next->prev = p->prev;
+            else
+                memtrack.tail = p->prev;
+
+            ret = 0;
+            MEM_TRACK_FREE(p);
+        }
+        else
+        {
+            memtrack_log("memory_tracker_remove(): addr not found in list, 0x%.8x\n", addr);
+            ret = -2;
+        }
+
+        memory_tracker_unlock_mutex();
+    }
+
+    return ret;
+}
+
+/*
+    memory_tracker_find(size_t addr)
+    Finds an address in our addrs list
+    NOTE: the mutex MUST be locked in the other internal
+          functions before calling this one. This avoids
+          the need for repeated locking and unlocking as in Remove
+    Returns: pointer to the mem block if found, NULL otherwise
+*/
+static struct mem_block *memory_tracker_find(size_t addr)
+{
+    struct mem_block *p = NULL;
+
+    if (memtrack.head)
+    {
+        p = memtrack.head->next;
+
+        while (p && (p->addr != addr))
+            p = p->next;
+    }
+
+    return p;
+}
+
+
+#if !defined(NO_MUTEX)
+/*
+    memory_tracker_lock_mutex()
+    Locks the memory tracker mutex with a platform specific call
+    Returns:
+        0: Success
+       <0: Failure, either the mutex was not initialized
+           or the call to lock the mutex failed
+*/
+static int memory_tracker_lock_mutex()
+{
+    int ret = -1;
+
+    if (g_b_mem_tracker_inited)
+    {
+
+#if defined(LINUX) || defined(__uClinux__)
+        ret = pthread_mutex_lock(&memtrack.mutex);
+#elif defined(WIN32) || defined(_WIN32_WCE)
+        ret = WaitForSingleObject(memtrack.mutex, INFINITE);
+#elif defined(VXWORKS)
+        ret = sem_take(memtrack.mutex, WAIT_FOREVER);
+#elif defined(NDS_NITRO)
+        os_lock_mutex(&memtrack.mutex);
+        ret = 0;
+#endif
+
+        if (ret)
+        {
+            memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n");
+        }
+    }
+
+    return ret;
+}
+
+/*
+    memory_tracker_unlock_mutex()
+    Unlocks the memory tracker mutex with a platform specific call
+    Returns:
+        0: Success
+       <0: Failure, either the mutex was not initialized
+           or the call to unlock the mutex failed
+*/
+static int memory_tracker_unlock_mutex()
+{
+    int ret = -1;
+
+    if (g_b_mem_tracker_inited)
+    {
+
+#if defined(LINUX) || defined(__uClinux__)
+        ret = pthread_mutex_unlock(&memtrack.mutex);
+#elif defined(WIN32) || defined(_WIN32_WCE)
+        ret = !release_mutex(memtrack.mutex);
+#elif defined(VXWORKS)
+        ret = sem_give(memtrack.mutex);
+#elif defined(NDS_NITRO)
+        os_unlock_mutex(&memtrack.mutex);
+        ret = 0;
+#endif
+
+        if (ret)
+        {
+            memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n");
+        }
+    }
+
+    return ret;
+}
+#endif
+
+/*
+    vpx_memory_tracker_set_functions
+
+    Sets the function pointers for the standard library functions.
+
+    Return:
+      0: on success
+      -1: if the use global function pointers is not set.
+*/
+int vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l
+                                     , mem_track_calloc_func g_calloc_l
+                                     , mem_track_realloc_func g_realloc_l
+                                     , mem_track_free_func g_free_l
+                                     , mem_track_memcpy_func g_memcpy_l
+                                     , mem_track_memset_func g_memset_l
+                                     , mem_track_memmove_func g_memmove_l)
+{
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+    if (g_malloc_l)
+        g_malloc = g_malloc_l;
+
+    if (g_calloc_l)
+        g_calloc = g_calloc_l;
+
+    if (g_realloc_l)
+        g_realloc = g_realloc_l;
+
+    if (g_free_l)
+        g_free = g_free_l;
+
+    if (g_memcpy_l)
+        g_memcpy = g_memcpy_l;
+
+    if (g_memset_l)
+        g_memset = g_memset_l;
+
+    if (g_memmove_l)
+        g_memmove = g_memmove_l;
+
+    return 0;
+#else
+    (void)g_malloc_l;
+    (void)g_calloc_l;
+    (void)g_realloc_l;
+    (void)g_free_l;
+    (void)g_memcpy_l;
+    (void)g_memset_l;
+    (void)g_memmove_l;
+    return -1;
+#endif
+}
diff --git a/vpx_mem/memory_manager/hmm_alloc.c b/vpx_mem/memory_manager/hmm_alloc.c
new file mode 100644 (file)
index 0000000..9abd81e
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+void *U(alloc)(U(descriptor) *desc, U(size_aau) n)
+{
+#ifdef HMM_AUDIT_FAIL
+
+    if (desc->avl_tree_root)
+        AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
+#endif
+
+        if (desc->last_freed)
+        {
+#ifdef HMM_AUDIT_FAIL
+            AUDIT_BLOCK(desc->last_freed)
+#endif
+
+            U(into_free_collection)(desc, (head_record *)(desc->last_freed));
+
+            desc->last_freed = 0;
+        }
+
+    /* Add space for block header. */
+    n += HEAD_AAUS;
+
+    /* Convert n from number of address alignment units to block alignment
+    ** units. */
+    n = DIV_ROUND_UP(n, HMM_BLOCK_ALIGN_UNIT);
+
+    if (n < MIN_BLOCK_BAUS)
+        n = MIN_BLOCK_BAUS;
+
+    {
+        /* Search for the first node of the bin containing the smallest
+        ** block big enough to satisfy request. */
+        ptr_record *ptr_rec_ptr =
+            U(avl_search)(
+                (U(avl_avl) *) & (desc->avl_tree_root), (U(size_bau)) n,
+                AVL_GREATER_EQUAL);
+
+        /* If an approprate bin is found, satisfy the allocation request,
+        ** otherwise return null pointer. */
+        return(ptr_rec_ptr ?
+               U(alloc_from_bin)(desc, ptr_rec_ptr, (U(size_bau)) n) : 0);
+    }
+}
diff --git a/vpx_mem/memory_manager/hmm_base.c b/vpx_mem/memory_manager/hmm_base.c
new file mode 100644 (file)
index 0000000..0cacc3f
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+void U(init)(U(descriptor) *desc)
+{
+    desc->avl_tree_root = 0;
+    desc->last_freed = 0;
+}
+
+/* Remove a free block from a bin's doubly-linked list when it is not,
+** the first block in the bin.
+*/
+void U(dll_remove)(
+    /* Pointer to pointer record in the block to be removed. */
+    ptr_record *to_remove)
+{
+    to_remove->prev->next = to_remove->next;
+
+    if (to_remove->next)
+        to_remove->next->prev = to_remove->prev;
+}
+
+/* Put a block into the free collection of a heap.
+*/
+void U(into_free_collection)(
+    /* Pointer to heap descriptor. */
+    U(descriptor) *desc,
+    /* Pointer to head record of block. */
+    head_record *head_ptr)
+{
+    ptr_record *ptr_rec_ptr = HEAD_TO_PTR_REC(head_ptr);
+
+    ptr_record *bin_front_ptr =
+        U(avl_insert)((U(avl_avl) *) & (desc->avl_tree_root), ptr_rec_ptr);
+
+    if (bin_front_ptr != ptr_rec_ptr)
+    {
+        /* The block was not inserted into the AVL tree because there is
+        ** already a bin for the size of the block. */
+
+        MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(head_ptr)
+        ptr_rec_ptr->self = ptr_rec_ptr;
+
+        /* Make the block the new second block in the bin's doubly-linked
+        ** list. */
+        ptr_rec_ptr->prev = bin_front_ptr;
+        ptr_rec_ptr->next = bin_front_ptr->next;
+        bin_front_ptr->next = ptr_rec_ptr;
+
+        if (ptr_rec_ptr->next)
+            ptr_rec_ptr->next->prev = ptr_rec_ptr;
+    }
+    else
+        /* Block is first block in new bin. */
+        ptr_rec_ptr->next = 0;
+}
+
+/* Allocate a block from a given bin.  Returns a pointer to the payload
+** of the removed block.  The "last freed" pointer must be null prior
+** to calling this function.
+*/
+void *U(alloc_from_bin)(
+    /* Pointer to heap descriptor. */
+    U(descriptor) *desc,
+    /* Pointer to pointer record of first block in bin. */
+    ptr_record *bin_front_ptr,
+    /* Number of BAUs needed in the allocated block.  If the block taken
+    ** from the bin is significantly larger than the number of BAUs needed,
+    ** the "extra" BAUs are split off to form a new free block. */
+    U(size_bau) n_baus)
+{
+    head_record *head_ptr;
+    U(size_bau) rem_baus;
+
+    if (bin_front_ptr->next)
+    {
+        /* There are multiple blocks in this bin.  Use the 2nd block in
+        ** the bin to avoid needless change to the AVL tree.
+        */
+
+        ptr_record *ptr_rec_ptr = bin_front_ptr->next;
+        head_ptr = PTR_REC_TO_HEAD(ptr_rec_ptr);
+
+#ifdef AUDIT_FAIL
+        AUDIT_BLOCK(head_ptr)
+#endif
+
+        U(dll_remove)(ptr_rec_ptr);
+    }
+    else
+    {
+        /* There is only one block in the bin, so it has to be removed
+        ** from the AVL tree.
+        */
+
+        head_ptr = PTR_REC_TO_HEAD(bin_front_ptr);
+
+        U(avl_remove)(
+            (U(avl_avl) *) &(desc->avl_tree_root), BLOCK_BAUS(head_ptr));
+    }
+
+    MARK_BLOCK_ALLOCATED(head_ptr)
+
+    rem_baus = BLOCK_BAUS(head_ptr) - n_baus;
+
+    if (rem_baus >= MIN_BLOCK_BAUS)
+    {
+        /* Since there are enough "extra" BAUs, split them off to form
+        ** a new free block.
+        */
+
+        head_record *rem_head_ptr =
+            (head_record *) BAUS_FORWARD(head_ptr, n_baus);
+
+        /* Change the next block's header to reflect the fact that the
+        ** block preceeding it is now smaller.
+        */
+        SET_PREV_BLOCK_BAUS(
+            BAUS_FORWARD(head_ptr, head_ptr->block_size), rem_baus)
+
+        head_ptr->block_size = n_baus;
+
+        rem_head_ptr->previous_block_size = n_baus;
+        rem_head_ptr->block_size = rem_baus;
+
+        desc->last_freed = rem_head_ptr;
+    }
+
+    return(HEAD_TO_PTR_REC(head_ptr));
+}
+
+/* Take a block out of the free collection.
+*/
+void U(out_of_free_collection)(
+    /* Descriptor of heap that block is in. */
+    U(descriptor) *desc,
+    /* Pointer to head of block to take out of free collection. */
+    head_record *head_ptr)
+{
+    ptr_record *ptr_rec_ptr = HEAD_TO_PTR_REC(head_ptr);
+
+    if (ptr_rec_ptr->self == ptr_rec_ptr)
+        /* Block is not the front block in its bin, so all we have to
+        ** do is take it out of the bin's doubly-linked list. */
+        U(dll_remove)(ptr_rec_ptr);
+    else
+    {
+        ptr_record *next = ptr_rec_ptr->next;
+
+        if (next)
+            /* Block is the front block in its bin, and there is at least
+            ** one other block in the bin.  Substitute the next block for
+            ** the front block. */
+            U(avl_subst)((U(avl_avl) *) &(desc->avl_tree_root), next);
+        else
+            /* Block is the front block in its bin, but there is no other
+            ** block in the bin.  Eliminate the bin. */
+            U(avl_remove)(
+                (U(avl_avl) *) &(desc->avl_tree_root), BLOCK_BAUS(head_ptr));
+    }
+}
+
+void U(free)(U(descriptor) *desc, void *payload_ptr)
+{
+    /* Flags if coalesce with adjacent block. */
+    int coalesce;
+
+    head_record *fwd_head_ptr;
+    head_record *free_head_ptr = PTR_REC_TO_HEAD(payload_ptr);
+
+    desc->num_baus_can_shrink = 0;
+
+#ifdef HMM_AUDIT_FAIL
+
+    AUDIT_BLOCK(free_head_ptr)
+
+    /* Make sure not freeing an already free block. */
+    if (!IS_BLOCK_ALLOCATED(free_head_ptr))
+        HMM_AUDIT_FAIL
+
+        if (desc->avl_tree_root)
+            /* Audit root block in AVL tree. */
+            AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
+
+#endif
+
+            fwd_head_ptr =
+                (head_record *) BAUS_FORWARD(free_head_ptr, free_head_ptr->block_size);
+
+    if (free_head_ptr->previous_block_size)
+    {
+        /* Coalesce with backward block if possible. */
+
+        head_record *bkwd_head_ptr =
+            (head_record *) BAUS_BACKWARD(
+                free_head_ptr, free_head_ptr->previous_block_size);
+
+#ifdef HMM_AUDIT_FAIL
+        AUDIT_BLOCK(bkwd_head_ptr)
+#endif
+
+        if (bkwd_head_ptr == (head_record *)(desc->last_freed))
+        {
+            desc->last_freed = 0;
+            coalesce = 1;
+        }
+        else if (IS_BLOCK_ALLOCATED(bkwd_head_ptr))
+            coalesce = 0;
+        else
+        {
+            U(out_of_free_collection)(desc, bkwd_head_ptr);
+            coalesce = 1;
+        }
+
+        if (coalesce)
+        {
+            bkwd_head_ptr->block_size += free_head_ptr->block_size;
+            SET_PREV_BLOCK_BAUS(fwd_head_ptr, BLOCK_BAUS(bkwd_head_ptr))
+            free_head_ptr = bkwd_head_ptr;
+        }
+    }
+
+    if (fwd_head_ptr->block_size == 0)
+    {
+        /* Block to be freed is last block before dummy end-of-chunk block. */
+        desc->end_of_shrinkable_chunk =
+            BAUS_FORWARD(fwd_head_ptr, DUMMY_END_BLOCK_BAUS);
+        desc->num_baus_can_shrink = BLOCK_BAUS(free_head_ptr);
+
+        if (PREV_BLOCK_BAUS(free_head_ptr) == 0)
+            /* Free block is the entire chunk, so shrinking can eliminate
+            ** entire chunk including dummy end block. */
+            desc->num_baus_can_shrink += DUMMY_END_BLOCK_BAUS;
+    }
+    else
+    {
+        /* Coalesce with forward block if possible. */
+
+#ifdef HMM_AUDIT_FAIL
+        AUDIT_BLOCK(fwd_head_ptr)
+#endif
+
+        if (fwd_head_ptr == (head_record *)(desc->last_freed))
+        {
+            desc->last_freed = 0;
+            coalesce = 1;
+        }
+        else if (IS_BLOCK_ALLOCATED(fwd_head_ptr))
+            coalesce = 0;
+        else
+        {
+            U(out_of_free_collection)(desc, fwd_head_ptr);
+            coalesce = 1;
+        }
+
+        if (coalesce)
+        {
+            free_head_ptr->block_size += fwd_head_ptr->block_size;
+
+            fwd_head_ptr =
+                (head_record *) BAUS_FORWARD(
+                    fwd_head_ptr, BLOCK_BAUS(fwd_head_ptr));
+
+            SET_PREV_BLOCK_BAUS(fwd_head_ptr, BLOCK_BAUS(free_head_ptr))
+
+            if (fwd_head_ptr->block_size == 0)
+            {
+                /* Coalesced block to be freed is last block before dummy
+                ** end-of-chunk block. */
+                desc->end_of_shrinkable_chunk =
+                    BAUS_FORWARD(fwd_head_ptr, DUMMY_END_BLOCK_BAUS);
+                desc->num_baus_can_shrink = BLOCK_BAUS(free_head_ptr);
+
+                if (PREV_BLOCK_BAUS(free_head_ptr) == 0)
+                    /* Free block is the entire chunk, so shrinking can
+                    ** eliminate entire chunk including dummy end block. */
+                    desc->num_baus_can_shrink += DUMMY_END_BLOCK_BAUS;
+            }
+        }
+    }
+
+    if (desc->last_freed)
+    {
+        /* There is a last freed block, but it is not adjacent to the
+        ** block being freed by this call to free, so put the last
+        ** freed block into the free collection.
+        */
+
+#ifdef HMM_AUDIT_FAIL
+        AUDIT_BLOCK(desc->last_freed)
+#endif
+
+        U(into_free_collection)(desc, (head_record *)(desc->last_freed));
+    }
+
+    desc->last_freed = free_head_ptr;
+}
+
+void U(new_chunk)(U(descriptor) *desc, void *start, U(size_bau) n_baus)
+{
+#ifdef HMM_AUDIT_FAIL
+
+    if (desc->avl_tree_root)
+        /* Audit root block in AVL tree. */
+        AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
+#endif
+
+#undef HEAD_PTR
+#define HEAD_PTR ((head_record *) start)
+
+        /* Make the chunk one big free block followed by a dummy end block.
+        */
+
+        n_baus -= DUMMY_END_BLOCK_BAUS;
+
+    HEAD_PTR->previous_block_size = 0;
+    HEAD_PTR->block_size = n_baus;
+
+    U(into_free_collection)(desc, HEAD_PTR);
+
+    /* Set up the dummy end block. */
+    start = BAUS_FORWARD(start, n_baus);
+    HEAD_PTR->previous_block_size = n_baus;
+    HEAD_PTR->block_size = 0;
+
+#undef HEAD_PTR
+}
+
+#ifdef HMM_AUDIT_FAIL
+
+/* Function that does audit fail actions defined my preprocessor symbol,
+** and returns a dummy integer value.
+*/
+int U(audit_block_fail_dummy_return)(void)
+{
+    HMM_AUDIT_FAIL
+
+    /* Dummy return. */
+    return(0);
+}
+
+#endif
+
+/* AVL Tree instantiation. */
+
+#ifdef HMM_AUDIT_FAIL
+
+/* The AVL tree generic package passes an ACCESS of 1 when it "touches"
+** a child node for the first time during a particular operation.  I use
+** this feature to audit only one time (per operation) the free blocks
+** that are tree nodes.  Since the root node is not a child node, it has
+** to be audited directly.
+*/
+
+/* The pain you feel while reading these macros will not be in vain.  It
+** will remove all doubt from you mind that C++ inline functions are
+** a very good thing.
+*/
+
+#define AVL_GET_LESS(H, ACCESS) \
+    (((ACCESS) ? AUDIT_BLOCK_AS_EXPR(PTR_REC_TO_HEAD(H)) : 0), (H)->self)
+#define AVL_GET_GREATER(H, ACCESS) \
+    (((ACCESS) ? AUDIT_BLOCK_AS_EXPR(PTR_REC_TO_HEAD(H)) : 0), (H)->prev)
+
+#else
+
+#define AVL_GET_LESS(H, ACCESS) ((H)->self)
+#define AVL_GET_GREATER(H, ACCESS) ((H)->prev)
+
+#endif
+
+#define AVL_SET_LESS(H, LH) (H)->self = (LH);
+#define AVL_SET_GREATER(H, GH) (H)->prev = (GH);
+
+/*  high bit of high bit of
+**  block_size  previous_block_size balance factor
+**  ----------- ------------------- --------------
+**  0       0           n/a (block allocated)
+**  0       1           1
+**  1       0           -1
+**  1       1           0
+*/
+
+#define AVL_GET_BALANCE_FACTOR(H) \
+    ((((head_record *) (PTR_REC_TO_HEAD(H)))->block_size & \
+      HIGH_BIT_BAU_SIZE) ? \
+     (((head_record *) (PTR_REC_TO_HEAD(H)))->previous_block_size & \
+      HIGH_BIT_BAU_SIZE ? 0 : -1) : 1)
+
+#define AVL_SET_BALANCE_FACTOR(H, BF) \
+    {                         \
+        register head_record *p =               \
+                                                (head_record *) PTR_REC_TO_HEAD(H);       \
+        register int bal_f = (BF);              \
+        \
+        if (bal_f <= 0)                 \
+            p->block_size |= HIGH_BIT_BAU_SIZE;       \
+        else                        \
+            p->block_size &= ~HIGH_BIT_BAU_SIZE;      \
+        if (bal_f >= 0)                 \
+            p->previous_block_size |= HIGH_BIT_BAU_SIZE;  \
+        else                        \
+            p->previous_block_size &= ~HIGH_BIT_BAU_SIZE; \
+    }
+
+#define COMPARE_KEY_KEY(K1, K2) ((K1) == (K2) ? 0 : ((K1) > (K2) ? 1 : -1))
+
+#define AVL_COMPARE_KEY_NODE(K, H) \
+    COMPARE_KEY_KEY(K, BLOCK_BAUS(PTR_REC_TO_HEAD(H)))
+
+#define AVL_COMPARE_NODE_NODE(H1, H2) \
+    COMPARE_KEY_KEY(BLOCK_BAUS(PTR_REC_TO_HEAD(H1)), \
+                    BLOCK_BAUS(PTR_REC_TO_HEAD(H2)))
+
+#define AVL_NULL ((ptr_record *) 0)
+
+#define AVL_IMPL_MASK \
+    ( AVL_IMPL_INSERT | AVL_IMPL_SEARCH | AVL_IMPL_REMOVE | AVL_IMPL_SUBST )
+
+#include "cavl_impl.h"
diff --git a/vpx_mem/memory_manager/hmm_dflt_abort.c b/vpx_mem/memory_manager/hmm_dflt_abort.c
new file mode 100644 (file)
index 0000000..dc59f55
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+/* The function in this file performs default actions if self-auditing
+** finds heap corruption.  Don't rely on this code to handle the
+** case where HMM is being used to implement the malloc and free standard
+** library functions.  Rewrite the function if necessary to avoid using
+** I/O and execution termination functions that call malloc or free.
+** In Unix, for example, you would replace the fputs calls with calls
+** to the write system call using file handle number 2.
+*/
+#include "hmm_intrnl.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static int entered = 0;
+
+/* Print abort message, file and line.  Terminate execution.
+*/
+void hmm_dflt_abort(const char *file, const char *line)
+{
+    /* Avoid use of printf(), which is more likely to use heap. */
+
+    if (entered)
+
+        /* The standard I/O functions called a heap function and caused
+        ** an indirect recursive call to this function.  So we'll have
+        ** to just exit without printing a message.  */
+        while (1);
+
+    entered = 1;
+
+    fputs("\n_abort - Heap corruption\n" "File: ", stderr);
+    fputs(file, stderr);
+    fputs("  Line: ", stderr);
+    fputs(line, stderr);
+    fputs("\n\n", stderr);
+    fputs("hmm_dflt_abort: while(1)!!!\n", stderr);
+    fflush(stderr);
+
+    while (1);
+}
diff --git a/vpx_mem/memory_manager/hmm_grow.c b/vpx_mem/memory_manager/hmm_grow.c
new file mode 100644 (file)
index 0000000..79d75a7
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+void U(grow_chunk)(U(descriptor) *desc, void *end, U(size_bau) n_baus)
+{
+#undef HEAD_PTR
+#define HEAD_PTR ((head_record *) end)
+
+    end = BAUS_BACKWARD(end, DUMMY_END_BLOCK_BAUS);
+
+#ifdef HMM_AUDIT_FAIL
+
+    if (HEAD_PTR->block_size != 0)
+        /* Chunk does not have valid dummy end block. */
+        HMM_AUDIT_FAIL
+
+#endif
+
+        /* Create a new block that absorbs the old dummy end block. */
+        HEAD_PTR->block_size = n_baus;
+
+    /* Set up the new dummy end block. */
+    {
+        head_record *dummy = (head_record *) BAUS_FORWARD(end, n_baus);
+        dummy->previous_block_size = n_baus;
+        dummy->block_size = 0;
+    }
+
+    /* Simply free the new block, allowing it to coalesce with any
+    ** free block at that was the last block in the chunk prior to
+    ** growth.
+    */
+    U(free)(desc, HEAD_TO_PTR_REC(end));
+
+#undef HEAD_PTR
+}
diff --git a/vpx_mem/memory_manager/hmm_largest.c b/vpx_mem/memory_manager/hmm_largest.c
new file mode 100644 (file)
index 0000000..5ebe398
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+U(size_aau) U(largest_available)(U(descriptor) *desc)
+{
+    U(size_bau) largest;
+
+    if (!(desc->avl_tree_root))
+        largest = 0;
+    else
+    {
+#ifdef HMM_AUDIT_FAIL
+        /* Audit root block in AVL tree. */
+        AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
+#endif
+
+        largest =
+            BLOCK_BAUS(
+                PTR_REC_TO_HEAD(
+                    U(avl_search)(
+                        (U(avl_avl) *) & (desc->avl_tree_root),
+                        (U(size_bau)) ~(U(size_bau)) 0, AVL_LESS)));
+    }
+
+    if (desc->last_freed)
+    {
+        /* Size of last freed block. */
+        register U(size_bau) lf_size;
+
+#ifdef HMM_AUDIT_FAIL
+        AUDIT_BLOCK(desc->last_freed)
+#endif
+
+        lf_size = BLOCK_BAUS(desc->last_freed);
+
+        if (lf_size > largest)
+            largest = lf_size;
+    }
+
+    /* Convert largest size to AAUs and subract head size leaving payload
+    ** size.
+    */
+    return(largest ?
+           ((largest * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) - HEAD_AAUS) :
+           0);
+}
diff --git a/vpx_mem/memory_manager/hmm_resize.c b/vpx_mem/memory_manager/hmm_resize.c
new file mode 100644 (file)
index 0000000..6e3f2f0
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+int U(resize)(U(descriptor) *desc, void *mem, U(size_aau) n)
+{
+    U(size_aau) i;
+    head_record *next_head_ptr;
+    head_record *head_ptr = PTR_REC_TO_HEAD(mem);
+
+    /* Flag. */
+    int next_block_free;
+
+    /* Convert n from desired block size in AAUs to BAUs. */
+    n += HEAD_AAUS;
+    n = DIV_ROUND_UP(n, HMM_BLOCK_ALIGN_UNIT);
+
+    if (n < MIN_BLOCK_BAUS)
+        n = MIN_BLOCK_BAUS;
+
+#ifdef HMM_AUDIT_FAIL
+
+    AUDIT_BLOCK(head_ptr)
+
+    if (!IS_BLOCK_ALLOCATED(head_ptr))
+        HMM_AUDIT_FAIL
+
+        if (desc->avl_tree_root)
+            AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
+
+#endif
+
+            i = head_ptr->block_size;
+
+    next_head_ptr =
+        (head_record *) BAUS_FORWARD(head_ptr, head_ptr->block_size);
+
+    next_block_free =
+        (next_head_ptr == desc->last_freed) ||
+        !IS_BLOCK_ALLOCATED(next_head_ptr);
+
+    if (next_block_free)
+        /* Block can expand into next free block. */
+        i += BLOCK_BAUS(next_head_ptr);
+
+    if (n > i)
+        /* Not enough room for block to expand. */
+        return(-1);
+
+    if (next_block_free)
+    {
+#ifdef HMM_AUDIT_FAIL
+        AUDIT_BLOCK(next_head_ptr)
+#endif
+
+        if (next_head_ptr == desc->last_freed)
+            desc->last_freed = 0;
+        else
+            U(out_of_free_collection)(desc, next_head_ptr);
+
+        next_head_ptr =
+            (head_record *) BAUS_FORWARD(head_ptr, (U(size_bau)) i);
+    }
+
+    /* Set i to number of "extra" BAUs. */
+    i -= n;
+
+    if (i < MIN_BLOCK_BAUS)
+        /* Not enough extra BAUs to be a block on their own, so just keep them
+        ** in the block being resized.
+        */
+    {
+        n += i;
+        i = n;
+    }
+    else
+    {
+        /* There are enough "leftover" BAUs in the next block to
+        ** form a remainder block. */
+
+        head_record *rem_head_ptr;
+
+        rem_head_ptr = (head_record *) BAUS_FORWARD(head_ptr, n);
+
+        rem_head_ptr->previous_block_size = (U(size_bau)) n;
+        rem_head_ptr->block_size = (U(size_bau)) i;
+
+        if (desc->last_freed)
+        {
+#ifdef HMM_AUDIT_FAIL
+            AUDIT_BLOCK(desc->last_freed)
+#endif
+
+            U(into_free_collection)(desc, (head_record *)(desc->last_freed));
+
+            desc->last_freed = 0;
+        }
+
+        desc->last_freed = rem_head_ptr;
+    }
+
+    head_ptr->block_size = (U(size_bau)) n;
+    next_head_ptr->previous_block_size = (U(size_bau)) i;
+
+    return(0);
+}
diff --git a/vpx_mem/memory_manager/hmm_shrink.c b/vpx_mem/memory_manager/hmm_shrink.c
new file mode 100644 (file)
index 0000000..5ef9b23
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+void U(shrink_chunk)(U(descriptor) *desc, U(size_bau) n_baus_to_shrink)
+{
+    head_record *dummy_end_block = (head_record *)
+                                   BAUS_BACKWARD(desc->end_of_shrinkable_chunk, DUMMY_END_BLOCK_BAUS);
+
+#ifdef HMM_AUDIT_FAIL
+
+    if (dummy_end_block->block_size != 0)
+        /* Chunk does not have valid dummy end block. */
+        HMM_AUDIT_FAIL
+
+#endif
+
+        if (n_baus_to_shrink)
+        {
+            head_record *last_block = (head_record *)
+                                      BAUS_BACKWARD(
+                                          dummy_end_block, dummy_end_block->previous_block_size);
+
+#ifdef HMM_AUDIT_FAIL
+            AUDIT_BLOCK(last_block)
+#endif
+
+            if (last_block == desc->last_freed)
+            {
+                U(size_bau) bs = BLOCK_BAUS(last_block);
+
+                /* Chunk will not be shrunk out of existence if
+                ** 1.  There is at least one allocated block in the chunk
+                **     and the amount to shrink is exactly the size of the
+                **     last block, OR
+                ** 2.  After the last block is shrunk, there will be enough
+                **     BAUs left in it to form a minimal size block. */
+                int chunk_will_survive =
+                    (PREV_BLOCK_BAUS(last_block) && (n_baus_to_shrink == bs)) ||
+                    (n_baus_to_shrink <= (U(size_bau))(bs - MIN_BLOCK_BAUS));
+
+                if (chunk_will_survive ||
+                    (!PREV_BLOCK_BAUS(last_block) &&
+                     (n_baus_to_shrink ==
+                      (U(size_bau))(bs + DUMMY_END_BLOCK_BAUS))))
+                {
+                    desc->last_freed = 0;
+
+                    if (chunk_will_survive)
+                    {
+                        bs -= n_baus_to_shrink;
+
+                        if (bs)
+                        {
+                            /* The last (non-dummy) block was not completely
+                            ** eliminated by the shrink. */
+
+                            last_block->block_size = bs;
+
+                            /* Create new dummy end record.
+                            */
+                            dummy_end_block =
+                                (head_record *) BAUS_FORWARD(last_block, bs);
+                            dummy_end_block->previous_block_size = bs;
+                            dummy_end_block->block_size = 0;
+
+#ifdef HMM_AUDIT_FAIL
+
+                            if (desc->avl_tree_root)
+                                AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
+#endif
+
+                                U(into_free_collection)(desc, last_block);
+                        }
+                        else
+                        {
+                            /* The last (non-dummy) block was completely
+                            ** eliminated by the shrink.  Make its head
+                            ** the new dummy end block.
+                            */
+                            last_block->block_size = 0;
+                            last_block->previous_block_size &= ~HIGH_BIT_BAU_SIZE;
+                        }
+                    }
+                }
+
+#ifdef HMM_AUDIT_FAIL
+                else
+                    HMM_AUDIT_FAIL
+#endif
+                }
+
+#ifdef HMM_AUDIT_FAIL
+            else
+                HMM_AUDIT_FAIL
+#endif
+            }
+}
diff --git a/vpx_mem/memory_manager/hmm_true.c b/vpx_mem/memory_manager/hmm_true.c
new file mode 100644 (file)
index 0000000..41103c8
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#include "hmm_intrnl.h"
+
+U(size_aau) U(true_size)(void *payload_ptr)
+{
+    register  head_record *head_ptr = PTR_REC_TO_HEAD(payload_ptr);
+
+#ifdef HMM_AUDIT_FAIL
+    AUDIT_BLOCK(head_ptr)
+#endif
+
+    /* Convert block size from BAUs to AAUs.  Subtract head size, leaving
+    ** payload size.
+    */
+    return(
+              (BLOCK_BAUS(head_ptr) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) -
+              HEAD_AAUS);
+}
diff --git a/vpx_mem/memory_manager/include/cavl_if.h b/vpx_mem/memory_manager/include/cavl_if.h
new file mode 100644 (file)
index 0000000..e2733ef
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* Abstract AVL Tree Generic C Package.
+** Interface generation header file.
+**
+** This code is in the public domain.  See cavl_tree.html for interface
+** documentation.
+**
+** Version: 1.5  Author: Walt Karas
+*/
+
+/* This header contains the definition of CHAR_BIT (number of bits in a
+** char). */
+#include <limits.h>
+
+#undef L_
+#undef L_EST_LONG_BIT
+#undef L_SIZE
+#undef L_SC
+#undef L_LONG_BIT
+#undef L_BIT_ARR_DEFN
+
+#ifndef AVL_SEARCH_TYPE_DEFINED_
+#define AVL_SEARCH_TYPE_DEFINED_
+
+typedef enum
+{
+    AVL_EQUAL = 1,
+    AVL_LESS = 2,
+    AVL_GREATER = 4,
+    AVL_LESS_EQUAL = AVL_EQUAL | AVL_LESS,
+    AVL_GREATER_EQUAL = AVL_EQUAL | AVL_GREATER
+}
+avl_search_type;
+
+#endif
+
+#ifdef AVL_UNIQUE
+
+#define L_ AVL_UNIQUE
+
+#else
+
+#define L_(X) X
+
+#endif
+
+/* Determine storage class for function prototypes. */
+#ifdef AVL_PRIVATE
+
+#define L_SC static
+
+#else
+
+#define L_SC extern
+
+#endif
+
+#ifdef AVL_SIZE
+
+#define L_SIZE AVL_SIZE
+
+#else
+
+#define L_SIZE unsigned long
+
+#endif
+
+typedef struct
+{
+#ifdef AVL_INSIDE_STRUCT
+
+    AVL_INSIDE_STRUCT
+
+#endif
+
+    AVL_HANDLE root;
+}
+L_(avl);
+
+/* Function prototypes. */
+
+L_SC void L_(init)(L_(avl) *tree);
+
+L_SC int L_(is_empty)(L_(avl) *tree);
+
+L_SC AVL_HANDLE L_(insert)(L_(avl) *tree, AVL_HANDLE h);
+
+L_SC AVL_HANDLE L_(search)(L_(avl) *tree, AVL_KEY k, avl_search_type st);
+
+L_SC AVL_HANDLE L_(search_least)(L_(avl) *tree);
+
+L_SC AVL_HANDLE L_(search_greatest)(L_(avl) *tree);
+
+L_SC AVL_HANDLE L_(remove)(L_(avl) *tree, AVL_KEY k);
+
+L_SC AVL_HANDLE L_(subst)(L_(avl) *tree, AVL_HANDLE new_node);
+
+#ifdef AVL_BUILD_ITER_TYPE
+
+L_SC int L_(build)(
+    L_(avl) *tree, AVL_BUILD_ITER_TYPE p, L_SIZE num_nodes);
+
+#endif
+
+/* ANSI C/ISO C++ require that a long have at least 32 bits.  Set
+** L_EST_LONG_BIT to be the greatest multiple of 8 in the range
+** 32 - 64 (inclusive) that is less than or equal to the number of
+** bits in a long.
+*/
+
+#if (((LONG_MAX >> 31) >> 7) == 0)
+
+#define L_EST_LONG_BIT 32
+
+#elif (((LONG_MAX >> 31) >> 15) == 0)
+
+#define L_EST_LONG_BIT 40
+
+#elif (((LONG_MAX >> 31) >> 23) == 0)
+
+#define L_EST_LONG_BIT 48
+
+#elif (((LONG_MAX >> 31) >> 31) == 0)
+
+#define L_EST_LONG_BIT 56
+
+#else
+
+#define L_EST_LONG_BIT 64
+
+#endif
+
+/* Number of bits in a long. */
+#define L_LONG_BIT (sizeof(long) * CHAR_BIT)
+
+/* The macro L_BIT_ARR_DEFN defines a bit array whose index is a (0-based)
+** node depth.  The definition depends on whether the maximum depth is more
+** or less than the number of bits in a single long.
+*/
+
+#if ((AVL_MAX_DEPTH) > L_EST_LONG_BIT)
+
+/* Maximum depth may be more than number of bits in a long. */
+
+#define L_BIT_ARR_DEFN(NAME) \
+    unsigned long NAME[((AVL_MAX_DEPTH) + L_LONG_BIT - 1) / L_LONG_BIT];
+
+#else
+
+/* Maximum depth is definitely less than number of bits in a long. */
+
+#define L_BIT_ARR_DEFN(NAME) unsigned long NAME;
+
+#endif
+
+/* Iterator structure. */
+typedef struct
+{
+    /* Tree being iterated over. */
+    L_(avl) *tree_;
+
+    /* Records a path into the tree.  If bit n is true, indicates
+    ** take greater branch from the nth node in the path, otherwise
+    ** take the less branch.  bit 0 gives branch from root, and
+    ** so on. */
+    L_BIT_ARR_DEFN(branch)
+
+    /* Zero-based depth of path into tree. */
+    unsigned depth;
+
+    /* Handles of nodes in path from root to current node (returned by *). */
+    AVL_HANDLE path_h[(AVL_MAX_DEPTH) - 1];
+}
+L_(iter);
+
+/* Iterator function prototypes. */
+
+L_SC void L_(start_iter)(
+    L_(avl) *tree, L_(iter) *iter, AVL_KEY k, avl_search_type st);
+
+L_SC void L_(start_iter_least)(L_(avl) *tree, L_(iter) *iter);
+
+L_SC void L_(start_iter_greatest)(L_(avl) *tree, L_(iter) *iter);
+
+L_SC AVL_HANDLE L_(get_iter)(L_(iter) *iter);
+
+L_SC void L_(incr_iter)(L_(iter) *iter);
+
+L_SC void L_(decr_iter)(L_(iter) *iter);
+
+L_SC void L_(init_iter)(L_(iter) *iter);
+
+#define AVL_IMPL_INIT           1
+#define AVL_IMPL_IS_EMPTY       (1 << 1)
+#define AVL_IMPL_INSERT         (1 << 2)
+#define AVL_IMPL_SEARCH         (1 << 3)
+#define AVL_IMPL_SEARCH_LEAST       (1 << 4)
+#define AVL_IMPL_SEARCH_GREATEST    (1 << 5)
+#define AVL_IMPL_REMOVE         (1 << 6)
+#define AVL_IMPL_BUILD          (1 << 7)
+#define AVL_IMPL_START_ITER     (1 << 8)
+#define AVL_IMPL_START_ITER_LEAST   (1 << 9)
+#define AVL_IMPL_START_ITER_GREATEST    (1 << 10)
+#define AVL_IMPL_GET_ITER       (1 << 11)
+#define AVL_IMPL_INCR_ITER      (1 << 12)
+#define AVL_IMPL_DECR_ITER      (1 << 13)
+#define AVL_IMPL_INIT_ITER      (1 << 14)
+#define AVL_IMPL_SUBST          (1 << 15)
+
+#define AVL_IMPL_ALL            (~0)
+
+#undef L_
+#undef L_EST_LONG_BIT
+#undef L_SIZE
+#undef L_SC
+#undef L_LONG_BIT
+#undef L_BIT_ARR_DEFN
diff --git a/vpx_mem/memory_manager/include/cavl_impl.h b/vpx_mem/memory_manager/include/cavl_impl.h
new file mode 100644 (file)
index 0000000..267bc73
--- /dev/null
@@ -0,0 +1,1266 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* Abstract AVL Tree Generic C Package.
+** Implementation generation header file.
+**
+** This code is in the public domain.  See cavl_tree.html for interface
+** documentation.
+**
+** Version: 1.5  Author: Walt Karas
+*/
+
+#undef L_
+#undef L_EST_LONG_BIT
+#undef L_SIZE
+#undef l_tree
+#undef L_MASK_HIGH_BIT
+#undef L_LONG_BIT
+#undef L_BIT_ARR_DEFN
+#undef L_BIT_ARR_VAL
+#undef L_BIT_ARR_0
+#undef L_BIT_ARR_1
+#undef L_BIT_ARR_ALL
+#undef L_BIT_ARR_LONGS
+#undef L_IMPL_MASK
+#undef L_CHECK_READ_ERROR
+#undef L_CHECK_READ_ERROR_INV_DEPTH
+#undef L_SC
+#undef L_BALANCE_PARAM_PREFIX
+
+#ifdef AVL_UNIQUE
+
+#define L_ AVL_UNIQUE
+
+#else
+
+#define L_(X) X
+
+#endif
+
+/* Determine correct storage class for functions */
+#ifdef AVL_PRIVATE
+
+#define L_SC static
+
+#else
+
+#define L_SC
+
+#endif
+
+#ifdef AVL_SIZE
+
+#define L_SIZE AVL_SIZE
+
+#else
+
+#define L_SIZE unsigned long
+
+#endif
+
+#define L_MASK_HIGH_BIT ((int) ~ ((~ (unsigned) 0) >> 1))
+
+/* ANSI C/ISO C++ require that a long have at least 32 bits.  Set
+** L_EST_LONG_BIT to be the greatest multiple of 8 in the range
+** 32 - 64 (inclusive) that is less than or equal to the number of
+** bits in a long.
+*/
+
+#if (((LONG_MAX >> 31) >> 7) == 0)
+
+#define L_EST_LONG_BIT 32
+
+#elif (((LONG_MAX >> 31) >> 15) == 0)
+
+#define L_EST_LONG_BIT 40
+
+#elif (((LONG_MAX >> 31) >> 23) == 0)
+
+#define L_EST_LONG_BIT 48
+
+#elif (((LONG_MAX >> 31) >> 31) == 0)
+
+#define L_EST_LONG_BIT 56
+
+#else
+
+#define L_EST_LONG_BIT 64
+
+#endif
+
+#define L_LONG_BIT (sizeof(long) * CHAR_BIT)
+
+#if ((AVL_MAX_DEPTH) > L_EST_LONG_BIT)
+
+/* The maximum depth may be greater than the number of bits in a long,
+** so multiple longs are needed to hold a bit array indexed by node
+** depth. */
+
+#define L_BIT_ARR_LONGS (((AVL_MAX_DEPTH) + L_LONG_BIT - 1) / L_LONG_BIT)
+
+#define L_BIT_ARR_DEFN(NAME) unsigned long NAME[L_BIT_ARR_LONGS];
+
+#define L_BIT_ARR_VAL(BIT_ARR, BIT_NUM) \
+    ((BIT_ARR)[(BIT_NUM) / L_LONG_BIT] & (1L << ((BIT_NUM) % L_LONG_BIT)))
+
+#define L_BIT_ARR_0(BIT_ARR, BIT_NUM) \
+    (BIT_ARR)[(BIT_NUM) / L_LONG_BIT] &= ~(1L << ((BIT_NUM) % L_LONG_BIT));
+
+#define L_BIT_ARR_1(BIT_ARR, BIT_NUM) \
+    (BIT_ARR)[(BIT_NUM) / L_LONG_BIT] |= 1L << ((BIT_NUM) % L_LONG_BIT);
+
+#define L_BIT_ARR_ALL(BIT_ARR, BIT_VAL) \
+    { int i = L_BIT_ARR_LONGS; do (BIT_ARR)[--i] = 0L - (BIT_VAL); while(i); }
+
+#else /* The bit array can definitely fit in one long */
+
+#define L_BIT_ARR_DEFN(NAME) unsigned long NAME;
+
+#define L_BIT_ARR_VAL(BIT_ARR, BIT_NUM) ((BIT_ARR) & (1L << (BIT_NUM)))
+
+#define L_BIT_ARR_0(BIT_ARR, BIT_NUM) (BIT_ARR) &= ~(1L << (BIT_NUM));
+
+#define L_BIT_ARR_1(BIT_ARR, BIT_NUM) (BIT_ARR) |= 1L << (BIT_NUM);
+
+#define L_BIT_ARR_ALL(BIT_ARR, BIT_VAL) (BIT_ARR) = 0L - (BIT_VAL);
+
+#endif
+
+#ifdef AVL_READ_ERRORS_HAPPEN
+
+#define L_CHECK_READ_ERROR(ERROR_RETURN) \
+    { if (AVL_READ_ERROR) return(ERROR_RETURN); }
+
+#else
+
+#define L_CHECK_READ_ERROR(ERROR_RETURN)
+
+#endif
+
+/* The presumed reason that an instantiation places additional fields
+** inside the AVL tree structure is that the SET_ and GET_ macros
+** need these fields.  The "balance" function does not explicitly use
+** any fields in the AVL tree structure, so only pass an AVL tree
+** structure pointer to "balance" if it has instantiation-specific
+** fields that are (presumably) needed by the SET_/GET_ calls within
+** "balance".
+*/
+#ifdef AVL_INSIDE_STRUCT
+
+#define L_BALANCE_PARAM_CALL_PREFIX l_tree,
+#define L_BALANCE_PARAM_DECL_PREFIX L_(avl) *l_tree,
+
+#else
+
+#define L_BALANCE_PARAM_CALL_PREFIX
+#define L_BALANCE_PARAM_DECL_PREFIX
+
+#endif
+
+#ifdef AVL_IMPL_MASK
+
+#define L_IMPL_MASK (AVL_IMPL_MASK)
+
+#else
+
+/* Define all functions. */
+#define L_IMPL_MASK AVL_IMPL_ALL
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_INIT)
+
+L_SC void L_(init)(L_(avl) *l_tree)
+{
+    l_tree->root = AVL_NULL;
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_IS_EMPTY)
+
+L_SC int L_(is_empty)(L_(avl) *l_tree)
+{
+    return(l_tree->root == AVL_NULL);
+}
+
+#endif
+
+/* Put the private balance function in the same compilation module as
+** the insert function.  */
+#if (L_IMPL_MASK & AVL_IMPL_INSERT)
+
+/* Balances subtree, returns handle of root node of subtree after balancing.
+*/
+L_SC AVL_HANDLE L_(balance)(L_BALANCE_PARAM_DECL_PREFIX AVL_HANDLE bal_h)
+{
+    AVL_HANDLE deep_h;
+
+    /* Either the "greater than" or the "less than" subtree of
+    ** this node has to be 2 levels deeper (or else it wouldn't
+    ** need balancing).
+    */
+    if (AVL_GET_BALANCE_FACTOR(bal_h) > 0)
+    {
+        /* "Greater than" subtree is deeper. */
+
+        deep_h = AVL_GET_GREATER(bal_h, 1);
+
+        L_CHECK_READ_ERROR(AVL_NULL)
+
+        if (AVL_GET_BALANCE_FACTOR(deep_h) < 0)
+        {
+            int bf;
+
+            AVL_HANDLE old_h = bal_h;
+            bal_h = AVL_GET_LESS(deep_h, 1);
+            L_CHECK_READ_ERROR(AVL_NULL)
+            AVL_SET_GREATER(old_h, AVL_GET_LESS(bal_h, 1))
+            AVL_SET_LESS(deep_h, AVL_GET_GREATER(bal_h, 1))
+            AVL_SET_LESS(bal_h, old_h)
+            AVL_SET_GREATER(bal_h, deep_h)
+
+            bf = AVL_GET_BALANCE_FACTOR(bal_h);
+
+            if (bf != 0)
+            {
+                if (bf > 0)
+                {
+                    AVL_SET_BALANCE_FACTOR(old_h, -1)
+                    AVL_SET_BALANCE_FACTOR(deep_h, 0)
+                }
+                else
+                {
+                    AVL_SET_BALANCE_FACTOR(deep_h, 1)
+                    AVL_SET_BALANCE_FACTOR(old_h, 0)
+                }
+
+                AVL_SET_BALANCE_FACTOR(bal_h, 0)
+            }
+            else
+            {
+                AVL_SET_BALANCE_FACTOR(old_h, 0)
+                AVL_SET_BALANCE_FACTOR(deep_h, 0)
+            }
+        }
+        else
+        {
+            AVL_SET_GREATER(bal_h, AVL_GET_LESS(deep_h, 0))
+            AVL_SET_LESS(deep_h, bal_h)
+
+            if (AVL_GET_BALANCE_FACTOR(deep_h) == 0)
+            {
+                AVL_SET_BALANCE_FACTOR(deep_h, -1)
+                AVL_SET_BALANCE_FACTOR(bal_h, 1)
+            }
+            else
+            {
+                AVL_SET_BALANCE_FACTOR(deep_h, 0)
+                AVL_SET_BALANCE_FACTOR(bal_h, 0)
+            }
+
+            bal_h = deep_h;
+        }
+    }
+    else
+    {
+        /* "Less than" subtree is deeper. */
+
+        deep_h = AVL_GET_LESS(bal_h, 1);
+        L_CHECK_READ_ERROR(AVL_NULL)
+
+        if (AVL_GET_BALANCE_FACTOR(deep_h) > 0)
+        {
+            int bf;
+            AVL_HANDLE old_h = bal_h;
+            bal_h = AVL_GET_GREATER(deep_h, 1);
+            L_CHECK_READ_ERROR(AVL_NULL)
+            AVL_SET_LESS(old_h, AVL_GET_GREATER(bal_h, 0))
+            AVL_SET_GREATER(deep_h, AVL_GET_LESS(bal_h, 0))
+            AVL_SET_GREATER(bal_h, old_h)
+            AVL_SET_LESS(bal_h, deep_h)
+
+            bf = AVL_GET_BALANCE_FACTOR(bal_h);
+
+            if (bf != 0)
+            {
+                if (bf < 0)
+                {
+                    AVL_SET_BALANCE_FACTOR(old_h, 1)
+                    AVL_SET_BALANCE_FACTOR(deep_h, 0)
+                }
+                else
+                {
+                    AVL_SET_BALANCE_FACTOR(deep_h, -1)
+                    AVL_SET_BALANCE_FACTOR(old_h, 0)
+                }
+
+                AVL_SET_BALANCE_FACTOR(bal_h, 0)
+            }
+            else
+            {
+                AVL_SET_BALANCE_FACTOR(old_h, 0)
+                AVL_SET_BALANCE_FACTOR(deep_h, 0)
+            }
+        }
+        else
+        {
+            AVL_SET_LESS(bal_h, AVL_GET_GREATER(deep_h, 0))
+            AVL_SET_GREATER(deep_h, bal_h)
+
+            if (AVL_GET_BALANCE_FACTOR(deep_h) == 0)
+            {
+                AVL_SET_BALANCE_FACTOR(deep_h, 1)
+                AVL_SET_BALANCE_FACTOR(bal_h, -1)
+            }
+            else
+            {
+                AVL_SET_BALANCE_FACTOR(deep_h, 0)
+                AVL_SET_BALANCE_FACTOR(bal_h, 0)
+            }
+
+            bal_h = deep_h;
+        }
+    }
+
+    return(bal_h);
+}
+
+L_SC AVL_HANDLE L_(insert)(L_(avl) *l_tree, AVL_HANDLE h)
+{
+    AVL_SET_LESS(h, AVL_NULL)
+    AVL_SET_GREATER(h, AVL_NULL)
+    AVL_SET_BALANCE_FACTOR(h, 0)
+
+    if (l_tree->root == AVL_NULL)
+        l_tree->root = h;
+    else
+    {
+        /* Last unbalanced node encountered in search for insertion point. */
+        AVL_HANDLE unbal = AVL_NULL;
+        /* Parent of last unbalanced node. */
+        AVL_HANDLE parent_unbal = AVL_NULL;
+        /* Balance factor of last unbalanced node. */
+        int unbal_bf;
+
+        /* Zero-based depth in tree. */
+        unsigned depth = 0, unbal_depth = 0;
+
+        /* Records a path into the tree.  If bit n is true, indicates
+        ** take greater branch from the nth node in the path, otherwise
+        ** take the less branch.  bit 0 gives branch from root, and
+        ** so on. */
+        L_BIT_ARR_DEFN(branch)
+
+        AVL_HANDLE hh = l_tree->root;
+        AVL_HANDLE parent = AVL_NULL;
+        int cmp;
+
+        do
+        {
+            if (AVL_GET_BALANCE_FACTOR(hh) != 0)
+            {
+                unbal = hh;
+                parent_unbal = parent;
+                unbal_depth = depth;
+            }
+
+            cmp = AVL_COMPARE_NODE_NODE(h, hh);
+
+            if (cmp == 0)
+                /* Duplicate key. */
+                return(hh);
+
+            parent = hh;
+
+            if (cmp > 0)
+            {
+                hh = AVL_GET_GREATER(hh, 1);
+                L_BIT_ARR_1(branch, depth)
+            }
+            else
+            {
+                hh = AVL_GET_LESS(hh, 1);
+                L_BIT_ARR_0(branch, depth)
+            }
+
+            L_CHECK_READ_ERROR(AVL_NULL)
+            depth++;
+        }
+        while (hh != AVL_NULL);
+
+        /*  Add node to insert as leaf of tree. */
+        if (cmp < 0)
+            AVL_SET_LESS(parent, h)
+            else
+                AVL_SET_GREATER(parent, h)
+
+                depth = unbal_depth;
+
+        if (unbal == AVL_NULL)
+            hh = l_tree->root;
+        else
+        {
+            cmp = L_BIT_ARR_VAL(branch, depth) ? 1 : -1;
+            depth++;
+            unbal_bf = AVL_GET_BALANCE_FACTOR(unbal);
+
+            if (cmp < 0)
+                unbal_bf--;
+            else  /* cmp > 0 */
+                unbal_bf++;
+
+            hh = cmp < 0 ? AVL_GET_LESS(unbal, 1) : AVL_GET_GREATER(unbal, 1);
+            L_CHECK_READ_ERROR(AVL_NULL)
+
+            if ((unbal_bf != -2) && (unbal_bf != 2))
+            {
+                /* No rebalancing of tree is necessary. */
+                AVL_SET_BALANCE_FACTOR(unbal, unbal_bf)
+                unbal = AVL_NULL;
+            }
+        }
+
+        if (hh != AVL_NULL)
+            while (h != hh)
+            {
+                cmp = L_BIT_ARR_VAL(branch, depth) ? 1 : -1;
+                depth++;
+
+                if (cmp < 0)
+                {
+                    AVL_SET_BALANCE_FACTOR(hh, -1)
+                    hh = AVL_GET_LESS(hh, 1);
+                }
+                else /* cmp > 0 */
+                {
+                    AVL_SET_BALANCE_FACTOR(hh, 1)
+                    hh = AVL_GET_GREATER(hh, 1);
+                }
+
+                L_CHECK_READ_ERROR(AVL_NULL)
+            }
+
+        if (unbal != AVL_NULL)
+        {
+            unbal = L_(balance)(L_BALANCE_PARAM_CALL_PREFIX unbal);
+            L_CHECK_READ_ERROR(AVL_NULL)
+
+            if (parent_unbal == AVL_NULL)
+                l_tree->root = unbal;
+            else
+            {
+                depth = unbal_depth - 1;
+                cmp = L_BIT_ARR_VAL(branch, depth) ? 1 : -1;
+
+                if (cmp < 0)
+                    AVL_SET_LESS(parent_unbal, unbal)
+                    else  /* cmp > 0 */
+                        AVL_SET_GREATER(parent_unbal, unbal)
+                    }
+        }
+
+    }
+
+    return(h);
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_SEARCH)
+
+L_SC AVL_HANDLE L_(search)(L_(avl) *l_tree, AVL_KEY k, avl_search_type st)
+{
+    int cmp, target_cmp;
+    AVL_HANDLE match_h = AVL_NULL;
+    AVL_HANDLE h = l_tree->root;
+
+    if (st & AVL_LESS)
+        target_cmp = 1;
+    else if (st & AVL_GREATER)
+        target_cmp = -1;
+    else
+        target_cmp = 0;
+
+    while (h != AVL_NULL)
+    {
+        cmp = AVL_COMPARE_KEY_NODE(k, h);
+
+        if (cmp == 0)
+        {
+            if (st & AVL_EQUAL)
+            {
+                match_h = h;
+                break;
+            }
+
+            cmp = -target_cmp;
+        }
+        else if (target_cmp != 0)
+            if (!((cmp ^ target_cmp) & L_MASK_HIGH_BIT))
+                /* cmp and target_cmp are both positive or both negative. */
+                match_h = h;
+
+        h = cmp < 0 ? AVL_GET_LESS(h, 1) : AVL_GET_GREATER(h, 1);
+        L_CHECK_READ_ERROR(AVL_NULL)
+    }
+
+    return(match_h);
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_SEARCH_LEAST)
+
+L_SC AVL_HANDLE L_(search_least)(L_(avl) *l_tree)
+{
+    AVL_HANDLE h = l_tree->root;
+    AVL_HANDLE parent = AVL_NULL;
+
+    while (h != AVL_NULL)
+    {
+        parent = h;
+        h = AVL_GET_LESS(h, 1);
+        L_CHECK_READ_ERROR(AVL_NULL)
+    }
+
+    return(parent);
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_SEARCH_GREATEST)
+
+L_SC AVL_HANDLE L_(search_greatest)(L_(avl) *l_tree)
+{
+    AVL_HANDLE h = l_tree->root;
+    AVL_HANDLE parent = AVL_NULL;
+
+    while (h != AVL_NULL)
+    {
+        parent = h;
+        h = AVL_GET_GREATER(h, 1);
+        L_CHECK_READ_ERROR(AVL_NULL)
+    }
+
+    return(parent);
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_REMOVE)
+
+/* Prototype of balance function (called by remove) in case not in
+** same compilation unit.
+*/
+L_SC AVL_HANDLE L_(balance)(L_BALANCE_PARAM_DECL_PREFIX AVL_HANDLE bal_h);
+
+L_SC AVL_HANDLE L_(remove)(L_(avl) *l_tree, AVL_KEY k)
+{
+    /* Zero-based depth in tree. */
+    unsigned depth = 0, rm_depth;
+
+    /* Records a path into the tree.  If bit n is true, indicates
+    ** take greater branch from the nth node in the path, otherwise
+    ** take the less branch.  bit 0 gives branch from root, and
+    ** so on. */
+    L_BIT_ARR_DEFN(branch)
+
+    AVL_HANDLE h = l_tree->root;
+    AVL_HANDLE parent = AVL_NULL;
+    AVL_HANDLE child;
+    AVL_HANDLE path;
+    int cmp, cmp_shortened_sub_with_path;
+    int reduced_depth;
+    int bf;
+    AVL_HANDLE rm;
+    AVL_HANDLE parent_rm;
+
+    for (; ;)
+    {
+        if (h == AVL_NULL)
+            /* No node in tree with given key. */
+            return(AVL_NULL);
+
+        cmp = AVL_COMPARE_KEY_NODE(k, h);
+
+        if (cmp == 0)
+            /* Found node to remove. */
+            break;
+
+        parent = h;
+
+        if (cmp > 0)
+        {
+            h = AVL_GET_GREATER(h, 1);
+            L_BIT_ARR_1(branch, depth)
+        }
+        else
+        {
+            h = AVL_GET_LESS(h, 1);
+            L_BIT_ARR_0(branch, depth)
+        }
+
+        L_CHECK_READ_ERROR(AVL_NULL)
+        depth++;
+        cmp_shortened_sub_with_path = cmp;
+    }
+
+    rm = h;
+    parent_rm = parent;
+    rm_depth = depth;
+
+    /* If the node to remove is not a leaf node, we need to get a
+    ** leaf node, or a node with a single leaf as its child, to put
+    ** in the place of the node to remove.  We will get the greatest
+    ** node in the less subtree (of the node to remove), or the least
+    ** node in the greater subtree.  We take the leaf node from the
+    ** deeper subtree, if there is one. */
+
+    if (AVL_GET_BALANCE_FACTOR(h) < 0)
+    {
+        child = AVL_GET_LESS(h, 1);
+        L_BIT_ARR_0(branch, depth)
+        cmp = -1;
+    }
+    else
+    {
+        child = AVL_GET_GREATER(h, 1);
+        L_BIT_ARR_1(branch, depth)
+        cmp = 1;
+    }
+
+    L_CHECK_READ_ERROR(AVL_NULL)
+    depth++;
+
+    if (child != AVL_NULL)
+    {
+        cmp = -cmp;
+
+        do
+        {
+            parent = h;
+            h = child;
+
+            if (cmp < 0)
+            {
+                child = AVL_GET_LESS(h, 1);
+                L_BIT_ARR_0(branch, depth)
+            }
+            else
+            {
+                child = AVL_GET_GREATER(h, 1);
+                L_BIT_ARR_1(branch, depth)
+            }
+
+            L_CHECK_READ_ERROR(AVL_NULL)
+            depth++;
+        }
+        while (child != AVL_NULL);
+
+        if (parent == rm)
+            /* Only went through do loop once.  Deleted node will be replaced
+            ** in the tree structure by one of its immediate children. */
+            cmp_shortened_sub_with_path = -cmp;
+        else
+            cmp_shortened_sub_with_path = cmp;
+
+        /* Get the handle of the opposite child, which may not be null. */
+        child = cmp > 0 ? AVL_GET_LESS(h, 0) : AVL_GET_GREATER(h, 0);
+    }
+
+    if (parent == AVL_NULL)
+        /* There were only 1 or 2 nodes in this tree. */
+        l_tree->root = child;
+    else if (cmp_shortened_sub_with_path < 0)
+        AVL_SET_LESS(parent, child)
+        else
+            AVL_SET_GREATER(parent, child)
+
+            /* "path" is the parent of the subtree being eliminated or reduced
+            ** from a depth of 2 to 1.  If "path" is the node to be removed, we
+            ** set path to the node we're about to poke into the position of the
+            ** node to be removed. */
+            path = parent == rm ? h : parent;
+
+    if (h != rm)
+    {
+        /* Poke in the replacement for the node to be removed. */
+        AVL_SET_LESS(h, AVL_GET_LESS(rm, 0))
+        AVL_SET_GREATER(h, AVL_GET_GREATER(rm, 0))
+        AVL_SET_BALANCE_FACTOR(h, AVL_GET_BALANCE_FACTOR(rm))
+
+        if (parent_rm == AVL_NULL)
+            l_tree->root = h;
+        else
+        {
+            depth = rm_depth - 1;
+
+            if (L_BIT_ARR_VAL(branch, depth))
+                AVL_SET_GREATER(parent_rm, h)
+                else
+                    AVL_SET_LESS(parent_rm, h)
+                }
+    }
+
+    if (path != AVL_NULL)
+    {
+        /* Create a temporary linked list from the parent of the path node
+        ** to the root node. */
+        h = l_tree->root;
+        parent = AVL_NULL;
+        depth = 0;
+
+        while (h != path)
+        {
+            if (L_BIT_ARR_VAL(branch, depth))
+            {
+                child = AVL_GET_GREATER(h, 1);
+                AVL_SET_GREATER(h, parent)
+            }
+            else
+            {
+                child = AVL_GET_LESS(h, 1);
+                AVL_SET_LESS(h, parent)
+            }
+
+            L_CHECK_READ_ERROR(AVL_NULL)
+            depth++;
+            parent = h;
+            h = child;
+        }
+
+        /* Climb from the path node to the root node using the linked
+        ** list, restoring the tree structure and rebalancing as necessary.
+        */
+        reduced_depth = 1;
+        cmp = cmp_shortened_sub_with_path;
+
+        for (; ;)
+        {
+            if (reduced_depth)
+            {
+                bf = AVL_GET_BALANCE_FACTOR(h);
+
+                if (cmp < 0)
+                    bf++;
+                else  /* cmp > 0 */
+                    bf--;
+
+                if ((bf == -2) || (bf == 2))
+                {
+                    h = L_(balance)(L_BALANCE_PARAM_CALL_PREFIX h);
+                    L_CHECK_READ_ERROR(AVL_NULL)
+                    bf = AVL_GET_BALANCE_FACTOR(h);
+                }
+                else
+                    AVL_SET_BALANCE_FACTOR(h, bf)
+                    reduced_depth = (bf == 0);
+            }
+
+            if (parent == AVL_NULL)
+                break;
+
+            child = h;
+            h = parent;
+            depth--;
+            cmp = L_BIT_ARR_VAL(branch, depth) ? 1 : -1;
+
+            if (cmp < 0)
+            {
+                parent = AVL_GET_LESS(h, 1);
+                AVL_SET_LESS(h, child)
+            }
+            else
+            {
+                parent = AVL_GET_GREATER(h, 1);
+                AVL_SET_GREATER(h, child)
+            }
+
+            L_CHECK_READ_ERROR(AVL_NULL)
+        }
+
+        l_tree->root = h;
+    }
+
+    return(rm);
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_SUBST)
+
+L_SC AVL_HANDLE L_(subst)(L_(avl) *l_tree, AVL_HANDLE new_node)
+{
+    AVL_HANDLE h = l_tree->root;
+    AVL_HANDLE parent = AVL_NULL;
+    int cmp, last_cmp;
+
+    /* Search for node already in tree with same key. */
+    for (; ;)
+    {
+        if (h == AVL_NULL)
+            /* No node in tree with same key as new node. */
+            return(AVL_NULL);
+
+        cmp = AVL_COMPARE_NODE_NODE(new_node, h);
+
+        if (cmp == 0)
+            /* Found the node to substitute new one for. */
+            break;
+
+        last_cmp = cmp;
+        parent = h;
+        h = cmp < 0 ? AVL_GET_LESS(h, 1) : AVL_GET_GREATER(h, 1);
+        L_CHECK_READ_ERROR(AVL_NULL)
+    }
+
+    /* Copy tree housekeeping fields from node in tree to new node. */
+    AVL_SET_LESS(new_node, AVL_GET_LESS(h, 0))
+    AVL_SET_GREATER(new_node, AVL_GET_GREATER(h, 0))
+    AVL_SET_BALANCE_FACTOR(new_node, AVL_GET_BALANCE_FACTOR(h))
+
+    if (parent == AVL_NULL)
+        /* New node is also new root. */
+        l_tree->root = new_node;
+    else
+    {
+        /* Make parent point to new node. */
+        if (last_cmp < 0)
+            AVL_SET_LESS(parent, new_node)
+            else
+                AVL_SET_GREATER(parent, new_node)
+            }
+
+    return(h);
+}
+
+#endif
+
+#ifdef AVL_BUILD_ITER_TYPE
+
+#if (L_IMPL_MASK & AVL_IMPL_BUILD)
+
+L_SC int L_(build)(
+    L_(avl) *l_tree, AVL_BUILD_ITER_TYPE p, L_SIZE num_nodes)
+{
+    /* Gives path to subtree being built.  If bit n is false, branch
+    ** less from the node at depth n, if true branch greater. */
+    L_BIT_ARR_DEFN(branch)
+
+    /* If bit n is true, then for the current subtree at depth n, its
+    ** greater subtree has one more node than its less subtree. */
+    L_BIT_ARR_DEFN(rem)
+
+    /* Depth of root node of current subtree. */
+    unsigned depth = 0;
+
+    /* Number of nodes in current subtree. */
+    L_SIZE num_sub = num_nodes;
+
+    /* The algorithm relies on a stack of nodes whose less subtree has
+    ** been built, but whose greater subtree has not yet been built.
+    ** The stack is implemented as linked list.  The nodes are linked
+    ** together by having the "greater" handle of a node set to the
+    ** next node in the list.  "less_parent" is the handle of the first
+    ** node in the list. */
+    AVL_HANDLE less_parent = AVL_NULL;
+
+    /* h is root of current subtree, child is one of its children. */
+    AVL_HANDLE h;
+    AVL_HANDLE child;
+
+    if (num_nodes == 0)
+    {
+        l_tree->root = AVL_NULL;
+        return(1);
+    }
+
+    for (; ;)
+    {
+        while (num_sub > 2)
+        {
+            /* Subtract one for root of subtree. */
+            num_sub--;
+
+            if (num_sub & 1)
+                L_BIT_ARR_1(rem, depth)
+                else
+                    L_BIT_ARR_0(rem, depth)
+                    L_BIT_ARR_0(branch, depth)
+                    depth++;
+
+            num_sub >>= 1;
+        }
+
+        if (num_sub == 2)
+        {
+            /* Build a subtree with two nodes, slanting to greater.
+            ** I arbitrarily chose to always have the extra node in the
+            ** greater subtree when there is an odd number of nodes to
+            ** split between the two subtrees. */
+
+            h = AVL_BUILD_ITER_VAL(p);
+            L_CHECK_READ_ERROR(0)
+            AVL_BUILD_ITER_INCR(p)
+            child = AVL_BUILD_ITER_VAL(p);
+            L_CHECK_READ_ERROR(0)
+            AVL_BUILD_ITER_INCR(p)
+            AVL_SET_LESS(child, AVL_NULL)
+            AVL_SET_GREATER(child, AVL_NULL)
+            AVL_SET_BALANCE_FACTOR(child, 0)
+            AVL_SET_GREATER(h, child)
+            AVL_SET_LESS(h, AVL_NULL)
+            AVL_SET_BALANCE_FACTOR(h, 1)
+        }
+        else  /* num_sub == 1 */
+        {
+            /* Build a subtree with one node. */
+
+            h = AVL_BUILD_ITER_VAL(p);
+            L_CHECK_READ_ERROR(0)
+            AVL_BUILD_ITER_INCR(p)
+            AVL_SET_LESS(h, AVL_NULL)
+            AVL_SET_GREATER(h, AVL_NULL)
+            AVL_SET_BALANCE_FACTOR(h, 0)
+        }
+
+        while (depth)
+        {
+            depth--;
+
+            if (!L_BIT_ARR_VAL(branch, depth))
+                /* We've completed a less subtree. */
+                break;
+
+            /* We've completed a greater subtree, so attach it to
+            ** its parent (that is less than it).  We pop the parent
+            ** off the stack of less parents. */
+            child = h;
+            h = less_parent;
+            less_parent = AVL_GET_GREATER(h, 1);
+            L_CHECK_READ_ERROR(0)
+            AVL_SET_GREATER(h, child)
+            /* num_sub = 2 * (num_sub - rem[depth]) + rem[depth] + 1 */
+            num_sub <<= 1;
+            num_sub += L_BIT_ARR_VAL(rem, depth) ? 0 : 1;
+
+            if (num_sub & (num_sub - 1))
+                /* num_sub is not a power of 2. */
+                AVL_SET_BALANCE_FACTOR(h, 0)
+                else
+                    /* num_sub is a power of 2. */
+                    AVL_SET_BALANCE_FACTOR(h, 1)
+                }
+
+        if (num_sub == num_nodes)
+            /* We've completed the full tree. */
+            break;
+
+        /* The subtree we've completed is the less subtree of the
+        ** next node in the sequence. */
+
+        child = h;
+        h = AVL_BUILD_ITER_VAL(p);
+        L_CHECK_READ_ERROR(0)
+        AVL_BUILD_ITER_INCR(p)
+        AVL_SET_LESS(h, child)
+
+        /* Put h into stack of less parents. */
+        AVL_SET_GREATER(h, less_parent)
+        less_parent = h;
+
+        /* Proceed to creating greater than subtree of h. */
+        L_BIT_ARR_1(branch, depth)
+        num_sub += L_BIT_ARR_VAL(rem, depth) ? 1 : 0;
+        depth++;
+
+    } /* end for ( ; ; ) */
+
+    l_tree->root = h;
+
+    return(1);
+}
+
+#endif
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_INIT_ITER)
+
+/* Initialize depth to invalid value, to indicate iterator is
+** invalid.   (Depth is zero-base.)  It's not necessary to initialize
+** iterators prior to passing them to the "start" function.
+*/
+L_SC void L_(init_iter)(L_(iter) *iter)
+{
+    iter->depth = ~0;
+}
+
+#endif
+
+#ifdef AVL_READ_ERRORS_HAPPEN
+
+#define L_CHECK_READ_ERROR_INV_DEPTH \
+    { if (AVL_READ_ERROR) { iter->depth = ~0; return; } }
+
+#else
+
+#define L_CHECK_READ_ERROR_INV_DEPTH
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_START_ITER)
+
+L_SC void L_(start_iter)(
+    L_(avl) *l_tree, L_(iter) *iter, AVL_KEY k, avl_search_type st)
+{
+    AVL_HANDLE h = l_tree->root;
+    unsigned d = 0;
+    int cmp, target_cmp;
+
+    /* Save the tree that we're going to iterate through in a
+    ** member variable. */
+    iter->tree_ = l_tree;
+
+    iter->depth = ~0;
+
+    if (h == AVL_NULL)
+        /* Tree is empty. */
+        return;
+
+    if (st & AVL_LESS)
+        /* Key can be greater than key of starting node. */
+        target_cmp = 1;
+    else if (st & AVL_GREATER)
+        /* Key can be less than key of starting node. */
+        target_cmp = -1;
+    else
+        /* Key must be same as key of starting node. */
+        target_cmp = 0;
+
+    for (; ;)
+    {
+        cmp = AVL_COMPARE_KEY_NODE(k, h);
+
+        if (cmp == 0)
+        {
+            if (st & AVL_EQUAL)
+            {
+                /* Equal node was sought and found as starting node. */
+                iter->depth = d;
+                break;
+            }
+
+            cmp = -target_cmp;
+        }
+        else if (target_cmp != 0)
+            if (!((cmp ^ target_cmp) & L_MASK_HIGH_BIT))
+                /* cmp and target_cmp are both negative or both positive. */
+                iter->depth = d;
+
+        h = cmp < 0 ? AVL_GET_LESS(h, 1) : AVL_GET_GREATER(h, 1);
+        L_CHECK_READ_ERROR_INV_DEPTH
+
+        if (h == AVL_NULL)
+            break;
+
+        if (cmp > 0)
+            L_BIT_ARR_1(iter->branch, d)
+            else
+                L_BIT_ARR_0(iter->branch, d)
+                iter->path_h[d++] = h;
+    }
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_START_ITER_LEAST)
+
+L_SC void L_(start_iter_least)(L_(avl) *l_tree, L_(iter) *iter)
+{
+    AVL_HANDLE h = l_tree->root;
+
+    iter->tree_ = l_tree;
+
+    iter->depth = ~0;
+
+    L_BIT_ARR_ALL(iter->branch, 0)
+
+    while (h != AVL_NULL)
+    {
+        if (iter->depth != ~0)
+            iter->path_h[iter->depth] = h;
+
+        iter->depth++;
+        h = AVL_GET_LESS(h, 1);
+        L_CHECK_READ_ERROR_INV_DEPTH
+    }
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_START_ITER_GREATEST)
+
+L_SC void L_(start_iter_greatest)(L_(avl) *l_tree, L_(iter) *iter)
+{
+    AVL_HANDLE h = l_tree->root;
+
+    iter->tree_ = l_tree;
+
+    iter->depth = ~0;
+
+    L_BIT_ARR_ALL(iter->branch, 1)
+
+    while (h != AVL_NULL)
+    {
+        if (iter->depth != ~0)
+            iter->path_h[iter->depth] = h;
+
+        iter->depth++;
+        h = AVL_GET_GREATER(h, 1);
+        L_CHECK_READ_ERROR_INV_DEPTH
+    }
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_GET_ITER)
+
+L_SC AVL_HANDLE L_(get_iter)(L_(iter) *iter)
+{
+    if (iter->depth == ~0)
+        return(AVL_NULL);
+
+    return(iter->depth == 0 ?
+           iter->tree_->root : iter->path_h[iter->depth - 1]);
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_INCR_ITER)
+
+L_SC void L_(incr_iter)(L_(iter) *iter)
+{
+#define l_tree (iter->tree_)
+
+    if (iter->depth != ~0)
+    {
+        AVL_HANDLE h =
+            AVL_GET_GREATER((iter->depth == 0 ?
+                             iter->tree_->root : iter->path_h[iter->depth - 1]), 1);
+        L_CHECK_READ_ERROR_INV_DEPTH
+
+        if (h == AVL_NULL)
+            do
+            {
+                if (iter->depth == 0)
+                {
+                    iter->depth = ~0;
+                    break;
+                }
+
+                iter->depth--;
+            }
+            while (L_BIT_ARR_VAL(iter->branch, iter->depth));
+        else
+        {
+            L_BIT_ARR_1(iter->branch, iter->depth)
+            iter->path_h[iter->depth++] = h;
+
+            for (; ;)
+            {
+                h = AVL_GET_LESS(h, 1);
+                L_CHECK_READ_ERROR_INV_DEPTH
+
+                if (h == AVL_NULL)
+                    break;
+
+                L_BIT_ARR_0(iter->branch, iter->depth)
+                iter->path_h[iter->depth++] = h;
+            }
+        }
+    }
+
+#undef l_tree
+}
+
+#endif
+
+#if (L_IMPL_MASK & AVL_IMPL_DECR_ITER)
+
+L_SC void L_(decr_iter)(L_(iter) *iter)
+{
+#define l_tree (iter->tree_)
+
+    if (iter->depth != ~0)
+    {
+        AVL_HANDLE h =
+            AVL_GET_LESS((iter->depth == 0 ?
+                          iter->tree_->root : iter->path_h[iter->depth - 1]), 1);
+        L_CHECK_READ_ERROR_INV_DEPTH
+
+        if (h == AVL_NULL)
+            do
+            {
+                if (iter->depth == 0)
+                {
+                    iter->depth = ~0;
+                    break;
+                }
+
+                iter->depth--;
+            }
+            while (!L_BIT_ARR_VAL(iter->branch, iter->depth));
+        else
+        {
+            L_BIT_ARR_0(iter->branch, iter->depth)
+            iter->path_h[iter->depth++] = h;
+
+            for (; ;)
+            {
+                h = AVL_GET_GREATER(h, 1);
+                L_CHECK_READ_ERROR_INV_DEPTH
+
+                if (h == AVL_NULL)
+                    break;
+
+                L_BIT_ARR_1(iter->branch, iter->depth)
+                iter->path_h[iter->depth++] = h;
+            }
+        }
+    }
+
+#undef l_tree
+}
+
+#endif
+
+/* Tidy up the preprocessor symbol name space. */
+#undef L_
+#undef L_EST_LONG_BIT
+#undef L_SIZE
+#undef L_MASK_HIGH_BIT
+#undef L_LONG_BIT
+#undef L_BIT_ARR_DEFN
+#undef L_BIT_ARR_VAL
+#undef L_BIT_ARR_0
+#undef L_BIT_ARR_1
+#undef L_BIT_ARR_ALL
+#undef L_CHECK_READ_ERROR
+#undef L_CHECK_READ_ERROR_INV_DEPTH
+#undef L_BIT_ARR_LONGS
+#undef L_IMPL_MASK
+#undef L_CHECK_READ_ERROR
+#undef L_CHECK_READ_ERROR_INV_DEPTH
+#undef L_SC
+#undef L_BALANCE_PARAM_CALL_PREFIX
+#undef L_BALANCE_PARAM_DECL_PREFIX
diff --git a/vpx_mem/memory_manager/include/heapmm.h b/vpx_mem/memory_manager/include/heapmm.h
new file mode 100644 (file)
index 0000000..933e30d
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+/* External header file for Heap Memory Manager.  See documentation in
+** heapmm.html.
+*/
+
+#undef HMM_PROCESS
+
+/* Include once per configuration in a particular translation unit. */
+
+#ifndef HMM_CNFG_NUM
+
+/* Default configuration. */
+
+#ifndef HMM_INC_CNFG_DFLT
+#define HMM_INC_CNFG_DFLT
+#define HMM_PROCESS
+#endif
+
+#elif HMM_CNFG_NUM == 0
+
+/* Test configuration. */
+
+#ifndef HMM_INC_CNFG_0
+#define HMM_INC_CNFG_0
+#define HMM_PROCESS
+#endif
+
+#elif HMM_CNFG_NUM == 1
+
+#ifndef HMM_INC_CNFG_1
+#define HMM_INC_CNFG_1
+#define HMM_PROCESS
+#endif
+
+#elif HMM_CNFG_NUM == 2
+
+#ifndef HMM_INC_CNFG_2
+#define HMM_INC_CNFG_2
+#define HMM_PROCESS
+#endif
+
+#elif HMM_CNFG_NUM == 3
+
+#ifndef HMM_INC_CNFG_3
+#define HMM_INC_CNFG_3
+#define HMM_PROCESS
+#endif
+
+#elif HMM_CNFG_NUM == 4
+
+#ifndef HMM_INC_CNFG_4
+#define HMM_INC_CNFG_4
+#define HMM_PROCESS
+#endif
+
+#elif HMM_CNFG_NUM == 5
+
+#ifndef HMM_INC_CNFG_5
+#define HMM_INC_CNFG_5
+#define HMM_PROCESS
+#endif
+
+#endif
+
+#ifdef HMM_PROCESS
+
+#include "hmm_cnfg.h"
+
+/* Heap descriptor. */
+typedef struct HMM_UNIQUE(structure)
+{
+    /* private: */
+
+    /* Pointer to (payload of) root node in AVL tree.  This field should
+    ** really be the AVL tree descriptor (type avl_avl).  But (in the
+    ** instantiation of the AVL tree generic package used in package) the
+    ** AVL tree descriptor simply contains a pointer to the root.  So,
+    ** whenever a pointer to the AVL tree descriptor is needed, I use the
+    ** cast:
+    **
+    ** (avl_avl *) &(heap_desc->avl_tree_root)
+    **
+    ** (where heap_desc is a pointer to a heap descriptor).  This trick
+    ** allows me to avoid including cavl_if.h in this external header. */
+    void *avl_tree_root;
+
+    /* Pointer to first byte of last block freed, after any coalescing. */
+    void *last_freed;
+
+    /* public: */
+
+    HMM_UNIQUE(size_bau) num_baus_can_shrink;
+    void *end_of_shrinkable_chunk;
+}
+HMM_UNIQUE(descriptor);
+
+/* Prototypes for externally-callable functions. */
+
+void HMM_UNIQUE(init)(HMM_UNIQUE(descriptor) *desc);
+
+void *HMM_UNIQUE(alloc)(
+    HMM_UNIQUE(descriptor) *desc, HMM_UNIQUE(size_aau) num_addr_align_units);
+
+/* NOT YET IMPLEMENTED */
+void *HMM_UNIQUE(greedy_alloc)(
+    HMM_UNIQUE(descriptor) *desc, HMM_UNIQUE(size_aau) needed_addr_align_units,
+    HMM_UNIQUE(size_aau) coveted_addr_align_units);
+
+int HMM_UNIQUE(resize)(
+    HMM_UNIQUE(descriptor) *desc, void *mem,
+    HMM_UNIQUE(size_aau) num_addr_align_units);
+
+/* NOT YET IMPLEMENTED */
+int HMM_UNIQUE(greedy_resize)(
+    HMM_UNIQUE(descriptor) *desc, void *mem,
+    HMM_UNIQUE(size_aau) needed_addr_align_units,
+    HMM_UNIQUE(size_aau) coveted_addr_align_units);
+
+void HMM_UNIQUE(free)(HMM_UNIQUE(descriptor) *desc, void *mem);
+
+HMM_UNIQUE(size_aau) HMM_UNIQUE(true_size)(void *mem);
+
+HMM_UNIQUE(size_aau) HMM_UNIQUE(largest_available)(
+    HMM_UNIQUE(descriptor) *desc);
+
+void HMM_UNIQUE(new_chunk)(
+    HMM_UNIQUE(descriptor) *desc, void *start_of_chunk,
+    HMM_UNIQUE(size_bau) num_block_align_units);
+
+void HMM_UNIQUE(grow_chunk)(
+    HMM_UNIQUE(descriptor) *desc, void *end_of_chunk,
+    HMM_UNIQUE(size_bau) num_block_align_units);
+
+/* NOT YET IMPLEMENTED */
+void HMM_UNIQUE(shrink_chunk)(
+    HMM_UNIQUE(descriptor) *desc,
+    HMM_UNIQUE(size_bau) num_block_align_units);
+
+#endif /* defined HMM_PROCESS */
diff --git a/vpx_mem/memory_manager/include/hmm_cnfg.h b/vpx_mem/memory_manager/include/hmm_cnfg.h
new file mode 100644 (file)
index 0000000..86e4e9f
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+/* Configure Heap Memory Manager for processor architecture, compiler,
+** and desired performance characteristics.  This file is included
+** by heapmm.h, so these definitions can be used by code external to
+** HMM.  You can change the default configuration, and/or create alternate
+** configuration(s).
+*/
+
+/* To allow for multiple configurations of HMM to be used in the same
+** compilation unit, undefine all preprocessor symbols that will be
+** defined below.
+*/
+#undef HMM_ADDR_ALIGN_UNIT
+#undef HMM_BLOCK_ALIGN_UNIT
+#undef HMM_UNIQUE
+#undef HMM_DESC_PARAM
+#undef HMM_SYM_TO_STRING
+#undef HMM_SYM_TO_STRING
+#undef HMM_AUDIT_FAIL
+
+/* Turn X into a string after one macro expansion pass of X.  This trick
+** works with both GCC and Visual C++. */
+#define HMM_SYM_TO_STRING(X) HMM_SYM_TO_STRING(X)
+#define HMM_SYM_TO_STRING(X) #X
+
+#ifndef HMM_CNFG_NUM
+
+/* Default configuration. */
+
+/* Use hmm_ prefix to avoid identifier conflicts. */
+#define HMM_UNIQUE(BASE) hmm_ ## BASE
+
+/* Number of bytes in an Address Alignment Unit (AAU). */
+//fwg
+//#define HMM_ADDR_ALIGN_UNIT sizeof(int)
+#define HMM_ADDR_ALIGN_UNIT 32
+
+/* Number of AAUs in a Block Alignment Unit (BAU). */
+#define HMM_BLOCK_ALIGN_UNIT 1
+
+/* Type of unsigned integer big enough to hold the size of a Block in AAUs. */
+typedef unsigned long HMM_UNIQUE(size_aau);
+
+/* Type of unsigned integer big enough to hold the size of a Block/Chunk
+** in BAUs.  The high bit will be robbed. */
+typedef unsigned long HMM_UNIQUE(size_bau);
+
+void hmm_dflt_abort(const char *, const char *);
+
+/* Actions upon a self-audit failure.  Must expand to a single complete
+** statement.  If you remove the definition of this macro, no self-auditing
+** will be performed. */
+#define HMM_AUDIT_FAIL \
+    hmm_dflt_abort(__FILE__, HMM_SYM_TO_STRING(__LINE__));
+
+#elif HMM_CNFG_NUM == 0
+
+/* Definitions for testing. */
+
+#define HMM_UNIQUE(BASE) thmm_ ## BASE
+
+#define HMM_ADDR_ALIGN_UNIT sizeof(int)
+
+#define HMM_BLOCK_ALIGN_UNIT 3
+
+typedef unsigned HMM_UNIQUE(size_aau);
+
+typedef unsigned short HMM_UNIQUE(size_bau);
+
+/* Under this test setup, a long jump is done if there is a self-audit
+** failure.
+*/
+
+extern jmp_buf HMM_UNIQUE(jmp_buf);
+extern const char *HMM_UNIQUE(fail_file);
+extern unsigned HMM_UNIQUE(fail_line);
+
+#define HMM_AUDIT_FAIL \
+    { HMM_UNIQUE(fail_file) = __FILE__; HMM_UNIQUE(fail_line) = __LINE__; \
+        longjmp(HMM_UNIQUE(jmp_buf), 1); }
+
+#elif HMM_CNFG_NUM == 1
+
+/* Put configuration 1 definitions here (if there is a configuration 1). */
+
+#elif HMM_CNFG_NUM == 2
+
+/* Put configuration 2 definitions here. */
+
+#elif HMM_CNFG_NUM == 3
+
+/* Put configuration 3 definitions here. */
+
+#elif HMM_CNFG_NUM == 4
+
+/* Put configuration 4 definitions here. */
+
+#elif HMM_CNFG_NUM == 5
+
+/* Put configuration 5 definitions here. */
+
+#endif
diff --git a/vpx_mem/memory_manager/include/hmm_intrnl.h b/vpx_mem/memory_manager/include/hmm_intrnl.h
new file mode 100644 (file)
index 0000000..6e2be08
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This code is in the public domain.
+** Version: 1.1  Author: Walt Karas
+*/
+
+#ifndef HMM_INTRNL_H_
+#define HMM_INTRNL_H_
+
+#ifdef __uClinux__
+# include <lddk.h>
+#endif
+
+#include "heapmm.h"
+
+#define U(BASE) HMM_UNIQUE(BASE)
+
+/* Mask of high bit of variable of size_bau type. */
+#define HIGH_BIT_BAU_SIZE \
+    ((U(size_bau)) ~ (((U(size_bau)) ~ (U(size_bau)) 0) >> 1))
+
+/* Add a given number of AAUs to pointer. */
+#define AAUS_FORWARD(PTR, AAU_OFFSET) \
+    (((char *) (PTR)) + ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT)))
+
+/* Subtract a given number of AAUs from pointer. */
+#define AAUS_BACKWARD(PTR, AAU_OFFSET) \
+    (((char *) (PTR)) - ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT)))
+
+/* Add a given number of BAUs to a pointer. */
+#define BAUS_FORWARD(PTR, BAU_OFFSET) \
+    AAUS_FORWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT))
+
+/* Subtract a given number of BAUs to a pointer. */
+#define BAUS_BACKWARD(PTR, BAU_OFFSET) \
+    AAUS_BACKWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT))
+
+typedef struct head_struct
+{
+    /* Sizes in Block Alignment Units. */
+    HMM_UNIQUE(size_bau) previous_block_size, block_size;
+}
+head_record;
+
+typedef struct ptr_struct
+{
+    struct ptr_struct *self, *prev, *next;
+}
+ptr_record;
+
+/* Divide and round up any fraction to the next whole number. */
+#define DIV_ROUND_UP(NUMER, DENOM) (((NUMER) + (DENOM) - 1) / (DENOM))
+
+/* Number of AAUs in a block head. */
+#define HEAD_AAUS DIV_ROUND_UP(sizeof(head_record), HMM_ADDR_ALIGN_UNIT)
+
+/* Number of AAUs in a block pointer record. */
+#define PTR_RECORD_AAUS DIV_ROUND_UP(sizeof(ptr_record), HMM_ADDR_ALIGN_UNIT)
+
+/* Number of BAUs in a dummy end record (at end of chunk). */
+#define DUMMY_END_BLOCK_BAUS DIV_ROUND_UP(HEAD_AAUS, HMM_BLOCK_ALIGN_UNIT)
+
+/* Minimum number of BAUs in a block (allowing room for the pointer record. */
+#define MIN_BLOCK_BAUS \
+    DIV_ROUND_UP(HEAD_AAUS + PTR_RECORD_AAUS, HMM_BLOCK_ALIGN_UNIT)
+
+/* Return number of BAUs in block (masking off high bit containing block
+** status). */
+#define BLOCK_BAUS(HEAD_PTR) \
+    (((head_record *) (HEAD_PTR))->block_size & ~HIGH_BIT_BAU_SIZE)
+
+/* Return number of BAUs in previous block (masking off high bit containing
+** block status). */
+#define PREV_BLOCK_BAUS(HEAD_PTR) \
+    (((head_record *) (HEAD_PTR))->previous_block_size & ~HIGH_BIT_BAU_SIZE)
+
+/* Set number of BAUs in previous block, preserving high bit containing
+** block status. */
+#define SET_PREV_BLOCK_BAUS(HEAD_PTR, N_BAUS) \
+    { register head_record *h_ptr = (head_record *) (HEAD_PTR); \
+        h_ptr->previous_block_size &= HIGH_BIT_BAU_SIZE; \
+        h_ptr->previous_block_size |= (N_BAUS); }
+
+/* Convert pointer to pointer record of block to pointer to block's head
+** record. */
+#define PTR_REC_TO_HEAD(PTR_REC_PTR) \
+    ((head_record *) AAUS_BACKWARD(PTR_REC_PTR, HEAD_AAUS))
+
+/* Convert pointer to block head to pointer to block's pointer record. */
+#define HEAD_TO_PTR_REC(HEAD_PTR) \
+    ((ptr_record *) AAUS_FORWARD(HEAD_PTR, HEAD_AAUS))
+
+/* Returns non-zero if block is allocated. */
+#define IS_BLOCK_ALLOCATED(HEAD_PTR) \
+    (((((head_record *) (HEAD_PTR))->block_size | \
+       ((head_record *) (HEAD_PTR))->previous_block_size) & \
+      HIGH_BIT_BAU_SIZE) == 0)
+
+#define MARK_BLOCK_ALLOCATED(HEAD_PTR) \
+    { register head_record *h_ptr = (head_record *) (HEAD_PTR); \
+        h_ptr->block_size &= ~HIGH_BIT_BAU_SIZE; \
+        h_ptr->previous_block_size &= ~HIGH_BIT_BAU_SIZE; }
+
+/* Mark a block as free when it is not the first block in a bin (and
+** therefore not a node in the AVL tree). */
+#define MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(HEAD_PTR) \
+    { register head_record *h_ptr = (head_record *) (HEAD_PTR); \
+        h_ptr->block_size |= HIGH_BIT_BAU_SIZE; }
+
+/* Prototypes for internal functions implemented in one file and called in
+** another.
+*/
+
+void U(into_free_collection)(U(descriptor) *desc, head_record *head_ptr);
+
+void U(out_of_free_collection)(U(descriptor) *desc, head_record *head_ptr);
+
+void *U(alloc_from_bin)(
+    U(descriptor) *desc, ptr_record *bin_front_ptr, U(size_bau) n_baus);
+
+#ifdef HMM_AUDIT_FAIL
+
+/* Simply contains a reference to the HMM_AUDIT_FAIL macro and a
+** dummy return. */
+int U(audit_block_fail_dummy_return)(void);
+
+
+/* Auditing a block consists of checking that the size in its head
+** matches the previous block size in the head of the next block. */
+#define AUDIT_BLOCK_AS_EXPR(HEAD_PTR) \
+    ((BLOCK_BAUS(HEAD_PTR) == \
+      PREV_BLOCK_BAUS(BAUS_FORWARD(HEAD_PTR, BLOCK_BAUS(HEAD_PTR)))) ? \
+     0 : U(audit_block_fail_dummy_return)())
+
+#define AUDIT_BLOCK(HEAD_PTR) \
+    { void *h_ptr = (HEAD_PTR); AUDIT_BLOCK_AS_EXPR(h_ptr); }
+
+#endif
+
+/* Interface to AVL tree generic package instantiation. */
+
+#define AVL_UNIQUE(BASE) U(avl_ ## BASE)
+
+#define AVL_HANDLE ptr_record *
+
+#define AVL_KEY U(size_bau)
+
+#define AVL_MAX_DEPTH 64
+
+#include "cavl_if.h"
+
+#endif /* Include once. */
diff --git a/vpx_mem/nds/vpx_mem_nds.c b/vpx_mem/nds/vpx_mem_nds.c
new file mode 100644 (file)
index 0000000..f2a3043
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#define __VPX_MEM_C__
+#include "vpx_mem.h"
+#include <nitro.h>
+#include "vpx_mem_intrnl.h"
+
+// Allocate memory from the Arena specified by id.  Align it to
+//  the value specified by align.
+void *vpx_mem_nds_alloc(osarena_id id, osheap_handle handle, size_t size, size_t align)
+{
+    void *addr,
+         * x = NULL;
+
+    addr = os_alloc_from_heap((osarena_id) id, handle,
+                              size + align - 1 + ADDRESS_STORAGE_SIZE);
+
+    if (addr)
+    {
+        x = align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, (int)align);
+
+        // save the actual malloc address
+        ((size_t *)x)[-1] = (size_t)addr;
+    }
+
+    return x;
+}
+
+// Free them memory allocated by vpx_mem_nds_alloc
+void vpx_mem_nds_free(osarena_id id, osheap_handle handle, void *mem)
+{
+    if (mem)
+    {
+        void *addr = (void *)(((size_t *)mem)[-1]);
+        os_free_to_heap(id, handle, addr);
+    }
+}
+
+int vpx_nds_alloc_heap(osarena_id id, u32 size)
+{
+    osheap_handle    arena_handle;
+    void           *nstart;
+    void           *heap_start;
+
+    nstart = os_init_alloc(id, os_get_arena_lo(id), os_get_arena_hi(id), 1);
+    os_set_arena_lo(id, nstart);
+
+    heap_start = os_alloc_from_arena_lo(id, size, 32);
+    arena_handle = os_create_heap(id, heap_start, (void *)((u32)heap_start + size));
+
+    if (os_check_heap(id, arena_handle) == -1)
+        return -1;      //ERROR: DTCM heap is not consistent
+
+    (void)os_set_current_heap(id, arena_handle);
+
+    return arena_handle;
+}
diff --git a/vpx_mem/ti_c6x/vpx_mem_ti_6cx.c b/vpx_mem/ti_c6x/vpx_mem_ti_6cx.c
new file mode 100644 (file)
index 0000000..6501855
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#define __VPX_MEM_C__
+
+#include "..\include\vpx_mem.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "..\include\vpx_mem_intrnl.h"
+
+void *vpx_mem_alloc(int id, size_t size, size_t align)
+{
+#if defined CHIP_DM642 || defined __uClinux__
+    void *mem = (void *)mem_alloc(id, size, align);
+
+    if (!mem)
+    {
+        _P(fprintf(stderr,
+                   "\n"
+                   "*********************************************************\n"
+                   "WARNING: mem_alloc returned 0 for id=%p size=%u align=%u.\n"
+                   "*********************************************************\n",
+                   mem, size, align));
+        // should no longer need this.  Softier says it's fixed. 2005-01-21 tjf
+        //#if defined __uClinux__
+        //while(1)usleep(1000000);
+        //#endif
+    }
+
+#if defined __uClinux__
+    else if (mem == (void *)0xFFFFFFFF)
+    {
+        // out of memory/error
+        mem = (void *)0;
+
+        _P(fprintf(stderr,
+                   "\n"
+                   "******************************************************\n"
+                   "ERROR: mem_alloc id=%p size=%u align=%u OUT OF MEMORY.\n"
+                   "******************************************************\n",
+                   mem, size, align));
+    }
+
+#endif  // __uClinux__
+
+    return mem;
+#else
+    (void)id;
+    (void)size;
+    (void)align;
+    return (void *)0;
+#endif
+}
+
+void vpx_mem_free(int id, void *mem, size_t size)
+{
+#if defined CHIP_DM642 || defined __uClinux__
+
+    if (!mem)
+    {
+        _P(fprintf(stderr,
+                   "\n"
+                   "**************************************\n"
+                   "WARNING: 0 being free'd id=%p size=%u.\n"
+                   "**************************************\n",
+                   id, size));
+
+        // should no longer need this.  Softier says it's fixed. 2005-01-21 tjf
+        //#if defined __uClinux__
+        //while(1)usleep(1000000);
+        //#endif
+    }
+
+    mem_free(id, mem, size);
+#else
+    (void)id;
+    (void)mem;
+    (void)size;
+#endif
+}
+
+#if CONFIG_MEM_TRACKER
+void *xvpx_mem_alloc(int id, size_t size, size_t align, char *file, int line)
+{
+    void *mem = vpx_mem_alloc(id, size, align);
+
+    vpx_memory_tracker_add((size_t)mem, size, file, line, 0);
+
+    return mem;
+}
+
+void xvpx_mem_free(int id, void *mem, size_t size, char *file, int line)
+{
+    if (vpx_memory_tracker_remove((size_t)mem) == -2)
+    {
+#if REMOVE_PRINTFS
+        (void)file;
+        (void)line;
+#endif
+        _P(fprintf(stderr, "[vpx_mem][xvpx_mem_free] addr: %p (id=%p size=%u) "
+                   "not found in list; freed from file:%s"
+                   " line:%d\n", mem, id, size, file, line));
+    }
+
+    vpx_mem_free(id, mem, size);
+}
+#endif /*CONFIG_MEM_TRACKER*/
diff --git a/vpx_mem/vpx_mem.c b/vpx_mem/vpx_mem.c
new file mode 100644 (file)
index 0000000..f6b1a35
--- /dev/null
@@ -0,0 +1,719 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#define __VPX_MEM_C__
+
+#include "vpx_mem.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "include/vpx_mem_intrnl.h"
+
+#if CONFIG_MEM_TRACKER
+#ifndef VPX_NO_GLOBALS
+static unsigned long g_alloc_count = 0;
+#else
+#include "vpx_global_handling.h"
+#define g_alloc_count vpxglobalm(vpxmem,g_alloc_count)
+#endif
+#endif
+
+#if CONFIG_MEM_MANAGER
+# include "heapmm.h"
+# include "hmm_intrnl.h"
+
+# define SHIFT_HMM_ADDR_ALIGN_UNIT 5
+# define TOTAL_MEMORY_TO_ALLOCATE  20971520 // 20 * 1024 * 1024
+
+# define MM_DYNAMIC_MEMORY 1
+# if MM_DYNAMIC_MEMORY
+static unsigned char *g_p_mng_memory_raw = NULL;
+static unsigned char *g_p_mng_memory     = NULL;
+# else
+static unsigned char g_p_mng_memory[TOTAL_MEMORY_TO_ALLOCATE];
+# endif
+
+static size_t g_mm_memory_size = TOTAL_MEMORY_TO_ALLOCATE;
+
+static hmm_descriptor hmm_d;
+static int g_mng_memory_allocated = 0;
+
+static int vpx_mm_create_heap_memory();
+static void *vpx_mm_realloc(void *memblk, size_t size);
+#endif //CONFIG_MEM_MANAGER
+
+#if USE_GLOBAL_FUNCTION_POINTERS
+struct GLOBAL_FUNC_POINTERS
+{
+    g_malloc_func g_malloc;
+    g_calloc_func g_calloc;
+    g_realloc_func g_realloc;
+    g_free_func g_free;
+    g_memcpy_func g_memcpy;
+    g_memset_func g_memset;
+    g_memmove_func g_memmove;
+} *g_func = NULL;
+
+# define VPX_MALLOC_L  g_func->g_malloc
+# define VPX_REALLOC_L g_func->g_realloc
+# define VPX_FREE_L    g_func->g_free
+# define VPX_MEMCPY_L  g_func->g_memcpy
+# define VPX_MEMSET_L  g_func->g_memset
+# define VPX_MEMMOVE_L g_func->g_memmove
+#else
+# define VPX_MALLOC_L  malloc
+# define VPX_REALLOC_L realloc
+# define VPX_FREE_L    free
+# define VPX_MEMCPY_L  memcpy
+# define VPX_MEMSET_L  memset
+# define VPX_MEMMOVE_L memmove
+#endif // USE_GLOBAL_FUNCTION_POINTERS
+
+unsigned int vpx_mem_get_version()
+{
+    unsigned int ver = ((unsigned int)(unsigned char)VPX_MEM_VERSION_CHIEF << 24 |
+                        (unsigned int)(unsigned char)VPX_MEM_VERSION_MAJOR << 16 |
+                        (unsigned int)(unsigned char)VPX_MEM_VERSION_MINOR << 8  |
+                        (unsigned int)(unsigned char)VPX_MEM_VERSION_PATCH);
+    return ver;
+}
+
+int vpx_mem_set_heap_size(size_t size)
+{
+    int ret = -1;
+
+#if CONFIG_MEM_MANAGER
+#if MM_DYNAMIC_MEMORY
+
+    if (!g_mng_memory_allocated && size)
+    {
+        g_mm_memory_size = size;
+        ret = 0;
+    }
+    else
+        ret = -3;
+
+#else
+    ret = -2;
+#endif
+#else
+    (void)size;
+#endif
+
+    return ret;
+}
+
+void *vpx_memalign(size_t align, size_t size)
+{
+    void *addr,
+         * x = NULL;
+
+#if CONFIG_MEM_MANAGER
+    int number_aau;
+
+    if (vpx_mm_create_heap_memory() < 0)
+    {
+        _P(printf("[vpx][mm] ERROR vpx_memalign() Couldn't create memory for Heap.\n");)
+    }
+
+    number_aau = ((size + align - 1 + ADDRESS_STORAGE_SIZE) >>
+                  SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
+
+    addr = hmm_alloc(&hmm_d, number_aau);
+#else
+    addr = VPX_MALLOC_L(size + align - 1 + ADDRESS_STORAGE_SIZE);
+#endif //CONFIG_MEM_MANAGER
+
+    if (addr)
+    {
+        x = align_addr((unsigned char *)addr + ADDRESS_STORAGE_SIZE, (int)align);
+        /* save the actual malloc address */
+        ((size_t *)x)[-1] = (size_t)addr;
+    }
+
+    return x;
+}
+
+void *vpx_malloc(size_t size)
+{
+    return vpx_memalign(DEFAULT_ALIGNMENT, size);
+}
+
+void *vpx_calloc(size_t num, size_t size)
+{
+    void *x;
+
+    x = vpx_memalign(DEFAULT_ALIGNMENT, num * size);
+
+    if (x)
+        VPX_MEMSET_L(x, 0, num * size);
+
+    return x;
+}
+
+void *vpx_realloc(void *memblk, size_t size)
+{
+    void *addr,
+         * new_addr = NULL;
+    int align = DEFAULT_ALIGNMENT;
+
+    /*
+    The realloc() function changes the size of the object pointed to by
+    ptr to the size specified by size, and returns a pointer to the
+    possibly moved block. The contents are unchanged up to the lesser
+    of the new and old sizes. If ptr is null, realloc() behaves like
+    malloc() for the specified size. If size is zero (0) and ptr is
+    not a null pointer, the object pointed to is freed.
+    */
+    if (!memblk)
+        new_addr = vpx_malloc(size);
+    else if (!size)
+        vpx_free(memblk);
+    else
+    {
+        addr   = (void *)(((size_t *)memblk)[-1]);
+        memblk = NULL;
+
+#if CONFIG_MEM_MANAGER
+        new_addr = vpx_mm_realloc(addr, size + align + ADDRESS_STORAGE_SIZE);
+#else
+        new_addr = VPX_REALLOC_L(addr, size + align + ADDRESS_STORAGE_SIZE);
+#endif
+
+        if (new_addr)
+        {
+            addr = new_addr;
+            new_addr = (void *)(((size_t)
+                                 ((unsigned char *)new_addr + ADDRESS_STORAGE_SIZE) + (align - 1)) &
+                                (size_t) - align);
+            /* save the actual malloc address */
+            ((size_t *)new_addr)[-1] = (size_t)addr;
+        }
+    }
+
+    return new_addr;
+}
+
+void vpx_free(void *memblk)
+{
+    if (memblk)
+    {
+        void *addr = (void *)(((size_t *)memblk)[-1]);
+#if CONFIG_MEM_MANAGER
+        hmm_free(&hmm_d, addr);
+#else
+        VPX_FREE_L(addr);
+#endif
+    }
+}
+
+#if CONFIG_MEM_TRACKER
+void *xvpx_memalign(size_t align, size_t size, char *file, int line)
+{
+#if TRY_BOUNDS_CHECK
+    unsigned char *x_bounds;
+#endif
+
+    void *x;
+
+    if (g_alloc_count == 0)
+    {
+#if TRY_BOUNDS_CHECK
+        int i_rv = vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE);
+#else
+        int i_rv = vpx_memory_tracker_init(0, 0);
+#endif
+
+        if (i_rv < 0)
+        {
+            _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");)
+        }
+    }
+
+#if TRY_BOUNDS_CHECK
+    {
+        int i;
+        unsigned int tempme = BOUNDS_CHECK_VALUE;
+
+        x_bounds = vpx_memalign(align, size + (BOUNDS_CHECK_PAD_SIZE * 2));
+
+        if (x_bounds)
+        {
+            /*we're aligning the address twice here but to keep things
+              consistent we want to have the padding come before the stored
+              address so no matter what free function gets called we will
+              attempt to free the correct address*/
+            x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]);
+            x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE,
+                           (int)align);
+            /* save the actual malloc address */
+            ((size_t *)x)[-1] = (size_t)x_bounds;
+
+            for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int))
+            {
+                VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int));
+                VPX_MEMCPY_L((unsigned char *)x + size + i,
+                             &tempme, sizeof(unsigned int));
+            }
+        }
+        else
+            x = NULL;
+    }
+#else
+    x = vpx_memalign(align, size);
+#endif //TRY_BOUNDS_CHECK
+
+    g_alloc_count++;
+
+    vpx_memory_tracker_add((size_t)x, (unsigned int)size, file, line, 1);
+
+    return x;
+}
+
+void *xvpx_malloc(size_t size, char *file, int line)
+{
+    return xvpx_memalign(DEFAULT_ALIGNMENT, size, file, line);
+}
+
+void *xvpx_calloc(size_t num, size_t size, char *file, int line)
+{
+    void *x = xvpx_memalign(DEFAULT_ALIGNMENT, num * size, file, line);
+
+    if (x)
+        VPX_MEMSET_L(x, 0, num * size);
+
+    return x;
+}
+
+void *xvpx_realloc(void *memblk, size_t size, char *file, int line)
+{
+    struct mem_block *p = NULL;
+    int orig_size = 0,
+        orig_line = 0;
+    char *orig_file = NULL;
+
+#if TRY_BOUNDS_CHECK
+    unsigned char *x_bounds = memblk ?
+                              (unsigned char *)(((size_t *)memblk)[-1]) :
+                              NULL;
+#endif
+
+    void *x;
+
+    if (g_alloc_count == 0)
+    {
+#if TRY_BOUNDS_CHECK
+
+        if (!vpx_memory_tracker_init(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE))
+#else
+        if (!vpx_memory_tracker_init(0, 0))
+#endif
+        {
+            _P(printf("ERROR xvpx_malloc MEM_TRACK_USAGE error vpx_memory_tracker_init().\n");)
+        }
+    }
+
+    if ((p = vpx_memory_tracker_find((size_t)memblk)))
+    {
+        orig_size = p->size;
+        orig_file = p->file;
+        orig_line = p->line;
+    }
+
+#if TRY_BOUNDS_CHECK_ON_FREE
+    vpx_memory_tracker_check_integrity(file, line);
+#endif
+
+    //have to do this regardless of success, because
+    //the memory that does get realloc'd may change
+    //the bounds values of this block
+    vpx_memory_tracker_remove((size_t)memblk);
+
+#if TRY_BOUNDS_CHECK
+    {
+        int i;
+        unsigned int tempme = BOUNDS_CHECK_VALUE;
+
+        x_bounds = vpx_realloc(memblk, size + (BOUNDS_CHECK_PAD_SIZE * 2));
+
+        if (x_bounds)
+        {
+            x_bounds = (unsigned char *)(((size_t *)x_bounds)[-1]);
+            x = align_addr(x_bounds + BOUNDS_CHECK_PAD_SIZE + ADDRESS_STORAGE_SIZE,
+                           (int)DEFAULT_ALIGNMENT);
+            /* save the actual malloc address */
+            ((size_t *)x)[-1] = (size_t)x_bounds;
+
+            for (i = 0; i < BOUNDS_CHECK_PAD_SIZE; i += sizeof(unsigned int))
+            {
+                VPX_MEMCPY_L(x_bounds + i, &tempme, sizeof(unsigned int));
+                VPX_MEMCPY_L((unsigned char *)x + size + i,
+                             &tempme, sizeof(unsigned int));
+            }
+        }
+        else
+            x = NULL;
+    }
+#else
+    x = vpx_realloc(memblk, size);
+#endif //TRY_BOUNDS_CHECK
+
+    if (!memblk) ++g_alloc_count;
+
+    if (x)
+        vpx_memory_tracker_add((size_t)x, (unsigned int)size, file, line, 1);
+    else
+        vpx_memory_tracker_add((size_t)memblk, orig_size, orig_file, orig_line, 1);
+
+    return x;
+}
+
+void xvpx_free(void *p_address, char *file, int line)
+{
+#if TRY_BOUNDS_CHECK
+    unsigned char *p_bounds_address = (unsigned char *)p_address;
+    //p_bounds_address -= BOUNDS_CHECK_PAD_SIZE;
+#endif
+
+#if !TRY_BOUNDS_CHECK_ON_FREE
+    (void)file;
+    (void)line;
+#endif
+
+    if (p_address)
+    {
+#if TRY_BOUNDS_CHECK_ON_FREE
+        vpx_memory_tracker_check_integrity(file, line);
+#endif
+
+        //if the addr isn't found in the list, assume it was allocated via
+        //vpx_ calls not xvpx_, therefore it does not contain any padding
+        if (vpx_memory_tracker_remove((size_t)p_address) == -2)
+        {
+            p_bounds_address = p_address;
+            _P(fprintf(stderr, "[vpx_mem][xvpx_free] addr: %p not found in"
+                       " list; freed from file:%s"
+                       " line:%d\n", p_address, file, line));
+        }
+        else
+            --g_alloc_count;
+
+#if TRY_BOUNDS_CHECK
+        vpx_free(p_bounds_address);
+#else
+        vpx_free(p_address);
+#endif
+
+        if (!g_alloc_count)
+            vpx_memory_tracker_destroy();
+    }
+}
+
+#endif /*CONFIG_MEM_TRACKER*/
+
+#if CONFIG_MEM_CHECKS
+#if defined(VXWORKS)
+#include <task_lib.h> //for task_delay()
+/* This function is only used to get a stack trace of the player
+object so we can se where we are having a problem. */
+static int get_my_tt(int task)
+{
+    tt(task);
+
+    return 0;
+}
+
+static void vx_sleep(int msec)
+{
+    int ticks_to_sleep = 0;
+
+    if (msec)
+    {
+        int msec_per_tick = 1000 / sys_clk_rate_get();
+
+        if (msec < msec_per_tick)
+            ticks_to_sleep++;
+        else
+            ticks_to_sleep = msec / msec_per_tick;
+    }
+
+    task_delay(ticks_to_sleep);
+}
+#endif
+#endif
+
+void *vpx_memcpy(void *dest, const void *source, size_t length)
+{
+#if CONFIG_MEM_CHECKS
+
+    if (((int)dest < 0x4000) || ((int)source < 0x4000))
+    {
+        _P(printf("WARNING: vpx_memcpy dest:0x%x source:0x%x len:%d\n", (int)dest, (int)source, length);)
+
+#if defined(VXWORKS)
+        sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
+
+        vx_sleep(10000);
+#endif
+    }
+
+#endif
+
+    return VPX_MEMCPY_L(dest, source, length);
+}
+
+void *vpx_memset(void *dest, int val, size_t length)
+{
+#if CONFIG_MEM_CHECKS
+
+    if ((int)dest < 0x4000)
+    {
+        _P(printf("WARNING: vpx_memset dest:0x%x val:%d len:%d\n", (int)dest, val, length);)
+
+#if defined(VXWORKS)
+        sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
+
+        vx_sleep(10000);
+#endif
+    }
+
+#endif
+
+    return VPX_MEMSET_L(dest, val, length);
+}
+
+void *vpx_memmove(void *dest, const void *src, size_t count)
+{
+#if CONFIG_MEM_CHECKS
+
+    if (((int)dest < 0x4000) || ((int)src < 0x4000))
+    {
+        _P(printf("WARNING: vpx_memmove dest:0x%x src:0x%x count:%d\n", (int)dest, (int)src, count);)
+
+#if defined(VXWORKS)
+        sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
+
+        vx_sleep(10000);
+#endif
+    }
+
+#endif
+
+    return VPX_MEMMOVE_L(dest, src, count);
+}
+
+#if CONFIG_MEM_MANAGER
+
+static int vpx_mm_create_heap_memory()
+{
+    int i_rv = 0;
+
+    if (!g_mng_memory_allocated)
+    {
+#if MM_DYNAMIC_MEMORY
+        g_p_mng_memory_raw =
+            (unsigned char *)malloc(g_mm_memory_size + HMM_ADDR_ALIGN_UNIT);
+
+        if (g_p_mng_memory_raw)
+        {
+            g_p_mng_memory = (unsigned char *)((((unsigned int)g_p_mng_memory_raw) +
+                                                HMM_ADDR_ALIGN_UNIT - 1) &
+                                               -(int)HMM_ADDR_ALIGN_UNIT);
+
+            _P(printf("[vpx][mm] total memory size:%d g_p_mng_memory_raw:0x%x g_p_mng_memory:0x%x\n"
+                      , g_mm_memory_size + HMM_ADDR_ALIGN_UNIT
+                      , (unsigned int)g_p_mng_memory_raw
+                      , (unsigned int)g_p_mng_memory);)
+        }
+        else
+        {
+            _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n"
+                      , g_mm_memory_size);)
+
+            i_rv = -1;
+        }
+
+        if (g_p_mng_memory)
+#endif
+        {
+            int chunk_size = 0;
+
+            g_mng_memory_allocated = 1;
+
+            hmm_init(&hmm_d);
+
+            chunk_size = g_mm_memory_size >> SHIFT_HMM_ADDR_ALIGN_UNIT;
+
+            chunk_size -= DUMMY_END_BLOCK_BAUS;
+
+            _P(printf("[vpx][mm] memory size:%d for vpx memory manager. g_p_mng_memory:0x%x  chunk_size:%d\n"
+                      , g_mm_memory_size
+                      , (unsigned int)g_p_mng_memory
+                      , chunk_size);)
+
+            hmm_new_chunk(&hmm_d, (void *)g_p_mng_memory, chunk_size);
+        }
+
+#if MM_DYNAMIC_MEMORY
+        else
+        {
+            _P(printf("[vpx][mm] Couldn't allocate memory:%d for vpx memory manager.\n"
+                      , g_mm_memory_size);)
+
+            i_rv = -1;
+        }
+
+#endif
+    }
+
+    return i_rv;
+}
+
+static void *vpx_mm_realloc(void *memblk, size_t size)
+{
+    void *p_ret = NULL;
+
+    if (vpx_mm_create_heap_memory() < 0)
+    {
+        _P(printf("[vpx][mm] ERROR vpx_mm_realloc() Couldn't create memory for Heap.\n");)
+    }
+    else
+    {
+        int i_rv = 0;
+        int old_num_aaus;
+        int new_num_aaus;
+
+        old_num_aaus = hmm_true_size(memblk);
+        new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
+
+        if (old_num_aaus == new_num_aaus)
+        {
+            p_ret = memblk;
+        }
+        else
+        {
+            i_rv = hmm_resize(&hmm_d, memblk, new_num_aaus);
+
+            if (i_rv == 0)
+            {
+                p_ret = memblk;
+            }
+            else
+            {
+                /* Error. Try to malloc and then copy data. */
+                void *p_from_malloc;
+
+                new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
+                p_from_malloc  = hmm_alloc(&hmm_d, new_num_aaus);
+
+                if (p_from_malloc)
+                {
+                    vpx_memcpy(p_from_malloc, memblk, size);
+                    hmm_free(&hmm_d, memblk);
+
+                    p_ret = p_from_malloc;
+                }
+            }
+        }
+    }
+
+    return p_ret;
+}
+#endif //CONFIG_MEM_MANAGER
+
+#if USE_GLOBAL_FUNCTION_POINTERS
+# if CONFIG_MEM_TRACKER
+extern int vpx_memory_tracker_set_functions(g_malloc_func g_malloc_l
+        , g_calloc_func g_calloc_l
+        , g_realloc_func g_realloc_l
+        , g_free_func g_free_l
+        , g_memcpy_func g_memcpy_l
+        , g_memset_func g_memset_l
+        , g_memmove_func g_memmove_l);
+# endif
+#endif //USE_GLOBAL_FUNCTION_POINTERS
+int vpx_mem_set_functions(g_malloc_func g_malloc_l
+                          , g_calloc_func g_calloc_l
+                          , g_realloc_func g_realloc_l
+                          , g_free_func g_free_l
+                          , g_memcpy_func g_memcpy_l
+                          , g_memset_func g_memset_l
+                          , g_memmove_func g_memmove_l)
+{
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+    /* If use global functions is turned on then the
+    application must set the global functions before
+    it does anything else or vpx_mem will have
+    unpredictable results. */
+    if (!g_func)
+    {
+        g_func = (struct GLOBAL_FUNC_POINTERS *)
+                 g_malloc_l(sizeof(struct GLOBAL_FUNC_POINTERS));
+
+        if (!g_func)
+        {
+            return -1;
+        }
+    }
+
+#if CONFIG_MEM_TRACKER
+    {
+        int rv = 0;
+        rv = vpx_memory_tracker_set_functions(g_malloc_l
+                                              , g_calloc_l
+                                              , g_realloc_l
+                                              , g_free_l
+                                              , g_memcpy_l
+                                              , g_memset_l
+                                              , g_memmove_l);
+
+        if (rv < 0)
+        {
+            return rv;
+        }
+    }
+#endif
+
+    g_func->g_malloc  = g_malloc_l;
+    g_func->g_calloc  = g_calloc_l;
+    g_func->g_realloc = g_realloc_l;
+    g_func->g_free    = g_free_l;
+    g_func->g_memcpy  = g_memcpy_l;
+    g_func->g_memset  = g_memset_l;
+    g_func->g_memmove = g_memmove_l;
+
+    return 0;
+#else
+    (void)g_malloc_l;
+    (void)g_calloc_l;
+    (void)g_realloc_l;
+    (void)g_free_l;
+    (void)g_memcpy_l;
+    (void)g_memset_l;
+    (void)g_memmove_l;
+    return -1;
+#endif
+}
+
+int vpx_mem_unset_functions()
+{
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+    if (g_func)
+    {
+        g_free_func temp_free = g_func->g_free;
+        temp_free(g_func);
+        g_func = NULL;
+    }
+
+#endif
+    return 0;
+}
diff --git a/vpx_mem/vpx_mem.h b/vpx_mem/vpx_mem.h
new file mode 100644 (file)
index 0000000..6ccb9be
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __VPX_MEM_H__
+#define __VPX_MEM_H__
+
+#if defined(__uClinux__)
+# include <lddk.h>
+#endif
+
+/* vpx_mem version info */
+#define vpx_mem_version "2.2.1.5"
+
+#define VPX_MEM_VERSION_CHIEF 2
+#define VPX_MEM_VERSION_MAJOR 2
+#define VPX_MEM_VERSION_MINOR 1
+#define VPX_MEM_VERSION_PATCH 5
+/* end - vpx_mem version info */
+
+#ifndef VPX_TRACK_MEM_USAGE
+# define VPX_TRACK_MEM_USAGE       0  //enable memory tracking/integrity checks
+#endif
+#ifndef VPX_CHECK_MEM_FUNCTIONS
+# define VPX_CHECK_MEM_FUNCTIONS   0  //enable basic safety checks in _memcpy,
+//_memset, and _memmove
+#endif
+#ifndef REPLACE_BUILTIN_FUNCTIONS
+# define REPLACE_BUILTIN_FUNCTIONS 0  //replace builtin functions with their
+//vpx_ equivalents
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+    /*
+        vpx_mem_get_version()
+        provided for runtime version checking. Returns an unsigned int of the form
+        CHIEF | MAJOR | MINOR | PATCH, where the chief version number is the high
+        order byte.
+    */
+    unsigned int vpx_mem_get_version(void);
+
+    /*
+        vpx_mem_set_heap_size(size_t size)
+          size - size in bytes for the memory manager to allocate for its heap
+        Sets the memory manager's initial heap size
+        Return:
+          0: on success
+          -1: if memory manager calls have not been included in the vpx_mem lib
+          -2: if the memory manager has been compiled to use static memory
+          -3: if the memory manager has already allocated its heap
+    */
+    int vpx_mem_set_heap_size(size_t size);
+
+    void *vpx_memalign(size_t align, size_t size);
+    void *vpx_malloc(size_t size);
+    void *vpx_calloc(size_t num, size_t size);
+    void *vpx_realloc(void *memblk, size_t size);
+    void vpx_free(void *memblk);
+
+    void *vpx_memcpy(void *dest, const void *src, size_t length);
+    void *vpx_memset(void *dest, int val, size_t length);
+    void *vpx_memmove(void *dest, const void *src, size_t count);
+
+// special memory functions
+    void *vpx_mem_alloc(int id, size_t size, size_t align);
+    void vpx_mem_free(int id, void *mem, size_t size);
+
+    /* Wrappers to standard library functions. */
+    typedef void*(* g_malloc_func)(size_t);
+    typedef void*(* g_calloc_func)(size_t, size_t);
+    typedef void*(* g_realloc_func)(void *, size_t);
+    typedef void (* g_free_func)(void *);
+    typedef void*(* g_memcpy_func)(void *, const void *, size_t);
+    typedef void*(* g_memset_func)(void *, int, size_t);
+    typedef void*(* g_memmove_func)(void *, const void *, size_t);
+
+    int vpx_mem_set_functions(g_malloc_func g_malloc_l
+                              , g_calloc_func g_calloc_l
+                              , g_realloc_func g_realloc_l
+                              , g_free_func g_free_l
+                              , g_memcpy_func g_memcpy_l
+                              , g_memset_func g_memset_l
+                              , g_memmove_func g_memmove_l);
+    int vpx_mem_unset_functions(void);
+
+
+    /* some defines for backward compatibility */
+#define DMEM_GENERAL 0
+
+#define duck_memalign(X,Y,Z) vpx_memalign(X,Y)
+#define duck_malloc(X,Y) vpx_malloc(X)
+#define duck_calloc(X,Y,Z) vpx_calloc(X,Y)
+#define duck_realloc  vpx_realloc
+#define duck_free     vpx_free
+#define duck_memcpy   vpx_memcpy
+#define duck_memmove  vpx_memmove
+#define duck_memset   vpx_memset
+
+#if REPLACE_BUILTIN_FUNCTIONS
+# ifndef __VPX_MEM_C__
+#  define memalign vpx_memalign
+#  define malloc   vpx_malloc
+#  define calloc   vpx_calloc
+#  define realloc  vpx_realloc
+#  define free     vpx_free
+#  define memcpy   vpx_memcpy
+#  define memmove  vpx_memmove
+#  define memset   vpx_memset
+# endif
+#endif
+
+#if CONFIG_MEM_TRACKER
+#include <stdarg.h>
+    /*from vpx_mem/vpx_mem_tracker.c*/
+    extern void vpx_memory_tracker_dump();
+    extern void vpx_memory_tracker_check_integrity(char *file, unsigned int line);
+    extern int vpx_memory_tracker_set_log_type(int type, char *option);
+    extern int vpx_memory_tracker_set_log_func(void *userdata,
+            void(*logfunc)(void *userdata,
+                           const char *fmt, va_list args));
+# ifndef __VPX_MEM_C__
+#  define vpx_memalign(align, size) xvpx_memalign((align), (size), __FILE__, __LINE__)
+#  define vpx_malloc(size)          xvpx_malloc((size), __FILE__, __LINE__)
+#  define vpx_calloc(num, size)     xvpx_calloc(num, size, __FILE__, __LINE__)
+#  define vpx_realloc(addr, size)   xvpx_realloc(addr, size, __FILE__, __LINE__)
+#  define vpx_free(addr)            xvpx_free(addr, __FILE__, __LINE__)
+#  define vpx_memory_tracker_check_integrity() vpx_memory_tracker_check_integrity(__FILE__, __LINE__)
+#  define vpx_mem_alloc(id,size,align) xvpx_mem_alloc(id, size, align, __FILE__, __LINE__)
+#  define vpx_mem_free(id,mem,size) xvpx_mem_free(id, mem, size, __FILE__, __LINE__)
+# endif
+
+    void *xvpx_memalign(size_t align, size_t size, char *file, int line);
+    void *xvpx_malloc(size_t size, char *file, int line);
+    void *xvpx_calloc(size_t num, size_t size, char *file, int line);
+    void *xvpx_realloc(void *memblk, size_t size, char *file, int line);
+    void xvpx_free(void *memblk, char *file, int line);
+    void *xvpx_mem_alloc(int id, size_t size, size_t align, char *file, int line);
+    void xvpx_mem_free(int id, void *mem, size_t size, char *file, int line);
+
+#else
+# ifndef __VPX_MEM_C__
+#  define vpx_memory_tracker_dump()
+#  define vpx_memory_tracker_check_integrity()
+#  define vpx_memory_tracker_set_log_type(t,o) 0
+#  define vpx_memory_tracker_set_log_func(u,f) 0
+# endif
+#endif
+
+#if !VPX_CHECK_MEM_FUNCTIONS
+# ifndef __VPX_MEM_C__
+#  include <string.h>
+#  define vpx_memcpy  memcpy
+#  define vpx_memset  memset
+#  define vpx_memmove memmove
+# endif
+#endif
+
+#ifdef VPX_MEM_PLTFRM
+# include VPX_MEM_PLTFRM
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __VPX_MEM_H__ */
diff --git a/vpx_mem/vpx_mem.mk b/vpx_mem/vpx_mem.mk
new file mode 100644 (file)
index 0000000..4663c5a
--- /dev/null
@@ -0,0 +1,22 @@
+MEM_SRCS-yes += vpx_mem.mk
+MEM_SRCS-yes += vpx_mem.c
+MEM_SRCS-yes += vpx_mem.h
+MEM_SRCS-yes += include/vpx_mem_intrnl.h
+
+MEM_SRCS-$(CONFIG_MEM_TRACKER) += vpx_mem_tracker.c
+MEM_SRCS-$(CONFIG_MEM_TRACKER) += include/vpx_mem_tracker.h
+
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_true.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_resize.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_shrink.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_largest.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_dflt_abort.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_base.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/include
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/include/hmm_intrnl.h
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/include/cavl_if.h
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/include/hmm_cnfg.h
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/include/heapmm.h
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/include/cavl_impl.h
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_grow.c
+MEM_SRCS-$(CONFIG_MEM_MANAGER) += memory_manager/hmm_alloc.c
diff --git a/vpx_mem/vpx_mem_tracker.c b/vpx_mem/vpx_mem_tracker.c
new file mode 100644 (file)
index 0000000..4427e27
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/*
+  vpx_mem_tracker.c
+
+  jwz 2003-09-30:
+   Stores a list of addreses, their size, and file and line they came from.
+   All exposed lib functions are prefaced by vpx_ and allow the global list
+   to be thread safe.
+   Current supported platforms are:
+    Linux, Win32, win_ce and vx_works
+   Further support can be added by defining the platform specific mutex
+   in the memory_tracker struct as well as calls to create/destroy/lock/unlock
+   the mutex in vpx_memory_tracker_init/Destroy and memory_tracker_lock_mutex/unlock_mutex
+*/
+#include "vpx_ports/config.h"
+
+#if defined(__uClinux__)
+# include <lddk.h>
+#endif
+
+#if HAVE_PTHREAD_H
+# include <pthread.h>
+#elif defined(WIN32) || defined(_WIN32_WCE)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <winbase.h>
+#elif defined(VXWORKS)
+# include <sem_lib.h>
+#elif defined(NDS_NITRO)
+# include <nitro.h>
+# include <nitro/os.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> //VXWORKS doesn't have a malloc/memory.h file,
+//this should pull in malloc,free,etc.
+#include <stdarg.h>
+
+#include "include/vpx_mem_tracker.h"
+
+#undef vpx_malloc   //undefine any vpx_mem macros that may affect calls to
+#undef vpx_free     //memory functions in this file
+#undef vpx_memcpy
+#undef vpx_memset
+
+
+#ifndef USE_GLOBAL_FUNCTION_POINTERS
+# define USE_GLOBAL_FUNCTION_POINTERS   0  //use function pointers instead of compiled functions.
+#endif
+
+#if USE_GLOBAL_FUNCTION_POINTERS
+static mem_track_malloc_func g_malloc   = malloc;
+static mem_track_calloc_func g_calloc   = calloc;
+static mem_track_realloc_func g_realloc = realloc;
+static mem_track_free_func g_free       = free;
+static mem_track_memcpy_func g_memcpy   = memcpy;
+static mem_track_memset_func g_memset   = memset;
+static mem_track_memmove_func g_memmove = memmove;
+# define MEM_TRACK_MALLOC g_malloc
+# define MEM_TRACK_FREE   g_free
+# define MEM_TRACK_MEMCPY g_memcpy
+# define MEM_TRACK_MEMSET g_memset
+#else
+# define MEM_TRACK_MALLOC vpx_malloc
+# define MEM_TRACK_FREE   vpx_free
+# define MEM_TRACK_MEMCPY vpx_memcpy
+# define MEM_TRACK_MEMSET vpx_memset
+#endif // USE_GLOBAL_FUNCTION_POINTERS
+
+/* prototypes for internal library functions */
+static void memtrack_log(const char *fmt, ...);
+static void memory_tracker_dump();
+static void memory_tracker_check_integrity(char *file, unsigned int line);
+static void memory_tracker_add(size_t addr, unsigned int size,
+                               char *file, unsigned int line,
+                               int padded);
+static int memory_tracker_remove(size_t addr);
+static struct mem_block *memory_tracker_find(size_t addr);
+
+#if defined(NO_MUTEX)
+# define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited)
+# define memory_tracker_unlock_mutex()
+#else
+static int memory_tracker_lock_mutex();
+static int memory_tracker_unlock_mutex();
+#endif
+
+#ifndef VPX_NO_GLOBALS
+struct memory_tracker
+{
+    struct mem_block *head,
+            * tail;
+    int len,
+        totalsize;
+    unsigned int current_allocated,
+             max_allocated;
+
+#if HAVE_PTHREAD_H
+    pthread_mutex_t mutex;
+#elif defined(WIN32) || defined(_WIN32_WCE)
+    HANDLE mutex;
+#elif defined(VXWORKS)
+    SEM_ID mutex;
+#elif defined(NDS_NITRO)
+    OSMutex mutex;
+#elif defined(NO_MUTEX)
+#else
+#error "No mutex type defined for this platform!"
+#endif
+
+    int padding_size,
+        pad_value;
+};
+
+static struct memory_tracker memtrack;   //our global memory allocation list
+static int g_b_mem_tracker_inited = 0;     //indicates whether the global list has
+//been initialized (1:yes/0:no)
+static struct
+{
+    FILE *file;
+    int type;
+    void (*func)(void *userdata, const char *fmt, va_list args);
+    void *userdata;
+} g_logging = {NULL, 0, NULL, NULL};
+#else
+# include "vpx_global_handling.h"
+#define g_b_mem_tracker_inited vpxglobalm(vpxmem,g_b_mem_tracker_inited)
+#define g_logging vpxglobalm(vpxmem,g_logging)
+#define memtrack vpxglobalm(vpxmem,memtrack)
+#endif // #ifndef VPX_NO_GLOBALS
+
+extern void *vpx_malloc(size_t size);
+extern void vpx_free(void *memblk);
+extern void *vpx_memcpy(void *dest, const void *src, size_t length);
+extern void *vpx_memset(void *dest, int val, size_t length);
+
+/*
+ *
+ * Exposed library functions
+ *
+*/
+
+/*
+    vpx_memory_tracker_init(int padding_size, int pad_value)
+      padding_size - the size of the padding before and after each mem addr.
+                     Values > 0 indicate that integrity checks can be performed
+                     by inspecting these areas.
+      pad_value - the initial value within the padding area before and after
+                  each mem addr.
+
+    Initializes global memory tracker structure
+    Allocates the head of the list
+*/
+int vpx_memory_tracker_init(int padding_size, int pad_value)
+{
+    if (!g_b_mem_tracker_inited)
+    {
+        if ((memtrack.head = (struct mem_block *)
+                             MEM_TRACK_MALLOC(sizeof(struct mem_block))))
+        {
+            int ret;
+
+            MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block));
+
+            memtrack.tail = memtrack.head;
+
+            memtrack.current_allocated = 0;
+            memtrack.max_allocated     = 0;
+
+            memtrack.padding_size = padding_size;
+            memtrack.pad_value    = pad_value;
+
+#if HAVE_PTHREAD_H
+            ret = pthread_mutex_init(&memtrack.mutex,
+                                     NULL);            /*mutex attributes (NULL=default)*/
+#elif defined(WIN32) || defined(_WIN32_WCE)
+            memtrack.mutex = CreateMutex(NULL,   /*security attributes*/
+                                          FALSE,  /*we don't want initial ownership*/
+                                          NULL);  /*mutex name*/
+            ret = !memtrack.mutex;
+#elif defined(VXWORKS)
+            memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based mutex*/
+                                         SEM_FULL);  /*SEM_FULL initial state is unlocked*/
+            ret = !memtrack.mutex;
+#elif defined(NDS_NITRO)
+            os_init_mutex(&memtrack.mutex);
+            ret = 0;
+#elif defined(NO_MUTEX)
+            ret = 0;
+#endif
+
+            if (ret)
+            {
+                memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n");
+
+                MEM_TRACK_FREE(memtrack.head);
+                memtrack.head = NULL;
+            }
+            else
+            {
+                memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version" pad_size:%d pad_val:0x%x %d\n"
+                             , padding_size
+                             , pad_value
+                             , pad_value);
+                g_b_mem_tracker_inited = 1;
+            }
+        }
+    }
+
+    return g_b_mem_tracker_inited;
+}
+
+/*
+    vpx_memory_tracker_destroy()
+    If our global struct was initialized zeros out all its members,
+    frees memory and destroys it's mutex
+*/
+void vpx_memory_tracker_destroy()
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        struct mem_block *p  = memtrack.head,
+                                  * p2 = memtrack.head;
+
+        memory_tracker_dump();
+
+        while (p)
+    {
+            p2 = p;
+            p  = p->next;
+
+            MEM_TRACK_FREE(p2);
+        }
+
+        memtrack.head              = NULL;
+        memtrack.tail              = NULL;
+        memtrack.len               = 0;
+        memtrack.current_allocated = 0;
+        memtrack.max_allocated     = 0;
+
+        if (!g_logging.type && g_logging.file && g_logging.file != stderr)
+        {
+#if !defined(NDS_NITRO)
+            fclose(g_logging.file);
+#endif
+            g_logging.file = NULL;
+        }
+
+        memory_tracker_unlock_mutex();
+
+        g_b_mem_tracker_inited = 0;
+    }
+}
+
+/*
+    vpx_memory_tracker_add(size_t addr, unsigned int size,
+                         char * file, unsigned int line)
+      addr - memory address to be added to list
+      size - size of addr
+      file - the file addr was referenced from
+      line - the line in file addr was referenced from
+    Adds memory address addr, it's size, file and line it came from
+    to the global list via the thread safe internal library function
+*/
+void vpx_memory_tracker_add(size_t addr, unsigned int size,
+                            char *file, unsigned int line,
+                            int padded)
+{
+    memory_tracker_add(addr, size, file, line, padded);
+}
+
+/*
+    vpx_memory_tracker_remove(size_t addr)
+      addr - memory address to be removed from list
+    Removes addr from the global list via the thread safe
+    internal remove function
+    Return:
+      Same as described for memory_tracker_remove
+*/
+int vpx_memory_tracker_remove(size_t addr)
+{
+    return memory_tracker_remove(addr);
+}
+
+/*
+    vpx_memory_tracker_find(size_t addr)
+      addr - address to be found in list
+    Return:
+        If found, pointer to the memory block that matches addr
+        NULL otherwise
+*/
+struct mem_block *vpx_memory_tracker_find(size_t addr)
+{
+    struct mem_block *p = NULL;
+
+    if (!memory_tracker_lock_mutex())
+    {
+        p = memory_tracker_find(addr);
+        memory_tracker_unlock_mutex();
+    }
+
+    return p;
+}
+
+/*
+    vpx_memory_tracker_dump()
+    Locks the memory tracker's mutex and calls the internal
+    library function to dump the current contents of the
+    global memory allocation list
+*/
+void vpx_memory_tracker_dump()
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        memory_tracker_dump();
+        memory_tracker_unlock_mutex();
+    }
+}
+
+/*
+    vpx_memory_tracker_check_integrity(char* file, unsigned int line)
+      file - The file name where the check was placed
+      line - The line in file where the check was placed
+    Locks the memory tracker's mutex and calls the internal
+    integrity check function to inspect every address in the global
+    memory allocation list
+*/
+void vpx_memory_tracker_check_integrity(char *file, unsigned int line)
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        memory_tracker_check_integrity(file, line);
+        memory_tracker_unlock_mutex();
+    }
+}
+
+/*
+    vpx_memory_tracker_set_log_type
+    Sets the logging type for the memory tracker. Based on the value it will
+    direct its output to the appropriate place.
+    Return:
+      0: on success
+      -1: if the logging type could not be set, because the value was invalid
+          or because a file could not be opened
+*/
+int vpx_memory_tracker_set_log_type(int type, char *option)
+{
+    int ret = -1;
+
+    switch (type)
+    {
+    case 0:
+        g_logging.type = 0;
+
+        if (!option)
+        {
+            g_logging.file = stderr;
+            ret = 0;
+        }
+
+#if !defined(NDS_NITRO)
+        else
+        {
+            if ((g_logging.file = fopen((char *)option, "w")))
+                ret = 0;
+        }
+
+#endif
+        break;
+#if defined(WIN32) && !defined(_WIN32_WCE)
+    case 1:
+        g_logging.type = type;
+        ret = 0;
+        break;
+#endif
+    default:
+        break;
+    }
+
+    //output the version to the new logging destination
+    if (!ret)
+        memtrack_log("Memory Tracker logging initialized, "
+                     "Memory Tracker v."vpx_mem_tracker_version"\n");
+
+    return ret;
+}
+
+/*
+    vpx_memory_tracker_set_log_func
+    Sets a logging function to be used by the memory tracker.
+    Return:
+      0: on success
+      -1: if the logging type could not be set because logfunc was NULL
+*/
+int vpx_memory_tracker_set_log_func(void *userdata,
+                                    void(*logfunc)(void *userdata,
+                                            const char *fmt, va_list args))
+{
+    int ret = -1;
+
+    if (logfunc)
+    {
+        g_logging.type     = -1;
+        g_logging.userdata = userdata;
+        g_logging.func     = logfunc;
+        ret = 0;
+    }
+
+    //output the version to the new logging destination
+    if (!ret)
+        memtrack_log("Memory Tracker logging initialized, "
+                     "Memory Tracker v."vpx_mem_tracker_version"\n");
+
+    return ret;
+}
+
+/*
+ *
+ * END - Exposed library functions
+ *
+*/
+
+
+/*
+ *
+ * Internal library functions
+ *
+*/
+
+static void memtrack_log(const char *fmt, ...)
+{
+    va_list list;
+
+    va_start(list, fmt);
+
+    switch (g_logging.type)
+    {
+    case -1:
+
+        if (g_logging.func)
+            g_logging.func(g_logging.userdata, fmt, list);
+
+        break;
+    case 0:
+
+        if (g_logging.file)
+        {
+            vfprintf(g_logging.file, fmt, list);
+            fflush(g_logging.file);
+        }
+
+        break;
+#if defined(WIN32) && !defined(_WIN32_WCE)
+    case 1:
+    {
+        char temp[1024];
+        _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list);
+        OutputDebugString(temp);
+    }
+    break;
+#endif
+    default:
+        break;
+    }
+
+    va_end(list);
+}
+
+/*
+    memory_tracker_dump()
+    Dumps the current contents of the global memory allocation list
+*/
+static void memory_tracker_dump()
+{
+    int i = 0;
+    struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL);
+
+    memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n",
+                 memtrack.current_allocated, memtrack.max_allocated);
+
+    while (p)
+    {
+#if defined(WIN32) && !defined(_WIN32_WCE)
+
+        /*when using outputdebugstring, output filenames so they
+          can be clicked to be opened in visual studio*/
+        if (g_logging.type == 1)
+            memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file:\n"
+                         "  %s(%d):\n", i,
+                         p->addr, i, p->size,
+                         p->file, p->line);
+        else
+#endif
+            memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s, line: %d\n", i,
+                         p->addr, i, p->size,
+                         p->file, p->line);
+
+#ifdef NDS_NITRO
+
+        if (!(i % 20)) os_sleep(500);
+
+#endif
+
+        p = p->next;
+        ++i;
+    }
+
+    memtrack_log("\n");
+}
+
+/*
+    memory_tracker_check_integrity(char* file, unsigned int file)
+      file - the file name where the check was placed
+      line - the line in file where the check was placed
+    If a padding_size was supplied to vpx_memory_tracker_init()
+    this function will check ea. addr in the list verifying that
+    addr-padding_size and addr+padding_size is filled with pad_value
+*/
+static void memory_tracker_check_integrity(char *file, unsigned int line)
+{
+    if (memtrack.padding_size)
+    {
+        int i,
+            index = 0;
+        unsigned char *p_show_me,
+                 * p_show_me2;
+        unsigned int tempme = memtrack.pad_value,
+                     dead1,
+                     dead2;
+        unsigned char *x_bounds;
+        struct mem_block *p = memtrack.head->next;
+
+        while (p)
+        {
+            //x_bounds = (unsigned char*)p->addr;
+            //back up VPX_BYTE_ALIGNMENT
+            //x_bounds -= memtrack.padding_size;
+
+            if (p->padded)   // can the bounds be checked?
+            {
+                /*yes, move to the address that was actually allocated
+                by the vpx_* calls*/
+                x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]);
+
+                for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int))
+                {
+                    p_show_me = (x_bounds + i);
+                    p_show_me2 = (unsigned char *)(p->addr + p->size + i);
+
+                    MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int));
+                    MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int));
+
+                    if ((dead1 != tempme) || (dead2 != tempme))
+                    {
+                        memtrack_log("\n[vpx_mem integrity check failed]:\n"
+                                     "    index[%d,%d] {%s:%d} addr=0x%x, size=%d,"
+                                     " file: %s, line: %d c0:0x%x c1:0x%x\n",
+                                     index, i, file, line, p->addr, p->size, p->file,
+                                     p->line, dead1, dead2);
+                    }
+                }
+            }
+
+            ++index;
+            p = p->next;
+        }
+    }
+}
+
+/*
+    memory_tracker_add(size_t addr, unsigned int size,
+                     char * file, unsigned int line)
+    Adds an address (addr), it's size, file and line number to our list.
+    Adjusts the total bytes allocated and max bytes allocated if necessary.
+    If memory cannot be allocated the list will be destroyed.
+*/
+void memory_tracker_add(size_t addr, unsigned int size,
+                        char *file, unsigned int line,
+                        int padded)
+{
+    if (!memory_tracker_lock_mutex())
+    {
+        struct mem_block *p;
+
+        p = MEM_TRACK_MALLOC(sizeof(struct mem_block));
+
+        if (p)
+        {
+            p->prev       = memtrack.tail;
+            p->prev->next = p;
+            p->addr       = addr;
+            p->size       = size;
+            p->line       = line;
+            p->file       = file;
+            p->padded     = padded;
+            p->next       = NULL;
+
+            memtrack.tail = p;
+
+            memtrack.current_allocated += size;
+
+            if (memtrack.current_allocated > memtrack.max_allocated)
+                memtrack.max_allocated = memtrack.current_allocated;
+
+            //memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr);
+
+            memory_tracker_unlock_mutex();
+        }
+        else
+        {
+            memtrack_log("memory_tracker_add: error allocating memory!\n");
+            memory_tracker_unlock_mutex();
+            vpx_memory_tracker_destroy();
+        }
+    }
+}
+
+/*
+    memory_tracker_remove(size_t addr)
+    Removes an address and its corresponding size (if they exist)
+    from the memory tracker list and adjusts the current number
+    of bytes allocated.
+    Return:
+      0: on success
+      -1: if the mutex could not be locked
+      -2: if the addr was not found in the list
+*/
+int memory_tracker_remove(size_t addr)
+{
+    int ret = -1;
+
+    if (!memory_tracker_lock_mutex())
+    {
+        struct mem_block *p;
+
+        if ((p = memory_tracker_find(addr)))
+        {
+            memtrack.current_allocated -= p->size;
+
+            p->prev->next = p->next;
+
+            if (p->next)
+                p->next->prev = p->prev;
+            else
+                memtrack.tail = p->prev;
+
+            ret = 0;
+            MEM_TRACK_FREE(p);
+        }
+        else
+        {
+            if (addr)
+                memtrack_log("memory_tracker_remove(): addr not found in list,"
+                             " 0x%.8x\n", addr);
+
+            ret = -2;
+        }
+
+        memory_tracker_unlock_mutex();
+    }
+
+    return ret;
+}
+
+/*
+    memory_tracker_find(size_t addr)
+    Finds an address in our addrs list
+    NOTE: the mutex MUST be locked in the other internal
+          functions before calling this one. This avoids
+          the need for repeated locking and unlocking as in Remove
+    Returns: pointer to the mem block if found, NULL otherwise
+*/
+static struct mem_block *memory_tracker_find(size_t addr)
+{
+    struct mem_block *p = NULL;
+
+    if (memtrack.head)
+    {
+        p = memtrack.head->next;
+
+        while (p && (p->addr != addr))
+            p = p->next;
+    }
+
+    return p;
+}
+
+
+#if !defined(NO_MUTEX)
+/*
+    memory_tracker_lock_mutex()
+    Locks the memory tracker mutex with a platform specific call
+    Returns:
+        0: Success
+       <0: Failure, either the mutex was not initialized
+           or the call to lock the mutex failed
+*/
+static int memory_tracker_lock_mutex()
+{
+    int ret = -1;
+
+    if (g_b_mem_tracker_inited)
+    {
+
+#if HAVE_PTHREAD_H
+        ret = pthread_mutex_lock(&memtrack.mutex);
+#elif defined(WIN32) || defined(_WIN32_WCE)
+        ret = WaitForSingleObject(memtrack.mutex, INFINITE);
+#elif defined(VXWORKS)
+        ret = sem_take(memtrack.mutex, WAIT_FOREVER);
+#elif defined(NDS_NITRO)
+        os_lock_mutex(&memtrack.mutex);
+        ret = 0;
+#endif
+
+        if (ret)
+        {
+            memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n");
+        }
+    }
+
+    return ret;
+}
+
+/*
+    memory_tracker_unlock_mutex()
+    Unlocks the memory tracker mutex with a platform specific call
+    Returns:
+        0: Success
+       <0: Failure, either the mutex was not initialized
+           or the call to unlock the mutex failed
+*/
+static int memory_tracker_unlock_mutex()
+{
+    int ret = -1;
+
+    if (g_b_mem_tracker_inited)
+    {
+
+#if HAVE_PTHREAD_H
+        ret = pthread_mutex_unlock(&memtrack.mutex);
+#elif defined(WIN32) || defined(_WIN32_WCE)
+        ret = !ReleaseMutex(memtrack.mutex);
+#elif defined(VXWORKS)
+        ret = sem_give(memtrack.mutex);
+#elif defined(NDS_NITRO)
+        os_unlock_mutex(&memtrack.mutex);
+        ret = 0;
+#endif
+
+        if (ret)
+        {
+            memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n");
+        }
+    }
+
+    return ret;
+}
+#endif
+
+/*
+    vpx_memory_tracker_set_functions
+
+    Sets the function pointers for the standard library functions.
+
+    Return:
+      0: on success
+      -1: if the use global function pointers is not set.
+*/
+int vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l
+                                     , mem_track_calloc_func g_calloc_l
+                                     , mem_track_realloc_func g_realloc_l
+                                     , mem_track_free_func g_free_l
+                                     , mem_track_memcpy_func g_memcpy_l
+                                     , mem_track_memset_func g_memset_l
+                                     , mem_track_memmove_func g_memmove_l)
+{
+#if USE_GLOBAL_FUNCTION_POINTERS
+
+    if (g_malloc_l)
+        g_malloc = g_malloc_l;
+
+    if (g_calloc_l)
+        g_calloc = g_calloc_l;
+
+    if (g_realloc_l)
+        g_realloc = g_realloc_l;
+
+    if (g_free_l)
+        g_free = g_free_l;
+
+    if (g_memcpy_l)
+        g_memcpy = g_memcpy_l;
+
+    if (g_memset_l)
+        g_memset = g_memset_l;
+
+    if (g_memmove_l)
+        g_memmove = g_memmove_l;
+
+    return 0;
+#else
+    (void)g_malloc_l;
+    (void)g_calloc_l;
+    (void)g_realloc_l;
+    (void)g_free_l;
+    (void)g_memcpy_l;
+    (void)g_memset_l;
+    (void)g_memmove_l;
+    return -1;
+#endif
+}
diff --git a/vpx_ports/config.h b/vpx_ports/config.h
new file mode 100644 (file)
index 0000000..da38137
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This file uses some preprocessor magic to expand the value of HAVE_CONFIG_H,
+ * as defined by the build system, so that different projects can use the file
+ * name for config.h that suits them.
+ */
+#define QUOTE_(x) #x
+#define QUOTE(x) QUOTE_(x)
+#include QUOTE(HAVE_CONFIG_H)
+#undef QUOTE
+#undef QUOTE_
diff --git a/vpx_ports/emms.asm b/vpx_ports/emms.asm
new file mode 100644 (file)
index 0000000..03e3499
--- /dev/null
@@ -0,0 +1,37 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "x86_abi_support.asm"
+
+section .text
+    global sym(vpx_reset_mmx_state)
+sym(vpx_reset_mmx_state):
+    emms
+    ret
+
+
+%ifidn __OUTPUT_FORMAT__,x64
+global sym(vpx_winx64_fldcw)
+sym(vpx_winx64_fldcw):
+    sub   rsp, 8
+    mov   [rsp], rcx ; win x64 specific
+    fldcw [rsp]
+    add   rsp, 8
+    ret
+
+
+global sym(vpx_winx64_fstcw)
+sym(vpx_winx64_fstcw):
+    sub   rsp, 8
+    fstcw [rsp]
+    mov   rax, [rsp]
+    add   rsp, 8
+    ret
+%endif
diff --git a/vpx_ports/mem.h b/vpx_ports/mem.h
new file mode 100644 (file)
index 0000000..10942f1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VPX_PORTS_MEM_H
+#define VPX_PORTS_MEM_H
+#include "vpx_config.h"
+#include "vpx_integer.h"
+
+#if defined(__GNUC__) && __GNUC__
+#define DECLARE_ALIGNED(n,typ,val)  typ val __attribute__ ((aligned (n)))
+#elif defined(_MSC_VER)
+#define DECLARE_ALIGNED(n,typ,val)  __declspec(align(n)) typ val
+#else
+#warning No alignment directives known for this compiler.
+#define DECLARE_ALIGNED(n,typ,val)  typ val
+#endif
+#endif
+
+
+/* Declare an aligned array on the stack, for situations where the stack
+ * pointer may not have the alignment we expect. Creates an array with a
+ * modified name, then defines val to be a pointer, and aligns that pointer
+ * within the array.
+ */
+#define DECLARE_ALIGNED_ARRAY(a,typ,val,n)\
+typ val##_[(n)+(a)/sizeof(typ)+1];\
+typ *val = (typ*)((((intptr_t)val##_)+(a)-1)&((intptr_t)-(a)))
+
+
+/* Indicates that the usage of the specified variable has been audited to assure
+ * that it's safe to use uninitialized. Silences 'may be used uninitialized'
+ * warnings on gcc.
+ */
+#if defined(__GNUC__) && __GNUC__
+#define UNINITIALIZED_IS_SAFE(x) x=x
+#else
+#define UNINITIALIZED_IS_SAFE(x) x
+#endif
diff --git a/vpx_ports/mem_ops.h b/vpx_ports/mem_ops.h
new file mode 100644 (file)
index 0000000..869d583
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* \file mem_ops.h
+ * \brief Provides portable memory access primatives
+ *
+ * This function provides portable primatives for getting and setting of
+ * signed and unsigned integers in 16, 24, and 32 bit sizes. The operations
+ * can be performed on unaligned data regardless of hardware support for
+ * unaligned accesses.
+ *
+ * The type used to pass the integral values may be changed by defining
+ * MEM_VALUE_T with the appropriate type. The type given must be an integral
+ * numeric type.
+ *
+ * The actual functions instantiated have the MEM_VALUE_T type name pasted
+ * on to the symbol name. This allows the developer to instantiate these
+ * operations for multiple types within the same translation unit. This is
+ * of somewhat questionable utility, but the capability exists nonetheless.
+ * Users not making use of this functionality should call the functions
+ * without the type name appended, and the preprocessor will take care of
+ * it.
+ *
+ * NOTE: This code is not supported on platforms where char > 1 octet ATM.
+ */
+
+#ifndef MAU_T
+/* Minimum Access Unit for this target */
+#define MAU_T unsigned char
+#endif
+
+#ifndef MEM_VALUE_T
+#define MEM_VALUE_T int
+#endif
+
+#undef MEM_VALUE_T_SZ_BITS
+#define MEM_VALUE_T_SZ_BITS (sizeof(MEM_VALUE_T) << 3)
+
+#undef  mem_ops_wrap_symbol
+#define mem_ops_wrap_symbol(fn) mem_ops_wrap_symbol2(fn, MEM_VALUE_T)
+#undef  mem_ops_wrap_symbol2
+#define mem_ops_wrap_symbol2(fn,typ) mem_ops_wrap_symbol3(fn,typ)
+#undef  mem_ops_wrap_symbol3
+#define mem_ops_wrap_symbol3(fn,typ) fn##_as_##typ
+
+/*
+ * Include aligned access routines
+ */
+#define INCLUDED_BY_MEM_OPS_H
+#include "mem_ops_aligned.h"
+#undef  INCLUDED_BY_MEM_OPS_H
+
+#undef  mem_get_be16
+#define mem_get_be16 mem_ops_wrap_symbol(mem_get_be16)
+static INLINE unsigned MEM_VALUE_T mem_get_be16(const void *vmem)
+{
+    unsigned MEM_VALUE_T  val;
+    const MAU_T          *mem = (const MAU_T *)vmem;
+
+    val = mem[0] << 8;
+    val |= mem[1];
+    return val;
+}
+
+#undef  mem_get_be24
+#define mem_get_be24 mem_ops_wrap_symbol(mem_get_be24)
+static INLINE unsigned MEM_VALUE_T mem_get_be24(const void *vmem)
+{
+    unsigned MEM_VALUE_T  val;
+    const MAU_T          *mem = (const MAU_T *)vmem;
+
+    val = mem[0] << 16;
+    val |= mem[1] << 8;
+    val |= mem[2];
+    return val;
+}
+
+#undef  mem_get_be32
+#define mem_get_be32 mem_ops_wrap_symbol(mem_get_be32)
+static INLINE unsigned MEM_VALUE_T mem_get_be32(const void *vmem)
+{
+    unsigned MEM_VALUE_T  val;
+    const MAU_T          *mem = (const MAU_T *)vmem;
+
+    val = mem[0] << 24;
+    val |= mem[1] << 16;
+    val |= mem[2] << 8;
+    val |= mem[3];
+    return val;
+}
+
+#undef  mem_get_le16
+#define mem_get_le16 mem_ops_wrap_symbol(mem_get_le16)
+static INLINE unsigned MEM_VALUE_T mem_get_le16(const void *vmem)
+{
+    unsigned MEM_VALUE_T  val;
+    const MAU_T          *mem = (const MAU_T *)vmem;
+
+    val = mem[1] << 8;
+    val |= mem[0];
+    return val;
+}
+
+#undef  mem_get_le24
+#define mem_get_le24 mem_ops_wrap_symbol(mem_get_le24)
+static INLINE unsigned MEM_VALUE_T mem_get_le24(const void *vmem)
+{
+    unsigned MEM_VALUE_T  val;
+    const MAU_T          *mem = (const MAU_T *)vmem;
+
+    val = mem[2] << 16;
+    val |= mem[1] << 8;
+    val |= mem[0];
+    return val;
+}
+
+#undef  mem_get_le32
+#define mem_get_le32 mem_ops_wrap_symbol(mem_get_le32)
+static INLINE unsigned MEM_VALUE_T mem_get_le32(const void *vmem)
+{
+    unsigned MEM_VALUE_T  val;
+    const MAU_T          *mem = (const MAU_T *)vmem;
+
+    val = mem[3] << 24;
+    val |= mem[2] << 16;
+    val |= mem[1] << 8;
+    val |= mem[0];
+    return val;
+}
+
+#define mem_get_s_generic(end,sz) \
+    static INLINE signed MEM_VALUE_T mem_get_s##end##sz(const void *vmem) {\
+        const MAU_T *mem = (const MAU_T*)vmem;\
+        signed MEM_VALUE_T val = mem_get_##end##sz(mem);\
+        return (val << (MEM_VALUE_T_SZ_BITS - sz)) >> (MEM_VALUE_T_SZ_BITS - sz);\
+    }
+
+#undef  mem_get_sbe16
+#define mem_get_sbe16 mem_ops_wrap_symbol(mem_get_sbe16)
+mem_get_s_generic(be, 16);
+
+#undef  mem_get_sbe24
+#define mem_get_sbe24 mem_ops_wrap_symbol(mem_get_sbe24)
+mem_get_s_generic(be, 24);
+
+#undef  mem_get_sbe32
+#define mem_get_sbe32 mem_ops_wrap_symbol(mem_get_sbe32)
+mem_get_s_generic(be, 32);
+
+#undef  mem_get_sle16
+#define mem_get_sle16 mem_ops_wrap_symbol(mem_get_sle16)
+mem_get_s_generic(le, 16);
+
+#undef  mem_get_sle24
+#define mem_get_sle24 mem_ops_wrap_symbol(mem_get_sle24)
+mem_get_s_generic(le, 24);
+
+#undef  mem_get_sle32
+#define mem_get_sle32 mem_ops_wrap_symbol(mem_get_sle32)
+mem_get_s_generic(le, 32);
+
+#undef  mem_put_be16
+#define mem_put_be16 mem_ops_wrap_symbol(mem_put_be16)
+static INLINE void mem_put_be16(void *vmem, MEM_VALUE_T val)
+{
+    MAU_T *mem = (MAU_T *)vmem;
+
+    mem[0] = (val >> 8) & 0xff;
+    mem[1] = (val >> 0) & 0xff;
+}
+
+#undef  mem_put_be24
+#define mem_put_be24 mem_ops_wrap_symbol(mem_put_be24)
+static INLINE void mem_put_be24(void *vmem, MEM_VALUE_T val)
+{
+    MAU_T *mem = (MAU_T *)vmem;
+
+    mem[0] = (val >> 16) & 0xff;
+    mem[1] = (val >>  8) & 0xff;
+    mem[2] = (val >>  0) & 0xff;
+}
+
+#undef  mem_put_be32
+#define mem_put_be32 mem_ops_wrap_symbol(mem_put_be32)
+static INLINE void mem_put_be32(void *vmem, MEM_VALUE_T val)
+{
+    MAU_T *mem = (MAU_T *)vmem;
+
+    mem[0] = (val >> 24) & 0xff;
+    mem[1] = (val >> 16) & 0xff;
+    mem[2] = (val >>  8) & 0xff;
+    mem[3] = (val >>  0) & 0xff;
+}
+
+#undef  mem_put_le16
+#define mem_put_le16 mem_ops_wrap_symbol(mem_put_le16)
+static INLINE void mem_put_le16(void *vmem, MEM_VALUE_T val)
+{
+    MAU_T *mem = (MAU_T *)vmem;
+
+    mem[0] = (val >>  0) & 0xff;
+    mem[1] = (val >>  8) & 0xff;
+}
+
+#undef  mem_put_le24
+#define mem_put_le24 mem_ops_wrap_symbol(mem_put_le24)
+static INLINE void mem_put_le24(void *vmem, MEM_VALUE_T val)
+{
+    MAU_T *mem = (MAU_T *)vmem;
+
+    mem[0] = (val >>  0) & 0xff;
+    mem[1] = (val >>  8) & 0xff;
+    mem[2] = (val >> 16) & 0xff;
+}
+
+#undef  mem_put_le32
+#define mem_put_le32 mem_ops_wrap_symbol(mem_put_le32)
+static INLINE void mem_put_le32(void *vmem, MEM_VALUE_T val)
+{
+    MAU_T *mem = (MAU_T *)vmem;
+
+    mem[0] = (val >>  0) & 0xff;
+    mem[1] = (val >>  8) & 0xff;
+    mem[2] = (val >> 16) & 0xff;
+    mem[3] = (val >> 24) & 0xff;
+}
diff --git a/vpx_ports/mem_ops_aligned.h b/vpx_ports/mem_ops_aligned.h
new file mode 100644 (file)
index 0000000..1d0db2c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* \file mem_ops_aligned.h
+ * \brief Provides portable memory access primatives for operating on aligned
+ *        data
+ *
+ * This file is split from mem_ops.h for easier maintainence. See mem_ops.h
+ * for a more detailed description of these primatives.
+ */
+#ifndef INCLUDED_BY_MEM_OPS_H
+#error Include mem_ops.h, not mem_ops_aligned.h directly.
+#endif
+
+/* Architectures that provide instructions for doing this byte swapping
+ * could redefine these macros.
+ */
+#define swap_endian_16(val,raw) do {\
+        val = ((raw>>8) & 0x00ff) \
+              | ((raw<<8) & 0xff00);\
+    } while(0)
+#define swap_endian_32(val,raw) do {\
+        val = ((raw>>24) & 0x000000ff) \
+              | ((raw>>8)  & 0x0000ff00) \
+              | ((raw<<8)  & 0x00ff0000) \
+              | ((raw<<24) & 0xff000000); \
+    } while(0)
+#define swap_endian_16_se(val,raw) do {\
+        swap_endian_16(val,raw);\
+        val = ((val << 16) >> 16);\
+    } while(0)
+#define swap_endian_32_se(val,raw) swap_endian_32(val,raw)
+
+#define mem_get_ne_aligned_generic(end,sz) \
+    static INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned(const void *vmem) {\
+        const uint##sz##_t *mem = (const uint##sz##_t *)vmem;\
+        return *mem;\
+    }
+
+#define mem_get_sne_aligned_generic(end,sz) \
+    static INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned(const void *vmem) {\
+        const int##sz##_t *mem = (const int##sz##_t *)vmem;\
+        return *mem;\
+    }
+
+#define mem_get_se_aligned_generic(end,sz) \
+    static INLINE unsigned MEM_VALUE_T mem_get_##end##sz##_aligned(const void *vmem) {\
+        const uint##sz##_t *mem = (const uint##sz##_t *)vmem;\
+        unsigned MEM_VALUE_T val, raw = *mem;\
+        swap_endian_##sz(val,raw);\
+        return val;\
+    }
+
+#define mem_get_sse_aligned_generic(end,sz) \
+    static INLINE signed MEM_VALUE_T mem_get_s##end##sz##_aligned(const void *vmem) {\
+        const int##sz##_t *mem = (const int##sz##_t *)vmem;\
+        unsigned MEM_VALUE_T val, raw = *mem;\
+        swap_endian_##sz##_se(val,raw);\
+        return val;\
+    }
+
+#define mem_put_ne_aligned_generic(end,sz) \
+    static INLINE void mem_put_##end##sz##_aligned(void *vmem, MEM_VALUE_T val) {\
+        uint##sz##_t *mem = (uint##sz##_t *)vmem;\
+        *mem = (uint##sz##_t)val;\
+    }
+
+#define mem_put_se_aligned_generic(end,sz) \
+    static INLINE void mem_put_##end##sz##_aligned(void *vmem, MEM_VALUE_T val) {\
+        uint##sz##_t *mem = (uint##sz##_t *)vmem, raw;\
+        swap_endian_##sz(raw,val);\
+        *mem = (uint##sz##_t)raw;\
+    }
+
+#include "config.h"
+#if CONFIG_BIG_ENDIAN
+#define mem_get_be_aligned_generic(sz)  mem_get_ne_aligned_generic(be,sz)
+#define mem_get_sbe_aligned_generic(sz) mem_get_sne_aligned_generic(be,sz)
+#define mem_get_le_aligned_generic(sz)  mem_get_se_aligned_generic(le,sz)
+#define mem_get_sle_aligned_generic(sz) mem_get_sse_aligned_generic(le,sz)
+#define mem_put_be_aligned_generic(sz)  mem_put_ne_aligned_generic(be,sz)
+#define mem_put_le_aligned_generic(sz)  mem_put_se_aligned_generic(le,sz)
+#else
+#define mem_get_be_aligned_generic(sz)  mem_get_se_aligned_generic(be,sz)
+#define mem_get_sbe_aligned_generic(sz) mem_get_sse_aligned_generic(be,sz)
+#define mem_get_le_aligned_generic(sz)  mem_get_ne_aligned_generic(le,sz)
+#define mem_get_sle_aligned_generic(sz) mem_get_sne_aligned_generic(le,sz)
+#define mem_put_be_aligned_generic(sz)  mem_put_se_aligned_generic(be,sz)
+#define mem_put_le_aligned_generic(sz)  mem_put_ne_aligned_generic(le,sz)
+#endif
+
+#undef  mem_get_be16_aligned
+#define mem_get_be16_aligned mem_ops_wrap_symbol(mem_get_be16_aligned)
+mem_get_be_aligned_generic(16);
+
+#undef  mem_get_be32_aligned
+#define mem_get_be32_aligned mem_ops_wrap_symbol(mem_get_be32_aligned)
+mem_get_be_aligned_generic(32);
+
+#undef  mem_get_le16_aligned
+#define mem_get_le16_aligned mem_ops_wrap_symbol(mem_get_le16_aligned)
+mem_get_le_aligned_generic(16);
+
+#undef  mem_get_le32_aligned
+#define mem_get_le32_aligned mem_ops_wrap_symbol(mem_get_le32_aligned)
+mem_get_le_aligned_generic(32);
+
+#undef  mem_get_sbe16_aligned
+#define mem_get_sbe16_aligned mem_ops_wrap_symbol(mem_get_sbe16_aligned)
+mem_get_sbe_aligned_generic(16);
+
+#undef  mem_get_sbe32_aligned
+#define mem_get_sbe32_aligned mem_ops_wrap_symbol(mem_get_sbe32_aligned)
+mem_get_sbe_aligned_generic(32);
+
+#undef  mem_get_sle16_aligned
+#define mem_get_sle16_aligned mem_ops_wrap_symbol(mem_get_sle16_aligned)
+mem_get_sle_aligned_generic(16);
+
+#undef  mem_get_sle32_aligned
+#define mem_get_sle32_aligned mem_ops_wrap_symbol(mem_get_sle32_aligned)
+mem_get_sle_aligned_generic(32);
+
+#undef  mem_put_be16_aligned
+#define mem_put_be16_aligned mem_ops_wrap_symbol(mem_put_be16_aligned)
+mem_put_be_aligned_generic(16);
+
+#undef  mem_put_be32_aligned
+#define mem_put_be32_aligned mem_ops_wrap_symbol(mem_put_be32_aligned)
+mem_put_be_aligned_generic(32);
+
+#undef  mem_put_le16_aligned
+#define mem_put_le16_aligned mem_ops_wrap_symbol(mem_put_le16_aligned)
+mem_put_le_aligned_generic(16);
+
+#undef  mem_put_le32_aligned
+#define mem_put_le32_aligned mem_ops_wrap_symbol(mem_put_le32_aligned)
+mem_put_le_aligned_generic(32);
+
+#undef mem_get_ne_aligned_generic
+#undef mem_get_se_aligned_generic
+#undef mem_get_sne_aligned_generic
+#undef mem_get_sse_aligned_generic
+#undef mem_put_ne_aligned_generic
+#undef mem_put_se_aligned_generic
+#undef swap_endian_16
+#undef swap_endian_32
+#undef swap_endian_16_se
+#undef swap_endian_32_se
diff --git a/vpx_ports/vpx_integer.h b/vpx_ports/vpx_integer.h
new file mode 100644 (file)
index 0000000..d3f7ddd
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VPX_INTEGER_H
+#define VPX_INTEGER_H
+
+/* get ptrdiff_t, size_t, wchar_t, NULL */
+#include <stddef.h>
+
+#if defined(HAVE_STDINT_H) && HAVE_STDINT_H
+#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS)
+#define __STDC_FORMAT_MACROS
+#endif
+#include <stdint.h>
+#include <inttypes.h>
+#else
+typedef signed char  int8_t;
+typedef signed short int16_t;
+typedef signed int   int32_t;
+
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int   uint32_t;
+
+#if defined(_MSC_VER)
+typedef signed __int64   int64_t;
+typedef unsigned __int64 uint64_t;
+#define PRId64 "I64d"
+#endif
+
+#ifdef HAVE_ARMV6
+typedef unsigned int int_fast16_t;
+#else
+typedef signed short int_fast16_t;
+#endif
+typedef signed char int_fast8_t;
+typedef unsigned char uint_fast8_t;
+
+#ifndef _UINTPTR_T_DEFINED
+typedef unsigned int   uintptr_t;
+#endif
+
+#endif
+
+#endif
diff --git a/vpx_ports/vpx_timer.h b/vpx_ports/vpx_timer.h
new file mode 100644 (file)
index 0000000..5c04538
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VPX_TIMER_H
+#define VPX_TIMER_H
+
+#if defined(_MSC_VER)
+/*
+ * Win32 specific includes
+ */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#else
+/*
+ * POSIX specific includes
+ */
+#include <sys/time.h>
+
+/* timersub is not provided by msys at this time. */
+#ifndef timersub
+#define timersub(a, b, result) \
+    do { \
+        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+        if ((result)->tv_usec < 0) { \
+            --(result)->tv_sec; \
+            (result)->tv_usec += 1000000; \
+        } \
+    } while (0)
+#endif
+#endif
+
+
+struct vpx_usec_timer
+{
+#if defined(_MSC_VER)
+    LARGE_INTEGER  begin, end;
+#else
+    struct timeval begin, end;
+#endif
+};
+
+
+static INLINE void
+vpx_usec_timer_start(struct vpx_usec_timer *t)
+{
+#if defined(_MSC_VER)
+    QueryPerformanceCounter(&t->begin);
+#else
+    gettimeofday(&t->begin, NULL);
+#endif
+}
+
+
+static INLINE void
+vpx_usec_timer_mark(struct vpx_usec_timer *t)
+{
+#if defined(_MSC_VER)
+    QueryPerformanceCounter(&t->end);
+#else
+    gettimeofday(&t->end, NULL);
+#endif
+}
+
+
+static INLINE long
+vpx_usec_timer_elapsed(struct vpx_usec_timer *t)
+{
+#if defined(_MSC_VER)
+    LARGE_INTEGER freq, diff;
+
+    diff.QuadPart = t->end.QuadPart - t->begin.QuadPart;
+
+    if (QueryPerformanceFrequency(&freq) && diff.QuadPart < freq.QuadPart)
+        return (long)(diff.QuadPart * 1000000 / freq.QuadPart);
+
+    return 1000000;
+#else
+    struct timeval diff;
+
+    timersub(&t->end, &t->begin, &diff);
+    return diff.tv_sec ? 1000000 : diff.tv_usec;
+#endif
+}
+
+
+#endif
diff --git a/vpx_ports/vpxtypes.h b/vpx_ports/vpxtypes.h
new file mode 100644 (file)
index 0000000..86525b7
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __VPXTYPES_H__
+#define __VPXTYPES_H__
+
+#ifdef   HAVE_CONFIG_H
+#include HAVE_CONFIG_H
+#endif
+
+//#include <sys/types.h>
+#ifdef _MSC_VER
+# include <basetsd.h>
+typedef SSIZE_T ssize_t;
+#endif
+
+#if defined(HAVE_STDINT_H) && HAVE_STDINT_H
+/* C99 types are preferred to vpx integer types */
+# include <stdint.h>
+#endif
+
+/*!\defgroup basetypes Base Types
+  @{*/
+#if !defined(HAVE_STDINT_H) && !defined(INT_T_DEFINED)
+# ifdef STRICTTYPES
+typedef signed char  int8_t;
+typedef signed short int16_t;
+typedef signed int   int32_t;
+# else
+typedef char         int8_t;
+typedef short        int16_t;
+typedef int          int32_t;
+# endif
+typedef unsigned char  uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int   uint32_t;
+#endif
+
+typedef int8_t     vpxs8;
+typedef uint8_t    vpxu8;
+typedef int16_t    vpxs16;
+typedef uint16_t   vpxu16;
+typedef int32_t    vpxs32;
+typedef uint32_t   vpxu32;
+typedef int32_t    vpxbool;
+
+enum {vpxfalse, vpxtrue};
+
+/*!\def OTC
+   \brief a macro suitable for declaring a constant #vpxtc*/
+/*!\def VPXTC
+   \brief printf format string suitable for printing an #vpxtc*/
+#ifdef UNICODE
+# ifdef NO_WCHAR
+#  error "no non-wchar support added yet"
+# else
+#  include <wchar.h>
+typedef wchar_t vpxtc;
+#  define OTC(str) L ## str
+#  define VPXTC "ls"
+# endif /*NO_WCHAR*/
+#else
+typedef char vpxtc;
+# define OTC(str) (vpxtc*)str
+# define VPXTC "s"
+#endif /*UNICODE*/
+/*@} end - base types*/
+
+/*!\addtogroup basetypes
+  @{*/
+/*!\def VPX64
+   \brief printf format string suitable for printing an #vpxs64*/
+#if defined(HAVE_STDINT_H)
+# define VPX64 PRId64
+typedef int64_t vpxs64;
+#elif defined(HASLONGLONG)
+# undef  PRId64
+# define PRId64 "lld"
+# define VPX64 PRId64
+typedef long long vpxs64;
+#elif defined(WIN32) || defined(_WIN32_WCE)
+# undef  PRId64
+# define PRId64 "I64d"
+# define VPX64 PRId64
+typedef __int64 vpxs64;
+typedef unsigned __int64 vpxu64;
+#elif defined(__uClinux__) && defined(CHIP_DM642)
+# include <lddk.h>
+# undef  PRId64
+# define PRId64 "lld"
+# define VPX64 PRId64
+typedef long vpxs64;
+#elif defined(__SYMBIAN32__)
+# undef  PRId64
+# define PRId64 "u"
+# define VPX64 PRId64
+typedef unsigned int vpxs64;
+#else
+# error "64 bit integer type undefined for this platform!"
+#endif
+#if !defined(HAVE_STDINT_H) && !defined(INT_T_DEFINED)
+typedef vpxs64 int64_t;
+typedef vpxu64 uint64_t;
+#endif
+/*!@} end - base types*/
+
+/*!\ingroup basetypes
+   \brief Common return type*/
+typedef enum
+{
+    VPX_NOT_FOUND        = -404,
+    VPX_BUFFER_EMPTY     = -202,
+    VPX_BUFFER_FULL      = -201,
+
+    VPX_CONNREFUSED      = -102,
+    VPX_TIMEDOUT         = -101,
+    VPX_WOULDBLOCK       = -100,
+
+    VPX_NET_ERROR        = -9,
+    VPX_INVALID_VERSION  = -8,
+    VPX_INPROGRESS       = -7,
+    VPX_NOT_SUPP         = -6,
+    VPX_NO_MEM           = -3,
+    VPX_INVALID_PARAMS   = -2,
+    VPX_ERROR            = -1,
+    VPX_OK               = 0,
+    VPX_DONE             = 1
+} vpxsc;
+
+#if defined(WIN32) || defined(_WIN32_WCE)
+# define DLLIMPORT __declspec(dllimport)
+# define DLLEXPORT __declspec(dllexport)
+# define DLLLOCAL
+#elif defined(LINUX)
+# define DLLIMPORT
+/*visibility attribute support is available in 3.4 and later.
+  see: http://gcc.gnu.org/wiki/Visibility for more info*/
+# if defined(__GNUC__) && ((__GNUC__<<16|(__GNUC_MINOR__&0xff)) >= (3<<16|4))
+#  define GCC_HASCLASSVISIBILITY
+# endif /*defined(__GNUC__) && __GNUC_PREREQ(3,4)*/
+# ifdef GCC_HASCLASSVISIBILITY
+#  define DLLEXPORT   __attribute__ ((visibility("default")))
+#  define DLLLOCAL __attribute__ ((visibility("hidden")))
+# else
+#  define DLLEXPORT
+#  define DLLLOCAL
+# endif /*GCC_HASCLASSVISIBILITY*/
+#endif /*platform ifdefs*/
+
+#endif /*__VPXTYPES_H__*/
+
+#undef VPXAPI
+/*!\def VPXAPI
+   \brief library calling convention/storage class attributes.
+
+   Specifies whether the function is imported through a dll
+   or is from a static library.*/
+#ifdef VPXDLL
+# ifdef VPXDLLEXPORT
+#  define VPXAPI DLLEXPORT
+# else
+#  define VPXAPI DLLIMPORT
+# endif /*VPXDLLEXPORT*/
+#else
+# define VPXAPI
+#endif /*VPXDLL*/
diff --git a/vpx_ports/x86.h b/vpx_ports/x86.h
new file mode 100644 (file)
index 0000000..935d037
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VPX_PORTS_X86_H
+#define VPX_PORTS_X86_H
+#include <stdlib.h>
+#include "config.h"
+
+#if defined(__GNUC__) && __GNUC__
+#if ARCH_X86_64
+#define cpuid(func,ax,bx,cx,dx)\
+    __asm__ __volatile__ (\
+                          "cpuid           \n\t" \
+                          : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
+                          : "a"  (func));
+#else
+#define cpuid(func,ax,bx,cx,dx)\
+    __asm__ __volatile__ (\
+                          "pushl %%ebx     \n\t" \
+                          "cpuid           \n\t" \
+                          "movl  %%ebx, %1 \n\t" \
+                          "popl  %%ebx     \n\t" \
+                          : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) \
+                          : "a"  (func));
+#endif
+#else
+#if ARCH_X86_64
+void __cpuid(int CPUInfo[4], int info_type);
+#pragma intrinsic(__cpuid)
+#define cpuid(func,a,b,c,d) do{\
+        int regs[4];\
+        __cpuid(regs,func); a=regs[0];  b=regs[1];  c=regs[2];  d=regs[3];\
+    } while(0)
+#else
+#define cpuid(func,a,b,c,d)\
+    __asm mov eax, func\
+    __asm cpuid\
+    __asm mov a, eax\
+    __asm mov b, ebx\
+    __asm mov c, ecx\
+    __asm mov d, edx
+#endif
+#endif
+
+#define HAS_MMX   0x01
+#define HAS_SSE   0x02
+#define HAS_SSE2  0x04
+#define HAS_SSE3  0x08
+#define HAS_SSSE3 0x10
+#ifndef BIT
+#define BIT(n) (1<<n)
+#endif
+
+static int
+x86_simd_caps(void)
+{
+    unsigned int flags = 0;
+    unsigned int mask = ~0;
+    unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
+    char *env;
+    (void)reg_ebx;
+
+    /* See if the CPU capabilities are being overridden by the environment */
+    env = getenv("VPX_SIMD_CAPS");
+
+    if (env && *env)
+        return (int)strtol(env, NULL, 0);
+
+    env = getenv("VPX_SIMD_CAPS_MASK");
+
+    if (env && *env)
+        mask = strtol(env, NULL, 0);
+
+    /* Ensure that the CPUID instruction supports extended features */
+    cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx);
+
+    if (reg_eax < 1)
+        return 0;
+
+    /* Get the standard feature flags */
+    cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx);
+
+    if (reg_edx & BIT(23)) flags |= HAS_MMX;
+
+    if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */
+
+    if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */
+
+    if (reg_ecx & BIT(0))  flags |= HAS_SSE3;
+
+    if (reg_ecx & BIT(9))  flags |= HAS_SSSE3;
+
+    return flags & mask;
+}
+
+
+#if ARCH_X86_64 && defined(_MSC_VER)
+unsigned __int64 __rdtsc(void);
+#pragma intrinsic(__rdtsc)
+#endif
+static unsigned int
+x86_readtsc(void)
+{
+#if defined(__GNUC__) && __GNUC__
+    unsigned int tsc;
+    __asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
+    return tsc;
+#else
+#if ARCH_X86_64
+    return __rdtsc();
+#else
+    __asm  rdtsc;
+#endif
+#endif
+}
+
+
+#if defined(__GNUC__) && __GNUC__
+#define x86_pause_hint()\
+    __asm__ __volatile__ ("pause \n\t")
+#else
+#if ARCH_X86_64
+/* No pause intrinsic for windows x64 */
+#define x86_pause_hint()
+#else
+#define x86_pause_hint()\
+    __asm pause
+#endif
+#endif
+
+#if defined(__GNUC__) && __GNUC__
+static void
+x87_set_control_word(unsigned short mode)
+{
+    __asm__ __volatile__("fldcw %0" : : "m"(*&mode));
+}
+static unsigned short
+x87_get_control_word(void)
+{
+    unsigned short mode;
+    __asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):);
+    return mode;
+}
+#elif ARCH_X86_64
+/* No fldcw intrinsics on Windows x64, punt to external asm */
+extern void           vpx_winx64_fldcw(unsigned short mode);
+extern unsigned short vpx_winx64_fstcw(void);
+#define x87_set_control_word vpx_winx64_fldcw
+#define x87_get_control_word vpx_winx64_fstcw
+#else
+static void
+x87_set_control_word(unsigned short mode)
+{
+    __asm { fldcw mode }
+}
+static unsigned short
+x87_get_control_word(void)
+{
+    unsigned short mode;
+    __asm { fstcw mode }
+    return mode;
+}
+#endif
+
+static unsigned short
+x87_set_double_precision(void)
+{
+    unsigned short mode = x87_get_control_word();
+    x87_set_control_word((mode&~0x300) | 0x200);
+    return mode;
+}
+
+
+extern void vpx_reset_mmx_state(void);
+#endif
+
diff --git a/vpx_ports/x86_abi_support.asm b/vpx_ports/x86_abi_support.asm
new file mode 100644 (file)
index 0000000..db8208f
--- /dev/null
@@ -0,0 +1,231 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+%include "vpx_config.asm"
+
+; 32/64 bit compatibility macros
+;
+; In general, we make the source use 64 bit syntax, then twiddle with it using
+; the preprocessor to get the 32 bit syntax on 32 bit platforms.
+;
+%ifidn __OUTPUT_FORMAT__,elf32
+%define ABI_IS_32BIT 1
+%elifidn __OUTPUT_FORMAT__,macho32
+%define ABI_IS_32BIT 1
+%elifidn __OUTPUT_FORMAT__,win32
+%define ABI_IS_32BIT 1
+%else
+%define ABI_IS_32BIT 0
+%endif
+
+%if ABI_IS_32BIT
+%define rax eax
+%define rbx ebx
+%define rcx ecx
+%define rdx edx
+%define rsi esi
+%define rdi edi
+%define rsp esp
+%define rbp ebp
+%define movsxd mov
+%endif
+
+
+; sym()
+; Return the proper symbol name for the target ABI.
+;
+; Certain ABIs, notably MS COFF and Darwin MACH-O, require that symbols
+; with C linkage be prefixed with an underscore.
+;
+%ifidn   __OUTPUT_FORMAT__,elf32
+%define sym(x) x
+%elifidn __OUTPUT_FORMAT__,elf64
+%define sym(x) x
+%elifidn __OUTPUT_FORMAT__,x64
+%define sym(x) x
+%else
+%define sym(x) _ %+ x
+%endif
+
+; arg()
+; Return the address specification of the given argument
+;
+%if ABI_IS_32BIT
+  %define arg(x) [ebp+8+4*x]
+%else
+  ; 64 bit ABI passes arguments in registers. This is a workaround to get up
+  ; and running quickly. Relies on SHADOW_ARGS_TO_STACK
+  %ifidn __OUTPUT_FORMAT__,x64
+    %define arg(x) [rbp+16+8*x]
+  %else
+    %define arg(x) [rbp-8-8*x]
+  %endif
+%endif
+
+; REG_SZ_BYTES, REG_SZ_BITS
+; Size of a register
+%if ABI_IS_32BIT
+%define REG_SZ_BYTES 4
+%define REG_SZ_BITS  32
+%else
+%define REG_SZ_BYTES 8
+%define REG_SZ_BITS  64
+%endif
+
+
+; ALIGN_STACK <alignment> <register>
+; This macro aligns the stack to the given alignment (in bytes). The stack
+; is left such that the previous value of the stack pointer is the first
+; argument on the stack (ie, the inverse of this macro is 'pop rsp.')
+; This macro uses one temporary register, which is not preserved, and thus
+; must be specified as an argument.
+%macro ALIGN_STACK 2
+    mov         %2, rsp
+    and         rsp, -%1
+    sub         rsp, %1 - REG_SZ_BYTES
+    push        %2
+%endmacro
+
+
+;
+; The Microsoft assembler tries to impose a certain amount of type safety in
+; its register usage. YASM doesn't recognize these directives, so we just
+; %define them away to maintain as much compatibility as possible with the
+; original inline assembler we're porting from.
+;
+%idefine PTR
+%idefine XMMWORD
+%idefine MMWORD
+
+
+; PIC macros
+;
+%if ABI_IS_32BIT
+  %if CONFIG_PIC=1
+  %ifidn __OUTPUT_FORMAT__,elf32
+    %define WRT_PLT wrt ..plt
+    %macro GET_GOT 1
+      extern _GLOBAL_OFFSET_TABLE_
+      push %1
+      call %%get_got
+      %%get_got:
+      pop %1
+      add %1, _GLOBAL_OFFSET_TABLE_ + $$ - %%get_got wrt ..gotpc
+      %undef GLOBAL
+      %define GLOBAL + %1 wrt ..gotoff
+      %undef RESTORE_GOT
+      %define RESTORE_GOT pop %1
+    %endmacro
+  %elifidn __OUTPUT_FORMAT__,macho32
+    %macro GET_GOT 1
+      push %1
+      call %%get_got
+      %%get_got:
+      pop %1
+      add %1, fake_got - %%get_got
+      %undef GLOBAL
+      %define GLOBAL + %1 - fake_got
+      %undef RESTORE_GOT
+      %define RESTORE_GOT pop %1
+    %endmacro
+  %endif
+  %endif
+%else
+  %macro GET_GOT 1
+  %endmacro
+  %define GLOBAL wrt rip
+  %ifidn __OUTPUT_FORMAT__,elf64
+    %define WRT_PLT wrt ..plt
+  %endif
+%endif
+%ifnmacro GET_GOT
+    %macro GET_GOT 1
+    %endmacro
+    %define GLOBAL
+%endif
+%ifndef RESTORE_GOT
+%define RESTORE_GOT
+%endif
+%ifndef WRT_PLT
+%define WRT_PLT
+%endif
+
+%if ABI_IS_32BIT
+  %macro SHADOW_ARGS_TO_STACK 1
+  %endm
+  %define UNSHADOW_ARGS
+%else
+%ifidn __OUTPUT_FORMAT__,x64
+  %macro SHADOW_ARGS_TO_STACK 1 ; argc
+    %if %1 > 0
+        mov arg(0),rcx
+    %endif
+    %if %1 > 1
+        mov arg(1),rdx
+    %endif
+    %if %1 > 2
+        mov arg(2),r8
+    %endif
+    %if %1 > 3
+        mov arg(3),r9
+    %endif
+  %endm
+%else
+  %macro SHADOW_ARGS_TO_STACK 1 ; argc
+    %if %1 > 0
+        push rdi
+    %endif
+    %if %1 > 1
+        push rsi
+    %endif
+    %if %1 > 2
+        push rdx
+    %endif
+    %if %1 > 3
+        push rcx
+    %endif
+    %if %1 > 4
+        push r8
+    %endif
+    %if %1 > 5
+        push r9
+    %endif
+    %if %1 > 6
+        mov rax,[rbp+16]
+        push rax
+    %endif
+    %if %1 > 7
+        mov rax,[rbp+24]
+        push rax
+    %endif
+    %if %1 > 8
+        mov rax,[rbp+32]
+        push rax
+    %endif
+  %endm
+%endif
+  %define UNSHADOW_ARGS mov rsp, rbp
+%endif
+
+
+; Name of the rodata section
+;
+; .rodata seems to be an elf-ism, as it doesn't work on OSX.
+;
+%ifidn __OUTPUT_FORMAT__,macho64
+%define SECTION_RODATA section .text
+%elifidn __OUTPUT_FORMAT__,macho32
+%macro SECTION_RODATA 0
+section .text
+fake_got:
+%endmacro
+%else
+%define SECTION_RODATA section .rodata
+%endif
diff --git a/vpx_scale/arm/armv4/gen_scalers_armv4.asm b/vpx_scale/arm/armv4/gen_scalers_armv4.asm
new file mode 100644 (file)
index 0000000..1c904ed
--- /dev/null
@@ -0,0 +1,773 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |horizontal_line_4_5_scale_armv4|
+    EXPORT  |vertical_band_4_5_scale_armv4|
+    EXPORT  |horizontal_line_2_3_scale_armv4|
+    EXPORT  |vertical_band_2_3_scale_armv4|
+    EXPORT  |horizontal_line_3_5_scale_armv4|
+    EXPORT  |vertical_band_3_5_scale_armv4|
+    EXPORT  |horizontal_line_3_4_scale_armv4|
+    EXPORT  |vertical_band_3_4_scale_armv4|
+    EXPORT  |horizontal_line_1_2_scale_armv4|
+    EXPORT  |vertical_band_1_2_scale_armv4|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+src         RN  r0
+srcw        RN  r1
+dest        RN  r2
+mask        RN  r12
+c51_205     RN  r10
+c102_154    RN  r11
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_4_5_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 4 to 5.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; ****************************************************************************/
+;void horizontal_line_4_5_scale_armv4
+;(
+;   r0 = UINT8 *source
+;   r1 = UINT32 source_width
+;   r2 = UINT8 *dest
+;   r3 = UINT32 dest_width
+;)
+|horizontal_line_4_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    mov     mask, #255              ; mask for selection
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldr     r3, [src], #4
+
+hl45_loop
+
+    and     r4, r3, mask            ; a = src[0]
+    and     r5, mask, r3, lsr #8    ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    and     r7, mask, r3, lsr #16   ; c = src[2]
+    mul     r6, c51_205, r6         ; a * 51 + 205 * b
+
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5        ; b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsr #24   ; d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mul     r7, c102_154, r7        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    ldr     r3, [src], #4
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    and     r9, mask, r3            ; e = src[4]
+    orr     r9, r9, r8, lsl #16     ; d | e
+    mul     r9, c51_205, r9         ; d * 205 + 51 * e
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #4
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bne     hl45_loop
+
+    and     r4, r3, mask
+    and     r5, mask, r3, lsl #8
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    mul     r6, c51_205, r6
+
+    and     r7, mask, r3, lsl #16
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsl #24
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mul     r7, c102_154, r7
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    ldrb    r3, [src]
+    strb    r3, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_4_5_scale_c|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_4_5_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+; *                  height of the band scaled is 4-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_4_5_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_4_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl45_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    mul     r6, c51_205, r6         ; a * 51 + 205 * b
+
+    ldrb    r8, [r3], r1            ; d = des[dest_pitch*3]
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5        ; b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    ldrb    r9, [r3, r1]            ; e = des [dest_pitch * 5]
+    mul     r7, c102_154, r7        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    orr     r9, r9, r8, lsl #16     ; d | e
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    mul     r9, c51_205, r9         ; d * 205 + 51 * e
+    add     r7, r7, #0x8000
+    add     src, src, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+    add     r9, r9, #0x8000
+    subs    r2, r2, #1
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    bne     vl45_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_4_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_2_3_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 2 to 3.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void horizontal_line_2_3_scale_armv4
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_2_3_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+
+hl23_loop
+
+    ldrb    r3, [src], #1           ; a
+    ldrb    r4, [src], #1           ; b
+    ldrb    r5, [src]               ; c
+
+    strb    r3, [dest], #1
+    mul     r4, r12, r4             ; b * 171
+    mla     r6, lr, r3, r4          ; a * 85
+    mla     r7, lr, r5, r4          ; c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest], #1
+
+    add     r7, r7, #128
+    mov     r7, r7, lsr #8
+    strb    r7, [dest], #1
+
+    subs    srcw, srcw, #2
+    bne     hl23_loop
+
+    ldrb    r4, [src, #1]           ; b
+    strb    r5, [dest], #1
+    strb    r4, [dest, #1]
+
+    mul     r4, r12, r4             ; b * 171
+    mla     r6, lr, r5, r4          ; a * 85 + b *171
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest]
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|horizontal_line_2_3_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_2_3_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 2 to 3. The
+; *                  height of the band scaled is 2-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_2_3_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_2_3_scale_armv4| PROC
+    stmdb   sp!, {r4 - r8, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+    add     r3, r1, r1, lsl #1      ; 3 * dest_pitch
+
+vl23_loop
+    ldrb    r4, [src]               ; a = des [0]
+    ldrb    r5, [src, r1]           ; b = des [dest_pitch]
+    ldrb    r7, [src, r3]           ; c = des [dest_pitch*3]
+    subs    r2, r2, #1
+
+    mul     r5, r12, r5             ; b * 171
+    mla     r6, lr, r4, r5          ; a * 85
+    mla     r8, lr, r7, r5          ; c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [src, r1]
+
+    add     r8, r8, #128
+    mov     r8, r8, lsr #8
+    strb    r8, [src, r1, lsl #1]
+
+    add     src, src, #1
+
+    bne     vl23_loop
+
+    ldmia   sp!, {r4 - r8, pc}
+    ENDP    ;|vertical_band_2_3_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 3 to 5.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void vp8cx_horizontal_line_3_5_scale_c
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_3_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldrb    r4, [src], #1           ; a = src[0]
+
+hl35_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     ; b | a
+    ldrb    r9, [src], #1           ; c = src[2]
+    mul     r6, c102_154, r6        ; a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     ; b | c
+    mul     r5, c51_205, r5         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    ldrb    r4, [src], #1           ; d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     ; c | b
+    mul     r7, c51_205, r7         ; c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    orr     r9, r4, r9, lsl #16     ; c | d
+    mul     r9, c102_154, r9        ; c * 154 + 102 * d
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #3
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bpl     hl35_loop
+
+    ldrb    r5, [src], #1           ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     ; b | a
+    ldrb    r9, [src], #1           ; c = src[2]
+    mul     r6, c102_154, r6        ; a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     ; b | c
+    mul     r5, c51_205, r5         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     ; c | b
+    mul     r7, c51_205, r7         ; c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+    strb    r9, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_3_5_scale_c|
+
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_vertical_band_3_5_scale_c
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+; *                  height of the band scaled is 3-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_4_5_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_3_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl35_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r8, r4, r5, lsl #16     ; b | a
+    mul     r6, c102_154, r8        ; a * 102 + 154 * b
+
+    ldrb    r8, [r3, r1, lsl #1]    ; d = des[dest_pitch*5]
+    orr     r3, r7, r5, lsl #16     ; b | c
+    mul     r9, c51_205, r3         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    orr     r3, r5, r7, lsl #16     ; c | b
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    mul     r5, c51_205, r3         ; c * 205 + 154 * b
+    add     r9, r9, #0x8000
+    orr     r3, r8, r7, lsl #16     ; c | d
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    mul     r7, c102_154, r3        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    add     src, src, #1
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    add     r7, r7, #0x8000
+    subs    r2, r2, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+
+    bne     vl35_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_3_4_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 3 to 4.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void horizontal_line_3_4_scale_armv4
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_3_4_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+    ldrb    r4, [src], #1           ; a = src[0]
+
+hl34_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    ldrb    r7, [src], #1           ; c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r8, r4         ; a*64 + b*192 + 1
+
+    add     r8, r8, #1              ; b + 1
+    add     r8, r8, r7              ; b + c + 1
+    mov     r8, r8, asr #1          ; (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    strb    r8, [dest], #1
+
+    ldrb    r4, [src], #1           ; [a+1]
+
+    mla     r7, r11, r7, r9         ; c*192 + 128
+    mla     r7, r4, r10, r7         ; a*64 + b*192 + 128
+
+    subs    srcw, srcw, #3
+
+    mov     r7, r7, asr #8          ; (a*64 + b*192 + 128) >> 8
+    strb    r7, [dest], #1
+
+    bpl     hl34_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    ldrb    r7, [src], #1           ; c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r8, r4         ; a*64 + b*192 + 1
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    add     r8, r8, #1              ; b + 1
+    add     r8, r8, r7              ; b + c + 1
+    mov     r8, r8, asr #1          ; (b + c + 1) >> 1
+    strb    r8, [dest], #1
+    strb    r7, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_3_4_scale_c|
+
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_3_4_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 3 to 4. The
+; *                  height of the band scaled is 3-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_3_4_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_3_4_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+;   ldr     r1,[r1]
+vl34_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des [dest_pitch*2]
+    add     lr, src, r1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r5, r4         ; a*64 + b*192 + 1
+
+    add     r5, r5, #1              ; b + 1
+    add     r5, r5, r7              ; b + c + 1
+    mov     r5, r5, asr #1          ; (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [lr], r1
+
+    ldrb    r4, [r3, r1]            ; a = des [dest_pitch*4]
+
+    strb    r5, [lr], r1
+
+    mla     r7, r11, r7, r9         ; c*192 + 128
+    mla     r7, r4, r10, r7         ; a*64 + b*192 + 128
+    mov     r7, r7, asr #8          ; (a*64 + b*192 + 128) >> 8
+
+    add     src, src, #1
+    subs    r2, r2, #1
+
+    strb    r7, [lr]
+
+    bne     vl34_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_3_4_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 1 to 2.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; ****************************************************************************/
+;void vp8cx_horizontal_line_1_2_scale_c
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_1_2_scale_armv4| PROC
+    stmdb   sp!, {r4 - r5, lr}
+
+    sub     srcw, srcw, #1
+
+    ldrb    r3, [src], #1
+    ldrb    r4, [src], #1
+hl12_loop
+    subs    srcw, srcw, #1
+
+    add     r5, r3, r4
+    add     r5, r5, #1
+    mov     r5, r5, lsr #1
+
+    orr     r5, r3, r5, lsl #8
+    strh    r5, [dest], #2
+
+    mov     r3, r4
+
+    ldrneb  r4, [src], #1
+    bne     hl12_loop
+
+    orr     r5, r4, r4, lsl #8
+    strh    r5, [dest]
+
+    ldmia   sp!, {r4 - r5, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_vertical_band_1_2_scale_c
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+; *                  height of the band scaled is 1-pixel.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vp8cx_vertical_band_1_2_scale_c
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_1_2_scale_armv4| PROC
+    stmdb   sp!, {r4 - r7, lr}
+
+    ldr     mask, =0xff00ff             ; mask for selection
+    ldr     lr, = 0x010001
+
+vl12_loop
+    mov     r3, src
+    ldr     r4, [r3], r1
+    ldr     r5, [r3, r1]
+
+    add     src, src, #4
+    subs    r2, r2, #4
+
+    and     r6, r4, mask
+    and     r7, r5, mask
+
+    add     r6, r7, r6
+    add     r6, r6, lr
+
+    and     r4, mask, r4, lsr #8
+    and     r5, mask, r5, lsr #8
+
+    mov     r6, r6, lsr #1
+    and     r6, r6, mask
+
+    add     r4, r5, r4
+    add     r4, r4, lr
+
+    mov     r4, r4, lsr #1
+    and     r4, r4, mask
+
+    orr     r5, r6, r4, lsl #8
+
+    str     r5, [r3]
+
+    bpl     vl12_loop
+
+    ldmia   sp!, {r4 - r7, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+    END
diff --git a/vpx_scale/arm/nds/yv12extend.c b/vpx_scale/arm/nds/yv12extend.c
new file mode 100644 (file)
index 0000000..56959cb
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     yv12extend.c
+*
+*   Description  :
+*
+***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+#include <nitro.h>
+#include <nitro/mi.h>
+#include <nitro/itcm_begin.h>
+
+//---- DMA Number
+#define DMA_NO  3
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+
+/****************************************************************************
+*
+****************************************************************************/
+void
+vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->y_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        mi_cpu_fill8(dest_ptr1, src_ptr1[0], Border);
+        mi_cpu_fill8(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        mi_cpu_copy_fast(src_ptr1, dest_ptr1, plane_stride);
+        mi_cpu_copy_fast(src_ptr2, dest_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    plane_stride /= 2;
+    plane_height /= 2;
+    plane_width /= 2;
+    Border /= 2;
+
+    /***********/
+    /* U Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->u_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        mi_cpu_fill8(dest_ptr1, src_ptr1[0], Border);
+        mi_cpu_fill8(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->u_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        mi_cpu_copy_fast(src_ptr1, dest_ptr1, plane_stride);
+        mi_cpu_copy_fast(src_ptr2, dest_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    /***********/
+    /* V Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->v_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        mi_cpu_fill8(dest_ptr1, src_ptr1[0], Border);
+        mi_cpu_fill8(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->v_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        mi_cpu_copy_fast(src_ptr1, dest_ptr1, plane_stride);
+        mi_cpu_copy_fast(src_ptr2, dest_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+}
+
+
+
+/****************************************************************************
+*
+*  ROUTINE       : vp8_yv12_copy_frame
+*
+*  INPUTS        :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : Copies the source image into the destination image and
+*                  updates the destination's UMV borders.
+*
+*  SPECIAL NOTES : The frames are assumed to be identical in size.
+*
+****************************************************************************/
+void
+vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    int yplane_size = (src_ybc->y_height + 2 * src_ybc->border) * (src_ybc->y_stride);
+    int mem_size = (yplane_size * 3 / 2) + (src_ybc->y_stride * 2);
+
+    mi_cpu_copy_fast(src_ybc->buffer_alloc, dst_ybc->buffer_alloc, mem_size);
+
+    /*  unsigned char *src_y, *dst_y;
+        unsigned char *src_u, *dst_u;
+        unsigned char *src_v, *dst_v;
+
+        int yheight, uv_height;
+        int ystride, uv_stride;
+        int border;
+        int yoffset, uvoffset;
+
+        border   = src_ybc->border;
+        yheight  = src_ybc->y_height;
+        uv_height = src_ybc->uv_height;
+
+        ystride  = src_ybc->y_stride;
+        uv_stride = src_ybc->uv_stride;
+
+        yoffset  = border * (ystride + 1);
+        uvoffset = border/2 * (uv_stride + 1);
+
+        src_y = src_ybc->y_buffer - yoffset;
+        dst_y = dst_ybc->y_buffer - yoffset;
+        src_u = src_ybc->u_buffer - uvoffset;
+        dst_u = dst_ybc->u_buffer - uvoffset;
+        src_v = src_ybc->v_buffer - uvoffset;
+        dst_v = dst_ybc->v_buffer - uvoffset;
+
+        mi_cpu_copy_fast (src_y, dst_y, ystride *  (yheight + 2 * border));
+        mi_cpu_copy_fast (src_u, dst_u, uv_stride * (uv_height + border));
+        mi_cpu_copy_fast (src_v, dst_v, uv_stride * (uv_height + border));
+    */
+}
+
+#include <nitro/itcm_end.h>
diff --git a/vpx_scale/arm/neon/vp8_vpxyv12_copyframe_func_neon.asm b/vpx_scale/arm/neon/vp8_vpxyv12_copyframe_func_neon.asm
new file mode 100644 (file)
index 0000000..26384c4
--- /dev/null
@@ -0,0 +1,227 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_yv12_copy_frame_func_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    INCLUDE vpx_asm_offsets.asm
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+
+;void vp8_yv12_copy_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+|vp8_yv12_copy_frame_func_neon| PROC
+    push            {r4 - r11, lr}
+    vpush           {d8 - d15}
+
+    sub             sp, sp, #16
+
+    ;Copy Y plane
+    ldr             r8, [r0, #yv12_buffer_config_u_buffer]       ;srcptr1
+    ldr             r9, [r1, #yv12_buffer_config_u_buffer]       ;srcptr1
+    ldr             r10, [r0, #yv12_buffer_config_v_buffer]      ;srcptr1
+    ldr             r11, [r1, #yv12_buffer_config_v_buffer]      ;srcptr1
+
+    ldr             r4, [r0, #yv12_buffer_config_y_height]
+    ldr             r5, [r0, #yv12_buffer_config_y_width]
+    ldr             r6, [r0, #yv12_buffer_config_y_stride]
+    ldr             r7, [r1, #yv12_buffer_config_y_stride]
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+
+    str             r8, [sp]
+    str             r9, [sp, #4]
+    str             r10, [sp, #8]
+    str             r11, [sp, #12]
+
+    ; copy two rows at one time
+    mov             lr, r4, lsr #1
+
+cp_src_to_dst_height_loop
+    mov             r8, r2
+    mov             r9, r3
+    add             r10, r2, r6
+    add             r11, r3, r7
+    mov             r12, r5, lsr #7
+
+cp_src_to_dst_width_loop
+    vld1.8          {q0, q1}, [r8]!
+    vld1.8          {q8, q9}, [r10]!
+    vld1.8          {q2, q3}, [r8]!
+    vld1.8          {q10, q11}, [r10]!
+    vld1.8          {q4, q5}, [r8]!
+    vld1.8          {q12, q13}, [r10]!
+    vld1.8          {q6, q7}, [r8]!
+    vld1.8          {q14, q15}, [r10]!
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0, q1}, [r9]!
+    vst1.8          {q8, q9}, [r11]!
+    vst1.8          {q2, q3}, [r9]!
+    vst1.8          {q10, q11}, [r11]!
+    vst1.8          {q4, q5}, [r9]!
+    vst1.8          {q12, q13}, [r11]!
+    vst1.8          {q6, q7}, [r9]!
+    vst1.8          {q14, q15}, [r11]!
+
+    bne             cp_src_to_dst_width_loop
+
+    subs            lr, lr, #1
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             cp_src_to_dst_height_loop
+
+    ands            r10, r5, #0x7f                  ;check to see if extra copy is needed
+    sub             r11, r5, r10
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+    bne             extra_cp_src_to_dst_width
+end_of_cp_src_to_dst
+
+;Copy U & V planes
+    ldr             r2, [sp]        ;srcptr1
+    ldr             r3, [sp, #4]        ;dstptr1
+    mov             r4, r4, lsr #1                  ;src uv_height
+    mov             r5, r5, lsr #1                  ;src uv_width
+    mov             r6, r6, lsr #1                  ;src uv_stride
+    mov             r7, r7, lsr #1                  ;dst uv_stride
+
+    mov             r1, #2
+
+cp_uv_loop
+
+    ;copy two rows at one time
+    mov             lr, r4, lsr #1
+
+cp_src_to_dst_height_uv_loop
+    mov             r8, r2
+    mov             r9, r3
+    add             r10, r2, r6
+    add             r11, r3, r7
+    mov             r12, r5, lsr #6
+
+cp_src_to_dst_width_uv_loop
+    vld1.8          {q0, q1}, [r8]!
+    vld1.8          {q8, q9}, [r10]!
+    vld1.8          {q2, q3}, [r8]!
+    vld1.8          {q10, q11}, [r10]!
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0, q1}, [r9]!
+    vst1.8          {q8, q9}, [r11]!
+    vst1.8          {q2, q3}, [r9]!
+    vst1.8          {q10, q11}, [r11]!
+
+    bne             cp_src_to_dst_width_uv_loop
+
+    subs            lr, lr, #1
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             cp_src_to_dst_height_uv_loop
+
+    ands            r10, r5, #0x3f                  ;check to see if extra copy is needed
+    sub             r11, r5, r10
+    ldr             r2, [sp]        ;srcptr1
+    ldr             r3, [sp, #4]        ;dstptr1
+    bne             extra_cp_src_to_dst_uv_width
+end_of_cp_src_to_dst_uv
+
+    subs            r1, r1, #1
+
+    addne               sp, sp, #8
+
+    ldrne               r2, [sp]        ;srcptr1
+    ldrne               r3, [sp, #4]        ;dstptr1
+
+    bne             cp_uv_loop
+
+    add             sp, sp, #8
+
+    vpop            {d8 - d15}
+    pop             {r4 - r11, pc}
+
+;=============================
+extra_cp_src_to_dst_width
+    add             r2, r2, r11
+    add             r3, r3, r11
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             lr, r4, lsr #1
+extra_cp_src_to_dst_height_loop
+    mov             r8, r2
+    mov             r9, r3
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             r12, r10
+
+extra_cp_src_to_dst_width_loop
+    vld1.8          {q0}, [r8]!
+    vld1.8          {q1}, [r0]!
+
+    subs            r12, r12, #16
+
+    vst1.8          {q0}, [r9]!
+    vst1.8          {q1}, [r11]!
+    bne             extra_cp_src_to_dst_width_loop
+
+    subs            lr, lr, #1
+
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             extra_cp_src_to_dst_height_loop
+
+    b               end_of_cp_src_to_dst
+
+;=================================
+extra_cp_src_to_dst_uv_width
+    add             r2, r2, r11
+    add             r3, r3, r11
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             lr, r4, lsr #1
+extra_cp_src_to_dst_height_uv_loop
+    mov             r8, r2
+    mov             r9, r3
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             r12, r10
+
+extra_cp_src_to_dst_width_uv_loop
+    vld1.8          {d0}, [r8]!
+    vld1.8          {d1}, [r0]!
+
+    subs            r12, r12, #8
+
+    vst1.8          {d0}, [r9]!
+    vst1.8          {d1}, [r11]!
+    bne             extra_cp_src_to_dst_width_uv_loop
+
+    subs            lr, lr, #1
+
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             extra_cp_src_to_dst_height_uv_loop
+
+    b               end_of_cp_src_to_dst_uv
+
+    ENDP
+    END
diff --git a/vpx_scale/arm/neon/vp8_vpxyv12_copyframeyonly_neon.asm b/vpx_scale/arm/neon/vp8_vpxyv12_copyframeyonly_neon.asm
new file mode 100644 (file)
index 0000000..a50ae60
--- /dev/null
@@ -0,0 +1,499 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_yv12_copy_frame_yonly_neon|
+    EXPORT  |vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon|
+
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    INCLUDE vpx_asm_offsets.asm
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vpxyv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+; Note: this is VP8 function, which has border=32 and 16. Internal y_width and y_height
+; are always multiples of 16.
+
+|vp8_yv12_copy_frame_yonly_neon| PROC
+    push            {r4 - r11, lr}
+    vpush           {d8 - d15}
+
+    ldr             r4, [r0, #yv12_buffer_config_y_height]
+    ldr             r5, [r0, #yv12_buffer_config_y_width]
+    ldr             r6, [r0, #yv12_buffer_config_y_stride]
+    ldr             r7, [r1, #yv12_buffer_config_y_stride]
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+
+    ; copy two rows at one time
+    mov             lr, r4, lsr #1
+
+cp_src_to_dst_height_loop
+    mov             r8, r2
+    mov             r9, r3
+    add             r10, r2, r6
+    add             r11, r3, r7
+    mov             r12, r5, lsr #7
+
+cp_src_to_dst_width_loop
+    vld1.8          {q0, q1}, [r8]!
+    vld1.8          {q8, q9}, [r10]!
+    vld1.8          {q2, q3}, [r8]!
+    vld1.8          {q10, q11}, [r10]!
+    vld1.8          {q4, q5}, [r8]!
+    vld1.8          {q12, q13}, [r10]!
+    vld1.8          {q6, q7}, [r8]!
+    vld1.8          {q14, q15}, [r10]!
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0, q1}, [r9]!
+    vst1.8          {q8, q9}, [r11]!
+    vst1.8          {q2, q3}, [r9]!
+    vst1.8          {q10, q11}, [r11]!
+    vst1.8          {q4, q5}, [r9]!
+    vst1.8          {q12, q13}, [r11]!
+    vst1.8          {q6, q7}, [r9]!
+    vst1.8          {q14, q15}, [r11]!
+
+    bne             cp_src_to_dst_width_loop
+
+    subs            lr, lr, #1
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             cp_src_to_dst_height_loop
+
+    ands            r10, r5, #0x7f                  ;check to see if extra copy is needed
+    sub             r11, r5, r10
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+    bne             extra_cp_src_to_dst_width
+end_of_cp_src_to_dst
+
+
+    ;vpxyv12_extend_frame_borders_yonly
+    mov             r0, r1
+    ;Not need to load y_width, since: y_width = y_stride - 2*border
+    ldr             r3, [r0, #yv12_buffer_config_border]
+    ldr             r1, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r4, [r0, #yv12_buffer_config_y_height]
+    ldr             lr, [r0, #yv12_buffer_config_y_stride]
+
+    cmp             r3, #16
+    beq             b16_extend_frame_borders
+
+;=======================
+b32_extend_frame_borders
+;border = 32
+;=======================
+;Border copy for Y plane
+;copy the left and right most columns out
+    sub             r5, r1, r3              ;destptr1
+    add             r6, r1, lr
+    sub             r6, r6, r3, lsl #1      ;destptr2
+    sub             r2, r6, #1              ;srcptr2
+
+    ;Do four rows at one time
+    mov             r12, r4, lsr #2
+
+copy_left_right_y
+    vld1.8          {d0[], d1[]}, [r1], lr
+    vld1.8          {d4[], d5[]}, [r2], lr
+    vld1.8          {d8[], d9[]}, [r1], lr
+    vld1.8          {d12[], d13[]}, [r2], lr
+    vld1.8          {d16[], d17[]},  [r1], lr
+    vld1.8          {d20[], d21[]}, [r2], lr
+    vld1.8          {d24[], d25[]}, [r1], lr
+    vld1.8          {d28[], d29[]}, [r2], lr
+
+    vmov            q1, q0
+    vmov            q3, q2
+    vmov            q5, q4
+    vmov            q7, q6
+    vmov            q9, q8
+    vmov            q11, q10
+    vmov            q13, q12
+    vmov            q15, q14
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0, q1}, [r5], lr
+    vst1.8          {q2, q3}, [r6], lr
+    vst1.8          {q4, q5}, [r5], lr
+    vst1.8          {q6, q7}, [r6], lr
+    vst1.8          {q8, q9}, [r5], lr
+    vst1.8          {q10, q11}, [r6], lr
+    vst1.8          {q12, q13}, [r5], lr
+    vst1.8          {q14, q15}, [r6], lr
+
+    bne             copy_left_right_y
+
+;Now copy the top and bottom source lines into each line of the respective borders
+    ldr             r7, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    mul             r8, r3, lr
+
+    mov             r12, lr, lsr #7
+
+    sub             r6, r1, r3              ;destptr2
+    sub             r2, r6, lr              ;srcptr2
+    sub             r1, r7, r3              ;srcptr1
+    sub             r5, r1, r8              ;destptr1
+
+copy_top_bottom_y
+    vld1.8          {q0, q1}, [r1]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q2, q3}, [r1]!
+    vld1.8          {q10, q11}, [r2]!
+    vld1.8          {q4, q5}, [r1]!
+    vld1.8          {q12, q13}, [r2]!
+    vld1.8          {q6, q7}, [r1]!
+    vld1.8          {q14, q15}, [r2]!
+
+    mov             r7, r3
+
+top_bottom_32
+    subs            r7, r7, #1
+
+    vst1.8          {q0, q1}, [r5]!
+    vst1.8          {q8, q9}, [r6]!
+    vst1.8          {q2, q3}, [r5]!
+    vst1.8          {q10, q11}, [r6]!
+    vst1.8          {q4, q5}, [r5]!
+    vst1.8          {q12, q13}, [r6]!
+    vst1.8          {q6, q7}, [r5]!
+    vst1.8          {q14, q15}, [r6]!
+
+    add             r5, r5, lr
+    sub             r5, r5, #128
+    add             r6, r6, lr
+    sub             r6, r6, #128
+
+    bne             top_bottom_32
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+
+    subs            r12, r12, #1
+    bne             copy_top_bottom_y
+
+    mov             r7, lr, lsr #4              ;check to see if extra copy is needed
+    ands            r7, r7, #0x7
+    bne             extra_top_bottom_y
+end_of_border_copy_y
+
+    vpop            {d8 - d15}
+    pop             {r4 - r11, pc}
+
+;=====================
+;extra copy part for Y
+extra_top_bottom_y
+    vld1.8          {q0}, [r1]!
+    vld1.8          {q2}, [r2]!
+
+    mov             r9, r3, lsr #3
+
+extra_top_bottom_32
+    subs            r9, r9, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    bne             extra_top_bottom_32
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+    subs            r7, r7, #1
+    bne             extra_top_bottom_y
+
+    b               end_of_border_copy_y
+
+
+;=======================
+b16_extend_frame_borders
+;border = 16
+;=======================
+;Border copy for Y plane
+;copy the left and right most columns out
+    sub             r5, r1, r3              ;destptr1
+    add             r6, r1, lr
+    sub             r6, r6, r3, lsl #1      ;destptr2
+    sub             r2, r6, #1              ;srcptr2
+
+    ;Do four rows at one time
+    mov             r12, r4, lsr #2
+
+copy_left_right_y_b16
+    vld1.8          {d0[], d1[]}, [r1], lr
+    vld1.8          {d4[], d5[]}, [r2], lr
+    vld1.8          {d8[], d9[]}, [r1], lr
+    vld1.8          {d12[], d13[]}, [r2], lr
+    vld1.8          {d16[], d17[]},  [r1], lr
+    vld1.8          {d20[], d21[]}, [r2], lr
+    vld1.8          {d24[], d25[]}, [r1], lr
+    vld1.8          {d28[], d29[]}, [r2], lr
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q4}, [r5], lr
+    vst1.8          {q6}, [r6], lr
+    vst1.8          {q8}, [r5], lr
+    vst1.8          {q10}, [r6], lr
+    vst1.8          {q12}, [r5], lr
+    vst1.8          {q14}, [r6], lr
+
+    bne             copy_left_right_y_b16
+
+;Now copy the top and bottom source lines into each line of the respective borders
+    ldr             r7, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    mul             r8, r3, lr
+
+    mov             r12, lr, lsr #7
+
+    sub             r6, r1, r3              ;destptr2
+    sub             r2, r6, lr              ;srcptr2
+    sub             r1, r7, r3              ;srcptr1
+    sub             r5, r1, r8              ;destptr1
+
+copy_top_bottom_y_b16
+    vld1.8          {q0, q1}, [r1]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q2, q3}, [r1]!
+    vld1.8          {q10, q11}, [r2]!
+    vld1.8          {q4, q5}, [r1]!
+    vld1.8          {q12, q13}, [r2]!
+    vld1.8          {q6, q7}, [r1]!
+    vld1.8          {q14, q15}, [r2]!
+
+    mov             r7, r3
+
+top_bottom_16_b16
+    subs            r7, r7, #1
+
+    vst1.8          {q0, q1}, [r5]!
+    vst1.8          {q8, q9}, [r6]!
+    vst1.8          {q2, q3}, [r5]!
+    vst1.8          {q10, q11}, [r6]!
+    vst1.8          {q4, q5}, [r5]!
+    vst1.8          {q12, q13}, [r6]!
+    vst1.8          {q6, q7}, [r5]!
+    vst1.8          {q14, q15}, [r6]!
+
+    add             r5, r5, lr
+    sub             r5, r5, #128
+    add             r6, r6, lr
+    sub             r6, r6, #128
+
+    bne             top_bottom_16_b16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+
+    subs            r12, r12, #1
+    bne             copy_top_bottom_y_b16
+
+    mov             r7, lr, lsr #4              ;check to see if extra copy is needed
+    ands            r7, r7, #0x7
+    bne             extra_top_bottom_y_b16
+end_of_border_copy_y_b16
+
+    vpop            {d8 - d15}
+    pop             {r4 - r11, pc}
+
+;=====================
+;extra copy part for Y
+extra_top_bottom_y_b16
+    vld1.8          {q0}, [r1]!
+    vld1.8          {q2}, [r2]!
+
+    mov             r9, r3, lsr #3
+
+extra_top_bottom_16_b16
+    subs            r9, r9, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    bne             extra_top_bottom_16_b16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+    subs            r7, r7, #1
+    bne             extra_top_bottom_y_b16
+
+    b               end_of_border_copy_y_b16
+
+;=============================
+extra_cp_src_to_dst_width
+    add             r2, r2, r11
+    add             r3, r3, r11
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             lr, r4, lsr #1
+extra_cp_src_to_dst_height_loop
+    mov             r8, r2
+    mov             r9, r3
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             r12, r10
+
+extra_cp_src_to_dst_width_loop
+    vld1.8          {q0}, [r8]!
+    vld1.8          {q1}, [r0]!
+
+    subs            r12, r12, #16
+
+    vst1.8          {q0}, [r9]!
+    vst1.8          {q1}, [r11]!
+    bne             extra_cp_src_to_dst_width_loop
+
+    subs            lr, lr, #1
+
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             extra_cp_src_to_dst_height_loop
+
+    b               end_of_cp_src_to_dst
+
+    ENDP
+
+;===========================================================
+;In vp8cx_pick_filter_level(), call vp8_yv12_copy_frame_yonly
+;without extend_frame_borders.
+|vp8_yv12_copy_frame_yonly_no_extend_frame_borders_neon| PROC
+    push            {r4 - r11, lr}
+    vpush           {d8-d15}
+
+    ldr             r4, [r0, #yv12_buffer_config_y_height]
+    ldr             r5, [r0, #yv12_buffer_config_y_width]
+    ldr             r6, [r0, #yv12_buffer_config_y_stride]
+    ldr             r7, [r1, #yv12_buffer_config_y_stride]
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+
+    ; copy two rows at one time
+    mov             lr, r4, lsr #1
+
+cp_src_to_dst_height_loop1
+    mov             r8, r2
+    mov             r9, r3
+    add             r10, r2, r6
+    add             r11, r3, r7
+    mov             r12, r5, lsr #7
+
+cp_src_to_dst_width_loop1
+    vld1.8          {q0, q1}, [r8]!
+    vld1.8          {q8, q9}, [r10]!
+    vld1.8          {q2, q3}, [r8]!
+    vld1.8          {q10, q11}, [r10]!
+    vld1.8          {q4, q5}, [r8]!
+    vld1.8          {q12, q13}, [r10]!
+    vld1.8          {q6, q7}, [r8]!
+    vld1.8          {q14, q15}, [r10]!
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0, q1}, [r9]!
+    vst1.8          {q8, q9}, [r11]!
+    vst1.8          {q2, q3}, [r9]!
+    vst1.8          {q10, q11}, [r11]!
+    vst1.8          {q4, q5}, [r9]!
+    vst1.8          {q12, q13}, [r11]!
+    vst1.8          {q6, q7}, [r9]!
+    vst1.8          {q14, q15}, [r11]!
+
+    bne             cp_src_to_dst_width_loop1
+
+    subs            lr, lr, #1
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             cp_src_to_dst_height_loop1
+
+    ands            r10, r5, #0x7f                  ;check to see if extra copy is needed
+    sub             r11, r5, r10
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+    bne             extra_cp_src_to_dst_width1
+end_of_cp_src_to_dst1
+
+    vpop            {d8 - d15}
+    pop             {r4-r11, pc}
+
+;=============================
+extra_cp_src_to_dst_width1
+    add             r2, r2, r11
+    add             r3, r3, r11
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             lr, r4, lsr #1
+extra_cp_src_to_dst_height_loop1
+    mov             r8, r2
+    mov             r9, r3
+    add             r0, r8, r6
+    add             r11, r9, r7
+
+    mov             r12, r10
+
+extra_cp_src_to_dst_width_loop1
+    vld1.8          {q0}, [r8]!
+    vld1.8          {q1}, [r0]!
+
+    subs            r12, r12, #16
+
+    vst1.8          {q0}, [r9]!
+    vst1.8          {q1}, [r11]!
+    bne             extra_cp_src_to_dst_width_loop1
+
+    subs            lr, lr, #1
+
+    add             r2, r2, r6, lsl #1
+    add             r3, r3, r7, lsl #1
+
+    bne             extra_cp_src_to_dst_height_loop1
+
+    b               end_of_cp_src_to_dst1
+
+    ENDP
+
+    END
diff --git a/vpx_scale/arm/neon/vp8_vpxyv12_copysrcframe_func_neon.asm b/vpx_scale/arm/neon/vp8_vpxyv12_copysrcframe_func_neon.asm
new file mode 100644 (file)
index 0000000..c8923d5
--- /dev/null
@@ -0,0 +1,257 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_yv12_copy_src_frame_func_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    INCLUDE vpx_asm_offsets.asm
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;Note: This function is used to copy source data in src_buffer[i] at beginning of
+;the encoding. The buffer has a width and height of cpi->oxcf.Width and cpi->oxcf.Height,
+;which can be ANY numbers(NOT always multiples of 16 or 4).
+
+;void vp8_yv12_copy_src_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+|vp8_yv12_copy_src_frame_func_neon| PROC
+    push            {r4 - r11, lr}
+    vpush           {d8 - d15}
+
+    ;Copy Y plane
+    ldr             r4, [r0, #yv12_buffer_config_y_height]
+    ldr             r5, [r0, #yv12_buffer_config_y_width]
+    ldr             r6, [r0, #yv12_buffer_config_y_stride]
+    ldr             r7, [r1, #yv12_buffer_config_y_stride]
+    ldr             r2, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_y_buffer]       ;dstptr1
+
+    add             r10, r2, r6             ;second row src
+    add             r11, r3, r7             ;second row dst
+    mov             r6, r6, lsl #1
+    mov             r7, r7, lsl #1
+    sub             r6, r6, r5              ;adjust stride
+    sub             r7, r7, r5
+
+    ; copy two rows at one time
+    mov             lr, r4, lsr #1
+
+cp_src_to_dst_height_loop
+    mov             r12, r5
+
+cp_width_128_loop
+    vld1.8          {q0, q1}, [r2]!
+    vld1.8          {q4, q5}, [r10]!
+    vld1.8          {q2, q3}, [r2]!
+    vld1.8          {q6, q7}, [r10]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q12, q13}, [r10]!
+    vld1.8          {q10, q11}, [r2]!
+    vld1.8          {q14, q15}, [r10]!
+    sub             r12, r12, #128
+    cmp             r12, #128
+    vst1.8          {q0, q1}, [r3]!
+    vst1.8          {q4, q5}, [r11]!
+    vst1.8          {q2, q3}, [r3]!
+    vst1.8          {q6, q7}, [r11]!
+    vst1.8          {q8, q9}, [r3]!
+    vst1.8          {q12, q13}, [r11]!
+    vst1.8          {q10, q11}, [r3]!
+    vst1.8          {q14, q15}, [r11]!
+    bhs             cp_width_128_loop
+
+    cmp             r12, #0
+    beq             cp_width_done
+
+cp_width_8_loop
+    vld1.8          {d0}, [r2]!
+    vld1.8          {d1}, [r10]!
+    sub             r12, r12, #8
+    cmp             r12, #8
+    vst1.8          {d0}, [r3]!
+    vst1.8          {d1}, [r11]!
+    bhs             cp_width_8_loop
+
+    cmp             r12, #0
+    beq             cp_width_done
+
+cp_width_1_loop
+    ldrb            r8, [r2], #1
+    subs            r12, r12, #1
+    strb            r8, [r3], #1
+    ldrb            r8, [r10], #1
+    strb            r8, [r11], #1
+    bne             cp_width_1_loop
+
+cp_width_done
+    subs            lr, lr, #1
+    add             r2, r2, r6
+    add             r3, r3, r7
+    add             r10, r10, r6
+    add             r11, r11, r7
+    bne             cp_src_to_dst_height_loop
+
+;copy last line for Y if y_height is odd
+    tst             r4, #1
+    beq             cp_width_done_1
+    mov             r12, r5
+
+cp_width_128_loop_1
+    vld1.8          {q0, q1}, [r2]!
+    vld1.8          {q2, q3}, [r2]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q10, q11}, [r2]!
+    sub             r12, r12, #128
+    cmp             r12, #128
+    vst1.8          {q0, q1}, [r3]!
+    vst1.8          {q2, q3}, [r3]!
+    vst1.8          {q8, q9}, [r3]!
+    vst1.8          {q10, q11}, [r3]!
+    bhs             cp_width_128_loop_1
+
+    cmp             r12, #0
+    beq             cp_width_done_1
+
+cp_width_8_loop_1
+    vld1.8          {d0}, [r2]!
+    sub             r12, r12, #8
+    cmp             r12, #8
+    vst1.8          {d0}, [r3]!
+    bhs             cp_width_8_loop_1
+
+    cmp             r12, #0
+    beq             cp_width_done_1
+
+cp_width_1_loop_1
+    ldrb            r8, [r2], #1
+    subs            r12, r12, #1
+    strb            r8, [r3], #1
+    bne             cp_width_1_loop_1
+cp_width_done_1
+
+;Copy U & V planes
+    ldr             r4, [r0, #yv12_buffer_config_uv_height]
+    ldr             r5, [r0, #yv12_buffer_config_uv_width]
+    ldr             r6, [r0, #yv12_buffer_config_uv_stride]
+    ldr             r7, [r1, #yv12_buffer_config_uv_stride]
+    ldr             r2, [r0, #yv12_buffer_config_u_buffer]       ;srcptr1
+    ldr             r3, [r1, #yv12_buffer_config_u_buffer]       ;dstptr1
+
+    add             r10, r2, r6             ;second row src
+    add             r11, r3, r7             ;second row dst
+    mov             r6, r6, lsl #1
+    mov             r7, r7, lsl #1
+    sub             r6, r6, r5              ;adjust stride
+    sub             r7, r7, r5
+
+    mov             r9, #2
+
+cp_uv_loop
+    ;copy two rows at one time
+    mov             lr, r4, lsr #1
+
+cp_src_to_dst_height_uv_loop
+    mov             r12, r5
+
+cp_width_uv_64_loop
+    vld1.8          {q0, q1}, [r2]!
+    vld1.8          {q4, q5}, [r10]!
+    vld1.8          {q2, q3}, [r2]!
+    vld1.8          {q6, q7}, [r10]!
+    sub             r12, r12, #64
+    cmp             r12, #64
+    vst1.8          {q0, q1}, [r3]!
+    vst1.8          {q4, q5}, [r11]!
+    vst1.8          {q2, q3}, [r3]!
+    vst1.8          {q6, q7}, [r11]!
+    bhs             cp_width_uv_64_loop
+
+    cmp             r12, #0
+    beq             cp_width_uv_done
+
+cp_width_uv_8_loop
+    vld1.8          {d0}, [r2]!
+    vld1.8          {d1}, [r10]!
+    sub             r12, r12, #8
+    cmp             r12, #8
+    vst1.8          {d0}, [r3]!
+    vst1.8          {d1}, [r11]!
+    bhs             cp_width_uv_8_loop
+
+    cmp             r12, #0
+    beq             cp_width_uv_done
+
+cp_width_uv_1_loop
+    ldrb            r8, [r2], #1
+    subs            r12, r12, #1
+    strb            r8, [r3], #1
+    ldrb            r8, [r10], #1
+    strb            r8, [r11], #1
+    bne             cp_width_uv_1_loop
+
+cp_width_uv_done
+    subs            lr, lr, #1
+    add             r2, r2, r6
+    add             r3, r3, r7
+    add             r10, r10, r6
+    add             r11, r11, r7
+    bne             cp_src_to_dst_height_uv_loop
+
+;copy last line for U & V if uv_height is odd
+    tst             r4, #1
+    beq             cp_width_uv_done_1
+    mov             r12, r5
+
+cp_width_uv_64_loop_1
+    vld1.8          {q0, q1}, [r2]!
+    vld1.8          {q2, q3}, [r2]!
+    sub             r12, r12, #64
+    cmp             r12, #64
+    vst1.8          {q0, q1}, [r3]!
+    vst1.8          {q2, q3}, [r3]!
+    bhs             cp_width_uv_64_loop_1
+
+    cmp             r12, #0
+    beq             cp_width_uv_done_1
+
+cp_width_uv_8_loop_1
+    vld1.8          {d0}, [r2]!
+    sub             r12, r12, #8
+    cmp             r12, #8
+    vst1.8          {d0}, [r3]!
+    bhs             cp_width_uv_8_loop_1
+
+    cmp             r12, #0
+    beq             cp_width_uv_done_1
+
+cp_width_uv_1_loop_1
+    ldrb            r8, [r2], #1
+    subs            r12, r12, #1
+    strb            r8, [r3], #1
+    bne             cp_width_uv_1_loop_1
+cp_width_uv_done_1
+
+    subs            r9, r9, #1
+    ldrne           r2, [r0, #yv12_buffer_config_v_buffer]      ;srcptr1
+    ldrne           r3, [r1, #yv12_buffer_config_v_buffer]      ;dstptr1
+    ldrne           r10, [r0, #yv12_buffer_config_uv_stride]
+    ldrne           r11, [r1, #yv12_buffer_config_uv_stride]
+
+    addne           r10, r2, r10                ;second row src
+    addne           r11, r3, r11                ;second row dst
+
+    bne             cp_uv_loop
+
+    vpop            {d8 - d15}
+    pop             {r4 - r11, pc}
+
+    ENDP
+    END
diff --git a/vpx_scale/arm/neon/vp8_vpxyv12_extendframeborders_neon.asm b/vpx_scale/arm/neon/vp8_vpxyv12_extendframeborders_neon.asm
new file mode 100644 (file)
index 0000000..8c9ce19
--- /dev/null
@@ -0,0 +1,587 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |vp8_yv12_extend_frame_borders_neon|
+    ARM
+    REQUIRE8
+    PRESERVE8
+
+    INCLUDE vpx_asm_offsets.asm
+
+    AREA ||.text||, CODE, READONLY, ALIGN=2
+;void vp8_yv12_extend_frame_borders_neon (YV12_BUFFER_CONFIG *ybf);
+;Note: this is VP8 function, which has border=32 and 16. Internal y_width and y_height
+; are always multiples of 16.
+
+|vp8_yv12_extend_frame_borders_neon| PROC
+    push            {r4 - r10, lr}
+    vpush           {d8 - d15}
+
+    ;Not need to load y_width, since: y_width = y_stride - 2*border
+    ldr             r3, [r0, #yv12_buffer_config_border]
+    ldr             r1, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    ldr             r4, [r0, #yv12_buffer_config_y_height]
+    ldr             lr, [r0, #yv12_buffer_config_y_stride]
+
+    cmp             r3, #16
+    beq             b16_extend_frame_borders
+
+;=======================
+b32_extend_frame_borders
+;border = 32
+;=======================
+;Border copy for Y plane
+;copy the left and right most columns out
+    sub             r5, r1, r3              ;destptr1
+    add             r6, r1, lr
+    sub             r6, r6, r3, lsl #1      ;destptr2
+    sub             r2, r6, #1              ;srcptr2
+
+    ;Do four rows at one time
+    mov             r12, r4, lsr #2
+
+copy_left_right_y
+    vld1.8          {d0[], d1[]}, [r1], lr
+    vld1.8          {d4[], d5[]}, [r2], lr
+    vld1.8          {d8[], d9[]}, [r1], lr
+    vld1.8          {d12[], d13[]}, [r2], lr
+    vld1.8          {d16[], d17[]},  [r1], lr
+    vld1.8          {d20[], d21[]}, [r2], lr
+    vld1.8          {d24[], d25[]}, [r1], lr
+    vld1.8          {d28[], d29[]}, [r2], lr
+
+    vmov            q1, q0
+    vmov            q3, q2
+    vmov            q5, q4
+    vmov            q7, q6
+    vmov            q9, q8
+    vmov            q11, q10
+    vmov            q13, q12
+    vmov            q15, q14
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0, q1}, [r5], lr
+    vst1.8          {q2, q3}, [r6], lr
+    vst1.8          {q4, q5}, [r5], lr
+    vst1.8          {q6, q7}, [r6], lr
+    vst1.8          {q8, q9}, [r5], lr
+    vst1.8          {q10, q11}, [r6], lr
+    vst1.8          {q12, q13}, [r5], lr
+    vst1.8          {q14, q15}, [r6], lr
+
+    bne             copy_left_right_y
+
+;Now copy the top and bottom source lines into each line of the respective borders
+    ldr             r7, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    mul             r8, r3, lr
+
+    mov             r12, lr, lsr #7
+
+    sub             r6, r1, r3              ;destptr2
+    sub             r2, r6, lr              ;srcptr2
+    sub             r1, r7, r3              ;srcptr1
+    sub             r5, r1, r8              ;destptr1
+
+copy_top_bottom_y
+    vld1.8          {q0, q1}, [r1]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q2, q3}, [r1]!
+    vld1.8          {q10, q11}, [r2]!
+    vld1.8          {q4, q5}, [r1]!
+    vld1.8          {q12, q13}, [r2]!
+    vld1.8          {q6, q7}, [r1]!
+    vld1.8          {q14, q15}, [r2]!
+
+    mov             r7, r3
+
+top_bottom_32
+    subs            r7, r7, #1
+
+    vst1.8          {q0, q1}, [r5]!
+    vst1.8          {q8, q9}, [r6]!
+    vst1.8          {q2, q3}, [r5]!
+    vst1.8          {q10, q11}, [r6]!
+    vst1.8          {q4, q5}, [r5]!
+    vst1.8          {q12, q13}, [r6]!
+    vst1.8          {q6, q7}, [r5]!
+    vst1.8          {q14, q15}, [r6]!
+
+    add             r5, r5, lr
+    sub             r5, r5, #128
+    add             r6, r6, lr
+    sub             r6, r6, #128
+
+    bne             top_bottom_32
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+
+    subs            r12, r12, #1
+    bne             copy_top_bottom_y
+
+    mov             r7, lr, lsr #4              ;check to see if extra copy is needed
+    ands            r7, r7, #0x7
+    bne             extra_top_bottom_y
+end_of_border_copy_y
+
+;Border copy for U, V planes
+    ldr             r1, [r0, #yv12_buffer_config_u_buffer]       ;srcptr1
+    mov             lr, lr, lsr #1              ;uv_stride
+    mov             r3, r3, lsr #1              ;border
+    mov             r4, r4, lsr #1              ;uv_height
+    mov             r8, r8, lsr #2
+
+    mov             r10, #2
+
+;copy the left and right most columns out
+border_copy_uv
+    sub             r5, r1, r3              ;destptr1
+    add             r6, r1, lr
+    sub             r6, r6, r3, lsl #1      ;destptr2
+    sub             r2, r6, #1              ;srcptr2
+
+    mov             r7, r1
+
+    ;Do eight rows at one time
+    mov             r12, r4, lsr #3
+
+copy_left_right_uv
+    vld1.8          {d0[], d1[]}, [r1], lr
+    vld1.8          {d2[], d3[]}, [r2], lr
+    vld1.8          {d4[], d5[]}, [r1], lr
+    vld1.8          {d6[], d7[]}, [r2], lr
+    vld1.8          {d8[], d9[]},  [r1], lr
+    vld1.8          {d10[], d11[]}, [r2], lr
+    vld1.8          {d12[], d13[]}, [r1], lr
+    vld1.8          {d14[], d15[]}, [r2], lr
+    vld1.8          {d16[], d17[]}, [r1], lr
+    vld1.8          {d18[], d19[]}, [r2], lr
+    vld1.8          {d20[], d21[]}, [r1], lr
+    vld1.8          {d22[], d23[]}, [r2], lr
+    vld1.8          {d24[], d25[]},  [r1], lr
+    vld1.8          {d26[], d27[]}, [r2], lr
+    vld1.8          {d28[], d29[]}, [r1], lr
+    vld1.8          {d30[], d31[]}, [r2], lr
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q1}, [r6], lr
+    vst1.8          {q2}, [r5], lr
+    vst1.8          {q3}, [r6], lr
+    vst1.8          {q4}, [r5], lr
+    vst1.8          {q5}, [r6], lr
+    vst1.8          {q6}, [r5], lr
+    vst1.8          {q7}, [r6], lr
+    vst1.8          {q8}, [r5], lr
+    vst1.8          {q9}, [r6], lr
+    vst1.8          {q10}, [r5], lr
+    vst1.8          {q11}, [r6], lr
+    vst1.8          {q12}, [r5], lr
+    vst1.8          {q13}, [r6], lr
+    vst1.8          {q14}, [r5], lr
+    vst1.8          {q15}, [r6], lr
+
+    bne             copy_left_right_uv
+
+;Now copy the top and bottom source lines into each line of the respective borders
+    mov             r12, lr, lsr #6
+
+    sub             r6, r1, r3              ;destptr2
+    sub             r2, r6, lr              ;srcptr2
+    sub             r1, r7, r3              ;srcptr1
+    sub             r5, r1, r8              ;destptr1
+
+copy_top_bottom_uv
+    vld1.8          {q0, q1}, [r1]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q2, q3}, [r1]!
+    vld1.8          {q10, q11}, [r2]!
+
+    mov             r7, r3
+
+top_bottom_16
+    subs            r7, r7, #1
+
+    vst1.8          {q0, q1}, [r5]!
+    vst1.8          {q8, q9}, [r6]!
+    vst1.8          {q2, q3}, [r5]!
+    vst1.8          {q10, q11}, [r6]!
+
+    add             r5, r5, lr
+    sub             r5, r5, #64
+    add             r6, r6, lr
+    sub             r6, r6, #64
+
+    bne             top_bottom_16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+
+    subs            r12, r12, #1
+    bne             copy_top_bottom_uv
+
+    mov             r7, lr, lsr #3              ;check to see if extra copy is needed
+    ands            r7, r7, #0x7
+    bne             extra_top_bottom_uv
+
+end_of_border_copy_uv
+    subs            r10, r10, #1
+    ldrne           r1, [r0, #yv12_buffer_config_v_buffer]       ;srcptr1
+    bne             border_copy_uv
+
+    vpop            {d8 - d15}
+    pop             {r4 - r10, pc}
+
+;;;;;;;;;;;;;;;;;;;;;;
+;extra copy part for Y
+extra_top_bottom_y
+    vld1.8          {q0}, [r1]!
+    vld1.8          {q2}, [r2]!
+
+    mov             r9, r3, lsr #3
+
+extra_top_bottom_32
+    subs            r9, r9, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    bne             extra_top_bottom_32
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+    subs            r7, r7, #1
+    bne             extra_top_bottom_y
+
+    b               end_of_border_copy_y
+
+;extra copy part for UV
+extra_top_bottom_uv
+    vld1.8          {d0}, [r1]!
+    vld1.8          {d8}, [r2]!
+
+    mov             r9, r3, lsr #3
+
+extra_top_bottom_16
+    subs            r9, r9, #1
+
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    bne             extra_top_bottom_16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+    subs            r7, r7, #1
+    bne             extra_top_bottom_uv
+
+    b               end_of_border_copy_uv
+
+
+;=======================
+b16_extend_frame_borders
+;border = 16
+;=======================
+;Border copy for Y plane
+;copy the left and right most columns out
+    sub             r5, r1, r3              ;destptr1
+    add             r6, r1, lr
+    sub             r6, r6, r3, lsl #1      ;destptr2
+    sub             r2, r6, #1              ;srcptr2
+
+    ;Do four rows at one time
+    mov             r12, r4, lsr #2
+
+copy_left_right_y_b16
+    vld1.8          {d0[], d1[]}, [r1], lr
+    vld1.8          {d4[], d5[]}, [r2], lr
+    vld1.8          {d8[], d9[]}, [r1], lr
+    vld1.8          {d12[], d13[]}, [r2], lr
+    vld1.8          {d16[], d17[]},  [r1], lr
+    vld1.8          {d20[], d21[]}, [r2], lr
+    vld1.8          {d24[], d25[]}, [r1], lr
+    vld1.8          {d28[], d29[]}, [r2], lr
+
+    subs            r12, r12, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q4}, [r5], lr
+    vst1.8          {q6}, [r6], lr
+    vst1.8          {q8}, [r5], lr
+    vst1.8          {q10}, [r6], lr
+    vst1.8          {q12}, [r5], lr
+    vst1.8          {q14}, [r6], lr
+
+    bne             copy_left_right_y_b16
+
+;Now copy the top and bottom source lines into each line of the respective borders
+    ldr             r7, [r0, #yv12_buffer_config_y_buffer]       ;srcptr1
+    mul             r8, r3, lr
+
+    mov             r12, lr, lsr #7
+
+    sub             r6, r1, r3              ;destptr2
+    sub             r2, r6, lr              ;srcptr2
+    sub             r1, r7, r3              ;srcptr1
+    sub             r5, r1, r8              ;destptr1
+
+copy_top_bottom_y_b16
+    vld1.8          {q0, q1}, [r1]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q2, q3}, [r1]!
+    vld1.8          {q10, q11}, [r2]!
+    vld1.8          {q4, q5}, [r1]!
+    vld1.8          {q12, q13}, [r2]!
+    vld1.8          {q6, q7}, [r1]!
+    vld1.8          {q14, q15}, [r2]!
+
+    mov             r7, r3
+
+top_bottom_16_b16
+    subs            r7, r7, #1
+
+    vst1.8          {q0, q1}, [r5]!
+    vst1.8          {q8, q9}, [r6]!
+    vst1.8          {q2, q3}, [r5]!
+    vst1.8          {q10, q11}, [r6]!
+    vst1.8          {q4, q5}, [r5]!
+    vst1.8          {q12, q13}, [r6]!
+    vst1.8          {q6, q7}, [r5]!
+    vst1.8          {q14, q15}, [r6]!
+
+    add             r5, r5, lr
+    sub             r5, r5, #128
+    add             r6, r6, lr
+    sub             r6, r6, #128
+
+    bne             top_bottom_16_b16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+
+    subs            r12, r12, #1
+    bne             copy_top_bottom_y_b16
+
+    mov             r7, lr, lsr #4              ;check to see if extra copy is needed
+    ands            r7, r7, #0x7
+    bne             extra_top_bottom_y_b16
+end_of_border_copy_y_b16
+
+;Border copy for U, V planes
+    ldr             r1, [r0, #yv12_buffer_config_u_buffer]       ;srcptr1
+    mov             lr, lr, lsr #1              ;uv_stride
+    mov             r3, r3, lsr #1              ;border
+    mov             r4, r4, lsr #1              ;uv_height
+    mov             r8, r8, lsr #2
+
+    mov             r10, #2
+
+;copy the left and right most columns out
+border_copy_uv_b16
+    sub             r5, r1, r3              ;destptr1
+    add             r6, r1, lr
+    sub             r6, r6, r3, lsl #1      ;destptr2
+    sub             r2, r6, #1              ;srcptr2
+
+    mov             r7, r1
+
+    ;Do eight rows at one time
+    mov             r12, r4, lsr #3
+
+copy_left_right_uv_b16
+    vld1.8          {d0[]}, [r1], lr
+    vld1.8          {d2[]}, [r2], lr
+    vld1.8          {d4[]}, [r1], lr
+    vld1.8          {d6[]}, [r2], lr
+    vld1.8          {d8[]},  [r1], lr
+    vld1.8          {d10[]}, [r2], lr
+    vld1.8          {d12[]}, [r1], lr
+    vld1.8          {d14[]}, [r2], lr
+    vld1.8          {d16[]}, [r1], lr
+    vld1.8          {d18[]}, [r2], lr
+    vld1.8          {d20[]}, [r1], lr
+    vld1.8          {d22[]}, [r2], lr
+    vld1.8          {d24[]},  [r1], lr
+    vld1.8          {d26[]}, [r2], lr
+    vld1.8          {d28[]}, [r1], lr
+    vld1.8          {d30[]}, [r2], lr
+
+    subs            r12, r12, #1
+
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d2}, [r6], lr
+    vst1.8          {d4}, [r5], lr
+    vst1.8          {d6}, [r6], lr
+    vst1.8          {d8}, [r5], lr
+    vst1.8          {d10}, [r6], lr
+    vst1.8          {d12}, [r5], lr
+    vst1.8          {d14}, [r6], lr
+    vst1.8          {d16}, [r5], lr
+    vst1.8          {d18}, [r6], lr
+    vst1.8          {d20}, [r5], lr
+    vst1.8          {d22}, [r6], lr
+    vst1.8          {d24}, [r5], lr
+    vst1.8          {d26}, [r6], lr
+    vst1.8          {d28}, [r5], lr
+    vst1.8          {d30}, [r6], lr
+
+    bne             copy_left_right_uv_b16
+
+;Now copy the top and bottom source lines into each line of the respective borders
+    mov             r12, lr, lsr #6
+
+    sub             r6, r1, r3              ;destptr2
+    sub             r2, r6, lr              ;srcptr2
+    sub             r1, r7, r3              ;srcptr1
+    sub             r5, r1, r8              ;destptr1
+
+copy_top_bottom_uv_b16
+    vld1.8          {q0, q1}, [r1]!
+    vld1.8          {q8, q9}, [r2]!
+    vld1.8          {q2, q3}, [r1]!
+    vld1.8          {q10, q11}, [r2]!
+
+    mov             r7, r3
+
+top_bottom_8_b16
+    subs            r7, r7, #1
+
+    vst1.8          {q0, q1}, [r5]!
+    vst1.8          {q8, q9}, [r6]!
+    vst1.8          {q2, q3}, [r5]!
+    vst1.8          {q10, q11}, [r6]!
+
+    add             r5, r5, lr
+    sub             r5, r5, #64
+    add             r6, r6, lr
+    sub             r6, r6, #64
+
+    bne             top_bottom_8_b16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+
+    subs            r12, r12, #1
+    bne             copy_top_bottom_uv_b16
+
+    mov             r7, lr, lsr #3              ;check to see if extra copy is needed
+    ands            r7, r7, #0x7
+    bne             extra_top_bottom_uv_b16
+
+end_of_border_copy_uv_b16
+    subs            r10, r10, #1
+    ldrne           r1, [r0, #yv12_buffer_config_v_buffer]       ;srcptr1
+    bne             border_copy_uv_b16
+
+    vpop            {d8-d15}
+    pop             {r4 - r10, pc}
+
+;;;;;;;;;;;;;;;;;;;;;;
+;extra copy part for Y
+extra_top_bottom_y_b16
+    vld1.8          {q0}, [r1]!
+    vld1.8          {q2}, [r2]!
+
+    mov             r9, r3, lsr #3
+
+extra_top_bottom_16_b16
+    subs            r9, r9, #1
+
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    vst1.8          {q0}, [r5], lr
+    vst1.8          {q2}, [r6], lr
+    bne             extra_top_bottom_16_b16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+    subs            r7, r7, #1
+    bne             extra_top_bottom_y_b16
+
+    b               end_of_border_copy_y_b16
+
+;extra copy part for UV
+extra_top_bottom_uv_b16
+    vld1.8          {d0}, [r1]!
+    vld1.8          {d8}, [r2]!
+
+    mov             r9, r3, lsr #3
+
+extra_top_bottom_8_b16
+    subs            r9, r9, #1
+
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    vst1.8          {d0}, [r5], lr
+    vst1.8          {d8}, [r6], lr
+    bne             extra_top_bottom_8_b16
+
+    sub             r5, r1, r8
+    add             r6, r2, lr
+    subs            r7, r7, #1
+    bne             extra_top_bottom_uv_b16
+
+    b               end_of_border_copy_uv_b16
+
+    ENDP
+    END
diff --git a/vpx_scale/arm/scalesystemdependant.c b/vpx_scale/arm/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..3c355be
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/vpxscale.h"
+
+#ifdef HAVE_CONFIG_H
+#include "vpx_config.h"
+#endif
+
+void (*vp8_yv12_extend_frame_borders_ptr)(YV12_BUFFER_CONFIG *ybf);
+extern void vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf);
+extern void vp8_yv12_extend_frame_borders_neon(YV12_BUFFER_CONFIG *ybf);
+
+void (*vp8_yv12_copy_frame_yonly_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_yonly_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+void (*vp8_yv12_copy_frame_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_scale_machine_specific_config()
+{
+    /*
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_armv4;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_armv4;
+    vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_armv4;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_armv4;
+    vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+    vp8_horizontal_line_3_4_scale        = horizontal_line_3_4_scale_armv4;
+    vp8_vertical_band_3_4_scale          = vertical_band_3_4_scale_armv4;
+    vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+    vp8_horizontal_line_2_3_scale        = horizontal_line_2_3_scale_armv4;
+    vp8_vertical_band_2_3_scale          = vertical_band_2_3_scale_armv4;
+    vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_armv4;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_armv4;
+    vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+
+    vp8_vertical_band_5_4_scale           = vp8cx_vertical_band_5_4_scale_c;
+    vp8_vertical_band_5_3_scale           = vp8cx_vertical_band_5_3_scale_c;
+    vp8_vertical_band_2_1_scale           = vp8cx_vertical_band_2_1_scale_c;
+    vp8_vertical_band_2_1_scale_i         = vp8cx_vertical_band_2_1_scale_i_c;
+    vp8_horizontal_line_2_1_scale         = vp8cx_horizontal_line_2_1_scale_c;
+    vp8_horizontal_line_5_3_scale         = vp8cx_horizontal_line_5_3_scale_c;
+    vp8_horizontal_line_5_4_scale         = vp8cx_horizontal_line_5_4_scale_c;
+    */
+
+#if HAVE_ARMV7
+    vp8_yv12_extend_frame_borders_ptr      = vp8_yv12_extend_frame_borders_neon;
+    vp8_yv12_copy_frame_yonly_ptr          = vp8_yv12_copy_frame_yonly_neon;
+    vp8_yv12_copy_frame_ptr               = vp8_yv12_copy_frame_neon;
+#else
+    vp8_yv12_extend_frame_borders_ptr      = vp8_yv12_extend_frame_borders;
+    vp8_yv12_copy_frame_yonly_ptr          = vp8_yv12_copy_frame_yonly;
+    vp8_yv12_copy_frame_ptr           = vp8_yv12_copy_frame;
+#endif
+
+}
diff --git a/vpx_scale/arm/yv12extend_arm.c b/vpx_scale/arm/yv12extend_arm.c
new file mode 100644 (file)
index 0000000..7c3f7cd
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/vpxscale.h"
+
+void vp8_yv12_copy_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+void
+vp8_yv12_copy_frame_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    vp8_yv12_copy_frame_func_neon(src_ybc, dst_ybc);
+    //printf("Border:%d; plane_stride:%d; plane_height:%d; plane_width:%d\n",dst_ybc->border,dst_ybc->y_stride,dst_ybc->y_height,dst_ybc->y_width);
+
+    vp8_yv12_extend_frame_borders_ptr(dst_ybc);
+}
diff --git a/vpx_scale/blackfin/yv12config.c b/vpx_scale/blackfin/yv12config.c
new file mode 100644 (file)
index 0000000..7cb083f
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     yv12config.c
+ *
+ *   Description  :
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+
+#include <cdef_bf533.h>
+
+/****************************************************************************
+*  Imports
+****************************************************************************/
+void
+extend_memset(void *dst, unsigned char value, unsigned int size);
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+int
+vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf)
+{
+    if (ybf)
+    {
+        if (ybf->buffer_alloc)
+        {
+            duck_free(ybf->buffer_alloc);
+        }
+
+        ybf->buffer_alloc = 0;
+    }
+    else
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+int
+vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border)
+{
+//NOTE:
+
+    int yplane_size = (height + 2 * border) * (width + 2 * border);
+    int uvplane_size = (height / 2 + border) * (width / 2 + border);
+
+    if (ybf)
+    {
+        vp8_yv12_de_alloc_frame_buffer(ybf);
+
+        ybf->y_width  = width;
+        ybf->y_height = height;
+        ybf->y_stride = width + 2 * border;
+
+        ybf->uv_width = width / 2;
+        ybf->uv_height = height / 2;
+        ybf->uv_stride = ybf->uv_width + border;
+
+        ybf->border = border;
+
+        // Added 2 extra lines to framebuffer so that copy12x12 doesn't fail
+        // when we have a large motion vector in V on the last v block.
+        // Note : We never use these pixels anyway so this doesn't hurt.
+        ybf->buffer_alloc = (unsigned char *) duck_memalign(32, (yplane_size * 3 / 2) +  ybf->y_stride , 0);
+
+        if (ybf->buffer_alloc == NULL)
+            return -1;
+
+        ybf->y_buffer = ybf->buffer_alloc + border * ybf->y_stride + border;
+        ybf->u_buffer = ybf->buffer_alloc + yplane_size + border / 2  * ybf->uv_stride + border / 2;
+        ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + border / 2  * ybf->uv_stride + border / 2;
+    }
+    else
+    {
+        return -2;
+    }
+
+    return 0;
+}
+/****************************************************************************
+ *
+ ****************************************************************************/
+int
+vp8_yv12_black_frame_buffer(YV12_BUFFER_CONFIG *ybf)
+{
+    if (ybf)
+    {
+        if (ybf->buffer_alloc)
+        {
+            extend_memset(ybf->y_buffer, 0x0, ybf->y_stride *(ybf->y_height + 2 * ybf->border));
+            extend_memset(ybf->u_buffer, 0x80, ybf->uv_stride *(ybf->uv_height + ybf->border));
+            extend_memset(ybf->v_buffer, 0x80, ybf->uv_stride *(ybf->uv_height + ybf->border));
+        }
+
+        return 0;
+    }
+
+    return -1;
+}
diff --git a/vpx_scale/blackfin/yv12extend.c b/vpx_scale/blackfin/yv12extend.c
new file mode 100644 (file)
index 0000000..d5be495
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     yv12extend.c
+ *
+ *   Description  :
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include <cdef_bf533.h>
+
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+*
+****************************************************************************/
+
+
+/****************************************************************************
+*
+****************************************************************************/
+void
+extend_memset(void *dst, unsigned char value, unsigned int size)
+{
+#if 0
+    unsigned int quad_value;
+
+    quad_value = (unsigned int) value;
+    quad_value |= (unsigned int) value << 8;
+    quad_value |= (unsigned int) value << 16;
+    quad_value |= (unsigned int) value << 24;
+#else
+    unsigned short quad_value;
+
+    quad_value = (unsigned int) value;
+    quad_value |= (unsigned int) value << 8;
+#endif
+
+
+    if (size / 2 >= 64 * 1024)
+        printf("_Extend_memset__________ dma memset is broken\n");
+
+    *p_mdma_s1_start_addr = &quad_value;
+    *p_mdma_s1_x_count = size / 2;
+    *p_mdma_s1_x_modify = 0x0;
+    *p_mdma_d1_start_addr = dst;
+    *p_mdma_d1_x_count = size / 2;
+    *p_mdma_d1_x_modify = 2;
+
+    *p_mdma_s1_config = DMAEN | WDSIZE_16;
+    asm("ssync;");
+
+    *p_mdma_d1_config = DI_EN | DMAEN | WNR | WDSIZE_16;
+    asm("ssync;");
+
+    while ((*p_mdma_d1_irq_status & DMA_DONE) == 0);
+
+    *p_mdma_d1_irq_status |= DMA_DONE;
+}
+
+/****************************************************************************
+*
+****************************************************************************/
+void
+extend_memcpy(void *dst, void *src, unsigned int size)
+{
+    if (size / 2 >= 64 * 1024)
+        printf("_Extend_memcpy__________ dma memcpy is broken\n");
+
+
+    if ((size & 0x3))
+        printf("_)__________ size not a multiple of 4\n");
+
+//32 bit dma here caused some data to be corrupted --- WHY ??????
+
+    *p_mdma_s1_start_addr = src;
+    *p_mdma_s1_x_count = size / 2;
+    *p_mdma_s1_x_modify = 2;
+    *p_mdma_d1_start_addr = dst;
+    *p_mdma_d1_x_count = size / 2;
+    *p_mdma_d1_x_modify = 2;
+
+    *p_mdma_s1_config = DMAEN | WDSIZE_16;
+    asm("ssync;");
+
+    *p_mdma_d1_config = DI_EN | DMAEN | WNR | WDSIZE_16;
+    asm("ssync;");
+
+    while ((*p_mdma_d1_irq_status & DMA_DONE) == 0);
+
+    *p_mdma_d1_irq_status |= DMA_DONE;
+}
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+void
+vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf)
+{
+#if 1
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    unsigned int quad_sample;
+    unsigned int sample;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->y_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        extend_memset(dest_ptr1, src_ptr1[0], Border);
+        extend_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        extend_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        dest_ptr1 += plane_stride;
+    }
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        extend_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr2 += plane_stride;
+    }
+
+    plane_stride /= 2;
+    plane_height /= 2;
+    plane_width /= 2;
+    Border /= 2;
+
+    /***********/
+    /* U Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->u_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        extend_memset(dest_ptr1, src_ptr1[0], Border);
+        extend_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->u_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        extend_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        dest_ptr1 += plane_stride;
+    }
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        extend_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr2 += plane_stride;
+    }
+
+    /***********/
+    /* V Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->v_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        extend_memset(dest_ptr1, src_ptr1[0], Border);
+        extend_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->v_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        extend_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        dest_ptr1 += plane_stride;
+    }
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        extend_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr2 += plane_stride;
+    }
+
+#endif
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_yv12_copy_frame
+ *
+ *  INPUTS        :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies the source image into the destination image and
+ *                  updates the destination's UMV borders.
+ *
+ *  SPECIAL NOTES : The frames are assumed to be identical in size.
+ *
+ ****************************************************************************/
+void
+vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+#if 1
+    int row;
+    unsigned char *source, *dest;
+
+    source = src_ybc->y_buffer;
+    dest = dst_ybc->y_buffer;
+
+    for (row = 0; row < src_ybc->y_height; row++)
+    {
+        extend_memcpy(dest, source, src_ybc->y_width);
+        source += src_ybc->y_stride;
+        dest   += dst_ybc->y_stride;
+    }
+
+    source = src_ybc->u_buffer;
+    dest = dst_ybc->u_buffer;
+
+    for (row = 0; row < src_ybc->uv_height; row++)
+    {
+        extend_memcpy(dest, source, src_ybc->uv_width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    source = src_ybc->v_buffer;
+    dest = dst_ybc->v_buffer;
+
+    for (row = 0; row < src_ybc->uv_height; row++)
+    {
+        extend_memcpy(dest, source, src_ybc->uv_width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    vp8_yv12_extend_frame_borders(dst_ybc);
+
+#else
+    int row;
+    char *source, *dest;
+    int height;
+    int width;
+
+    height = src_ybc->y_height + (src_ybc->border * 2);
+    width =  src_ybc->y_width + (src_ybc->border * 2);
+    source = src_ybc->y_buffer;
+    dest = dst_ybc->y_buffer;
+
+    for (row = 0; row < height; row++)
+    {
+        extend_memcpy(dest, source, width);
+        source += src_ybc->y_stride;
+        dest   += dst_ybc->y_stride;
+    }
+
+    height = src_ybc->uv_height + (src_ybc->border);
+    width =  src_ybc->uv_width + (src_ybc->border);
+
+    source = src_ybc->u_buffer;
+    dest = dst_ybc->u_buffer;
+
+    for (row = 0; row < height; row++)
+    {
+        extend_memcpy(dest, source, width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    source = src_ybc->v_buffer;
+    dest = dst_ybc->v_buffer;
+
+    for (row = 0; row < height; row++)
+    {
+        extend_memcpy(dest, source, width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+#endif
+
+}
diff --git a/vpx_scale/dm642/bicubic_scaler_c64.c b/vpx_scale/dm642/bicubic_scaler_c64.c
new file mode 100644 (file)
index 0000000..9bd3797
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include "vpx_mem/vpx_mem.h"
+#include "vpxscale_arbitrary.h"
+
+extern BICUBIC_SCALER_STRUCT g_b_scaler;
+
+int bicubic_scale_c64(int in_width, int in_height, int in_stride,
+                      int out_width, int out_height, int out_stride,
+                      unsigned char *input_image, unsigned char *output_image)
+{
+    short *restrict l_w, * restrict l_h;
+    short *restrict c_w, * restrict c_h;
+    unsigned char *restrict ip, * restrict op, *restrict op_w;
+    unsigned char *restrict hbuf;
+    int h, w, lw, lh;
+    int phase_offset_w, phase_offset_h;
+    double coeff;
+    int max_phase;
+
+    c_w = g_b_scaler.c_w;
+    c_h = g_b_scaler.c_h;
+
+    op = output_image;
+
+    l_w = g_b_scaler.l_w;
+    l_h = g_b_scaler.l_h;
+
+    phase_offset_h = 0;
+
+    for (h = 0; h < out_height; h++)
+    {
+        // select the row to work on
+        lh = l_h[h];
+        ip = input_image + (in_stride * lh);
+
+        coeff = _memd8_const(&c_h[phase_offset_h*4]);
+
+        // vp8_filter the row vertically into an temporary buffer.
+        //  If the phase offset == 0 then all the multiplication
+        //  is going to result in the output equalling the input.
+        //  So instead point the temporary buffer to the input.
+        //  Also handle the boundry condition of not being able to
+        //  filter that last lines.
+        if (phase_offset_h && (lh < in_height - 2))
+        {
+            hbuf = g_b_scaler.hbuf;
+
+            for (w = 0; w < in_width; w += 4)
+            {
+                int ip1, ip2, ip3, ip4;
+                int y13_12, y11_10, y23_22, y21_20, y33_32, y31_30, y43_42, y41_40;
+                int y10_20, y11_21, y12_22, y13_23, y30_40, y31_41, y32_42, y33_43;
+                int s1, s2, s3, s4;
+
+                ip1 = _mem4_const(&ip[w - in_stride]);
+                ip2 = _mem4_const(&ip[w]);
+                ip3 = _mem4_const(&ip[w + in_stride]);
+                ip4 = _mem4_const(&ip[w + 2*in_stride]);
+
+                // realignment of data.  Unpack the data so that it is in short
+                //  format instead of bytes.
+                y13_12 = _unpkhu4(ip1);
+                y11_10 = _unpklu4(ip1);
+                y23_22 = _unpkhu4(ip2);
+                y21_20 = _unpklu4(ip2);
+                y33_32 = _unpkhu4(ip3);
+                y31_30 = _unpklu4(ip3);
+                y43_42 = _unpkhu4(ip4);
+                y41_40 = _unpklu4(ip4);
+
+                // repack the data so that elements 1 and 2 are together.  this
+                //  lines up so that a dot product with the coefficients can be
+                //  done.
+                y10_20 = _pack2(y11_10, y21_20);
+                y11_21 = _packh2(y11_10, y21_20);
+                y12_22 = _pack2(y13_12, y23_22);
+                y13_23 = _packh2(y13_12, y23_22);
+
+                s1 = _dotp2(_hi(coeff), y10_20);
+                s2 = _dotp2(_hi(coeff), y11_21);
+                s3 = _dotp2(_hi(coeff), y12_22);
+                s4 = _dotp2(_hi(coeff), y13_23);
+
+                y30_40 = _pack2(y31_30, y41_40);
+                y31_41 = _packh2(y31_30, y41_40);
+                y32_42 = _pack2(y33_32, y43_42);
+                y33_43 = _packh2(y33_32, y43_42);
+
+                // now repack elements 3 and 4 together.
+                s1 += _dotp2(_lo(coeff), y30_40);
+                s2 += _dotp2(_lo(coeff), y31_41);
+                s3 += _dotp2(_lo(coeff), y32_42);
+                s4 += _dotp2(_lo(coeff), y33_43);
+
+                s1 = s1 >> 12;
+                s2 = s2 >> 12;
+                s3 = s3 >> 12;
+                s4 = s4 >> 12;
+
+                s1 = _pack2(s2, s1);
+                s2 = _pack2(s4, s3);
+
+                _amem4(&hbuf[w])  = _spacku4(s2, s1);
+            }
+        }
+        else
+            hbuf = ip;
+
+        // increase the phase offset for the next time around.
+        if (++phase_offset_h >= g_b_scaler.nh)
+            phase_offset_h = 0;
+
+        op_w = op;
+
+        // will never be able to interpolate first pixel, so just copy it
+        // over here.
+        phase_offset_w = 1;
+        *op_w++ = hbuf[0];
+
+        if (1 >= g_b_scaler.nw) phase_offset_w = 0;
+
+        max_phase = g_b_scaler.nw;
+
+        for (w = 1; w < out_width; w++)
+        {
+            double coefficients;
+            int hbuf_high, hbuf_low, hbuf_both;
+            int sum_high, sum_low, sum;
+
+            // get the index to use to expand the image
+            lw = l_w[w];
+            coefficients = _amemd8_const(&c_w[phase_offset_w*4]);
+            hbuf_both = _mem4_const(&hbuf[lw-1]);
+
+            hbuf_high = _unpkhu4(hbuf_both);
+            hbuf_low  = _unpklu4(hbuf_both);
+
+            sum_high = _dotp2(_hi(coefficients), hbuf_high);
+            sum_low  = _dotp2(_lo(coefficients), hbuf_low);
+
+            sum = (sum_high + sum_low) >> 12;
+
+            if (++phase_offset_w >= max_phase)
+                phase_offset_w = 0;
+
+            if ((lw + 2) >= in_width)
+                sum = hbuf[lw];
+
+            *op_w++ = sum;
+        }
+
+        op += out_stride;
+    }
+
+    return 0;
+}
+
+void bicubic_scale_frame_c64(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
+                             int new_width, int new_height)
+{
+
+    dst->y_width = new_width;
+    dst->y_height = new_height;
+    dst->uv_width = new_width / 2;
+    dst->uv_height = new_height / 2;
+
+    dst->y_stride = dst->y_width;
+    dst->uv_stride = dst->uv_width;
+
+    bicubic_scale_c64(src->y_width, src->y_height, src->y_stride,
+                      new_width, new_height, dst->y_stride,
+                      src->y_buffer, dst->y_buffer);
+
+    bicubic_scale_c64(src->uv_width, src->uv_height, src->uv_stride,
+                      new_width / 2, new_height / 2, dst->uv_stride,
+                      src->u_buffer, dst->u_buffer);
+
+    bicubic_scale_c64(src->uv_width, src->uv_height, src->uv_stride,
+                      new_width / 2, new_height / 2, dst->uv_stride,
+                      src->v_buffer, dst->v_buffer);
+}
diff --git a/vpx_scale/dm642/gen_scalers_c64.c b/vpx_scale/dm642/gen_scalers_c64.c
new file mode 100644 (file)
index 0000000..2126a75
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     gen_scalers.c
+ *
+ *   Description  :     Generic image scaling functions.
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/vpxscale.h"
+
+/****************************************************************************
+*  Imports
+****************************************************************************/
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_4_5_scale_c4
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 4 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_4_5_scale_c64
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned i;
+    unsigned int ba, cb, dc, ed;
+    unsigned char *restrict des = dest;
+    unsigned int *restrict src = (unsigned int *)source;
+    unsigned int const_51_205, const_102_154,
+             const_205_51, const_154_102;
+
+    unsigned int src_current, src_next;
+
+    (void) dest_width;
+
+    // Constants that are to be used for the filtering.  For
+    //  best speed we are going to want to right shift by 16.
+    //  In the generic version they were shift by 8, so put
+    //  an extra 8 in now so that 16 will come out later.
+    const_51_205 = 0x3300CD00; //_pack2 (51 << 8, 205 << 8);
+    const_205_51 = 0xCD003300; //_pack2 (205 << 8, 51 << 8);
+    const_102_154 = 0x66009A00; //_pack2 (102 << 8, 154 << 8);
+    const_154_102 = 0x9A006600; //_pack2 (154 << 8, 102 << 8);
+
+    // 5 points are needed to filter to give 5 output points.
+    //  A load can pull up 4 at a time, and one needs to be
+    //  "borrowed" from the next set of data.  So instead of
+    //  loading those 5 points each time, "steal" a point from
+    //  the next set and only load up 4 each time through.
+    src_current = _mem4(src);
+
+    for (i = 0; i < source_width - 4; i += 4)
+    {
+        src_next = _mem4(src++);
+
+        // Reorder the data so that it is ready for the
+        //  dot product.
+        ba = _unpklu4(src_current);
+        cb = _unpkhu4(_rotl(src_current, 8));
+        dc = _unpkhu4(src_current);
+        ed = _unpkhu4(_shrmb(src_next, src_current));
+
+        // Use the dot product with round and shift.
+        des [0] = src_current & 0xff;
+        des [1] = _dotprsu2(ba, const_205_51);
+        des [2] = _dotprsu2(cb, const_154_102);
+        des [3] = _dotprsu2(dc, const_102_154);
+        des [4] = _dotprsu2(ed, const_51_205);
+
+        des += 5;
+
+        // reuse loaded vales next time around.
+        src_current = src_next;
+    }
+
+    // vp8_filter the last set of points.  Normally a point from the next set
+    //  would be used, but there is no next set, so just fill.
+    ba = _unpklu4(src_current);
+    cb = _unpkhu4(_rotl(src_current, 8));
+    dc = _unpkhu4(src_current);
+
+    des [0] = src_current & 0xff;
+    des [1] = _dotprsu2(ba, const_205_51);
+    des [2] = _dotprsu2(cb, const_154_102);
+    des [3] = _dotprsu2(dc, const_102_154);
+    des [4] = src_current & 0xff;
+
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_4_5_scale_c64
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+ *                  height of the band scaled is 4-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+static
+void vertical_band_4_5_scale_c64(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d, e;
+    unsigned int ba, cb, dc, ed;
+    unsigned char *restrict src = dest;
+    unsigned char *restrict des = dest;
+    unsigned int const_51_205, const_102_154,
+             const_205_51, const_154_102;
+
+    const_51_205 = 0x3300CD00; //_pack2 (51 << 8, 205 << 8);
+    const_205_51 = 0xCD003300; //_pack2 (205 << 8, 51 << 8);
+    const_102_154 = 0x66009A00; //_pack2 (102 << 8, 154 << 8);
+    const_154_102 = 0x9A006600; //_pack2 (154 << 8, 102 << 8);
+
+    // Force a loop unroll here so that there is not such a
+    //  dependancy.
+    a = src [0];
+    b = src [dest_pitch];
+    c = src [dest_pitch*2];
+    d = src [dest_pitch*3];
+    e = src [dest_pitch*5];
+    src ++;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        ba = _pack2(b, a);
+        cb = _pack2(c, b);
+        dc = _pack2(d, c);
+        ed = _pack2(e, d);
+
+        a = src [0];
+        b = src [dest_pitch];
+        c = src [dest_pitch*2];
+        d = src [dest_pitch*3];
+        e = src [dest_pitch*5];
+        src ++;
+
+        des [dest_pitch] = _dotprsu2(ba, const_205_51);
+        des [dest_pitch*2] = _dotprsu2(cb, const_154_102);
+        des [dest_pitch*3] = _dotprsu2(dc, const_102_154);
+        des [dest_pitch*4] = _dotprsu2(ed, const_51_205);
+
+        des ++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_4_5_scale_c64
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 4 to 5. The
+ *                  height of the band scaled is 4-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_4_5_scale_c64(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d;
+    unsigned int ba, cb, dc;
+    unsigned char *restrict src = dest;
+    unsigned char *restrict des = dest;
+    unsigned int const_102_154, const_205_51, const_154_102;
+
+    const_205_51 = 0xCD003300; //_pack2 (205 << 8, 51 << 8);
+    const_102_154 = 0x66009A00; //_pack2 (102 << 8, 154 << 8);
+    const_154_102 = 0x9A006600; //_pack2 (154 << 8, 102 << 8);
+
+    a = src [0];
+    b = src [dest_pitch];
+    c = src [dest_pitch*2];
+    d = src [dest_pitch*3];
+    src ++;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        ba = _pack2(b, a);
+        cb = _pack2(c, b);
+        dc = _pack2(d, c);
+
+        a = src [0];
+        b = src [dest_pitch];
+        c = src [dest_pitch*2];
+        d = src [dest_pitch*3];
+        src ++;
+
+        des [dest_pitch] = _dotprsu2(ba, const_205_51);
+        des [dest_pitch*2] = _dotprsu2(cb, const_154_102);
+        des [dest_pitch*3] = _dotprsu2(dc, const_102_154);
+        des [dest_pitch*4] = (unsigned char) d;
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_3_5_scale_c64
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 3 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ *
+ ****************************************************************************/
+static
+void horizontal_line_3_5_scale_c64
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int ba, cb, dc;
+    unsigned int src_current;
+    unsigned char *restrict des = dest;
+    unsigned char *restrict src = (unsigned char *)source;
+    unsigned int const_51_205, const_102_154,
+             const_205_51, const_154_102;
+
+    (void) dest_width;
+
+    const_51_205 = 0x3300CD00; //_pack2 (51 << 8, 205 << 8);
+    const_205_51 = 0xCD003300; //_pack2 (205 << 8, 51 << 8);
+    const_102_154 = 0x66009A00; //_pack2 (102 << 8, 154 << 8);
+    const_154_102 = 0x9A006600; //_pack2 (154 << 8, 102 << 8);
+
+    for (i = 0; i < source_width - 3; i += 3)
+    {
+        src_current = _mem4(src);
+
+        // Reorder the data so that it is ready for the
+        //  dot product.
+        ba = _unpklu4(src_current);
+        cb = _unpkhu4(_rotl(src_current, 8));
+        dc = _unpkhu4(src_current);
+
+        des [0] = src_current & 0xff;
+        des [1] = _dotprsu2(ba, const_154_102);
+        des [2] = _dotprsu2(cb, const_51_205);
+        des [3] = _dotprsu2(cb, const_205_51);
+        des [4] = _dotprsu2(dc, const_102_154);
+
+        src += 3;
+        des += 5;
+    }
+
+    src_current = _mem4(src);
+
+    ba = _unpklu4(src_current);
+    cb = _unpkhu4(_rotl(src_current, 8));
+    dc = _unpkhu4(src_current);
+
+
+    des [0] = src_current & 0xff;
+    des [1] = _dotprsu2(ba, const_154_102);
+    des [2] = _dotprsu2(cb, const_51_205);
+    des [3] = _dotprsu2(cb, const_205_51);
+    des [4] = dc & 0xff;
+
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_3_5_scale_c64
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+static
+void vertical_band_3_5_scale_c64(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d;
+    unsigned int ba, cb, dc;
+    unsigned char *restrict src = dest;
+    unsigned char *restrict des = dest;
+    unsigned int const_51_205, const_102_154,
+             const_205_51, const_154_102;
+
+    const_51_205 = 0x3300CD00; //_pack2 (51 << 8, 205 << 8);
+    const_205_51 = 0xCD003300; //_pack2 (205 << 8, 51 << 8);
+    const_102_154 = 0x66009A00; //_pack2 (102 << 8, 154 << 8);
+    const_154_102 = 0x9A006600; //_pack2 (154 << 8, 102 << 8);
+
+    a = src [0];
+    b = src [dest_pitch];
+    c = src [dest_pitch*2];
+    d = src [dest_pitch*5];
+    src ++;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        ba = _pack2(b, a);
+        cb = _pack2(c, b);
+        dc = _pack2(d, c);
+
+        a = src [0];
+        b = src [dest_pitch];
+        c = src [dest_pitch*2];
+        d = src [dest_pitch*5];
+        src ++;
+
+        des [dest_pitch]   = _dotprsu2(ba, const_154_102);
+        des [dest_pitch*2] = _dotprsu2(cb, const_51_205);
+        des [dest_pitch*3] = _dotprsu2(cb, const_205_51);
+        des [dest_pitch*4] = _dotprsu2(dc, const_102_154);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_3_5_scale_c64
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 3 to 5. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_3_5_scale_c64(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned int ba, cb;
+    unsigned char *restrict src = dest;
+    unsigned char *restrict des = dest;
+    unsigned int const_51_205, const_205_51, const_154_102;
+
+    const_51_205 = 0x3300CD00; //_pack2 (51 << 8, 205 << 8);
+    const_205_51 = 0xCD003300; //_pack2 (205 << 8, 51 << 8);
+    const_154_102 = 0x9A006600; //_pack2 (154 << 8, 102 << 8);
+
+    a = src [0];
+    b = src [dest_pitch];
+    c = src [dest_pitch*2];
+    src ++;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        ba = _pack2(b, a);
+        cb = _pack2(c, b);
+
+        a = src [0];
+        b = src [dest_pitch];
+        c = src [dest_pitch*2];
+        src ++;
+
+        des [dest_pitch]   = _dotprsu2(ba, const_154_102);
+        des [dest_pitch*2] = _dotprsu2(cb, const_51_205);
+        des [dest_pitch*3] = _dotprsu2(cb, const_205_51);
+        des [dest_pitch*4] = (unsigned char)(c) ;
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_1_2_scale_c64
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 1 to 2.
+ *
+ *  SPECIAL NOTES : source width must be a multiple of 4.
+ *
+ ****************************************************************************/
+void horizontal_line_1_2_scale_c64
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned char *restrict des = dest;
+    unsigned char *restrict src = (unsigned char *)source;
+    unsigned int src7_4i, src4_1i, src3_0i;
+    unsigned int a4_0i, ahi, alo;
+    double src7_0d, src3_0d;
+    const unsigned int k01 = 0x01010101;
+
+    for (i = 0; i < source_width / 4; i += 1)
+    {
+        // Load up the data from src.  Here a wide load is
+        //  used to get 8 bytes at once, only 5 will be used
+        //  for the actual computation.
+        src7_0d = _memd8(src);
+        src3_0i = _lo(src7_0d);
+        src7_4i = _hi(src7_0d);
+
+        // Need to average between points.  Shift byte 5 into
+        //  the lower word.  This will result in bytes 5-1
+        //  averaged with 4-0.
+        src4_1i = _shrmb(src7_4i, src3_0i);
+        a4_0i = _avgu4(src4_1i, src3_0i);
+
+        // Expand the data out. Could do an unpack, however
+        //  all but the multiply units are getting pretty hard
+        //  here the multiply unit can take some of the computations.
+        src3_0d = _mpyu4(src3_0i, k01);
+
+        // The averages need to be unpacked so that they are in 16
+        //  bit form and will be able to be interleaved with the
+        //  original data
+        ahi = _unpkhu4(a4_0i);
+        alo = _unpklu4(a4_0i);
+
+        ahi = _swap4(ahi);
+        alo = _swap4(alo);
+
+        // Mix the average result in with the orginal data.
+        ahi = _hi(src3_0d) | ahi;
+        alo = _lo(src3_0d) | alo;
+
+        _memd8(des) = _itod(ahi, alo);
+
+        des += 8;
+        src += 4;
+    }
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_1_2_scale_c64
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+ *                  height of the band scaled is 1-pixel.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *                  Destination width must be a multiple of 4.  Because the
+ *                  intput must be, therefore the output must be.
+ *
+ ****************************************************************************/
+static
+void vertical_band_1_2_scale_c64(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b;
+    unsigned int *restrict line_a = (unsigned int *)dest;
+    unsigned int *restrict line_b = (unsigned int *)(dest + (dest_pitch * 2));
+    unsigned int *restrict des = (unsigned int *)(dest + dest_pitch);
+
+    for (i = 0; i < dest_width / 4; i++)
+    {
+        a = _mem4(line_a++);
+        b = _mem4(line_b++);
+
+        _mem4(des++) = _avgu4(a, b);
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_1_2_scale_c64
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 1 to 2. The
+ *                  height of the band scaled is 1-pixel.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.  Again, width must be a multiple of 4.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_1_2_scale_c64(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int *restrict src = (unsigned int *)dest;
+    unsigned int *restrict des = (unsigned int *)(dest + dest_pitch);
+
+    for (i = 0; i < dest_width / 4; ++i)
+    {
+        _mem4(des++) = _mem4(src++);
+    }
+}
+
+void
+register_generic_scalers(void)
+{
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_c64;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_c64;
+    vp8_last_vertical_band_1_2_scale      = last_vertical_band_1_2_scale_c64;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_c64;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_c64;
+    vp8_last_vertical_band_3_5_scale      = last_vertical_band_3_5_scale_c64;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_c64;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_c64;
+    vp8_last_vertical_band_4_5_scale      = last_vertical_band_4_5_scale_c64;
+}
diff --git a/vpx_scale/dm642/yv12extend.c b/vpx_scale/dm642/yv12extend.c
new file mode 100644 (file)
index 0000000..ca25a5f
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     yv12extend.c
+ *
+ *   Description  :
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+//#include <stdlib.h>
+#include "csl_dat.h"
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+#define UINT8 unsigned char
+#define UINT32 unsigned int
+
+
+static inline
+void copy_yleft_right_border(
+    UINT8 *restrict src_ptr1,
+    UINT8 *restrict src_ptr2,
+    UINT8 *restrict dest_ptr1,
+    UINT8 *restrict dest_ptr2,
+    UINT32  plane_height,
+    UINT32  plane_stride
+)
+{
+    UINT32 left, right, left2, left4, right2, right4;
+    double dl, dr;
+    int i;
+
+#pragma MUST_ITERATE(16,16,16)
+
+    for (i = 0; i < plane_height; i++)
+    {
+        left  = src_ptr1[0];
+        right = src_ptr2[0];
+
+        left2 = _pack2(left, left);
+        left4 = _packl4(left2, left2);
+
+        right2 = _pack2(right, right);
+        right4 = _packl4(right2, right2);
+
+        dl = _itod(left4, left4);
+        dr = _itod(right4, right4);
+
+        _amemd8(&dest_ptr1[ 0]) = dl;
+        _amemd8(&dest_ptr2[ 0]) = dr;
+
+        _amemd8(&dest_ptr1[ 8]) = dl;
+        _amemd8(&dest_ptr2[ 8]) = dr;
+
+        _amemd8(&dest_ptr1[16]) = dl;
+        _amemd8(&dest_ptr2[16]) = dr;
+
+        _amemd8(&dest_ptr1[24]) = dl;
+        _amemd8(&dest_ptr2[24]) = dr;
+
+        _amemd8(&dest_ptr1[32]) = dl;
+        _amemd8(&dest_ptr2[32]) = dr;
+
+        _amemd8(&dest_ptr1[40]) = dl;
+        _amemd8(&dest_ptr2[40]) = dr;
+
+
+        src_ptr1 += plane_stride;
+        src_ptr2 += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+}
+/****************************************************************************
+ *
+ *
+ ****************************************************************************/
+static
+void copy_uvleft_right_border(
+    UINT8 *restrict src_ptr1,
+    UINT8 *restrict src_ptr2,
+    UINT8 *restrict dest_ptr1,
+    UINT8 *restrict dest_ptr2,
+    UINT32  plane_height,
+    UINT32  plane_stride
+)
+{
+    UINT32 left, right, left2, left4, right2, right4;
+    double dl, dr;
+    int i;
+
+#pragma MUST_ITERATE(8,8 ,8)
+
+    for (i = 0; i < plane_height; i++)
+    {
+        left  = src_ptr1[0];
+        right = src_ptr2[0];
+
+        left2 = _pack2(left, left);
+        left4 = _packl4(left2, left2);
+
+        right2 = _pack2(right, right);
+        right4 = _packl4(right2, right2);
+
+        dl = _itod(left4, left4);
+        dr = _itod(right4, right4);
+
+        _amemd8(&dest_ptr1[ 0]) = dl;
+        _amemd8(&dest_ptr2[ 0]) = dr;
+
+        _amemd8(&dest_ptr1[ 8]) = dl;
+        _amemd8(&dest_ptr2[ 8]) = dr;
+
+        _amemd8(&dest_ptr1[16]) = dl;
+        _amemd8(&dest_ptr2[16]) = dr;
+
+
+        src_ptr1 += plane_stride;
+        src_ptr2 += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+}
+/****************************************************************************
+ *
+ ****************************************************************************/
+void
+vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+#if 1
+    // copy the left and right most columns out
+    src_ptr1 = ybf->y_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+    copy_yleft_right_border(src_ptr1, src_ptr2, dest_ptr1, dest_ptr2, plane_height, plane_stride);
+#endif
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    plane_stride /= 2;
+    plane_height /= 2;
+    plane_width /= 2;
+    Border /= 2;
+
+    /***********/
+    /* U Plane */
+    /***********/
+#if 1
+    // copy the left and right most columns out
+    src_ptr1 = ybf->u_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    copy_uvleft_right_border(src_ptr1, src_ptr2, dest_ptr1, dest_ptr2, plane_height, plane_stride);
+
+
+#endif
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->u_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    /***********/
+    /* V Plane */
+    /***********/
+#if 1
+    // copy the left and right most columns out
+    src_ptr1 = ybf->v_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    copy_uvleft_right_border(src_ptr1, src_ptr2, dest_ptr1, dest_ptr2, plane_height, plane_stride);
+
+#endif
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->v_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+}
+/****************************************************************************
+ *
+ ****************************************************************************/
+void
+vpxyv12_extend_frame_tbborders(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+    int tid1, tid2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        dat_copy(src_ptr1, dest_ptr1, plane_stride);
+        dat_copy(src_ptr2, dest_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    plane_stride /= 2;
+    plane_height /= 2;
+    plane_width /= 2;
+    Border /= 2;
+
+    /***********/
+    /* U Plane */
+    /***********/
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->u_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        dat_copy(src_ptr1, dest_ptr1, plane_stride);
+        dat_copy(src_ptr2, dest_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    /***********/
+    /* V Plane */
+    /***********/
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->v_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        tid1 = dat_copy(src_ptr1, dest_ptr1, plane_stride);
+        tid2 = dat_copy(src_ptr2, dest_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    dat_wait(tid1);
+    dat_wait(tid2);
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_yv12_copy_frame
+ *
+ *  INPUTS        :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies the source image into the destination image and
+ *                  updates the destination's UMV borders.  Because the
+ *                  borders have been update prior to this so the whole frame
+ *                  is copied, borders and all.  This is also to circumvent
+ *                  using copy_left_right Border functions when copying data
+ *                  between L2 and main memory.  When that occurs a cache
+ *                  clean needs to be done, which would require invalidating
+ *                  an entire frame.
+ *
+ *  SPECIAL NOTES : The frames are assumed to be identical in size.
+ *
+ ****************************************************************************/
+void
+vpxyv12_copy_frame_dma(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    int yheight, uv_height;
+    int ystride, uv_stride;
+    int border;
+    int yoffset, uvoffset;
+
+    border = src_ybc->border;
+    yheight = src_ybc->y_height;
+    uv_height = src_ybc->uv_height;
+
+    ystride = src_ybc->y_stride;
+    uv_stride = src_ybc->uv_stride;
+
+    yoffset = border * (ystride + 1);
+    uvoffset = border / 2 * (uv_stride + 1);
+
+    dat_copy2d(DAT_2D2D,
+               src_ybc->y_buffer - yoffset,
+               dst_ybc->y_buffer - yoffset,
+               ystride,
+               yheight + 2 * border,
+               ystride);
+    dat_copy2d(DAT_2D2D,
+               src_ybc->u_buffer - uvoffset,
+               dst_ybc->u_buffer - uvoffset,
+               uv_stride,
+               uv_height + border,
+               uv_stride);
+    dat_copy2d(DAT_2D2D,
+               src_ybc->v_buffer - uvoffset,
+               dst_ybc->v_buffer - uvoffset,
+               uv_stride,
+               uv_height + border,
+               uv_stride);
+
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_yv12_copy_frame
+ *
+ *  INPUTS        :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies the source image into the destination image and
+ *                  updates the destination's UMV borders.
+ *
+ *  SPECIAL NOTES : The frames are assumed to be identical in size.
+ *
+ ****************************************************************************/
+void
+vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    int row;
+    unsigned char *source, *dest;
+
+    source = src_ybc->y_buffer;
+    dest = dst_ybc->y_buffer;
+
+    for (row = 0; row < src_ybc->y_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->y_width);
+        source += src_ybc->y_stride;
+        dest   += dst_ybc->y_stride;
+    }
+
+    source = src_ybc->u_buffer;
+    dest = dst_ybc->u_buffer;
+
+    for (row = 0; row < src_ybc->uv_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->uv_width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    source = src_ybc->v_buffer;
+    dest = dst_ybc->v_buffer;
+
+    for (row = 0; row < src_ybc->uv_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->uv_width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    vp8_yv12_extend_frame_borders(dst_ybc);
+}
diff --git a/vpx_scale/generic/bicubic_scaler.c b/vpx_scale/generic/bicubic_scaler.c
new file mode 100644 (file)
index 0000000..e3c2b4a
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include "vpx_mem/vpx_mem.h"
+#include "vpxscale_arbitrary.h"
+
+#define FIXED_POINT
+
+#define MAX_IN_WIDTH        800
+#define MAX_IN_HEIGHT       600
+#define MAX_OUT_WIDTH       800
+#define MAX_OUT_HEIGHT      600
+#define MAX_OUT_DIMENSION   ((MAX_OUT_WIDTH > MAX_OUT_HEIGHT) ? \
+                             MAX_OUT_WIDTH : MAX_OUT_HEIGHT)
+
+BICUBIC_SCALER_STRUCT g_b_scaler;
+static int g_first_time = 1;
+
+#pragma DATA_SECTION(g_hbuf, "VP6_HEAP")
+#pragma DATA_ALIGN (g_hbuf, 32);
+unsigned char g_hbuf[MAX_OUT_DIMENSION];
+
+#pragma DATA_SECTION(g_hbuf_uv, "VP6_HEAP")
+#pragma DATA_ALIGN (g_hbuf_uv, 32);
+unsigned char g_hbuf_uv[MAX_OUT_DIMENSION];
+
+
+#ifdef FIXED_POINT
+static int a_i = 0.6 * 65536;
+#else
+static float a = -0.6;
+#endif
+
+#ifdef FIXED_POINT
+//         3     2
+// C0 = a*t - a*t
+//
+static INLINE short c0_fixed(unsigned int t)
+{
+    // put t in Q16 notation
+    unsigned short v1, v2;
+
+    // Q16
+    v1 = (a_i * t) >> 16;
+    v1 = (v1 * t) >> 16;
+
+    // Q16
+    v2 = (a_i * t) >> 16;
+    v2 = (v2 * t) >> 16;
+    v2 = (v2 * t) >> 16;
+
+    // Q12
+    return -((v1 - v2) >> 4);
+}
+
+//                     2          3
+// C1 = a*t + (3-2*a)*t  - (2-a)*t
+//
+static INLINE short c1_fixed(unsigned int t)
+{
+    unsigned short v1, v2, v3;
+    unsigned short two, three;
+
+    // Q16
+    v1 = (a_i * t) >> 16;
+
+    // Q13
+    two = 2 << 13;
+    v2 = two - (a_i >> 3);
+    v2 = (v2 * t) >> 16;
+    v2 = (v2 * t) >> 16;
+    v2 = (v2 * t) >> 16;
+
+    // Q13
+    three = 3 << 13;
+    v3 = three - (2 * (a_i >> 3));
+    v3 = (v3 * t) >> 16;
+    v3 = (v3 * t) >> 16;
+
+    // Q12
+    return (((v1 >> 3) - v2 + v3) >> 1);
+
+}
+
+//                 2          3
+// C2 = 1 - (3-a)*t  + (2-a)*t
+//
+static INLINE short c2_fixed(unsigned int t)
+{
+    unsigned short v1, v2, v3;
+    unsigned short two, three;
+
+    // Q13
+    v1 = 1 << 13;
+
+    // Q13
+    three = 3 << 13;
+    v2 = three - (a_i >> 3);
+    v2 = (v2 * t) >> 16;
+    v2 = (v2 * t) >> 16;
+
+    // Q13
+    two = 2 << 13;
+    v3 = two - (a_i >> 3);
+    v3 = (v3 * t) >> 16;
+    v3 = (v3 * t) >> 16;
+    v3 = (v3 * t) >> 16;
+
+    // Q12
+    return (v1 - v2 + v3) >> 1;
+}
+
+//                 2      3
+// C3 = a*t - 2*a*t  + a*t
+//
+static INLINE short c3_fixed(unsigned int t)
+{
+    int v1, v2, v3;
+
+    // Q16
+    v1 = (a_i * t) >> 16;
+
+    // Q15
+    v2 = 2 * (a_i >> 1);
+    v2 = (v2 * t) >> 16;
+    v2 = (v2 * t) >> 16;
+
+    // Q16
+    v3 = (a_i * t) >> 16;
+    v3 = (v3 * t) >> 16;
+    v3 = (v3 * t) >> 16;
+
+    // Q12
+    return ((v2 - (v1 >> 1) - (v3 >> 1)) >> 3);
+}
+#else
+//          3     2
+// C0 = -a*t + a*t
+//
+float C0(float t)
+{
+    return -a * t * t * t + a * t * t;
+}
+
+//                      2          3
+// C1 = -a*t + (2*a+3)*t  - (a+2)*t
+//
+float C1(float t)
+{
+    return -(a + 2.0f) * t * t * t + (2.0f * a + 3.0f) * t * t - a * t;
+}
+
+//                 2          3
+// C2 = 1 - (a+3)*t  + (a+2)*t
+//
+float C2(float t)
+{
+    return (a + 2.0f) * t * t * t - (a + 3.0f) * t * t + 1.0f;
+}
+
+//                 2      3
+// C3 = a*t - 2*a*t  + a*t
+//
+float C3(float t)
+{
+    return a * t * t * t - 2.0f * a * t * t + a * t;
+}
+#endif
+
+#if 0
+int compare_real_fixed()
+{
+    int i, errors = 0;
+    float mult = 1.0 / 10000.0;
+    unsigned int fixed_mult = mult * 4294967296;//65536;
+    unsigned int phase_offset_int;
+    float phase_offset_real;
+
+    for (i = 0; i < 10000; i++)
+    {
+        int fixed0, fixed1, fixed2, fixed3, fixed_total;
+        int real0, real1, real2, real3, real_total;
+
+        phase_offset_real = (float)i * mult;
+        phase_offset_int = (fixed_mult * i) >> 16;
+//      phase_offset_int = phase_offset_real * 65536;
+
+        fixed0 = c0_fixed(phase_offset_int);
+        real0 = C0(phase_offset_real) * 4096.0;
+
+        if ((abs(fixed0) > (abs(real0) + 1)) || (abs(fixed0) < (abs(real0) - 1)))
+            errors++;
+
+        fixed1 = c1_fixed(phase_offset_int);
+        real1 = C1(phase_offset_real) * 4096.0;
+
+        if ((abs(fixed1) > (abs(real1) + 1)) || (abs(fixed1) < (abs(real1) - 1)))
+            errors++;
+
+        fixed2 = c2_fixed(phase_offset_int);
+        real2 = C2(phase_offset_real) * 4096.0;
+
+        if ((abs(fixed2) > (abs(real2) + 1)) || (abs(fixed2) < (abs(real2) - 1)))
+            errors++;
+
+        fixed3 = c3_fixed(phase_offset_int);
+        real3 = C3(phase_offset_real) * 4096.0;
+
+        if ((abs(fixed3) > (abs(real3) + 1)) || (abs(fixed3) < (abs(real3) - 1)))
+            errors++;
+
+        fixed_total = fixed0 + fixed1 + fixed2 + fixed3;
+        real_total = real0 + real1 + real2 + real3;
+
+        if ((fixed_total > 4097) || (fixed_total < 4094))
+            errors ++;
+
+        if ((real_total > 4097) || (real_total < 4095))
+            errors ++;
+    }
+
+    return errors;
+}
+#endif
+
+// Find greatest common denominator between two integers.  Method used here is
+//  slow compared to Euclid's algorithm, but does not require any division.
+int gcd(int a, int b)
+{
+    // Problem with this algorithm is that if a or b = 0 this function
+    //  will never exit.  Don't want to return 0 because any computation
+    //  that was based on a common denoninator and tried to reduce by
+    //  dividing by 0 would fail.  Best solution that could be thought of
+    //  would to be fail by returing a 1;
+    if (a <= 0 || b <= 0)
+        return 1;
+
+    while (a != b)
+    {
+        if (b > a)
+            b = b - a;
+        else
+        {
+            int tmp = a;//swap large and
+            a = b; //small
+            b = tmp;
+        }
+    }
+
+    return b;
+}
+
+void bicubic_coefficient_init()
+{
+    vpx_memset(&g_b_scaler, 0, sizeof(BICUBIC_SCALER_STRUCT));
+    g_first_time = 0;
+}
+
+void bicubic_coefficient_destroy()
+{
+    if (!g_first_time)
+    {
+        if (g_b_scaler.l_w) vpx_free(g_b_scaler.l_w);
+
+        if (g_b_scaler.l_h) vpx_free(g_b_scaler.l_h);
+
+        if (g_b_scaler.l_h_uv) vpx_free(g_b_scaler.l_h_uv);
+
+        if (g_b_scaler.c_w) vpx_free(g_b_scaler.c_w);
+
+        if (g_b_scaler.c_h) vpx_free(g_b_scaler.c_h);
+
+        if (g_b_scaler.c_h_uv) vpx_free(g_b_scaler.c_h_uv);
+
+        vpx_memset(&g_b_scaler, 0, sizeof(BICUBIC_SCALER_STRUCT));
+    }
+}
+
+// Create the coeffients that will be used for the cubic interpolation.
+//  Because scaling does not have to be equal in the vertical and horizontal
+//  regimes the phase offsets will be different.  There are 4 coefficents
+//  for each point, two on each side.  The layout is that there are the
+//  4 coefficents for each phase in the array and then the next phase.
+int bicubic_coefficient_setup(int in_width, int in_height, int out_width, int out_height)
+{
+    int i;
+#ifdef FIXED_POINT
+    int phase_offset_int;
+    unsigned int fixed_mult;
+    int product_val = 0;
+#else
+    float phase_offset;
+#endif
+    int gcd_w, gcd_h, gcd_h_uv, d_w, d_h, d_h_uv;
+
+    if (g_first_time)
+        bicubic_coefficient_init();
+
+
+    // check to see if the coefficents have already been set up correctly
+    if ((in_width == g_b_scaler.in_width) && (in_height == g_b_scaler.in_height)
+        && (out_width == g_b_scaler.out_width) && (out_height == g_b_scaler.out_height))
+        return 0;
+
+    g_b_scaler.in_width = in_width;
+    g_b_scaler.in_height = in_height;
+    g_b_scaler.out_width = out_width;
+    g_b_scaler.out_height = out_height;
+
+    // Don't want to allow crazy scaling, just try and prevent a catastrophic
+    //  failure here.  Want to fail after setting the member functions so if
+    //  if the scaler is called the member functions will not scale.
+    if (out_width <= 0 || out_height <= 0)
+        return -1;
+
+    // reduce in/out width and height ratios using the gcd
+    gcd_w = gcd(out_width, in_width);
+    gcd_h = gcd(out_height, in_height);
+    gcd_h_uv = gcd(out_height, in_height / 2);
+
+    // the numerator width and height are to be saved in
+    //  globals so they can be used during the scaling process
+    //  without having to be recalculated.
+    g_b_scaler.nw = out_width / gcd_w;
+    d_w = in_width / gcd_w;
+
+    g_b_scaler.nh = out_height / gcd_h;
+    d_h = in_height / gcd_h;
+
+    g_b_scaler.nh_uv = out_height / gcd_h_uv;
+    d_h_uv = (in_height / 2) / gcd_h_uv;
+
+    // allocate memory for the coefficents
+    if (g_b_scaler.l_w) vpx_free(g_b_scaler.l_w);
+
+    if (g_b_scaler.l_h) vpx_free(g_b_scaler.l_h);
+
+    if (g_b_scaler.l_h_uv) vpx_free(g_b_scaler.l_h_uv);
+
+    g_b_scaler.l_w = (short *)vpx_memalign(32, out_width * 2);
+    g_b_scaler.l_h = (short *)vpx_memalign(32, out_height * 2);
+    g_b_scaler.l_h_uv = (short *)vpx_memalign(32, out_height * 2);
+
+    if (g_b_scaler.c_w) vpx_free(g_b_scaler.c_w);
+
+    if (g_b_scaler.c_h) vpx_free(g_b_scaler.c_h);
+
+    if (g_b_scaler.c_h_uv) vpx_free(g_b_scaler.c_h_uv);
+
+    g_b_scaler.c_w = (short *)vpx_memalign(32, g_b_scaler.nw * 4 * 2);
+    g_b_scaler.c_h = (short *)vpx_memalign(32, g_b_scaler.nh * 4 * 2);
+    g_b_scaler.c_h_uv = (short *)vpx_memalign(32, g_b_scaler.nh_uv * 4 * 2);
+
+    g_b_scaler.hbuf = g_hbuf;
+    g_b_scaler.hbuf_uv = g_hbuf_uv;
+
+    // Set up polyphase filter taps.  This needs to be done before
+    //  the scaling because of the floating point math required.  The
+    //  coefficients are multiplied by 2^12 so that fixed point math
+    //  can be used in the main scaling loop.
+#ifdef FIXED_POINT
+    fixed_mult = (1.0 / (float)g_b_scaler.nw) * 4294967296;
+
+    product_val = 0;
+
+    for (i = 0; i < g_b_scaler.nw; i++)
+    {
+        if (product_val > g_b_scaler.nw)
+            product_val -= g_b_scaler.nw;
+
+        phase_offset_int = (fixed_mult * product_val) >> 16;
+
+        g_b_scaler.c_w[i*4]   = c3_fixed(phase_offset_int);
+        g_b_scaler.c_w[i*4+1] = c2_fixed(phase_offset_int);
+        g_b_scaler.c_w[i*4+2] = c1_fixed(phase_offset_int);
+        g_b_scaler.c_w[i*4+3] = c0_fixed(phase_offset_int);
+
+        product_val += d_w;
+    }
+
+
+    fixed_mult = (1.0 / (float)g_b_scaler.nh) * 4294967296;
+
+    product_val = 0;
+
+    for (i = 0; i < g_b_scaler.nh; i++)
+    {
+        if (product_val > g_b_scaler.nh)
+            product_val -= g_b_scaler.nh;
+
+        phase_offset_int = (fixed_mult * product_val) >> 16;
+
+        g_b_scaler.c_h[i*4]   = c0_fixed(phase_offset_int);
+        g_b_scaler.c_h[i*4+1] = c1_fixed(phase_offset_int);
+        g_b_scaler.c_h[i*4+2] = c2_fixed(phase_offset_int);
+        g_b_scaler.c_h[i*4+3] = c3_fixed(phase_offset_int);
+
+        product_val += d_h;
+    }
+
+    fixed_mult = (1.0 / (float)g_b_scaler.nh_uv) * 4294967296;
+
+    product_val = 0;
+
+    for (i = 0; i < g_b_scaler.nh_uv; i++)
+    {
+        if (product_val > g_b_scaler.nh_uv)
+            product_val -= g_b_scaler.nh_uv;
+
+        phase_offset_int = (fixed_mult * product_val) >> 16;
+
+        g_b_scaler.c_h_uv[i*4]   = c0_fixed(phase_offset_int);
+        g_b_scaler.c_h_uv[i*4+1] = c1_fixed(phase_offset_int);
+        g_b_scaler.c_h_uv[i*4+2] = c2_fixed(phase_offset_int);
+        g_b_scaler.c_h_uv[i*4+3] = c3_fixed(phase_offset_int);
+
+        product_val += d_h_uv;
+    }
+
+#else
+
+    for (i = 0; i < g_nw; i++)
+    {
+        phase_offset = (float)((i * d_w) % g_nw) / (float)g_nw;
+        g_c_w[i*4]   = (C3(phase_offset) * 4096.0);
+        g_c_w[i*4+1] = (C2(phase_offset) * 4096.0);
+        g_c_w[i*4+2] = (C1(phase_offset) * 4096.0);
+        g_c_w[i*4+3] = (C0(phase_offset) * 4096.0);
+    }
+
+    for (i = 0; i < g_nh; i++)
+    {
+        phase_offset = (float)((i * d_h) % g_nh) / (float)g_nh;
+        g_c_h[i*4]   = (C0(phase_offset) * 4096.0);
+        g_c_h[i*4+1] = (C1(phase_offset) * 4096.0);
+        g_c_h[i*4+2] = (C2(phase_offset) * 4096.0);
+        g_c_h[i*4+3] = (C3(phase_offset) * 4096.0);
+    }
+
+    for (i = 0; i < g_nh_uv; i++)
+    {
+        phase_offset = (float)((i * d_h_uv) % g_nh_uv) / (float)g_nh_uv;
+        g_c_h_uv[i*4]   = (C0(phase_offset) * 4096.0);
+        g_c_h_uv[i*4+1] = (C1(phase_offset) * 4096.0);
+        g_c_h_uv[i*4+2] = (C2(phase_offset) * 4096.0);
+        g_c_h_uv[i*4+3] = (C3(phase_offset) * 4096.0);
+    }
+
+#endif
+
+    // Create an array that corresponds input lines to output lines.
+    //  This doesn't require floating point math, but it does require
+    //  a division and because hardware division is not present that
+    //  is a call.
+    for (i = 0; i < out_width; i++)
+    {
+        g_b_scaler.l_w[i] = (i * d_w) / g_b_scaler.nw;
+
+        if ((g_b_scaler.l_w[i] + 2) <= in_width)
+            g_b_scaler.max_usable_out_width = i;
+
+    }
+
+    for (i = 0; i < out_height + 1; i++)
+    {
+        g_b_scaler.l_h[i] = (i * d_h) / g_b_scaler.nh;
+        g_b_scaler.l_h_uv[i] = (i * d_h_uv) / g_b_scaler.nh_uv;
+    }
+
+    return 0;
+}
+
+int bicubic_scale(int in_width, int in_height, int in_stride,
+                  int out_width, int out_height, int out_stride,
+                  unsigned char *input_image, unsigned char *output_image)
+{
+    short *RESTRICT l_w, * RESTRICT l_h;
+    short *RESTRICT c_w, * RESTRICT c_h;
+    unsigned char *RESTRICT ip, * RESTRICT op;
+    unsigned char *RESTRICT hbuf;
+    int h, w, lw, lh;
+    int temp_sum;
+    int phase_offset_w, phase_offset_h;
+
+    c_w = g_b_scaler.c_w;
+    c_h = g_b_scaler.c_h;
+
+    op = output_image;
+
+    l_w = g_b_scaler.l_w;
+    l_h = g_b_scaler.l_h;
+
+    phase_offset_h = 0;
+
+    for (h = 0; h < out_height; h++)
+    {
+        // select the row to work on
+        lh = l_h[h];
+        ip = input_image + (in_stride * lh);
+
+        // vp8_filter the row vertically into an temporary buffer.
+        //  If the phase offset == 0 then all the multiplication
+        //  is going to result in the output equalling the input.
+        //  So instead point the temporary buffer to the input.
+        //  Also handle the boundry condition of not being able to
+        //  filter that last lines.
+        if (phase_offset_h && (lh < in_height - 2))
+        {
+            hbuf = g_b_scaler.hbuf;
+
+            for (w = 0; w < in_width; w++)
+            {
+                temp_sum =  c_h[phase_offset_h*4+3] * ip[w - in_stride];
+                temp_sum += c_h[phase_offset_h*4+2] * ip[w];
+                temp_sum += c_h[phase_offset_h*4+1] * ip[w + in_stride];
+                temp_sum += c_h[phase_offset_h*4]   * ip[w + 2*in_stride];
+
+                hbuf[w] = temp_sum >> 12;
+            }
+        }
+        else
+            hbuf = ip;
+
+        // increase the phase offset for the next time around.
+        if (++phase_offset_h >= g_b_scaler.nh)
+            phase_offset_h = 0;
+
+        // now filter and expand it horizontally into the final
+        //  output buffer
+        phase_offset_w = 0;
+
+        for (w = 0; w < out_width; w++)
+        {
+            // get the index to use to expand the image
+            lw = l_w[w];
+
+            temp_sum =  c_w[phase_offset_w*4]   * hbuf[lw - 1];
+            temp_sum += c_w[phase_offset_w*4+1] * hbuf[lw];
+            temp_sum += c_w[phase_offset_w*4+2] * hbuf[lw + 1];
+            temp_sum += c_w[phase_offset_w*4+3] * hbuf[lw + 2];
+            temp_sum = temp_sum >> 12;
+
+            if (++phase_offset_w >= g_b_scaler.nw)
+                phase_offset_w = 0;
+
+            // boundry conditions
+            if ((lw + 2) >= in_width)
+                temp_sum = hbuf[lw];
+
+            if (lw == 0)
+                temp_sum = hbuf[0];
+
+            op[w] = temp_sum;
+        }
+
+        op += out_stride;
+    }
+
+    return 0;
+}
+
+void bicubic_scale_frame_reset()
+{
+    g_b_scaler.out_width = 0;
+    g_b_scaler.out_height = 0;
+}
+
+void bicubic_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
+                         int new_width, int new_height)
+{
+
+    dst->y_width = new_width;
+    dst->y_height = new_height;
+    dst->uv_width = new_width / 2;
+    dst->uv_height = new_height / 2;
+
+    dst->y_stride = dst->y_width;
+    dst->uv_stride = dst->uv_width;
+
+    bicubic_scale(src->y_width, src->y_height, src->y_stride,
+                  new_width, new_height, dst->y_stride,
+                  src->y_buffer, dst->y_buffer);
+
+    bicubic_scale(src->uv_width, src->uv_height, src->uv_stride,
+                  new_width / 2, new_height / 2, dst->uv_stride,
+                  src->u_buffer, dst->u_buffer);
+
+    bicubic_scale(src->uv_width, src->uv_height, src->uv_stride,
+                  new_width / 2, new_height / 2, dst->uv_stride,
+                  src->v_buffer, dst->v_buffer);
+}
diff --git a/vpx_scale/generic/gen_scalers.c b/vpx_scale/generic/gen_scalers.c
new file mode 100644 (file)
index 0000000..a5e545f
--- /dev/null
@@ -0,0 +1,954 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+/****************************************************************************
+*  Imports
+****************************************************************************/
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_4_5_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 4 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_4_5_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 4; i += 4)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char) a;
+        des [1] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+        c = src[2] * 154;
+        a = src[3];
+        des [2] = (unsigned char)((b * 102 + c + 128) >> 8);
+        des [3] = (unsigned char)((c + 102 * a + 128) >> 8);
+        b = src[4];
+        des [4] = (unsigned char)((a * 205 + 51 * b + 128) >> 8);
+
+        src += 4;
+        des += 5;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (unsigned char)(a);
+    des [1] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+    c = src[2] * 154;
+    a = src[3];
+    des [2] = (unsigned char)((b * 102 + c + 128) >> 8);
+    des [3] = (unsigned char)((c + 102 * a + 128) >> 8);
+    des [4] = (unsigned char)(a);
+
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_4_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+ *                  height of the band scaled is 4-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+void vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+
+        des[dest_pitch] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+
+        c = des[dest_pitch*2] * 154;
+        d = des[dest_pitch*3];
+
+        des [dest_pitch*2] = (unsigned char)((b * 102 + c + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((c + 102 * d + 128) >> 8);
+
+        // First line in next band
+        a = des [dest_pitch * 5];
+        des [dest_pitch * 4] = (unsigned char)((d * 205 + 51 * a + 128) >> 8);
+
+        des ++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_4_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 4 to 5. The
+ *                  height of the band scaled is 4-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+void vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        a = des[0];
+        b = des[dest_pitch];
+
+        des[dest_pitch] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+
+        c = des[dest_pitch*2] * 154;
+        d = des[dest_pitch*3];
+
+        des [dest_pitch*2] = (unsigned char)((b * 102 + c + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((c + 102 * d + 128) >> 8);
+
+        // No other line for interplation of this line, so ..
+        des[dest_pitch*4] = (unsigned char) d;
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_2_3_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 2 to 3.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_2_3_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 2; i += 2)
+    {
+        a = src[0];
+        b = src[1];
+        c = src[2];
+
+        des [0] = (unsigned char)(a);
+        des [1] = (unsigned char)((a * 85 + 171 * b + 128) >> 8);
+        des [2] = (unsigned char)((b * 171 + 85 * c + 128) >> 8);
+
+        src += 2;
+        des += 3;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (unsigned char)(a);
+    des [1] = (unsigned char)((a * 85 + 171 * b + 128) >> 8);
+    des [2] = (unsigned char)(b);
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_2_3_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 2 to 3. The
+ *                  height of the band scaled is 2-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+void vp8cx_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+        c = des[dest_pitch*3];
+        des [dest_pitch  ] = (unsigned char)((a * 85 + 171 * b + 128) >> 8);
+        des [dest_pitch*2] = (unsigned char)((b * 171 + 85 * c + 128) >> 8);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_2_3_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 2 to 3. The
+ *                  height of the band scaled is 2-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+void vp8cx_last_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+
+        des [dest_pitch  ] = (unsigned char)((a * 85 + 171 * b + 128) >> 8);
+        des [dest_pitch*2] = (unsigned char)(b);
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 3 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_3_5_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 3; i += 3)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char)(a);
+        des [1] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+
+        c = src[2] ;
+        des [2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+        des [3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+        a = src[3];
+        des [4] = (unsigned char)((c * 154 + a * 102 + 128) >> 8);
+
+        src += 3;
+        des += 5;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (unsigned char)(a);
+
+    des [1] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+    c = src[2] ;
+    des [2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+    des [3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+    des [4] = (unsigned char)(c);
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_3_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+void vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+        des [dest_pitch] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+
+        c = des[dest_pitch*2];
+        des [dest_pitch*2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+        // First line in next band...
+        a = des [dest_pitch * 5];
+        des [dest_pitch * 4] = (unsigned char)((c * 154 + a * 102 + 128) >> 8);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_3_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 3 to 5. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+void vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+
+        des [ dest_pitch ] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+
+        c = des[dest_pitch*2];
+        des [dest_pitch*2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+        // No other line for interplation of this line, so ..
+        des [ dest_pitch * 4 ] = (unsigned char)(c) ;
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_3_4_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 3 to 4.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_3_4_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 3; i += 3)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char)(a);
+        des [1] = (unsigned char)((a * 64 + b * 192 + 128) >> 8);
+
+        c = src[2];
+        des [2] = (unsigned char)((b + c + 1) >> 1);
+
+        a = src[3];
+        des [3] = (unsigned char)((c * 192 + a * 64 + 128) >> 8);
+
+        src += 3;
+        des += 4;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (unsigned char)(a);
+    des [1] = (unsigned char)((a * 64 + b * 192 + 128) >> 8);
+
+    c = src[2] ;
+    des [2] = (unsigned char)((b + c + 1) >> 1);
+    des [3] = (unsigned char)(c);
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_3_4_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 3 to 4. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+void vp8cx_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+        des [dest_pitch]   = (unsigned char)((a * 64 + b * 192 + 128) >> 8);
+
+        c = des[dest_pitch*2];
+        des [dest_pitch*2] = (unsigned char)((b + c + 1) >> 1);
+
+        // First line in next band...
+        a = des [dest_pitch*4];
+        des [dest_pitch*3] = (unsigned char)((c * 192 + a * 64 + 128) >> 8);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_3_4_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 3 to 4. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+void vp8cx_last_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+
+        des [dest_pitch]   = (unsigned char)((a * 64 + b * 192 + 128) >> 8);
+
+        c = des[dest_pitch*2];
+        des [dest_pitch*2] = (unsigned char)((b + c + 1) >> 1);
+
+        // No other line for interplation of this line, so ..
+        des [dest_pitch*3] = (unsigned char)(c);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 1 to 2.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_1_2_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 1; i += 1)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char)(a);
+        des [1] = (unsigned char)((a + b + 1) >> 1);
+        src += 1;
+        des += 2;
+    }
+
+    a = src[0];
+    des [0] = (unsigned char)(a);
+    des [1] = (unsigned char)(a);
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_1_2_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+ *                  height of the band scaled is 1-pixel.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+void vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch * 2];
+
+        des[dest_pitch] = (unsigned char)((a + b + 1) >> 1);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_1_2_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 1 to 2. The
+ *                  height of the band scaled is 1-pixel.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+void vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        des[dest_pitch] = des[0];
+        des++;
+    }
+}
+
+
+
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_4_5_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 4 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_5_4_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned i;
+    unsigned int a, b, c, d, e;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width; i += 5)
+    {
+        a = src[0];
+        b = src[1];
+        c = src[2];
+        d = src[3];
+        e = src[4];
+
+        des[0] = (unsigned char) a;
+        des[1] = (unsigned char)((b * 192 + c * 64 + 128) >> 8);
+        des[2] = (unsigned char)((c * 128 + d * 128 + 128) >> 8);
+        des[3] = (unsigned char)((d * 64 + e * 192 + 128) >> 8);
+
+        src += 5;
+        des += 4;
+    }
+}
+
+
+
+
+void vp8cx_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d, e;
+    unsigned char *des = dest;
+    unsigned char *src = source;
+
+    for (i = 0; i < dest_width; i++)
+    {
+
+        a = src[0 * src_pitch];
+        b = src[1 * src_pitch];
+        c = src[2 * src_pitch];
+        d = src[3 * src_pitch];
+        e = src[4 * src_pitch];
+
+        des[0 * dest_pitch] = (unsigned char) a;
+        des[1 * dest_pitch] = (unsigned char)((b * 192 + c * 64 + 128) >> 8);
+        des[2 * dest_pitch] = (unsigned char)((c * 128 + d * 128 + 128) >> 8);
+        des[3 * dest_pitch] = (unsigned char)((d * 64 + e * 192 + 128) >> 8);
+
+        src ++;
+        des ++;
+
+    }
+}
+
+
+/*7***************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 3 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_5_3_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b, c, d , e;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width; i += 5)
+    {
+        a = src[0];
+        b = src[1];
+        c = src[2];
+        d = src[3];
+        e = src[4];
+
+        des[0] = (unsigned char) a;
+        des[1] = (unsigned char)((b * 85  + c * 171 + 128) >> 8);
+        des[2] = (unsigned char)((d * 171 + e * 85 + 128) >> 8);
+
+        src += 5;
+        des += 3;
+    }
+
+}
+
+void vp8cx_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d, e;
+    unsigned char *des = dest;
+    unsigned char *src = source;
+
+    for (i = 0; i < dest_width; i++)
+    {
+
+        a = src[0 * src_pitch];
+        b = src[1 * src_pitch];
+        c = src[2 * src_pitch];
+        d = src[3 * src_pitch];
+        e = src[4 * src_pitch];
+
+        des[0 * dest_pitch] = (unsigned char) a;
+        des[1 * dest_pitch] = (unsigned char)((b * 85 + c * 171 + 128) >> 8);
+        des[2 * dest_pitch] = (unsigned char)((d * 171 + e * 85 + 128) >> 8);
+
+        src ++;
+        des ++;
+
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 1 to 2.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8cx_horizontal_line_2_1_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width; i += 2)
+    {
+        a = src[0];
+        des [0] = (unsigned char)(a);
+        src += 2;
+        des += 1;
+    }
+
+
+
+}
+void vp8cx_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    (void) dest_pitch;
+    (void) src_pitch;
+    vpx_memcpy(dest, source, dest_width);
+}
+
+void vp8cx_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    int temp;
+
+    (void) dest_pitch;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        temp = 8;
+        temp += source[i-(int)src_pitch] * 3;
+        temp += source[i] * 10;
+        temp += source[i+src_pitch] * 3;
+        temp >>= 4 ;
+        dest[i] = (unsigned char)(temp);
+    }
+
+}
diff --git a/vpx_scale/generic/scalesystemdependant.c b/vpx_scale/generic/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..28f5c72
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/vpxscale.h"
+
+#ifdef HAVE_CONFIG_H
+#include "vpx_config.h"
+#endif
+
+void (*vp8_yv12_extend_frame_borders_ptr)(YV12_BUFFER_CONFIG *ybf);
+extern void vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf);
+
+void (*vp8_yv12_copy_frame_yonly_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+void (*vp8_yv12_copy_frame_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_scale_machine_specific_config()
+{
+#if CONFIG_SPATIAL_RESAMPLING
+    vp8_horizontal_line_1_2_scale        = vp8cx_horizontal_line_1_2_scale_c;
+    vp8_vertical_band_1_2_scale          = vp8cx_vertical_band_1_2_scale_c;
+    vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+    vp8_horizontal_line_3_5_scale        = vp8cx_horizontal_line_3_5_scale_c;
+    vp8_vertical_band_3_5_scale          = vp8cx_vertical_band_3_5_scale_c;
+    vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+    vp8_horizontal_line_3_4_scale        = vp8cx_horizontal_line_3_4_scale_c;
+    vp8_vertical_band_3_4_scale          = vp8cx_vertical_band_3_4_scale_c;
+    vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+    vp8_horizontal_line_2_3_scale        = vp8cx_horizontal_line_2_3_scale_c;
+    vp8_vertical_band_2_3_scale          = vp8cx_vertical_band_2_3_scale_c;
+    vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+    vp8_horizontal_line_4_5_scale        = vp8cx_horizontal_line_4_5_scale_c;
+    vp8_vertical_band_4_5_scale          = vp8cx_vertical_band_4_5_scale_c;
+    vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+
+
+    vp8_vertical_band_5_4_scale           = vp8cx_vertical_band_5_4_scale_c;
+    vp8_vertical_band_5_3_scale           = vp8cx_vertical_band_5_3_scale_c;
+    vp8_vertical_band_2_1_scale           = vp8cx_vertical_band_2_1_scale_c;
+    vp8_vertical_band_2_1_scale_i         = vp8cx_vertical_band_2_1_scale_i_c;
+    vp8_horizontal_line_2_1_scale         = vp8cx_horizontal_line_2_1_scale_c;
+    vp8_horizontal_line_5_3_scale         = vp8cx_horizontal_line_5_3_scale_c;
+    vp8_horizontal_line_5_4_scale         = vp8cx_horizontal_line_5_4_scale_c;
+#endif
+
+    vp8_yv12_extend_frame_borders_ptr      = vp8_yv12_extend_frame_borders;
+    vp8_yv12_copy_frame_yonly_ptr          = vp8_yv12_copy_frame_yonly;
+    vp8_yv12_copy_frame_ptr           = vp8_yv12_copy_frame;
+
+}
diff --git a/vpx_scale/generic/vpxscale.c b/vpx_scale/generic/vpxscale.c
new file mode 100644 (file)
index 0000000..206cd55
--- /dev/null
@@ -0,0 +1,1088 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     scale.c
+ *
+ *   Description  :     Image scaling functions.
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/yv12config.h"
+#include "vpx_scale/scale_mode.h"
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+#ifndef VPX_NO_GLOBALS
+void (*vp8_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_last_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_2_3_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_last_vertical_band_2_3_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_last_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_3_4_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_last_vertical_band_3_4_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_1_2_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_3_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_3_4_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_2_3_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_4_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_last_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+
+void (*vp8_vertical_band_5_4_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_5_3_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_2_1_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_vertical_band_2_1_scale_i)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_2_1_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_5_3_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+void (*vp8_horizontal_line_5_4_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width) = 0;
+#else
+# include "vpxscale_nofp.h"
+#endif
+
+typedef struct
+{
+    int     expanded_frame_width;
+    int     expanded_frame_height;
+
+    int HScale;
+    int HRatio;
+    int VScale;
+    int VRatio;
+
+    YV12_BUFFER_CONFIG *src_yuv_config;
+    YV12_BUFFER_CONFIG *dst_yuv_config;
+
+} SCALE_VARS;
+
+/****************************************************************************
+ *
+ *  ROUTINE       :     horizontal_line_copy
+ *
+ *  INPUTS        :     None
+ *
+ *
+ *  OUTPUTS       :     None.
+ *
+ *  RETURNS       :     None
+ *
+ *  FUNCTION      :     1 to 1 scaling up for a horizontal line of pixles
+ *
+ *  SPECIAL NOTES :     None.
+ *
+ *  ERRORS        :     None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_copy(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    duck_memcpy(dest, source, source_width);
+}
+/****************************************************************************
+ *
+ *  ROUTINE       :     null_scale
+ *
+ *  INPUTS        :     None
+ *
+ *
+ *  OUTPUTS       :     None.
+ *
+ *  RETURNS       :     None
+ *
+ *  FUNCTION      :     1 to 1 scaling up for a vertical band
+ *
+ *  SPECIAL NOTES :     None.
+ *
+ *  ERRORS        :     None.
+ *
+ ****************************************************************************/
+static
+void null_scale(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    (void) dest;
+    (void) dest_pitch;
+    (void) dest_width;
+
+    return;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : scale1d_2t1_i
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
+ *                  int source_step              : Number of pixels to step on in source.
+ *                  unsigned int source_scale    : Scale for source (UNUSED).
+ *                  unsigned int source_length   : Length of source (UNUSED).
+ *                  unsigned char *dest         : Pointer to output data array.
+ *                  int dest_step                : Number of pixels to step on in destination.
+ *                  unsigned int dest_scale      : Scale for destination (UNUSED).
+ *                  unsigned int dest_length     : Length of destination.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-to-1 interpolated scaling.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void scale1d_2t1_i
+(
+    const unsigned char *source,
+    int source_step,
+    unsigned int source_scale,
+    unsigned int source_length,
+    unsigned char *dest,
+    int dest_step,
+    unsigned int dest_scale,
+    unsigned int dest_length
+)
+{
+    unsigned int i, j;
+    unsigned int temp;
+    int source_pitch = source_step;
+    (void) source_length;
+    (void) source_scale;
+    (void) dest_scale;
+
+    source_step *= 2;
+    dest[0] = source[0];
+
+    for (i = dest_step, j = source_step; i < dest_length * dest_step; i += dest_step, j += source_step)
+    {
+        temp = 8;
+        temp += 3 * source[j-source_pitch];
+        temp += 10 * source[j];
+        temp += 3 * source[j+source_pitch];
+        temp >>= 4;
+        dest[i] = (char)(temp);
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : scale1d_2t1_ps
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
+ *                  int source_step              : Number of pixels to step on in source.
+ *                  unsigned int source_scale    : Scale for source (UNUSED).
+ *                  unsigned int source_length   : Length of source (UNUSED).
+ *                  unsigned char *dest         : Pointer to output data array.
+ *                  int dest_step                : Number of pixels to step on in destination.
+ *                  unsigned int dest_scale      : Scale for destination (UNUSED).
+ *                  unsigned int dest_length     : Length of destination.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-to-1 point subsampled scaling.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void scale1d_2t1_ps
+(
+    const unsigned char *source,
+    int source_step,
+    unsigned int source_scale,
+    unsigned int source_length,
+    unsigned char *dest,
+    int dest_step,
+    unsigned int dest_scale,
+    unsigned int dest_length
+)
+{
+    unsigned int i, j;
+
+    (void) source_length;
+    (void) source_scale;
+    (void) dest_scale;
+
+    source_step *= 2;
+    j = 0;
+
+    for (i = 0; i < dest_length * dest_step; i += dest_step, j += source_step)
+        dest[i] = source[j];
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : scale1d_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
+ *                  int source_step              : Number of pixels to step on in source.
+ *                  unsigned int source_scale    : Scale for source.
+ *                  unsigned int source_length   : Length of source (UNUSED).
+ *                  unsigned char *dest         : Pointer to output data array.
+ *                  int dest_step                : Number of pixels to step on in destination.
+ *                  unsigned int dest_scale      : Scale for destination.
+ *                  unsigned int dest_length     : Length of destination.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs linear interpolation in one dimension.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void scale1d_c
+(
+    const unsigned char *source,
+    int source_step,
+    unsigned int source_scale,
+    unsigned int source_length,
+    unsigned char *dest,
+    int dest_step,
+    unsigned int dest_scale,
+    unsigned int dest_length
+)
+{
+    unsigned int i;
+    unsigned int round_value = dest_scale / 2;
+    unsigned int left_modifier = dest_scale;
+    unsigned int right_modifier = 0;
+    unsigned char left_pixel = *source;
+    unsigned char right_pixel = *(source + source_step);
+
+    (void) source_length;
+
+    // These asserts are needed if there are boundary issues...
+    //assert ( dest_scale > source_scale );
+    //assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale );
+
+    for (i = 0; i < dest_length * dest_step; i += dest_step)
+    {
+        dest[i] = (char)((left_modifier * left_pixel + right_modifier * right_pixel + round_value) / dest_scale);
+
+        right_modifier += source_scale;
+
+        while (right_modifier > dest_scale)
+        {
+            right_modifier -= dest_scale;
+            source += source_step;
+            left_pixel = *source;
+            right_pixel = *(source + source_step);
+        }
+
+        left_modifier = dest_scale - right_modifier;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : Scale2D
+ *
+ *  INPUTS        : const unsigned char *source  : Pointer to data to be scaled.
+ *                  int source_pitch              : Stride of source image.
+ *                  unsigned int source_width     : Width of input image.
+ *                  unsigned int source_height    : Height of input image.
+ *                  unsigned char *dest          : Pointer to output data array.
+ *                  int dest_pitch                : Stride of destination image.
+ *                  unsigned int dest_width       : Width of destination image.
+ *                  unsigned int dest_height      : Height of destination image.
+ *                  unsigned char *temp_area      : Pointer to temp work area.
+ *                  unsigned char temp_area_height : Height of temp work area.
+ *                  unsigned int hscale          : Horizontal scale factor numerator.
+ *                  unsigned int hratio          : Horizontal scale factor denominator.
+ *                  unsigned int vscale          : Vertical scale factor numerator.
+ *                  unsigned int vratio          : Vertical scale factor denominator.
+ *                  unsigned int interlaced      : Interlace flag.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
+ *
+ *  SPECIAL NOTES : Expansion is performed one band at a time to help with
+ *                  caching.
+ *
+ ****************************************************************************/
+static
+void Scale2D
+(
+    //const
+    unsigned char *source,
+    int source_pitch,
+    unsigned int source_width,
+    unsigned int source_height,
+    unsigned char *dest,
+    int dest_pitch,
+    unsigned int dest_width,
+    unsigned int dest_height,
+    unsigned char *temp_area,
+    unsigned char temp_area_height,
+    unsigned int hscale,
+    unsigned int hratio,
+    unsigned int vscale,
+    unsigned int vratio,
+    unsigned int interlaced
+)
+{
+    //unsigned
+    int i, j, k;
+    int bands;
+    int dest_band_height;
+    int source_band_height;
+
+    typedef void (*Scale1D)(const unsigned char * source, int source_step, unsigned int source_scale, unsigned int source_length,
+                            unsigned char * dest, int dest_step, unsigned int dest_scale, unsigned int dest_length);
+
+    Scale1D Scale1Dv = scale1d_c;
+    Scale1D Scale1Dh = scale1d_c;
+
+    void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
+    void (*vert_band_scale)(unsigned char *, unsigned int, unsigned char *, unsigned int, unsigned int) = NULL;
+
+    int ratio_scalable = 1;
+    int interpolation = 0;
+
+    unsigned char *source_base; // = (unsigned char *) ((source_pitch >= 0) ? source : (source + ((source_height-1) * source_pitch)));
+    unsigned char *line_src;
+
+
+    source_base = (unsigned char *)source;
+
+    if (source_pitch < 0)
+    {
+        int offset;
+
+        offset = (source_height - 1);
+        offset *= source_pitch;
+
+        source_base += offset;
+    }
+
+    // find out the ratio for each direction
+    switch (hratio * 10 / hscale)
+    {
+    case 8:
+        // 4-5 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_5_4_scale;
+        break;
+    case 6:
+        // 3-5 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_5_3_scale;
+        break;
+    case 5:
+        // 1-2 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_2_1_scale;
+        break;
+    default:
+        // The ratio is not acceptable now
+        // throw("The ratio is not acceptable for now!");
+        ratio_scalable = 0;
+        break;
+    }
+
+    switch (vratio * 10 / vscale)
+    {
+    case 8:
+        // 4-5 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_5_4_scale;
+        source_band_height  = 5;
+        dest_band_height    = 4;
+        break;
+    case 6:
+        // 3-5 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_5_3_scale;
+        source_band_height  = 5;
+        dest_band_height    = 3;
+        break;
+    case 5:
+        // 1-2 Scale in vertical direction
+
+        if (interlaced)
+        {
+            //if the content is interlaced, point sampling is used
+            vert_band_scale     = vp8_vertical_band_2_1_scale;
+        }
+        else
+        {
+
+            interpolation = 1;
+            //if the content is progressive, interplo
+            vert_band_scale     = vp8_vertical_band_2_1_scale_i;
+
+        }
+
+        source_band_height  = 2;
+        dest_band_height    = 1;
+        break;
+    default:
+        // The ratio is not acceptable now
+        // throw("The ratio is not acceptable for now!");
+        ratio_scalable = 0;
+        break;
+    }
+
+    if (ratio_scalable)
+    {
+        if (source_height == dest_height)
+        {
+            // for each band of the image
+            for (k = 0; k < (int)dest_height; k++)
+            {
+                horiz_line_scale(source, source_width, dest, dest_width);
+                source += source_pitch;
+                dest   += dest_pitch;
+            }
+
+            return;
+        }
+
+        if (interpolation)
+        {
+            if (source < source_base)
+                source = source_base;
+
+            horiz_line_scale(source, source_width, temp_area, dest_width);
+        }
+
+        for (k = 0; k < (int)(dest_height + dest_band_height - 1) / dest_band_height; k++)
+        {
+            // scale one band horizontally
+            for (i = 0; i < source_band_height; i++)
+            {
+                // Trap case where we could read off the base of the source buffer
+
+                line_src = (unsigned char *)source + i * source_pitch;
+
+                if (line_src < source_base)
+                    line_src = source_base;
+
+                horiz_line_scale(line_src, source_width,
+                                 temp_area + (i + 1)*dest_pitch, dest_width);
+            }
+
+            // Vertical scaling is in place
+            vert_band_scale(temp_area + dest_pitch, dest_pitch, dest, dest_pitch, dest_width);
+
+            if (interpolation)
+                vpx_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_width);
+
+            // Next band...
+            source += (unsigned long) source_band_height  * source_pitch;
+            dest   += (unsigned long) dest_band_height * dest_pitch;
+        }
+
+        return;
+    }
+
+    if (hscale == 2 && hratio == 1)
+        Scale1Dh = scale1d_2t1_ps;
+
+    if (vscale == 2 && vratio == 1)
+    {
+        if (interlaced)
+            Scale1Dv = scale1d_2t1_ps;
+        else
+            Scale1Dv = scale1d_2t1_i;
+    }
+
+    if (source_height == dest_height)
+    {
+        // for each band of the image
+        for (k = 0; k < (int)dest_height; k++)
+        {
+            Scale1Dh(source, 1, hscale, source_width + 1, dest, 1, hratio, dest_width);
+            source += source_pitch;
+            dest   += dest_pitch;
+        }
+
+        return;
+    }
+
+    if (dest_height > source_height)
+    {
+        dest_band_height   = temp_area_height - 1;
+        source_band_height = dest_band_height * source_height / dest_height;
+    }
+    else
+    {
+        source_band_height = temp_area_height - 1;
+        dest_band_height   = source_band_height * vratio / vscale;
+    }
+
+    // first row needs to be done so that we can stay one row ahead for vertical zoom
+    Scale1Dh(source, 1, hscale, source_width + 1, temp_area, 1, hratio, dest_width);
+
+    // for each band of the image
+    bands = (dest_height + dest_band_height - 1) / dest_band_height;
+
+    for (k = 0; k < bands; k++)
+    {
+        // scale one band horizontally
+        for (i = 1; i < source_band_height + 1; i++)
+        {
+            if (k * source_band_height + i < (int) source_height)
+            {
+                Scale1Dh(source + i * source_pitch, 1, hscale, source_width + 1,
+                         temp_area + i * dest_pitch, 1, hratio, dest_width);
+            }
+            else  //  Duplicate the last row
+            {
+                // copy temp_area row 0 over from last row in the past
+                duck_memcpy(temp_area + i * dest_pitch, temp_area + (i - 1)*dest_pitch, dest_pitch);
+            }
+        }
+
+        // scale one band vertically
+        for (j = 0; j < (int)dest_width; j++)
+        {
+            Scale1Dv(&temp_area[j], dest_pitch, vscale, source_band_height + 1,
+                     &dest[j], dest_pitch, vratio, dest_band_height);
+        }
+
+        // copy temp_area row 0 over from last row in the past
+        duck_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_pitch);
+
+        // move to the next band
+        source += source_band_height * source_pitch;
+        dest   += dest_band_height * dest_pitch;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       :
+ *
+ *  INPUTS        : YV12_BUFFER_CONFIG *src       : Pointer to frame to be scaled.
+ *                  YV12_BUFFER_CONFIG *dst       : Pointer to buffer to hold scaled frame.
+ *                  unsigned char *temp_area      : Pointer to temp work area.
+ *                  unsigned char temp_area_height : Height of temp work area.
+ *                  unsigned int hscale          : Horizontal scale factor numerator.
+ *                  unsigned int hratio          : Horizontal scale factor denominator.
+ *                  unsigned int vscale          : Vertical scale factor numerator.
+ *                  unsigned int vratio          : Vertical scale factor denominator.
+ *                  unsigned int interlaced      : Interlace flag.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
+ *
+ *  SPECIAL NOTES : Expansion is performed one band at a time to help with
+ *                  caching.
+ *
+ ****************************************************************************/
+void vp8_scale_frame
+(
+    YV12_BUFFER_CONFIG *src,
+    YV12_BUFFER_CONFIG *dst,
+    unsigned char *temp_area,
+    unsigned char temp_height,
+    unsigned int hscale,
+    unsigned int hratio,
+    unsigned int vscale,
+    unsigned int vratio,
+    unsigned int interlaced
+)
+{
+    int i;
+    int dw = (hscale - 1 + src->y_width * hratio) / hscale;
+    int dh = (vscale - 1 + src->y_height * vratio) / vscale;
+
+    // call our internal scaling routines!!
+    Scale2D((unsigned char *) src->y_buffer, src->y_stride, src->y_width, src->y_height,
+            (unsigned char *) dst->y_buffer, dst->y_stride, dw, dh,
+            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
+
+    if (dw < (int)dst->y_width)
+        for (i = 0; i < dh; i++)
+            duck_memset(dst->y_buffer + i * dst->y_stride + dw - 1, dst->y_buffer[i*dst->y_stride+dw-2], dst->y_width - dw + 1);
+
+    if (dh < (int)dst->y_height)
+        for (i = dh - 1; i < (int)dst->y_height; i++)
+            duck_memcpy(dst->y_buffer + i * dst->y_stride, dst->y_buffer + (dh - 2) * dst->y_stride, dst->y_width + 1);
+
+    Scale2D((unsigned char *) src->u_buffer, src->uv_stride, src->uv_width, src->uv_height,
+            (unsigned char *) dst->u_buffer, dst->uv_stride, dw / 2, dh / 2,
+            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
+
+    if (dw / 2 < (int)dst->uv_width)
+        for (i = 0; i < dst->uv_height; i++)
+            duck_memset(dst->u_buffer + i * dst->uv_stride + dw / 2 - 1, dst->u_buffer[i*dst->uv_stride+dw/2-2], dst->uv_width - dw / 2 + 1);
+
+    if (dh / 2 < (int)dst->uv_height)
+        for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
+            duck_memcpy(dst->u_buffer + i * dst->uv_stride, dst->u_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
+
+    Scale2D((unsigned char *) src->v_buffer, src->uv_stride, src->uv_width, src->uv_height,
+            (unsigned char *) dst->v_buffer, dst->uv_stride, dw / 2, dh / 2,
+            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
+
+    if (dw / 2 < (int)dst->uv_width)
+        for (i = 0; i < dst->uv_height; i++)
+            duck_memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, dst->v_buffer[i*dst->uv_stride+dw/2-2], dst->uv_width - dw / 2 + 1);
+
+    if (dh / 2 < (int) dst->uv_height)
+        for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
+            duck_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : any_ratio_2d_scale
+ *
+ *  INPUTS        : SCALE_INSTANCE *si      : Pointer to post-processor instance (NOT USED).
+ *                  const unsigned char *source : Pointer to source image.
+ *                  unsigned int source_pitch    : Stride of source image.
+ *                  unsigned int source_width    : Width of source image.
+ *                  unsigned int source_height   : Height of source image (NOT USED).
+ *                  unsigned char *dest         : Pointer to destination image.
+ *                  unsigned int dest_pitch      : Stride of destination image.
+ *                  unsigned int dest_width      : Width of destination image.
+ *                  unsigned int dest_height     : Height of destination image.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int: 1 if image scaled, 0 if image could not be scaled.
+ *
+ *  FUNCTION      : Scale the image with changing apect ratio.
+ *
+ *  SPECIAL NOTES : This scaling is a bi-linear scaling. Need to re-work the
+ *                  whole function for new scaling algorithm.
+ *
+ ****************************************************************************/
+static
+int any_ratio_2d_scale
+(
+    SCALE_VARS *si,
+    const unsigned char *source,
+    int source_pitch,
+    unsigned int source_width,
+    unsigned int source_height,
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width,
+    unsigned int dest_height
+)
+{
+    unsigned int i, k;
+    unsigned int src_band_height  = 0;
+    unsigned int dest_band_height = 0;
+
+    // suggested scale factors
+    int hs = si->HScale;
+    int hr = si->HRatio;
+    int vs = si->VScale;
+    int vr = si->VRatio;
+
+    // assume the ratios are scalable instead of should be centered
+    int ratio_scalable = 1;
+
+    const unsigned char *source_base = ((source_pitch >= 0) ? source : (source + ((source_height - 1) * source_pitch)));
+    const unsigned char *line_src;
+
+    void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
+    void (*vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
+    void (*last_vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
+
+    (void) si;
+
+    // find out the ratio for each direction
+    switch (hr * 30 / hs)
+    {
+    case 24:
+        // 4-5 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_4_5_scale;
+        break;
+    case 22:
+        // 3-4 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_3_4_scale;
+        break;
+
+    case 20:
+        // 4-5 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_2_3_scale;
+        break;
+    case 18:
+        // 3-5 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_3_5_scale;
+        break;
+    case 15:
+        // 1-2 Scale in Width direction
+        horiz_line_scale = vp8_horizontal_line_1_2_scale;
+        break;
+    case 30:
+        // no scale in Width direction
+        horiz_line_scale = horizontal_line_copy;
+        break;
+    default:
+        // The ratio is not acceptable now
+        // throw("The ratio is not acceptable for now!");
+        ratio_scalable = 0;
+        break;
+    }
+
+    switch (vr * 30 / vs)
+    {
+    case 24:
+        // 4-5 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_4_5_scale;
+        last_vert_band_scale = vp8_last_vertical_band_4_5_scale;
+        src_band_height     = 4;
+        dest_band_height    = 5;
+        break;
+    case 22:
+        // 3-4 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_3_4_scale;
+        last_vert_band_scale = vp8_last_vertical_band_3_4_scale;
+        src_band_height     = 3;
+        dest_band_height    = 4;
+        break;
+    case 20:
+        // 2-3 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_2_3_scale;
+        last_vert_band_scale = vp8_last_vertical_band_2_3_scale;
+        src_band_height     = 2;
+        dest_band_height    = 3;
+        break;
+    case 18:
+        // 3-5 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_3_5_scale;
+        last_vert_band_scale = vp8_last_vertical_band_3_5_scale;
+        src_band_height     = 3;
+        dest_band_height    = 5;
+        break;
+    case 15:
+        // 1-2 Scale in vertical direction
+        vert_band_scale     = vp8_vertical_band_1_2_scale;
+        last_vert_band_scale = vp8_last_vertical_band_1_2_scale;
+        src_band_height     = 1;
+        dest_band_height    = 2;
+        break;
+    case 30:
+        // no scale in Width direction
+        vert_band_scale     = null_scale;
+        last_vert_band_scale = null_scale;
+        src_band_height     = 4;
+        dest_band_height    = 4;
+        break;
+    default:
+        // The ratio is not acceptable now
+        // throw("The ratio is not acceptable for now!");
+        ratio_scalable = 0;
+        break;
+    }
+
+    if (ratio_scalable == 0)
+        return ratio_scalable;
+
+    horiz_line_scale(source, source_width, dest, dest_width);
+
+    // except last band
+    for (k = 0; k < (dest_height + dest_band_height - 1) / dest_band_height - 1; k++)
+    {
+        // scale one band horizontally
+        for (i = 1; i < src_band_height; i++)
+        {
+            // Trap case where we could read off the base of the source buffer
+            line_src = source + i * source_pitch;
+
+            if (line_src < source_base)
+                line_src = source_base;
+
+            horiz_line_scale(line_src, source_width,
+                             dest + i * dest_pitch, dest_width);
+        }
+
+        // first line of next band
+        // Trap case where we could read off the base of the source buffer
+        line_src = source + src_band_height * source_pitch;
+
+        if (line_src < source_base)
+            line_src = source_base;
+
+        horiz_line_scale(line_src, source_width,
+                         dest + dest_band_height * dest_pitch,
+                         dest_width);
+
+        // Vertical scaling is in place
+        vert_band_scale(dest, dest_pitch, dest_width);
+
+        // Next band...
+        source += src_band_height  * source_pitch;
+        dest   += dest_band_height * dest_pitch;
+    }
+
+    // scale one band horizontally
+    for (i = 1; i < src_band_height; i++)
+    {
+        // Trap case where we could read off the base of the source buffer
+        line_src = source + i * source_pitch;
+
+        if (line_src < source_base)
+            line_src = source_base;
+
+        horiz_line_scale(line_src, source_width,
+                         dest + i * dest_pitch,
+                         dest_width);
+    }
+
+    // Vertical scaling is in place
+    last_vert_band_scale(dest, dest_pitch, dest_width);
+
+    return ratio_scalable;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : any_ratio_frame_scale
+ *
+ *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance (NOT USED).
+ *                  unsigned char *frame_buffer           : Pointer to source image.
+ *                  int YOffset                : Offset from start of buffer to Y samples.
+ *                  int UVOffset               : Offset from start of buffer to UV samples.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int: 1 if image scaled, 0 if image could not be scaled.
+ *
+ *  FUNCTION      : Scale the image with changing apect ratio.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+int any_ratio_frame_scale(SCALE_VARS *scale_vars, int YOffset, int UVOffset)
+{
+    int i;
+    int ew;
+    int eh;
+
+    // suggested scale factors
+    int hs = scale_vars->HScale;
+    int hr = scale_vars->HRatio;
+    int vs = scale_vars->VScale;
+    int vr = scale_vars->VRatio;
+
+    int ratio_scalable = 1;
+
+    int sw = (scale_vars->expanded_frame_width * hr + hs - 1) / hs;
+    int sh = (scale_vars->expanded_frame_height * vr + vs - 1) / vs;
+    int dw = scale_vars->expanded_frame_width;
+    int dh = scale_vars->expanded_frame_height;
+    YV12_BUFFER_CONFIG *src_yuv_config = scale_vars->src_yuv_config;
+    YV12_BUFFER_CONFIG *dst_yuv_config = scale_vars->dst_yuv_config;
+
+    if (hr == 3)
+        ew = (sw + 2) / 3 * 3 * hs / hr;
+    else
+        ew = (sw + 7) / 8 * 8 * hs / hr;
+
+    if (vr == 3)
+        eh = (sh + 2) / 3 * 3 * vs / vr;
+    else
+        eh = (sh + 7) / 8 * 8 * vs / vr;
+
+    ratio_scalable = any_ratio_2d_scale(scale_vars,
+                                        (const unsigned char *)src_yuv_config->y_buffer,
+                                        src_yuv_config->y_stride, sw, sh,
+                                        (unsigned char *) dst_yuv_config->y_buffer + YOffset,
+                                        dst_yuv_config->y_stride, dw, dh);
+
+    for (i = 0; i < eh; i++)
+        duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_stride + dw, 0, ew - dw);
+
+    for (i = dh; i < eh; i++)
+        duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_stride, 0, ew);
+
+    if (ratio_scalable == 0)
+        return ratio_scalable;
+
+    sw = (sw + 1) >> 1;
+    sh = (sh + 1) >> 1;
+    dw = (dw + 1) >> 1;
+    dh = (dh + 1) >> 1;
+
+    any_ratio_2d_scale(scale_vars,
+                       (const unsigned char *)src_yuv_config->u_buffer,
+                       src_yuv_config->y_stride / 2, sw, sh,
+                       (unsigned char *)dst_yuv_config->u_buffer + UVOffset,
+                       dst_yuv_config->uv_stride, dw, dh);
+
+    any_ratio_2d_scale(scale_vars,
+                       (const unsigned char *)src_yuv_config->v_buffer,
+                       src_yuv_config->y_stride / 2, sw, sh,
+                       (unsigned char *)dst_yuv_config->v_buffer + UVOffset,
+                       dst_yuv_config->uv_stride, dw, dh);
+
+    return ratio_scalable;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : center_image
+ *
+ *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Centers the image without scaling in the output buffer.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static void
+center_image(YV12_BUFFER_CONFIG *src_yuv_config, YV12_BUFFER_CONFIG *dst_yuv_config)
+{
+    int i;
+    int row_offset, col_offset;
+    unsigned char *src_data_pointer;
+    unsigned char *dst_data_pointer;
+
+    // center values
+    row_offset = (dst_yuv_config->y_height - src_yuv_config->y_height) / 2;
+    col_offset = (dst_yuv_config->y_width - src_yuv_config->y_width) / 2;
+
+    // Y's
+    src_data_pointer = src_yuv_config->y_buffer;
+    dst_data_pointer = (unsigned char *)dst_yuv_config->y_buffer + (row_offset * dst_yuv_config->y_stride) + col_offset;
+
+    for (i = 0; i < src_yuv_config->y_height; i++)
+    {
+        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->y_width);
+        dst_data_pointer += dst_yuv_config->y_stride;
+        src_data_pointer += src_yuv_config->y_stride;
+    }
+
+    row_offset /= 2;
+    col_offset /= 2;
+
+    // U's
+    src_data_pointer = src_yuv_config->u_buffer;
+    dst_data_pointer = (unsigned char *)dst_yuv_config->u_buffer + (row_offset * dst_yuv_config->uv_stride) + col_offset;
+
+    for (i = 0; i < src_yuv_config->uv_height; i++)
+    {
+        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
+        dst_data_pointer += dst_yuv_config->uv_stride;
+        src_data_pointer += src_yuv_config->uv_stride;
+    }
+
+    // V's
+    src_data_pointer = src_yuv_config->v_buffer;
+    dst_data_pointer = (unsigned char *)dst_yuv_config->v_buffer + (row_offset * dst_yuv_config->uv_stride) + col_offset;
+
+    for (i = 0; i < src_yuv_config->uv_height; i++)
+    {
+        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
+        dst_data_pointer += dst_yuv_config->uv_stride;
+        src_data_pointer += src_yuv_config->uv_stride;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : scale_or_center
+ *
+ *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance.
+ *
+ *
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Decides to scale or center image in scale buffer for blit
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void
+vp8_yv12_scale_or_center
+(
+    YV12_BUFFER_CONFIG *src_yuv_config,
+    YV12_BUFFER_CONFIG *dst_yuv_config,
+    int expanded_frame_width,
+    int expanded_frame_height,
+    int scaling_mode,
+    int HScale,
+    int HRatio,
+    int VScale,
+    int VRatio
+)
+{
+//    if ( ppi->post_processing_level )
+    //      update_umvborder ( ppi, frame_buffer );
+
+
+    switch (scaling_mode)
+    {
+    case SCALE_TO_FIT:
+    case MAINTAIN_ASPECT_RATIO:
+    {
+        SCALE_VARS scale_vars;
+        // center values
+#if 1
+        int row = (dst_yuv_config->y_height - expanded_frame_height) / 2;
+        int col = (dst_yuv_config->y_width  - expanded_frame_width) / 2;
+//        int YOffset  = row * dst_yuv_config->y_width + col;
+//        int UVOffset = (row>>1) * dst_yuv_config->uv_width + (col>>1);
+        int YOffset  = row * dst_yuv_config->y_stride + col;
+        int UVOffset = (row >> 1) * dst_yuv_config->uv_stride + (col >> 1);
+#else
+        int row = (src_yuv_config->y_height - expanded_frame_height) / 2;
+        int col = (src_yuv_config->y_width  - expanded_frame_width) / 2;
+        int YOffset  = row * src_yuv_config->y_width + col;
+        int UVOffset = (row >> 1) * src_yuv_config->uv_width + (col >> 1);
+#endif
+
+        scale_vars.dst_yuv_config = dst_yuv_config;
+        scale_vars.src_yuv_config = src_yuv_config;
+        scale_vars.HScale = HScale;
+        scale_vars.HRatio = HRatio;
+        scale_vars.VScale = VScale;
+        scale_vars.VRatio = VRatio;
+        scale_vars.expanded_frame_width = expanded_frame_width;
+        scale_vars.expanded_frame_height = expanded_frame_height;
+
+        // perform center and scale
+        any_ratio_frame_scale(&scale_vars, YOffset, UVOffset);
+
+        break;
+    }
+    case CENTER:
+        center_image(src_yuv_config, dst_yuv_config);
+        break;
+
+    default:
+        break;
+    }
+}
diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c
new file mode 100644 (file)
index 0000000..04617be
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+int
+vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf)
+{
+    if (ybf)
+    {
+        if (ybf->buffer_alloc)
+        {
+            duck_free(ybf->buffer_alloc);
+        }
+
+        ybf->buffer_alloc = 0;
+    }
+    else
+    {
+        return -1;
+    }
+
+    return 0;
+}
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+int
+vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border)
+{
+//NOTE:
+
+    int yplane_size = (height + 2 * border) * (width + 2 * border);
+    int uvplane_size = ((1 + height) / 2 + border) * ((1 + width) / 2 + border);
+
+    if (ybf)
+    {
+        vp8_yv12_de_alloc_frame_buffer(ybf);
+
+        ybf->y_width  = width;
+        ybf->y_height = height;
+        ybf->y_stride = width + 2 * border;
+
+        ybf->uv_width = (1 + width) / 2;
+        ybf->uv_height = (1 + height) / 2;
+        ybf->uv_stride = ybf->uv_width + border;
+
+        ybf->border = border;
+        ybf->frame_size = yplane_size + 2 * uvplane_size;
+
+        // Added 2 extra lines to framebuffer so that copy12x12 doesn't fail
+        // when we have a large motion vector in V on the last v block.
+        // Note : We never use these pixels anyway so this doesn't hurt.
+        ybf->buffer_alloc = (unsigned char *) duck_memalign(32,  ybf->frame_size + (ybf->y_stride * 2) + 32, 0);
+
+        if (ybf->buffer_alloc == NULL)
+            return -1;
+
+        ybf->y_buffer = ybf->buffer_alloc + (border * ybf->y_stride) + border;
+
+        if (yplane_size & 0xf)
+            yplane_size += 16 - (yplane_size & 0xf);
+
+        ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2  * ybf->uv_stride) + border / 2;
+        ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2  * ybf->uv_stride) + border / 2;
+    }
+    else
+    {
+        return -2;
+    }
+
+    return 0;
+}
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+int
+vp8_yv12_black_frame_buffer(YV12_BUFFER_CONFIG *ybf)
+{
+    if (ybf)
+    {
+        if (ybf->buffer_alloc)
+        {
+            duck_memset(ybf->y_buffer, 0x0, ybf->y_stride * ybf->y_height);
+            duck_memset(ybf->u_buffer, 0x80, ybf->uv_stride * ybf->uv_height);
+            duck_memset(ybf->v_buffer, 0x80, ybf->uv_stride * ybf->uv_height);
+        }
+
+        return 0;
+    }
+
+    return -1;
+}
diff --git a/vpx_scale/generic/yv12extend.c b/vpx_scale/generic/yv12extend.c
new file mode 100644 (file)
index 0000000..4906625
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/vpxscale.h"
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+void
+vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->y_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        vpx_memset(dest_ptr1, src_ptr1[0], Border);
+        vpx_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+
+    /***********/
+    /* U Plane */
+    /***********/
+    plane_stride = ybf->uv_stride;
+    plane_height = ybf->uv_height;
+    plane_width = ybf->uv_width;
+    Border /= 2;
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->u_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        vpx_memset(dest_ptr1, src_ptr1[0], Border);
+        vpx_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->u_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    /***********/
+    /* V Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->v_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        vpx_memset(dest_ptr1, src_ptr1[0], Border);
+        vpx_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->v_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+}
+
+
+void
+vp8_yv12_extend_frame_borders_yonly(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+    unsigned char *src_ptr1, *src_ptr2;
+    unsigned char *dest_ptr1, *dest_ptr2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->y_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        vpx_memset(dest_ptr1, src_ptr1[0], Border);
+        vpx_memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        vpx_memcpy(dest_ptr1, src_ptr1, plane_stride);
+        vpx_memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    plane_stride /= 2;
+    plane_height /= 2;
+    plane_width /= 2;
+    Border /= 2;
+
+}
+
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_yv12_copy_frame
+ *
+ *  INPUTS        :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies the source image into the destination image and
+ *                  updates the destination's UMV borders.
+ *
+ *  SPECIAL NOTES : The frames are assumed to be identical in size.
+ *
+ ****************************************************************************/
+void
+vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    int row;
+    unsigned char *source, *dest;
+
+    source = src_ybc->y_buffer;
+    dest = dst_ybc->y_buffer;
+
+    for (row = 0; row < src_ybc->y_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->y_width);
+        source += src_ybc->y_stride;
+        dest   += dst_ybc->y_stride;
+    }
+
+    source = src_ybc->u_buffer;
+    dest = dst_ybc->u_buffer;
+
+    for (row = 0; row < src_ybc->uv_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->uv_width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    source = src_ybc->v_buffer;
+    dest = dst_ybc->v_buffer;
+
+    for (row = 0; row < src_ybc->uv_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->uv_width);
+        source += src_ybc->uv_stride;
+        dest   += dst_ybc->uv_stride;
+    }
+
+    vp8_yv12_extend_frame_borders_ptr(dst_ybc);
+}
+
+void
+vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    int row;
+    unsigned char *source, *dest;
+
+
+    source = src_ybc->y_buffer;
+    dest = dst_ybc->y_buffer;
+
+    for (row = 0; row < src_ybc->y_height; row++)
+    {
+        vpx_memcpy(dest, source, src_ybc->y_width);
+        source += src_ybc->y_stride;
+        dest   += dst_ybc->y_stride;
+    }
+
+    vp8_yv12_extend_frame_borders_yonly(dst_ybc);
+}
diff --git a/vpx_scale/include/arm/vpxscale_nofp.h b/vpx_scale/include/arm/vpxscale_nofp.h
new file mode 100644 (file)
index 0000000..d6181d2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+void  vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_horizontal_line_1_2_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_3_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_3_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_2_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_4_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+void  vp8cx_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_horizontal_line_2_1_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_5_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_5_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+
+void horizontal_line_4_5_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_2_3_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_3_5_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_3_4_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_1_2_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vertical_band_4_5_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_2_3_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_3_5_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_3_4_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_1_2_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+#define vp8_vertical_band_4_5_scale     vertical_band_4_5_scale_armv4
+#define vp8_last_vertical_band_4_5_scale vp8cx_last_vertical_band_4_5_scale_c
+#define vp8_vertical_band_2_3_scale     vertical_band_2_3_scale_armv4
+#define vp8_last_vertical_band_2_3_scale vp8cx_last_vertical_band_2_3_scale_c
+#define vp8_vertical_band_3_5_scale     vertical_band_3_5_scale_armv4
+#define vp8_last_vertical_band_3_5_scale vp8cx_last_vertical_band_3_5_scale_c
+#define vp8_vertical_band_3_4_scale     vertical_band_3_4_scale_armv4
+#define vp8_last_vertical_band_3_4_scale vp8cx_last_vertical_band_3_4_scale_c
+#define vp8_horizontal_line_1_2_scale   horizontal_line_1_2_scale_armv4
+#define vp8_horizontal_line_3_5_scale   horizontal_line_3_5_scale_armv4
+#define vp8_horizontal_line_3_4_scale   horizontal_line_3_4_scale_armv4
+#define vp8_horizontal_line_4_5_scale   horizontal_line_4_5_scale_armv4
+#define vp8_horizontal_line_2_3_scale   horizontal_line_2_3_scale_armv4
+#define vp8_vertical_band_1_2_scale     vertical_band_1_2_scale_armv4
+#define vp8_last_vertical_band_1_2_scale vp8cx_last_vertical_band_1_2_scale_c
+#define vp8_vertical_band_5_4_scale     vp8cx_vertical_band_5_4_scale_c
+#define vp8_vertical_band_5_3_scale     vp8cx_vertical_band_5_3_scale_c
+#define vp8_vertical_band_2_1_scale     vp8cx_vertical_band_2_1_scale_c
+#define vp8_vertical_band_2_1_scale_i   vp8cx_vertical_band_2_1_scale_i_c
+#define vp8_horizontal_line_2_1_scale   vp8cx_horizontal_line_2_1_scale_c
+#define vp8_horizontal_line_5_3_scale   vp8cx_horizontal_line_5_3_scale_c
+#define vp8_horizontal_line_5_4_scale   vp8cx_horizontal_line_5_4_scale_c
diff --git a/vpx_scale/include/generic/vpxscale_arbitrary.h b/vpx_scale/include/generic/vpxscale_arbitrary.h
new file mode 100644 (file)
index 0000000..2b50f24
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef __VPX_SCALE_ARBITRARY_H__
+#define __VPX_SCALE_ARBITRARY_H__
+
+#include "vpx_scale/yv12config.h"
+
+typedef struct
+{
+    int in_width;
+    int in_height;
+
+    int out_width;
+    int out_height;
+    int max_usable_out_width;
+
+    // numerator for the width and height
+    int nw;
+    int nh;
+    int nh_uv;
+
+    // output to input correspondance array
+    short *l_w;
+    short *l_h;
+    short *l_h_uv;
+
+    // polyphase coefficients
+    short *c_w;
+    short *c_h;
+    short *c_h_uv;
+
+    // buffer for horizontal filtering.
+    unsigned char *hbuf;
+    unsigned char *hbuf_uv;
+} BICUBIC_SCALER_STRUCT;
+
+int bicubic_coefficient_setup(int in_width, int in_height, int out_width, int out_height);
+int bicubic_scale(int in_width, int in_height, int in_stride,
+                  int out_width, int out_height, int out_stride,
+                  unsigned char *input_image, unsigned char *output_image);
+void bicubic_scale_frame_reset();
+void bicubic_scale_frame(YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
+                         int new_width, int new_height);
+void bicubic_coefficient_init();
+void bicubic_coefficient_destroy();
+
+#endif /* __VPX_SCALE_ARBITRARY_H__ */
diff --git a/vpx_scale/include/generic/vpxscale_depricated.h b/vpx_scale/include/generic/vpxscale_depricated.h
new file mode 100644 (file)
index 0000000..015eed0
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     postp.h
+*
+*   Description  :     Post processor interface
+*
+****************************************************************************/
+#ifndef VPXSCALE_H
+#define VPXSCALE_H
+
+extern void (*vp8_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_horizontal_line_1_2_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_3_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_4_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+extern void  dmachine_specific_config(int mmx_enabled, int xmm_enabled, int wmt_enabled);
+
+#endif
diff --git a/vpx_scale/include/generic/vpxscale_nofp.h b/vpx_scale/include/generic/vpxscale_nofp.h
new file mode 100644 (file)
index 0000000..c4d5f4c
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+void  vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_horizontal_line_1_2_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_3_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_2_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_4_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+void  vp8cx_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_horizontal_line_2_1_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_5_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_5_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+
+#define vp8_vertical_band_4_5_scale     vp8cx_vertical_band_4_5_scale_c
+#define vp8_last_vertical_band_4_5_scale vp8cx_last_vertical_band_4_5_scale_c
+#define vp8_vertical_band_2_3_scale     vp8cx_vertical_band_2_3_scale_c
+#define vp8_last_vertical_band_2_3_scale vp8cx_last_vertical_band_2_3_scale_c
+#define vp8_vertical_band_3_5_scale     vp8cx_vertical_band_3_5_scale_c
+#define vp8_last_vertical_band_3_5_scale vp8cx_last_vertical_band_3_5_scale_c
+#define vp8_horizontal_line_1_2_scale   vp8cx_horizontal_line_1_2_scale_c
+#define vp8_horizontal_line_3_5_scale   vp8cx_horizontal_line_3_5_scale_c
+#define vp8_horizontal_line_4_5_scale   vp8cx_horizontal_line_4_5_scale_c
+#define vp8_horizontal_line_2_3_scale   vp8cx_horizontal_line_2_3_scale_c
+#define vp8_vertical_band_1_2_scale     vp8cx_vertical_band_1_2_scale_c
+#define vp8_last_vertical_band_1_2_scale vp8cx_last_vertical_band_1_2_scale_c
+#define vp8_vertical_band_5_4_scale     vp8cx_vertical_band_5_4_scale_c
+#define vp8_vertical_band_5_3_scale     vp8cx_vertical_band_5_3_scale_c
+#define vp8_vertical_band_2_1_scale     vp8cx_vertical_band_2_1_scale_c
+#define vp8_vertical_band_2_1_scale_i   vp8cx_vertical_band_2_1_scale_i_c
+#define vp8_horizontal_line_2_1_scale   vp8cx_horizontal_line_2_1_scale_c
+#define vp8_horizontal_line_5_3_scale   vp8cx_horizontal_line_5_3_scale_c
+#define vp8_horizontal_line_5_4_scale   vp8cx_horizontal_line_5_4_scale_c
diff --git a/vpx_scale/include/leapster/vpxscale.h b/vpx_scale/include/leapster/vpxscale.h
new file mode 100644 (file)
index 0000000..f70029c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     postp.h
+*
+*   Description  :     Post processor interface
+*
+****************************************************************************/
+#ifndef VPXSCALE_H
+#define VPXSCALE_H
+
+
+// fwg 2004-10-14
+typedef void (*vpxvertical_band_4_5_scale_lf)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+typedef void (*vpxlast_vertical_band_4_5_scale_lf)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+typedef void (*vpxvertical_band_3_5_scale_lf)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+typedef void (*vpxlast_vertical_band_3_5_scale_lf)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+typedef void (*vpxhorizontal_line_1_2_scale_lf)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+typedef void (*vpxhorizontal_line_3_5_scale_lf)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+typedef void (*vpxhorizontal_line_4_5_scale_lf)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+typedef void (*vpxvertical_band_1_2_scale_lf)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+typedef void (*vpxlast_vertical_band_1_2_scale_lf)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+
+typedef struct vpxglobal_scalling_ptrs_t
+{
+    vpxvertical_band_4_5_scale_lf        vpxvertical_band_4_5_scale_t;
+    vpxlast_vertical_band_4_5_scale_lf    vpxlast_vertical_band_4_5_scale_t;
+    vpxvertical_band_3_5_scale_lf        vpxvertical_band_3_5_scale_t;
+    vpxlast_vertical_band_3_5_scale_lf    vpxlast_vertical_band_3_5_scale_t;
+    vpxhorizontal_line_1_2_scale_lf      vpxhorizontal_line_1_2_scale_t;
+    vpxhorizontal_line_3_5_scale_lf      vpxhorizontal_line_3_5_scale_t;
+    vpxhorizontal_line_4_5_scale_lf      vpxhorizontal_line_4_5_scale_t;
+    vpxvertical_band_1_2_scale_lf        vpxvertical_band_1_2_scale_t;
+    vpxlast_vertical_band_1_2_scale_lf    vpxlast_vertical_band_1_2_scale_t;
+} vpxglobal_scalling_ptrs;
+
+extern struct vpxglobal_scalling_ptrs_t *g_scaling_ptrs;
+
+/*
+extern void  (*vp8_vertical_band_4_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+extern void  (*vp8_last_vertical_band_4_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+extern void  (*vp8_vertical_band_3_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+extern void  (*vp8_last_vertical_band_3_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+extern void  (*vp8_horizontal_line_1_2_scale)(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width);
+extern void  (*vp8_horizontal_line_3_5_scale)(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width);
+extern void  (*vp8_horizontal_line_4_5_scale)(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width);
+extern void  (*vp8_vertical_band_1_2_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+extern void  (*vp8_last_vertical_band_1_2_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+*/
+
+#endif
diff --git a/vpx_scale/include/symbian/vpxscale_nofp.h b/vpx_scale/include/symbian/vpxscale_nofp.h
new file mode 100644 (file)
index 0000000..d6181d2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+void  vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_horizontal_line_1_2_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_3_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_3_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_2_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_4_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+void  vp8cx_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void  vp8cx_horizontal_line_2_1_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_5_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void  vp8cx_horizontal_line_5_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+
+void horizontal_line_4_5_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_2_3_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_3_5_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_3_4_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_1_2_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vertical_band_4_5_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_2_3_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_3_5_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_3_4_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_1_2_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+#define vp8_vertical_band_4_5_scale     vertical_band_4_5_scale_armv4
+#define vp8_last_vertical_band_4_5_scale vp8cx_last_vertical_band_4_5_scale_c
+#define vp8_vertical_band_2_3_scale     vertical_band_2_3_scale_armv4
+#define vp8_last_vertical_band_2_3_scale vp8cx_last_vertical_band_2_3_scale_c
+#define vp8_vertical_band_3_5_scale     vertical_band_3_5_scale_armv4
+#define vp8_last_vertical_band_3_5_scale vp8cx_last_vertical_band_3_5_scale_c
+#define vp8_vertical_band_3_4_scale     vertical_band_3_4_scale_armv4
+#define vp8_last_vertical_band_3_4_scale vp8cx_last_vertical_band_3_4_scale_c
+#define vp8_horizontal_line_1_2_scale   horizontal_line_1_2_scale_armv4
+#define vp8_horizontal_line_3_5_scale   horizontal_line_3_5_scale_armv4
+#define vp8_horizontal_line_3_4_scale   horizontal_line_3_4_scale_armv4
+#define vp8_horizontal_line_4_5_scale   horizontal_line_4_5_scale_armv4
+#define vp8_horizontal_line_2_3_scale   horizontal_line_2_3_scale_armv4
+#define vp8_vertical_band_1_2_scale     vertical_band_1_2_scale_armv4
+#define vp8_last_vertical_band_1_2_scale vp8cx_last_vertical_band_1_2_scale_c
+#define vp8_vertical_band_5_4_scale     vp8cx_vertical_band_5_4_scale_c
+#define vp8_vertical_band_5_3_scale     vp8cx_vertical_band_5_3_scale_c
+#define vp8_vertical_band_2_1_scale     vp8cx_vertical_band_2_1_scale_c
+#define vp8_vertical_band_2_1_scale_i   vp8cx_vertical_band_2_1_scale_i_c
+#define vp8_horizontal_line_2_1_scale   vp8cx_horizontal_line_2_1_scale_c
+#define vp8_horizontal_line_5_3_scale   vp8cx_horizontal_line_5_3_scale_c
+#define vp8_horizontal_line_5_4_scale   vp8cx_horizontal_line_5_4_scale_c
diff --git a/vpx_scale/include/vpxscale_nofp.h b/vpx_scale/include/vpxscale_nofp.h
new file mode 100644 (file)
index 0000000..f6482f9
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#if defined(__S60_V20__) || defined(__SYMBIAN32__) && !defined(__WINS__)
+#include "symbian\vpxscale_nofp.h"
+#else
+#include "generic\vpxscale_nofp.h"
+#endif
diff --git a/vpx_scale/intel_linux/scaleopt.c b/vpx_scale/intel_linux/scaleopt.c
new file mode 100644 (file)
index 0000000..6555600
--- /dev/null
@@ -0,0 +1,1852 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     scaleopt.cpp
+*
+*   Description  :     Optimized scaling functions
+*
+****************************************************************************/
+#include "pragmas.h"
+
+/****************************************************************************
+*  Module Statics
+****************************************************************************/
+#if 0
+__declspec(align(16)) const static unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+__declspec(align(16)) const static unsigned short two_fifths[] = { 102, 102, 102, 102 };
+__declspec(align(16)) const static unsigned short three_fifths[] = { 154, 154, 154, 154 };
+__declspec(align(16)) const static unsigned short four_fifths[] = { 205, 205, 205, 205 };
+__declspec(align(16)) const static unsigned short round_values[] = { 128, 128, 128, 128 };
+__declspec(align(16)) const static unsigned short four_ones[] = { 1, 1, 1, 1};
+__declspec(align(16)) const static unsigned short const45_2[] = {205, 154, 102,  51 };
+__declspec(align(16)) const static unsigned short const45_1[] = { 51, 102, 154, 205 };
+__declspec(align(16)) const static unsigned char  mask45[] = { 0, 0, 0, 0, 0, 0, 255, 0};
+__declspec(align(16)) const static unsigned short const35_2[] = { 154,  51, 205, 102 };
+__declspec(align(16)) const static unsigned short const35_1[] = { 102, 205,  51, 154 };
+#endif
+
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_3_5_scale_mmx
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 3 to 5 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_3_5_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16)) unsigned short const35_2[] = { 154,  51, 205, 102 };
+    __declspec(align(16)) unsigned short const35_1[] = { 102, 205,  51, 154 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+
+    (void) dest_width;
+
+    __asm
+    {
+
+        push ebx
+
+        mov         esi,    source
+        mov         edi,    dest
+
+        mov         ecx,    source_width
+        lea         edx,    [esi+ecx-3];
+
+        movq        mm5,    const35_1       // mm5 = 66 xx cd xx 33 xx 9a xx
+        movq        mm6,    const35_2       // mm6 = 9a xx 33 xx cd xx 66 xx
+
+        movq        mm4,    round_values     // mm4 = 80 xx 80 xx 80 xx 80 xx
+        pxor        mm7,    mm7             // clear mm7
+
+        horiz_line_3_5_loop:
+
+        mov        eax,    DWORD PTR [esi] // eax = 00 01 02 03
+        mov        ebx,    eax
+
+        and         ebx,    0xffff00        // ebx = xx 01 02 xx
+        mov         ecx,    eax             // ecx = 00 01 02 03
+
+        and         eax,    0xffff0000      // eax = xx xx 02 03
+        xor         ecx,    eax             // ecx = 00 01 xx xx
+
+        shr         ebx,    8               // ebx = 01 02 xx xx
+        or          eax,    ebx             // eax = 01 02 02 03
+
+        shl         ebx,    16              // ebx = xx xx 01 02
+        movd        mm1,    eax             // mm1 = 01 02 02 03 xx xx xx xx
+
+        or          ebx,    ecx             // ebx = 00 01 01 02
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 02 xx 03 xx
+
+        movd        mm0,    ebx             // mm0 = 00 01 01 02
+        pmullw      mm1,    mm6             //
+
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 01 xx 02 xx
+        pmullw      mm0,    mm5             //
+
+        mov         [edi],  ebx             // writeoutput 00 xx xx xx
+        add         esi,    3
+
+        add         edi,    5
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm4
+        psrlw       mm0,    8
+
+        cmp         esi,    edx
+        packuswb    mm0,    mm7
+
+        movd        DWORD Ptr [edi-4], mm0
+        jl          horiz_line_3_5_loop
+
+//Exit:
+        mov         eax,    DWORD PTR [esi] // eax = 00 01 02 03
+        mov         ebx,    eax
+
+        and         ebx,    0xffff00        // ebx = xx 01 02 xx
+        mov         ecx,    eax             // ecx = 00 01 02 03
+
+        and         eax,    0xffff0000      // eax = xx xx 02 03
+        xor         ecx,    eax             // ecx = 00 01 xx xx
+
+        shr         ebx,    8               // ebx = 01 02 xx xx
+        or          eax,    ebx             // eax = 01 02 02 03
+
+        shl         eax,    8               // eax = xx 01 02 02
+        and         eax,    0xffff0000      // eax = xx xx 02 02
+
+        or          eax,    ebx             // eax = 01 02 02 02
+
+        shl         ebx,    16              // ebx = xx xx 01 02
+        movd        mm1,    eax             // mm1 = 01 02 02 02 xx xx xx xx
+
+        or          ebx,    ecx             // ebx = 00 01 01 02
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 02 xx 02 xx
+
+        movd        mm0,    ebx             // mm0 = 00 01 01 02
+        pmullw      mm1,    mm6             //
+
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 01 xx 02 xx
+        pmullw      mm0,    mm5             //
+
+        mov         [edi],  ebx             // writeoutput 00 xx xx xx
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm4
+        psrlw       mm0,    8
+
+        packuswb    mm0,    mm7
+        movd        DWORD Ptr [edi+1], mm0
+
+        pop ebx
+
+    }
+
+    /*
+    const unsigned char *src = source;
+    unsigned char *des = dest;
+    unsigned int a, b, c ;
+    unsigned int i;
+    (void) dest_width;
+
+    for ( i=0; i<source_width-3; i+=3 )
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (UINT8) (a);
+        // 2 * left + 3 * right /5
+        des [1] = (UINT8) (( a * 102 + 154 * b + 128 ) >> 8);
+        c = src[2] ;
+        // 4 * left + 1 * right /5
+        des [2] = (UINT8) (( b * 205 + c * 51 + 128 ) >> 8);
+        // 1 * left + 4 * right /5
+        des [3] = (UINT8) (( b * 51 + c * 205 + 128 ) >> 8);
+
+        a = src[3];
+        // 3 * left + 2 * right /5
+        des [4] = (UINT8) (( c * 154 + a * 102 + 128 ) >> 8);
+
+        src += 3;
+        des += 5;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (UINT8) (a);
+    // 2 * left + 3 * right /5
+    des [1] = (UINT8) (( a * 102 + 154 * b + 128 ) >> 8);
+    c = src[2] ;
+    // 4 * left + 1 * right /5
+    des [2] = (UINT8) (( b * 205 + c * 51 + 128 ) >> 8);
+    // 1 * left + 4 * right /5
+    des [3] = (UINT8) (( b * 51 + c * 205 + 128 ) >> 8);
+
+    des [4] = (UINT8) (c);
+    */
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_4_5_scale_mmx
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 4 to 5 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_4_5_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    __declspec(align(16)) unsigned short const45_2[] = {205, 154, 102,  51 };
+    __declspec(align(16)) unsigned short const45_1[] = { 51, 102, 154, 205 };
+    __declspec(align(16)) unsigned char  mask45[] = { 0, 0, 0, 0, 0, 0, 255, 0};
+
+    (void)dest_width;
+
+    __asm
+    {
+
+        mov         esi,    source
+        mov         edi,    dest
+
+        mov         ecx,    source_width
+        lea         edx,    [esi+ecx-8];
+
+        movq        mm5,    const45_1       // mm5 = 33 xx 66 xx 9a xx cd xx
+        movq        mm6,    const45_2       // mm6 = cd xx 9a xx 66 xx 33 xx
+
+        movq        mm4,    round_values     // mm4 = 80 xx 80 xx 80 xx 80 xx
+        pxor        mm7,    mm7             // clear mm7
+
+        horiz_line_4_5_loop:
+
+        movq        mm0,    QWORD PTR [esi]           // mm0 = 00 01 02 03 04 05 06 07
+        movq        mm1,    QWORD PTR [esi+1];        // mm1 = 01 02 03 04 05 06 07 08
+
+        movq        mm2,    mm0             // mm2 = 00 01 02 03 04 05 06 07
+        movq        mm3,    mm1             // mm3 = 01 02 03 04 05 06 07 08
+
+        movd        DWORD PTR [edi],  mm0             // write output 00 xx xx xx
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 02 xx 03 xx
+
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 03 xx 04 xx
+        pmullw      mm0,    mm5             // 00* 51 01*102 02*154 03*205
+
+        pmullw      mm1,    mm6             // 01*205 02*154 03*102 04* 51
+        punpckhbw   mm2,    mm7             // mm2 = 04 xx 05 xx 06 xx 07 xx
+
+        movd        DWORD PTR [edi+5], mm2            // write ouput 05 xx xx xx
+        pmullw      mm2,    mm5             // 04* 51 05*102 06*154 07*205
+
+        punpckhbw   mm3,    mm7             // mm3 = 05 xx 06 xx 07 xx 08 xx
+        pmullw      mm3,    mm6             // 05*205 06*154 07*102 08* 51
+
+        paddw       mm0,    mm1             // added round values
+        paddw       mm0,    mm4
+
+        psrlw       mm0,    8               // output: 01 xx 02 xx 03 xx 04 xx
+        packuswb    mm0,    mm7
+
+        movd        DWORD PTR [edi+1], mm0  // write output 01 02 03 04
+        add         edi,    10
+
+        add         esi,    8
+        paddw       mm2,    mm3             //
+
+        paddw       mm2,    mm4             // added round values
+        cmp         esi,    edx
+
+        psrlw       mm2,    8
+        packuswb    mm2,    mm7
+
+        movd        DWORD PTR [edi-4], mm2 // writeoutput 06 07 08 09
+        jl         horiz_line_4_5_loop
+
+//Exit:
+        movq        mm0,    [esi]           // mm0 = 00 01 02 03 04 05 06 07
+        movq        mm1,    mm0             // mm1 = 00 01 02 03 04 05 06 07
+
+        movq        mm2,    mm0             // mm2 = 00 01 02 03 04 05 06 07
+        psrlq       mm1,    8               // mm1 = 01 02 03 04 05 06 07 00
+
+        movq        mm3,    mask45          // mm3 = 00 00 00 00 00 00 ff 00
+        pand        mm3,    mm1             // mm3 = 00 00 00 00 00 00 07 00
+
+        psllq       mm3,    8               // mm3 = 00 00 00 00 00 00 00 07
+        por         mm1,    mm3             // mm1 = 01 02 03 04 05 06 07 07
+
+        movq        mm3,    mm1
+
+        movd        DWORD PTR [edi],  mm0   // write output 00 xx xx xx
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 02 xx 03 xx
+
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 03 xx 04 xx
+        pmullw      mm0,    mm5             // 00* 51 01*102 02*154 03*205
+
+        pmullw      mm1,    mm6             // 01*205 02*154 03*102 04* 51
+        punpckhbw   mm2,    mm7             // mm2 = 04 xx 05 xx 06 xx 07 xx
+
+        movd        DWORD PTR [edi+5], mm2  // write ouput 05 xx xx xx
+        pmullw      mm2,    mm5             // 04* 51 05*102 06*154 07*205
+
+        punpckhbw   mm3,    mm7             // mm3 = 05 xx 06 xx 07 xx 08 xx
+        pmullw      mm3,    mm6             // 05*205 06*154 07*102 07* 51
+
+        paddw       mm0,    mm1             // added round values
+        paddw       mm0,    mm4
+
+        psrlw       mm0,    8               // output: 01 xx 02 xx 03 xx 04 xx
+        packuswb    mm0,    mm7             // 01 02 03 04 xx xx xx xx
+
+        movd        DWORD PTR [edi+1], mm0  // write output 01 02 03 04
+        paddw       mm2,    mm3             //
+
+        paddw       mm2,    mm4             // added round values
+        psrlw       mm2,    8
+
+        packuswb    mm2,    mm7
+        movd        DWORD PTR [edi+6], mm2  // writeoutput 06 07 08 09
+
+
+    }
+    /*
+        const unsigned char *src = source;
+        unsigned char *des = dest;
+        unsigned int a, b, c ;
+        unsigned i;
+        (void) dest_width;
+
+        for ( i=0; i<source_width-4; i+=4 )
+        {
+            a = src[0];
+            b = src[1];
+            des [0] = (UINT8) a;
+            des [1] = (UINT8) (( a * 51 + 205 * b + 128) >> 8);
+            c = src[2] * 154;
+            a = src[3];
+            des [2] = (UINT8) (( b * 102 + c + 128) >> 8);
+            des [3] = (UINT8) (( c + 102 * a + 128) >> 8);
+            b = src[4];
+            des [4] = (UINT8) (( a * 205 + 51 * b + 128) >> 8);
+
+            src += 4;
+            des += 5;
+        }
+
+        a = src[0];
+        b = src[1];
+        des [0] = (UINT8) (a);
+        des [1] = (UINT8) (( a * 51 + 205 * b + 128) >> 8);
+        c = src[2] * 154;
+        a = src[3];
+        des [2] = (UINT8) (( b * 102 + c + 128) >> 8);
+        des [3] = (UINT8) (( c + 102 * a + 128) >> 8);
+        des [4] = (UINT8) (a);
+    */
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_4_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 4 to 5 up-scaling of a 4 pixel high band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has a "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void vertical_band_4_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+
+    __declspec(align(16)) unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+    __declspec(align(16)) unsigned short two_fifths[] = { 102, 102, 102, 102 };
+    __declspec(align(16)) unsigned short three_fifths[] = { 154, 154, 154, 154 };
+    __declspec(align(16)) unsigned short four_fifths[] = { 205, 205, 205, 205 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+
+    __asm
+    {
+
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_4_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    one_fifth
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 1/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 1/5
+        movq        mm6,    four_fifths               // constan
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 4/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 4/5
+        paddw       mm0,    mm4                     // a * 1/5 + b * 4/5
+
+        paddw       mm2,    mm5                     // a * 1/5 + b * 4/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm5,    two_fifths
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm1,    mm5                     // b * 2/5
+        movq        mm6,    three_fifths
+
+
+        punpcklbw   mm0,    mm7                     // unpack low to word
+        pmullw      mm3,    mm5                     // b * 2/5
+
+        movq        mm4,    mm0                     // make copy of c
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm4,    mm6                     // c * 3/5
+        movq        mm5,    mm2
+
+        pmullw      mm5,    mm6                     // c * 3/5
+        paddw       mm1,    mm4                     // b * 2/5 + c * 3/5
+
+        paddw       mm3,    mm5                     // b * 2/5 + c * 3/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[2]
+
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+        movq        mm1,    [edi]                   // mm1=Src[3];
+
+        // mm0, mm2 --- Src[2]
+        // mm1 --- Src[3]
+        // mm6 --- 3/5
+        // mm7 for unpacking
+
+        pmullw      mm0,    mm6                     // c * 3/5
+        movq        mm5,    two_fifths               // mm5 = 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        pmullw      mm2,    mm6                     // c * 3/5
+
+        punpcklbw   mm1,    mm7                     // unpack low
+        movq        mm4,    mm1                     // make a copy
+
+        punpckhbw   mm3,    mm7                     // unpack high
+        pmullw      mm4,    mm5                     // d * 2/5
+
+        movq        mm6,    mm3                     // make a copy
+        pmullw      mm6,    mm5                     // d * 2/5
+
+        paddw       mm0,    mm4                     // c * 3/5 + d * 2/5
+        paddw       mm2,    mm6                     // c * 3/5 + d * 2/5
+
+        paddw       mm0,    round_values             // + 128
+        paddw       mm2,    round_values             // + 128
+
+        psrlw       mm0,    8
+        psrlw       mm2,    8
+
+        packuswb    mm0,    mm2                     // des[3]
+        movq        QWORD ptr [edi], mm0            // write des[3]
+
+        //  mm1, mm3 --- Src[3]
+        //  mm7 -- cleared for unpacking
+
+        movq        mm0,    [edi+ecx*2]             // mm0, Src[0] of the next group
+
+        movq        mm5,    four_fifths              // mm5 = 4/5
+        pmullw      mm1,    mm5                     // d * 4/5
+
+        movq        mm6,    one_fifth                // mm6 = 1/5
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm3,    mm5                     // d * 4/5
+        punpcklbw   mm0,    mm7                     // unpack low
+
+        pmullw      mm0,    mm6                     // an * 1/5
+        punpckhbw   mm2,    mm7                     // unpack high
+
+        paddw       mm1,    mm0                     // d * 4/5 + an * 1/5
+        pmullw      mm2,    mm6                     // an * 1/5
+
+        paddw       mm3,    mm2                     // d * 4/5 + an * 1/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[4]
+
+        movq        QWORD ptr [edi+ecx], mm1        // write des[4]
+
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg         vs_4_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_4_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : None
+ *
+ *  FUNCTION      : 4 to 5 up-scaling of the last 4-pixel high band in an image.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_4_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16)) unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+    __declspec(align(16)) unsigned short two_fifths[] = { 102, 102, 102, 102 };
+    __declspec(align(16)) unsigned short three_fifths[] = { 154, 154, 154, 154 };
+    __declspec(align(16)) unsigned short four_fifths[] = { 205, 205, 205, 205 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        last_vs_4_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    one_fifth
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 1/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 1/5
+        movq        mm6,    four_fifths               // constan
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 4/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 4/5
+        paddw       mm0,    mm4                     // a * 1/5 + b * 4/5
+
+        paddw       mm2,    mm5                     // a * 1/5 + b * 4/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm5,    two_fifths
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm1,    mm5                     // b * 2/5
+        movq        mm6,    three_fifths
+
+
+        punpcklbw   mm0,    mm7                     // unpack low to word
+        pmullw      mm3,    mm5                     // b * 2/5
+
+        movq        mm4,    mm0                     // make copy of c
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm4,    mm6                     // c * 3/5
+        movq        mm5,    mm2
+
+        pmullw      mm5,    mm6                     // c * 3/5
+        paddw       mm1,    mm4                     // b * 2/5 + c * 3/5
+
+        paddw       mm3,    mm5                     // b * 2/5 + c * 3/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[2]
+
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+        movq        mm1,    [edi]                   // mm1=Src[3];
+
+        movq        QWORD ptr [edi+ecx], mm1        // write des[4];
+
+        // mm0, mm2 --- Src[2]
+        // mm1 --- Src[3]
+        // mm6 --- 3/5
+        // mm7 for unpacking
+
+        pmullw      mm0,    mm6                     // c * 3/5
+        movq        mm5,    two_fifths               // mm5 = 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        pmullw      mm2,    mm6                     // c * 3/5
+
+        punpcklbw   mm1,    mm7                     // unpack low
+        movq        mm4,    mm1                     // make a copy
+
+        punpckhbw   mm3,    mm7                     // unpack high
+        pmullw      mm4,    mm5                     // d * 2/5
+
+        movq        mm6,    mm3                     // make a copy
+        pmullw      mm6,    mm5                     // d * 2/5
+
+        paddw       mm0,    mm4                     // c * 3/5 + d * 2/5
+        paddw       mm2,    mm6                     // c * 3/5 + d * 2/5
+
+        paddw       mm0,    round_values             // + 128
+        paddw       mm2,    round_values             // + 128
+
+        psrlw       mm0,    8
+        psrlw       mm2,    8
+
+        packuswb    mm0,    mm2                     // des[3]
+        movq        QWORD ptr [edi], mm0            // write des[3]
+
+        //  mm1, mm3 --- Src[3]
+        //  mm7 -- cleared for unpacking
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg          last_vs_4_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_3_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 3 to 5 up-scaling of a 3-pixel high band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void vertical_band_3_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16)) unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+    __declspec(align(16)) unsigned short two_fifths[] = { 102, 102, 102, 102 };
+    __declspec(align(16)) unsigned short three_fifths[] = { 154, 154, 154, 154 };
+    __declspec(align(16)) unsigned short four_fifths[] = { 205, 205, 205, 205 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_3_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    two_fifths               // mm5 = 2/5
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 2/5
+        movq        mm6,    three_fifths             // mm6 = 3/5
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 3/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 3/5
+        paddw       mm0,    mm4                     // a * 2/5 + b * 3/5
+
+        paddw       mm2,    mm5                     // a * 2/5 + b * 3/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm4,    mm1                     // b low
+        pmullw      mm1,    four_fifths              // b * 4/5 low
+
+        movq        mm5,    mm3                     // b high
+        pmullw      mm3,    four_fifths              // b * 4/5 high
+
+        movq        mm2,    mm0                     // c
+        pmullw      mm4,    one_fifth                // b * 1/5
+
+        punpcklbw   mm0,    mm7                     // c low
+        pmullw      mm5,    one_fifth                // b * 1/5
+
+        movq        mm6,    mm0                     // make copy of c low
+        punpckhbw   mm2,    mm7                     // c high
+
+        pmullw      mm6,    one_fifth                // c * 1/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    one_fifth                // c * 1/5 high
+        paddw       mm1,    mm6                     // b * 4/5 + c * 1/5 low
+
+        paddw       mm3,    mm7                     // b * 4/5 + c * 1/5 high
+        movq        mm6,    mm0                     // make copy of c low
+
+        pmullw      mm6,    four_fifths              // c * 4/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    four_fifths              // c * 4/5 high
+
+        paddw       mm4,    mm6                     // b * 1/5 + c * 4/5 low
+        paddw       mm5,    mm7                     // b * 1/5 + c * 4/5 high
+
+        paddw       mm1,    round_values             // + 128
+        paddw       mm3,    round_values             // + 128
+
+        psrlw       mm1,    8
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm3                     // des[2]
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+
+        paddw       mm4,    round_values             // + 128
+        paddw       mm5,    round_values             // + 128
+
+        psrlw       mm4,    8
+        psrlw       mm5,    8
+
+        packuswb    mm4,    mm5                     // des[3]
+        movq        QWORD ptr [edi], mm4            // write des[3]
+
+        //  mm0, mm2 --- Src[3]
+
+        pxor        mm7,    mm7                     // clear mm7 for unpacking
+        movq        mm1,    [edi+ecx*2]             // mm1 = Src[0] of the next group
+
+        movq        mm5,    three_fifths             // mm5 = 3/5
+        pmullw      mm0,    mm5                     // d * 3/5
+
+        movq        mm6,    two_fifths                // mm6 = 2/5
+        movq        mm3,    mm1                     // make a copy
+
+        pmullw      mm2,    mm5                     // d * 3/5
+        punpcklbw   mm1,    mm7                     // unpack low
+
+        pmullw      mm1,    mm6                     // an * 2/5
+        punpckhbw   mm3,    mm7                     // unpack high
+
+        paddw       mm0,    mm1                     // d * 3/5 + an * 2/5
+        pmullw      mm3,    mm6                     // an * 2/5
+
+        paddw       mm2,    mm3                     // d * 3/5 + an * 2/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des[4]
+
+        movq        QWORD ptr [edi+ecx], mm0        // write des[4]
+
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg          vs_3_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_3_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 3 to 5 up-scaling of a 3-pixel high band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_3_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16)) unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+    __declspec(align(16)) unsigned short two_fifths[] = { 102, 102, 102, 102 };
+    __declspec(align(16)) unsigned short three_fifths[] = { 154, 154, 154, 154 };
+    __declspec(align(16)) unsigned short four_fifths[] = { 205, 205, 205, 205 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+
+        last_vs_3_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    two_fifths               // mm5 = 2/5
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 2/5
+        movq        mm6,    three_fifths             // mm6 = 3/5
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 3/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 3/5
+        paddw       mm0,    mm4                     // a * 2/5 + b * 3/5
+
+        paddw       mm2,    mm5                     // a * 2/5 + b * 3/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm4,    mm1                     // b low
+        pmullw      mm1,    four_fifths              // b * 4/5 low
+
+        movq        QWORD ptr [edi+ecx], mm0        // write des[4]
+
+        movq        mm5,    mm3                     // b high
+        pmullw      mm3,    four_fifths              // b * 4/5 high
+
+        movq        mm2,    mm0                     // c
+        pmullw      mm4,    one_fifth                // b * 1/5
+
+        punpcklbw   mm0,    mm7                     // c low
+        pmullw      mm5,    one_fifth                // b * 1/5
+
+        movq        mm6,    mm0                     // make copy of c low
+        punpckhbw   mm2,    mm7                     // c high
+
+        pmullw      mm6,    one_fifth                // c * 1/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    one_fifth                // c * 1/5 high
+        paddw       mm1,    mm6                     // b * 4/5 + c * 1/5 low
+
+        paddw       mm3,    mm7                     // b * 4/5 + c * 1/5 high
+        movq        mm6,    mm0                     // make copy of c low
+
+        pmullw      mm6,    four_fifths              // c * 4/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    four_fifths              // c * 4/5 high
+
+        paddw       mm4,    mm6                     // b * 1/5 + c * 4/5 low
+        paddw       mm5,    mm7                     // b * 1/5 + c * 4/5 high
+
+        paddw       mm1,    round_values             // + 128
+        paddw       mm3,    round_values             // + 128
+
+        psrlw       mm1,    8
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm3                     // des[2]
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+
+        paddw       mm4,    round_values             // + 128
+        paddw       mm5,    round_values             // + 128
+
+        psrlw       mm4,    8
+        psrlw       mm5,    8
+
+        packuswb    mm4,    mm5                     // des[3]
+        movq        QWORD ptr [edi], mm4            // write des[3]
+
+        //  mm0, mm2 --- Src[3]
+
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg          last_vs_3_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_1_2_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of a band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void vertical_band_1_2_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16))unsigned short four_ones[] = { 1, 1, 1, 1};
+
+    __asm
+    {
+
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_1_2_loop:
+
+        movq        mm0,    [esi]                   // get Src[0]
+        movq        mm1,    [esi + ecx * 2]         // get Src[1]
+
+        movq        mm2,    mm0                     // make copy before unpack
+        movq        mm3,    mm1                     // make copy before unpack
+
+        punpcklbw   mm0,    mm7                     // low Src[0]
+        movq        mm6,    four_ones                // mm6= 1, 1, 1, 1
+
+        punpcklbw   mm1,    mm7                     // low Src[1]
+        paddw       mm0,    mm1                     // low (a + b)
+
+        punpckhbw   mm2,    mm7                     // high Src[0]
+        paddw       mm0,    mm6                     // low (a + b + 1)
+
+        punpckhbw   mm3,    mm7
+        paddw       mm2,    mm3                     // high (a + b )
+
+        psraw       mm0,    1                       // low (a + b +1 )/2
+        paddw       mm2,    mm6                     // high (a + b + 1)
+
+        psraw       mm2,    1                       // high (a + b + 1)/2
+        packuswb    mm0,    mm2                     // pack results
+
+        movq        [esi+ecx], mm0                  // write out eight bytes
+        add         esi,    8
+
+        sub         edx,    8
+        jg          vs_1_2_loop
+    }
+
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_1_2_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_1_2_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        mov         edx,    dest_width               // Loop counter
+
+        last_vs_1_2_loop:
+
+        movq        mm0,    [esi]                   // get Src[0]
+        movq        [esi+ecx], mm0                  // write out eight bytes
+
+        add         esi,    8
+        sub         edx,    8
+
+        jg         last_vs_1_2_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_1_2_scale
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_1_2_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16))unsigned short four_ones[] = { 1, 1, 1, 1};
+
+    (void) dest_width;
+
+    __asm
+    {
+        mov         esi,    source
+        mov         edi,    dest
+
+        pxor        mm7,    mm7
+        movq        mm6,    four_ones
+
+        mov         ecx,    source_width
+
+        hs_1_2_loop:
+
+        movq        mm0,    [esi]
+        movq        mm1,    [esi+1]
+
+        movq        mm2,    mm0
+        movq        mm3,    mm1
+
+        movq        mm4,    mm0
+        punpcklbw   mm0,    mm7
+
+        punpcklbw   mm1,    mm7
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm6
+        punpckhbw   mm2,    mm7
+
+        punpckhbw   mm3,    mm7
+        paddw       mm2,    mm3
+
+        paddw       mm2,    mm6
+        psraw       mm0,    1
+
+        psraw       mm2,    1
+        packuswb    mm0,    mm2
+
+        movq        mm2,    mm4
+        punpcklbw   mm2,    mm0
+
+        movq        [edi],  mm2
+        punpckhbw   mm4,    mm0
+
+        movq        [edi+8], mm4
+        add         esi,    8
+
+        add         edi,    16
+        sub         ecx,    8
+
+        cmp         ecx,    8
+        jg          hs_1_2_loop
+
+// last eight pixel
+
+        movq        mm0,    [esi]
+        movq        mm1,    mm0
+
+        movq        mm2,    mm0
+        movq        mm3,    mm1
+
+        psrlq       mm1,    8
+        psrlq       mm3,    56
+
+        psllq       mm3,    56
+        por         mm1,    mm3
+
+        movq        mm3,    mm1
+        movq        mm4,    mm0
+
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+
+        paddw       mm0,    mm1
+        paddw       mm0,    mm6
+
+        punpckhbw   mm2,    mm7
+        punpckhbw   mm3,    mm7
+
+        paddw       mm2,    mm3
+        paddw       mm2,    mm6
+
+        psraw       mm0,    1
+        psraw       mm2,    1
+
+        packuswb    mm0,    mm2
+        movq        mm2,    mm4
+
+        punpcklbw   mm2,    mm0
+        movq        [edi],  mm2
+
+        punpckhbw   mm4,    mm0
+        movq        [edi+8], mm4
+    }
+}
+
+
+
+
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_5_4_scale_mmx
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 4 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_5_4_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+
+    __declspec(align(16)) const unsigned short const54_2[] = {  0,  64, 128, 192 };
+    __declspec(align(16)) const unsigned short const54_1[] = {256, 192, 128,  64 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    /*
+    unsigned i;
+    unsigned int a, b, c, d, e;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for ( i=0; i<source_width; i+=5 )
+    {
+        a = src[0];
+        b = src[1];
+        c = src[2];
+        d = src[3];
+        e = src[4];
+
+        des[0] = a;
+        des[1] = ((b*192 + c* 64 + 128)>>8);
+        des[2] = ((c*128 + d*128 + 128)>>8);
+        des[3] = ((d* 64 + e*192 + 128)>>8);
+
+        src += 5;
+        des += 4;
+    }
+    */
+    __asm
+    {
+
+        mov         esi,        source              ;
+        mov         edi,        dest                ;
+
+        mov         ecx,        source_width         ;
+        movq        mm5,        const54_1           ;
+
+        pxor        mm7,        mm7                 ;
+        movq        mm6,        const54_2           ;
+
+        movq        mm4,        round_values         ;
+        lea         edx,        [esi+ecx]           ;
+        horizontal_line_5_4_loop:
+
+        movq        mm0,        QWORD PTR  [esi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psrlq       mm0,        8                   ;
+        01 02 03 04 05 06 07 xx
+        punpcklbw   mm1,        mm7                 ;
+        xx 00 xx 01 xx 02 xx 03
+
+        punpcklbw   mm0,        mm7                 ;
+        xx 01 xx 02 xx 03 xx 04
+        pmullw      mm1,        mm5
+
+        pmullw      mm0,        mm6
+        add         esi,        5
+
+        add         edi,        4
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        cmp         esi,        edx
+        packuswb    mm1,        mm7
+
+        movd        DWORD PTR [edi-4], mm1
+
+        jl          horizontal_line_5_4_loop
+
+    }
+
+}
+
+static
+void vertical_band_5_4_scale_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+
+    __declspec(align(16)) const unsigned short one_fourths[]   = {  64,  64,  64, 64  };
+    __declspec(align(16)) const unsigned short two_fourths[]   = { 128, 128, 128, 128 };
+    __declspec(align(16)) const unsigned short three_fourths[] = { 192, 192, 192, 192 };
+
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    __asm
+    {
+        push        ebx
+
+        mov         esi,    source                    // Get the source and destination pointer
+        mov         ecx,    src_pitch               // Get the pitch size
+
+        mov         edi,    dest                    // tow lines below
+        pxor        mm7,    mm7                     // clear out mm7
+
+        mov         edx,    dest_pitch               // Loop counter
+        mov         ebx,    dest_width
+
+        vs_5_4_loop:
+
+        movd        mm0,    DWORD ptr [esi]         // src[0];
+        movd        mm1,    DWORD ptr [esi+ecx]     // src[1];
+
+        movd        mm2,    DWORD ptr [esi+ecx*2]
+        lea         eax,    [esi+ecx*2]             //
+
+        punpcklbw   mm1,    mm7
+        punpcklbw   mm2,    mm7
+
+        movq        mm3,    mm2
+        pmullw      mm1,    three_fourths
+
+        pmullw      mm2,    one_fourths
+        movd        mm4,    [eax+ecx]
+
+        pmullw      mm3,    two_fourths
+        punpcklbw   mm4,    mm7
+
+        movq        mm5,    mm4
+        pmullw      mm4,    two_fourths
+
+        paddw       mm1,    mm2
+        movd        mm6,    [eax+ecx*2]
+
+        pmullw      mm5,    one_fourths
+        paddw       mm1,    round_values;
+
+        paddw       mm3,    mm4
+        psrlw       mm1,    8
+
+        punpcklbw   mm6,    mm7
+        paddw       mm3,    round_values
+
+        pmullw      mm6,    three_fourths
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm7
+        packuswb    mm3,    mm7
+
+        movd        DWORD PTR [edi], mm0
+        movd        DWORD PTR [edi+edx], mm1
+
+
+        paddw       mm5,    mm6
+        movd        DWORD PTR [edi+edx*2], mm3
+
+        lea         eax,    [edi+edx*2]
+        paddw       mm5,    round_values
+
+        psrlw       mm5,    8
+        add         edi,    4
+
+        packuswb    mm5,    mm7
+        movd        DWORD PTR [eax+edx], mm5
+
+        add         esi,    4
+        sub         ebx,    4
+
+        jg         vs_5_4_loop
+
+        pop         ebx
+    }
+}
+
+
+
+static
+void horizontal_line_5_3_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    __declspec(align(16)) const unsigned short const53_1[] = {  0,  85, 171, 0 };
+    __declspec(align(16)) const unsigned short const53_2[] = {256, 171,  85, 0 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    __asm
+    {
+
+        mov         esi,        source              ;
+        mov         edi,        dest                ;
+
+        mov         ecx,        source_width         ;
+        movq        mm5,        const53_1           ;
+
+        pxor        mm7,        mm7                 ;
+        movq        mm6,        const53_2           ;
+
+        movq        mm4,        round_values         ;
+        lea         edx,        [esi+ecx-5]         ;
+        horizontal_line_5_3_loop:
+
+        movq        mm0,        QWORD PTR  [esi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psllw       mm0,        8                   ;
+        xx 00 xx 02 xx 04 xx 06
+        psrlw       mm1,        8                   ;
+        01 xx 03 xx 05 xx 07 xx
+
+        psrlw       mm0,        8                   ;
+        00 xx 02 xx 04 xx 06 xx
+        psllq       mm1,        16                  ;
+        xx xx 01 xx 03 xx 05 xx
+
+        pmullw      mm0,        mm6
+
+        pmullw      mm1,        mm5
+        add         esi,        5
+
+        add         edi,        3
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        cmp         esi,        edx
+        packuswb    mm1,        mm7
+
+        movd        DWORD PTR [edi-3], mm1
+        jl          horizontal_line_5_3_loop
+
+//exit condition
+        movq        mm0,        QWORD PTR  [esi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psllw       mm0,        8                   ;
+        xx 00 xx 02 xx 04 xx 06
+        psrlw       mm1,        8                   ;
+        01 xx 03 xx 05 xx 07 xx
+
+        psrlw       mm0,        8                   ;
+        00 xx 02 xx 04 xx 06 xx
+        psllq       mm1,        16                  ;
+        xx xx 01 xx 03 xx 05 xx
+
+        pmullw      mm0,        mm6
+
+        pmullw      mm1,        mm5
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        packuswb    mm1,        mm7
+        movd        eax,        mm1
+
+        mov         edx,        eax
+        shr         edx,        16
+
+        mov         WORD PTR[edi],   ax
+        mov         BYTE PTR[edi+2], dl
+
+    }
+
+}
+
+
+static
+void vertical_band_5_3_scale_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    __declspec(align(16)) const unsigned short one_thirds[] = {  85,  85,  85,  85 };
+    __declspec(align(16)) const unsigned short two_thirds[] = { 171, 171, 171, 171 };
+
+    __asm
+    {
+        push        ebx
+
+        mov         esi,    source                    // Get the source and destination pointer
+        mov         ecx,    src_pitch               // Get the pitch size
+
+        mov         edi,    dest                    // tow lines below
+        pxor        mm7,    mm7                     // clear out mm7
+
+        mov         edx,    dest_pitch               // Loop counter
+        movq        mm5,    one_thirds
+
+        movq        mm6,    two_thirds
+        mov         ebx,    dest_width;
+
+        vs_5_3_loop:
+
+        movd        mm0,    DWORD ptr [esi]         // src[0];
+        movd        mm1,    DWORD ptr [esi+ecx]     // src[1];
+
+        movd        mm2,    DWORD ptr [esi+ecx*2]
+        lea         eax,    [esi+ecx*2]             //
+
+        punpcklbw   mm1,    mm7
+        punpcklbw   mm2,    mm7
+
+        pmullw      mm1,    mm5
+        pmullw      mm2,    mm6
+
+        movd        mm3,    DWORD ptr [eax+ecx]
+        movd        mm4,    DWORD ptr [eax+ecx*2]
+
+        punpcklbw   mm3,    mm7
+        punpcklbw   mm4,    mm7
+
+        pmullw      mm3,    mm6
+        pmullw      mm4,    mm5
+
+
+        movd        DWORD PTR [edi], mm0
+        paddw       mm1,    mm2
+
+        paddw       mm1,    round_values
+        psrlw       mm1,    8
+
+        packuswb    mm1,    mm7
+        paddw       mm3,    mm4
+
+        paddw       mm3,    round_values
+        movd        DWORD PTR [edi+edx], mm1
+
+        psrlw       mm3,    8
+        packuswb    mm3,    mm7
+
+        movd        DWORD PTR [edi+edx*2], mm3
+
+
+        add         edi,    4
+        add         esi,    4
+
+        sub         ebx,    4
+        jg          vs_5_3_loop
+
+        pop         ebx
+    }
+}
+
+
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_2_1_scale
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_2_1_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    __asm
+    {
+        mov         esi,    source
+        mov         edi,    dest
+
+        pxor        mm7,    mm7
+        mov         ecx,    dest_width
+
+        xor         edx,    edx
+        hs_2_1_loop:
+
+        movq        mm0,    [esi+edx*2]
+        psllw       mm0,    8
+
+        psrlw       mm0,    8
+        packuswb    mm0,    mm7
+
+        movd        DWORD Ptr [edi+edx], mm0;
+        add         edx,    4
+
+        cmp         edx,    ecx
+        jl          hs_2_1_loop
+
+    }
+}
+
+
+
+static
+void vertical_band_2_1_scale_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    vpx_memcpy(dest, source, dest_width);
+}
+
+
+
+static
+void vertical_band_2_1_scale_i_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+
+    __declspec(align(16)) const unsigned short three_sixteenths[] = {  48,  48,  48,  48 };
+    __declspec(align(16)) const unsigned short ten_sixteenths[]   = { 160, 160, 160, 160 };
+    __declspec(align(16)) unsigned short round_values[] = { 128, 128, 128, 128 };
+    __asm
+    {
+        mov         esi,        source
+        mov         edi,        dest
+
+        mov         eax,        src_pitch
+        mov         edx,        dest_width
+
+        pxor        mm7,        mm7
+        sub         esi,        eax             //back one line
+
+
+        lea         ecx,        [esi+edx];
+        movq        mm6,        round_values;
+
+        movq        mm5,        three_sixteenths;
+        movq        mm4,        ten_sixteenths;
+
+        vs_2_1_i_loop:
+        movd        mm0,        [esi]           //
+        movd        mm1,        [esi+eax]       //
+
+        movd        mm2,        [esi+eax*2]     //
+        punpcklbw   mm0,        mm7
+
+        pmullw      mm0,        mm5
+        punpcklbw   mm1,        mm7
+
+        pmullw      mm1,        mm4
+        punpcklbw   mm2,        mm7
+
+        pmullw      mm2,        mm5
+        paddw       mm0,        round_values
+
+        paddw       mm1,        mm2
+        paddw       mm0,        mm1
+
+        psrlw       mm0,        8
+        packuswb    mm0,        mm7
+
+        movd        DWORD PTR [edi],        mm0
+        add         esi,        4
+
+        add         edi,        4;
+        cmp         esi,        ecx
+        jl          vs_2_1_i_loop
+
+    }
+}
+
+void
+register_mmxscalers(void)
+{
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_mmx;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_mmx;
+    vp8_last_vertical_band_1_2_scale      = last_vertical_band_1_2_scale_mmx;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_mmx;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_mmx;
+    vp8_last_vertical_band_3_5_scale      = last_vertical_band_3_5_scale_mmx;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_mmx;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_mmx;
+    vp8_last_vertical_band_4_5_scale      = last_vertical_band_4_5_scale_mmx;
+
+    vp8_horizontal_line_3_4_scale        = vp8cx_horizontal_line_3_4_scale_c;
+    vp8_vertical_band_3_4_scale          = vp8cx_vertical_band_3_4_scale_c;
+    vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+    vp8_horizontal_line_2_3_scale        = vp8cx_horizontal_line_2_3_scale_c;
+    vp8_vertical_band_2_3_scale          = vp8cx_vertical_band_2_3_scale_c;
+    vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+
+
+
+    vp8_vertical_band_5_4_scale          = vertical_band_5_4_scale_mmx;
+    vp8_vertical_band_5_3_scale          = vertical_band_5_3_scale_mmx;
+    vp8_vertical_band_2_1_scale          = vertical_band_2_1_scale_mmx;
+    vp8_vertical_band_2_1_scale_i        = vertical_band_2_1_scale_i_mmx;
+    vp8_horizontal_line_2_1_scale        = horizontal_line_2_1_scale_mmx;
+    vp8_horizontal_line_5_3_scale        = horizontal_line_5_3_scale_mmx;
+    vp8_horizontal_line_5_4_scale        = horizontal_line_5_4_scale_mmx;
+
+}
diff --git a/vpx_scale/intel_linux/scalesystemdependant.c b/vpx_scale/intel_linux/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..9ed48bf
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     system_dependant.c
+*
+*   Description  :     Miscellaneous system dependant functions
+*
+****************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/vpxscale.h"
+#include "cpuidlib.h"
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+extern void register_generic_scalers(void);
+extern void register_mmxscalers(void);
+
+/****************************************************************************
+ *
+ *  ROUTINE       : post_proc_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void
+vp8_scale_machine_specific_config(void)
+{
+    // If MMX supported then set to use MMX versions of functions else
+    // use original 'C' versions.
+    int mmx_enabled;
+    int xmm_enabled;
+    int wmt_enabled;
+
+    vpx_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled);
+
+    if (mmx_enabled || xmm_enabled || wmt_enabled)
+    {
+        register_mmxscalers();
+    }
+    else
+    {
+        vp8_horizontal_line_1_2_scale        = vp8cx_horizontal_line_1_2_scale_c;
+        vp8_vertical_band_1_2_scale          = vp8cx_vertical_band_1_2_scale_c;
+        vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+        vp8_horizontal_line_3_5_scale        = vp8cx_horizontal_line_3_5_scale_c;
+        vp8_vertical_band_3_5_scale          = vp8cx_vertical_band_3_5_scale_c;
+        vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+        vp8_horizontal_line_3_4_scale        = vp8cx_horizontal_line_3_4_scale_c;
+        vp8_vertical_band_3_4_scale          = vp8cx_vertical_band_3_4_scale_c;
+        vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+        vp8_horizontal_line_2_3_scale        = vp8cx_horizontal_line_2_3_scale_c;
+        vp8_vertical_band_2_3_scale          = vp8cx_vertical_band_2_3_scale_c;
+        vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+        vp8_horizontal_line_4_5_scale        = vp8cx_horizontal_line_4_5_scale_c;
+        vp8_vertical_band_4_5_scale          = vp8cx_vertical_band_4_5_scale_c;
+        vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+
+
+        vp8_vertical_band_5_4_scale           = vp8cx_vertical_band_5_4_scale_c;
+        vp8_vertical_band_5_3_scale           = vp8cx_vertical_band_5_3_scale_c;
+        vp8_vertical_band_2_1_scale           = vp8cx_vertical_band_2_1_scale_c;
+        vp8_vertical_band_2_1_scale_i         = vp8cx_vertical_band_2_1_scale_i_c;
+        vp8_horizontal_line_2_1_scale         = vp8cx_horizontal_line_2_1_scale_c;
+        vp8_horizontal_line_5_3_scale         = vp8cx_horizontal_line_5_3_scale_c;
+        vp8_horizontal_line_5_4_scale         = vp8cx_horizontal_line_5_4_scale_c;
+
+    }
+}
diff --git a/vpx_scale/leapster/doptsystemdependant_lf.c b/vpx_scale/leapster/doptsystemdependant_lf.c
new file mode 100644 (file)
index 0000000..ca13167
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     system_dependant.c
+*
+*   Description  :     Miscellaneous system dependant functions
+*
+****************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/vpxscale.h"
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+extern int register_generic_scalers(void);
+extern int de_register_generic_scalers(void);
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+int
+vp8_scale_machine_specific_config()
+{
+    return register_generic_scalers();
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int
+ *
+ *  FUNCTION      : Resets the funtion pointers and deallocates memory.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+int
+scale_machine_specific_de_config()
+{
+    return de_register_generic_scalers();
+}
diff --git a/vpx_scale/leapster/gen_scalers_lf.c b/vpx_scale/leapster/gen_scalers_lf.c
new file mode 100644 (file)
index 0000000..1b9c7c7
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     gen_scalers.c
+ *
+ *   Description  :     Generic image scaling functions.
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/vpxscale.h"
+
+/****************************************************************************
+*  Imports
+****************************************************************************/
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_4_5_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 4 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void vp8cx_horizontal_line_4_5_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 4; i += 4)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char) a;
+        des [1] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+        c = src[2] * 154;
+        a = src[3];
+        des [2] = (unsigned char)((b * 102 + c + 128) >> 8);
+        des [3] = (unsigned char)((c + 102 * a + 128) >> 8);
+        b = src[4];
+        des [4] = (unsigned char)((a * 205 + 51 * b + 128) >> 8);
+
+        src += 4;
+        des += 5;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (unsigned char)(a);
+    des [1] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+    c = src[2] * 154;
+    a = src[3];
+    des [2] = (unsigned char)((b * 102 + c + 128) >> 8);
+    des [3] = (unsigned char)((c + 102 * a + 128) >> 8);
+    des [4] = (unsigned char)(a);
+
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_4_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+ *                  height of the band scaled is 4-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+static
+void vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+
+        des[dest_pitch] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+
+        c = des[dest_pitch*2] * 154;
+        d = des[dest_pitch*3];
+
+        des [dest_pitch*2] = (unsigned char)((b * 102 + c + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((c + 102 * d + 128) >> 8);
+
+        // First line in next band
+        a = des [dest_pitch * 5];
+        des [dest_pitch * 4] = (unsigned char)((d * 205 + 51 * a + 128) >> 8);
+
+        des ++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_4_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 4 to 5. The
+ *                  height of the band scaled is 4-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+static
+void vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c, d;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        a = des[0];
+        b = des[dest_pitch];
+
+        des[dest_pitch] = (unsigned char)((a * 51 + 205 * b + 128) >> 8);
+
+        c = des[dest_pitch*2] * 154;
+        d = des[dest_pitch*3];
+
+        des [dest_pitch*2] = (unsigned char)((b * 102 + c + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((c + 102 * d + 128) >> 8);
+
+        // No other line for interplation of this line, so ..
+        des[dest_pitch*4] = (unsigned char) d;
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 3 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ *
+ ****************************************************************************/
+static
+void vp8cx_horizontal_line_3_5_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 3; i += 3)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char)(a);
+        des [1] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+
+        c = src[2] ;
+        des [2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+        des [3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+        a = src[3];
+        des [4] = (unsigned char)((c * 154 + a * 102 + 128) >> 8);
+
+        src += 3;
+        des += 5;
+    }
+
+    a = src[0];
+    b = src[1];
+    des [0] = (unsigned char)(a);
+
+    des [1] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+    c = src[2] ;
+    des [2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+    des [3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+    des [4] = (unsigned char)(c);
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_3_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+static
+void vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+        des [dest_pitch] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+
+        c = des[dest_pitch*2];
+        des [dest_pitch*2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+        // First line in next band...
+        a = des [dest_pitch * 5];
+        des [dest_pitch * 4] = (unsigned char)((c * 154 + a * 102 + 128) >> 8);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_3_5_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 3 to 5. The
+ *                  height of the band scaled is 3-pixels.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+static
+void vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b, c;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        a = des [0];
+        b = des [dest_pitch];
+
+        des [ dest_pitch ] = (unsigned char)((a * 102 + 154 * b + 128) >> 8);
+
+        c = des[dest_pitch*2];
+        des [dest_pitch*2] = (unsigned char)((b * 205 + c * 51 + 128) >> 8);
+        des [dest_pitch*3] = (unsigned char)((b * 51 + c * 205 + 128) >> 8);
+
+        // No other line for interplation of this line, so ..
+        des [ dest_pitch * 4 ] = (unsigned char)(c) ;
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 1 to 2.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void vp8cx_horizontal_line_1_2_scale_c
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    unsigned int i;
+    unsigned int a, b;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for (i = 0; i < source_width - 1; i += 1)
+    {
+        a = src[0];
+        b = src[1];
+        des [0] = (unsigned char)(a);
+        des [1] = (unsigned char)((a + b + 1) >> 1);
+        src += 1;
+        des += 2;
+    }
+
+    a = src[0];
+    des [0] = (unsigned char)(a);
+    des [1] = (unsigned char)(a);
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_vertical_band_1_2_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+ *                  height of the band scaled is 1-pixel.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band.
+ *
+ ****************************************************************************/
+static
+void vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned int a, b;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; i++)
+    {
+        a = des [0];
+        b = des [dest_pitch * 2];
+
+        des[dest_pitch] = (unsigned char)((a + b + 1) >> 1);
+
+        des++;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8cx_last_vertical_band_1_2_scale_c
+ *
+ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+ *                  unsigned int dest_pitch : Stride of destination data.
+ *                  unsigned int dest_width : Width of destination data.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Scales last vertical band of pixels by scale 1 to 2. The
+ *                  height of the band scaled is 1-pixel.
+ *
+ *  SPECIAL NOTES : The routine does not have available the first line of
+ *                  the band below the current band, since this is the
+ *                  last band.
+ *
+ ****************************************************************************/
+static
+void vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    unsigned int i;
+    unsigned char *des = dest;
+
+    for (i = 0; i < dest_width; ++i)
+    {
+        des[dest_pitch] = des[0];
+        des++;
+    }
+}
+
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+
+struct vpxglobal_scalling_ptrs_t *g_scaling_ptrs = 0;
+
+int
+register_generic_scalers(void)
+{
+    int rv = 0;
+
+    g_scaling_ptrs = (struct vpxglobal_scalling_ptrs_t *)vpx_malloc(sizeof(struct vpxglobal_scalling_ptrs_t));
+
+    if (g_scaling_ptrs)
+    {
+        g_scaling_ptrs->vpxhorizontal_line_1_2_scale_t        = vp8cx_horizontal_line_1_2_scale_c;
+        g_scaling_ptrs->vpxvertical_band_1_2_scale_t          = vp8cx_vertical_band_1_2_scale_c;
+        g_scaling_ptrs->vpxlast_vertical_band_1_2_scale_t      = vp8cx_last_vertical_band_1_2_scale_c;
+        g_scaling_ptrs->vpxhorizontal_line_3_5_scale_t        = vp8cx_horizontal_line_3_5_scale_c;
+        g_scaling_ptrs->vpxvertical_band_3_5_scale_t          = vp8cx_vertical_band_3_5_scale_c;
+        g_scaling_ptrs->vpxlast_vertical_band_3_5_scale_t      = vp8cx_last_vertical_band_3_5_scale_c;
+        g_scaling_ptrs->vpxhorizontal_line_4_5_scale_t        = vp8cx_horizontal_line_4_5_scale_c;
+        g_scaling_ptrs->vpxvertical_band_4_5_scale_t          = vp8cx_vertical_band_4_5_scale_c;
+        g_scaling_ptrs->vpxlast_vertical_band_4_5_scale_t      = vp8cx_last_vertical_band_4_5_scale_c;
+    }
+    else
+    {
+        rv = -1;
+    }
+
+    /*
+    vp8_horizontal_line_1_2_scale        = vp8cx_horizontal_line_1_2_scale_c;
+    vp8_vertical_band_1_2_scale          = vp8cx_vertical_band_1_2_scale_c;
+    vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+    vp8_horizontal_line_3_5_scale        = vp8cx_horizontal_line_3_5_scale_c;
+    vp8_vertical_band_3_5_scale          = vp8cx_vertical_band_3_5_scale_c;
+    vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+    vp8_horizontal_line_4_5_scale        = vp8cx_horizontal_line_4_5_scale_c;
+    vp8_vertical_band_4_5_scale          = vp8cx_vertical_band_4_5_scale_c;
+    vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+    */
+
+    return rv;
+}
+
+int
+de_register_generic_scalers(void)
+{
+    int rv = 0;
+
+    if (g_scaling_ptrs)
+    {
+        vpx_free(g_scaling_ptrs);
+        g_scaling_ptrs = 0;
+    }
+    else
+    {
+        rv = -1;
+    }
+
+    return rv;
+}
diff --git a/vpx_scale/leapster/vpxscale_lf.c b/vpx_scale/leapster/vpxscale_lf.c
new file mode 100644 (file)
index 0000000..5f05e5d
--- /dev/null
@@ -0,0 +1,890 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     scale.c
+ *
+ *   Description  :     Image scaling functions.
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "stdlib.h"
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+#include "vpx_scale/yv12config.h"
+#include "codec_common_interface.h"
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+/*
+void  (*vp8_vertical_band_4_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+void  (*vp8_last_vertical_band_4_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+void  (*vp8_vertical_band_3_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+void  (*vp8_last_vertical_band_3_5_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+void  (*vp8_horizontal_line_1_2_scale)(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width);
+void  (*vp8_horizontal_line_3_5_scale)(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width);
+void  (*vp8_horizontal_line_4_5_scale)(const unsigned char * source,unsigned int source_width,unsigned char * dest,unsigned int dest_width);
+void  (*vp8_vertical_band_1_2_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+void  (*vp8_last_vertical_band_1_2_scale)(unsigned char * dest,unsigned int dest_pitch,unsigned int dest_width);
+*/
+
+
+typedef struct
+{
+    int     expanded_frame_width;
+    int     expanded_frame_height;
+
+    int HScale;
+    int HRatio;
+    int VScale;
+    int VRatio;
+
+    YV12_BUFFER_CONFIG *src_yuv_config;
+    YV12_BUFFER_CONFIG *dst_yuv_config;
+
+} SCALE_VARS;
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       :     horizontal_line_copy
+ *
+ *  INPUTS        :     None
+ *
+ *
+ *  OUTPUTS       :     None.
+ *
+ *  RETURNS       :     None
+ *
+ *  FUNCTION      :     1 to 1 scaling up for a horizontal line of pixles
+ *
+ *  SPECIAL NOTES :     None.
+ *
+ *  ERRORS        :     None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_copy(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    duck_memcpy(dest, source, source_width);
+}
+/****************************************************************************
+ *
+ *  ROUTINE       :     null_scale
+ *
+ *  INPUTS        :     None
+ *
+ *
+ *  OUTPUTS       :     None.
+ *
+ *  RETURNS       :     None
+ *
+ *  FUNCTION      :     1 to 1 scaling up for a vertical band
+ *
+ *  SPECIAL NOTES :     None.
+ *
+ *  ERRORS        :     None.
+ *
+ ****************************************************************************/
+static
+void null_scale(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    return;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : scale1d_2t1_i
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
+ *                  int source_step              : Number of pixels to step on in source.
+ *                  unsigned int source_scale    : Scale for source (UNUSED).
+ *                  unsigned int source_length   : Length of source (UNUSED).
+ *                  unsigned char *dest         : Pointer to output data array.
+ *                  int dest_step                : Number of pixels to step on in destination.
+ *                  unsigned int dest_scale      : Scale for destination (UNUSED).
+ *                  unsigned int dest_length     : Length of destination.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-to-1 interpolated scaling.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void scale1d_2t1_i
+(
+    const unsigned char *source,
+    int source_step,
+    unsigned int source_scale,
+    unsigned int source_length,
+    unsigned char *dest,
+    int dest_step,
+    unsigned int dest_scale,
+    unsigned int dest_length
+)
+{
+    unsigned int i, j;
+    unsigned int temp;
+
+    (void) source_length;
+    (void) source_scale;
+    (void) dest_scale;
+
+    source_step *= 2;
+    dest[0] = source[0];
+
+    for (i = dest_step, j = source_step; i < dest_length * dest_step; i += dest_step, j += source_step)
+    {
+        temp = 8;
+        temp += 3 * source[j-source_step];
+        temp += 10 * source[j];
+        temp += 3 * source[j+source_step];
+        temp >>= 4;
+        dest[i] = (char)(temp);
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : scale1d_2t1_ps
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
+ *                  int source_step              : Number of pixels to step on in source.
+ *                  unsigned int source_scale    : Scale for source (UNUSED).
+ *                  unsigned int source_length   : Length of source (UNUSED).
+ *                  unsigned char *dest         : Pointer to output data array.
+ *                  int dest_step                : Number of pixels to step on in destination.
+ *                  unsigned int dest_scale      : Scale for destination (UNUSED).
+ *                  unsigned int dest_length     : Length of destination.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-to-1 point subsampled scaling.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void scale1d_2t1_ps
+(
+    const unsigned char *source,
+    int source_step,
+    unsigned int source_scale,
+    unsigned int source_length,
+    unsigned char *dest,
+    int dest_step,
+    unsigned int dest_scale,
+    unsigned int dest_length
+)
+{
+    unsigned int i, j;
+
+    (void) source_length;
+    (void) source_scale;
+    (void) dest_scale;
+
+    source_step *= 2;
+    j = 0;
+
+    for (i = 0; i < dest_length * dest_step; i += dest_step, j += source_step)
+        dest[i] = source[j];
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : scale1d_c
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to data to be scaled.
+ *                  int source_step              : Number of pixels to step on in source.
+ *                  unsigned int source_scale    : Scale for source.
+ *                  unsigned int source_length   : Length of source (UNUSED).
+ *                  unsigned char *dest         : Pointer to output data array.
+ *                  int dest_step                : Number of pixels to step on in destination.
+ *                  unsigned int dest_scale      : Scale for destination.
+ *                  unsigned int dest_length     : Length of destination.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs linear interpolation in one dimension.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void scale1d_c
+(
+    const unsigned char *source,
+    int source_step,
+    unsigned int source_scale,
+    unsigned int source_length,
+    unsigned char *dest,
+    int dest_step,
+    unsigned int dest_scale,
+    unsigned int dest_length
+)
+{
+    unsigned int i;
+    unsigned int round_value = dest_scale / 2;
+    unsigned int left_modifier = dest_scale;
+    unsigned int right_modifier = 0;
+    unsigned char left_pixel = *source;
+    unsigned char right_pixel = *(source + source_step);
+
+    (void) source_length;
+
+    // These asserts are needed if there are boundary issues...
+    //assert ( dest_scale > source_scale );
+    //assert ( (source_length-1) * dest_scale >= (dest_length-1) * source_scale );
+
+    for (i = 0; i < dest_length * dest_step; i += dest_step)
+    {
+        dest[i] = (char)((left_modifier * left_pixel + right_modifier * right_pixel + round_value) / dest_scale);
+
+        right_modifier += source_scale;
+
+        while (right_modifier > dest_scale)
+        {
+            right_modifier -= dest_scale;
+            source += source_step;
+            left_pixel = *source;
+            right_pixel = *(source + source_step);
+        }
+
+        left_modifier = dest_scale - right_modifier;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : Scale2D
+ *
+ *  INPUTS        : const unsigned char *source  : Pointer to data to be scaled.
+ *                  int source_pitch              : Stride of source image.
+ *                  unsigned int source_width     : Width of input image.
+ *                  unsigned int source_height    : Height of input image.
+ *                  unsigned char *dest          : Pointer to output data array.
+ *                  int dest_pitch                : Stride of destination image.
+ *                  unsigned int dest_width       : Width of destination image.
+ *                  unsigned int dest_height      : Height of destination image.
+ *                  unsigned char *temp_area      : Pointer to temp work area.
+ *                  unsigned char temp_area_height : Height of temp work area.
+ *                  unsigned int hscale          : Horizontal scale factor numerator.
+ *                  unsigned int hratio          : Horizontal scale factor denominator.
+ *                  unsigned int vscale          : Vertical scale factor numerator.
+ *                  unsigned int vratio          : Vertical scale factor denominator.
+ *                  unsigned int interlaced      : Interlace flag.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
+ *
+ *  SPECIAL NOTES : Expansion is performed one band at a time to help with
+ *                  caching.
+ *
+ ****************************************************************************/
+static
+void Scale2D
+(
+    const unsigned char *source,
+    int source_pitch,
+    unsigned int source_width,
+    unsigned int source_height,
+    unsigned char *dest,
+    int dest_pitch,
+    unsigned int dest_width,
+    unsigned int dest_height,
+    unsigned char *temp_area,
+    unsigned char temp_area_height,
+    unsigned int hscale,
+    unsigned int hratio,
+    unsigned int vscale,
+    unsigned int vratio,
+    unsigned int interlaced
+)
+{
+    unsigned int i, j, k;
+    unsigned int bands;
+    unsigned int dest_band_height;
+    unsigned int source_band_height;
+
+    typedef void (*Scale1D)(const unsigned char * source, int source_step, unsigned int source_scale, unsigned int source_length,
+                            unsigned char * dest, int dest_step, unsigned int dest_scale, unsigned int dest_length);
+
+    Scale1D Scale1Dv = scale1d_c;
+    Scale1D Scale1Dh = scale1d_c;
+
+    if (hscale == 2 && hratio == 1)
+        Scale1Dh = scale1d_2t1_ps;
+
+    if (vscale == 2 && vratio == 1)
+    {
+        if (interlaced)
+            Scale1Dv = scale1d_2t1_ps;
+        else
+            Scale1Dv = scale1d_2t1_i;
+    }
+
+    if (source_height == dest_height)
+    {
+        // for each band of the image
+        for (k = 0; k < dest_height; k++)
+        {
+            Scale1Dh(source, 1, hscale, source_width + 1, dest, 1, hratio, dest_width);
+            source += source_pitch;
+            dest   += dest_pitch;
+        }
+
+        return;
+    }
+
+    if (dest_height > source_height)
+    {
+        dest_band_height   = temp_area_height - 1;
+        source_band_height = dest_band_height * source_height / dest_height;
+    }
+    else
+    {
+        source_band_height = temp_area_height - 1;
+        dest_band_height   = source_band_height * vratio / vscale;
+    }
+
+    // first row needs to be done so that we can stay one row ahead for vertical zoom
+    Scale1Dh(source, 1, hscale, source_width + 1, temp_area, 1, hratio, dest_width);
+
+    // for each band of the image
+    bands = (dest_height + dest_band_height - 1) / dest_band_height;
+
+    for (k = 0; k < bands; k++)
+    {
+        // scale one band horizontally
+        for (i = 1; i < source_band_height + 1; i++)
+        {
+            if (k * source_band_height + i < source_height)
+            {
+                Scale1Dh(source + i * source_pitch, 1, hscale, source_width + 1,
+                         temp_area + i * dest_pitch, 1, hratio, dest_width);
+            }
+            else  //  Duplicate the last row
+            {
+                // copy temp_area row 0 over from last row in the past
+                duck_memcpy(temp_area + i * dest_pitch, temp_area + (i - 1)*dest_pitch, dest_pitch);
+            }
+        }
+
+        // scale one band vertically
+        for (j = 0; j < dest_width; j++)
+        {
+            Scale1Dv(&temp_area[j], dest_pitch, vscale, source_band_height + 1,
+                     &dest[j], dest_pitch, vratio, dest_band_height);
+        }
+
+        // copy temp_area row 0 over from last row in the past
+        duck_memcpy(temp_area, temp_area + source_band_height * dest_pitch, dest_pitch);
+
+        // move to the next band
+        source += source_band_height * source_pitch;
+        dest   += dest_band_height * dest_pitch;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_frame
+ *
+ *  INPUTS        : YV12_BUFFER_CONFIG *src       : Pointer to frame to be scaled.
+ *                  YV12_BUFFER_CONFIG *dst       : Pointer to buffer to hold scaled frame.
+ *                  unsigned char *temp_area      : Pointer to temp work area.
+ *                  unsigned char temp_area_height : Height of temp work area.
+ *                  unsigned int hscale          : Horizontal scale factor numerator.
+ *                  unsigned int hratio          : Horizontal scale factor denominator.
+ *                  unsigned int vscale          : Vertical scale factor numerator.
+ *                  unsigned int vratio          : Vertical scale factor denominator.
+ *                  unsigned int interlaced      : Interlace flag.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Performs 2-tap linear interpolation in two dimensions.
+ *
+ *  SPECIAL NOTES : Expansion is performed one band at a time to help with
+ *                  caching.
+ *
+ ****************************************************************************/
+void vp8_scale_frame
+(
+    YV12_BUFFER_CONFIG *src,
+    YV12_BUFFER_CONFIG *dst,
+    unsigned char *temp_area,
+    unsigned char temp_height,
+    unsigned int hscale,
+    unsigned int hratio,
+    unsigned int vscale,
+    unsigned int vratio,
+    unsigned int interlaced
+)
+{
+    int i;
+    int dw = (hscale - 1 + src->y_width * hratio) / hscale;
+    int dh = (vscale - 1 + src->y_height * vratio) / vscale;
+
+    // call our internal scaling routines!!
+    Scale2D((unsigned char *) src->y_buffer, src->y_stride, src->y_width, src->y_height,
+            (unsigned char *) dst->y_buffer, dst->y_stride, dw, dh,
+            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
+
+    if (dw < (int)dst->y_width)
+        for (i = 0; i < dh; i++)
+            duck_memset(dst->y_buffer + i * dst->y_stride + dw - 1, dst->y_buffer[i*dst->y_stride+dw-2], dst->y_width - dw + 1);
+
+    if (dh < (int)dst->y_height)
+        for (i = dh - 1; i < (int)dst->y_height; i++)
+            duck_memcpy(dst->y_buffer + i * dst->y_stride, dst->y_buffer + (dh - 2) * dst->y_stride, dst->y_width + 1);
+
+    Scale2D((unsigned char *) src->u_buffer, src->uv_stride, src->uv_width, src->uv_height,
+            (unsigned char *) dst->u_buffer, dst->uv_stride, dw / 2, dh / 2,
+            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
+
+    if (dw / 2 < (int)dst->uv_width)
+        for (i = 0; i < dst->uv_height; i++)
+            duck_memset(dst->u_buffer + i * dst->uv_stride + dw / 2 - 1, dst->u_buffer[i*dst->uv_stride+dw/2-2], dst->uv_width - dw / 2 + 1);
+
+    if (dh / 2 < (int)dst->uv_height)
+        for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
+            duck_memcpy(dst->u_buffer + i * dst->uv_stride, dst->u_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
+
+    Scale2D((unsigned char *) src->v_buffer, src->uv_stride, src->uv_width, src->uv_height,
+            (unsigned char *) dst->v_buffer, dst->uv_stride, dw / 2, dh / 2,
+            temp_area, temp_height, hscale, hratio, vscale, vratio, interlaced);
+
+    if (dw / 2 < (int)dst->uv_width)
+        for (i = 0; i < dst->uv_height; i++)
+            duck_memset(dst->v_buffer + i * dst->uv_stride + dw / 2 - 1, dst->v_buffer[i*dst->uv_stride+dw/2-2], dst->uv_width - dw / 2 + 1);
+
+    if (dh / 2 < (int) dst->uv_height)
+        for (i = dh / 2 - 1; i < (int)dst->y_height / 2; i++)
+            duck_memcpy(dst->v_buffer + i * dst->uv_stride, dst->v_buffer + (dh / 2 - 2)*dst->uv_stride, dst->uv_width);
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : any_ratio_2d_scale
+ *
+ *  INPUTS        : SCALE_INSTANCE *si      : Pointer to post-processor instance (NOT USED).
+ *                  const unsigned char *source : Pointer to source image.
+ *                  unsigned int source_pitch    : Stride of source image.
+ *                  unsigned int source_width    : Width of source image.
+ *                  unsigned int source_height   : Height of source image (NOT USED).
+ *                  unsigned char *dest         : Pointer to destination image.
+ *                  unsigned int dest_pitch      : Stride of destination image.
+ *                  unsigned int dest_width      : Width of destination image.
+ *                  unsigned int dest_height     : Height of destination image.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int: 1 if image scaled, 0 if image could not be scaled.
+ *
+ *  FUNCTION      : Scale the image with changing apect ratio.
+ *
+ *  SPECIAL NOTES : This scaling is a bi-linear scaling. Need to re-work the
+ *                  whole function for new scaling algorithm.
+ *
+ ****************************************************************************/
+static
+int any_ratio_2d_scale
+(
+    SCALE_VARS *si,
+    const unsigned char *source,
+    unsigned int source_pitch,
+    unsigned int source_width,
+    unsigned int source_height,
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width,
+    unsigned int dest_height
+)
+{
+    unsigned int i, k;
+    unsigned int src_band_height  = 0;
+    unsigned int dest_band_height = 0;
+
+    // suggested scale factors
+    int hs = si->HScale;
+    int hr = si->HRatio;
+    int vs = si->VScale;
+    int vr = si->VRatio;
+
+    // assume the ratios are scalable instead of should be centered
+    int ratio_scalable = 1;
+
+    void (*horiz_line_scale)(const unsigned char *, unsigned int, unsigned char *, unsigned int) = NULL;
+    void (*vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
+    void (*last_vert_band_scale)(unsigned char *, unsigned int, unsigned int) = NULL;
+
+    (void) si;
+
+    // find out the ratio for each direction
+    switch (hr * 10 / hs)
+    {
+    case 8:
+        // 4-5 Scale in Width direction
+        horiz_line_scale = g_scaling_ptrs->vpxhorizontal_line_4_5_scale_t;
+        break;
+    case 6:
+        // 3-5 Scale in Width direction
+        horiz_line_scale = g_scaling_ptrs->vpxhorizontal_line_3_5_scale_t;
+        break;
+    case 5:
+        // 1-2 Scale in Width direction
+        horiz_line_scale = g_scaling_ptrs->vpxhorizontal_line_1_2_scale_t;
+        break;
+    case 10:
+        // no scale in Width direction
+        horiz_line_scale = horizontal_line_copy;
+        break;
+    default:
+        // The ratio is not acceptable now
+        // throw("The ratio is not acceptable for now!");
+        ratio_scalable = 0;
+        break;
+    }
+
+    switch (vr * 10 / vs)
+    {
+    case 8:
+        // 4-5 Scale in vertical direction
+        vert_band_scale     = g_scaling_ptrs->vpxvertical_band_4_5_scale_t;
+        last_vert_band_scale = g_scaling_ptrs->vpxlast_vertical_band_4_5_scale_t;
+        src_band_height     = 4;
+        dest_band_height    = 5;
+        break;
+    case 6:
+        // 3-5 Scale in vertical direction
+        vert_band_scale     = g_scaling_ptrs->vpxvertical_band_3_5_scale_t;
+        last_vert_band_scale = g_scaling_ptrs->vpxlast_vertical_band_3_5_scale_t;
+        src_band_height     = 3;
+        dest_band_height    = 5;
+        break;
+    case 5:
+        // 1-2 Scale in vertical direction
+        vert_band_scale     = g_scaling_ptrs->vpxvertical_band_1_2_scale_t;
+        last_vert_band_scale = g_scaling_ptrs->vpxlast_vertical_band_1_2_scale_t;
+        src_band_height     = 1;
+        dest_band_height    = 2;
+        break;
+    case 10:
+        // no scale in Width direction
+        vert_band_scale     = null_scale;
+        last_vert_band_scale = null_scale;
+        src_band_height     = 4;
+        dest_band_height    = 4;
+        break;
+    default:
+        // The ratio is not acceptable now
+        // throw("The ratio is not acceptable for now!");
+        ratio_scalable = 0;
+        break;
+    }
+
+    if (ratio_scalable == 0)
+        return ratio_scalable;
+
+    horiz_line_scale(source, source_width, dest, dest_width);
+
+    // except last band
+    for (k = 0; k < (dest_height + dest_band_height - 1) / dest_band_height - 1; k++)
+    {
+        // scale one band horizontally
+        for (i = 1; i < src_band_height; i++)
+        {
+            horiz_line_scale(source + i * source_pitch,
+                             source_width,
+                             dest + i * dest_pitch,
+                             dest_width);
+        }
+
+        // first line of next band
+        horiz_line_scale(source + src_band_height * source_pitch,
+                         source_width,
+                         dest + dest_band_height * dest_pitch,
+                         dest_width);
+
+        // Vertical scaling is in place
+        vert_band_scale(dest, dest_pitch, dest_width);
+
+        // Next band...
+        source += src_band_height  * source_pitch;
+        dest   += dest_band_height * dest_pitch;
+    }
+
+    // scale one band horizontally
+    for (i = 1; i < src_band_height; i++)
+    {
+        horiz_line_scale(source + i * source_pitch,
+                         source_width,
+                         dest + i * dest_pitch,
+                         dest_width);
+    }
+
+    // Vertical scaling is in place
+    last_vert_band_scale(dest, dest_pitch, dest_width);
+
+    return ratio_scalable;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : any_ratio_frame_scale
+ *
+ *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance (NOT USED).
+ *                  unsigned char *frame_buffer           : Pointer to source image.
+ *                  int YOffset                : Offset from start of buffer to Y samples.
+ *                  int UVOffset               : Offset from start of buffer to UV samples.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : int: 1 if image scaled, 0 if image could not be scaled.
+ *
+ *  FUNCTION      : Scale the image with changing apect ratio.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+int any_ratio_frame_scale(SCALE_VARS *scale_vars, int YOffset, int UVOffset)
+{
+    int i;
+    int ew;
+    int eh;
+
+    // suggested scale factors
+    int hs = scale_vars->HScale;
+    int hr = scale_vars->HRatio;
+    int vs = scale_vars->VScale;
+    int vr = scale_vars->VRatio;
+
+    int ratio_scalable = 1;
+
+    int sw = (scale_vars->expanded_frame_width * hr + hs - 1) / hs;
+    int sh = (scale_vars->expanded_frame_height * vr + vs - 1) / vs;
+    int dw = scale_vars->expanded_frame_width;
+    int dh = scale_vars->expanded_frame_height;
+    YV12_BUFFER_CONFIG *src_yuv_config = scale_vars->src_yuv_config;
+    YV12_BUFFER_CONFIG *dst_yuv_config = scale_vars->dst_yuv_config;
+
+    if (hr == 3)
+        ew = (sw + 2) / 3 * 3 * hs / hr;
+    else
+        ew = (sw + 7) / 8 * 8 * hs / hr;
+
+    if (vr == 3)
+        eh = (sh + 2) / 3 * 3 * vs / vr;
+    else
+        eh = (sh + 7) / 8 * 8 * vs / vr;
+
+    ratio_scalable = any_ratio_2d_scale(scale_vars,
+                                        (const unsigned char *)src_yuv_config->y_buffer,
+                                        src_yuv_config->y_stride, sw, sh,
+                                        (unsigned char *) dst_yuv_config->y_buffer + YOffset,
+                                        dst_yuv_config->y_stride, dw, dh);
+
+    for (i = 0; i < eh; i++)
+        duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_stride + dw, 0, ew - dw);
+
+    for (i = dh; i < eh; i++)
+        duck_memset(dst_yuv_config->y_buffer + YOffset + i * dst_yuv_config->y_stride, 0, ew);
+
+    if (ratio_scalable == 0)
+        return ratio_scalable;
+
+    sw = (sw + 1) >> 1;
+    sh = (sh + 1) >> 1;
+    dw = (dw + 1) >> 1;
+    dh = (dh + 1) >> 1;
+
+    any_ratio_2d_scale(scale_vars,
+                       (const unsigned char *)src_yuv_config->u_buffer,
+                       src_yuv_config->y_stride / 2, sw, sh,
+                       (unsigned char *)dst_yuv_config->u_buffer + UVOffset,
+                       dst_yuv_config->uv_stride, dw, dh);
+
+    any_ratio_2d_scale(scale_vars,
+                       (const unsigned char *)src_yuv_config->v_buffer,
+                       src_yuv_config->y_stride / 2, sw, sh,
+                       (unsigned char *)dst_yuv_config->v_buffer + UVOffset,
+                       dst_yuv_config->uv_stride, dw, dh);
+
+    return ratio_scalable;
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : center_image
+ *
+ *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Centers the image without scaling in the output buffer.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static void
+center_image(YV12_BUFFER_CONFIG *src_yuv_config, YV12_BUFFER_CONFIG *dst_yuv_config)
+{
+    int i;
+    int row_offset, col_offset;
+    char *src_data_pointer;
+    char *dst_data_pointer;
+
+    // center values
+    row_offset = (dst_yuv_config->y_height - src_yuv_config->y_height) / 2;
+    col_offset = (dst_yuv_config->y_width - src_yuv_config->y_width) / 2;
+
+    // Y's
+    src_data_pointer = src_yuv_config->y_buffer;
+    dst_data_pointer = (char *)dst_yuv_config->y_buffer + (row_offset * dst_yuv_config->y_stride) + col_offset;
+
+    for (i = 0; i < src_yuv_config->y_height; i++)
+    {
+        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->y_width);
+        dst_data_pointer += dst_yuv_config->y_stride;
+        src_data_pointer += src_yuv_config->y_stride;
+    }
+
+    row_offset /= 2;
+    col_offset /= 2;
+
+    // U's
+    src_data_pointer = src_yuv_config->u_buffer;
+    dst_data_pointer = (char *)dst_yuv_config->u_buffer + (row_offset * dst_yuv_config->uv_stride) + col_offset;
+
+    for (i = 0; i < src_yuv_config->uv_height; i++)
+    {
+        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
+        dst_data_pointer += dst_yuv_config->uv_stride;
+        src_data_pointer += src_yuv_config->uv_stride;
+    }
+
+    // V's
+    src_data_pointer = src_yuv_config->v_buffer;
+    dst_data_pointer = (char *)dst_yuv_config->v_buffer + (row_offset * dst_yuv_config->uv_stride) + col_offset;
+
+    for (i = 0; i < src_yuv_config->uv_height; i++)
+    {
+        duck_memcpy(dst_data_pointer, src_data_pointer, src_yuv_config->uv_width);
+        dst_data_pointer += dst_yuv_config->uv_stride;
+        src_data_pointer += src_yuv_config->uv_stride;
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : scale_or_center
+ *
+ *  INPUTS        : SCALE_INSTANCE *si       : Pointer to post-processor instance.
+ *
+ *
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Decides to scale or center image in scale buffer for blit
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void
+vp8_yv12_scale_or_center
+(
+    YV12_BUFFER_CONFIG *src_yuv_config,
+    YV12_BUFFER_CONFIG *dst_yuv_config,
+    int expanded_frame_width,
+    int expanded_frame_height,
+    int scaling_mode,
+    int HScale,
+    int HRatio,
+    int VScale,
+    int VRatio
+)
+{
+//    if ( ppi->post_processing_level )
+    //      update_umvborder ( ppi, frame_buffer );
+
+
+    switch (scaling_mode)
+    {
+    case SCALE_TO_FIT:
+    case MAINTAIN_ASPECT_RATIO:
+    {
+        SCALE_VARS scale_vars;
+        // center values
+#if 1
+        int row = (dst_yuv_config->y_height - expanded_frame_height) / 2;
+        int col = (dst_yuv_config->y_width  - expanded_frame_width) / 2;
+//        int YOffset  = row * dst_yuv_config->y_width + col;
+//        int UVOffset = (row>>1) * dst_yuv_config->uv_width + (col>>1);
+        int YOffset  = row * dst_yuv_config->y_stride + col;
+        int UVOffset = (row >> 1) * dst_yuv_config->uv_stride + (col >> 1);
+#else
+        int row = (src_yuv_config->y_height - expanded_frame_height) / 2;
+        int col = (src_yuv_config->y_width  - expanded_frame_width) / 2;
+        int YOffset  = row * src_yuv_config->y_width + col;
+        int UVOffset = (row >> 1) * src_yuv_config->uv_width + (col >> 1);
+#endif
+
+        scale_vars.dst_yuv_config = dst_yuv_config;
+        scale_vars.src_yuv_config = src_yuv_config;
+        scale_vars.HScale = HScale;
+        scale_vars.HRatio = HRatio;
+        scale_vars.VScale = VScale;
+        scale_vars.VRatio = VRatio;
+        scale_vars.expanded_frame_width = expanded_frame_width;
+        scale_vars.expanded_frame_height = expanded_frame_height;
+
+        // perform center and scale
+        any_ratio_frame_scale(&scale_vars, YOffset, UVOffset);
+
+        break;
+    }
+    case CENTER:
+        center_image(src_yuv_config, dst_yuv_config);
+        break;
+
+    default:
+        break;
+    }
+}
diff --git a/vpx_scale/leapster/yv12extend.c b/vpx_scale/leapster/yv12extend.c
new file mode 100644 (file)
index 0000000..480d971
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+ *
+ *   Module Title :     yv12extend.c
+ *
+ *   Description  :
+ *
+ ***************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+//#include <stdlib.h>
+#include "vpx_scale/yv12config.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+*  Exports
+****************************************************************************/
+
+/****************************************************************************
+ *
+ ****************************************************************************/
+void
+vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf)
+{
+    int i;
+    char *src_ptr1, *src_ptr2;
+    char *dest_ptr1, *dest_ptr2;
+
+    unsigned int Border;
+    int plane_stride;
+    int plane_height;
+    int plane_width;
+
+    /***********/
+    /* Y Plane */
+    /***********/
+    Border = ybf->border;
+    plane_stride = ybf->y_stride;
+    plane_height = ybf->y_height;
+    plane_width = ybf->y_width;
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->y_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        memset(dest_ptr1, src_ptr1[0], Border);
+        memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->y_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)Border; i++)
+    {
+        memcpy(dest_ptr1, src_ptr1, plane_stride);
+        memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    plane_stride /= 2;
+    plane_height /= 2;
+    plane_width /= 2;
+    Border /= 2;
+
+    /***********/
+    /* U Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->u_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        memset(dest_ptr1, src_ptr1[0], Border);
+        memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->u_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        memcpy(dest_ptr1, src_ptr1, plane_stride);
+        memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    /***********/
+    /* V Plane */
+    /***********/
+
+    // copy the left and right most columns out
+    src_ptr1 = ybf->v_buffer;
+    src_ptr2 = src_ptr1 + plane_width - 1;
+    dest_ptr1 = src_ptr1 - Border;
+    dest_ptr2 = src_ptr2 + 1;
+
+    for (i = 0; i < plane_height; i++)
+    {
+        memset(dest_ptr1, src_ptr1[0], Border);
+        memset(dest_ptr2, src_ptr2[0], Border);
+        src_ptr1  += plane_stride;
+        src_ptr2  += plane_stride;
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+
+    // Now copy the top and bottom source lines into each line of the respective borders
+    src_ptr1 = ybf->v_buffer - Border;
+    src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;
+    dest_ptr1 = src_ptr1 - (Border * plane_stride);
+    dest_ptr2 = src_ptr2 + plane_stride;
+
+    for (i = 0; i < (int)(Border); i++)
+    {
+        memcpy(dest_ptr1, src_ptr1, plane_stride);
+        memcpy(dest_ptr2, src_ptr2, plane_stride);
+        dest_ptr1 += plane_stride;
+        dest_ptr2 += plane_stride;
+    }
+}
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_yv12_copy_frame
+ *
+ *  INPUTS        :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies the source image into the destination image and
+ *                  updates the destination's UMV borders.
+ *
+ *  SPECIAL NOTES : The frames are assumed to be identical in size.
+ *
+ ****************************************************************************/
+void
+vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc)
+{
+    int row;
+    int i;
+    unsigned int *source;
+    _Uncached unsigned int *dest;
+    int height;
+    int width;
+
+    height = src_ybc->y_height + (src_ybc->border * 2);
+    width =  src_ybc->y_width + (src_ybc->border * 2);
+    width /= 4;
+    source = (unsigned int *)(src_ybc->y_buffer - (src_ybc->border * src_ybc->y_stride) - src_ybc->border);
+    dest = (_Uncached unsigned int *)(dst_ybc->y_buffer - (dst_ybc->border * dst_ybc->y_stride) - dst_ybc->border);
+
+    for (row = 0; row < height; row++)
+    {
+        for (i = 0; i < width; i++)
+        {
+            dest[i] = source[i];
+        }
+
+        source += width;
+        dest   += width;
+    }
+
+    height = src_ybc->uv_height + (src_ybc->border);
+    width =  src_ybc->uv_width + (src_ybc->border);
+    width /= 4;
+
+    source = (unsigned int *)(src_ybc->u_buffer - (src_ybc->border / 2 * src_ybc->uv_stride) - src_ybc->border / 2);
+    dest = (_Uncached unsigned int *)(dst_ybc->u_buffer - (dst_ybc->border / 2 * dst_ybc->uv_stride) - dst_ybc->border / 2);
+
+    for (row = 0; row < height; row++)
+    {
+        for (i = 0; i < width; i++)
+        {
+            dest[i] = source[i];
+        }
+
+        source += width;
+        dest   += width;
+    }
+
+    source = (unsigned int *)(src_ybc->v_buffer - (src_ybc->border / 2 * src_ybc->uv_stride) - src_ybc->border / 2);
+    dest = (_Uncached unsigned int *)(dst_ybc->v_buffer - (dst_ybc->border / 2 * dst_ybc->uv_stride) - dst_ybc->border / 2);
+
+    for (row = 0; row < height; row++)
+    {
+        for (i = 0; i < width; i++)
+        {
+            dest[i] = source[i];
+        }
+
+        source += width;
+        dest   += width;
+    }
+
+}
diff --git a/vpx_scale/scale_mode.h b/vpx_scale/scale_mode.h
new file mode 100644 (file)
index 0000000..2a9ab76
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*****************************************************************************
+*/
+
+#ifndef SCALE_MODE_H
+#define SCALE_MODE_H
+
+typedef enum
+{
+    MAINTAIN_ASPECT_RATIO   = 0x0,
+    SCALE_TO_FIT            = 0x1,
+    CENTER                  = 0x2,
+    OTHER                   = 0x3
+} SCALE_MODE;
+
+
+#endif
diff --git a/vpx_scale/symbian/gen_scalers_armv4.asm b/vpx_scale/symbian/gen_scalers_armv4.asm
new file mode 100644 (file)
index 0000000..1c904ed
--- /dev/null
@@ -0,0 +1,773 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |horizontal_line_4_5_scale_armv4|
+    EXPORT  |vertical_band_4_5_scale_armv4|
+    EXPORT  |horizontal_line_2_3_scale_armv4|
+    EXPORT  |vertical_band_2_3_scale_armv4|
+    EXPORT  |horizontal_line_3_5_scale_armv4|
+    EXPORT  |vertical_band_3_5_scale_armv4|
+    EXPORT  |horizontal_line_3_4_scale_armv4|
+    EXPORT  |vertical_band_3_4_scale_armv4|
+    EXPORT  |horizontal_line_1_2_scale_armv4|
+    EXPORT  |vertical_band_1_2_scale_armv4|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+src         RN  r0
+srcw        RN  r1
+dest        RN  r2
+mask        RN  r12
+c51_205     RN  r10
+c102_154    RN  r11
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_4_5_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 4 to 5.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; ****************************************************************************/
+;void horizontal_line_4_5_scale_armv4
+;(
+;   r0 = UINT8 *source
+;   r1 = UINT32 source_width
+;   r2 = UINT8 *dest
+;   r3 = UINT32 dest_width
+;)
+|horizontal_line_4_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    mov     mask, #255              ; mask for selection
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldr     r3, [src], #4
+
+hl45_loop
+
+    and     r4, r3, mask            ; a = src[0]
+    and     r5, mask, r3, lsr #8    ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    and     r7, mask, r3, lsr #16   ; c = src[2]
+    mul     r6, c51_205, r6         ; a * 51 + 205 * b
+
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5        ; b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsr #24   ; d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mul     r7, c102_154, r7        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    ldr     r3, [src], #4
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    and     r9, mask, r3            ; e = src[4]
+    orr     r9, r9, r8, lsl #16     ; d | e
+    mul     r9, c51_205, r9         ; d * 205 + 51 * e
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #4
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bne     hl45_loop
+
+    and     r4, r3, mask
+    and     r5, mask, r3, lsl #8
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    mul     r6, c51_205, r6
+
+    and     r7, mask, r3, lsl #16
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsl #24
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mul     r7, c102_154, r7
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    ldrb    r3, [src]
+    strb    r3, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_4_5_scale_c|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_4_5_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+; *                  height of the band scaled is 4-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_4_5_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_4_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl45_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    mul     r6, c51_205, r6         ; a * 51 + 205 * b
+
+    ldrb    r8, [r3], r1            ; d = des[dest_pitch*3]
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5        ; b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    ldrb    r9, [r3, r1]            ; e = des [dest_pitch * 5]
+    mul     r7, c102_154, r7        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    orr     r9, r9, r8, lsl #16     ; d | e
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    mul     r9, c51_205, r9         ; d * 205 + 51 * e
+    add     r7, r7, #0x8000
+    add     src, src, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+    add     r9, r9, #0x8000
+    subs    r2, r2, #1
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    bne     vl45_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_4_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_2_3_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 2 to 3.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void horizontal_line_2_3_scale_armv4
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_2_3_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+
+hl23_loop
+
+    ldrb    r3, [src], #1           ; a
+    ldrb    r4, [src], #1           ; b
+    ldrb    r5, [src]               ; c
+
+    strb    r3, [dest], #1
+    mul     r4, r12, r4             ; b * 171
+    mla     r6, lr, r3, r4          ; a * 85
+    mla     r7, lr, r5, r4          ; c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest], #1
+
+    add     r7, r7, #128
+    mov     r7, r7, lsr #8
+    strb    r7, [dest], #1
+
+    subs    srcw, srcw, #2
+    bne     hl23_loop
+
+    ldrb    r4, [src, #1]           ; b
+    strb    r5, [dest], #1
+    strb    r4, [dest, #1]
+
+    mul     r4, r12, r4             ; b * 171
+    mla     r6, lr, r5, r4          ; a * 85 + b *171
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest]
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|horizontal_line_2_3_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_2_3_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 2 to 3. The
+; *                  height of the band scaled is 2-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_2_3_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_2_3_scale_armv4| PROC
+    stmdb   sp!, {r4 - r8, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+    add     r3, r1, r1, lsl #1      ; 3 * dest_pitch
+
+vl23_loop
+    ldrb    r4, [src]               ; a = des [0]
+    ldrb    r5, [src, r1]           ; b = des [dest_pitch]
+    ldrb    r7, [src, r3]           ; c = des [dest_pitch*3]
+    subs    r2, r2, #1
+
+    mul     r5, r12, r5             ; b * 171
+    mla     r6, lr, r4, r5          ; a * 85
+    mla     r8, lr, r7, r5          ; c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [src, r1]
+
+    add     r8, r8, #128
+    mov     r8, r8, lsr #8
+    strb    r8, [src, r1, lsl #1]
+
+    add     src, src, #1
+
+    bne     vl23_loop
+
+    ldmia   sp!, {r4 - r8, pc}
+    ENDP    ;|vertical_band_2_3_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 3 to 5.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void vp8cx_horizontal_line_3_5_scale_c
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_3_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldrb    r4, [src], #1           ; a = src[0]
+
+hl35_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     ; b | a
+    ldrb    r9, [src], #1           ; c = src[2]
+    mul     r6, c102_154, r6        ; a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     ; b | c
+    mul     r5, c51_205, r5         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    ldrb    r4, [src], #1           ; d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     ; c | b
+    mul     r7, c51_205, r7         ; c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    orr     r9, r4, r9, lsl #16     ; c | d
+    mul     r9, c102_154, r9        ; c * 154 + 102 * d
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #3
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bpl     hl35_loop
+
+    ldrb    r5, [src], #1           ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     ; b | a
+    ldrb    r9, [src], #1           ; c = src[2]
+    mul     r6, c102_154, r6        ; a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     ; b | c
+    mul     r5, c51_205, r5         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     ; c | b
+    mul     r7, c51_205, r7         ; c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+    strb    r9, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_3_5_scale_c|
+
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_vertical_band_3_5_scale_c
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+; *                  height of the band scaled is 3-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_4_5_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_3_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl35_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r8, r4, r5, lsl #16     ; b | a
+    mul     r6, c102_154, r8        ; a * 102 + 154 * b
+
+    ldrb    r8, [r3, r1, lsl #1]    ; d = des[dest_pitch*5]
+    orr     r3, r7, r5, lsl #16     ; b | c
+    mul     r9, c51_205, r3         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    orr     r3, r5, r7, lsl #16     ; c | b
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    mul     r5, c51_205, r3         ; c * 205 + 154 * b
+    add     r9, r9, #0x8000
+    orr     r3, r8, r7, lsl #16     ; c | d
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    mul     r7, c102_154, r3        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    add     src, src, #1
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    add     r7, r7, #0x8000
+    subs    r2, r2, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+
+    bne     vl35_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_3_4_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 3 to 4.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void horizontal_line_3_4_scale_armv4
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_3_4_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+    ldrb    r4, [src], #1           ; a = src[0]
+
+hl34_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    ldrb    r7, [src], #1           ; c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r8, r4         ; a*64 + b*192 + 1
+
+    add     r8, r8, #1              ; b + 1
+    add     r8, r8, r7              ; b + c + 1
+    mov     r8, r8, asr #1          ; (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    strb    r8, [dest], #1
+
+    ldrb    r4, [src], #1           ; [a+1]
+
+    mla     r7, r11, r7, r9         ; c*192 + 128
+    mla     r7, r4, r10, r7         ; a*64 + b*192 + 128
+
+    subs    srcw, srcw, #3
+
+    mov     r7, r7, asr #8          ; (a*64 + b*192 + 128) >> 8
+    strb    r7, [dest], #1
+
+    bpl     hl34_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    ldrb    r7, [src], #1           ; c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r8, r4         ; a*64 + b*192 + 1
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    add     r8, r8, #1              ; b + 1
+    add     r8, r8, r7              ; b + c + 1
+    mov     r8, r8, asr #1          ; (b + c + 1) >> 1
+    strb    r8, [dest], #1
+    strb    r7, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_3_4_scale_c|
+
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_3_4_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 3 to 4. The
+; *                  height of the band scaled is 3-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_3_4_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_3_4_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+;   ldr     r1,[r1]
+vl34_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des [dest_pitch*2]
+    add     lr, src, r1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r5, r4         ; a*64 + b*192 + 1
+
+    add     r5, r5, #1              ; b + 1
+    add     r5, r5, r7              ; b + c + 1
+    mov     r5, r5, asr #1          ; (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [lr], r1
+
+    ldrb    r4, [r3, r1]            ; a = des [dest_pitch*4]
+
+    strb    r5, [lr], r1
+
+    mla     r7, r11, r7, r9         ; c*192 + 128
+    mla     r7, r4, r10, r7         ; a*64 + b*192 + 128
+    mov     r7, r7, asr #8          ; (a*64 + b*192 + 128) >> 8
+
+    add     src, src, #1
+    subs    r2, r2, #1
+
+    strb    r7, [lr]
+
+    bne     vl34_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_3_4_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 1 to 2.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; ****************************************************************************/
+;void vp8cx_horizontal_line_1_2_scale_c
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_1_2_scale_armv4| PROC
+    stmdb   sp!, {r4 - r5, lr}
+
+    sub     srcw, srcw, #1
+
+    ldrb    r3, [src], #1
+    ldrb    r4, [src], #1
+hl12_loop
+    subs    srcw, srcw, #1
+
+    add     r5, r3, r4
+    add     r5, r5, #1
+    mov     r5, r5, lsr #1
+
+    orr     r5, r3, r5, lsl #8
+    strh    r5, [dest], #2
+
+    mov     r3, r4
+
+    ldrneb  r4, [src], #1
+    bne     hl12_loop
+
+    orr     r5, r4, r4, lsl #8
+    strh    r5, [dest]
+
+    ldmia   sp!, {r4 - r5, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_vertical_band_1_2_scale_c
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+; *                  height of the band scaled is 1-pixel.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vp8cx_vertical_band_1_2_scale_c
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_1_2_scale_armv4| PROC
+    stmdb   sp!, {r4 - r7, lr}
+
+    ldr     mask, =0xff00ff             ; mask for selection
+    ldr     lr, = 0x010001
+
+vl12_loop
+    mov     r3, src
+    ldr     r4, [r3], r1
+    ldr     r5, [r3, r1]
+
+    add     src, src, #4
+    subs    r2, r2, #4
+
+    and     r6, r4, mask
+    and     r7, r5, mask
+
+    add     r6, r7, r6
+    add     r6, r6, lr
+
+    and     r4, mask, r4, lsr #8
+    and     r5, mask, r5, lsr #8
+
+    mov     r6, r6, lsr #1
+    and     r6, r6, mask
+
+    add     r4, r5, r4
+    add     r4, r4, lr
+
+    mov     r4, r4, lsr #1
+    and     r4, r4, mask
+
+    orr     r5, r6, r4, lsl #8
+
+    str     r5, [r3]
+
+    bpl     vl12_loop
+
+    ldmia   sp!, {r4 - r7, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+    END
diff --git a/vpx_scale/symbian/gen_scalers_armv4.s b/vpx_scale/symbian/gen_scalers_armv4.s
new file mode 100644 (file)
index 0000000..3dfd0b9
--- /dev/null
@@ -0,0 +1,808 @@
+@ This file was created from a .asm file
+@  using the ads2gas.pl script.
+
+    .equ WIDE_REFERENCE, 0
+    .ifndef ARCHITECTURE
+    .equ ARCHITECTURE, 5
+    .endif
+    .global horizontal_line_4_5_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type horizontal_line_4_5_scale_armv4, function
+    .endif
+    .global vertical_band_4_5_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type vertical_band_4_5_scale_armv4, function
+    .endif
+    .global horizontal_line_2_3_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type horizontal_line_2_3_scale_armv4, function
+    .endif
+    .global vertical_band_2_3_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type vertical_band_2_3_scale_armv4, function
+    .endif
+    .global horizontal_line_3_5_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type horizontal_line_3_5_scale_armv4, function
+    .endif
+    .global vertical_band_3_5_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type vertical_band_3_5_scale_armv4, function
+    .endif
+    .global horizontal_line_3_4_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type horizontal_line_3_4_scale_armv4, function
+    .endif
+    .global vertical_band_3_4_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type vertical_band_3_4_scale_armv4, function
+    .endif
+    .global horizontal_line_1_2_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type horizontal_line_1_2_scale_armv4, function
+    .endif
+    .global vertical_band_1_2_scale_armv4
+    .ifndef NO_TYPE_PSEUDO_OP
+    .type vertical_band_1_2_scale_armv4, function
+    .endif
+
+.text
+
+src         .req    r0
+srcw        .req    r1
+dest        .req    r2
+mask        .req    r12
+c51_205     .req    r10
+c102_154    .req    r11
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : horizontal_line_4_5_scale_armv4
+@ *
+@ *  INPUTS        : const unsigned char *source : Pointer to source data.
+@ *                  unsigned int source_width    : Stride of source.
+@ *                  unsigned char *dest         : Pointer to destination data.
+@ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Copies horizontal line of pixels from source to
+@ *                  destination scaling up by 4 to 5.
+@ *
+@ *  SPECIAL NOTES : None.
+@ *
+@ ****************************************************************************/
+@void horizontal_line_4_5_scale_armv4
+@(
+@   r0 = UINT8 *source
+@   r1 = UINT32 source_width
+@   r2 = UINT8 *dest
+@   r3 = UINT32 dest_width
+@)
+_HorizontalLine_4_5_Scale_ARMv4:
+    horizontal_line_4_5_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+
+    mov     mask, #255              @ mask for selection
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldr     r3, [src], #4
+
+hl45_loop:
+
+    and     r4, r3, mask            @ a = src[0]
+    and     r5, mask, r3, lsr #8    @ b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     @ b | a
+    and     r7, mask, r3, lsr #16   @ c = src[2]
+    mul     r6, c51_205, r6         @ a * 51 + 205 * b
+
+    orr     r5, r5, r7, lsl #16     @ c | b
+    mul     r5, c102_154, r5        @ b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsr #24   @ d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     @ c | d
+    mul     r7, c102_154, r7        @ c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    ldr     r3, [src], #4
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    and     r9, mask, r3            @ e = src[4]
+    orr     r9, r9, r8, lsl #16     @ d | e
+    mul     r9, c51_205, r9         @ d * 205 + 51 * e
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #4
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bne     hl45_loop
+
+    and     r4, r3, mask
+    and     r5, mask, r3, lsl #8
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     @ b | a
+    mul     r6, c51_205, r6
+
+    and     r7, mask, r3, lsl #16
+    orr     r5, r5, r7, lsl #16     @ c | b
+    mul     r5, c102_154, r5
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsl #24
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     @ c | d
+    mul     r7, c102_154, r7
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    ldrb    r3, [src]
+    strb    r3, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|vp8cx_horizontal_line_4_5_scale_c|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vertical_band_4_5_scale_armv4
+@ *
+@ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+@ *                  unsigned int dest_pitch : Stride of destination data.
+@ *                  unsigned int dest_width : Width of destination data.
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+@ *                  height of the band scaled is 4-pixels.
+@ *
+@ *  SPECIAL NOTES : The routine uses the first line of the band below
+@ *                  the current band.
+@ *
+@ ****************************************************************************/
+@void vertical_band_4_5_scale_armv4
+@(
+@   r0 = UINT8 *dest
+@   r1 = UINT32 dest_pitch
+@   r2 = UINT32 dest_width
+@)
+_VerticalBand_4_5_Scale_ARMv4:
+    vertical_band_4_5_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl45_loop:
+    mov     r3, src
+    ldrb    r4, [r3], r1            @ a = des [0]
+    ldrb    r5, [r3], r1            @ b = des [dest_pitch]
+    ldrb    r7, [r3], r1            @ c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r6, r4, r5, lsl #16     @ b | a
+    mul     r6, c51_205, r6         @ a * 51 + 205 * b
+
+    ldrb    r8, [r3], r1            @ d = des[dest_pitch*3]
+    orr     r5, r5, r7, lsl #16     @ c | b
+    mul     r5, c102_154, r5        @ b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    orr     r7, r8, r7, lsl #16     @ c | d
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    ldrb    r9, [r3, r1]            @ e = des [dest_pitch * 5]
+    mul     r7, c102_154, r7        @ c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    orr     r9, r9, r8, lsl #16     @ d | e
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    mul     r9, c51_205, r9         @ d * 205 + 51 * e
+    add     r7, r7, #0x8000
+    add     src, src, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+    add     r9, r9, #0x8000
+    subs    r2, r2, #1
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    bne     vl45_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|vertical_band_4_5_scale_armv4|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : horizontal_line_2_3_scale_armv4
+@ *
+@ *  INPUTS        : const unsigned char *source : Pointer to source data.
+@ *                  unsigned int source_width    : Stride of source.
+@ *                  unsigned char *dest         : Pointer to destination data.
+@ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Copies horizontal line of pixels from source to
+@ *                  destination scaling up by 2 to 3.
+@ *
+@ *  SPECIAL NOTES : None.
+@ *
+@ *
+@ ****************************************************************************/
+@void horizontal_line_2_3_scale_armv4
+@(
+@   const unsigned char *source,
+@   unsigned int source_width,
+@   unsigned char *dest,
+@   unsigned int dest_width
+@)
+_HorizontalLine_2_3_Scale_ARMv4:
+    horizontal_line_2_3_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+
+hl23_loop:
+
+    ldrb    r3, [src], #1           @ a
+    ldrb    r4, [src], #1           @ b
+    ldrb    r5, [src]               @ c
+
+    strb    r3, [dest], #1
+    mul     r4, r12, r4             @ b * 171
+    mla     r6, lr, r3, r4          @ a * 85
+    mla     r7, lr, r5, r4          @ c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest], #1
+
+    add     r7, r7, #128
+    mov     r7, r7, lsr #8
+    strb    r7, [dest], #1
+
+    subs    srcw, srcw, #2
+    bne     hl23_loop
+
+    ldrb    r4, [src, #1]           @ b
+    strb    r5, [dest], #1
+    strb    r4, [dest, #1]
+
+    mul     r4, r12, r4             @ b * 171
+    mla     r6, lr, r5, r4          @ a * 85 + b *171
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest]
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|horizontal_line_2_3_scale_armv4|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vertical_band_2_3_scale_armv4
+@ *
+@ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+@ *                  unsigned int dest_pitch : Stride of destination data.
+@ *                  unsigned int dest_width : Width of destination data.
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Scales vertical band of pixels by scale 2 to 3. The
+@ *                  height of the band scaled is 2-pixels.
+@ *
+@ *  SPECIAL NOTES : The routine uses the first line of the band below
+@ *                  the current band.
+@ *
+@ ****************************************************************************/
+@void vertical_band_2_3_scale_armv4
+@(
+@   r0 = UINT8 *dest
+@   r1 = UINT32 dest_pitch
+@   r2 = UINT32 dest_width
+@)
+_VerticalBand_2_3_Scale_ARMv4:
+    vertical_band_2_3_scale_armv4: @
+    stmdb   sp!, {r4 - r8, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+    add     r3, r1, r1, lsl #1      @ 3 * dest_pitch
+
+vl23_loop:
+    ldrb    r4, [src]               @ a = des [0]
+    ldrb    r5, [src, r1]           @ b = des [dest_pitch]
+    ldrb    r7, [src, r3]           @ c = des [dest_pitch*3]
+    subs    r2, r2, #1
+
+    mul     r5, r12, r5             @ b * 171
+    mla     r6, lr, r4, r5          @ a * 85
+    mla     r8, lr, r7, r5          @ c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [src, r1]
+
+    add     r8, r8, #128
+    mov     r8, r8, lsr #8
+    strb    r8, [src, r1, lsl #1]
+
+    add     src, src, #1
+
+    bne     vl23_loop
+
+    ldmia   sp!, {r4 - r8, pc}
+    @   @|vertical_band_2_3_scale_armv4|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+@ *
+@ *  INPUTS        : const unsigned char *source : Pointer to source data.
+@ *                  unsigned int source_width    : Stride of source.
+@ *                  unsigned char *dest         : Pointer to destination data.
+@ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Copies horizontal line of pixels from source to
+@ *                  destination scaling up by 3 to 5.
+@ *
+@ *  SPECIAL NOTES : None.
+@ *
+@ *
+@ ****************************************************************************/
+@void vp8cx_horizontal_line_3_5_scale_c
+@(
+@   const unsigned char *source,
+@   unsigned int source_width,
+@   unsigned char *dest,
+@   unsigned int dest_width
+@)
+_HorizontalLine_3_5_Scale_ARMv4:
+    horizontal_line_3_5_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldrb    r4, [src], #1           @ a = src[0]
+
+hl35_loop:
+
+    ldrb    r8, [src], #1           @ b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     @ b | a
+    ldrb    r9, [src], #1           @ c = src[2]
+    mul     r6, c102_154, r6        @ a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     @ b | c
+    mul     r5, c51_205, r5         @ b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    ldrb    r4, [src], #1           @ d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     @ c | b
+    mul     r7, c51_205, r7         @ c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    orr     r9, r4, r9, lsl #16     @ c | d
+    mul     r9, c102_154, r9        @ c * 154 + 102 * d
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #3
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bpl     hl35_loop
+
+    ldrb    r5, [src], #1           @ b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     @ b | a
+    ldrb    r9, [src], #1           @ c = src[2]
+    mul     r6, c102_154, r6        @ a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     @ b | c
+    mul     r5, c51_205, r5         @ b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     @ c | b
+    mul     r7, c51_205, r7         @ c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+    strb    r9, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|vp8cx_horizontal_line_3_5_scale_c|
+
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vp8cx_vertical_band_3_5_scale_c
+@ *
+@ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+@ *                  unsigned int dest_pitch : Stride of destination data.
+@ *                  unsigned int dest_width : Width of destination data.
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+@ *                  height of the band scaled is 3-pixels.
+@ *
+@ *  SPECIAL NOTES : The routine uses the first line of the band below
+@ *                  the current band.
+@ *
+@ ****************************************************************************/
+@void vertical_band_4_5_scale_armv4
+@(
+@   r0 = UINT8 *dest
+@   r1 = UINT32 dest_pitch
+@   r2 = UINT32 dest_width
+@)
+_VerticalBand_3_5_Scale_ARMv4:
+    vertical_band_3_5_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl35_loop:
+    mov     r3, src
+    ldrb    r4, [r3], r1            @ a = des [0]
+    ldrb    r5, [r3], r1            @ b = des [dest_pitch]
+    ldrb    r7, [r3], r1            @ c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r8, r4, r5, lsl #16     @ b | a
+    mul     r6, c102_154, r8        @ a * 102 + 154 * b
+
+    ldrb    r8, [r3, r1, lsl #1]    @ d = des[dest_pitch*5]
+    orr     r3, r7, r5, lsl #16     @ b | c
+    mul     r9, c51_205, r3         @ b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    orr     r3, r5, r7, lsl #16     @ c | b
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    mul     r5, c51_205, r3         @ c * 205 + 154 * b
+    add     r9, r9, #0x8000
+    orr     r3, r8, r7, lsl #16     @ c | d
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    mul     r7, c102_154, r3        @ c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    add     src, src, #1
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    add     r7, r7, #0x8000
+    subs    r2, r2, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+
+    bne     vl35_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|vertical_band_3_5_scale_armv4|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : horizontal_line_3_4_scale_armv4
+@ *
+@ *  INPUTS        : const unsigned char *source : Pointer to source data.
+@ *                  unsigned int source_width    : Stride of source.
+@ *                  unsigned char *dest         : Pointer to destination data.
+@ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Copies horizontal line of pixels from source to
+@ *                  destination scaling up by 3 to 4.
+@ *
+@ *  SPECIAL NOTES : None.
+@ *
+@ *
+@ ****************************************************************************/
+@void horizontal_line_3_4_scale_armv4
+@(
+@   const unsigned char *source,
+@   unsigned int source_width,
+@   unsigned char *dest,
+@   unsigned int dest_width
+@)
+_HorizontalLine_3_4_Scale_ARMv4:
+    horizontal_line_3_4_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+    ldrb    r4, [src], #1           @ a = src[0]
+
+hl34_loop:
+
+    ldrb    r8, [src], #1           @ b = src[1]
+    ldrb    r7, [src], #1           @ c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         @ a*64 + 128
+    mla     r4, r11, r8, r4         @ a*64 + b*192 + 1
+
+    add     r8, r8, #1              @ b + 1
+    add     r8, r8, r7              @ b + c + 1
+    mov     r8, r8, asr #1          @ (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          @ (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    strb    r8, [dest], #1
+
+    ldrb    r4, [src], #1           @ [a+1]
+
+    mla     r7, r11, r7, r9         @ c*192 + 128
+    mla     r7, r4, r10, r7         @ a*64 + b*192 + 128
+
+    subs    srcw, srcw, #3
+
+    mov     r7, r7, asr #8          @ (a*64 + b*192 + 128) >> 8
+    strb    r7, [dest], #1
+
+    bpl     hl34_loop
+
+    ldrb    r8, [src], #1           @ b = src[1]
+    ldrb    r7, [src], #1           @ c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         @ a*64 + 128
+    mla     r4, r11, r8, r4         @ a*64 + b*192 + 1
+    mov     r4, r4, asr #8          @ (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    add     r8, r8, #1              @ b + 1
+    add     r8, r8, r7              @ b + c + 1
+    mov     r8, r8, asr #1          @ (b + c + 1) >> 1
+    strb    r8, [dest], #1
+    strb    r7, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|vp8cx_horizontal_line_3_4_scale_c|
+
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vertical_band_3_4_scale_armv4
+@ *
+@ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+@ *                  unsigned int dest_pitch : Stride of destination data.
+@ *                  unsigned int dest_width : Width of destination data.
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Scales vertical band of pixels by scale 3 to 4. The
+@ *                  height of the band scaled is 3-pixels.
+@ *
+@ *  SPECIAL NOTES : The routine uses the first line of the band below
+@ *                  the current band.
+@ *
+@ ****************************************************************************/
+@void vertical_band_3_4_scale_armv4
+@(
+@   r0 = UINT8 *dest
+@   r1 = UINT32 dest_pitch
+@   r2 = UINT32 dest_width
+@)
+_VerticalBand_3_4_Scale_ARMv4:
+    vertical_band_3_4_scale_armv4: @
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+@   ldr     r1,[r1]
+vl34_loop:
+    mov     r3, src
+    ldrb    r4, [r3], r1            @ a = des [0]
+    ldrb    r5, [r3], r1            @ b = des [dest_pitch]
+    ldrb    r7, [r3], r1            @ c = des [dest_pitch*2]
+    add     lr, src, r1
+
+    mla     r4, r10, r4, r9         @ a*64 + 128
+    mla     r4, r11, r5, r4         @ a*64 + b*192 + 1
+
+    add     r5, r5, #1              @ b + 1
+    add     r5, r5, r7              @ b + c + 1
+    mov     r5, r5, asr #1          @ (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          @ (a*64 + b*192 + 1) >> 8
+    strb    r4, [lr], r1
+
+    ldrb    r4, [r3, r1]            @ a = des [dest_pitch*4]
+
+    strb    r5, [lr], r1
+
+    mla     r7, r11, r7, r9         @ c*192 + 128
+    mla     r7, r4, r10, r7         @ a*64 + b*192 + 128
+    mov     r7, r7, asr #8          @ (a*64 + b*192 + 128) >> 8
+
+    add     src, src, #1
+    subs    r2, r2, #1
+
+    strb    r7, [lr]
+
+    bne     vl34_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    @   @|vertical_band_3_4_scale_armv4|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+@ *
+@ *  INPUTS        : const unsigned char *source : Pointer to source data.
+@ *                  unsigned int source_width    : Stride of source.
+@ *                  unsigned char *dest         : Pointer to destination data.
+@ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Copies horizontal line of pixels from source to
+@ *                  destination scaling up by 1 to 2.
+@ *
+@ *  SPECIAL NOTES : None.
+@ *
+@ ****************************************************************************/
+@void vp8cx_horizontal_line_1_2_scale_c
+@(
+@   const unsigned char *source,
+@   unsigned int source_width,
+@   unsigned char *dest,
+@   unsigned int dest_width
+@)
+_HorizontalLine_1_2_Scale_ARMv4:
+    horizontal_line_1_2_scale_armv4: @
+    stmdb   sp!, {r4 - r5, lr}
+
+    sub     srcw, srcw, #1
+
+    ldrb    r3, [src], #1
+    ldrb    r4, [src], #1
+hl12_loop:
+    subs    srcw, srcw, #1
+
+    add     r5, r3, r4
+    add     r5, r5, #1
+    mov     r5, r5, lsr #1
+
+    orr     r5, r3, r5, lsl #8
+    strh    r5, [dest], #2
+
+    mov     r3, r4
+
+    ldrneb  r4, [src], #1
+    bne     hl12_loop
+
+    orr     r5, r4, r4, lsl #8
+    strh    r5, [dest]
+
+    ldmia   sp!, {r4 - r5, pc}
+    @   @|vertical_band_3_5_scale_armv4|
+
+@/****************************************************************************
+@ *
+@ *  ROUTINE       : vp8cx_vertical_band_1_2_scale_c
+@ *
+@ *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+@ *                  unsigned int dest_pitch : Stride of destination data.
+@ *                  unsigned int dest_width : Width of destination data.
+@ *
+@ *  OUTPUTS       : None.
+@ *
+@ *  RETU.req_s       : void
+@ *
+@ *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+@ *                  height of the band scaled is 1-pixel.
+@ *
+@ *  SPECIAL NOTES : The routine uses the first line of the band below
+@ *                  the current band.
+@ *
+@ ****************************************************************************/
+@void vp8cx_vertical_band_1_2_scale_c
+@(
+@   r0 = UINT8 *dest
+@   r1 = UINT32 dest_pitch
+@   r2 = UINT32 dest_width
+@)
+_VerticalBand_1_2_Scale_ARMv4:
+    vertical_band_1_2_scale_armv4: @
+    stmdb   sp!, {r4 - r7, lr}
+
+    ldr     mask, =0xff00ff             @ mask for selection
+    ldr     lr, = 0x010001
+
+vl12_loop:
+    mov     r3, src
+    ldr     r4, [r3], r1
+    ldr     r5, [r3, r1]
+
+    add     src, src, #4
+    subs    r2, r2, #4
+
+    and     r6, r4, mask
+    and     r7, r5, mask
+
+    add     r6, r7, r6
+    add     r6, r6, lr
+
+    and     r4, mask, r4, lsr #8
+    and     r5, mask, r5, lsr #8
+
+    mov     r6, r6, lsr #1
+    and     r6, r6, mask
+
+    add     r4, r5, r4
+    add     r4, r4, lr
+
+    mov     r4, r4, lsr #1
+    and     r4, r4, mask
+
+    orr     r5, r6, r4, lsl #8
+
+    str     r5, [r3]
+
+    bpl     vl12_loop
+
+    ldmia   sp!, {r4 - r7, pc}
+    @   @|vertical_band_3_5_scale_armv4|
diff --git a/vpx_scale/symbian/scalesystemdependant.c b/vpx_scale/symbian/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..a2acc3e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/vpxscale.h"
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_scale_machine_specific_config()
+{
+#ifndef VPX_NO_GLOBALS
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_armv4;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_armv4;
+    vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_armv4;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_armv4;
+    vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+    vp8_horizontal_line_3_4_scale        = horizontal_line_3_4_scale_armv4;
+    vp8_vertical_band_3_4_scale          = vertical_band_3_4_scale_armv4;
+    vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+    vp8_horizontal_line_2_3_scale        = horizontal_line_2_3_scale_armv4;
+    vp8_vertical_band_2_3_scale          = vertical_band_2_3_scale_armv4;
+    vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_armv4;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_armv4;
+    vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+
+
+    vp8_vertical_band_5_4_scale           = vp8cx_vertical_band_5_4_scale_c;
+    vp8_vertical_band_5_3_scale           = vp8cx_vertical_band_5_3_scale_c;
+    vp8_vertical_band_2_1_scale           = vp8cx_vertical_band_2_1_scale_c;
+    vp8_vertical_band_2_1_scale_i         = vp8cx_vertical_band_2_1_scale_i_c;
+    vp8_horizontal_line_2_1_scale         = vp8cx_horizontal_line_2_1_scale_c;
+    vp8_horizontal_line_5_3_scale         = vp8cx_horizontal_line_5_3_scale_c;
+    vp8_horizontal_line_5_4_scale         = vp8cx_horizontal_line_5_4_scale_c;
+#endif
+}
diff --git a/vpx_scale/vpx_scale.mk b/vpx_scale/vpx_scale.mk
new file mode 100644 (file)
index 0000000..f4ab258
--- /dev/null
@@ -0,0 +1,23 @@
+SCALE_SRCS-yes += vpx_scale.mk
+SCALE_SRCS-yes += scale_mode.h
+SCALE_SRCS-yes += yv12extend.h
+SCALE_SRCS-yes += yv12config.h
+SCALE_SRCS-yes += vpxscale.h
+SCALE_SRCS-yes += generic/vpxscale.c
+SCALE_SRCS-yes += generic/yv12config.c
+SCALE_SRCS-yes += generic/yv12extend.c
+SCALE_SRCS-yes += generic/scalesystemdependant.c
+SCALE_SRCS-$(CONFIG_SPATIAL_RESAMPLING) += generic/gen_scalers.c
+
+#arm
+SCALE_SRCS-$(HAVE_ARMV7)         += arm/scalesystemdependant.c
+SCALE_SRCS-$(HAVE_ARMV7)         += arm/yv12extend_arm.c
+SCALE_SRCS_REMOVE-$(HAVE_ARMV7)  += generic/scalesystemdependant.c
+
+#neon
+SCALE_SRCS-$(HAVE_ARMV7)  += arm/neon/vp8_vpxyv12_copyframe_func_neon$(ASM)
+SCALE_SRCS-$(HAVE_ARMV7)  += arm/neon/vp8_vpxyv12_copyframeyonly_neon$(ASM)
+SCALE_SRCS-$(HAVE_ARMV7)  += arm/neon/vp8_vpxyv12_copysrcframe_func_neon$(ASM)
+SCALE_SRCS-$(HAVE_ARMV7)  += arm/neon/vp8_vpxyv12_extendframeborders_neon$(ASM)
+
+SCALE_SRCS-no += $(SCALE_SRCS_REMOVE-yes)
diff --git a/vpx_scale/vpxscale.h b/vpx_scale/vpxscale.h
new file mode 100644 (file)
index 0000000..9a86b75
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef VPXSCALE_H
+#define VPXSCALE_H
+
+#include "vpx_scale/yv12config.h"
+void vp8cx_horizontal_line_4_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_last_vertical_band_4_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_2_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_last_vertical_band_2_3_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_3_5_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_last_vertical_band_3_5_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_3_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_last_vertical_band_3_4_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_1_2_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_last_vertical_band_1_2_scale_c(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_5_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_5_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_horizontal_line_2_1_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vp8cx_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vp8cx_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+
+extern void (*vp8_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_4_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_2_3_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_2_3_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_3_5_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_3_4_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_3_4_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_horizontal_line_1_2_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_3_4_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_3_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_2_3_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_4_5_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_last_vertical_band_1_2_scale)(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_5_4_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_5_3_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_2_1_scale)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_vertical_band_2_1_scale_i)(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+extern void (*vp8_horizontal_line_2_1_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_5_3_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+extern void (*vp8_horizontal_line_5_4_scale)(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+
+void horizontal_line_4_5_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_2_3_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_3_5_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_3_4_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void horizontal_line_1_2_scale_armv4(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width);
+void vertical_band_4_5_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_2_3_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_3_5_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_3_4_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+void vertical_band_1_2_scale_armv4(unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width);
+
+
+extern void  dmachine_specific_config(int mmx_enabled, int xmm_enabled, int wmt_enabled);
+extern void vp8_yv12_scale_or_center
+(
+    YV12_BUFFER_CONFIG *src_yuv_config,
+    YV12_BUFFER_CONFIG *dst_yuv_config,
+    int expanded_frame_width,
+    int expanded_frame_height,
+    int scaling_mode,
+    int HScale,
+    int HRatio,
+    int VScale,
+    int VRatio
+);
+extern void vp8_scale_frame
+(
+    YV12_BUFFER_CONFIG *src,
+    YV12_BUFFER_CONFIG *dst,
+    unsigned char *temp_area,
+    unsigned char temp_height,
+    unsigned int hscale,
+    unsigned int hratio,
+    unsigned int vscale,
+    unsigned int vratio,
+    unsigned int interlaced
+);
+extern void vp8_scale_machine_specific_config(void);
+
+extern void (*vp8_yv12_extend_frame_borders_ptr)(YV12_BUFFER_CONFIG *ybf);
+extern void vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf);
+extern void vp8_yv12_extend_frame_borders_neon(YV12_BUFFER_CONFIG *ybf);
+
+extern void (*vp8_yv12_copy_frame_yonly_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_yonly_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+extern void (*vp8_yv12_copy_frame_ptr)(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+extern void vp8_yv12_copy_frame_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+#endif
diff --git a/vpx_scale/wce/gen_scalers_armv4.asm b/vpx_scale/wce/gen_scalers_armv4.asm
new file mode 100644 (file)
index 0000000..1c904ed
--- /dev/null
@@ -0,0 +1,773 @@
+;
+;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+;
+;  Use of this source code is governed by a BSD-style license and patent
+;  grant that can be found in the LICENSE file in the root of the source
+;  tree. All contributing project authors may be found in the AUTHORS
+;  file in the root of the source tree.
+;
+
+
+    EXPORT  |horizontal_line_4_5_scale_armv4|
+    EXPORT  |vertical_band_4_5_scale_armv4|
+    EXPORT  |horizontal_line_2_3_scale_armv4|
+    EXPORT  |vertical_band_2_3_scale_armv4|
+    EXPORT  |horizontal_line_3_5_scale_armv4|
+    EXPORT  |vertical_band_3_5_scale_armv4|
+    EXPORT  |horizontal_line_3_4_scale_armv4|
+    EXPORT  |vertical_band_3_4_scale_armv4|
+    EXPORT  |horizontal_line_1_2_scale_armv4|
+    EXPORT  |vertical_band_1_2_scale_armv4|
+
+    AREA    |.text|, CODE, READONLY  ; name this block of code
+
+src         RN  r0
+srcw        RN  r1
+dest        RN  r2
+mask        RN  r12
+c51_205     RN  r10
+c102_154    RN  r11
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_4_5_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 4 to 5.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; ****************************************************************************/
+;void horizontal_line_4_5_scale_armv4
+;(
+;   r0 = UINT8 *source
+;   r1 = UINT32 source_width
+;   r2 = UINT8 *dest
+;   r3 = UINT32 dest_width
+;)
+|horizontal_line_4_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    mov     mask, #255              ; mask for selection
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldr     r3, [src], #4
+
+hl45_loop
+
+    and     r4, r3, mask            ; a = src[0]
+    and     r5, mask, r3, lsr #8    ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    and     r7, mask, r3, lsr #16   ; c = src[2]
+    mul     r6, c51_205, r6         ; a * 51 + 205 * b
+
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5        ; b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsr #24   ; d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mul     r7, c102_154, r7        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    ldr     r3, [src], #4
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    and     r9, mask, r3            ; e = src[4]
+    orr     r9, r9, r8, lsl #16     ; d | e
+    mul     r9, c51_205, r9         ; d * 205 + 51 * e
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #4
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bne     hl45_loop
+
+    and     r4, r3, mask
+    and     r5, mask, r3, lsl #8
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    mul     r6, c51_205, r6
+
+    and     r7, mask, r3, lsl #16
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5
+    add     r6, r6, #0x8000
+    and     r8, mask, r3, lsl #24
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mul     r7, c102_154, r7
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    ldrb    r3, [src]
+    strb    r3, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_4_5_scale_c|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_4_5_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 4 to 5. The
+; *                  height of the band scaled is 4-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_4_5_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_4_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl45_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r6, r4, r5, lsl #16     ; b | a
+    mul     r6, c51_205, r6         ; a * 51 + 205 * b
+
+    ldrb    r8, [r3], r1            ; d = des[dest_pitch*3]
+    orr     r5, r5, r7, lsl #16     ; c | b
+    mul     r5, c102_154, r5        ; b * 102 + 154 * c
+    add     r6, r6, #0x8000
+    orr     r7, r8, r7, lsl #16     ; c | d
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    ldrb    r9, [r3, r1]            ; e = des [dest_pitch * 5]
+    mul     r7, c102_154, r7        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    orr     r9, r9, r8, lsl #16     ; d | e
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    mul     r9, c51_205, r9         ; d * 205 + 51 * e
+    add     r7, r7, #0x8000
+    add     src, src, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+    add     r9, r9, #0x8000
+    subs    r2, r2, #1
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    bne     vl45_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_4_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_2_3_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 2 to 3.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void horizontal_line_2_3_scale_armv4
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_2_3_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+
+hl23_loop
+
+    ldrb    r3, [src], #1           ; a
+    ldrb    r4, [src], #1           ; b
+    ldrb    r5, [src]               ; c
+
+    strb    r3, [dest], #1
+    mul     r4, r12, r4             ; b * 171
+    mla     r6, lr, r3, r4          ; a * 85
+    mla     r7, lr, r5, r4          ; c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest], #1
+
+    add     r7, r7, #128
+    mov     r7, r7, lsr #8
+    strb    r7, [dest], #1
+
+    subs    srcw, srcw, #2
+    bne     hl23_loop
+
+    ldrb    r4, [src, #1]           ; b
+    strb    r5, [dest], #1
+    strb    r4, [dest, #1]
+
+    mul     r4, r12, r4             ; b * 171
+    mla     r6, lr, r5, r4          ; a * 85 + b *171
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [dest]
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|horizontal_line_2_3_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_2_3_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 2 to 3. The
+; *                  height of the band scaled is 2-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_2_3_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_2_3_scale_armv4| PROC
+    stmdb   sp!, {r4 - r8, lr}
+    ldr     lr,  =85
+    ldr     r12, =171
+    add     r3, r1, r1, lsl #1      ; 3 * dest_pitch
+
+vl23_loop
+    ldrb    r4, [src]               ; a = des [0]
+    ldrb    r5, [src, r1]           ; b = des [dest_pitch]
+    ldrb    r7, [src, r3]           ; c = des [dest_pitch*3]
+    subs    r2, r2, #1
+
+    mul     r5, r12, r5             ; b * 171
+    mla     r6, lr, r4, r5          ; a * 85
+    mla     r8, lr, r7, r5          ; c * 85
+
+    add     r6, r6, #128
+    mov     r6, r6, lsr #8
+    strb    r6, [src, r1]
+
+    add     r8, r8, #128
+    mov     r8, r8, lsr #8
+    strb    r8, [src, r1, lsl #1]
+
+    add     src, src, #1
+
+    bne     vl23_loop
+
+    ldmia   sp!, {r4 - r8, pc}
+    ENDP    ;|vertical_band_2_3_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_horizontal_line_3_5_scale_c
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 3 to 5.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void vp8cx_horizontal_line_3_5_scale_c
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_3_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+    ldrb    r4, [src], #1           ; a = src[0]
+
+hl35_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     ; b | a
+    ldrb    r9, [src], #1           ; c = src[2]
+    mul     r6, c102_154, r6        ; a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     ; b | c
+    mul     r5, c51_205, r5         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    ldrb    r4, [src], #1           ; d = src[3]
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     ; c | b
+    mul     r7, c51_205, r7         ; c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    orr     r9, r4, r9, lsl #16     ; c | d
+    mul     r9, c102_154, r9        ; c * 154 + 102 * d
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+
+    add     r9, r9, #0x8000
+    subs    srcw, srcw, #3
+    mov     r9, r9, lsr #24
+    strb    r9, [dest], #1
+
+    bpl     hl35_loop
+
+    ldrb    r5, [src], #1           ; b = src[1]
+    strb    r4, [dest], #1
+
+    orr     r6, r4, r8, lsl #16     ; b | a
+    ldrb    r9, [src], #1           ; c = src[2]
+    mul     r6, c102_154, r6        ; a * 102 + 154 * b
+
+    orr     r5, r9, r8, lsl #16     ; b | c
+    mul     r5, c51_205, r5         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    mov     r6, r6, lsr #24
+    strb    r6, [dest], #1
+
+    orr     r7, r8, r9, lsl #16     ; c | b
+    mul     r7, c51_205, r7         ; c * 205 + 154 * b
+    add     r5, r5, #0x8000
+    mov     r5, r5, lsr #24
+    strb    r5, [dest], #1
+
+    add     r7, r7, #0x8000
+    mov     r7, r7, lsr #24
+    strb    r7, [dest], #1
+    strb    r9, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_3_5_scale_c|
+
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_vertical_band_3_5_scale_c
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 3 to 5. The
+; *                  height of the band scaled is 3-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_4_5_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_3_5_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     c51_205, =0x3300cd
+    ldr     c102_154, =0x66009a
+
+vl35_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des[dest_pitch*2]
+    add     lr, src, r1
+
+    orr     r8, r4, r5, lsl #16     ; b | a
+    mul     r6, c102_154, r8        ; a * 102 + 154 * b
+
+    ldrb    r8, [r3, r1, lsl #1]    ; d = des[dest_pitch*5]
+    orr     r3, r7, r5, lsl #16     ; b | c
+    mul     r9, c51_205, r3         ; b * 205 + 51 * c
+    add     r6, r6, #0x8000
+    orr     r3, r5, r7, lsl #16     ; c | b
+    mov     r6, r6, lsr #24
+    strb    r6, [lr], r1
+
+    mul     r5, c51_205, r3         ; c * 205 + 154 * b
+    add     r9, r9, #0x8000
+    orr     r3, r8, r7, lsl #16     ; c | d
+    mov     r9, r9, lsr #24
+    strb    r9, [lr], r1
+
+    mul     r7, c102_154, r3        ; c * 154 + 102 * d
+    add     r5, r5, #0x8000
+    add     src, src, #1
+    mov     r5, r5, lsr #24
+    strb    r5, [lr], r1
+
+    add     r7, r7, #0x8000
+    subs    r2, r2, #1
+    mov     r7, r7, lsr #24
+    strb    r7, [lr], r1
+
+
+    bne     vl35_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : horizontal_line_3_4_scale_armv4
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 3 to 4.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; *
+; ****************************************************************************/
+;void horizontal_line_3_4_scale_armv4
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_3_4_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+    ldrb    r4, [src], #1           ; a = src[0]
+
+hl34_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    ldrb    r7, [src], #1           ; c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r8, r4         ; a*64 + b*192 + 1
+
+    add     r8, r8, #1              ; b + 1
+    add     r8, r8, r7              ; b + c + 1
+    mov     r8, r8, asr #1          ; (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    strb    r8, [dest], #1
+
+    ldrb    r4, [src], #1           ; [a+1]
+
+    mla     r7, r11, r7, r9         ; c*192 + 128
+    mla     r7, r4, r10, r7         ; a*64 + b*192 + 128
+
+    subs    srcw, srcw, #3
+
+    mov     r7, r7, asr #8          ; (a*64 + b*192 + 128) >> 8
+    strb    r7, [dest], #1
+
+    bpl     hl34_loop
+
+    ldrb    r8, [src], #1           ; b = src[1]
+    ldrb    r7, [src], #1           ; c = src[2]
+    strb    r4, [dest], #1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r8, r4         ; a*64 + b*192 + 1
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [dest], #1
+
+    add     r8, r8, #1              ; b + 1
+    add     r8, r8, r7              ; b + c + 1
+    mov     r8, r8, asr #1          ; (b + c + 1) >> 1
+    strb    r8, [dest], #1
+    strb    r7, [dest], #1
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vp8cx_horizontal_line_3_4_scale_c|
+
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vertical_band_3_4_scale_armv4
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 3 to 4. The
+; *                  height of the band scaled is 3-pixels.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vertical_band_3_4_scale_armv4
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_3_4_scale_armv4| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r10, =64
+    ldr     r11, =192
+    mov     r9, #128
+
+;   ldr     r1,[r1]
+vl34_loop
+    mov     r3, src
+    ldrb    r4, [r3], r1            ; a = des [0]
+    ldrb    r5, [r3], r1            ; b = des [dest_pitch]
+    ldrb    r7, [r3], r1            ; c = des [dest_pitch*2]
+    add     lr, src, r1
+
+    mla     r4, r10, r4, r9         ; a*64 + 128
+    mla     r4, r11, r5, r4         ; a*64 + b*192 + 1
+
+    add     r5, r5, #1              ; b + 1
+    add     r5, r5, r7              ; b + c + 1
+    mov     r5, r5, asr #1          ; (b + c + 1) >> 1
+
+    mov     r4, r4, asr #8          ; (a*64 + b*192 + 1) >> 8
+    strb    r4, [lr], r1
+
+    ldrb    r4, [r3, r1]            ; a = des [dest_pitch*4]
+
+    strb    r5, [lr], r1
+
+    mla     r7, r11, r7, r9         ; c*192 + 128
+    mla     r7, r4, r10, r7         ; a*64 + b*192 + 128
+    mov     r7, r7, asr #8          ; (a*64 + b*192 + 128) >> 8
+
+    add     src, src, #1
+    subs    r2, r2, #1
+
+    strb    r7, [lr]
+
+    bne     vl34_loop
+
+    ldmia   sp!, {r4 - r11, pc}
+    ENDP    ;|vertical_band_3_4_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_horizontal_line_1_2_scale_c
+; *
+; *  INPUTS        : const unsigned char *source : Pointer to source data.
+; *                  unsigned int source_width    : Stride of source.
+; *                  unsigned char *dest         : Pointer to destination data.
+; *                  unsigned int dest_width      : Stride of destination (NOT USED).
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Copies horizontal line of pixels from source to
+; *                  destination scaling up by 1 to 2.
+; *
+; *  SPECIAL NOTES : None.
+; *
+; ****************************************************************************/
+;void vp8cx_horizontal_line_1_2_scale_c
+;(
+;   const unsigned char *source,
+;   unsigned int source_width,
+;   unsigned char *dest,
+;   unsigned int dest_width
+;)
+|horizontal_line_1_2_scale_armv4| PROC
+    stmdb   sp!, {r4 - r5, lr}
+
+    sub     srcw, srcw, #1
+
+    ldrb    r3, [src], #1
+    ldrb    r4, [src], #1
+hl12_loop
+    subs    srcw, srcw, #1
+
+    add     r5, r3, r4
+    add     r5, r5, #1
+    mov     r5, r5, lsr #1
+
+    orr     r5, r3, r5, lsl #8
+    strh    r5, [dest], #2
+
+    mov     r3, r4
+
+    ldrneb  r4, [src], #1
+    bne     hl12_loop
+
+    orr     r5, r4, r4, lsl #8
+    strh    r5, [dest]
+
+    ldmia   sp!, {r4 - r5, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+;/****************************************************************************
+; *
+; *  ROUTINE       : vp8cx_vertical_band_1_2_scale_c
+; *
+; *  INPUTS        : unsigned char *dest    : Pointer to destination data.
+; *                  unsigned int dest_pitch : Stride of destination data.
+; *                  unsigned int dest_width : Width of destination data.
+; *
+; *  OUTPUTS       : None.
+; *
+; *  RETURNS       : void
+; *
+; *  FUNCTION      : Scales vertical band of pixels by scale 1 to 2. The
+; *                  height of the band scaled is 1-pixel.
+; *
+; *  SPECIAL NOTES : The routine uses the first line of the band below
+; *                  the current band.
+; *
+; ****************************************************************************/
+;void vp8cx_vertical_band_1_2_scale_c
+;(
+;   r0 = UINT8 *dest
+;   r1 = UINT32 dest_pitch
+;   r2 = UINT32 dest_width
+;)
+|vertical_band_1_2_scale_armv4| PROC
+    stmdb   sp!, {r4 - r7, lr}
+
+    ldr     mask, =0xff00ff             ; mask for selection
+    ldr     lr, = 0x010001
+
+vl12_loop
+    mov     r3, src
+    ldr     r4, [r3], r1
+    ldr     r5, [r3, r1]
+
+    add     src, src, #4
+    subs    r2, r2, #4
+
+    and     r6, r4, mask
+    and     r7, r5, mask
+
+    add     r6, r7, r6
+    add     r6, r6, lr
+
+    and     r4, mask, r4, lsr #8
+    and     r5, mask, r5, lsr #8
+
+    mov     r6, r6, lsr #1
+    and     r6, r6, mask
+
+    add     r4, r5, r4
+    add     r4, r4, lr
+
+    mov     r4, r4, lsr #1
+    and     r4, r4, mask
+
+    orr     r5, r6, r4, lsl #8
+
+    str     r5, [r3]
+
+    bpl     vl12_loop
+
+    ldmia   sp!, {r4 - r7, pc}
+    ENDP    ;|vertical_band_3_5_scale_armv4|
+
+    END
diff --git a/vpx_scale/wce/scalesystemdependant.c b/vpx_scale/wce/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..a5a6a52
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#include "vpx_scale/vpxscale.h"
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vp8_scale_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void vp8_scale_machine_specific_config()
+{
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_armv4;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_armv4;
+    vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_armv4;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_armv4;
+    vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+    vp8_horizontal_line_3_4_scale        = horizontal_line_3_4_scale_armv4;
+    vp8_vertical_band_3_4_scale          = vertical_band_3_4_scale_armv4;
+    vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+    vp8_horizontal_line_2_3_scale        = horizontal_line_2_3_scale_armv4;
+    vp8_vertical_band_2_3_scale          = vertical_band_2_3_scale_armv4;
+    vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_armv4;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_armv4;
+    vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+
+
+    vp8_vertical_band_5_4_scale           = vp8cx_vertical_band_5_4_scale_c;
+    vp8_vertical_band_5_3_scale           = vp8cx_vertical_band_5_3_scale_c;
+    vp8_vertical_band_2_1_scale           = vp8cx_vertical_band_2_1_scale_c;
+    vp8_vertical_band_2_1_scale_i         = vp8cx_vertical_band_2_1_scale_i_c;
+    vp8_horizontal_line_2_1_scale         = vp8cx_horizontal_line_2_1_scale_c;
+    vp8_horizontal_line_5_3_scale         = vp8cx_horizontal_line_5_3_scale_c;
+    vp8_horizontal_line_5_4_scale         = vp8cx_horizontal_line_5_4_scale_c;
+}
diff --git a/vpx_scale/win32/scaleopt.c b/vpx_scale/win32/scaleopt.c
new file mode 100644 (file)
index 0000000..da0533e
--- /dev/null
@@ -0,0 +1,1749 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     scaleopt.cpp
+*
+*   Description  :     Optimized scaling functions
+*
+****************************************************************************/
+#include "pragmas.h"
+
+
+
+/****************************************************************************
+*  Module Statics
+****************************************************************************/
+__declspec(align(16)) const static unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+__declspec(align(16)) const static unsigned short two_fifths[] = { 102, 102, 102, 102 };
+__declspec(align(16)) const static unsigned short three_fifths[] = { 154, 154, 154, 154 };
+__declspec(align(16)) const static unsigned short four_fifths[] = { 205, 205, 205, 205 };
+__declspec(align(16)) const static unsigned short round_values[] = { 128, 128, 128, 128 };
+__declspec(align(16)) const static unsigned short four_ones[] = { 1, 1, 1, 1};
+__declspec(align(16)) const static unsigned short const45_2[] = {205, 154, 102,  51 };
+__declspec(align(16)) const static unsigned short const45_1[] = { 51, 102, 154, 205 };
+__declspec(align(16)) const static unsigned char  mask45[] = { 0, 0, 0, 0, 0, 0, 255, 0};
+__declspec(align(16)) const static unsigned short const35_2[] = { 154,  51, 205, 102 };
+__declspec(align(16)) const static unsigned short const35_1[] = { 102, 205,  51, 154 };
+
+
+
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_3_5_scale_mmx
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 3 to 5 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_3_5_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    __asm
+    {
+
+        push ebx
+
+        mov         esi,    source
+        mov         edi,    dest
+
+        mov         ecx,    source_width
+        lea         edx,    [esi+ecx-3];
+
+        movq        mm5,    const35_1       // mm5 = 66 xx cd xx 33 xx 9a xx
+        movq        mm6,    const35_2       // mm6 = 9a xx 33 xx cd xx 66 xx
+
+        movq        mm4,    round_values     // mm4 = 80 xx 80 xx 80 xx 80 xx
+        pxor        mm7,    mm7             // clear mm7
+
+        horiz_line_3_5_loop:
+
+        mov        eax,    DWORD PTR [esi] // eax = 00 01 02 03
+        mov        ebx,    eax
+
+        and         ebx,    0xffff00        // ebx = xx 01 02 xx
+        mov         ecx,    eax             // ecx = 00 01 02 03
+
+        and         eax,    0xffff0000      // eax = xx xx 02 03
+        xor         ecx,    eax             // ecx = 00 01 xx xx
+
+        shr         ebx,    8               // ebx = 01 02 xx xx
+        or          eax,    ebx             // eax = 01 02 02 03
+
+        shl         ebx,    16              // ebx = xx xx 01 02
+        movd        mm1,    eax             // mm1 = 01 02 02 03 xx xx xx xx
+
+        or          ebx,    ecx             // ebx = 00 01 01 02
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 02 xx 03 xx
+
+        movd        mm0,    ebx             // mm0 = 00 01 01 02
+        pmullw      mm1,    mm6             //
+
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 01 xx 02 xx
+        pmullw      mm0,    mm5             //
+
+        mov         [edi],  ebx             // writeoutput 00 xx xx xx
+        add         esi,    3
+
+        add         edi,    5
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm4
+        psrlw       mm0,    8
+
+        cmp         esi,    edx
+        packuswb    mm0,    mm7
+
+        movd        DWORD Ptr [edi-4], mm0
+        jl          horiz_line_3_5_loop
+
+//Exit:
+        mov         eax,    DWORD PTR [esi] // eax = 00 01 02 03
+        mov         ebx,    eax
+
+        and         ebx,    0xffff00        // ebx = xx 01 02 xx
+        mov         ecx,    eax             // ecx = 00 01 02 03
+
+        and         eax,    0xffff0000      // eax = xx xx 02 03
+        xor         ecx,    eax             // ecx = 00 01 xx xx
+
+        shr         ebx,    8               // ebx = 01 02 xx xx
+        or          eax,    ebx             // eax = 01 02 02 03
+
+        shl         eax,    8               // eax = xx 01 02 02
+        and         eax,    0xffff0000      // eax = xx xx 02 02
+
+        or          eax,    ebx             // eax = 01 02 02 02
+
+        shl         ebx,    16              // ebx = xx xx 01 02
+        movd        mm1,    eax             // mm1 = 01 02 02 02 xx xx xx xx
+
+        or          ebx,    ecx             // ebx = 00 01 01 02
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 02 xx 02 xx
+
+        movd        mm0,    ebx             // mm0 = 00 01 01 02
+        pmullw      mm1,    mm6             //
+
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 01 xx 02 xx
+        pmullw      mm0,    mm5             //
+
+        mov         [edi],  ebx             // writeoutput 00 xx xx xx
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm4
+        psrlw       mm0,    8
+
+        packuswb    mm0,    mm7
+        movd        DWORD Ptr [edi+1], mm0
+
+        pop ebx
+
+    }
+
+}
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_4_5_scale_mmx
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 4 to 5 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_4_5_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void)dest_width;
+
+    __asm
+    {
+
+        mov         esi,    source
+        mov         edi,    dest
+
+        mov         ecx,    source_width
+        lea         edx,    [esi+ecx-8];
+
+        movq        mm5,    const45_1       // mm5 = 33 xx 66 xx 9a xx cd xx
+        movq        mm6,    const45_2       // mm6 = cd xx 9a xx 66 xx 33 xx
+
+        movq        mm4,    round_values     // mm4 = 80 xx 80 xx 80 xx 80 xx
+        pxor        mm7,    mm7             // clear mm7
+
+        horiz_line_4_5_loop:
+
+        movq        mm0,    QWORD PTR [esi]           // mm0 = 00 01 02 03 04 05 06 07
+        movq        mm1,    QWORD PTR [esi+1];        // mm1 = 01 02 03 04 05 06 07 08
+
+        movq        mm2,    mm0             // mm2 = 00 01 02 03 04 05 06 07
+        movq        mm3,    mm1             // mm3 = 01 02 03 04 05 06 07 08
+
+        movd        DWORD PTR [edi],  mm0             // write output 00 xx xx xx
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 02 xx 03 xx
+
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 03 xx 04 xx
+        pmullw      mm0,    mm5             // 00* 51 01*102 02*154 03*205
+
+        pmullw      mm1,    mm6             // 01*205 02*154 03*102 04* 51
+        punpckhbw   mm2,    mm7             // mm2 = 04 xx 05 xx 06 xx 07 xx
+
+        movd        DWORD PTR [edi+5], mm2            // write ouput 05 xx xx xx
+        pmullw      mm2,    mm5             // 04* 51 05*102 06*154 07*205
+
+        punpckhbw   mm3,    mm7             // mm3 = 05 xx 06 xx 07 xx 08 xx
+        pmullw      mm3,    mm6             // 05*205 06*154 07*102 08* 51
+
+        paddw       mm0,    mm1             // added round values
+        paddw       mm0,    mm4
+
+        psrlw       mm0,    8               // output: 01 xx 02 xx 03 xx 04 xx
+        packuswb    mm0,    mm7
+
+        movd        DWORD PTR [edi+1], mm0  // write output 01 02 03 04
+        add         edi,    10
+
+        add         esi,    8
+        paddw       mm2,    mm3             //
+
+        paddw       mm2,    mm4             // added round values
+        cmp         esi,    edx
+
+        psrlw       mm2,    8
+        packuswb    mm2,    mm7
+
+        movd        DWORD PTR [edi-4], mm2 // writeoutput 06 07 08 09
+        jl         horiz_line_4_5_loop
+
+//Exit:
+        movq        mm0,    [esi]           // mm0 = 00 01 02 03 04 05 06 07
+        movq        mm1,    mm0             // mm1 = 00 01 02 03 04 05 06 07
+
+        movq        mm2,    mm0             // mm2 = 00 01 02 03 04 05 06 07
+        psrlq       mm1,    8               // mm1 = 01 02 03 04 05 06 07 00
+
+        movq        mm3,    mask45          // mm3 = 00 00 00 00 00 00 ff 00
+        pand        mm3,    mm1             // mm3 = 00 00 00 00 00 00 07 00
+
+        psllq       mm3,    8               // mm3 = 00 00 00 00 00 00 00 07
+        por         mm1,    mm3             // mm1 = 01 02 03 04 05 06 07 07
+
+        movq        mm3,    mm1
+
+        movd        DWORD PTR [edi],  mm0   // write output 00 xx xx xx
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 02 xx 03 xx
+
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 03 xx 04 xx
+        pmullw      mm0,    mm5             // 00* 51 01*102 02*154 03*205
+
+        pmullw      mm1,    mm6             // 01*205 02*154 03*102 04* 51
+        punpckhbw   mm2,    mm7             // mm2 = 04 xx 05 xx 06 xx 07 xx
+
+        movd        DWORD PTR [edi+5], mm2  // write ouput 05 xx xx xx
+        pmullw      mm2,    mm5             // 04* 51 05*102 06*154 07*205
+
+        punpckhbw   mm3,    mm7             // mm3 = 05 xx 06 xx 07 xx 08 xx
+        pmullw      mm3,    mm6             // 05*205 06*154 07*102 07* 51
+
+        paddw       mm0,    mm1             // added round values
+        paddw       mm0,    mm4
+
+        psrlw       mm0,    8               // output: 01 xx 02 xx 03 xx 04 xx
+        packuswb    mm0,    mm7             // 01 02 03 04 xx xx xx xx
+
+        movd        DWORD PTR [edi+1], mm0  // write output 01 02 03 04
+        paddw       mm2,    mm3             //
+
+        paddw       mm2,    mm4             // added round values
+        psrlw       mm2,    8
+
+        packuswb    mm2,    mm7
+        movd        DWORD PTR [edi+6], mm2  // writeoutput 06 07 08 09
+
+
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_4_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 4 to 5 up-scaling of a 4 pixel high band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has a "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void vertical_band_4_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_4_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    one_fifth
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 1/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 1/5
+        movq        mm6,    four_fifths               // constan
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 4/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 4/5
+        paddw       mm0,    mm4                     // a * 1/5 + b * 4/5
+
+        paddw       mm2,    mm5                     // a * 1/5 + b * 4/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm5,    two_fifths
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm1,    mm5                     // b * 2/5
+        movq        mm6,    three_fifths
+
+
+        punpcklbw   mm0,    mm7                     // unpack low to word
+        pmullw      mm3,    mm5                     // b * 2/5
+
+        movq        mm4,    mm0                     // make copy of c
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm4,    mm6                     // c * 3/5
+        movq        mm5,    mm2
+
+        pmullw      mm5,    mm6                     // c * 3/5
+        paddw       mm1,    mm4                     // b * 2/5 + c * 3/5
+
+        paddw       mm3,    mm5                     // b * 2/5 + c * 3/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[2]
+
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+        movq        mm1,    [edi]                   // mm1=Src[3];
+
+        // mm0, mm2 --- Src[2]
+        // mm1 --- Src[3]
+        // mm6 --- 3/5
+        // mm7 for unpacking
+
+        pmullw      mm0,    mm6                     // c * 3/5
+        movq        mm5,    two_fifths               // mm5 = 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        pmullw      mm2,    mm6                     // c * 3/5
+
+        punpcklbw   mm1,    mm7                     // unpack low
+        movq        mm4,    mm1                     // make a copy
+
+        punpckhbw   mm3,    mm7                     // unpack high
+        pmullw      mm4,    mm5                     // d * 2/5
+
+        movq        mm6,    mm3                     // make a copy
+        pmullw      mm6,    mm5                     // d * 2/5
+
+        paddw       mm0,    mm4                     // c * 3/5 + d * 2/5
+        paddw       mm2,    mm6                     // c * 3/5 + d * 2/5
+
+        paddw       mm0,    round_values             // + 128
+        paddw       mm2,    round_values             // + 128
+
+        psrlw       mm0,    8
+        psrlw       mm2,    8
+
+        packuswb    mm0,    mm2                     // des[3]
+        movq        QWORD ptr [edi], mm0            // write des[3]
+
+        //  mm1, mm3 --- Src[3]
+        //  mm7 -- cleared for unpacking
+
+        movq        mm0,    [edi+ecx*2]             // mm0, Src[0] of the next group
+
+        movq        mm5,    four_fifths              // mm5 = 4/5
+        pmullw      mm1,    mm5                     // d * 4/5
+
+        movq        mm6,    one_fifth                // mm6 = 1/5
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm3,    mm5                     // d * 4/5
+        punpcklbw   mm0,    mm7                     // unpack low
+
+        pmullw      mm0,    mm6                     // an * 1/5
+        punpckhbw   mm2,    mm7                     // unpack high
+
+        paddw       mm1,    mm0                     // d * 4/5 + an * 1/5
+        pmullw      mm2,    mm6                     // an * 1/5
+
+        paddw       mm3,    mm2                     // d * 4/5 + an * 1/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[4]
+
+        movq        QWORD ptr [edi+ecx], mm1        // write des[4]
+
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg         vs_4_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_4_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : None
+ *
+ *  FUNCTION      : 4 to 5 up-scaling of the last 4-pixel high band in an image.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_4_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        last_vs_4_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    one_fifth
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 1/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 1/5
+        movq        mm6,    four_fifths               // constan
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 4/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 4/5
+        paddw       mm0,    mm4                     // a * 1/5 + b * 4/5
+
+        paddw       mm2,    mm5                     // a * 1/5 + b * 4/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm5,    two_fifths
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm1,    mm5                     // b * 2/5
+        movq        mm6,    three_fifths
+
+
+        punpcklbw   mm0,    mm7                     // unpack low to word
+        pmullw      mm3,    mm5                     // b * 2/5
+
+        movq        mm4,    mm0                     // make copy of c
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm4,    mm6                     // c * 3/5
+        movq        mm5,    mm2
+
+        pmullw      mm5,    mm6                     // c * 3/5
+        paddw       mm1,    mm4                     // b * 2/5 + c * 3/5
+
+        paddw       mm3,    mm5                     // b * 2/5 + c * 3/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[2]
+
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+        movq        mm1,    [edi]                   // mm1=Src[3];
+
+        movq        QWORD ptr [edi+ecx], mm1        // write des[4];
+
+        // mm0, mm2 --- Src[2]
+        // mm1 --- Src[3]
+        // mm6 --- 3/5
+        // mm7 for unpacking
+
+        pmullw      mm0,    mm6                     // c * 3/5
+        movq        mm5,    two_fifths               // mm5 = 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        pmullw      mm2,    mm6                     // c * 3/5
+
+        punpcklbw   mm1,    mm7                     // unpack low
+        movq        mm4,    mm1                     // make a copy
+
+        punpckhbw   mm3,    mm7                     // unpack high
+        pmullw      mm4,    mm5                     // d * 2/5
+
+        movq        mm6,    mm3                     // make a copy
+        pmullw      mm6,    mm5                     // d * 2/5
+
+        paddw       mm0,    mm4                     // c * 3/5 + d * 2/5
+        paddw       mm2,    mm6                     // c * 3/5 + d * 2/5
+
+        paddw       mm0,    round_values             // + 128
+        paddw       mm2,    round_values             // + 128
+
+        psrlw       mm0,    8
+        psrlw       mm2,    8
+
+        packuswb    mm0,    mm2                     // des[3]
+        movq        QWORD ptr [edi], mm0            // write des[3]
+
+        //  mm1, mm3 --- Src[3]
+        //  mm7 -- cleared for unpacking
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg          last_vs_4_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_3_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 3 to 5 up-scaling of a 3-pixel high band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void vertical_band_3_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_3_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    two_fifths               // mm5 = 2/5
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 2/5
+        movq        mm6,    three_fifths             // mm6 = 3/5
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 3/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 3/5
+        paddw       mm0,    mm4                     // a * 2/5 + b * 3/5
+
+        paddw       mm2,    mm5                     // a * 2/5 + b * 3/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm4,    mm1                     // b low
+        pmullw      mm1,    four_fifths              // b * 4/5 low
+
+        movq        mm5,    mm3                     // b high
+        pmullw      mm3,    four_fifths              // b * 4/5 high
+
+        movq        mm2,    mm0                     // c
+        pmullw      mm4,    one_fifth                // b * 1/5
+
+        punpcklbw   mm0,    mm7                     // c low
+        pmullw      mm5,    one_fifth                // b * 1/5
+
+        movq        mm6,    mm0                     // make copy of c low
+        punpckhbw   mm2,    mm7                     // c high
+
+        pmullw      mm6,    one_fifth                // c * 1/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    one_fifth                // c * 1/5 high
+        paddw       mm1,    mm6                     // b * 4/5 + c * 1/5 low
+
+        paddw       mm3,    mm7                     // b * 4/5 + c * 1/5 high
+        movq        mm6,    mm0                     // make copy of c low
+
+        pmullw      mm6,    four_fifths              // c * 4/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    four_fifths              // c * 4/5 high
+
+        paddw       mm4,    mm6                     // b * 1/5 + c * 4/5 low
+        paddw       mm5,    mm7                     // b * 1/5 + c * 4/5 high
+
+        paddw       mm1,    round_values             // + 128
+        paddw       mm3,    round_values             // + 128
+
+        psrlw       mm1,    8
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm3                     // des[2]
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+
+        paddw       mm4,    round_values             // + 128
+        paddw       mm5,    round_values             // + 128
+
+        psrlw       mm4,    8
+        psrlw       mm5,    8
+
+        packuswb    mm4,    mm5                     // des[3]
+        movq        QWORD ptr [edi], mm4            // write des[3]
+
+        //  mm0, mm2 --- Src[3]
+
+        pxor        mm7,    mm7                     // clear mm7 for unpacking
+        movq        mm1,    [edi+ecx*2]             // mm1 = Src[0] of the next group
+
+        movq        mm5,    three_fifths             // mm5 = 3/5
+        pmullw      mm0,    mm5                     // d * 3/5
+
+        movq        mm6,    two_fifths                // mm6 = 2/5
+        movq        mm3,    mm1                     // make a copy
+
+        pmullw      mm2,    mm5                     // d * 3/5
+        punpcklbw   mm1,    mm7                     // unpack low
+
+        pmullw      mm1,    mm6                     // an * 2/5
+        punpckhbw   mm3,    mm7                     // unpack high
+
+        paddw       mm0,    mm1                     // d * 3/5 + an * 2/5
+        pmullw      mm3,    mm6                     // an * 2/5
+
+        paddw       mm2,    mm3                     // d * 3/5 + an * 2/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des[4]
+
+        movq        QWORD ptr [edi+ecx], mm0        // write des[4]
+
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg          vs_3_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_3_5_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 3 to 5 up-scaling of a 3-pixel high band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_3_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         edi,    [esi+ecx*2]             // tow lines below
+        add         edi,    ecx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+
+        last_vs_3_5_loop:
+
+        movq        mm0,    QWORD ptr [esi]         // src[0];
+        movq        mm1,    QWORD ptr [esi+ecx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    two_fifths               // mm5 = 2/5
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 2/5
+        movq        mm6,    three_fifths             // mm6 = 3/5
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 3/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 3/5
+        paddw       mm0,    mm4                     // a * 2/5 + b * 3/5
+
+        paddw       mm2,    mm5                     // a * 2/5 + b * 3/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [esi+ecx], mm0        // write des[1]
+        movq        mm0,    [esi+ecx*2]             // mm0 = src[2]
+
+
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm4,    mm1                     // b low
+        pmullw      mm1,    four_fifths              // b * 4/5 low
+
+        movq        QWORD ptr [edi+ecx], mm0        // write des[4]
+
+        movq        mm5,    mm3                     // b high
+        pmullw      mm3,    four_fifths              // b * 4/5 high
+
+        movq        mm2,    mm0                     // c
+        pmullw      mm4,    one_fifth                // b * 1/5
+
+        punpcklbw   mm0,    mm7                     // c low
+        pmullw      mm5,    one_fifth                // b * 1/5
+
+        movq        mm6,    mm0                     // make copy of c low
+        punpckhbw   mm2,    mm7                     // c high
+
+        pmullw      mm6,    one_fifth                // c * 1/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    one_fifth                // c * 1/5 high
+        paddw       mm1,    mm6                     // b * 4/5 + c * 1/5 low
+
+        paddw       mm3,    mm7                     // b * 4/5 + c * 1/5 high
+        movq        mm6,    mm0                     // make copy of c low
+
+        pmullw      mm6,    four_fifths              // c * 4/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    four_fifths              // c * 4/5 high
+
+        paddw       mm4,    mm6                     // b * 1/5 + c * 4/5 low
+        paddw       mm5,    mm7                     // b * 1/5 + c * 4/5 high
+
+        paddw       mm1,    round_values             // + 128
+        paddw       mm3,    round_values             // + 128
+
+        psrlw       mm1,    8
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm3                     // des[2]
+        movq        QWORD ptr [esi+ecx*2], mm1      // write des[2]
+
+        paddw       mm4,    round_values             // + 128
+        paddw       mm5,    round_values             // + 128
+
+        psrlw       mm4,    8
+        psrlw       mm5,    8
+
+        packuswb    mm4,    mm5                     // des[3]
+        movq        QWORD ptr [edi], mm4            // write des[3]
+
+        //  mm0, mm2 --- Src[3]
+
+        add         edi,    8
+        add         esi,    8
+
+        sub         edx,    8
+        jg          last_vs_3_5_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : vertical_band_1_2_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of a band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void vertical_band_1_2_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_1_2_loop:
+
+        movq        mm0,    [esi]                   // get Src[0]
+        movq        mm1,    [esi + ecx * 2]         // get Src[1]
+
+        movq        mm2,    mm0                     // make copy before unpack
+        movq        mm3,    mm1                     // make copy before unpack
+
+        punpcklbw   mm0,    mm7                     // low Src[0]
+        movq        mm6,    four_ones                // mm6= 1, 1, 1, 1
+
+        punpcklbw   mm1,    mm7                     // low Src[1]
+        paddw       mm0,    mm1                     // low (a + b)
+
+        punpckhbw   mm2,    mm7                     // high Src[0]
+        paddw       mm0,    mm6                     // low (a + b + 1)
+
+        punpckhbw   mm3,    mm7
+        paddw       mm2,    mm3                     // high (a + b )
+
+        psraw       mm0,    1                       // low (a + b +1 )/2
+        paddw       mm2,    mm6                     // high (a + b + 1)
+
+        psraw       mm2,    1                       // high (a + b + 1)/2
+        packuswb    mm0,    mm2                     // pack results
+
+        movq        [esi+ecx], mm0                  // write out eight bytes
+        add         esi,    8
+
+        sub         edx,    8
+        jg          vs_1_2_loop
+    }
+
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : last_vertical_band_1_2_scale_mmx
+ *
+ *  INPUTS        : unsigned char *dest    :
+ *                  unsigned int dest_pitch :
+ *                  unsigned int dest_width :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of band of pixels.
+ *
+ *  SPECIAL NOTES : The routine uses the first line of the band below
+ *                  the current band. The function also has an "C" only
+ *                  version.
+ *
+ ****************************************************************************/
+static
+void last_vertical_band_1_2_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         esi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        mov         edx,    dest_width               // Loop counter
+
+        last_vs_1_2_loop:
+
+        movq        mm0,    [esi]                   // get Src[0]
+        movq        [esi+ecx], mm0                  // write out eight bytes
+
+        add         esi,    8
+        sub         edx,    8
+
+        jg         last_vs_1_2_loop
+    }
+}
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_1_2_scale
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_1_2_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    __asm
+    {
+        mov         esi,    source
+        mov         edi,    dest
+
+        pxor        mm7,    mm7
+        movq        mm6,    four_ones
+
+        mov         ecx,    source_width
+
+        hs_1_2_loop:
+
+        movq        mm0,    [esi]
+        movq        mm1,    [esi+1]
+
+        movq        mm2,    mm0
+        movq        mm3,    mm1
+
+        movq        mm4,    mm0
+        punpcklbw   mm0,    mm7
+
+        punpcklbw   mm1,    mm7
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm6
+        punpckhbw   mm2,    mm7
+
+        punpckhbw   mm3,    mm7
+        paddw       mm2,    mm3
+
+        paddw       mm2,    mm6
+        psraw       mm0,    1
+
+        psraw       mm2,    1
+        packuswb    mm0,    mm2
+
+        movq        mm2,    mm4
+        punpcklbw   mm2,    mm0
+
+        movq        [edi],  mm2
+        punpckhbw   mm4,    mm0
+
+        movq        [edi+8], mm4
+        add         esi,    8
+
+        add         edi,    16
+        sub         ecx,    8
+
+        cmp         ecx,    8
+        jg          hs_1_2_loop
+
+// last eight pixel
+
+        movq        mm0,    [esi]
+        movq        mm1,    mm0
+
+        movq        mm2,    mm0
+        movq        mm3,    mm1
+
+        psrlq       mm1,    8
+        psrlq       mm3,    56
+
+        psllq       mm3,    56
+        por         mm1,    mm3
+
+        movq        mm3,    mm1
+        movq        mm4,    mm0
+
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+
+        paddw       mm0,    mm1
+        paddw       mm0,    mm6
+
+        punpckhbw   mm2,    mm7
+        punpckhbw   mm3,    mm7
+
+        paddw       mm2,    mm3
+        paddw       mm2,    mm6
+
+        psraw       mm0,    1
+        psraw       mm2,    1
+
+        packuswb    mm0,    mm2
+        movq        mm2,    mm4
+
+        punpcklbw   mm2,    mm0
+        movq        [edi],  mm2
+
+        punpckhbw   mm4,    mm0
+        movq        [edi+8], mm4
+    }
+}
+
+
+
+
+
+__declspec(align(16)) const static unsigned short const54_2[] = {  0,  64, 128, 192 };
+__declspec(align(16)) const static unsigned short const54_1[] = {256, 192, 128,  64 };
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_5_4_scale_mmx
+ *
+ *  INPUTS        : const unsigned char *source : Pointer to source data.
+ *                  unsigned int source_width    : Stride of source.
+ *                  unsigned char *dest         : Pointer to destination data.
+ *                  unsigned int dest_width      : Stride of destination (NOT USED).
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Copies horizontal line of pixels from source to
+ *                  destination scaling up by 4 to 5.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_5_4_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    /*
+    unsigned i;
+    unsigned int a, b, c, d, e;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for ( i=0; i<source_width; i+=5 )
+    {
+        a = src[0];
+        b = src[1];
+        c = src[2];
+        d = src[3];
+        e = src[4];
+
+        des[0] = a;
+        des[1] = ((b*192 + c* 64 + 128)>>8);
+        des[2] = ((c*128 + d*128 + 128)>>8);
+        des[3] = ((d* 64 + e*192 + 128)>>8);
+
+        src += 5;
+        des += 4;
+    }
+    */
+    (void) dest_width;
+
+    __asm
+    {
+
+        mov         esi,        source              ;
+        mov         edi,        dest                ;
+
+        mov         ecx,        source_width         ;
+        movq        mm5,        const54_1           ;
+
+        pxor        mm7,        mm7                 ;
+        movq        mm6,        const54_2           ;
+
+        movq        mm4,        round_values         ;
+        lea         edx,        [esi+ecx]           ;
+        horizontal_line_5_4_loop:
+
+        movq        mm0,        QWORD PTR  [esi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psrlq       mm0,        8                   ;
+        01 02 03 04 05 06 07 xx
+        punpcklbw   mm1,        mm7                 ;
+        xx 00 xx 01 xx 02 xx 03
+
+        punpcklbw   mm0,        mm7                 ;
+        xx 01 xx 02 xx 03 xx 04
+        pmullw      mm1,        mm5
+
+        pmullw      mm0,        mm6
+        add         esi,        5
+
+        add         edi,        4
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        cmp         esi,        edx
+        packuswb    mm1,        mm7
+
+        movd        DWORD PTR [edi-4], mm1
+
+        jl          horizontal_line_5_4_loop
+
+    }
+
+}
+__declspec(align(16)) const static unsigned short one_fourths[]   = {  64,  64,  64, 64  };
+__declspec(align(16)) const static unsigned short two_fourths[]   = { 128, 128, 128, 128 };
+__declspec(align(16)) const static unsigned short three_fourths[] = { 192, 192, 192, 192 };
+
+static
+void vertical_band_5_4_scale_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+
+    __asm
+    {
+        push        ebx
+
+        mov         esi,    source                    // Get the source and destination pointer
+        mov         ecx,    src_pitch               // Get the pitch size
+
+        mov         edi,    dest                    // tow lines below
+        pxor        mm7,    mm7                     // clear out mm7
+
+        mov         edx,    dest_pitch               // Loop counter
+        mov         ebx,    dest_width
+
+        vs_5_4_loop:
+
+        movd        mm0,    DWORD ptr [esi]         // src[0];
+        movd        mm1,    DWORD ptr [esi+ecx]     // src[1];
+
+        movd        mm2,    DWORD ptr [esi+ecx*2]
+        lea         eax,    [esi+ecx*2]             //
+
+        punpcklbw   mm1,    mm7
+        punpcklbw   mm2,    mm7
+
+        movq        mm3,    mm2
+        pmullw      mm1,    three_fourths
+
+        pmullw      mm2,    one_fourths
+        movd        mm4,    [eax+ecx]
+
+        pmullw      mm3,    two_fourths
+        punpcklbw   mm4,    mm7
+
+        movq        mm5,    mm4
+        pmullw      mm4,    two_fourths
+
+        paddw       mm1,    mm2
+        movd        mm6,    [eax+ecx*2]
+
+        pmullw      mm5,    one_fourths
+        paddw       mm1,    round_values;
+
+        paddw       mm3,    mm4
+        psrlw       mm1,    8
+
+        punpcklbw   mm6,    mm7
+        paddw       mm3,    round_values
+
+        pmullw      mm6,    three_fourths
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm7
+        packuswb    mm3,    mm7
+
+        movd        DWORD PTR [edi], mm0
+        movd        DWORD PTR [edi+edx], mm1
+
+
+        paddw       mm5,    mm6
+        movd        DWORD PTR [edi+edx*2], mm3
+
+        lea         eax,    [edi+edx*2]
+        paddw       mm5,    round_values
+
+        psrlw       mm5,    8
+        add         edi,    4
+
+        packuswb    mm5,    mm7
+        movd        DWORD PTR [eax+edx], mm5
+
+        add         esi,    4
+        sub         ebx,    4
+
+        jg         vs_5_4_loop
+
+        pop         ebx
+    }
+}
+
+
+__declspec(align(16)) const static unsigned short const53_1[] = {  0,  85, 171, 0 };
+__declspec(align(16)) const static unsigned short const53_2[] = {256, 171,  85, 0 };
+
+
+static
+void horizontal_line_5_3_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+
+    (void) dest_width;
+    __asm
+    {
+
+        mov         esi,        source              ;
+        mov         edi,        dest                ;
+
+        mov         ecx,        source_width         ;
+        movq        mm5,        const53_1           ;
+
+        pxor        mm7,        mm7                 ;
+        movq        mm6,        const53_2           ;
+
+        movq        mm4,        round_values         ;
+        lea         edx,        [esi+ecx-5]         ;
+        horizontal_line_5_3_loop:
+
+        movq        mm0,        QWORD PTR  [esi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psllw       mm0,        8                   ;
+        xx 00 xx 02 xx 04 xx 06
+        psrlw       mm1,        8                   ;
+        01 xx 03 xx 05 xx 07 xx
+
+        psrlw       mm0,        8                   ;
+        00 xx 02 xx 04 xx 06 xx
+        psllq       mm1,        16                  ;
+        xx xx 01 xx 03 xx 05 xx
+
+        pmullw      mm0,        mm6
+
+        pmullw      mm1,        mm5
+        add         esi,        5
+
+        add         edi,        3
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        cmp         esi,        edx
+        packuswb    mm1,        mm7
+
+        movd        DWORD PTR [edi-3], mm1
+        jl          horizontal_line_5_3_loop
+
+//exit condition
+        movq        mm0,        QWORD PTR  [esi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psllw       mm0,        8                   ;
+        xx 00 xx 02 xx 04 xx 06
+        psrlw       mm1,        8                   ;
+        01 xx 03 xx 05 xx 07 xx
+
+        psrlw       mm0,        8                   ;
+        00 xx 02 xx 04 xx 06 xx
+        psllq       mm1,        16                  ;
+        xx xx 01 xx 03 xx 05 xx
+
+        pmullw      mm0,        mm6
+
+        pmullw      mm1,        mm5
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        packuswb    mm1,        mm7
+        movd        eax,        mm1
+
+        mov         edx,        eax
+        shr         edx,        16
+
+        mov         WORD PTR[edi],   ax
+        mov         BYTE PTR[edi+2], dl
+
+    }
+
+}
+
+__declspec(align(16)) const static unsigned short one_thirds[] = {  85,  85,  85,  85 };
+__declspec(align(16)) const static unsigned short two_thirds[] = { 171, 171, 171, 171 };
+
+static
+void vertical_band_5_3_scale_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+
+    __asm
+    {
+        push        ebx
+
+        mov         esi,    source                    // Get the source and destination pointer
+        mov         ecx,    src_pitch               // Get the pitch size
+
+        mov         edi,    dest                    // tow lines below
+        pxor        mm7,    mm7                     // clear out mm7
+
+        mov         edx,    dest_pitch               // Loop counter
+        movq        mm5,    one_thirds
+
+        movq        mm6,    two_thirds
+        mov         ebx,    dest_width;
+
+        vs_5_3_loop:
+
+        movd        mm0,    DWORD ptr [esi]         // src[0];
+        movd        mm1,    DWORD ptr [esi+ecx]     // src[1];
+
+        movd        mm2,    DWORD ptr [esi+ecx*2]
+        lea         eax,    [esi+ecx*2]             //
+
+        punpcklbw   mm1,    mm7
+        punpcklbw   mm2,    mm7
+
+        pmullw      mm1,    mm5
+        pmullw      mm2,    mm6
+
+        movd        mm3,    DWORD ptr [eax+ecx]
+        movd        mm4,    DWORD ptr [eax+ecx*2]
+
+        punpcklbw   mm3,    mm7
+        punpcklbw   mm4,    mm7
+
+        pmullw      mm3,    mm6
+        pmullw      mm4,    mm5
+
+
+        movd        DWORD PTR [edi], mm0
+        paddw       mm1,    mm2
+
+        paddw       mm1,    round_values
+        psrlw       mm1,    8
+
+        packuswb    mm1,    mm7
+        paddw       mm3,    mm4
+
+        paddw       mm3,    round_values
+        movd        DWORD PTR [edi+edx], mm1
+
+        psrlw       mm3,    8
+        packuswb    mm3,    mm7
+
+        movd        DWORD PTR [edi+edx*2], mm3
+
+
+        add         edi,    4
+        add         esi,    4
+
+        sub         ebx,    4
+        jg          vs_5_3_loop
+
+        pop         ebx
+    }
+}
+
+
+
+
+/****************************************************************************
+ *
+ *  ROUTINE       : horizontal_line_2_1_scale
+ *
+ *  INPUTS        : const unsigned char *source :
+ *                  unsigned int source_width    :
+ *                  unsigned char *dest         :
+ *                  unsigned int dest_width      :
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : 1 to 2 up-scaling of a horizontal line of pixels.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+static
+void horizontal_line_2_1_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+    (void) source_width;
+    __asm
+    {
+        mov         esi,    source
+        mov         edi,    dest
+
+        pxor        mm7,    mm7
+        mov         ecx,    dest_width
+
+        xor         edx,    edx
+        hs_2_1_loop:
+
+        movq        mm0,    [esi+edx*2]
+        psllw       mm0,    8
+
+        psrlw       mm0,    8
+        packuswb    mm0,    mm7
+
+        movd        DWORD Ptr [edi+edx], mm0;
+        add         edx,    4
+
+        cmp         edx,    ecx
+        jl          hs_2_1_loop
+
+    }
+}
+
+
+
+static
+void vertical_band_2_1_scale_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+    (void) dest_pitch;
+    (void) src_pitch;
+    vpx_memcpy(dest, source, dest_width);
+}
+
+
+__declspec(align(16)) const static unsigned short three_sixteenths[] = {  48,  48,  48,  48 };
+__declspec(align(16)) const static unsigned short ten_sixteenths[]   = { 160, 160, 160, 160 };
+
+static
+void vertical_band_2_1_scale_i_mmx(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width)
+{
+
+    (void) dest_pitch;
+    __asm
+    {
+        mov         esi,        source
+        mov         edi,        dest
+
+        mov         eax,        src_pitch
+        mov         edx,        dest_width
+
+        pxor        mm7,        mm7
+        sub         esi,        eax             //back one line
+
+
+        lea         ecx,        [esi+edx];
+        movq        mm6,        round_values;
+
+        movq        mm5,        three_sixteenths;
+        movq        mm4,        ten_sixteenths;
+
+        vs_2_1_i_loop:
+        movd        mm0,        [esi]           //
+        movd        mm1,        [esi+eax]       //
+
+        movd        mm2,        [esi+eax*2]     //
+        punpcklbw   mm0,        mm7
+
+        pmullw      mm0,        mm5
+        punpcklbw   mm1,        mm7
+
+        pmullw      mm1,        mm4
+        punpcklbw   mm2,        mm7
+
+        pmullw      mm2,        mm5
+        paddw       mm0,        round_values
+
+        paddw       mm1,        mm2
+        paddw       mm0,        mm1
+
+        psrlw       mm0,        8
+        packuswb    mm0,        mm7
+
+        movd        DWORD PTR [edi],        mm0
+        add         esi,        4
+
+        add         edi,        4;
+        cmp         esi,        ecx
+        jl          vs_2_1_i_loop
+
+    }
+}
+
+
+
+void
+register_mmxscalers(void)
+{
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_mmx;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_mmx;
+    vp8_last_vertical_band_1_2_scale      = last_vertical_band_1_2_scale_mmx;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_mmx;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_mmx;
+    vp8_last_vertical_band_3_5_scale      = last_vertical_band_3_5_scale_mmx;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_mmx;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_mmx;
+    vp8_last_vertical_band_4_5_scale      = last_vertical_band_4_5_scale_mmx;
+
+    vp8_horizontal_line_3_4_scale        = vp8cx_horizontal_line_3_4_scale_c;
+    vp8_vertical_band_3_4_scale          = vp8cx_vertical_band_3_4_scale_c;
+    vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+    vp8_horizontal_line_2_3_scale        = vp8cx_horizontal_line_2_3_scale_c;
+    vp8_vertical_band_2_3_scale          = vp8cx_vertical_band_2_3_scale_c;
+    vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+
+
+
+    vp8_vertical_band_5_4_scale           = vertical_band_5_4_scale_mmx;
+    vp8_vertical_band_5_3_scale           = vertical_band_5_3_scale_mmx;
+    vp8_vertical_band_2_1_scale           = vertical_band_2_1_scale_mmx;
+    vp8_vertical_band_2_1_scale_i         = vertical_band_2_1_scale_i_mmx;
+    vp8_horizontal_line_2_1_scale         = horizontal_line_2_1_scale_mmx;
+    vp8_horizontal_line_5_3_scale         = horizontal_line_5_3_scale_mmx;
+    vp8_horizontal_line_5_4_scale         = horizontal_line_5_4_scale_mmx;
+
+
+
+
+}
diff --git a/vpx_scale/win32/scalesystemdependant.c b/vpx_scale/win32/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..9ed48bf
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     system_dependant.c
+*
+*   Description  :     Miscellaneous system dependant functions
+*
+****************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/vpxscale.h"
+#include "cpuidlib.h"
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+extern void register_generic_scalers(void);
+extern void register_mmxscalers(void);
+
+/****************************************************************************
+ *
+ *  ROUTINE       : post_proc_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void
+vp8_scale_machine_specific_config(void)
+{
+    // If MMX supported then set to use MMX versions of functions else
+    // use original 'C' versions.
+    int mmx_enabled;
+    int xmm_enabled;
+    int wmt_enabled;
+
+    vpx_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled);
+
+    if (mmx_enabled || xmm_enabled || wmt_enabled)
+    {
+        register_mmxscalers();
+    }
+    else
+    {
+        vp8_horizontal_line_1_2_scale        = vp8cx_horizontal_line_1_2_scale_c;
+        vp8_vertical_band_1_2_scale          = vp8cx_vertical_band_1_2_scale_c;
+        vp8_last_vertical_band_1_2_scale      = vp8cx_last_vertical_band_1_2_scale_c;
+        vp8_horizontal_line_3_5_scale        = vp8cx_horizontal_line_3_5_scale_c;
+        vp8_vertical_band_3_5_scale          = vp8cx_vertical_band_3_5_scale_c;
+        vp8_last_vertical_band_3_5_scale      = vp8cx_last_vertical_band_3_5_scale_c;
+        vp8_horizontal_line_3_4_scale        = vp8cx_horizontal_line_3_4_scale_c;
+        vp8_vertical_band_3_4_scale          = vp8cx_vertical_band_3_4_scale_c;
+        vp8_last_vertical_band_3_4_scale      = vp8cx_last_vertical_band_3_4_scale_c;
+        vp8_horizontal_line_2_3_scale        = vp8cx_horizontal_line_2_3_scale_c;
+        vp8_vertical_band_2_3_scale          = vp8cx_vertical_band_2_3_scale_c;
+        vp8_last_vertical_band_2_3_scale      = vp8cx_last_vertical_band_2_3_scale_c;
+        vp8_horizontal_line_4_5_scale        = vp8cx_horizontal_line_4_5_scale_c;
+        vp8_vertical_band_4_5_scale          = vp8cx_vertical_band_4_5_scale_c;
+        vp8_last_vertical_band_4_5_scale      = vp8cx_last_vertical_band_4_5_scale_c;
+
+
+        vp8_vertical_band_5_4_scale           = vp8cx_vertical_band_5_4_scale_c;
+        vp8_vertical_band_5_3_scale           = vp8cx_vertical_band_5_3_scale_c;
+        vp8_vertical_band_2_1_scale           = vp8cx_vertical_band_2_1_scale_c;
+        vp8_vertical_band_2_1_scale_i         = vp8cx_vertical_band_2_1_scale_i_c;
+        vp8_horizontal_line_2_1_scale         = vp8cx_horizontal_line_2_1_scale_c;
+        vp8_horizontal_line_5_3_scale         = vp8cx_horizontal_line_5_3_scale_c;
+        vp8_horizontal_line_5_4_scale         = vp8cx_horizontal_line_5_4_scale_c;
+
+    }
+}
diff --git a/vpx_scale/x86_64/scaleopt.c b/vpx_scale/x86_64/scaleopt.c
new file mode 100644 (file)
index 0000000..3d2d5f2
--- /dev/null
@@ -0,0 +1,1749 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     scaleopt.cpp
+*
+*   Description  :     Optimized scaling functions
+*
+****************************************************************************/
+#include "pragmas.h"
+
+
+
+/****************************************************************************
+*  Module Statics
+****************************************************************************/
+__declspec(align(16)) const static unsigned short one_fifth[]  = { 51, 51, 51, 51 };
+__declspec(align(16)) const static unsigned short two_fifths[] = { 102, 102, 102, 102 };
+__declspec(align(16)) const static unsigned short three_fifths[] = { 154, 154, 154, 154 };
+__declspec(align(16)) const static unsigned short four_fifths[] = { 205, 205, 205, 205 };
+__declspec(align(16)) const static unsigned short round_values[] = { 128, 128, 128, 128 };
+__declspec(align(16)) const static unsigned short four_ones[] = { 1, 1, 1, 1};
+__declspec(align(16)) const static unsigned short const45_2[] = {205, 154, 102,  51 };
+__declspec(align(16)) const static unsigned short const45_1[] = { 51, 102, 154, 205 };
+__declspec(align(16)) const static unsigned char  mask45[] = { 0, 0, 0, 0, 0, 0, 255, 0};
+__declspec(align(16)) const static unsigned short const35_2[] = { 154,  51, 205, 102 };
+__declspec(align(16)) const static unsigned short const35_1[] = { 102, 205,  51, 154 };
+
+
+
+#include "vpx_scale/vpxscale.h"
+#include "vpx_mem/vpx_mem.h"
+
+/****************************************************************************
+*
+*  ROUTINE       : horizontal_line_3_5_scale_mmx
+*
+*  INPUTS        : const unsigned char *source :
+*                  unsigned int source_width    :
+*                  unsigned char *dest         :
+*                  unsigned int dest_width      :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 3 to 5 up-scaling of a horizontal line of pixels.
+*
+*  SPECIAL NOTES : None.
+*
+****************************************************************************/
+static
+void horizontal_line_3_5_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    __asm
+    {
+
+        push        rbx
+
+        mov         rsi,    source
+        mov         rdi,    dest
+
+        mov         ecx,    source_width
+        lea         rdx,    [rsi+rcx-3];
+
+        movq        mm5,    const35_1       // mm5 = 66 xx cd xx 33 xx 9a xx
+        movq        mm6,    const35_2       // mm6 = 9a xx 33 xx cd xx 66 xx
+
+        movq        mm4,    round_values     // mm4 = 80 xx 80 xx 80 xx 80 xx
+        pxor        mm7,    mm7             // clear mm7
+
+        horiz_line_3_5_loop:
+
+        mov         eax,    DWORD PTR [rsi] // eax = 00 01 02 03
+        mov         ebx,    eax
+
+        and         ebx,    0xffff00        // ebx = xx 01 02 xx
+        mov         ecx,    eax             // ecx = 00 01 02 03
+
+        and         eax,    0xffff0000      // eax = xx xx 02 03
+        xor         ecx,    eax             // ecx = 00 01 xx xx
+
+        shr         ebx,    8               // ebx = 01 02 xx xx
+        or          eax,    ebx             // eax = 01 02 02 03
+
+        shl         ebx,    16              // ebx = xx xx 01 02
+        movd        mm1,    eax             // mm1 = 01 02 02 03 xx xx xx xx
+
+        or          ebx,    ecx             // ebx = 00 01 01 02
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 02 xx 03 xx
+
+        movd        mm0,    ebx             // mm0 = 00 01 01 02
+        pmullw      mm1,    mm6             //
+
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 01 xx 02 xx
+        pmullw      mm0,    mm5             //
+
+        mov         [rdi],  ebx             // writeoutput 00 xx xx xx
+        add         rsi,    3
+
+        add         rdi,    5
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm4
+        psrlw       mm0,    8
+
+        cmp         rsi,    rdx
+        packuswb    mm0,    mm7
+
+        movd        DWORD Ptr [rdi-4], mm0
+        jl          horiz_line_3_5_loop
+
+//Exit:
+        mov         eax,    DWORD PTR [rsi] // eax = 00 01 02 03
+        mov         ebx,    eax
+
+        and         ebx,    0xffff00        // ebx = xx 01 02 xx
+        mov         ecx,    eax             // ecx = 00 01 02 03
+
+        and         eax,    0xffff0000      // eax = xx xx 02 03
+        xor         ecx,    eax             // ecx = 00 01 xx xx
+
+        shr         ebx,    8               // ebx = 01 02 xx xx
+        or          eax,    ebx             // eax = 01 02 02 03
+
+        shl         eax,    8               // eax = xx 01 02 02
+        and         eax,    0xffff0000      // eax = xx xx 02 02
+
+        or          eax,    ebx             // eax = 01 02 02 02
+
+        shl         ebx,    16              // ebx = xx xx 01 02
+        movd        mm1,    eax             // mm1 = 01 02 02 02 xx xx xx xx
+
+        or          ebx,    ecx             // ebx = 00 01 01 02
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 02 xx 02 xx
+
+        movd        mm0,    ebx             // mm0 = 00 01 01 02
+        pmullw      mm1,    mm6             //
+
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 01 xx 02 xx
+        pmullw      mm0,    mm5             //
+
+        mov         [rdi],  ebx             // writeoutput 00 xx xx xx
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm4
+        psrlw       mm0,    8
+
+        packuswb    mm0,    mm7
+        movd        DWORD Ptr [rdi+1], mm0
+
+        pop rbx
+
+    }
+
+}
+
+
+/****************************************************************************
+*
+*  ROUTINE       : horizontal_line_4_5_scale_mmx
+*
+*  INPUTS        : const unsigned char *source :
+*                  unsigned int source_width    :
+*                  unsigned char *dest         :
+*                  unsigned int dest_width      :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 4 to 5 up-scaling of a horizontal line of pixels.
+*
+*  SPECIAL NOTES : None.
+*
+****************************************************************************/
+static
+void horizontal_line_4_5_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void)dest_width;
+
+    __asm
+    {
+
+        mov         rsi,    source
+        mov         rdi,    dest
+
+        mov         ecx,    source_width
+        lea         rdx,    [rsi+rcx-8];
+
+        movq        mm5,    const45_1       // mm5 = 33 xx 66 xx 9a xx cd xx
+        movq        mm6,    const45_2       // mm6 = cd xx 9a xx 66 xx 33 xx
+
+        movq        mm4,    round_values     // mm4 = 80 xx 80 xx 80 xx 80 xx
+        pxor        mm7,    mm7             // clear mm7
+
+        horiz_line_4_5_loop:
+
+        movq        mm0,    QWORD PTR [rsi]           // mm0 = 00 01 02 03 04 05 06 07
+        movq        mm1,    QWORD PTR [rsi+1];        // mm1 = 01 02 03 04 05 06 07 08
+
+        movq        mm2,    mm0             // mm2 = 00 01 02 03 04 05 06 07
+        movq        mm3,    mm1             // mm3 = 01 02 03 04 05 06 07 08
+
+        movd        DWORD PTR [rdi],  mm0             // write output 00 xx xx xx
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 02 xx 03 xx
+
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 03 xx 04 xx
+        pmullw      mm0,    mm5             // 00* 51 01*102 02*154 03*205
+
+        pmullw      mm1,    mm6             // 01*205 02*154 03*102 04* 51
+        punpckhbw   mm2,    mm7             // mm2 = 04 xx 05 xx 06 xx 07 xx
+
+        movd        DWORD PTR [rdi+5], mm2            // write ouput 05 xx xx xx
+        pmullw      mm2,    mm5             // 04* 51 05*102 06*154 07*205
+
+        punpckhbw   mm3,    mm7             // mm3 = 05 xx 06 xx 07 xx 08 xx
+        pmullw      mm3,    mm6             // 05*205 06*154 07*102 08* 51
+
+        paddw       mm0,    mm1             // added round values
+        paddw       mm0,    mm4
+
+        psrlw       mm0,    8               // output: 01 xx 02 xx 03 xx 04 xx
+        packuswb    mm0,    mm7
+
+        movd        DWORD PTR [rdi+1], mm0  // write output 01 02 03 04
+        add         rdi,    10
+
+        add         rsi,    8
+        paddw       mm2,    mm3             //
+
+        paddw       mm2,    mm4             // added round values
+        cmp         rsi,    rdx
+
+        psrlw       mm2,    8
+        packuswb    mm2,    mm7
+
+        movd        DWORD PTR [rdi-4], mm2 // writeoutput 06 07 08 09
+        jl         horiz_line_4_5_loop
+
+//Exit:
+        movq        mm0,    [rsi]           // mm0 = 00 01 02 03 04 05 06 07
+        movq        mm1,    mm0             // mm1 = 00 01 02 03 04 05 06 07
+
+        movq        mm2,    mm0             // mm2 = 00 01 02 03 04 05 06 07
+        psrlq       mm1,    8               // mm1 = 01 02 03 04 05 06 07 00
+
+        movq        mm3,    mask45          // mm3 = 00 00 00 00 00 00 ff 00
+        pand        mm3,    mm1             // mm3 = 00 00 00 00 00 00 07 00
+
+        psllq       mm3,    8               // mm3 = 00 00 00 00 00 00 00 07
+        por         mm1,    mm3             // mm1 = 01 02 03 04 05 06 07 07
+
+        movq        mm3,    mm1
+
+        movd        DWORD PTR [rdi],  mm0   // write output 00 xx xx xx
+        punpcklbw   mm0,    mm7             // mm0 = 00 xx 01 xx 02 xx 03 xx
+
+        punpcklbw   mm1,    mm7             // mm1 = 01 xx 02 xx 03 xx 04 xx
+        pmullw      mm0,    mm5             // 00* 51 01*102 02*154 03*205
+
+        pmullw      mm1,    mm6             // 01*205 02*154 03*102 04* 51
+        punpckhbw   mm2,    mm7             // mm2 = 04 xx 05 xx 06 xx 07 xx
+
+        movd        DWORD PTR [rdi+5], mm2  // write ouput 05 xx xx xx
+        pmullw      mm2,    mm5             // 04* 51 05*102 06*154 07*205
+
+        punpckhbw   mm3,    mm7             // mm3 = 05 xx 06 xx 07 xx 08 xx
+        pmullw      mm3,    mm6             // 05*205 06*154 07*102 07* 51
+
+        paddw       mm0,    mm1             // added round values
+        paddw       mm0,    mm4
+
+        psrlw       mm0,    8               // output: 01 xx 02 xx 03 xx 04 xx
+        packuswb    mm0,    mm7             // 01 02 03 04 xx xx xx xx
+
+        movd        DWORD PTR [rdi+1], mm0  // write output 01 02 03 04
+        paddw       mm2,    mm3             //
+
+        paddw       mm2,    mm4             // added round values
+        psrlw       mm2,    8
+
+        packuswb    mm2,    mm7
+        movd        DWORD PTR [rdi+6], mm2  // writeoutput 06 07 08 09
+
+
+    }
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : vertical_band_4_5_scale_mmx
+*
+*  INPUTS        : unsigned char *dest    :
+*                  unsigned int dest_pitch :
+*                  unsigned int dest_width :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 4 to 5 up-scaling of a 4 pixel high band of pixels.
+*
+*  SPECIAL NOTES : The routine uses the first line of the band below
+*                  the current band. The function also has a "C" only
+*                  version.
+*
+****************************************************************************/
+static
+void vertical_band_4_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+
+        mov         rsi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         rdi,    [rsi+rcx*2]             // tow lines below
+        add         rdi,    rcx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_4_5_loop:
+
+        movq        mm0,    QWORD ptr [rsi]         // src[0];
+        movq        mm1,    QWORD ptr [rsi+rcx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    one_fifth
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 1/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 1/5
+        movq        mm6,    four_fifths               // constan
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 4/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 4/5
+        paddw       mm0,    mm4                     // a * 1/5 + b * 4/5
+
+        paddw       mm2,    mm5                     // a * 1/5 + b * 4/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [rsi+rcx], mm0        // write des[1]
+        movq        mm0,    [rsi+rcx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm5,    two_fifths
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm1,    mm5                     // b * 2/5
+        movq        mm6,    three_fifths
+
+
+        punpcklbw   mm0,    mm7                     // unpack low to word
+        pmullw      mm3,    mm5                     // b * 2/5
+
+        movq        mm4,    mm0                     // make copy of c
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm4,    mm6                     // c * 3/5
+        movq        mm5,    mm2
+
+        pmullw      mm5,    mm6                     // c * 3/5
+        paddw       mm1,    mm4                     // b * 2/5 + c * 3/5
+
+        paddw       mm3,    mm5                     // b * 2/5 + c * 3/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[2]
+
+        movq        QWORD ptr [rsi+rcx*2], mm1      // write des[2]
+        movq        mm1,    [rdi]                   // mm1=Src[3];
+
+        // mm0, mm2 --- Src[2]
+        // mm1 --- Src[3]
+        // mm6 --- 3/5
+        // mm7 for unpacking
+
+        pmullw      mm0,    mm6                     // c * 3/5
+        movq        mm5,    two_fifths               // mm5 = 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        pmullw      mm2,    mm6                     // c * 3/5
+
+        punpcklbw   mm1,    mm7                     // unpack low
+        movq        mm4,    mm1                     // make a copy
+
+        punpckhbw   mm3,    mm7                     // unpack high
+        pmullw      mm4,    mm5                     // d * 2/5
+
+        movq        mm6,    mm3                     // make a copy
+        pmullw      mm6,    mm5                     // d * 2/5
+
+        paddw       mm0,    mm4                     // c * 3/5 + d * 2/5
+        paddw       mm2,    mm6                     // c * 3/5 + d * 2/5
+
+        paddw       mm0,    round_values             // + 128
+        paddw       mm2,    round_values             // + 128
+
+        psrlw       mm0,    8
+        psrlw       mm2,    8
+
+        packuswb    mm0,    mm2                     // des[3]
+        movq        QWORD ptr [rdi], mm0            // write des[3]
+
+        //  mm1, mm3 --- Src[3]
+        //  mm7 -- cleared for unpacking
+
+        movq        mm0,    [rdi+rcx*2]             // mm0, Src[0] of the next group
+
+        movq        mm5,    four_fifths              // mm5 = 4/5
+        pmullw      mm1,    mm5                     // d * 4/5
+
+        movq        mm6,    one_fifth                // mm6 = 1/5
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm3,    mm5                     // d * 4/5
+        punpcklbw   mm0,    mm7                     // unpack low
+
+        pmullw      mm0,    mm6                     // an * 1/5
+        punpckhbw   mm2,    mm7                     // unpack high
+
+        paddw       mm1,    mm0                     // d * 4/5 + an * 1/5
+        pmullw      mm2,    mm6                     // an * 1/5
+
+        paddw       mm3,    mm2                     // d * 4/5 + an * 1/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[4]
+
+        movq        QWORD ptr [rdi+rcx], mm1        // write des[4]
+
+        add         rdi,    8
+        add         rsi,    8
+
+        sub         rdx,    8
+        jg          vs_4_5_loop
+    }
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : last_vertical_band_4_5_scale_mmx
+*
+*  INPUTS        : unsigned char *dest    :
+*                  unsigned int dest_pitch :
+*                  unsigned int dest_width :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : None
+*
+*  FUNCTION      : 4 to 5 up-scaling of the last 4-pixel high band in an image.
+*
+*  SPECIAL NOTES : The routine uses the first line of the band below
+*                  the current band. The function also has an "C" only
+*                  version.
+*
+****************************************************************************/
+static
+void last_vertical_band_4_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         rsi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         rdi,    [rsi+rcx*2]             // tow lines below
+        add         rdi,    rcx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        last_vs_4_5_loop:
+
+        movq        mm0,    QWORD ptr [rsi]         // src[0];
+        movq        mm1,    QWORD ptr [rsi+rcx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    one_fifth
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 1/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 1/5
+        movq        mm6,    four_fifths               // constan
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 4/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 4/5
+        paddw       mm0,    mm4                     // a * 1/5 + b * 4/5
+
+        paddw       mm2,    mm5                     // a * 1/5 + b * 4/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [rsi+rcx], mm0        // write des[1]
+        movq        mm0,    [rsi+rcx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm5,    two_fifths
+        movq        mm2,    mm0                     // make a copy
+
+        pmullw      mm1,    mm5                     // b * 2/5
+        movq        mm6,    three_fifths
+
+
+        punpcklbw   mm0,    mm7                     // unpack low to word
+        pmullw      mm3,    mm5                     // b * 2/5
+
+        movq        mm4,    mm0                     // make copy of c
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm4,    mm6                     // c * 3/5
+        movq        mm5,    mm2
+
+        pmullw      mm5,    mm6                     // c * 3/5
+        paddw       mm1,    mm4                     // b * 2/5 + c * 3/5
+
+        paddw       mm3,    mm5                     // b * 2/5 + c * 3/5
+        paddw       mm1,    round_values             // + 128
+
+        paddw       mm3,    round_values             // + 128
+        psrlw       mm1,    8
+
+        psrlw       mm3,    8
+        packuswb    mm1,    mm3                     // des[2]
+
+        movq        QWORD ptr [rsi+rcx*2], mm1      // write des[2]
+        movq        mm1,    [rdi]                   // mm1=Src[3];
+
+        movq        QWORD ptr [rdi+rcx], mm1        // write des[4];
+
+        // mm0, mm2 --- Src[2]
+        // mm1 --- Src[3]
+        // mm6 --- 3/5
+        // mm7 for unpacking
+
+        pmullw      mm0,    mm6                     // c * 3/5
+        movq        mm5,    two_fifths               // mm5 = 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        pmullw      mm2,    mm6                     // c * 3/5
+
+        punpcklbw   mm1,    mm7                     // unpack low
+        movq        mm4,    mm1                     // make a copy
+
+        punpckhbw   mm3,    mm7                     // unpack high
+        pmullw      mm4,    mm5                     // d * 2/5
+
+        movq        mm6,    mm3                     // make a copy
+        pmullw      mm6,    mm5                     // d * 2/5
+
+        paddw       mm0,    mm4                     // c * 3/5 + d * 2/5
+        paddw       mm2,    mm6                     // c * 3/5 + d * 2/5
+
+        paddw       mm0,    round_values             // + 128
+        paddw       mm2,    round_values             // + 128
+
+        psrlw       mm0,    8
+        psrlw       mm2,    8
+
+        packuswb    mm0,    mm2                     // des[3]
+        movq        QWORD ptr [rdi], mm0            // write des[3]
+
+        //  mm1, mm3 --- Src[3]
+        //  mm7 -- cleared for unpacking
+        add         rdi,    8
+        add         rsi,    8
+
+        sub         rdx,    8
+        jg          last_vs_4_5_loop
+    }
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : vertical_band_3_5_scale_mmx
+*
+*  INPUTS        : unsigned char *dest    :
+*                  unsigned int dest_pitch :
+*                  unsigned int dest_width :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 3 to 5 up-scaling of a 3-pixel high band of pixels.
+*
+*  SPECIAL NOTES : The routine uses the first line of the band below
+*                  the current band. The function also has an "C" only
+*                  version.
+*
+****************************************************************************/
+static
+void vertical_band_3_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         rsi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         rdi,    [rsi+rcx*2]             // two lines below
+        add         rdi,    rcx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_3_5_loop:
+
+        movq        mm0,    QWORD ptr [rsi]         // src[0];
+        movq        mm1,    QWORD ptr [rsi+rcx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    two_fifths               // mm5 = 2/5
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 2/5
+        movq        mm6,    three_fifths             // mm6 = 3/5
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 3/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 3/5
+        paddw       mm0,    mm4                     // a * 2/5 + b * 3/5
+
+        paddw       mm2,    mm5                     // a * 2/5 + b * 3/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [rsi+rcx], mm0        // write des[1]
+        movq        mm0,    [rsi+rcx*2]             // mm0 = src[2]
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm4,    mm1                     // b low
+        pmullw      mm1,    four_fifths              // b * 4/5 low
+
+        movq        mm5,    mm3                     // b high
+        pmullw      mm3,    four_fifths              // b * 4/5 high
+
+        movq        mm2,    mm0                     // c
+        pmullw      mm4,    one_fifth                // b * 1/5
+
+        punpcklbw   mm0,    mm7                     // c low
+        pmullw      mm5,    one_fifth                // b * 1/5
+
+        movq        mm6,    mm0                     // make copy of c low
+        punpckhbw   mm2,    mm7                     // c high
+
+        pmullw      mm6,    one_fifth                // c * 1/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    one_fifth                // c * 1/5 high
+        paddw       mm1,    mm6                     // b * 4/5 + c * 1/5 low
+
+        paddw       mm3,    mm7                     // b * 4/5 + c * 1/5 high
+        movq        mm6,    mm0                     // make copy of c low
+
+        pmullw      mm6,    four_fifths              // c * 4/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    four_fifths              // c * 4/5 high
+
+        paddw       mm4,    mm6                     // b * 1/5 + c * 4/5 low
+        paddw       mm5,    mm7                     // b * 1/5 + c * 4/5 high
+
+        paddw       mm1,    round_values             // + 128
+        paddw       mm3,    round_values             // + 128
+
+        psrlw       mm1,    8
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm3                     // des[2]
+        movq        QWORD ptr [rsi+rcx*2], mm1      // write des[2]
+
+        paddw       mm4,    round_values             // + 128
+        paddw       mm5,    round_values             // + 128
+
+        psrlw       mm4,    8
+        psrlw       mm5,    8
+
+        packuswb    mm4,    mm5                     // des[3]
+        movq        QWORD ptr [rdi], mm4            // write des[3]
+
+        //  mm0, mm2 --- Src[3]
+
+        pxor        mm7,    mm7                     // clear mm7 for unpacking
+        movq        mm1,    [rdi+rcx*2]             // mm1 = Src[0] of the next group
+
+        movq        mm5,    three_fifths             // mm5 = 3/5
+        pmullw      mm0,    mm5                     // d * 3/5
+
+        movq        mm6,    two_fifths                // mm6 = 2/5
+        movq        mm3,    mm1                     // make a copy
+
+        pmullw      mm2,    mm5                     // d * 3/5
+        punpcklbw   mm1,    mm7                     // unpack low
+
+        pmullw      mm1,    mm6                     // an * 2/5
+        punpckhbw   mm3,    mm7                     // unpack high
+
+        paddw       mm0,    mm1                     // d * 3/5 + an * 2/5
+        pmullw      mm3,    mm6                     // an * 2/5
+
+        paddw       mm2,    mm3                     // d * 3/5 + an * 2/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des[4]
+
+        movq        QWORD ptr [rdi+rcx], mm0        // write des[4]
+
+        add         rdi,    8
+        add         rsi,    8
+
+        sub         rdx,    8
+        jg          vs_3_5_loop
+    }
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : last_vertical_band_3_5_scale_mmx
+*
+*  INPUTS        : unsigned char *dest    :
+*                  unsigned int dest_pitch :
+*                  unsigned int dest_width :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 3 to 5 up-scaling of a 3-pixel high band of pixels.
+*
+*  SPECIAL NOTES : The routine uses the first line of the band below
+*                  the current band. The function also has an "C" only
+*                  version.
+*
+****************************************************************************/
+static
+void last_vertical_band_3_5_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         rsi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        lea         rdi,    [rsi+rcx*2]             // tow lines below
+        add         rdi,    rcx                     // three lines below
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+
+        last_vs_3_5_loop:
+
+        movq        mm0,    QWORD ptr [rsi]         // src[0];
+        movq        mm1,    QWORD ptr [rsi+rcx]     // src[1];
+
+        movq        mm2,    mm0                     // Make a copy
+        punpcklbw   mm0,    mm7                     // unpack low to word
+
+        movq        mm5,    two_fifths               // mm5 = 2/5
+        punpckhbw   mm2,    mm7                     // unpack high to word
+
+        pmullw      mm0,    mm5                     // a * 2/5
+
+        movq        mm3,    mm1                     // make a copy
+        punpcklbw   mm1,    mm7                     // unpack low to word
+
+        pmullw      mm2,    mm5                     // a * 2/5
+        movq        mm6,    three_fifths             // mm6 = 3/5
+
+        movq        mm4,    mm1                     // copy of low b
+        pmullw      mm4,    mm6                     // b * 3/5
+
+        punpckhbw   mm3,    mm7                     // unpack high to word
+        movq        mm5,    mm3                     // copy of high b
+
+        pmullw      mm5,    mm6                     // b * 3/5
+        paddw       mm0,    mm4                     // a * 2/5 + b * 3/5
+
+        paddw       mm2,    mm5                     // a * 2/5 + b * 3/5
+        paddw       mm0,    round_values             // + 128
+
+        paddw       mm2,    round_values             // + 128
+        psrlw       mm0,    8
+
+        psrlw       mm2,    8
+        packuswb    mm0,    mm2                     // des [1]
+
+        movq        QWORD ptr [rsi+rcx], mm0        // write des[1]
+        movq        mm0,    [rsi+rcx*2]             // mm0 = src[2]
+
+
+
+        // mm1, mm3 --- Src[1]
+        // mm0 --- Src[2]
+        // mm7 for unpacking
+
+        movq        mm4,    mm1                     // b low
+        pmullw      mm1,    four_fifths              // b * 4/5 low
+
+        movq        QWORD ptr [rdi+rcx], mm0        // write des[4]
+
+        movq        mm5,    mm3                     // b high
+        pmullw      mm3,    four_fifths              // b * 4/5 high
+
+        movq        mm2,    mm0                     // c
+        pmullw      mm4,    one_fifth                // b * 1/5
+
+        punpcklbw   mm0,    mm7                     // c low
+        pmullw      mm5,    one_fifth                // b * 1/5
+
+        movq        mm6,    mm0                     // make copy of c low
+        punpckhbw   mm2,    mm7                     // c high
+
+        pmullw      mm6,    one_fifth                // c * 1/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    one_fifth                // c * 1/5 high
+        paddw       mm1,    mm6                     // b * 4/5 + c * 1/5 low
+
+        paddw       mm3,    mm7                     // b * 4/5 + c * 1/5 high
+        movq        mm6,    mm0                     // make copy of c low
+
+        pmullw      mm6,    four_fifths              // c * 4/5 low
+        movq        mm7,    mm2                     // make copy of c high
+
+        pmullw      mm7,    four_fifths              // c * 4/5 high
+
+        paddw       mm4,    mm6                     // b * 1/5 + c * 4/5 low
+        paddw       mm5,    mm7                     // b * 1/5 + c * 4/5 high
+
+        paddw       mm1,    round_values             // + 128
+        paddw       mm3,    round_values             // + 128
+
+        psrlw       mm1,    8
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm3                     // des[2]
+        movq        QWORD ptr [rsi+rcx*2], mm1      // write des[2]
+
+        paddw       mm4,    round_values             // + 128
+        paddw       mm5,    round_values             // + 128
+
+        psrlw       mm4,    8
+        psrlw       mm5,    8
+
+        packuswb    mm4,    mm5                     // des[3]
+        movq        QWORD ptr [rdi], mm4            // write des[3]
+
+        //  mm0, mm2 --- Src[3]
+
+        add         rdi,    8
+        add         rsi,    8
+
+        sub         rdx,    8
+        jg          last_vs_3_5_loop
+    }
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : vertical_band_1_2_scale_mmx
+*
+*  INPUTS        : unsigned char *dest    :
+*                  unsigned int dest_pitch :
+*                  unsigned int dest_width :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 1 to 2 up-scaling of a band of pixels.
+*
+*  SPECIAL NOTES : The routine uses the first line of the band below
+*                  the current band. The function also has an "C" only
+*                  version.
+*
+****************************************************************************/
+static
+void vertical_band_1_2_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+
+        mov         rsi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        pxor        mm7,    mm7                     // clear out mm7
+        mov         edx,    dest_width               // Loop counter
+
+        vs_1_2_loop:
+
+        movq        mm0,    [rsi]                   // get Src[0]
+        movq        mm1,    [rsi + rcx * 2]         // get Src[1]
+
+        movq        mm2,    mm0                     // make copy before unpack
+        movq        mm3,    mm1                     // make copy before unpack
+
+        punpcklbw   mm0,    mm7                     // low Src[0]
+        movq        mm6,    four_ones                // mm6= 1, 1, 1, 1
+
+        punpcklbw   mm1,    mm7                     // low Src[1]
+        paddw       mm0,    mm1                     // low (a + b)
+
+        punpckhbw   mm2,    mm7                     // high Src[0]
+        paddw       mm0,    mm6                     // low (a + b + 1)
+
+        punpckhbw   mm3,    mm7
+        paddw       mm2,    mm3                     // high (a + b )
+
+        psraw       mm0,    1                       // low (a + b +1 )/2
+        paddw       mm2,    mm6                     // high (a + b + 1)
+
+        psraw       mm2,    1                       // high (a + b + 1)/2
+        packuswb    mm0,    mm2                     // pack results
+
+        movq        [rsi+rcx], mm0                  // write out eight bytes
+        add         rsi,    8
+
+        sub         rdx,    8
+        jg          vs_1_2_loop
+    }
+
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : last_vertical_band_1_2_scale_mmx
+*
+*  INPUTS        : unsigned char *dest    :
+*                  unsigned int dest_pitch :
+*                  unsigned int dest_width :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 1 to 2 up-scaling of band of pixels.
+*
+*  SPECIAL NOTES : The routine uses the first line of the band below
+*                  the current band. The function also has an "C" only
+*                  version.
+*
+****************************************************************************/
+static
+void last_vertical_band_1_2_scale_mmx
+(
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         rsi,    dest                    // Get the source and destination pointer
+        mov         ecx,    dest_pitch               // Get the pitch size
+
+        mov         edx,    dest_width               // Loop counter
+
+        last_vs_1_2_loop:
+
+        movq        mm0,    [rsi]                   // get Src[0]
+        movq        [rsi+rcx], mm0                  // write out eight bytes
+
+        add         rsi,    8
+        sub         rdx,    8
+
+        jg          last_vs_1_2_loop
+    }
+}
+
+/****************************************************************************
+*
+*  ROUTINE       : horizontal_line_1_2_scale
+*
+*  INPUTS        : const unsigned char *source :
+*                  unsigned int source_width    :
+*                  unsigned char *dest         :
+*                  unsigned int dest_width      :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 1 to 2 up-scaling of a horizontal line of pixels.
+*
+*  SPECIAL NOTES : None.
+*
+****************************************************************************/
+static
+void horizontal_line_1_2_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    __asm
+    {
+        mov         rsi,    source
+        mov         rdi,    dest
+
+        pxor        mm7,    mm7
+        movq        mm6,    four_ones
+
+        mov         ecx,    source_width
+
+        hs_1_2_loop:
+
+        movq        mm0,    [rsi]
+        movq        mm1,    [rsi+1]
+
+        movq        mm2,    mm0
+        movq        mm3,    mm1
+
+        movq        mm4,    mm0
+        punpcklbw   mm0,    mm7
+
+        punpcklbw   mm1,    mm7
+        paddw       mm0,    mm1
+
+        paddw       mm0,    mm6
+        punpckhbw   mm2,    mm7
+
+        punpckhbw   mm3,    mm7
+        paddw       mm2,    mm3
+
+        paddw       mm2,    mm6
+        psraw       mm0,    1
+
+        psraw       mm2,    1
+        packuswb    mm0,    mm2
+
+        movq        mm2,    mm4
+        punpcklbw   mm2,    mm0
+
+        movq        [rdi],  mm2
+        punpckhbw   mm4,    mm0
+
+        movq        [rdi+8], mm4
+        add         rsi,    8
+
+        add         rdi,    16
+        sub         rcx,    8
+
+        cmp         rcx,    8
+        jg          hs_1_2_loop
+
+// last eight pixel
+
+        movq        mm0,    [rsi]
+        movq        mm1,    mm0
+
+        movq        mm2,    mm0
+        movq        mm3,    mm1
+
+        psrlq       mm1,    8
+        psrlq       mm3,    56
+
+        psllq       mm3,    56
+        por         mm1,    mm3
+
+        movq        mm3,    mm1
+        movq        mm4,    mm0
+
+        punpcklbw   mm0,    mm7
+        punpcklbw   mm1,    mm7
+
+        paddw       mm0,    mm1
+        paddw       mm0,    mm6
+
+        punpckhbw   mm2,    mm7
+        punpckhbw   mm3,    mm7
+
+        paddw       mm2,    mm3
+        paddw       mm2,    mm6
+
+        psraw       mm0,    1
+        psraw       mm2,    1
+
+        packuswb    mm0,    mm2
+        movq        mm2,    mm4
+
+        punpcklbw   mm2,    mm0
+        movq        [rdi],  mm2
+
+        punpckhbw   mm4,    mm0
+        movq        [rdi+8], mm4
+    }
+}
+
+
+
+
+
+__declspec(align(16)) const static unsigned short const54_2[] = {  0,  64, 128, 192 };
+__declspec(align(16)) const static unsigned short const54_1[] = {256, 192, 128,  64 };
+
+
+/****************************************************************************
+*
+*  ROUTINE       : horizontal_line_5_4_scale_mmx
+*
+*  INPUTS        : const unsigned char *source : Pointer to source data.
+*                  unsigned int source_width    : Stride of source.
+*                  unsigned char *dest         : Pointer to destination data.
+*                  unsigned int dest_width      : Stride of destination (NOT USED).
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : Copies horizontal line of pixels from source to
+*                  destination scaling up by 4 to 5.
+*
+*  SPECIAL NOTES : None.
+*
+****************************************************************************/
+static
+void horizontal_line_5_4_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    /*
+    unsigned i;
+    unsigned int a, b, c, d, e;
+    unsigned char *des = dest;
+    const unsigned char *src = source;
+
+    (void) dest_width;
+
+    for ( i=0; i<source_width; i+=5 )
+    {
+        a = src[0];
+        b = src[1];
+        c = src[2];
+        d = src[3];
+        e = src[4];
+
+        des[0] = a;
+        des[1] = ((b*192 + c* 64 + 128)>>8);
+        des[2] = ((c*128 + d*128 + 128)>>8);
+        des[3] = ((d* 64 + e*192 + 128)>>8);
+
+        src += 5;
+        des += 4;
+    }
+    */
+    __asm
+    {
+
+        mov         rsi,        source              ;
+        mov         rdi,        dest                ;
+
+        mov         ecx,        source_width         ;
+        movq        mm5,        const54_1           ;
+
+        pxor        mm7,        mm7                 ;
+        movq        mm6,        const54_2           ;
+
+        movq        mm4,        round_values         ;
+        lea         rdx,        [rsi+rcx]           ;
+        horizontal_line_5_4_loop:
+
+        movq        mm0,        QWORD PTR  [rsi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psrlq       mm0,        8                   ;
+        01 02 03 04 05 06 07 xx
+        punpcklbw   mm1,        mm7                 ;
+        xx 00 xx 01 xx 02 xx 03
+
+        punpcklbw   mm0,        mm7                 ;
+        xx 01 xx 02 xx 03 xx 04
+        pmullw      mm1,        mm5
+
+        pmullw      mm0,        mm6
+        add         rsi,        5
+
+        add         rdi,        4
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        cmp         rsi,        rdx
+        packuswb    mm1,        mm7
+
+        movd        DWORD PTR [rdi-4], mm1
+
+        jl          horizontal_line_5_4_loop
+
+    }
+
+}
+__declspec(align(16)) const static unsigned short one_fourths[]   = {  64,  64,  64, 64  };
+__declspec(align(16)) const static unsigned short two_fourths[]   = { 128, 128, 128, 128 };
+__declspec(align(16)) const static unsigned short three_fourths[] = { 192, 192, 192, 192 };
+
+static
+void vertical_band_5_4_scale_mmx
+(
+    unsigned char *source,
+    unsigned int src_pitch,
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+
+    __asm
+    {
+
+        mov         rsi,    source                    // Get the source and destination pointer
+        mov         ecx,    src_pitch               // Get the pitch size
+
+        mov         rdi,    dest                    // tow lines below
+        pxor        mm7,    mm7                     // clear out mm7
+
+        mov         edx,    dest_pitch               // Loop counter
+        mov         ebx,    dest_width
+
+        vs_5_4_loop:
+
+        movd        mm0,    DWORD ptr [rsi]         // src[0];
+        movd        mm1,    DWORD ptr [rsi+rcx]     // src[1];
+
+        movd        mm2,    DWORD ptr [rsi+rcx*2]
+        lea         rax,    [rsi+rcx*2]             //
+
+        punpcklbw   mm1,    mm7
+        punpcklbw   mm2,    mm7
+
+        movq        mm3,    mm2
+        pmullw      mm1,    three_fourths
+
+        pmullw      mm2,    one_fourths
+        movd        mm4,    [rax+rcx]
+
+        pmullw      mm3,    two_fourths
+        punpcklbw   mm4,    mm7
+
+        movq        mm5,    mm4
+        pmullw      mm4,    two_fourths
+
+        paddw       mm1,    mm2
+        movd        mm6,    [rax+rcx*2]
+
+        pmullw      mm5,    one_fourths
+        paddw       mm1,    round_values;
+
+        paddw       mm3,    mm4
+        psrlw       mm1,    8
+
+        punpcklbw   mm6,    mm7
+        paddw       mm3,    round_values
+
+        pmullw      mm6,    three_fourths
+        psrlw       mm3,    8
+
+        packuswb    mm1,    mm7
+        packuswb    mm3,    mm7
+
+        movd        DWORD PTR [rdi], mm0
+        movd        DWORD PTR [rdi+rdx], mm1
+
+
+        paddw       mm5,    mm6
+        movd        DWORD PTR [rdi+rdx*2], mm3
+
+        lea         rax,    [rdi+rdx*2]
+        paddw       mm5,    round_values
+
+        psrlw       mm5,    8
+        add         rdi,    4
+
+        packuswb    mm5,    mm7
+        movd        DWORD PTR [rax+rdx], mm5
+
+        add         rsi,    4
+        sub         rbx,    4
+
+        jg         vs_5_4_loop
+    }
+}
+
+
+__declspec(align(16)) const static unsigned short const53_1[] = {  0,  85, 171, 0 };
+__declspec(align(16)) const static unsigned short const53_2[] = {256, 171,  85, 0 };
+
+
+static
+void horizontal_line_5_3_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+
+        mov         rsi,        source              ;
+        mov         rdi,        dest                ;
+
+        mov         ecx,        source_width         ;
+        movq        mm5,        const53_1           ;
+
+        pxor        mm7,        mm7                 ;
+        movq        mm6,        const53_2           ;
+
+        movq        mm4,        round_values         ;
+        lea         rdx,        [rsi+rcx-5]         ;
+        horizontal_line_5_3_loop:
+
+        movq        mm0,        QWORD PTR  [rsi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psllw       mm0,        8                   ;
+        xx 00 xx 02 xx 04 xx 06
+        psrlw       mm1,        8                   ;
+        01 xx 03 xx 05 xx 07 xx
+
+        psrlw       mm0,        8                   ;
+        00 xx 02 xx 04 xx 06 xx
+        psllq       mm1,        16                  ;
+        xx xx 01 xx 03 xx 05 xx
+
+        pmullw      mm0,        mm6
+
+        pmullw      mm1,        mm5
+        add         rsi,        5
+
+        add         rdi,        3
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        cmp         rsi,        rdx
+        packuswb    mm1,        mm7
+
+        movd        DWORD PTR [rdi-3], mm1
+        jl          horizontal_line_5_3_loop
+
+//exit condition
+        movq        mm0,        QWORD PTR  [rsi]    ;
+        00 01 02 03 04 05 06 07
+        movq        mm1,        mm0                 ;
+        00 01 02 03 04 05 06 07
+
+        psllw       mm0,        8                   ;
+        xx 00 xx 02 xx 04 xx 06
+        psrlw       mm1,        8                   ;
+        01 xx 03 xx 05 xx 07 xx
+
+        psrlw       mm0,        8                   ;
+        00 xx 02 xx 04 xx 06 xx
+        psllq       mm1,        16                  ;
+        xx xx 01 xx 03 xx 05 xx
+
+        pmullw      mm0,        mm6
+
+        pmullw      mm1,        mm5
+        paddw       mm1,        mm0
+
+        paddw       mm1,        mm4
+        psrlw       mm1,        8
+
+        packuswb    mm1,        mm7
+        movd        rax,        mm1
+
+        mov         rdx,        rax
+        shr         rdx,        16
+
+        mov         WORD PTR[rdi],   ax
+        mov         BYTE PTR[rdi+2], dl
+
+    }
+
+}
+
+__declspec(align(16)) const static unsigned short one_thirds[] = {  85,  85,  85,  85 };
+__declspec(align(16)) const static unsigned short two_thirds[] = { 171, 171, 171, 171 };
+
+static
+void vertical_band_5_3_scale_mmx
+(
+    unsigned char *source,
+    unsigned int src_pitch,
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+
+    __asm
+    {
+
+        mov         rsi,    source                    // Get the source and destination pointer
+        mov         ecx,    src_pitch               // Get the pitch size
+
+        mov         rdi,    dest                    // tow lines below
+        pxor        mm7,    mm7                     // clear out mm7
+
+        mov         edx,    dest_pitch               // Loop counter
+        movq        mm5,    one_thirds
+
+        movq        mm6,    two_thirds
+        mov         ebx,    dest_width;
+
+        vs_5_3_loop:
+
+        movd        mm0,    DWORD ptr [rsi]         // src[0];
+        movd        mm1,    DWORD ptr [rsi+rcx]     // src[1];
+
+        movd        mm2,    DWORD ptr [rsi+rcx*2]
+        lea         rax,    [rsi+rcx*2]             //
+
+        punpcklbw   mm1,    mm7
+        punpcklbw   mm2,    mm7
+
+        pmullw      mm1,    mm5
+        pmullw      mm2,    mm6
+
+        movd        mm3,    DWORD ptr [rax+rcx]
+        movd        mm4,    DWORD ptr [rax+rcx*2]
+
+        punpcklbw   mm3,    mm7
+        punpcklbw   mm4,    mm7
+
+        pmullw      mm3,    mm6
+        pmullw      mm4,    mm5
+
+
+        movd        DWORD PTR [rdi], mm0
+        paddw       mm1,    mm2
+
+        paddw       mm1,    round_values
+        psrlw       mm1,    8
+
+        packuswb    mm1,    mm7
+        paddw       mm3,    mm4
+
+        paddw       mm3,    round_values
+        movd        DWORD PTR [rdi+rdx], mm1
+
+        psrlw       mm3,    8
+        packuswb    mm3,    mm7
+
+        movd        DWORD PTR [rdi+rdx*2], mm3
+
+
+        add         rdi,    4
+        add         rsi,    4
+
+        sub         rbx,    4
+        jg          vs_5_3_loop
+    }
+}
+
+
+
+
+/****************************************************************************
+*
+*  ROUTINE       : horizontal_line_2_1_scale
+*
+*  INPUTS        : const unsigned char *source :
+*                  unsigned int source_width    :
+*                  unsigned char *dest         :
+*                  unsigned int dest_width      :
+*
+*  OUTPUTS       : None.
+*
+*  RETURNS       : void
+*
+*  FUNCTION      : 1 to 2 up-scaling of a horizontal line of pixels.
+*
+*  SPECIAL NOTES : None.
+*
+****************************************************************************/
+static
+void horizontal_line_2_1_scale_mmx
+(
+    const unsigned char *source,
+    unsigned int source_width,
+    unsigned char *dest,
+    unsigned int dest_width
+)
+{
+    (void) dest_width;
+
+    __asm
+    {
+        mov         rsi,    source
+        mov         rdi,    dest
+
+        pxor        mm7,    mm7
+        mov         ecx,    dest_width
+
+        xor         rdx,    rdx
+        hs_2_1_loop:
+
+        movq        mm0,    [rsi+rdx*2]
+        psllw       mm0,    8
+
+        psrlw       mm0,    8
+        packuswb    mm0,    mm7
+
+        movd        DWORD Ptr [rdi+rdx], mm0;
+        add         rdx,    4
+
+        cmp         rdx,    rcx
+        jl          hs_2_1_loop
+
+    }
+}
+
+
+
+static
+void vertical_band_2_1_scale_mmx
+(
+    unsigned char *source,
+    unsigned int src_pitch,
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width)
+{
+    vpx_memcpy(dest, source, dest_width);
+}
+
+
+__declspec(align(16)) const static unsigned short three_sixteenths[] = {  48,  48,  48,  48 };
+__declspec(align(16)) const static unsigned short ten_sixteenths[]   = { 160, 160, 160, 160 };
+
+static
+void vertical_band_2_1_scale_i_mmx
+(
+    unsigned char *source,
+    unsigned int src_pitch,
+    unsigned char *dest,
+    unsigned int dest_pitch,
+    unsigned int dest_width
+)
+{
+    __asm
+    {
+        mov         rsi,        source
+        mov         rdi,        dest
+
+        mov         eax,        src_pitch
+        mov         edx,        dest_width
+
+        pxor        mm7,        mm7
+        sub         rsi,        rax             //back one line
+
+
+        lea         rcx,        [rsi+rdx];
+        movq        mm6,        round_values;
+
+        movq        mm5,        three_sixteenths;
+        movq        mm4,        ten_sixteenths;
+
+        vs_2_1_i_loop:
+        movd        mm0,        [rsi]           //
+        movd        mm1,        [rsi+rax]       //
+
+        movd        mm2,        [rsi+rax*2]     //
+        punpcklbw   mm0,        mm7
+
+        pmullw      mm0,        mm5
+        punpcklbw   mm1,        mm7
+
+        pmullw      mm1,        mm4
+        punpcklbw   mm2,        mm7
+
+        pmullw      mm2,        mm5
+        paddw       mm0,        round_values
+
+        paddw       mm1,        mm2
+        paddw       mm0,        mm1
+
+        psrlw       mm0,        8
+        packuswb    mm0,        mm7
+
+        movd        DWORD PTR [rdi],        mm0
+        add         rsi,        4
+
+        add         rdi,        4;
+        cmp         rsi,        rcx
+        jl          vs_2_1_i_loop
+
+    }
+}
+
+
+
+void
+register_mmxscalers(void)
+{
+    vp8_horizontal_line_1_2_scale        = horizontal_line_1_2_scale_mmx;
+    vp8_horizontal_line_3_5_scale        = horizontal_line_3_5_scale_mmx;
+    vp8_horizontal_line_4_5_scale        = horizontal_line_4_5_scale_mmx;
+    vp8_vertical_band_1_2_scale          = vertical_band_1_2_scale_mmx;
+    vp8_last_vertical_band_1_2_scale      = last_vertical_band_1_2_scale_mmx;
+    vp8_vertical_band_3_5_scale          = vertical_band_3_5_scale_mmx;
+    vp8_last_vertical_band_3_5_scale      = last_vertical_band_3_5_scale_mmx;
+    vp8_vertical_band_4_5_scale          = vertical_band_4_5_scale_mmx;
+    vp8_last_vertical_band_4_5_scale      = last_vertical_band_4_5_scale_mmx;
+
+    vp8_vertical_band_5_4_scale           = vertical_band_5_4_scale_mmx;
+    vp8_vertical_band_5_3_scale           = vertical_band_5_3_scale_mmx;
+    vp8_vertical_band_2_1_scale           = vertical_band_2_1_scale_mmx;
+    vp8_vertical_band_2_1_scale_i         = vertical_band_2_1_scale_i_mmx;
+    vp8_horizontal_line_2_1_scale         = horizontal_line_2_1_scale_mmx;
+    vp8_horizontal_line_5_3_scale         = horizontal_line_5_3_scale_mmx;
+    vp8_horizontal_line_5_4_scale         = horizontal_line_5_4_scale_mmx;
+}
diff --git a/vpx_scale/x86_64/scalesystemdependant.c b/vpx_scale/x86_64/scalesystemdependant.c
new file mode 100644 (file)
index 0000000..43f05a6
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/****************************************************************************
+*
+*   Module Title :     system_dependant.c
+*
+*   Description  :     Miscellaneous system dependant functions
+*
+****************************************************************************/
+
+/****************************************************************************
+*  Header Files
+****************************************************************************/
+#include "vpx_scale/vpxscale.h"
+#include "cpuidlib.h"
+
+/****************************************************************************
+*  Imports
+*****************************************************************************/
+extern void register_generic_scalers(void);
+extern void register_mmxscalers(void);
+
+/****************************************************************************
+ *
+ *  ROUTINE       : post_proc_machine_specific_config
+ *
+ *  INPUTS        : UINT32 Version : Codec version number.
+ *
+ *  OUTPUTS       : None.
+ *
+ *  RETURNS       : void
+ *
+ *  FUNCTION      : Checks for machine specifc features such as MMX support
+ *                  sets appropriate flags and function pointers.
+ *
+ *  SPECIAL NOTES : None.
+ *
+ ****************************************************************************/
+void
+vp8_scale_machine_specific_config(void)
+{
+    int wmt_enabled = 1;
+
+    if (wmt_enabled)
+    {
+        register_mmxscalers();
+    }
+    else
+    {
+        register_generic_scalers();
+    }
+}
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
new file mode 100644 (file)
index 0000000..a8d0ce4
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef YV12_CONFIG_H
+#define YV12_CONFIG_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define VP7BORDERINPIXELS       48
+#define VP8BORDERINPIXELS       32
+
+    /*************************************
+     For INT_YUV:
+
+     Y = (R+G*2+B)/4;
+     U = (R-B)/2;
+     V =  (G*2 - R - B)/4;
+    And
+     R = Y+U-V;
+     G = Y+V;
+     B = Y-U-V;
+    ************************************/
+    typedef enum
+    {
+        REG_YUV = 0,    // Regular yuv
+        INT_YUV = 1     // The type of yuv that can be tranfer to and from RGB through integer transform
+              }
+              YUV_TYPE;
+
+    typedef struct
+    {
+        int   y_width;
+        int   y_height;
+        int   y_stride;
+//    int   yinternal_width;
+
+        int   uv_width;
+        int   uv_height;
+        int   uv_stride;
+//    int   uvinternal_width;
+
+        unsigned char *y_buffer;
+        unsigned char *u_buffer;
+        unsigned char *v_buffer;
+
+        unsigned char *buffer_alloc;
+        int border;
+        int frame_size;
+        YUV_TYPE clrtype;
+    } YV12_BUFFER_CONFIG;
+
+    int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border);
+    int vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf);
+    int vp8_yv12_black_frame_buffer(YV12_BUFFER_CONFIG *ybf);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //YV12_CONFIG_H
diff --git a/vpx_scale/yv12extend.h b/vpx_scale/yv12extend.h
new file mode 100644 (file)
index 0000000..9968fea
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+#ifndef YV12_EXTEND_H
+#define YV12_EXTEND_H
+
+#include "vpx_scale/yv12config.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    void vp8_yv12_extend_frame_borders(YV12_BUFFER_CONFIG *ybf);
+
+    /* Copy Y,U,V buffer data from src to dst, filling border of dst as well. */
+
+    void vp8_yv12_copy_frame(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+    void vp8_yv12_copy_frame_yonly(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/wince_wmain_adapter.cpp b/wince_wmain_adapter.cpp
new file mode 100644 (file)
index 0000000..db2119c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license and patent
+ *  grant that can be found in the LICENSE file in the root of the source
+ *  tree. All contributing project authors may be found in the AUTHORS
+ *  file in the root of the source tree.
+ */
+
+
+/* This program is created to take command arguments and pass
+ * them to main() in example.c or example_xma.c, because the
+ * correspending part in example.c or example_xma.c does not
+ * work on Pocket PC platform.
+ * To modify the command arguments, go to "Property" page and
+ * fill in "Command arguments." For example:
+ *  --codec vp6 --flipuv --progress _bnd.vp6
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_NUM_ARG 64
+#define MAX_SIZ_ARG 512
+
+extern "C"
+{
+    int main(int argc, char **argv);
+}
+
+int wmain(int argc, wchar_t **argv) {
+    char *cargv[MAX_NUM_ARG];
+    char chargv[MAX_SIZ_ARG];
+    int ret;
+
+    /* transform command line arguments from (wchar_t *) to (char *) */
+    for(int i=0; i<argc; i++) {
+        wcstombs( chargv, argv[i], sizeof(chargv));
+        cargv[i] = _strdup(chargv);
+    }
+
+    ret = main(argc, (char **)cargv);
+
+    //free the memory located by _strdup()
+    for(int i=0; i<argc; i++)
+        free(cargv[i]);
+
+    return ret;
+}